1 // Copyright (C) 2007-2019 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_DataMapOfShapeShape.hxx>
76 #include <TopTools_MapIteratorOfMapOfShape.hxx>
77 #include <TopTools_MapOfShape.hxx>
78 #include <TopoDS_Compound.hxx>
85 #include <vtkUnstructuredGridWriter.h>
87 // to pass CORBA exception through SMESH_TRY
88 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
90 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
93 static int MYDEBUG = 0;
95 static int MYDEBUG = 0;
99 using SMESH::TPythonDump;
102 int SMESH_Mesh_i::_idGenerator = 0;
104 //=============================================================================
108 //=============================================================================
110 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
112 : SALOME::GenericObj_i( thePOA )
116 _id = _idGenerator++;
119 _previewEditor = NULL;
124 //=============================================================================
128 //=============================================================================
130 SMESH_Mesh_i::~SMESH_Mesh_i()
133 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
134 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
135 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
137 aGroup->UnRegister();
138 SMESH::SMESH_GroupBase_var( itGr->second );
143 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
144 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
145 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
147 aSubMesh->UnRegister();
148 SMESH::SMESH_subMesh_var( itSM->second );
150 _mapSubMeshIor.clear();
152 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
153 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
154 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
155 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
156 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
157 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
160 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
164 // clear cached shapes if no more meshes remain; (the cache is blame,
165 // together with publishing, of spent time increasing in issue 22874)
166 if ( _impl->NbMeshes() == 1 )
167 _gen_i->GetShapeReader()->ClearClientBuffer();
169 delete _editor; _editor = NULL;
170 delete _previewEditor; _previewEditor = NULL;
171 delete _impl; _impl = NULL;
172 delete _preMeshInfo; _preMeshInfo = NULL;
175 //=============================================================================
179 * Associates <this> mesh with <theShape> and puts a reference
180 * to <theShape> into the current study;
181 * the previous shape is substituted by the new one.
183 //=============================================================================
185 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
186 throw (SALOME::SALOME_Exception)
188 Unexpect aCatch(SALOME_SalomeException);
190 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
192 catch(SALOME_Exception & S_ex) {
193 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
195 // to track changes of GEOM groups
196 SMESH::SMESH_Mesh_var mesh = _this();
197 addGeomGroupData( theShapeObject, mesh );
198 if ( !CORBA::is_nil( theShapeObject ))
199 _mainShapeTick = theShapeObject->GetTick();
202 //================================================================================
204 * \brief return true if mesh has a shape to build a shape on
206 //================================================================================
208 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
209 throw (SALOME::SALOME_Exception)
211 Unexpect aCatch(SALOME_SalomeException);
214 res = _impl->HasShapeToMesh();
216 catch(SALOME_Exception & S_ex) {
217 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
222 //=======================================================================
223 //function : GetShapeToMesh
225 //=======================================================================
227 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
228 throw (SALOME::SALOME_Exception)
230 Unexpect aCatch(SALOME_SalomeException);
231 GEOM::GEOM_Object_var aShapeObj;
233 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
236 aShapeObj = _gen_i->ShapeToGeomObject( S );
237 if ( aShapeObj->_is_nil() )
239 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
240 // find GEOM_Object by entry (IPAL52735)
241 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
242 for ( ; data != _geomGroupData.end(); ++data )
243 if ( data->_smeshObject->_is_equivalent( _this() ))
245 SALOMEDS::SObject_wrap so = _gen_i->getStudyServant()->FindObjectID( data->_groupEntry.c_str() );
246 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
247 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
253 catch(SALOME_Exception & S_ex) {
254 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
256 return aShapeObj._retn();
259 //================================================================================
261 * \brief Replaces a shape in the mesh
263 //================================================================================
264 void SMESH_Mesh_i::ReplaceShape(GEOM::GEOM_Object_ptr theNewGeom)
265 throw (SALOME::SALOME_Exception)
267 TopoDS_Shape S = _impl->GetShapeToMesh();
268 GEOM_Client* geomClient = _gen_i->GetShapeReader();
269 TCollection_AsciiString aIOR;
270 if (geomClient->Find(S, aIOR)) {
271 geomClient->RemoveShapeFromBuffer(aIOR);
273 // clear buffer also for sub-groups
274 const std::set<SMESHDS_GroupBase*>& groups = _impl->GetMeshDS()->GetGroups();
275 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
276 for (; g != groups.end(); ++g)
277 if (const SMESHDS_GroupOnGeom* group = dynamic_cast<SMESHDS_GroupOnGeom*>(*g))
279 const TopoDS_Shape& s = group->GetShape();
280 if (geomClient->Find(s, aIOR))
281 geomClient->RemoveShapeFromBuffer(aIOR);
284 // update the reference to theNewGeom (needed for correct execution of a dumped python script)
285 SMESH::SMESH_Mesh_var me = _this();
286 SALOMEDS::SObject_wrap aSO = _gen_i->ObjectToSObject( me );
287 CORBA::String_var entry = theNewGeom->GetStudyEntry();
288 if ( !aSO->_is_nil() )
290 SALOMEDS::SObject_wrap aShapeRefSO;
291 if ( aSO->FindSubObject( _gen_i->GetRefOnShapeTag(), aShapeRefSO.inout() ))
293 SALOMEDS::SObject_wrap aShapeSO = _gen_i->getStudyServant()->FindObjectID( entry );
294 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
295 builder->Addreference( aShapeRefSO, aShapeSO );
299 // re-assign global hypotheses to the new shape
301 CheckGeomModif( true );
303 TPythonDump() << "SHAPERSTUDY.breakLinkForSubElements(salome.ObjectToSObject("
304 << me <<".GetMesh()), " << entry.in() << ")";
306 TPythonDump() << me << ".ReplaceShape( " << entry.in() << " )";
310 //================================================================================
312 * \brief Return false if the mesh is not yet fully loaded from the study file
314 //================================================================================
316 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
318 Unexpect aCatch(SALOME_SalomeException);
319 return !_preMeshInfo;
322 //================================================================================
324 * \brief Load full mesh data from the study file
326 //================================================================================
328 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
330 Unexpect aCatch(SALOME_SalomeException);
332 _preMeshInfo->FullLoadFromFile();
335 //================================================================================
337 * \brief Remove all nodes and elements
339 //================================================================================
341 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
343 Unexpect aCatch(SALOME_SalomeException);
345 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
349 //CheckGeomGroupModif(); // issue 20145
351 catch(SALOME_Exception & S_ex) {
352 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
355 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
357 SMESH::SMESH_Mesh_var mesh = _this();
358 _gen_i->UpdateIcons( mesh );
361 //================================================================================
363 * \brief Remove all nodes and elements for indicated shape
365 //================================================================================
367 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
368 throw (SALOME::SALOME_Exception)
370 Unexpect aCatch(SALOME_SalomeException);
372 _preMeshInfo->FullLoadFromFile();
375 _impl->ClearSubMesh( ShapeID );
377 catch(SALOME_Exception & S_ex) {
378 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
380 _impl->GetMeshDS()->Modified();
382 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
385 //=============================================================================
387 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
389 //=============================================================================
391 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
393 SMESH::DriverMED_ReadStatus res;
396 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
397 res = SMESH::DRS_OK; break;
398 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
399 res = SMESH::DRS_EMPTY; break;
400 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
401 res = SMESH::DRS_WARN_RENUMBER; break;
402 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
403 res = SMESH::DRS_WARN_SKIP_ELEM; break;
404 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
405 res = SMESH::DRS_WARN_DESCENDING; break;
406 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
408 res = SMESH::DRS_FAIL; break;
413 //=============================================================================
415 * Convert ::SMESH_ComputeError to SMESH::ComputeError
417 //=============================================================================
419 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
421 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
422 errVar->subShapeID = -1;
423 errVar->hasBadMesh = false;
425 if ( !errorPtr || errorPtr->IsOK() )
427 errVar->code = SMESH::COMPERR_OK;
431 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
432 errVar->comment = errorPtr->myComment.c_str();
434 return errVar._retn();
437 //=============================================================================
441 * Imports mesh data from MED file
443 //=============================================================================
445 SMESH::DriverMED_ReadStatus
446 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
447 throw ( SALOME::SALOME_Exception )
449 Unexpect aCatch(SALOME_SalomeException);
452 status = _impl->MEDToMesh( theFileName, theMeshName );
454 catch( SALOME_Exception& S_ex ) {
455 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
458 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
461 CreateGroupServants();
463 int major, minor, release;
464 major = minor = release = 0;
465 MED::GetMEDVersion(theFileName, major, minor, release);
466 _medFileInfo = new SMESH::MedFileInfo();
467 _medFileInfo->fileName = theFileName;
468 _medFileInfo->fileSize = 0;
469 _medFileInfo->major = major;
470 _medFileInfo->minor = minor;
471 _medFileInfo->release = release;
472 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
474 return ConvertDriverMEDReadStatus(status);
477 //================================================================================
479 * \brief Imports mesh data from the CGNS file
481 //================================================================================
483 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
484 const int theMeshIndex,
485 std::string& theMeshName )
486 throw ( SALOME::SALOME_Exception )
488 Unexpect aCatch(SALOME_SalomeException);
491 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
493 catch( SALOME_Exception& S_ex ) {
494 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
497 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
500 CreateGroupServants();
502 _medFileInfo = new SMESH::MedFileInfo();
503 _medFileInfo->fileName = theFileName;
504 _medFileInfo->major = 0;
505 _medFileInfo->minor = 0;
506 _medFileInfo->release = 0;
507 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
509 return ConvertDriverMEDReadStatus(status);
512 //================================================================================
514 * \brief Return string representation of a MED file version comprising nbDigits
516 //================================================================================
518 char* SMESH_Mesh_i::GetVersionString(CORBA::Long minor, CORBA::Short nbDigits)
520 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(minor,
522 return CORBA::string_dup( ver.c_str() );
525 //================================================================================
527 * Return the list of med versions compatibles for write/append,
528 * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32)
530 //================================================================================
531 SMESH::long_array* SMESH_Mesh_i::GetMEDVersionsCompatibleForAppend()
533 SMESH::long_array_var aResult = new SMESH::long_array();
534 std::vector<int> mvok = MED::GetMEDVersionsAppendCompatible();
535 long nbver = mvok.size();
536 aResult->length( nbver );
537 for ( int i = 0; i < nbver; i++ )
538 aResult[i] = mvok[i];
539 return aResult._retn();
542 //=============================================================================
546 * Imports mesh data from MED file
548 //=============================================================================
550 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
551 throw ( SALOME::SALOME_Exception )
555 // Read mesh with name = <theMeshName> into SMESH_Mesh
556 _impl->UNVToMesh( theFileName );
558 CreateGroupServants();
560 _medFileInfo = new SMESH::MedFileInfo();
561 _medFileInfo->fileName = theFileName;
562 _medFileInfo->major = 0;
563 _medFileInfo->minor = 0;
564 _medFileInfo->release = 0;
565 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
567 SMESH_CATCH( SMESH::throwCorbaException );
572 //=============================================================================
576 * Imports mesh data from STL file
578 //=============================================================================
579 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
580 throw ( SALOME::SALOME_Exception )
584 // Read mesh with name = <theMeshName> into SMESH_Mesh
585 std::string name = _impl->STLToMesh( theFileName );
588 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
589 _gen_i->SetName( meshSO, name.c_str() );
591 _medFileInfo = new SMESH::MedFileInfo();
592 _medFileInfo->fileName = theFileName;
593 _medFileInfo->major = 0;
594 _medFileInfo->minor = 0;
595 _medFileInfo->release = 0;
596 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
598 SMESH_CATCH( SMESH::throwCorbaException );
603 //================================================================================
605 * \brief Function used in SMESH_CATCH by ImportGMFFile()
607 //================================================================================
611 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
613 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
617 //================================================================================
619 * \brief Imports data from a GMF file and returns an error description
621 //================================================================================
623 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
624 bool theMakeRequiredGroups )
625 throw (SALOME::SALOME_Exception)
627 SMESH_ComputeErrorPtr error;
630 #define SMESH_CAUGHT error =
633 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
635 _medFileInfo = new SMESH::MedFileInfo();
636 _medFileInfo->fileName = theFileName;
637 _medFileInfo->major = 0;
638 _medFileInfo->minor = 0;
639 _medFileInfo->release = 0;
640 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
642 SMESH_CATCH( exceptionToComputeError );
646 CreateGroupServants();
648 return ConvertComputeError( error );
651 //=============================================================================
655 //=============================================================================
657 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
659 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
660 (SMESH_Hypothesis::Hypothesis_Status theStatus)
663 RETURNCASE( HYP_OK );
664 RETURNCASE( HYP_MISSING );
665 RETURNCASE( HYP_CONCURRENT );
666 RETURNCASE( HYP_BAD_PARAMETER );
667 RETURNCASE( HYP_HIDDEN_ALGO );
668 RETURNCASE( HYP_HIDING_ALGO );
669 RETURNCASE( HYP_UNKNOWN_FATAL );
670 RETURNCASE( HYP_INCOMPATIBLE );
671 RETURNCASE( HYP_NOTCONFORM );
672 RETURNCASE( HYP_ALREADY_EXIST );
673 RETURNCASE( HYP_BAD_DIM );
674 RETURNCASE( HYP_BAD_SUBSHAPE );
675 RETURNCASE( HYP_BAD_GEOMETRY );
676 RETURNCASE( HYP_NEED_SHAPE );
677 RETURNCASE( HYP_INCOMPAT_HYPS );
680 return SMESH::HYP_UNKNOWN_FATAL;
683 //=============================================================================
687 * calls internal addHypothesis() and then adds a reference to <anHyp> under
688 * the SObject actually having a reference to <aSubShape>.
689 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
691 //=============================================================================
693 SMESH::Hypothesis_Status
694 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
695 SMESH::SMESH_Hypothesis_ptr anHyp,
696 CORBA::String_out anErrorText)
697 throw(SALOME::SALOME_Exception)
699 Unexpect aCatch(SALOME_SalomeException);
701 _preMeshInfo->ForgetOrLoad();
703 const int prevNbMeshEnt = _impl->NbNodes() + _impl->GetMeshDS()->NbElements();
706 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
707 anErrorText = error.c_str();
709 SMESH::SMESH_Mesh_var mesh( _this() );
710 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
712 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
714 int newNbMeshEnt = _impl->NbNodes() + _impl->GetMeshDS()->NbElements();
715 if ( newNbMeshEnt != prevNbMeshEnt )
716 _gen_i->UpdateIcons( mesh );
718 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
720 // Update Python script
721 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
722 << aSubShape << ", " << anHyp << " )";
724 return ConvertHypothesisStatus(status);
727 //=============================================================================
731 //=============================================================================
733 SMESH_Hypothesis::Hypothesis_Status
734 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
735 SMESH::SMESH_Hypothesis_ptr anHyp,
736 std::string* anErrorText)
738 if(MYDEBUG) MESSAGE("addHypothesis");
740 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
741 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
743 if (CORBA::is_nil( anHyp ))
744 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
746 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
749 TopoDS_Shape myLocSubShape;
750 //use PseudoShape in case if mesh has no shape
752 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
754 myLocSubShape = _impl->GetShapeToMesh();
756 const int hypId = anHyp->GetId();
758 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
759 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
761 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
763 // assure there is a corresponding submesh
764 if ( !_impl->IsMainShape( myLocSubShape )) {
765 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
766 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
767 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
770 else if ( anErrorText )
772 *anErrorText = error;
775 catch(SALOME_Exception & S_ex)
777 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
782 //=============================================================================
786 //=============================================================================
788 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
789 SMESH::SMESH_Hypothesis_ptr anHyp)
790 throw(SALOME::SALOME_Exception)
792 Unexpect aCatch(SALOME_SalomeException);
794 _preMeshInfo->ForgetOrLoad();
796 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
797 SMESH::SMESH_Mesh_var mesh = _this();
799 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
801 _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
802 _gen_i->UpdateIcons( mesh );
804 // Update Python script
805 if(_impl->HasShapeToMesh())
806 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
807 << aSubShape << ", " << anHyp << " )";
809 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
812 return ConvertHypothesisStatus(status);
815 //=============================================================================
819 //=============================================================================
821 SMESH_Hypothesis::Hypothesis_Status
822 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
823 SMESH::SMESH_Hypothesis_ptr anHyp)
825 if(MYDEBUG) MESSAGE("removeHypothesis()");
827 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
828 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
830 if (CORBA::is_nil( anHyp ))
831 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
834 _preMeshInfo->ForgetOrLoad();
836 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
839 TopoDS_Shape myLocSubShape;
840 //use PseudoShape in case if mesh has no shape
841 if( _impl->HasShapeToMesh() )
842 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
844 myLocSubShape = _impl->GetShapeToMesh();
846 const int hypId = anHyp->GetId();
847 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
848 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
850 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
854 catch(SALOME_Exception & S_ex)
856 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
861 //=============================================================================
865 //=============================================================================
867 SMESH::ListOfHypothesis *
868 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
869 throw(SALOME::SALOME_Exception)
871 Unexpect aCatch(SALOME_SalomeException);
872 if (MYDEBUG) MESSAGE("GetHypothesisList");
873 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
874 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
876 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
879 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
880 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
881 myLocSubShape = _impl->GetShapeToMesh();
882 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
883 int i = 0, n = aLocalList.size();
886 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
887 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
888 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
890 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
891 if ( id_hypptr != _mapHypo.end() )
892 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
896 catch(SALOME_Exception & S_ex) {
897 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
900 return aList._retn();
903 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
905 Unexpect aCatch(SALOME_SalomeException);
906 if (MYDEBUG) MESSAGE("GetSubMeshes");
908 SMESH::submesh_array_var aList = new SMESH::submesh_array();
911 TPythonDump aPythonDump;
912 if ( !_mapSubMeshIor.empty() )
916 aList->length( _mapSubMeshIor.size() );
918 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
919 for ( ; it != _mapSubMeshIor.end(); it++ ) {
920 if ( CORBA::is_nil( it->second )) continue;
921 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
923 if (i > 1) aPythonDump << ", ";
924 aPythonDump << it->second;
928 catch(SALOME_Exception & S_ex) {
929 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
932 // Update Python script
933 if ( !_mapSubMeshIor.empty() )
934 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
936 return aList._retn();
939 //=============================================================================
943 //=============================================================================
945 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
946 const char* theName )
947 throw(SALOME::SALOME_Exception)
949 Unexpect aCatch(SALOME_SalomeException);
950 if (CORBA::is_nil(aSubShape))
951 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
953 SMESH::SMESH_subMesh_var subMesh;
954 SMESH::SMESH_Mesh_var aMesh = _this();
956 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
958 //Get or Create the SMESH_subMesh object implementation
960 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
962 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
964 TopoDS_Iterator it( myLocSubShape );
966 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
968 subMesh = getSubMesh( subMeshId );
970 // create a new subMesh object servant if there is none for the shape
971 if ( subMesh->_is_nil() )
972 subMesh = createSubMesh( aSubShape );
973 if ( _gen_i->CanPublishInStudy( subMesh ))
975 SALOMEDS::SObject_wrap aSO =
976 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
977 if ( !aSO->_is_nil()) {
978 // Update Python script
979 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
980 << aSubShape << ", '" << theName << "' )";
984 catch(SALOME_Exception & S_ex) {
985 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
987 return subMesh._retn();
990 //=============================================================================
994 //=============================================================================
996 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
997 throw (SALOME::SALOME_Exception)
1001 if ( theSubMesh->_is_nil() )
1004 GEOM::GEOM_Object_var aSubShape;
1005 // Remove submesh's SObject
1006 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
1007 if ( !anSO->_is_nil() ) {
1008 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
1009 SALOMEDS::SObject_wrap anObj, aRef;
1010 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
1011 anObj->ReferencedObject( aRef.inout() ))
1013 CORBA::Object_var obj = aRef->GetObject();
1014 aSubShape = GEOM::GEOM_Object::_narrow( obj );
1016 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
1017 // aSubShape = theSubMesh->GetSubShape();
1019 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
1020 builder->RemoveObjectWithChildren( anSO );
1022 // Update Python script
1023 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
1026 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
1028 _preMeshInfo->ForgetOrLoad();
1030 SMESH_CATCH( SMESH::throwCorbaException );
1033 //=============================================================================
1037 //=============================================================================
1039 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
1040 const char* theName )
1041 throw(SALOME::SALOME_Exception)
1043 Unexpect aCatch(SALOME_SalomeException);
1045 _preMeshInfo->FullLoadFromFile();
1047 SMESH::SMESH_Group_var aNewGroup =
1048 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
1050 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1052 SMESH::SMESH_Mesh_var mesh = _this();
1053 SALOMEDS::SObject_wrap aSO =
1054 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
1055 if ( !aSO->_is_nil())
1056 // Update Python script
1057 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
1058 << theElemType << ", '" << theName << "' )";
1060 return aNewGroup._retn();
1063 //=============================================================================
1067 //=============================================================================
1068 SMESH::SMESH_GroupOnGeom_ptr
1069 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
1070 const char* theName,
1071 GEOM::GEOM_Object_ptr theGeomObj)
1072 throw(SALOME::SALOME_Exception)
1074 Unexpect aCatch(SALOME_SalomeException);
1076 _preMeshInfo->FullLoadFromFile();
1078 SMESH::SMESH_GroupOnGeom_var aNewGroup;
1080 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
1081 if ( !aShape.IsNull() )
1084 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, /*id=*/-1, aShape ));
1086 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1088 SMESH::SMESH_Mesh_var mesh = _this();
1089 SALOMEDS::SObject_wrap aSO =
1090 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
1091 if ( !aSO->_is_nil())
1092 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
1093 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
1097 return aNewGroup._retn();
1100 //================================================================================
1102 * \brief Creates a group whose contents is defined by filter
1103 * \param theElemType - group type
1104 * \param theName - group name
1105 * \param theFilter - the filter
1106 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1108 //================================================================================
1110 SMESH::SMESH_GroupOnFilter_ptr
1111 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1112 const char* theName,
1113 SMESH::Filter_ptr theFilter )
1114 throw (SALOME::SALOME_Exception)
1116 Unexpect aCatch(SALOME_SalomeException);
1118 _preMeshInfo->FullLoadFromFile();
1120 if ( CORBA::is_nil( theFilter ))
1121 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1123 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1125 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1127 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1128 ( createGroup( theElemType, theName, /*id=*/-1, TopoDS_Shape(), predicate ));
1131 if ( !aNewGroup->_is_nil() )
1132 aNewGroup->SetFilter( theFilter );
1134 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1136 SMESH::SMESH_Mesh_var mesh = _this();
1137 SALOMEDS::SObject_wrap aSO =
1138 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1140 if ( !aSO->_is_nil())
1141 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1142 << theElemType << ", '" << theName << "', " << theFilter << " )";
1144 return aNewGroup._retn();
1147 //=============================================================================
1151 //=============================================================================
1153 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1154 throw (SALOME::SALOME_Exception)
1156 if ( theGroup->_is_nil() )
1161 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1165 if ( aGroup->GetMeshServant() != this )
1166 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroup(): group does not belong to this mesh",
1167 SALOME::BAD_PARAM );
1169 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1170 if ( !aGroupSO->_is_nil() )
1172 // Update Python script
1173 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1175 // Remove group's SObject
1176 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1177 builder->RemoveObjectWithChildren( aGroupSO );
1179 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1181 // Remove the group from SMESH data structures
1182 removeGroup( aGroup->GetLocalID() );
1184 SMESH_CATCH( SMESH::throwCorbaException );
1187 //=============================================================================
1189 * Remove group with its contents
1191 //=============================================================================
1193 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1194 throw (SALOME::SALOME_Exception)
1198 _preMeshInfo->FullLoadFromFile();
1200 if ( theGroup->_is_nil() )
1203 SMESH_GroupBase_i* groupImpl = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup );
1204 if ( !groupImpl || groupImpl->GetMeshServant() != this )
1205 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroupWithContents(): group does not belong to this mesh",
1208 vector<int> nodeIds; // to remove nodes becoming free
1209 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1210 if ( !isNodal && !theGroup->IsEmpty() )
1212 CORBA::Long elemID = theGroup->GetID( 1 );
1213 int nbElemNodes = GetElemNbNodes( elemID );
1214 if ( nbElemNodes > 0 )
1215 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1218 // Retrieve contents
1219 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1220 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1221 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1222 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1223 elems.assign( elemBeg, elemEnd );
1225 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1228 RemoveGroup( theGroup );
1231 for ( size_t i = 0; i < elems.size(); ++i )
1233 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1237 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1238 nodeIds.push_back( nIt->next()->GetID() );
1240 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1244 _impl->GetMeshDS()->RemoveElement( elems[i] );
1248 // Remove free nodes
1249 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1250 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1251 if ( n->NbInverseElements() == 0 )
1252 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1254 // Update Python script (theGroup must be alive for this)
1255 pyDump << SMESH::SMESH_Mesh_var(_this())
1256 << ".RemoveGroupWithContents( " << theGroup << " )";
1258 SMESH_CATCH( SMESH::throwCorbaException );
1261 //================================================================================
1263 * \brief Get the list of groups existing in the mesh
1264 * \retval SMESH::ListOfGroups * - list of groups
1266 //================================================================================
1268 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1270 Unexpect aCatch(SALOME_SalomeException);
1271 if (MYDEBUG) MESSAGE("GetGroups");
1273 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1276 TPythonDump aPythonDump;
1277 if ( !_mapGroups.empty() )
1279 aPythonDump << "[ ";
1281 aList->length( _mapGroups.size() );
1283 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1284 for ( ; it != _mapGroups.end(); it++ ) {
1285 if ( CORBA::is_nil( it->second )) continue;
1286 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1288 if (i > 1) aPythonDump << ", ";
1289 aPythonDump << it->second;
1293 catch(SALOME_Exception & S_ex) {
1294 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1296 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1298 return aList._retn();
1301 //=============================================================================
1303 * Get number of groups existing in the mesh
1305 //=============================================================================
1307 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1309 Unexpect aCatch(SALOME_SalomeException);
1310 return _mapGroups.size();
1313 //=============================================================================
1315 * New group including all mesh elements present in initial groups is created.
1317 //=============================================================================
1319 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1320 SMESH::SMESH_GroupBase_ptr theGroup2,
1321 const char* theName )
1322 throw (SALOME::SALOME_Exception)
1324 SMESH::SMESH_Group_var aResGrp;
1328 _preMeshInfo->FullLoadFromFile();
1330 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1331 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1333 if ( theGroup1->GetType() != theGroup2->GetType() )
1334 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1339 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1340 if ( aResGrp->_is_nil() )
1341 return SMESH::SMESH_Group::_nil();
1343 aResGrp->AddFrom( theGroup1 );
1344 aResGrp->AddFrom( theGroup2 );
1346 // Update Python script
1347 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1348 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1350 SMESH_CATCH( SMESH::throwCorbaException );
1352 return aResGrp._retn();
1355 //=============================================================================
1357 * \brief New group including all mesh elements present in initial groups is created.
1358 * \param theGroups list of groups
1359 * \param theName name of group to be created
1360 * \return pointer to the new group
1362 //=============================================================================
1364 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1365 const char* theName )
1366 throw (SALOME::SALOME_Exception)
1368 SMESH::SMESH_Group_var aResGrp;
1371 _preMeshInfo->FullLoadFromFile();
1374 return SMESH::SMESH_Group::_nil();
1379 SMESH::ElementType aType = SMESH::ALL;
1380 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1382 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1383 if ( CORBA::is_nil( aGrp ) )
1385 if ( aType == SMESH::ALL )
1386 aType = aGrp->GetType();
1387 else if ( aType != aGrp->GetType() )
1388 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1391 if ( aType == SMESH::ALL )
1392 return SMESH::SMESH_Group::_nil();
1397 aResGrp = CreateGroup( aType, theName );
1398 if ( aResGrp->_is_nil() )
1399 return SMESH::SMESH_Group::_nil();
1401 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1402 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1404 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1405 if ( !CORBA::is_nil( aGrp ) )
1407 aResGrp->AddFrom( aGrp );
1408 if ( g > 0 ) pyDump << ", ";
1412 pyDump << " ], '" << theName << "' )";
1414 SMESH_CATCH( SMESH::throwCorbaException );
1416 return aResGrp._retn();
1419 //=============================================================================
1421 * New group is created. All mesh elements that are
1422 * present in both initial groups are added to the new one.
1424 //=============================================================================
1426 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1427 SMESH::SMESH_GroupBase_ptr theGroup2,
1428 const char* theName )
1429 throw (SALOME::SALOME_Exception)
1431 SMESH::SMESH_Group_var aResGrp;
1436 _preMeshInfo->FullLoadFromFile();
1438 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1439 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1441 if ( theGroup1->GetType() != theGroup2->GetType() )
1442 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1446 // Create Intersection
1447 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1448 if ( aResGrp->_is_nil() )
1449 return aResGrp._retn();
1451 SMESHDS_GroupBase* groupDS1 = 0;
1452 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1453 groupDS1 = grp_i->GetGroupDS();
1455 SMESHDS_GroupBase* groupDS2 = 0;
1456 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1457 groupDS2 = grp_i->GetGroupDS();
1459 SMESHDS_Group* resGroupDS = 0;
1460 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1461 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1463 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1465 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1466 while ( elemIt1->more() )
1468 const SMDS_MeshElement* e = elemIt1->next();
1469 if ( groupDS2->Contains( e ))
1470 resGroupDS->SMDSGroup().Add( e );
1473 // Update Python script
1474 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1475 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1477 SMESH_CATCH( SMESH::throwCorbaException );
1479 return aResGrp._retn();
1482 //=============================================================================
1484 \brief Intersect list of groups. New group is created. All mesh elements that
1485 are present in all initial groups simultaneously are added to the new one.
1486 \param theGroups list of groups
1487 \param theName name of group to be created
1488 \return pointer on the group
1490 //=============================================================================
1491 SMESH::SMESH_Group_ptr
1492 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1493 const char* theName )
1494 throw (SALOME::SALOME_Exception)
1496 SMESH::SMESH_Group_var aResGrp;
1501 _preMeshInfo->FullLoadFromFile();
1504 return SMESH::SMESH_Group::_nil();
1506 // check types and get SMESHDS_GroupBase's
1507 SMESH::ElementType aType = SMESH::ALL;
1508 vector< SMESHDS_GroupBase* > groupVec;
1509 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1511 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1512 if ( CORBA::is_nil( aGrp ) )
1514 if ( aType == SMESH::ALL )
1515 aType = aGrp->GetType();
1516 else if ( aType != aGrp->GetType() )
1517 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1520 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1521 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1523 if ( grpDS->IsEmpty() )
1528 groupVec.push_back( grpDS );
1531 if ( aType == SMESH::ALL ) // all groups are nil
1532 return SMESH::SMESH_Group::_nil();
1537 aResGrp = CreateGroup( aType, theName );
1539 SMESHDS_Group* resGroupDS = 0;
1540 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1541 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1542 if ( !resGroupDS || groupVec.empty() )
1543 return aResGrp._retn();
1546 size_t i, nb = groupVec.size();
1547 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1548 while ( elemIt1->more() )
1550 const SMDS_MeshElement* e = elemIt1->next();
1552 for ( i = 1; ( i < nb && inAll ); ++i )
1553 inAll = groupVec[i]->Contains( e );
1556 resGroupDS->SMDSGroup().Add( e );
1559 // Update Python script
1560 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1561 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1563 SMESH_CATCH( SMESH::throwCorbaException );
1565 return aResGrp._retn();
1568 //=============================================================================
1570 * New group is created. All mesh elements that are present in
1571 * a main group but is not present in a tool group are added to the new one
1573 //=============================================================================
1575 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1576 SMESH::SMESH_GroupBase_ptr theGroup2,
1577 const char* theName )
1578 throw (SALOME::SALOME_Exception)
1580 SMESH::SMESH_Group_var aResGrp;
1585 _preMeshInfo->FullLoadFromFile();
1587 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1588 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1590 if ( theGroup1->GetType() != theGroup2->GetType() )
1591 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1595 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1596 if ( aResGrp->_is_nil() )
1597 return aResGrp._retn();
1599 SMESHDS_GroupBase* groupDS1 = 0;
1600 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1601 groupDS1 = grp_i->GetGroupDS();
1603 SMESHDS_GroupBase* groupDS2 = 0;
1604 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1605 groupDS2 = grp_i->GetGroupDS();
1607 SMESHDS_Group* resGroupDS = 0;
1608 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1609 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1611 if ( groupDS1 && groupDS2 && resGroupDS )
1613 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1614 while ( elemIt1->more() )
1616 const SMDS_MeshElement* e = elemIt1->next();
1617 if ( !groupDS2->Contains( e ))
1618 resGroupDS->SMDSGroup().Add( e );
1621 // Update Python script
1622 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1623 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1625 SMESH_CATCH( SMESH::throwCorbaException );
1627 return aResGrp._retn();
1630 //=============================================================================
1632 \brief Cut lists of groups. New group is created. All mesh elements that are
1633 present in main groups but do not present in tool groups are added to the new one
1634 \param theMainGroups list of main groups
1635 \param theToolGroups list of tool groups
1636 \param theName name of group to be created
1637 \return pointer on the group
1639 //=============================================================================
1640 SMESH::SMESH_Group_ptr
1641 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1642 const SMESH::ListOfGroups& theToolGroups,
1643 const char* theName )
1644 throw (SALOME::SALOME_Exception)
1646 SMESH::SMESH_Group_var aResGrp;
1651 _preMeshInfo->FullLoadFromFile();
1654 return SMESH::SMESH_Group::_nil();
1656 // check types and get SMESHDS_GroupBase's
1657 SMESH::ElementType aType = SMESH::ALL;
1658 vector< SMESHDS_GroupBase* > toolGroupVec;
1659 vector< SMDS_ElemIteratorPtr > mainIterVec;
1661 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1663 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1664 if ( CORBA::is_nil( aGrp ) )
1666 if ( aType == SMESH::ALL )
1667 aType = aGrp->GetType();
1668 else if ( aType != aGrp->GetType() )
1669 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1671 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1672 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1673 if ( !grpDS->IsEmpty() )
1674 mainIterVec.push_back( grpDS->GetElements() );
1676 if ( aType == SMESH::ALL ) // all main groups are nil
1677 return SMESH::SMESH_Group::_nil();
1678 if ( mainIterVec.empty() ) // all main groups are empty
1679 return aResGrp._retn();
1681 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1683 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1684 if ( CORBA::is_nil( aGrp ) )
1686 if ( aType != aGrp->GetType() )
1687 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1689 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1690 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1691 toolGroupVec.push_back( grpDS );
1697 aResGrp = CreateGroup( aType, theName );
1699 SMESHDS_Group* resGroupDS = 0;
1700 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1701 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1703 return aResGrp._retn();
1706 size_t i, nb = toolGroupVec.size();
1707 SMDS_ElemIteratorPtr mainElemIt
1708 ( new SMDS_IteratorOnIterators
1709 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1710 while ( mainElemIt->more() )
1712 const SMDS_MeshElement* e = mainElemIt->next();
1714 for ( i = 0; ( i < nb && !isIn ); ++i )
1715 isIn = toolGroupVec[i]->Contains( e );
1718 resGroupDS->SMDSGroup().Add( e );
1721 // Update Python script
1722 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1723 << ".CutListOfGroups( " << theMainGroups << ", "
1724 << theToolGroups << ", '" << theName << "' )";
1726 SMESH_CATCH( SMESH::throwCorbaException );
1728 return aResGrp._retn();
1731 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1733 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1734 bool & toStopChecking )
1736 toStopChecking = ( nbCommon < nbChecked );
1737 return nbCommon == nbNodes;
1739 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1740 bool & toStopChecking )
1742 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1743 return nbCommon == nbCorners;
1745 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1746 bool & toStopChecking )
1748 return nbCommon > 0;
1750 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1751 bool & toStopChecking )
1753 return nbCommon >= (nbNodes+1) / 2;
1757 //=============================================================================
1759 * Create a group of entities basing on nodes of other groups.
1760 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1761 * \param [in] anElemType - a type of elements to include to the new group.
1762 * \param [in] theName - a name of the new group.
1763 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1764 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1765 * new group provided that it is based on nodes of an element of \a aListOfGroups
1766 * \return SMESH_Group - the created group
1768 // IMP 19939, bug 22010, IMP 22635
1769 //=============================================================================
1771 SMESH::SMESH_Group_ptr
1772 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1773 SMESH::ElementType theElemType,
1774 const char* theName,
1775 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1776 CORBA::Boolean theUnderlyingOnly)
1777 throw (SALOME::SALOME_Exception)
1779 SMESH::SMESH_Group_var aResGrp;
1783 _preMeshInfo->FullLoadFromFile();
1785 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1787 if ( !theName || !aMeshDS )
1788 return SMESH::SMESH_Group::_nil();
1790 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1792 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1793 SMESH_Comment nbCoNoStr( "SMESH.");
1794 switch ( theNbCommonNodes ) {
1795 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1796 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1797 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1798 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1799 default: return aResGrp._retn();
1801 int nbChecked, nbCommon, nbNodes, nbCorners;
1807 aResGrp = CreateGroup( theElemType, theName );
1808 if ( aResGrp->_is_nil() )
1809 return SMESH::SMESH_Group::_nil();
1811 SMESHDS_GroupBase* groupBaseDS =
1812 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1813 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1815 vector<bool> isNodeInGroups;
1817 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1819 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1820 if ( CORBA::is_nil( aGrp ) )
1822 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1823 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1826 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1827 if ( !elIt ) continue;
1829 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1831 while ( elIt->more() ) {
1832 const SMDS_MeshElement* el = elIt->next();
1833 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1834 while ( nIt->more() )
1835 resGroupCore.Add( nIt->next() );
1838 // get elements of theElemType based on nodes of every element of group
1839 else if ( theUnderlyingOnly )
1841 while ( elIt->more() )
1843 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1844 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1845 TIDSortedElemSet checkedElems;
1846 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1847 while ( nIt->more() )
1849 const SMDS_MeshNode* n = nIt->next();
1850 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1851 // check nodes of elements of theElemType around el
1852 while ( elOfTypeIt->more() )
1854 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1855 if ( !checkedElems.insert( elOfType ).second ) continue;
1856 nbNodes = elOfType->NbNodes();
1857 nbCorners = elOfType->NbCornerNodes();
1859 bool toStopChecking = false;
1860 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1861 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1862 if ( elNodes.count( nIt2->next() ) &&
1863 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1865 resGroupCore.Add( elOfType );
1872 // get all nodes of elements of groups
1875 while ( elIt->more() )
1877 const SMDS_MeshElement* el = elIt->next(); // an element of group
1878 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1879 while ( nIt->more() )
1881 const SMDS_MeshNode* n = nIt->next();
1882 if ( n->GetID() >= (int) isNodeInGroups.size() )
1883 isNodeInGroups.resize( n->GetID() + 1, false );
1884 isNodeInGroups[ n->GetID() ] = true;
1890 // Get elements of theElemType based on a certain number of nodes of elements of groups
1891 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1893 const SMDS_MeshNode* n;
1894 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1895 const int isNodeInGroupsSize = isNodeInGroups.size();
1896 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1898 if ( !isNodeInGroups[ iN ] ||
1899 !( n = aMeshDS->FindNode( iN )))
1902 // check nodes of elements of theElemType around n
1903 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1904 while ( elOfTypeIt->more() )
1906 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1907 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1912 nbNodes = elOfType->NbNodes();
1913 nbCorners = elOfType->NbCornerNodes();
1915 bool toStopChecking = false;
1916 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1917 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1919 const int nID = nIt->next()->GetID();
1920 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1921 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1923 resGroupCore.Add( elOfType );
1931 // Update Python script
1932 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1933 << ".CreateDimGroup( "
1934 << theGroups << ", " << theElemType << ", '" << theName << "', "
1935 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1937 SMESH_CATCH( SMESH::throwCorbaException );
1939 return aResGrp._retn();
1942 //================================================================================
1944 * \brief Distribute all faces of the mesh between groups using sharp edges and optionally
1945 * existing 1D elements as group boundaries.
1946 * \param [in] theSharpAngle - edge is considered sharp if an angle between normals of
1947 * adjacent faces is more than \a sharpAngle in degrees.
1948 * \param [in] theCreateEdges - to create 1D elements for detected sharp edges.
1949 * \param [in] theUseExistingEdges - to use existing edges as group boundaries
1950 * \return ListOfGroups - the created groups
1952 //================================================================================
1954 SMESH::ListOfGroups*
1955 SMESH_Mesh_i::FaceGroupsSeparatedByEdges( CORBA::Double theSharpAngle,
1956 CORBA::Boolean theCreateEdges,
1957 CORBA::Boolean theUseExistingEdges )
1958 throw (SALOME::SALOME_Exception)
1960 if ( theSharpAngle < 0 || theSharpAngle > 180 )
1961 THROW_SALOME_CORBA_EXCEPTION("Invalid sharp angle, it must be between 0 and 180 degrees",
1964 SMESH::ListOfGroups_var resultGroups = new SMESH::ListOfGroups;
1970 _preMeshInfo->FullLoadFromFile();
1972 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1974 std::vector< SMESH_MeshAlgos::Edge > edges =
1975 SMESH_MeshAlgos::FindSharpEdges( meshDS, theSharpAngle, theUseExistingEdges );
1977 if ( theCreateEdges )
1979 std::vector<const SMDS_MeshNode *> nodes(2);
1980 for ( size_t i = 0; i < edges.size(); ++i )
1982 nodes[0] = edges[i]._node1;
1983 nodes[1] = edges[i]._node2;
1984 if ( meshDS->FindElement( nodes, SMDSAbs_Edge ))
1986 if ( edges[i]._medium )
1987 meshDS->AddEdge( edges[i]._node1, edges[i]._node2, edges[i]._medium );
1989 meshDS->AddEdge( edges[i]._node1, edges[i]._node2 );
1993 std::vector< std::vector< const SMDS_MeshElement* > > faceGroups =
1994 SMESH_MeshAlgos::SeparateFacesByEdges( meshDS, edges );
1996 SMESH::SMESH_MeshEditor_var editor = GetMeshEditor(); // create _editor
1998 resultGroups->length( faceGroups.size() );
1999 for ( size_t iG = 0; iG < faceGroups.size(); ++iG )
2001 SMESH::SMESH_Group_var group = CreateGroup( SMESH::FACE,
2002 _editor->GenerateGroupName("Group").c_str());
2003 resultGroups[iG] = SMESH::SMESH_Group::_duplicate( group );
2005 SMESHDS_GroupBase* groupBaseDS =
2006 SMESH::DownCast<SMESH_GroupBase_i*>( group )->GetGroupDS();
2007 SMDS_MeshGroup& groupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
2009 std::vector< const SMDS_MeshElement* >& faces = faceGroups[ iG ];
2010 for ( size_t i = 0; i < faces.size(); ++i )
2011 groupCore.Add( faces[i] );
2014 pyDump << resultGroups << " = " << SMESH::SMESH_Mesh_var(_this())
2015 << ".FaceGroupsSeparatedByEdges( "
2016 << TVar( theSharpAngle ) << ", "
2017 << theCreateEdges << ", "
2018 << theUseExistingEdges << " )";
2020 SMESH_CATCH( SMESH::throwCorbaException );
2021 return resultGroups._retn();
2025 //================================================================================
2027 * \brief Remember GEOM group data
2029 //================================================================================
2031 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
2032 CORBA::Object_ptr theSmeshObj)
2034 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
2037 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
2038 if ( groupSO->_is_nil() )
2041 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( theGeomObj );
2042 GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations();
2043 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
2046 _geomGroupData.push_back( TGeomGroupData() );
2047 TGeomGroupData & groupData = _geomGroupData.back();
2049 CORBA::String_var entry = groupSO->GetID();
2050 groupData._groupEntry = entry.in();
2052 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2053 groupData._indices.insert( ids[i] );
2055 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
2056 // shape index in SMESHDS
2057 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
2058 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
2061 //================================================================================
2063 * Remove GEOM group data relating to removed smesh object
2065 //================================================================================
2067 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
2069 list<TGeomGroupData>::iterator
2070 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2071 for ( ; data != dataEnd; ++data ) {
2072 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
2073 _geomGroupData.erase( data );
2079 //================================================================================
2081 * \brief Return new group contents if it has been changed and update group data
2083 //================================================================================
2084 enum { ONLY_IF_CHANGED, IS_BREAK_LINK, MAIN_TRANSFORMED };
2086 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData, int how )
2088 TopoDS_Shape newShape;
2090 if ( how == IS_BREAK_LINK )
2092 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( groupData._smeshObject );
2093 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2094 if ( !meshSO->_is_nil() &&
2095 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2096 geomRefSO->ReferencedObject( geomSO.inout() ))
2098 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2099 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2100 if ( geom->_is_nil() ) return newShape;
2101 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( geom );
2102 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geom );
2104 if ( GEOM_Client* geomClient = _gen_i->GetShapeReader() )
2105 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
2106 newShape = _gen_i->GeomObjectToShape( geom );
2107 if ( !newShape.IsNull() )
2109 CORBA::String_var entry = geom->GetStudyEntry();
2110 groupData._groupEntry = entry.in();
2117 SALOMEDS::SObject_wrap groupSO = SMESH_Gen_i::getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
2118 if ( !groupSO->_is_nil() )
2120 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
2121 if ( CORBA::is_nil( groupObj )) return newShape;
2122 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
2124 // get indices of group items
2125 set<int> curIndices;
2126 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( geomGroup );
2127 GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations();
2128 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
2129 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2130 curIndices.insert( ids[i] );
2132 if ( how == ONLY_IF_CHANGED && groupData._indices == curIndices )
2133 return newShape; // group not changed
2136 groupData._indices = curIndices;
2138 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2139 if ( !geomClient ) return newShape;
2140 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
2141 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
2142 newShape = _gen_i->GeomObjectToShape( geomGroup );
2145 if ( newShape.IsNull() ) {
2146 // geom group becomes empty - return empty compound
2147 TopoDS_Compound compound;
2148 BRep_Builder().MakeCompound(compound);
2149 newShape = compound;
2156 //-----------------------------------------------------------------------------
2158 * \brief Storage of shape and index used in CheckGeomGroupModif()
2160 struct TIndexedShape
2163 TopoDS_Shape _shape;
2164 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
2166 //-----------------------------------------------------------------------------
2168 * \brief Data to re-create a group on geometry
2170 struct TGroupOnGeomData
2173 TopoDS_Shape _shape;
2174 SMDSAbs_ElementType _type;
2176 Quantity_Color _color;
2178 TGroupOnGeomData( const SMESHDS_GroupOnGeom* group )
2180 _oldID = group->GetID();
2181 _type = group->GetType();
2182 _name = group->GetStoreName();
2183 _color = group->GetColor();
2187 //-----------------------------------------------------------------------------
2189 * \brief Check if a filter is still valid after geometry removal
2191 bool isValidGeomFilter( SMESH::Filter_var theFilter )
2193 if ( theFilter->_is_nil() )
2195 SMESH::Filter::Criteria_var criteria;
2196 theFilter->GetCriteria( criteria.out() );
2198 for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr )
2200 const char* thresholdID = criteria[ iCr ].ThresholdID.in();
2202 switch ( criteria[ iCr ].Type )
2204 case SMESH::FT_BelongToGeom:
2205 case SMESH::FT_BelongToPlane:
2206 case SMESH::FT_BelongToCylinder:
2207 case SMESH::FT_BelongToGenSurface:
2208 case SMESH::FT_LyingOnGeom:
2209 entry = thresholdID;
2211 case SMESH::FT_ConnectedElements:
2214 entry = thresholdID;
2220 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
2221 SALOMEDS::SObject_wrap so = gen->getStudyServant()->FindObjectID( entry.c_str() );
2222 if ( so->_is_nil() )
2224 CORBA::Object_var obj = so->GetObject();
2225 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( obj );
2226 if ( gen->GeomObjectToShape( geom ).IsNull() )
2229 } // loop on criteria
2235 //=============================================================================
2237 * \brief Update data if geometry changes
2241 //=============================================================================
2243 void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink )
2245 SMESH::SMESH_Mesh_var me = _this();
2246 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2248 TPythonDump dumpNothing; // prevent any dump
2250 //bool removedFromClient = false;
2252 if ( mainGO->_is_nil() ) // GEOM_Client cleared or geometry removed? (IPAL52735, PAL23636)
2254 //removedFromClient = _impl->HasShapeToMesh();
2256 // try to find geometry by study reference
2257 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2258 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2259 if ( !meshSO->_is_nil() &&
2260 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2261 geomRefSO->ReferencedObject( geomSO.inout() ))
2263 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2264 mainGO = GEOM::GEOM_Object::_narrow( geomObj );
2267 if ( mainGO->_is_nil() && // geometry removed ==>
2268 !geomRefSO->_is_nil() ) // remove geom dependent data: sub-meshes etc.
2270 // convert geom dependent groups into standalone ones
2271 CheckGeomGroupModif();
2273 _impl->ShapeToMesh( TopoDS_Shape() );
2275 // remove sub-meshes
2276 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2277 while ( i_sm != _mapSubMeshIor.end() )
2279 SMESH::SMESH_subMesh_ptr sm = i_sm->second;
2281 RemoveSubMesh( sm );
2283 // remove all children except groups in the study
2284 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2285 SALOMEDS::SObject_wrap so;
2286 for ( CORBA::Long tag = SMESH::Tag_RefOnShape; tag <= SMESH::Tag_LastSubMesh; ++tag )
2287 if ( meshSO->FindSubObject( tag, so.inout() ))
2288 builder->RemoveObjectWithChildren( so );
2290 _gen_i->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED" );
2296 if ( !_impl->HasShapeToMesh() ) return;
2299 // Update after group modification
2301 if ( mainGO->GetType() == GEOM_GROUP || // is group or not modified
2302 mainGO->GetTick() == _mainShapeTick )
2304 int nb = NbNodes() + NbElements();
2305 CheckGeomGroupModif();
2306 if ( nb != NbNodes() + NbElements() ) // something removed due to hypotheses change
2307 _gen_i->UpdateIcons( me );
2311 // Update after shape modification
2313 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2314 if ( !geomClient ) return;
2315 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( mainGO );
2316 if ( geomGen->_is_nil() ) return;
2317 CORBA::String_var geomComponentType = geomGen->ComponentDataType();
2318 bool isShaper = ( strcmp( geomComponentType.in(), "SHAPERSTUDY" ) == 0 );
2320 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2321 geomClient->RemoveShapeFromBuffer( ior.in() );
2323 // Update data taking into account that if topology doesn't change
2324 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2327 _preMeshInfo->ForgetAllData();
2330 if ( isBreakLink || !isShaper )
2332 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2333 if ( newShape.IsNull() )
2336 _mainShapeTick = mainGO->GetTick();
2338 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2340 // store data of groups on geometry
2341 std::vector< TGroupOnGeomData > groupsData;
2342 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2343 groupsData.reserve( groups.size() );
2344 TopTools_DataMapOfShapeShape old2newShapeMap;
2345 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2346 for ( ; g != groups.end(); ++g )
2348 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2350 groupsData.push_back( TGroupOnGeomData( group ));
2353 SMESH::SMESH_GroupOnGeom_var gog;
2354 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.find( group->GetID() );
2355 if ( i_grp != _mapGroups.end() )
2356 gog = SMESH::SMESH_GroupOnGeom::_narrow( i_grp->second );
2358 GEOM::GEOM_Object_var geom;
2359 if ( !gog->_is_nil() )
2363 SALOMEDS::SObject_wrap grpSO = _gen_i->ObjectToSObject( gog );
2364 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2365 if ( !grpSO->_is_nil() &&
2366 grpSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2367 geomRefSO->ReferencedObject( geomSO.inout() ))
2369 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2370 geom = GEOM::GEOM_Object::_narrow( geomObj );
2375 geom = gog->GetShape();
2378 if ( !geom->_is_nil() )
2380 CORBA::String_var ior = geomGen->GetStringFromIOR( geom );
2381 geomClient->RemoveShapeFromBuffer( ior.in() );
2382 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2383 old2newShapeMap.Bind( group->GetShape(), groupsData.back()._shape );
2385 else if ( old2newShapeMap.IsBound( group->GetShape() ))
2387 groupsData.back()._shape = old2newShapeMap( group->GetShape() );
2391 // store assigned hypotheses
2392 std::vector< pair< int, THypList > > ids2Hyps;
2393 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2394 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2396 const TopoDS_Shape& s = s2hyps.Key();
2397 const THypList& hyps = s2hyps.ChangeValue();
2398 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2401 std::multimap< std::set<int>, int > ii2iMap; // group sub-ids to group id in SMESHDS
2403 // count shapes excluding compounds corresponding to geom groups
2404 int oldNbSubShapes = meshDS->MaxShapeIndex();
2405 for ( ; oldNbSubShapes > 0; --oldNbSubShapes )
2407 const TopoDS_Shape& s = meshDS->IndexToShape( oldNbSubShapes );
2408 if ( s.IsNull() || s.ShapeType() != TopAbs_COMPOUND )
2411 std::set<int> subIds;
2412 for ( TopoDS_Iterator it( s ); it.More(); it.Next() )
2413 subIds.insert( meshDS->ShapeToIndex( it.Value() ));
2414 ii2iMap.insert( std::make_pair( subIds, oldNbSubShapes ));
2417 // check if shape topology changes - save shape type per shape ID
2418 std::vector< TopAbs_ShapeEnum > shapeTypes( Max( oldNbSubShapes + 1, 1 ));
2419 for ( int shapeID = oldNbSubShapes; shapeID > 0; --shapeID )
2420 shapeTypes[ shapeID ] = meshDS->IndexToShape( shapeID ).ShapeType();
2422 // change shape to mesh
2423 _impl->ShapeToMesh( TopoDS_Shape() );
2424 _impl->ShapeToMesh( newShape );
2426 // check if shape topology changes - check new shape types
2427 bool sameTopology = ( oldNbSubShapes == meshDS->MaxShapeIndex() );
2428 for ( int shapeID = oldNbSubShapes; shapeID > 0 && sameTopology; --shapeID )
2430 const TopoDS_Shape& s = meshDS->IndexToShape( shapeID );
2431 sameTopology = ( !s.IsNull() && s.ShapeType() == shapeTypes[ shapeID ]);
2434 // re-add shapes (compounds) of geom groups
2435 std::map< int, int > old2newIDs; // group IDs
2436 std::list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2437 for ( ; data != _geomGroupData.end(); ++data )
2440 std::multimap< std::set<int>, int >::iterator ii2i = ii2iMap.find( data->_indices );
2441 if ( ii2i != ii2iMap.end() )
2443 oldID = ii2i->second;
2444 ii2iMap.erase( ii2i );
2446 if ( !oldID && data->_indices.size() == 1 )
2447 oldID = *data->_indices.begin();
2448 if ( old2newIDs.count( oldID ))
2451 int how = ( isBreakLink || !sameTopology ) ? IS_BREAK_LINK : MAIN_TRANSFORMED;
2452 newShape = newGroupShape( *data, how );
2453 if ( !newShape.IsNull() )
2455 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2457 TopoDS_Compound compound;
2458 BRep_Builder().MakeCompound( compound );
2459 BRep_Builder().Add( compound, newShape );
2460 newShape = compound;
2462 int newID = _impl->GetSubMesh( newShape )->GetId();
2463 if ( oldID /*&& oldID != newID*/ )
2464 old2newIDs.insert( std::make_pair( oldID, newID ));
2465 if ( data->_indices.size() == 1 )
2467 oldID = *data->_indices.begin();
2468 old2newIDs.insert( std::make_pair( oldID, newID ));
2473 // re-assign hypotheses
2474 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2476 int sID = ids2Hyps[i].first;
2477 std::map< int, int >::iterator o2n = old2newIDs.find( sID );
2478 if ( o2n != old2newIDs.end() )
2480 else if ( !sameTopology && sID != 1 )
2482 const TopoDS_Shape& s = meshDS->IndexToShape( sID );
2485 const THypList& hyps = ids2Hyps[i].second;
2486 THypList::const_iterator h = hyps.begin();
2487 for ( ; h != hyps.end(); ++h )
2488 _impl->AddHypothesis( s, (*h)->GetID() );
2492 // restore groups on geometry
2493 for ( size_t i = 0; i < groupsData.size(); ++i )
2495 const TGroupOnGeomData& data = groupsData[i];
2496 if ( data._shape.IsNull() )
2499 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2500 if ( i2g == _mapGroups.end() ) continue;
2502 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2503 if ( !gr_i ) continue;
2505 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape );
2507 _mapGroups.erase( i2g );
2509 g->GetGroupDS()->SetColor( data._color );
2512 if ( !sameTopology )
2514 std::map< int, int >::iterator o2n = old2newIDs.begin();
2515 for ( ; o2n != old2newIDs.end(); ++o2n )
2517 int newID = o2n->second, oldID = o2n->first;
2518 if ( newID == oldID || !_mapSubMesh.count( oldID ))
2522 _mapSubMesh [ newID ] = _impl->GetSubMeshContaining( newID );
2523 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2524 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2526 _mapSubMesh. erase(oldID);
2527 _mapSubMesh_i. erase(oldID);
2528 _mapSubMeshIor.erase(oldID);
2530 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2534 // update _mapSubMesh
2535 std::map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2536 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2537 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2540 if ( !sameTopology )
2542 // remove invalid study sub-objects
2543 CheckGeomGroupModif();
2546 _gen_i->UpdateIcons( me );
2548 if ( !isBreakLink && isShaper )
2550 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2551 if ( !meshSO->_is_nil() )
2552 _gen_i->SetPixMap(meshSO, "ICON_SMESH_TREE_GEOM_MODIF");
2556 //=============================================================================
2558 * \brief Update objects depending on changed geom groups
2560 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2561 * issue 0020210: Update of a smesh group after modification of the associated geom group
2563 //=============================================================================
2565 void SMESH_Mesh_i::CheckGeomGroupModif()
2567 // remove sub-meshes referring a removed sub-shapes (if main shape still exists)
2568 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2569 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2570 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() ));
2571 if ( !mainGO->_is_nil() && !meshSO->_is_nil() )
2573 SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO;
2574 for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag )
2575 if ( meshSO->FindSubObject( tag, rootSO.inout() ))
2577 int nbValid = 0, nbRemoved = 0;
2578 SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO );
2579 for ( ; chItr->More(); chItr->Next() )
2581 SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO
2582 if ( !smSO->_is_nil() &&
2583 smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2584 geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference
2586 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2587 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2588 if ( !geom->_non_existent() )
2591 continue; // keep the sub-mesh
2594 CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO );
2595 SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj );
2596 if ( !sm->_is_nil() && !sm->_non_existent() )
2598 GEOM::GEOM_Object_var smGeom = sm->GetSubShape();
2599 if ( smGeom->_is_nil() )
2601 RemoveSubMesh( sm );
2608 _preMeshInfo->ForgetAllData(); // unknown hypothesis modified
2609 builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH
2613 if ( /*nbRemoved > 0 &&*/ nbValid == 0 )
2614 builder->RemoveObjectWithChildren( rootSO );
2618 // check for removed sub-shapes and convert geom dependent groups into standalone ones
2619 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2620 while ( i_gr != _mapGroups.end())
2622 SMESH::SMESH_GroupBase_ptr group = i_gr->second;
2624 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO;
2625 SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group );
2626 SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group );
2627 bool isValidGeom = false;
2628 if ( !onGeom->_is_nil() )
2630 isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() );
2632 else if ( !onFilt->_is_nil() )
2634 isValidGeom = isValidGeomFilter( onFilt->GetFilter() );
2638 isValidGeom = ( !groupSO->_is_nil() &&
2639 !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ));
2643 if ( !IsLoaded() || group->IsEmpty() )
2645 RemoveGroup( group );
2647 else if ( !onGeom->_is_nil() || !onFilt->_is_nil() )
2649 SMESH::SMESH_Group_var ( ConvertToStandalone( group ));
2651 else // is it possible?
2653 builder->RemoveObjectWithChildren( refSO );
2659 if ( !_impl->HasShapeToMesh() ) return;
2661 CORBA::Long nbEntities = NbNodes() + NbElements();
2663 // Check if group contents changed
2665 typedef map< string, TopoDS_Shape > TEntry2Geom;
2666 TEntry2Geom newGroupContents;
2668 list<TGeomGroupData>::iterator
2669 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2670 for ( ; data != dataEnd; ++data )
2672 pair< TEntry2Geom::iterator, bool > it_new =
2673 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2674 bool processedGroup = !it_new.second;
2675 TopoDS_Shape& newShape = it_new.first->second;
2676 if ( !processedGroup )
2677 newShape = newGroupShape( *data, ONLY_IF_CHANGED );
2678 if ( newShape.IsNull() )
2679 continue; // no changes
2682 _preMeshInfo->ForgetOrLoad();
2684 if ( processedGroup ) { // update group indices
2685 list<TGeomGroupData>::iterator data2 = data;
2686 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2687 data->_indices = data2->_indices;
2690 // Update SMESH objects according to new GEOM group contents
2692 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2693 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2695 int oldID = submesh->GetId();
2696 if ( !_mapSubMeshIor.count( oldID ))
2698 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2700 // update hypotheses
2701 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2702 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2703 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2705 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2706 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2708 // care of submeshes
2709 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2710 int newID = newSubmesh->GetId();
2711 if ( newID != oldID ) {
2712 _mapSubMesh [ newID ] = newSubmesh;
2713 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2714 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2715 _mapSubMesh. erase(oldID);
2716 _mapSubMesh_i. erase(oldID);
2717 _mapSubMeshIor.erase(oldID);
2718 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2723 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2724 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2725 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2727 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2729 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2730 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2731 ds->SetShape( newShape );
2736 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2737 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2739 // Remove groups and submeshes basing on removed sub-shapes
2741 TopTools_MapOfShape newShapeMap;
2742 TopoDS_Iterator shapeIt( newShape );
2743 for ( ; shapeIt.More(); shapeIt.Next() )
2744 newShapeMap.Add( shapeIt.Value() );
2746 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2747 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2749 if ( newShapeMap.Contains( shapeIt.Value() ))
2751 TopTools_IndexedMapOfShape oldShapeMap;
2752 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2753 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2755 const TopoDS_Shape& oldShape = oldShapeMap(i);
2756 int oldInd = meshDS->ShapeToIndex( oldShape );
2758 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2759 if ( i_smIor != _mapSubMeshIor.end() ) {
2760 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2763 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2764 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2766 // check if a group bases on oldInd shape
2767 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2768 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2769 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2770 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2772 RemoveGroup( i_grp->second ); // several groups can base on same shape
2773 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2778 // Reassign hypotheses and update groups after setting the new shape to mesh
2780 // collect anassigned hypotheses
2781 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2782 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2783 TShapeHypList assignedHyps;
2784 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2786 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2787 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2788 if ( !hyps.empty() ) {
2789 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2790 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2791 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2794 // collect shapes supporting groups
2795 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2796 TShapeTypeList groupData;
2797 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2798 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2799 for ( ; grIt != groups.end(); ++grIt )
2801 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2803 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2805 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2807 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2808 _impl->ShapeToMesh( newShape );
2810 // reassign hypotheses
2811 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2812 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2814 TIndexedShape& geom = indS_hyps->first;
2815 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2816 int oldID = geom._index;
2817 int newID = meshDS->ShapeToIndex( geom._shape );
2818 if ( oldID == 1 ) { // main shape
2820 geom._shape = newShape;
2824 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2825 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2826 // care of sub-meshes
2827 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2828 if ( newID != oldID ) {
2829 _mapSubMesh [ newID ] = newSubmesh;
2830 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2831 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2832 _mapSubMesh. erase(oldID);
2833 _mapSubMesh_i. erase(oldID);
2834 _mapSubMeshIor.erase(oldID);
2835 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2839 TShapeTypeList::iterator geomType = groupData.begin();
2840 for ( ; geomType != groupData.end(); ++geomType )
2842 const TIndexedShape& geom = geomType->first;
2843 int oldID = geom._index;
2844 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2847 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2848 CORBA::String_var name = groupSO->GetName();
2850 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
2851 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
2852 /*id=*/-1, geom._shape ))
2853 group_i->changeLocalId( group->GetID() );
2856 break; // everything has been updated
2859 } // loop on group data
2863 CORBA::Long newNbEntities = NbNodes() + NbElements();
2864 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2865 if ( newNbEntities != nbEntities )
2867 // Add all SObjects with icons to soToUpdateIcons
2868 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2870 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2871 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2872 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2874 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2875 i_gr != _mapGroups.end(); ++i_gr ) // groups
2876 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2879 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2880 for ( ; so != soToUpdateIcons.end(); ++so )
2881 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2884 //=============================================================================
2886 * \brief Create standalone group from a group on geometry or filter
2888 //=============================================================================
2890 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2891 throw (SALOME::SALOME_Exception)
2893 SMESH::SMESH_Group_var aGroup;
2898 _preMeshInfo->FullLoadFromFile();
2900 if ( theGroup->_is_nil() )
2901 return aGroup._retn();
2903 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2905 return aGroup._retn();
2907 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2909 const int anId = aGroupToRem->GetLocalID();
2910 if ( !_impl->ConvertToStandalone( anId ) )
2911 return aGroup._retn();
2912 removeGeomGroupData( theGroup );
2914 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2916 // remove old instance of group from own map
2917 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2918 _mapGroups.erase( anId );
2920 SALOMEDS::StudyBuilder_var builder;
2921 SALOMEDS::SObject_wrap aGroupSO;
2922 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2923 if ( !aStudy->_is_nil() ) {
2924 builder = aStudy->NewBuilder();
2925 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2926 if ( !aGroupSO->_is_nil() )
2928 // remove reference to geometry
2929 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2930 for ( ; chItr->More(); chItr->Next() )
2932 // Remove group's child SObject
2933 SALOMEDS::SObject_wrap so = chItr->Value();
2934 builder->RemoveObject( so );
2936 // Update Python script
2937 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2938 << ".ConvertToStandalone( " << aGroupSO << " )";
2940 // change icon of Group on Filter
2943 // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2944 // const int isEmpty = ( elemTypes->length() == 0 );
2947 SALOMEDS::GenericAttribute_wrap anAttr =
2948 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2949 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2950 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2956 // remember new group in own map
2957 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2958 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2960 // register CORBA object for persistence
2961 _gen_i->RegisterObject( aGroup );
2963 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2964 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2965 //aGroup->Register();
2966 aGroupToRem->UnRegister();
2968 SMESH_CATCH( SMESH::throwCorbaException );
2970 return aGroup._retn();
2973 //=============================================================================
2977 //=============================================================================
2979 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2981 if(MYDEBUG) MESSAGE( "createSubMesh" );
2982 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2983 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2986 SMESH_subMesh_i * subMeshServant;
2989 subMeshId = mySubMesh->GetId();
2990 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2992 else // "invalid sub-mesh"
2994 // The invalid sub-mesh is created for the case where a valid sub-shape not found
2995 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
2996 if ( _mapSubMesh.empty() )
2999 subMeshId = _mapSubMesh.begin()->first - 1;
3000 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
3003 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
3005 _mapSubMesh [subMeshId] = mySubMesh;
3006 _mapSubMesh_i [subMeshId] = subMeshServant;
3007 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
3009 subMeshServant->Register();
3011 // register CORBA object for persistence
3012 int nextId = _gen_i->RegisterObject( subMesh );
3013 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
3014 else { nextId = 0; } // avoid "unused variable" warning
3016 // to track changes of GEOM groups
3017 if ( subMeshId > 0 )
3018 addGeomGroupData( theSubShapeObject, subMesh );
3020 return subMesh._retn();
3023 //=======================================================================
3024 //function : getSubMesh
3026 //=======================================================================
3028 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
3030 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
3031 if ( it == _mapSubMeshIor.end() )
3032 return SMESH::SMESH_subMesh::_nil();
3034 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
3037 //=============================================================================
3041 //=============================================================================
3043 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
3044 GEOM::GEOM_Object_ptr theSubShapeObject )
3046 bool isHypChanged = false;
3047 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
3048 return isHypChanged;
3050 const int subMeshId = theSubMesh->GetId();
3052 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
3055 if (( _mapSubMesh.count( subMeshId )) &&
3056 ( sm = _impl->GetSubMeshContaining( subMeshId )))
3058 TopoDS_Shape S = sm->GetSubShape();
3061 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
3062 isHypChanged = !hyps.empty();
3063 if ( isHypChanged && _preMeshInfo )
3064 _preMeshInfo->ForgetOrLoad();
3065 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
3066 for ( ; hyp != hyps.end(); ++hyp )
3067 _impl->RemoveHypothesis(S, (*hyp)->GetID());
3074 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
3075 isHypChanged = ( aHypList->length() > 0 );
3076 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
3077 removeHypothesis( theSubShapeObject, aHypList[i] );
3080 catch( const SALOME::SALOME_Exception& ) {
3081 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
3083 removeGeomGroupData( theSubShapeObject );
3087 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
3088 if ( id_smi != _mapSubMesh_i.end() )
3089 id_smi->second->UnRegister();
3091 // remove a CORBA object
3092 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
3093 if ( id_smptr != _mapSubMeshIor.end() )
3094 SMESH::SMESH_subMesh_var( id_smptr->second );
3096 _mapSubMesh.erase(subMeshId);
3097 _mapSubMesh_i.erase(subMeshId);
3098 _mapSubMeshIor.erase(subMeshId);
3100 return isHypChanged;
3103 //=============================================================================
3107 //=============================================================================
3109 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
3110 const char* theName,
3112 const TopoDS_Shape& theShape,
3113 const SMESH_PredicatePtr& thePredicate )
3115 std::string newName;
3116 if ( !theName || !theName[0] )
3118 std::set< std::string > presentNames;
3119 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
3120 for ( ; i_gr != _mapGroups.end(); ++i_gr )
3122 CORBA::String_var name = i_gr->second->GetName();
3123 presentNames.insert( name.in() );
3126 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
3127 } while ( !presentNames.insert( newName ).second );
3128 theName = newName.c_str();
3130 SMESH::SMESH_GroupBase_var aGroup;
3131 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
3132 theID, theShape, thePredicate ))
3134 int anId = g->GetID();
3135 SMESH_GroupBase_i* aGroupImpl;
3136 if ( !theShape.IsNull() )
3137 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3138 else if ( thePredicate )
3139 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
3141 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3143 aGroup = aGroupImpl->_this();
3144 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3145 aGroupImpl->Register();
3147 // register CORBA object for persistence
3148 int nextId = _gen_i->RegisterObject( aGroup );
3149 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
3150 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
3152 // to track changes of GEOM groups
3153 if ( !theShape.IsNull() ) {
3154 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
3155 addGeomGroupData( geom, aGroup );
3158 return aGroup._retn();
3161 //=============================================================================
3163 * SMESH_Mesh_i::removeGroup
3165 * Should be called by ~SMESH_Group_i()
3167 //=============================================================================
3169 void SMESH_Mesh_i::removeGroup( const int theId )
3171 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
3172 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
3173 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
3174 _mapGroups.erase( theId );
3175 removeGeomGroupData( group );
3176 if ( !_impl->RemoveGroup( theId ))
3178 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
3179 RemoveGroup( group );
3181 group->UnRegister();
3185 //=============================================================================
3189 //=============================================================================
3191 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
3192 throw(SALOME::SALOME_Exception)
3194 SMESH::log_array_var aLog;
3198 _preMeshInfo->FullLoadFromFile();
3200 list < SMESHDS_Command * >logDS = _impl->GetLog();
3201 aLog = new SMESH::log_array;
3203 int lg = logDS.size();
3206 list < SMESHDS_Command * >::iterator its = logDS.begin();
3207 while(its != logDS.end()){
3208 SMESHDS_Command *com = *its;
3209 int comType = com->GetType();
3211 int lgcom = com->GetNumber();
3213 const list < int >&intList = com->GetIndexes();
3214 int inum = intList.size();
3216 list < int >::const_iterator ii = intList.begin();
3217 const list < double >&coordList = com->GetCoords();
3218 int rnum = coordList.size();
3220 list < double >::const_iterator ir = coordList.begin();
3221 aLog[indexLog].commandType = comType;
3222 aLog[indexLog].number = lgcom;
3223 aLog[indexLog].coords.length(rnum);
3224 aLog[indexLog].indexes.length(inum);
3225 for(int i = 0; i < rnum; i++){
3226 aLog[indexLog].coords[i] = *ir;
3227 //MESSAGE(" "<<i<<" "<<ir.Value());
3230 for(int i = 0; i < inum; i++){
3231 aLog[indexLog].indexes[i] = *ii;
3232 //MESSAGE(" "<<i<<" "<<ii.Value());
3241 SMESH_CATCH( SMESH::throwCorbaException );
3243 return aLog._retn();
3247 //=============================================================================
3251 //=============================================================================
3253 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
3257 SMESH_CATCH( SMESH::throwCorbaException );
3260 //=============================================================================
3264 //=============================================================================
3266 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
3271 //=============================================================================
3274 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
3275 // issue 0020918: groups removal is caused by hyp modification
3276 // issue 0021208: to forget not loaded mesh data at hyp modification
3277 struct TCallUp_i : public SMESH_Mesh::TCallUp
3279 SMESH_Mesh_i* _mesh;
3280 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
3281 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
3282 virtual void HypothesisModified( int hypID,
3283 bool updIcons) { _mesh->onHypothesisModified( hypID,
3285 virtual void Load () { _mesh->Load(); }
3286 virtual bool IsLoaded() { return _mesh->IsLoaded(); }
3290 //================================================================================
3292 * \brief callback from _impl to
3293 * 1) forget not loaded mesh data (issue 0021208)
3294 * 2) mark hypothesis as valid
3296 //================================================================================
3298 void SMESH_Mesh_i::onHypothesisModified(int theHypID, bool theUpdateIcons)
3301 _preMeshInfo->ForgetOrLoad();
3303 if ( theUpdateIcons )
3305 SMESH::SMESH_Mesh_var mesh = _this();
3306 _gen_i->UpdateIcons( mesh );
3309 if ( _nbInvalidHypos != 0 )
3311 // mark a hypothesis as valid after edition
3313 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
3314 SALOMEDS::SObject_wrap hypRoot;
3315 if ( !smeshComp->_is_nil() &&
3316 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
3318 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
3319 for ( ; anIter->More(); anIter->Next() )
3321 SALOMEDS::SObject_wrap hypSO = anIter->Value();
3322 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
3323 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
3324 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
3325 _gen_i->HighLightInvalid( hyp, false );
3327 nbInvalid += _gen_i->IsInvalid( hypSO );
3330 _nbInvalidHypos = nbInvalid;
3334 //=============================================================================
3338 //=============================================================================
3340 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
3342 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
3345 _impl->SetCallUp( new TCallUp_i(this));
3348 //=============================================================================
3352 //=============================================================================
3354 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
3356 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
3360 //=============================================================================
3362 * Return mesh editor
3364 //=============================================================================
3366 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
3367 throw (SALOME::SALOME_Exception)
3369 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3373 _preMeshInfo->FullLoadFromFile();
3375 // Create MeshEditor
3377 _editor = new SMESH_MeshEditor_i( this, false );
3378 aMeshEdVar = _editor->_this();
3380 // Update Python script
3381 TPythonDump() << _editor << " = "
3382 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
3384 SMESH_CATCH( SMESH::throwCorbaException );
3386 return aMeshEdVar._retn();
3389 //=============================================================================
3391 * Return mesh edition previewer
3393 //=============================================================================
3395 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
3396 throw (SALOME::SALOME_Exception)
3398 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3402 _preMeshInfo->FullLoadFromFile();
3404 if ( !_previewEditor )
3405 _previewEditor = new SMESH_MeshEditor_i( this, true );
3406 aMeshEdVar = _previewEditor->_this();
3408 SMESH_CATCH( SMESH::throwCorbaException );
3410 return aMeshEdVar._retn();
3413 //================================================================================
3415 * \brief Return true if the mesh has been edited since a last total re-compute
3416 * and those modifications may prevent successful partial re-compute
3418 //================================================================================
3420 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
3422 Unexpect aCatch(SALOME_SalomeException);
3423 return _impl->HasModificationsToDiscard();
3426 //================================================================================
3428 * \brief Returns a random unique color
3430 //================================================================================
3432 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
3434 const int MAX_ATTEMPTS = 100;
3436 double tolerance = 0.5;
3437 SALOMEDS::Color col;
3441 // generate random color
3442 double red = (double)rand() / RAND_MAX;
3443 double green = (double)rand() / RAND_MAX;
3444 double blue = (double)rand() / RAND_MAX;
3445 // check existence in the list of the existing colors
3446 bool matched = false;
3447 std::list<SALOMEDS::Color>::const_iterator it;
3448 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3449 SALOMEDS::Color color = *it;
3450 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3451 matched = tol < tolerance;
3453 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3454 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3462 //=============================================================================
3464 * Sets auto-color mode. If it is on, groups get unique random colors
3466 //=============================================================================
3468 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
3470 Unexpect aCatch(SALOME_SalomeException);
3471 _impl->SetAutoColor(theAutoColor);
3473 TPythonDump pyDump; // not to dump group->SetColor() from below code
3474 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3476 std::list<SALOMEDS::Color> aReservedColors;
3477 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3478 for ( ; it != _mapGroups.end(); it++ ) {
3479 if ( CORBA::is_nil( it->second )) continue;
3480 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3481 it->second->SetColor( aColor );
3482 aReservedColors.push_back( aColor );
3486 //=============================================================================
3488 * Returns true if auto-color mode is on
3490 //=============================================================================
3492 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
3494 Unexpect aCatch(SALOME_SalomeException);
3495 return _impl->GetAutoColor();
3498 //=============================================================================
3500 * Checks if there are groups with equal names
3502 //=============================================================================
3504 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3506 return _impl->HasDuplicatedGroupNamesMED();
3509 //================================================================================
3511 * \brief Care of a file before exporting mesh into it
3513 //================================================================================
3515 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3517 SMESH_File aFile( file, false );
3519 if ( aFile.exists() ) {
3520 // existing filesystem node
3521 if ( !aFile.isDirectory() ) {
3522 if ( aFile.openForWriting() ) {
3523 if ( overwrite && ! aFile.remove()) {
3524 msg << "Can't replace " << aFile.getName();
3527 msg << "Can't write into " << aFile.getName();
3530 msg << "Location " << aFile.getName() << " is not a file";
3534 // nonexisting file; check if it can be created
3535 if ( !aFile.openForWriting() ) {
3536 msg << "You cannot create the file "
3538 << ". Check the directory existence and access rights";
3546 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3550 //================================================================================
3552 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
3553 * \param file - file name
3554 * \param overwrite - to erase the file or not
3555 * \retval string - mesh name
3557 //================================================================================
3559 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3560 CORBA::Boolean overwrite)
3563 PrepareForWriting(file, overwrite);
3564 string aMeshName = "Mesh";
3565 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3566 if ( !aStudy->_is_nil() ) {
3567 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3568 if ( !aMeshSO->_is_nil() ) {
3569 CORBA::String_var name = aMeshSO->GetName();
3571 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3572 if ( !aStudy->GetProperties()->IsLocked() )
3574 SALOMEDS::GenericAttribute_wrap anAttr;
3575 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3576 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3577 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3578 ASSERT(!aFileName->_is_nil());
3579 aFileName->SetValue(file);
3580 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3581 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3582 ASSERT(!aFileType->_is_nil());
3583 aFileType->SetValue("FICHIERMED");
3587 // Update Python script
3588 // set name of mesh before export
3589 TPythonDump() << _gen_i << ".SetName("
3590 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3592 // check names of groups
3598 //================================================================================
3600 * \brief Export to MED file
3602 //================================================================================
3604 void SMESH_Mesh_i::ExportMED(const char* file,
3605 CORBA::Boolean auto_groups,
3606 CORBA::Long version,
3607 CORBA::Boolean overwrite,
3608 CORBA::Boolean autoDimension)
3609 throw(SALOME::SALOME_Exception)
3611 //MESSAGE("MED minor version: "<< minor);
3614 _preMeshInfo->FullLoadFromFile();
3616 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3617 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3619 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3621 << "auto_groups=" <<auto_groups << ", "
3622 << "minor=" << version << ", "
3623 << "overwrite=" << overwrite << ", "
3624 << "meshPart=None, "
3625 << "autoDimension=" << autoDimension << " )";
3627 SMESH_CATCH( SMESH::throwCorbaException );
3630 //================================================================================
3632 * \brief Export a mesh to a SAUV file
3634 //================================================================================
3636 void SMESH_Mesh_i::ExportSAUV (const char* file,
3637 CORBA::Boolean auto_groups)
3638 throw(SALOME::SALOME_Exception)
3640 Unexpect aCatch(SALOME_SalomeException);
3642 _preMeshInfo->FullLoadFromFile();
3644 string aMeshName = prepareMeshNameAndGroups(file, true);
3645 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3646 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3647 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3651 //================================================================================
3653 * \brief Export a mesh to a DAT file
3655 //================================================================================
3657 void SMESH_Mesh_i::ExportDAT (const char *file)
3658 throw(SALOME::SALOME_Exception)
3660 Unexpect aCatch(SALOME_SalomeException);
3662 _preMeshInfo->FullLoadFromFile();
3664 // Update Python script
3665 // check names of groups
3667 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3670 PrepareForWriting(file);
3671 _impl->ExportDAT(file);
3674 //================================================================================
3676 * \brief Export a mesh to an UNV file
3678 //================================================================================
3680 void SMESH_Mesh_i::ExportUNV (const char *file)
3681 throw(SALOME::SALOME_Exception)
3683 Unexpect aCatch(SALOME_SalomeException);
3685 _preMeshInfo->FullLoadFromFile();
3687 // Update Python script
3688 // check names of groups
3690 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3693 PrepareForWriting(file);
3694 _impl->ExportUNV(file);
3697 //================================================================================
3699 * \brief Export a mesh to an STL file
3701 //================================================================================
3703 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3704 throw(SALOME::SALOME_Exception)
3706 Unexpect aCatch(SALOME_SalomeException);
3708 _preMeshInfo->FullLoadFromFile();
3710 // Update Python script
3711 // check names of groups
3713 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3714 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3716 CORBA::String_var name;
3717 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3718 if ( !so->_is_nil() )
3719 name = so->GetName();
3722 PrepareForWriting( file );
3723 _impl->ExportSTL( file, isascii, name.in() );
3726 //================================================================================
3728 * \brief Export a part of mesh to a med file
3730 //================================================================================
3732 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3734 CORBA::Boolean auto_groups,
3735 CORBA::Long version,
3736 CORBA::Boolean overwrite,
3737 CORBA::Boolean autoDimension,
3738 const GEOM::ListOfFields& fields,
3739 const char* geomAssocFields,
3740 CORBA::Double ZTolerance)
3741 throw (SALOME::SALOME_Exception)
3743 MESSAGE("MED version: "<< version);
3746 _preMeshInfo->FullLoadFromFile();
3749 bool have0dField = false;
3750 if ( fields.length() > 0 )
3752 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3753 if ( shapeToMesh->_is_nil() )
3754 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3756 for ( size_t i = 0; i < fields.length(); ++i )
3758 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3759 THROW_SALOME_CORBA_EXCEPTION
3760 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3761 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3762 if ( fieldShape->_is_nil() )
3763 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3764 if ( !fieldShape->IsSame( shapeToMesh ) )
3765 THROW_SALOME_CORBA_EXCEPTION
3766 ( "Field defined not on shape", SALOME::BAD_PARAM);
3767 if ( fields[i]->GetDimension() == 0 )
3770 if ( geomAssocFields )
3771 for ( int i = 0; geomAssocFields[i]; ++i )
3772 switch ( geomAssocFields[i] ) {
3773 case 'v':case 'e':case 'f':case 's': break;
3774 case 'V':case 'E':case 'F':case 'S': break;
3775 default: THROW_SALOME_CORBA_EXCEPTION
3776 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3780 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3784 string aMeshName = "Mesh";
3785 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3786 if ( CORBA::is_nil( meshPart ) ||
3787 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3789 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3790 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3791 0, autoDimension, /*addODOnVertices=*/have0dField,
3793 meshDS = _impl->GetMeshDS();
3798 _preMeshInfo->FullLoadFromFile();
3800 PrepareForWriting(file, overwrite);
3802 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3803 if ( !SO->_is_nil() ) {
3804 CORBA::String_var name = SO->GetName();
3808 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3809 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3810 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3811 meshDS = tmpDSDeleter._obj = partDS;
3816 if ( _impl->HasShapeToMesh() )
3818 DriverMED_W_Field fieldWriter;
3819 fieldWriter.SetFile( file );
3820 fieldWriter.SetMeshName( aMeshName );
3821 fieldWriter.AddODOnVertices( have0dField );
3823 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3827 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3828 goList->length( fields.length() );
3829 for ( size_t i = 0; i < fields.length(); ++i )
3831 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3834 TPythonDump() << _this() << ".ExportPartToMED( "
3835 << meshPart << ", r'"
3837 << auto_groups << ", "
3839 << overwrite << ", "
3840 << autoDimension << ", "
3842 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
3843 << TVar( ZTolerance )
3846 SMESH_CATCH( SMESH::throwCorbaException );
3849 //================================================================================
3851 * Write GEOM fields to MED file
3853 //================================================================================
3855 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3856 SMESHDS_Mesh* meshDS,
3857 const GEOM::ListOfFields& fields,
3858 const char* geomAssocFields)
3860 #define METH "SMESH_Mesh_i::exportMEDFields() "
3862 if (( fields.length() < 1 ) &&
3863 ( !geomAssocFields || !geomAssocFields[0] ))
3866 std::vector< std::vector< double > > dblVals;
3867 std::vector< std::vector< int > > intVals;
3868 std::vector< int > subIdsByDim[ 4 ];
3869 const double noneDblValue = 0.;
3870 const double noneIntValue = 0;
3872 for ( size_t iF = 0; iF < fields.length(); ++iF )
3876 int dim = fields[ iF ]->GetDimension();
3877 SMDSAbs_ElementType elemType;
3878 TopAbs_ShapeEnum shapeType;
3880 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3881 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3882 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3883 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3885 continue; // skip fields on whole shape
3887 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3888 if ( dataType == GEOM::FDT_String )
3890 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3891 if ( stepIDs->length() < 1 )
3893 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3894 if ( comps->length() < 1 )
3896 CORBA::String_var name = fields[ iF ]->GetName();
3898 if ( !fieldWriter.Set( meshDS,
3902 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3905 for ( size_t iC = 0; iC < comps->length(); ++iC )
3906 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3908 dblVals.resize( comps->length() );
3909 intVals.resize( comps->length() );
3911 // find sub-shape IDs
3913 std::vector< int >& subIds = subIdsByDim[ dim ];
3914 if ( subIds.empty() )
3915 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3916 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3917 subIds.push_back( id );
3921 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3925 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3927 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3928 if ( step->_is_nil() )
3931 CORBA::Long stamp = step->GetStamp();
3932 CORBA::Long id = step->GetID();
3933 fieldWriter.SetDtIt( int( stamp ), int( id ));
3935 // fill dblVals or intVals
3936 for ( size_t iC = 0; iC < comps->length(); ++iC )
3937 if ( dataType == GEOM::FDT_Double )
3939 dblVals[ iC ].clear();
3940 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3944 intVals[ iC ].clear();
3945 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3949 case GEOM::FDT_Double:
3951 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3952 if ( dblStep->_is_nil() ) continue;
3953 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3954 if ( vv->length() != subIds.size() * comps->length() )
3955 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3956 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3957 for ( size_t iC = 0; iC < comps->length(); ++iC )
3958 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3963 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3964 if ( intStep->_is_nil() ) continue;
3965 GEOM::ListOfLong_var vv = intStep->GetValues();
3966 if ( vv->length() != subIds.size() * comps->length() )
3967 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3968 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3969 for ( size_t iC = 0; iC < comps->length(); ++iC )
3970 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3973 case GEOM::FDT_Bool:
3975 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3976 if ( boolStep->_is_nil() ) continue;
3977 GEOM::short_array_var vv = boolStep->GetValues();
3978 if ( vv->length() != subIds.size() * comps->length() )
3979 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3980 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3981 for ( size_t iC = 0; iC < comps->length(); ++iC )
3982 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3988 // pass values to fieldWriter
3989 elemIt = fieldWriter.GetOrderedElems();
3990 if ( dataType == GEOM::FDT_Double )
3991 while ( elemIt->more() )
3993 const SMDS_MeshElement* e = elemIt->next();
3994 const int shapeID = e->getshapeId();
3995 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3996 for ( size_t iC = 0; iC < comps->length(); ++iC )
3997 fieldWriter.AddValue( noneDblValue );
3999 for ( size_t iC = 0; iC < comps->length(); ++iC )
4000 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
4003 while ( elemIt->more() )
4005 const SMDS_MeshElement* e = elemIt->next();
4006 const int shapeID = e->getshapeId();
4007 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
4008 for ( size_t iC = 0; iC < comps->length(); ++iC )
4009 fieldWriter.AddValue( (double) noneIntValue );
4011 for ( size_t iC = 0; iC < comps->length(); ++iC )
4012 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
4016 fieldWriter.Perform();
4017 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4018 if ( res && res->IsKO() )
4020 if ( res->myComment.empty() )
4021 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4023 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4029 if ( !geomAssocFields || !geomAssocFields[0] )
4032 // write geomAssocFields
4034 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
4035 shapeDim[ TopAbs_COMPOUND ] = 3;
4036 shapeDim[ TopAbs_COMPSOLID ] = 3;
4037 shapeDim[ TopAbs_SOLID ] = 3;
4038 shapeDim[ TopAbs_SHELL ] = 2;
4039 shapeDim[ TopAbs_FACE ] = 2;
4040 shapeDim[ TopAbs_WIRE ] = 1;
4041 shapeDim[ TopAbs_EDGE ] = 1;
4042 shapeDim[ TopAbs_VERTEX ] = 0;
4043 shapeDim[ TopAbs_SHAPE ] = 3;
4045 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
4047 std::vector< std::string > compNames;
4048 switch ( geomAssocFields[ iF ]) {
4050 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
4051 compNames.push_back( "dim" );
4054 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
4057 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
4060 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
4064 compNames.push_back( "id" );
4065 for ( size_t iC = 0; iC < compNames.size(); ++iC )
4066 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
4068 fieldWriter.SetDtIt( -1, -1 );
4070 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
4074 if ( compNames.size() == 2 ) // _vertices_
4075 while ( elemIt->more() )
4077 const SMDS_MeshElement* e = elemIt->next();
4078 const int shapeID = e->getshapeId();
4081 fieldWriter.AddValue( (double) -1 );
4082 fieldWriter.AddValue( (double) -1 );
4086 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
4087 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
4088 fieldWriter.AddValue( (double) shapeID );
4092 while ( elemIt->more() )
4094 const SMDS_MeshElement* e = elemIt->next();
4095 const int shapeID = e->getshapeId();
4097 fieldWriter.AddValue( (double) -1 );
4099 fieldWriter.AddValue( (double) shapeID );
4103 fieldWriter.Perform();
4104 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4105 if ( res && res->IsKO() )
4107 if ( res->myComment.empty() )
4108 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4110 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4113 } // loop on geomAssocFields
4118 //================================================================================
4120 * \brief Export a part of mesh to a DAT file
4122 //================================================================================
4124 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
4126 throw (SALOME::SALOME_Exception)
4128 Unexpect aCatch(SALOME_SalomeException);
4130 _preMeshInfo->FullLoadFromFile();
4132 PrepareForWriting(file);
4134 SMESH_MeshPartDS partDS( meshPart );
4135 _impl->ExportDAT(file,&partDS);
4137 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4138 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
4140 //================================================================================
4142 * \brief Export a part of mesh to an UNV file
4144 //================================================================================
4146 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
4148 throw (SALOME::SALOME_Exception)
4150 Unexpect aCatch(SALOME_SalomeException);
4152 _preMeshInfo->FullLoadFromFile();
4154 PrepareForWriting(file);
4156 SMESH_MeshPartDS partDS( meshPart );
4157 _impl->ExportUNV(file, &partDS);
4159 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4160 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
4162 //================================================================================
4164 * \brief Export a part of mesh to an STL file
4166 //================================================================================
4168 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
4170 ::CORBA::Boolean isascii)
4171 throw (SALOME::SALOME_Exception)
4173 Unexpect aCatch(SALOME_SalomeException);
4175 _preMeshInfo->FullLoadFromFile();
4177 PrepareForWriting(file);
4179 CORBA::String_var name;
4180 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4181 if ( !so->_is_nil() )
4182 name = so->GetName();
4184 SMESH_MeshPartDS partDS( meshPart );
4185 _impl->ExportSTL( file, isascii, name.in(), &partDS );
4187 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
4188 << meshPart<< ", r'" << file << "', " << isascii << ")";
4191 //================================================================================
4193 * \brief Export a part of mesh to an STL file
4195 //================================================================================
4197 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
4199 CORBA::Boolean overwrite,
4200 CORBA::Boolean groupElemsByType)
4201 throw (SALOME::SALOME_Exception)
4204 Unexpect aCatch(SALOME_SalomeException);
4206 _preMeshInfo->FullLoadFromFile();
4208 PrepareForWriting(file,overwrite);
4210 std::string meshName("");
4211 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4212 if ( !so->_is_nil() )
4214 CORBA::String_var name = so->GetName();
4215 meshName = name.in();
4219 SMESH_MeshPartDS partDS( meshPart );
4220 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
4222 SMESH_CATCH( SMESH::throwCorbaException );
4224 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
4225 << meshPart<< ", r'" << file << "', " << overwrite << ")";
4227 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
4231 //================================================================================
4233 * \brief Export a part of mesh to a GMF file
4235 //================================================================================
4237 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
4239 bool withRequiredGroups)
4240 throw (SALOME::SALOME_Exception)
4242 Unexpect aCatch(SALOME_SalomeException);
4244 _preMeshInfo->FullLoadFromFile();
4246 PrepareForWriting(file,/*overwrite=*/true);
4248 SMESH_MeshPartDS partDS( meshPart );
4249 _impl->ExportGMF(file, &partDS, withRequiredGroups);
4251 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
4252 << meshPart<< ", r'"
4254 << withRequiredGroups << ")";
4257 //=============================================================================
4259 * Return computation progress [0.,1]
4261 //=============================================================================
4263 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
4267 return _impl->GetComputeProgress();
4269 SMESH_CATCH( SMESH::doNothing );
4273 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
4275 Unexpect aCatch(SALOME_SalomeException);
4277 return _preMeshInfo->NbNodes();
4279 return _impl->NbNodes();
4282 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
4284 Unexpect aCatch(SALOME_SalomeException);
4286 return _preMeshInfo->NbElements();
4288 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
4291 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
4293 Unexpect aCatch(SALOME_SalomeException);
4295 return _preMeshInfo->Nb0DElements();
4297 return _impl->Nb0DElements();
4300 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
4302 Unexpect aCatch(SALOME_SalomeException);
4304 return _preMeshInfo->NbBalls();
4306 return _impl->NbBalls();
4309 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
4311 Unexpect aCatch(SALOME_SalomeException);
4313 return _preMeshInfo->NbEdges();
4315 return _impl->NbEdges();
4318 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
4319 throw(SALOME::SALOME_Exception)
4321 Unexpect aCatch(SALOME_SalomeException);
4323 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
4325 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
4328 //=============================================================================
4330 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
4332 Unexpect aCatch(SALOME_SalomeException);
4334 return _preMeshInfo->NbFaces();
4336 return _impl->NbFaces();
4339 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
4341 Unexpect aCatch(SALOME_SalomeException);
4343 return _preMeshInfo->NbTriangles();
4345 return _impl->NbTriangles();
4348 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
4350 Unexpect aCatch(SALOME_SalomeException);
4352 return _preMeshInfo->NbBiQuadTriangles();
4354 return _impl->NbBiQuadTriangles();
4357 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
4359 Unexpect aCatch(SALOME_SalomeException);
4361 return _preMeshInfo->NbQuadrangles();
4363 return _impl->NbQuadrangles();
4366 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
4368 Unexpect aCatch(SALOME_SalomeException);
4370 return _preMeshInfo->NbBiQuadQuadrangles();
4372 return _impl->NbBiQuadQuadrangles();
4375 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
4377 Unexpect aCatch(SALOME_SalomeException);
4379 return _preMeshInfo->NbPolygons();
4381 return _impl->NbPolygons();
4384 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
4386 Unexpect aCatch(SALOME_SalomeException);
4388 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
4390 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
4393 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
4394 throw(SALOME::SALOME_Exception)
4396 Unexpect aCatch(SALOME_SalomeException);
4398 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
4400 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
4403 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
4404 throw(SALOME::SALOME_Exception)
4406 Unexpect aCatch(SALOME_SalomeException);
4408 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
4410 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
4413 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
4414 throw(SALOME::SALOME_Exception)
4416 Unexpect aCatch(SALOME_SalomeException);
4418 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
4420 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
4423 //=============================================================================
4425 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
4427 Unexpect aCatch(SALOME_SalomeException);
4429 return _preMeshInfo->NbVolumes();
4431 return _impl->NbVolumes();
4434 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
4436 Unexpect aCatch(SALOME_SalomeException);
4438 return _preMeshInfo->NbTetras();
4440 return _impl->NbTetras();
4443 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
4445 Unexpect aCatch(SALOME_SalomeException);
4447 return _preMeshInfo->NbHexas();
4449 return _impl->NbHexas();
4452 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
4454 Unexpect aCatch(SALOME_SalomeException);
4456 return _preMeshInfo->NbTriQuadHexas();
4458 return _impl->NbTriQuadraticHexas();
4461 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
4463 Unexpect aCatch(SALOME_SalomeException);
4465 return _preMeshInfo->NbPyramids();
4467 return _impl->NbPyramids();
4470 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
4472 Unexpect aCatch(SALOME_SalomeException);
4474 return _preMeshInfo->NbPrisms();
4476 return _impl->NbPrisms();
4479 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
4481 Unexpect aCatch(SALOME_SalomeException);
4483 return _preMeshInfo->NbHexPrisms();
4485 return _impl->NbHexagonalPrisms();
4488 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
4490 Unexpect aCatch(SALOME_SalomeException);
4492 return _preMeshInfo->NbPolyhedrons();
4494 return _impl->NbPolyhedrons();
4497 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4498 throw(SALOME::SALOME_Exception)
4500 Unexpect aCatch(SALOME_SalomeException);
4502 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4504 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4507 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4508 throw(SALOME::SALOME_Exception)
4510 Unexpect aCatch(SALOME_SalomeException);
4512 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4514 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4517 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4518 throw(SALOME::SALOME_Exception)
4520 Unexpect aCatch(SALOME_SalomeException);
4522 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4524 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4527 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4528 throw(SALOME::SALOME_Exception)
4530 Unexpect aCatch(SALOME_SalomeException);
4532 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4534 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4537 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4538 throw(SALOME::SALOME_Exception)
4540 Unexpect aCatch(SALOME_SalomeException);
4542 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4544 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4547 //=============================================================================
4549 * Returns nb of published sub-meshes
4551 //=============================================================================
4553 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4555 Unexpect aCatch(SALOME_SalomeException);
4556 return _mapSubMesh_i.size();
4559 //=============================================================================
4561 * Dumps mesh into a string
4563 //=============================================================================
4565 char* SMESH_Mesh_i::Dump()
4569 return CORBA::string_dup( os.str().c_str() );
4572 //=============================================================================
4574 * Method of SMESH_IDSource interface
4576 //=============================================================================
4578 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4580 return GetElementsId();
4583 //=============================================================================
4585 * Returns ids of all elements
4587 //=============================================================================
4589 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4590 throw (SALOME::SALOME_Exception)
4592 Unexpect aCatch(SALOME_SalomeException);
4594 _preMeshInfo->FullLoadFromFile();
4596 SMESH::long_array_var aResult = new SMESH::long_array();
4597 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4599 if ( aSMESHDS_Mesh == NULL )
4600 return aResult._retn();
4602 long nbElements = NbElements();
4603 aResult->length( nbElements );
4604 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4605 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4606 aResult[i] = anIt->next()->GetID();
4608 return aResult._retn();
4612 //=============================================================================
4614 * Returns ids of all elements of given type
4616 //=============================================================================
4618 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4619 throw (SALOME::SALOME_Exception)
4621 Unexpect aCatch(SALOME_SalomeException);
4623 _preMeshInfo->FullLoadFromFile();
4625 SMESH::long_array_var aResult = new SMESH::long_array();
4626 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4628 if ( aSMESHDS_Mesh == NULL )
4629 return aResult._retn();
4631 long nbElements = NbElements();
4633 // No sense in returning ids of elements along with ids of nodes:
4634 // when theElemType == SMESH::ALL, return node ids only if
4635 // there are no elements
4636 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4637 return GetNodesId();
4639 aResult->length( nbElements );
4643 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4644 while ( i < nbElements && anIt->more() )
4645 aResult[i++] = anIt->next()->GetID();
4647 aResult->length( i );
4649 return aResult._retn();
4652 //=============================================================================
4654 * Returns ids of all nodes
4656 //=============================================================================
4658 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4659 throw (SALOME::SALOME_Exception)
4661 Unexpect aCatch(SALOME_SalomeException);
4663 _preMeshInfo->FullLoadFromFile();
4665 SMESH::long_array_var aResult = new SMESH::long_array();
4666 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4668 if ( aMeshDS == NULL )
4669 return aResult._retn();
4671 long nbNodes = NbNodes();
4672 aResult->length( nbNodes );
4673 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4674 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4675 aResult[i] = anIt->next()->GetID();
4677 return aResult._retn();
4680 //=============================================================================
4684 //=============================================================================
4686 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4687 throw (SALOME::SALOME_Exception)
4689 SMESH::ElementType type = SMESH::ALL;
4693 _preMeshInfo->FullLoadFromFile();
4695 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4697 SMESH_CATCH( SMESH::throwCorbaException );
4702 //=============================================================================
4706 //=============================================================================
4708 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4709 throw (SALOME::SALOME_Exception)
4712 _preMeshInfo->FullLoadFromFile();
4714 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4716 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4718 return ( SMESH::EntityType ) e->GetEntityType();
4721 //=============================================================================
4725 //=============================================================================
4727 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4728 throw (SALOME::SALOME_Exception)
4731 _preMeshInfo->FullLoadFromFile();
4733 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4735 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4737 return ( SMESH::GeometryType ) e->GetGeomType();
4740 //=============================================================================
4742 * Returns ID of elements for given submesh
4744 //=============================================================================
4745 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4746 throw (SALOME::SALOME_Exception)
4748 SMESH::long_array_var aResult = new SMESH::long_array();
4752 _preMeshInfo->FullLoadFromFile();
4754 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4755 if(!SM) return aResult._retn();
4757 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4758 if(!SDSM) return aResult._retn();
4760 aResult->length(SDSM->NbElements());
4762 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4764 while ( eIt->more() ) {
4765 aResult[i++] = eIt->next()->GetID();
4768 SMESH_CATCH( SMESH::throwCorbaException );
4770 return aResult._retn();
4773 //=============================================================================
4775 * Returns ID of nodes for given submesh
4776 * If param all==true - returns all nodes, else -
4777 * returns only nodes on shapes.
4779 //=============================================================================
4781 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4783 throw (SALOME::SALOME_Exception)
4785 SMESH::long_array_var aResult = new SMESH::long_array();
4789 _preMeshInfo->FullLoadFromFile();
4791 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4792 if(!SM) return aResult._retn();
4794 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4795 if(!SDSM) return aResult._retn();
4798 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4799 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4800 while ( nIt->more() ) {
4801 const SMDS_MeshNode* elem = nIt->next();
4802 theElems.insert( elem->GetID() );
4805 else { // all nodes of submesh elements
4806 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4807 while ( eIt->more() ) {
4808 const SMDS_MeshElement* anElem = eIt->next();
4809 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4810 while ( nIt->more() ) {
4811 const SMDS_MeshElement* elem = nIt->next();
4812 theElems.insert( elem->GetID() );
4817 aResult->length(theElems.size());
4818 set<int>::iterator itElem;
4820 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4821 aResult[i++] = *itElem;
4823 SMESH_CATCH( SMESH::throwCorbaException );
4825 return aResult._retn();
4828 //=============================================================================
4830 * Returns type of elements for given submesh
4832 //=============================================================================
4834 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4835 throw (SALOME::SALOME_Exception)
4837 SMESH::ElementType type = SMESH::ALL;
4841 _preMeshInfo->FullLoadFromFile();
4843 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4844 if(!SM) return SMESH::ALL;
4846 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4847 if(!SDSM) return SMESH::ALL;
4849 if(SDSM->NbElements()==0)
4850 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4852 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4853 const SMDS_MeshElement* anElem = eIt->next();
4855 type = ( SMESH::ElementType ) anElem->GetType();
4857 SMESH_CATCH( SMESH::throwCorbaException );
4863 //=============================================================================
4865 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4867 //=============================================================================
4869 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4872 _preMeshInfo->FullLoadFromFile();
4874 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4875 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4880 //=============================================================================
4882 * Get XYZ coordinates of node as list of double
4883 * If there is not node for given ID - returns empty list
4885 //=============================================================================
4887 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4890 _preMeshInfo->FullLoadFromFile();
4892 SMESH::double_array_var aResult = new SMESH::double_array();
4893 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4894 if ( aMeshDS == NULL )
4895 return aResult._retn();
4898 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4900 return aResult._retn();
4904 aResult[0] = aNode->X();
4905 aResult[1] = aNode->Y();
4906 aResult[2] = aNode->Z();
4907 return aResult._retn();
4911 //=============================================================================
4913 * For given node returns list of IDs of inverse elements
4914 * If there is not node for given ID - returns empty list
4916 //=============================================================================
4918 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id,
4919 SMESH::ElementType elemType)
4922 _preMeshInfo->FullLoadFromFile();
4924 SMESH::long_array_var aResult = new SMESH::long_array();
4925 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4926 if ( aMeshDS == NULL )
4927 return aResult._retn();
4930 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
4932 return aResult._retn();
4934 // find inverse elements
4935 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
4936 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
4937 aResult->length( aNode->NbInverseElements( type ));
4938 for( int i = 0; eIt->more(); ++i )
4940 const SMDS_MeshElement* elem = eIt->next();
4941 aResult[ i ] = elem->GetID();
4943 return aResult._retn();
4946 //=============================================================================
4948 * \brief Return position of a node on shape
4950 //=============================================================================
4952 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4955 _preMeshInfo->FullLoadFromFile();
4957 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4958 aNodePosition->shapeID = 0;
4959 aNodePosition->shapeType = GEOM::SHAPE;
4961 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4962 if ( !mesh ) return aNodePosition;
4964 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4966 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4968 aNodePosition->shapeID = aNode->getshapeId();
4969 switch ( pos->GetTypeOfPosition() ) {
4971 aNodePosition->shapeType = GEOM::EDGE;
4972 aNodePosition->params.length(1);
4973 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4975 case SMDS_TOP_FACE: {
4976 SMDS_FacePositionPtr fPos = pos;
4977 aNodePosition->shapeType = GEOM::FACE;
4978 aNodePosition->params.length(2);
4979 aNodePosition->params[0] = fPos->GetUParameter();
4980 aNodePosition->params[1] = fPos->GetVParameter();
4983 case SMDS_TOP_VERTEX:
4984 aNodePosition->shapeType = GEOM::VERTEX;
4986 case SMDS_TOP_3DSPACE:
4987 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4988 aNodePosition->shapeType = GEOM::SOLID;
4989 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4990 aNodePosition->shapeType = GEOM::SHELL;
4996 return aNodePosition;
4999 //=============================================================================
5001 * \brief Return position of an element on shape
5003 //=============================================================================
5005 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
5008 _preMeshInfo->FullLoadFromFile();
5010 SMESH::ElementPosition anElementPosition;
5011 anElementPosition.shapeID = 0;
5012 anElementPosition.shapeType = GEOM::SHAPE;
5014 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
5015 if ( !mesh ) return anElementPosition;
5017 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
5019 anElementPosition.shapeID = anElem->getshapeId();
5020 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
5021 if ( !aSp.IsNull() ) {
5022 switch ( aSp.ShapeType() ) {
5024 anElementPosition.shapeType = GEOM::EDGE;
5027 anElementPosition.shapeType = GEOM::FACE;
5030 anElementPosition.shapeType = GEOM::VERTEX;
5033 anElementPosition.shapeType = GEOM::SOLID;
5036 anElementPosition.shapeType = GEOM::SHELL;
5042 return anElementPosition;
5045 //=============================================================================
5047 * If given element is node returns IDs of shape from position
5048 * If there is not node for given ID - returns -1
5050 //=============================================================================
5052 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
5055 _preMeshInfo->FullLoadFromFile();
5057 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5058 if ( aMeshDS == NULL )
5062 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
5064 return aNode->getshapeId();
5071 //=============================================================================
5073 * For given element returns ID of result shape after
5074 * ::FindShape() from SMESH_MeshEditor
5075 * If there is not element for given ID - returns -1
5077 //=============================================================================
5079 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
5082 _preMeshInfo->FullLoadFromFile();
5084 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5085 if ( aMeshDS == NULL )
5088 // try to find element
5089 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5093 ::SMESH_MeshEditor aMeshEditor(_impl);
5094 int index = aMeshEditor.FindShape( elem );
5102 //=============================================================================
5104 * Returns number of nodes for given element
5105 * If there is not element for given ID - returns -1
5107 //=============================================================================
5109 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
5112 _preMeshInfo->FullLoadFromFile();
5114 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5115 if ( aMeshDS == NULL ) return -1;
5116 // try to find element
5117 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5118 if(!elem) return -1;
5119 return elem->NbNodes();
5123 //=============================================================================
5125 * Returns ID of node by given index for given element
5126 * If there is not element for given ID - returns -1
5127 * If there is not node for given index - returns -2
5129 //=============================================================================
5131 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
5134 _preMeshInfo->FullLoadFromFile();
5136 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5137 if ( aMeshDS == NULL ) return -1;
5138 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5139 if(!elem) return -1;
5140 if( index>=elem->NbNodes() || index<0 ) return -1;
5141 return elem->GetNode(index)->GetID();
5144 //=============================================================================
5146 * Returns IDs of nodes of given element
5148 //=============================================================================
5150 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
5153 _preMeshInfo->FullLoadFromFile();
5155 SMESH::long_array_var aResult = new SMESH::long_array();
5156 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5158 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
5160 aResult->length( elem->NbNodes() );
5161 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5162 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
5163 aResult[ i ] = n->GetID();
5166 return aResult._retn();
5169 //=============================================================================
5171 * Returns true if given node is medium node
5172 * in given quadratic element
5174 //=============================================================================
5176 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
5179 _preMeshInfo->FullLoadFromFile();
5181 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5182 if ( aMeshDS == NULL ) return false;
5184 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5185 if(!aNode) return false;
5186 // try to find element
5187 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
5188 if(!elem) return false;
5190 return elem->IsMediumNode(aNode);
5194 //=============================================================================
5196 * Returns true if given node is medium node
5197 * in one of quadratic elements
5199 //=============================================================================
5201 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
5202 SMESH::ElementType theElemType)
5205 _preMeshInfo->FullLoadFromFile();
5207 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5208 if ( aMeshDS == NULL ) return false;
5211 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5212 if(!aNode) return false;
5214 SMESH_MesherHelper aHelper( *(_impl) );
5216 SMDSAbs_ElementType aType;
5217 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
5218 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
5219 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
5220 else aType = SMDSAbs_All;
5222 return aHelper.IsMedium(aNode,aType);
5226 //=============================================================================
5228 * Returns number of edges for given element
5230 //=============================================================================
5232 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
5235 _preMeshInfo->FullLoadFromFile();
5237 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5238 if ( aMeshDS == NULL ) return -1;
5239 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5240 if(!elem) return -1;
5241 return elem->NbEdges();
5245 //=============================================================================
5247 * Returns number of faces for given element
5249 //=============================================================================
5251 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
5254 _preMeshInfo->FullLoadFromFile();
5256 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5257 if ( aMeshDS == NULL ) return -1;
5258 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5259 if(!elem) return -1;
5260 return elem->NbFaces();
5263 //=======================================================================
5264 //function : GetElemFaceNodes
5265 //purpose : Returns nodes of given face (counted from zero) for given element.
5266 //=======================================================================
5268 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
5269 CORBA::Short faceIndex)
5272 _preMeshInfo->FullLoadFromFile();
5274 SMESH::long_array_var aResult = new SMESH::long_array();
5275 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5277 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
5279 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
5280 if ( faceIndex < vtool.NbFaces() )
5282 aResult->length( vtool.NbFaceNodes( faceIndex ));
5283 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
5284 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5285 aResult[ i ] = nn[ i ]->GetID();
5289 return aResult._retn();
5292 //=======================================================================
5293 //function : GetFaceNormal
5294 //purpose : Returns three components of normal of given mesh face.
5295 //=======================================================================
5297 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
5298 CORBA::Boolean normalized)
5301 _preMeshInfo->FullLoadFromFile();
5303 SMESH::double_array_var aResult = new SMESH::double_array();
5305 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5308 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
5310 aResult->length( 3 );
5311 aResult[ 0 ] = normal.X();
5312 aResult[ 1 ] = normal.Y();
5313 aResult[ 2 ] = normal.Z();
5316 return aResult._retn();
5319 //=======================================================================
5320 //function : FindElementByNodes
5321 //purpose : Returns an element based on all given nodes.
5322 //=======================================================================
5324 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
5327 _preMeshInfo->FullLoadFromFile();
5329 CORBA::Long elemID(0);
5330 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5332 vector< const SMDS_MeshNode * > nn( nodes.length() );
5333 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5334 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
5337 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
5338 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
5339 _impl->NbFaces ( ORDER_QUADRATIC ) ||
5340 _impl->NbVolumes( ORDER_QUADRATIC )))
5341 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
5343 if ( elem ) elemID = CORBA::Long( elem->GetID() );
5348 //================================================================================
5350 * \brief Return elements including all given nodes.
5352 //================================================================================
5354 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
5355 SMESH::ElementType elemType)
5358 _preMeshInfo->FullLoadFromFile();
5360 SMESH::long_array_var result = new SMESH::long_array();
5362 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5364 vector< const SMDS_MeshNode * > nn( nodes.length() );
5365 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5366 nn[i] = mesh->FindNode( nodes[i] );
5368 std::vector<const SMDS_MeshElement *> elems;
5369 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
5370 result->length( elems.size() );
5371 for ( size_t i = 0; i < elems.size(); ++i )
5372 result[i] = elems[i]->GetID();
5374 return result._retn();
5377 //=============================================================================
5379 * Returns true if given element is polygon
5381 //=============================================================================
5383 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
5386 _preMeshInfo->FullLoadFromFile();
5388 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5389 if ( aMeshDS == NULL ) return false;
5390 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5391 if(!elem) return false;
5392 return elem->IsPoly();
5396 //=============================================================================
5398 * Returns true if given element is quadratic
5400 //=============================================================================
5402 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
5405 _preMeshInfo->FullLoadFromFile();
5407 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5408 if ( aMeshDS == NULL ) return false;
5409 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5410 if(!elem) return false;
5411 return elem->IsQuadratic();
5414 //=============================================================================
5416 * Returns diameter of ball discrete element or zero in case of an invalid \a id
5418 //=============================================================================
5420 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
5423 _preMeshInfo->FullLoadFromFile();
5425 if ( const SMDS_BallElement* ball =
5426 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
5427 return ball->GetDiameter();
5432 //=============================================================================
5434 * Returns bary center for given element
5436 //=============================================================================
5438 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5441 _preMeshInfo->FullLoadFromFile();
5443 SMESH::double_array_var aResult = new SMESH::double_array();
5444 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5445 if ( aMeshDS == NULL )
5446 return aResult._retn();
5448 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5450 return aResult._retn();
5452 if(elem->GetType()==SMDSAbs_Volume) {
5453 SMDS_VolumeTool aTool;
5454 if(aTool.Set(elem)) {
5456 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5461 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5463 double x=0., y=0., z=0.;
5464 for(; anIt->more(); ) {
5466 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5480 return aResult._retn();
5483 //================================================================================
5485 * \brief Create a group of elements preventing computation of a sub-shape
5487 //================================================================================
5489 SMESH::ListOfGroups*
5490 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5491 const char* theGroupName )
5492 throw ( SALOME::SALOME_Exception )
5494 Unexpect aCatch(SALOME_SalomeException);
5496 if ( !theGroupName || strlen( theGroupName) == 0 )
5497 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5499 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5500 ::SMESH_MeshEditor::ElemFeatures elemType;
5502 // submesh by subshape id
5503 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5504 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5507 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5508 if ( error && error->HasBadElems() )
5510 // sort bad elements by type
5511 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5512 const list<const SMDS_MeshElement*>& badElems =
5513 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5514 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5515 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5516 for ( ; elemIt != elemEnd; ++elemIt )
5518 const SMDS_MeshElement* elem = *elemIt;
5519 if ( !elem ) continue;
5521 if ( elem->GetID() < 1 )
5523 // elem is a temporary element, make a real element
5524 vector< const SMDS_MeshNode* > nodes;
5525 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5526 while ( nIt->more() && elem )
5528 nodes.push_back( nIt->next() );
5529 if ( nodes.back()->GetID() < 1 )
5530 elem = 0; // a temporary element on temporary nodes
5534 ::SMESH_MeshEditor editor( _impl );
5535 elem = editor.AddElement( nodes, elemType.Init( elem ));
5539 elemsByType[ elem->GetType() ].push_back( elem );
5542 // how many groups to create?
5544 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5545 nbTypes += int( !elemsByType[ i ].empty() );
5546 groups->length( nbTypes );
5549 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5551 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5552 if ( elems.empty() ) continue;
5554 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5555 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5557 SMESH::SMESH_Mesh_var mesh = _this();
5558 SALOMEDS::SObject_wrap aSO =
5559 _gen_i->PublishGroup( mesh, groups[ iG ],
5560 GEOM::GEOM_Object::_nil(), theGroupName);
5562 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5563 if ( !grp_i ) continue;
5565 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5566 for ( size_t iE = 0; iE < elems.size(); ++iE )
5567 grpDS->SMDSGroup().Add( elems[ iE ]);
5572 return groups._retn();
5575 //=============================================================================
5577 * Create and publish group servants if any groups were imported or created anyhow
5579 //=============================================================================
5581 void SMESH_Mesh_i::CreateGroupServants()
5583 SMESH::SMESH_Mesh_var aMesh = _this();
5586 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5587 while ( groupIt->more() )
5589 ::SMESH_Group* group = groupIt->next();
5590 int anId = group->GetID();
5592 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5593 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5595 addedIDs.insert( anId );
5597 SMESH_GroupBase_i* aGroupImpl;
5599 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5600 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5602 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5603 shape = groupOnGeom->GetShape();
5606 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5609 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5610 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5611 aGroupImpl->Register();
5613 // register CORBA object for persistence
5614 int nextId = _gen_i->RegisterObject( groupVar );
5615 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5616 else { nextId = 0; } // avoid "unused variable" warning in release mode
5618 // publishing the groups in the study
5619 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5620 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5622 if ( !addedIDs.empty() )
5625 set<int>::iterator id = addedIDs.begin();
5626 for ( ; id != addedIDs.end(); ++id )
5628 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5629 int i = std::distance( _mapGroups.begin(), it );
5630 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5635 //=============================================================================
5637 * \brief Return true if all sub-meshes are computed OK - to update an icon
5639 //=============================================================================
5641 bool SMESH_Mesh_i::IsComputedOK()
5643 return _impl->IsComputedOK();
5646 //=============================================================================
5648 * \brief Return groups cantained in _mapGroups by their IDs
5650 //=============================================================================
5652 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5654 int nbGroups = groupIDs.size();
5655 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5656 aList->length( nbGroups );
5658 list<int>::const_iterator ids = groupIDs.begin();
5659 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5661 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5662 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5663 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5665 aList->length( nbGroups );
5666 return aList._retn();
5669 //=============================================================================
5671 * \brief Return information about imported file
5673 //=============================================================================
5675 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5677 SMESH::MedFileInfo_var res( _medFileInfo );
5678 if ( !res.operator->() ) {
5679 res = new SMESH::MedFileInfo;
5681 res->fileSize = res->major = res->minor = res->release = -1;
5686 //=======================================================================
5687 //function : FileInfoToString
5688 //purpose : Persistence of file info
5689 //=======================================================================
5691 std::string SMESH_Mesh_i::FileInfoToString()
5694 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5696 s = SMESH_Comment( _medFileInfo->fileSize )
5697 << " " << _medFileInfo->major
5698 << " " << _medFileInfo->minor
5699 << " " << _medFileInfo->release
5700 << " " << _medFileInfo->fileName;
5705 //=======================================================================
5706 //function : FileInfoFromString
5707 //purpose : Persistence of file info
5708 //=======================================================================
5710 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5712 std::string size, major, minor, release, fileName;
5713 std::istringstream is(info);
5714 is >> size >> major >> minor >> release;
5715 fileName = info.data() + ( size.size() + 1 +
5718 release.size()+ 1 );
5720 _medFileInfo = new SMESH::MedFileInfo();
5721 _medFileInfo->fileName = fileName.c_str();
5722 _medFileInfo->fileSize = atoi( size.c_str() );
5723 _medFileInfo->major = atoi( major.c_str() );
5724 _medFileInfo->minor = atoi( minor.c_str() );
5725 _medFileInfo->release = atoi( release.c_str() );
5728 //=============================================================================
5730 * \brief Pass names of mesh groups from study to mesh DS
5732 //=============================================================================
5734 void SMESH_Mesh_i::checkGroupNames()
5736 int nbGrp = NbGroups();
5740 SMESH::ListOfGroups* grpList = 0;
5741 // avoid dump of "GetGroups"
5743 // store python dump into a local variable inside local scope
5744 SMESH::TPythonDump pDump; // do not delete this line of code
5745 grpList = GetGroups();
5748 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5749 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5752 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5753 if ( aGrpSO->_is_nil() )
5755 // correct name of the mesh group if necessary
5756 const char* guiName = aGrpSO->GetName();
5757 if ( strcmp(guiName, aGrp->GetName()) )
5758 aGrp->SetName( guiName );
5762 //=============================================================================
5764 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5766 //=============================================================================
5767 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5769 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5773 //=============================================================================
5775 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5777 //=============================================================================
5779 char* SMESH_Mesh_i::GetParameters()
5781 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5784 //=============================================================================
5786 * \brief Returns list of notebook variables used for last Mesh operation
5788 //=============================================================================
5789 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5791 SMESH::string_array_var aResult = new SMESH::string_array();
5792 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5794 CORBA::String_var aParameters = GetParameters();
5795 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5796 if ( aSections->length() > 0 ) {
5797 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5798 aResult->length( aVars.length() );
5799 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5800 aResult[i] = CORBA::string_dup( aVars[i] );
5803 return aResult._retn();
5806 //=======================================================================
5807 //function : GetTypes
5808 //purpose : Returns types of elements it contains
5809 //=======================================================================
5811 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5814 return _preMeshInfo->GetTypes();
5816 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5820 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5821 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5822 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5823 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5824 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5825 if (_impl->NbNodes() &&
5826 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5827 types->length( nbTypes );
5829 return types._retn();
5832 //=======================================================================
5833 //function : GetMesh
5834 //purpose : Returns self
5835 //=======================================================================
5837 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5839 return SMESH::SMESH_Mesh::_duplicate( _this() );
5842 //=======================================================================
5843 //function : IsMeshInfoCorrect
5844 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5845 // * happen if mesh data is not yet fully loaded from the file of study.
5846 //=======================================================================
5848 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5850 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5853 //=============================================================================
5855 * \brief Returns number of mesh elements per each \a EntityType
5857 //=============================================================================
5859 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5862 return _preMeshInfo->GetMeshInfo();
5864 SMESH::long_array_var aRes = new SMESH::long_array();
5865 aRes->length(SMESH::Entity_Last);
5866 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5868 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5870 return aRes._retn();
5871 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5872 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5873 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5874 return aRes._retn();
5877 //=============================================================================
5879 * \brief Returns number of mesh elements per each \a ElementType
5881 //=============================================================================
5883 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5885 SMESH::long_array_var aRes = new SMESH::long_array();
5886 aRes->length(SMESH::NB_ELEMENT_TYPES);
5887 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5890 const SMDS_MeshInfo* meshInfo = 0;
5892 meshInfo = _preMeshInfo;
5893 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5894 meshInfo = & meshDS->GetMeshInfo();
5897 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5898 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5900 return aRes._retn();
5903 //=============================================================================
5905 * Collect statistic of mesh elements given by iterator
5907 //=============================================================================
5909 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5910 SMESH::long_array& theInfo)
5912 if (!theItr) return;
5913 while (theItr->more())
5914 theInfo[ theItr->next()->GetEntityType() ]++;
5916 //=============================================================================
5918 * Returns mesh unstructed grid information.
5920 //=============================================================================
5922 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5924 SALOMEDS::TMPFile_var SeqFile;
5925 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5926 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5928 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5929 aWriter->WriteToOutputStringOn();
5930 aWriter->SetInputData(aGrid);
5931 aWriter->SetFileTypeToBinary();
5933 char* str = aWriter->GetOutputString();
5934 int size = aWriter->GetOutputStringLength();
5936 //Allocate octet buffer of required size
5937 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5938 //Copy ostrstream content to the octet buffer
5939 memcpy(OctetBuf, str, size);
5940 //Create and return TMPFile
5941 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5945 return SeqFile._retn();
5948 //=============================================================================
5949 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5950 * SMESH::ElementType type) */
5952 using namespace SMESH::Controls;
5953 //-----------------------------------------------------------------------------
5954 struct PredicateIterator : public SMDS_ElemIterator
5956 SMDS_ElemIteratorPtr _elemIter;
5957 PredicatePtr _predicate;
5958 const SMDS_MeshElement* _elem;
5959 SMDSAbs_ElementType _type;
5961 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5962 PredicatePtr predicate,
5963 SMDSAbs_ElementType type):
5964 _elemIter(iterator), _predicate(predicate), _type(type)
5972 virtual const SMDS_MeshElement* next()
5974 const SMDS_MeshElement* res = _elem;
5976 while ( _elemIter->more() && !_elem )
5978 if ((_elem = _elemIter->next()) &&
5979 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
5980 ( !_predicate->IsSatisfy( _elem->GetID() ))))
5987 //-----------------------------------------------------------------------------
5988 struct IDSourceIterator : public SMDS_ElemIterator
5990 const CORBA::Long* _idPtr;
5991 const CORBA::Long* _idEndPtr;
5992 SMESH::long_array_var _idArray;
5993 const SMDS_Mesh* _mesh;
5994 const SMDSAbs_ElementType _type;
5995 const SMDS_MeshElement* _elem;
5997 IDSourceIterator( const SMDS_Mesh* mesh,
5998 const CORBA::Long* ids,
6000 SMDSAbs_ElementType type):
6001 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
6003 if ( _idPtr && nbIds && _mesh )
6006 IDSourceIterator( const SMDS_Mesh* mesh,
6007 SMESH::long_array* idArray,
6008 SMDSAbs_ElementType type):
6009 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
6011 if ( idArray && _mesh )
6013 _idPtr = &_idArray[0];
6014 _idEndPtr = _idPtr + _idArray->length();
6022 virtual const SMDS_MeshElement* next()
6024 const SMDS_MeshElement* res = _elem;
6026 while ( _idPtr < _idEndPtr && !_elem )
6028 if ( _type == SMDSAbs_Node )
6030 _elem = _mesh->FindNode( *_idPtr++ );
6032 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
6033 (_elem->GetType() != _type && _type != SMDSAbs_All ))
6041 //-----------------------------------------------------------------------------
6043 struct NodeOfElemIterator : public SMDS_ElemIterator
6045 TColStd_MapOfInteger _checkedNodeIDs;
6046 SMDS_ElemIteratorPtr _elemIter;
6047 SMDS_ElemIteratorPtr _nodeIter;
6048 const SMDS_MeshElement* _node;
6050 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
6052 if ( _elemIter && _elemIter->more() )
6054 _nodeIter = _elemIter->next()->nodesIterator();
6062 virtual const SMDS_MeshElement* next()
6064 const SMDS_MeshElement* res = _node;
6066 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
6068 if ( _nodeIter->more() )
6070 _node = _nodeIter->next();
6071 if ( !_checkedNodeIDs.Add( _node->GetID() ))
6076 _nodeIter = _elemIter->next()->nodesIterator();
6084 //=============================================================================
6086 * Return iterator on elements of given type in given object
6088 //=============================================================================
6090 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
6091 SMESH::ElementType theType)
6093 SMDS_ElemIteratorPtr elemIt;
6094 bool typeOK = ( theType == SMESH::ALL );
6095 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
6097 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
6098 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
6099 if ( !mesh_i ) return elemIt;
6100 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
6102 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
6104 elemIt = meshDS->elementsIterator( elemType );
6107 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
6109 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
6112 elemIt = sm->GetElements();
6113 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6115 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
6116 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
6120 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
6122 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
6123 if ( groupDS && ( elemType == groupDS->GetType() ||
6124 elemType == SMDSAbs_Node ||
6125 elemType == SMDSAbs_All ))
6127 elemIt = groupDS->GetElements();
6128 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
6131 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
6133 if ( filter_i->GetElementType() == theType ||
6134 filter_i->GetElementType() == SMESH::ALL ||
6135 elemType == SMDSAbs_Node ||
6136 elemType == SMDSAbs_All)
6138 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
6139 if ( pred_i && pred_i->GetPredicate() )
6141 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
6142 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
6143 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
6144 elemIt = SMDS_ElemIteratorPtr
6145 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
6146 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
6152 SMESH::array_of_ElementType_var types = theObject->GetTypes();
6153 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
6154 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6156 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
6157 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
6160 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
6161 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
6165 SMESH::long_array_var ids = theObject->GetIDs();
6166 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
6168 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
6171 if ( elemIt && elemIt->more() && !typeOK )
6173 if ( elemType == SMDSAbs_Node )
6175 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
6179 elemIt = SMDS_ElemIteratorPtr();
6185 //=============================================================================
6186 namespace // Finding concurrent hypotheses
6187 //=============================================================================
6191 * \brief mapping of mesh dimension into shape type
6193 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
6195 TopAbs_ShapeEnum aType = TopAbs_SOLID;
6197 case 0: aType = TopAbs_VERTEX; break;
6198 case 1: aType = TopAbs_EDGE; break;
6199 case 2: aType = TopAbs_FACE; break;
6201 default:aType = TopAbs_SOLID; break;
6206 //-----------------------------------------------------------------------------
6208 * \brief Internal structure used to find concurrent submeshes
6210 * It represents a pair < submesh, concurrent dimension >, where
6211 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
6212 * with another submesh. In other words, it is dimension of a hypothesis assigned
6219 int _dim; //!< a dimension the algo can build (concurrent dimension)
6220 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
6221 TopTools_MapOfShape _shapeMap;
6222 SMESH_subMesh* _subMesh;
6223 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
6225 //-----------------------------------------------------------------------------
6226 // Return the algorithm
6227 const SMESH_Algo* GetAlgo() const
6228 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
6230 //-----------------------------------------------------------------------------
6232 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
6234 const TopoDS_Shape& theShape)
6236 _subMesh = (SMESH_subMesh*)theSubMesh;
6237 SetShape( theDim, theShape );
6240 //-----------------------------------------------------------------------------
6242 void SetShape(const int theDim,
6243 const TopoDS_Shape& theShape)
6246 _ownDim = SMESH_Gen::GetShapeDim(theShape);
6247 if (_dim >= _ownDim)
6248 _shapeMap.Add( theShape );
6250 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
6251 for( ; anExp.More(); anExp.Next() )
6252 _shapeMap.Add( anExp.Current() );
6256 //-----------------------------------------------------------------------------
6257 //! Check sharing of sub-shapes
6258 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
6259 const TopTools_MapOfShape& theToFind,
6260 const TopAbs_ShapeEnum theType)
6262 bool isShared = false;
6263 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
6264 for (; !isShared && anItr.More(); anItr.Next() )
6266 const TopoDS_Shape aSubSh = anItr.Key();
6267 // check for case when concurrent dimensions are same
6268 isShared = theToFind.Contains( aSubSh );
6269 // check for sub-shape with concurrent dimension
6270 TopExp_Explorer anExp( aSubSh, theType );
6271 for ( ; !isShared && anExp.More(); anExp.Next() )
6272 isShared = theToFind.Contains( anExp.Current() );
6277 //-----------------------------------------------------------------------------
6278 //! check algorithms
6279 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
6280 const SMESHDS_Hypothesis* theA2)
6282 if ( !theA1 || !theA2 ||
6283 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
6284 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
6285 return false; // one of the hypothesis is not algorithm
6286 // check algorithm names (should be equal)
6287 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
6291 //-----------------------------------------------------------------------------
6292 //! Check if sub-shape hypotheses are concurrent
6293 bool IsConcurrent(const SMESH_DimHyp* theOther) const
6295 if ( _subMesh == theOther->_subMesh )
6296 return false; // same sub-shape - should not be
6298 // if ( <own dim of either of submeshes> == <concurrent dim> &&
6299 // any of the two submeshes is not on COMPOUND shape )
6300 // -> no concurrency
6301 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
6302 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
6303 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
6304 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
6305 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
6308 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
6309 if ( !checkSubShape )
6312 // check algorithms to be same
6313 const SMESH_Algo* a1 = this->GetAlgo();
6314 const SMESH_Algo* a2 = theOther->GetAlgo();
6315 bool isSame = checkAlgo( a1, a2 );
6319 return false; // pb?
6320 return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency !
6323 // check hypothesises for concurrence (skip first as algorithm)
6325 // pointers should be same, because it is referened from mesh hypothesis partition
6326 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
6327 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
6328 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
6329 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
6331 // the submeshes are concurrent if their algorithms has different parameters
6332 return nbSame != theOther->_hypotheses.size() - 1;
6335 // Return true if algorithm of this SMESH_DimHyp is used if no
6336 // sub-mesh order is imposed by the user
6337 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
6339 // NeedDiscreteBoundary() algo has a higher priority
6340 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
6341 theOther->GetAlgo()->NeedDiscreteBoundary() )
6342 return !this->GetAlgo()->NeedDiscreteBoundary();
6344 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
6347 }; // end of SMESH_DimHyp
6348 //-----------------------------------------------------------------------------
6350 typedef list<const SMESH_DimHyp*> TDimHypList;
6352 //-----------------------------------------------------------------------------
6354 void addDimHypInstance(const int theDim,
6355 const TopoDS_Shape& theShape,
6356 const SMESH_Algo* theAlgo,
6357 const SMESH_subMesh* theSubMesh,
6358 const list <const SMESHDS_Hypothesis*>& theHypList,
6359 TDimHypList* theDimHypListArr )
6361 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
6362 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
6363 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
6364 dimHyp->_hypotheses.push_front(theAlgo);
6365 listOfdimHyp.push_back( dimHyp );
6368 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
6369 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
6370 theHypList.begin(), theHypList.end() );
6373 //-----------------------------------------------------------------------------
6374 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
6375 TDimHypList& theListOfConcurr)
6377 if ( theListOfConcurr.empty() )
6379 theListOfConcurr.push_back( theDimHyp );
6383 TDimHypList::iterator hypIt = theListOfConcurr.begin();
6384 while ( hypIt != theListOfConcurr.end() &&
6385 !theDimHyp->IsHigherPriorityThan( *hypIt ))
6387 theListOfConcurr.insert( hypIt, theDimHyp );
6391 //-----------------------------------------------------------------------------
6392 void findConcurrents(const SMESH_DimHyp* theDimHyp,
6393 const TDimHypList& theListOfDimHyp,
6394 TDimHypList& theListOfConcurrHyp,
6395 set<int>& theSetOfConcurrId )
6397 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
6398 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
6400 const SMESH_DimHyp* curDimHyp = *rIt;
6401 if ( curDimHyp == theDimHyp )
6402 break; // meet own dimHyp pointer in same dimension
6404 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
6405 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
6407 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
6412 //-----------------------------------------------------------------------------
6413 void unionLists(TListOfInt& theListOfId,
6414 TListOfListOfInt& theListOfListOfId,
6417 TListOfListOfInt::iterator it = theListOfListOfId.begin();
6418 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
6420 continue; //skip already treated lists
6421 // check if other list has any same submesh object
6422 TListOfInt& otherListOfId = *it;
6423 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
6424 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
6427 // union two lists (from source into target)
6428 TListOfInt::iterator it2 = otherListOfId.begin();
6429 for ( ; it2 != otherListOfId.end(); it2++ ) {
6430 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
6431 theListOfId.push_back(*it2);
6433 // clear source list
6434 otherListOfId.clear();
6437 //-----------------------------------------------------------------------------
6439 //! free memory allocated for dimension-hypothesis objects
6440 void removeDimHyps( TDimHypList* theArrOfList )
6442 for (int i = 0; i < 4; i++ ) {
6443 TDimHypList& listOfdimHyp = theArrOfList[i];
6444 TDimHypList::const_iterator it = listOfdimHyp.begin();
6445 for ( ; it != listOfdimHyp.end(); it++ )
6450 //-----------------------------------------------------------------------------
6452 * \brief find common submeshes with given submesh
6453 * \param theSubMeshList list of already collected submesh to check
6454 * \param theSubMesh given submesh to intersect with other
6455 * \param theCommonSubMeshes collected common submeshes
6457 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6458 const SMESH_subMesh* theSubMesh,
6459 set<const SMESH_subMesh*>& theCommon )
6463 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6464 for ( ; it != theSubMeshList.end(); it++ )
6465 theSubMesh->FindIntersection( *it, theCommon );
6466 theSubMeshList.push_back( theSubMesh );
6467 //theCommon.insert( theSubMesh );
6470 //-----------------------------------------------------------------------------
6471 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6473 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6474 for ( ; listsIt != smLists.end(); ++listsIt )
6476 const TListOfInt& smIDs = *listsIt;
6477 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6485 //=============================================================================
6487 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6489 //=============================================================================
6491 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6493 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6494 if ( isSubMeshInList( submeshID, anOrder ))
6497 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6498 return isSubMeshInList( submeshID, allConurrent );
6501 //=============================================================================
6503 * \brief Return submesh objects list in meshing order
6505 //=============================================================================
6507 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6509 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6511 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6513 return aResult._retn();
6515 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6516 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6517 anOrder.splice( anOrder.end(), allConurrent );
6520 TListOfListOfInt::iterator listIt = anOrder.begin();
6521 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6522 unionLists( *listIt, anOrder, listIndx + 1 );
6524 // convert submesh ids into interface instances
6525 // and dump command into python
6526 convertMeshOrder( anOrder, aResult, false );
6528 return aResult._retn();
6531 //=============================================================================
6533 * \brief Finds concurrent sub-meshes
6535 //=============================================================================
6537 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6539 TListOfListOfInt anOrder;
6540 ::SMESH_Mesh& mesh = GetImpl();
6542 // collect submeshes and detect concurrent algorithms and hypothesises
6543 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6545 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6546 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
6547 ::SMESH_subMesh* sm = (*i_sm).second;
6549 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6551 // list of assigned hypothesises
6552 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6553 // Find out dimensions where the submesh can be concurrent.
6554 // We define the dimensions by algo of each of hypotheses in hypList
6555 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6556 for( ; hypIt != hypList.end(); hypIt++ ) {
6557 SMESH_Algo* anAlgo = 0;
6558 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6559 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6560 // hyp it-self is algo
6561 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6563 // try to find algorithm with help of sub-shapes
6564 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6565 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6566 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6569 continue; // no algorithm assigned to a current submesh
6571 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6572 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
6574 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6575 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6576 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6578 } // end iterations on submesh
6580 // iterate on created dimension-hypotheses and check for concurrents
6581 for ( int i = 0; i < 4; i++ ) {
6582 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6583 // check for concurrents in own and other dimensions (step-by-step)
6584 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6585 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
6586 const SMESH_DimHyp* dimHyp = *dhIt;
6587 TDimHypList listOfConcurr;
6588 set<int> setOfConcurrIds;
6589 // looking for concurrents and collect into own list
6590 for ( int j = i; j < 4; j++ )
6591 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6592 // check if any concurrents found
6593 if ( listOfConcurr.size() > 0 ) {
6594 // add own submesh to list of concurrent
6595 addInOrderOfPriority( dimHyp, listOfConcurr );
6596 list<int> listOfConcurrIds;
6597 TDimHypList::iterator hypIt = listOfConcurr.begin();
6598 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6599 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6600 anOrder.push_back( listOfConcurrIds );
6605 removeDimHyps(dimHypListArr);
6607 // now, minimize the number of concurrent groups
6608 // Here we assume that lists of submeshes can have same submesh
6609 // in case of multi-dimension algorithms, as result
6610 // list with common submesh has to be united into one list
6612 TListOfListOfInt::iterator listIt = anOrder.begin();
6613 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6614 unionLists( *listIt, anOrder, listIndx + 1 );
6620 //=============================================================================
6622 * \brief Set submesh object order
6623 * \param theSubMeshArray submesh array order
6625 //=============================================================================
6627 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6630 _preMeshInfo->ForgetOrLoad();
6633 ::SMESH_Mesh& mesh = GetImpl();
6635 TPythonDump aPythonDump; // prevent dump of called methods
6636 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6638 TListOfListOfInt subMeshOrder;
6639 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6641 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6642 TListOfInt subMeshIds;
6644 aPythonDump << ", ";
6645 aPythonDump << "[ ";
6646 // Collect subMeshes which should be clear
6647 // do it list-by-list, because modification of submesh order
6648 // take effect between concurrent submeshes only
6649 set<const SMESH_subMesh*> subMeshToClear;
6650 list<const SMESH_subMesh*> subMeshList;
6651 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6653 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6655 aPythonDump << ", ";
6656 aPythonDump << subMesh;
6657 subMeshIds.push_back( subMesh->GetId() );
6658 // detect common parts of submeshes
6659 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6660 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6662 aPythonDump << " ]";
6663 subMeshOrder.push_back( subMeshIds );
6665 // clear collected sub-meshes
6666 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6667 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6668 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6670 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6671 if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748
6672 sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo
6675 aPythonDump << " ])";
6677 mesh.SetMeshOrder( subMeshOrder );
6680 SMESH::SMESH_Mesh_var me = _this();
6681 _gen_i->UpdateIcons( me );
6686 //=============================================================================
6688 * \brief Convert submesh ids into submesh interfaces
6690 //=============================================================================
6692 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6693 SMESH::submesh_array_array& theResOrder,
6694 const bool theIsDump)
6696 int nbSet = theIdsOrder.size();
6697 TPythonDump aPythonDump; // prevent dump of called methods
6699 aPythonDump << "[ ";
6700 theResOrder.length(nbSet);
6701 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6703 for( ; it != theIdsOrder.end(); it++ ) {
6704 // translate submesh identificators into submesh objects
6705 // takeing into account real number of concurrent lists
6706 const TListOfInt& aSubOrder = (*it);
6707 if (!aSubOrder.size())
6710 aPythonDump << "[ ";
6711 // convert shape indices into interfaces
6712 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6713 aResSubSet->length(aSubOrder.size());
6714 TListOfInt::const_iterator subIt = aSubOrder.begin();
6716 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6717 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6719 SMESH::SMESH_subMesh_var subMesh =
6720 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6723 aPythonDump << ", ";
6724 aPythonDump << subMesh;
6726 aResSubSet[ j++ ] = subMesh;
6729 aPythonDump << " ]";
6731 theResOrder[ listIndx++ ] = aResSubSet;
6733 // correct number of lists
6734 theResOrder.length( listIndx );
6737 // finilise python dump
6738 aPythonDump << " ]";
6739 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6743 namespace // utils used by SMESH_MeshPartDS
6746 * \brief Class used to access to protected data of SMDS_MeshInfo
6748 struct TMeshInfo : public SMDS_MeshInfo
6750 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6753 * \brief Element holing its ID only
6755 struct TElemID : public SMDS_LinearEdge
6757 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6761 //================================================================================
6763 // Implementation of SMESH_MeshPartDS
6765 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6766 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6768 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6769 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6772 _meshDS = mesh_i->GetImpl().GetMeshDS();
6774 SetPersistentId( _meshDS->GetPersistentId() );
6776 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6778 // <meshPart> is the whole mesh
6779 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6781 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6782 myGroupSet = _meshDS->GetGroups();
6787 SMESH::long_array_var anIDs = meshPart->GetIDs();
6788 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6789 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6791 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6792 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6793 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6798 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6799 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6800 if ( _elements[ e->GetType() ].insert( e ).second )
6803 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6804 while ( nIt->more() )
6806 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6807 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6814 ShapeToMesh( _meshDS->ShapeToMesh() );
6816 _meshDS = 0; // to enforce iteration on _elements and _nodes
6819 // -------------------------------------------------------------------------------------
6820 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6821 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6824 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6825 for ( ; partIt != meshPart.end(); ++partIt )
6826 if ( const SMDS_MeshElement * e = *partIt )
6827 if ( _elements[ e->GetType() ].insert( e ).second )
6830 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6831 while ( nIt->more() )
6833 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6834 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6840 // -------------------------------------------------------------------------------------
6841 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6843 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6845 TElemID elem( IDelem );
6846 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6847 if ( !_elements[ iType ].empty() )
6849 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6850 if ( it != _elements[ iType ].end() )
6855 // -------------------------------------------------------------------------------------
6856 bool SMESH_MeshPartDS::HasNumerationHoles()
6858 if ( _meshDS ) return _meshDS->HasNumerationHoles();
6860 return ( MinNodeID() != 1 ||
6861 MaxNodeID() != NbNodes() ||
6862 MinElementID() != 1 ||
6863 MaxElementID() != NbElements() );
6865 // -------------------------------------------------------------------------------------
6866 int SMESH_MeshPartDS::MaxNodeID() const
6868 if ( _meshDS ) return _meshDS->MaxNodeID();
6869 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID();
6871 // -------------------------------------------------------------------------------------
6872 int SMESH_MeshPartDS::MinNodeID() const
6874 if ( _meshDS ) return _meshDS->MinNodeID();
6875 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID();
6877 // -------------------------------------------------------------------------------------
6878 int SMESH_MeshPartDS::MaxElementID() const
6880 if ( _meshDS ) return _meshDS->MaxElementID();
6882 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6883 if ( !_elements[ iType ].empty() )
6884 maxID = Max( maxID, (*_elements[ iType ].rbegin())->GetID() );
6887 // -------------------------------------------------------------------------------------
6888 int SMESH_MeshPartDS::MinElementID() const
6890 if ( _meshDS ) return _meshDS->MinElementID();
6892 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6893 if ( !_elements[ iType ].empty() )
6894 minID = Min( minID, (*_elements[ iType ].begin())->GetID() );
6897 // -------------------------------------------------------------------------------------
6898 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6900 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6902 typedef SMDS_SetIterator
6903 <const SMDS_MeshElement*,
6904 TIDSortedElemSet::const_iterator,
6905 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6906 SMDS_MeshElement::GeomFilter
6909 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6911 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6912 _elements[type].end(),
6913 SMDS_MeshElement::GeomFilter( geomType )));
6915 // -------------------------------------------------------------------------------------
6916 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6918 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6920 typedef SMDS_SetIterator
6921 <const SMDS_MeshElement*,
6922 TIDSortedElemSet::const_iterator,
6923 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6924 SMDS_MeshElement::EntityFilter
6927 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6929 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6930 _elements[type].end(),
6931 SMDS_MeshElement::EntityFilter( entity )));
6933 // -------------------------------------------------------------------------------------
6934 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6936 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6937 if ( type == SMDSAbs_All && !_meshDS )
6939 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6941 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6942 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6944 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6946 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6947 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6949 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6950 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6952 // -------------------------------------------------------------------------------------
6953 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6954 iterType SMESH_MeshPartDS::methName() const \
6956 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6957 return _meshDS ? _meshDS->methName() : iterType \
6958 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6960 // -------------------------------------------------------------------------------------
6961 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6962 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6963 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6964 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6965 #undef _GET_ITER_DEFINE
6967 // END Implementation of SMESH_MeshPartDS
6969 //================================================================================