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;
2089 SALOMEDS::SObject_wrap groupSO;
2091 if ( how == IS_BREAK_LINK )
2093 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( groupData._smeshObject );
2094 SALOMEDS::SObject_wrap geomRefSO;
2095 if ( !meshSO->_is_nil() &&
2096 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ))
2098 geomRefSO->ReferencedObject( groupSO.inout() );
2104 groupSO = _gen_i->getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
2107 if ( groupSO->_is_nil() )
2110 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
2111 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
2112 if ( geomGroup->_is_nil() )
2115 // get indices of group items
2116 set<int> curIndices;
2117 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( geomGroup );
2118 GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations();
2119 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
2120 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2121 curIndices.insert( ids[i] );
2123 bool sameIndices = ( groupData._indices == curIndices );
2124 if ( how == ONLY_IF_CHANGED && sameIndices )
2125 return newShape; // group not changed
2127 newShape = _gen_i->GeomObjectToShape( geomGroup );
2129 if ( !newShape.IsNull() && ids->length() > 0 )
2131 if ( !sameIndices || !_impl->GetMeshDS()->IsGroupOfSubShapes( newShape ))
2133 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2134 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
2135 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
2136 newShape = _gen_i->GeomObjectToShape( geomGroup );
2141 // geom group becomes empty - return empty compound
2142 TopoDS_Compound compound;
2143 BRep_Builder().MakeCompound(compound);
2144 newShape = compound;
2148 CORBA::String_var entry = geomGroup->GetStudyEntry();
2149 groupData._groupEntry = entry.in();
2150 groupData._indices = curIndices;
2157 //-----------------------------------------------------------------------------
2159 * \brief Storage of shape and index used in CheckGeomGroupModif()
2161 struct TIndexedShape
2164 TopoDS_Shape _shape;
2165 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
2167 //-----------------------------------------------------------------------------
2169 * \brief Data to re-create a group on geometry
2171 struct TGroupOnGeomData
2174 TopoDS_Shape _shape;
2175 SMDSAbs_ElementType _type;
2177 Quantity_Color _color;
2179 TGroupOnGeomData( const SMESHDS_GroupOnGeom* group )
2181 _oldID = group->GetID();
2182 _type = group->GetType();
2183 _name = group->GetStoreName();
2184 _color = group->GetColor();
2188 //-----------------------------------------------------------------------------
2190 * \brief Check if a filter is still valid after geometry removal
2192 bool isValidGeomFilter( SMESH::Filter_var theFilter )
2194 if ( theFilter->_is_nil() )
2196 SMESH::Filter::Criteria_var criteria;
2197 theFilter->GetCriteria( criteria.out() );
2199 for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr )
2201 const char* thresholdID = criteria[ iCr ].ThresholdID.in();
2203 switch ( criteria[ iCr ].Type )
2205 case SMESH::FT_BelongToGeom:
2206 case SMESH::FT_BelongToPlane:
2207 case SMESH::FT_BelongToCylinder:
2208 case SMESH::FT_BelongToGenSurface:
2209 case SMESH::FT_LyingOnGeom:
2210 entry = thresholdID;
2212 case SMESH::FT_ConnectedElements:
2215 entry = thresholdID;
2221 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
2222 SALOMEDS::SObject_wrap so = gen->getStudyServant()->FindObjectID( entry.c_str() );
2223 if ( so->_is_nil() )
2225 CORBA::Object_var obj = so->GetObject();
2226 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( obj );
2227 if ( gen->GeomObjectToShape( geom ).IsNull() )
2230 } // loop on criteria
2236 //=============================================================================
2238 * \brief Update data if geometry changes
2242 //=============================================================================
2244 void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink )
2246 SMESH::SMESH_Mesh_var me = _this();
2247 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2249 TPythonDump dumpNothing; // prevent any dump
2251 //bool removedFromClient = false;
2253 if ( mainGO->_is_nil() ) // GEOM_Client cleared or geometry removed? (IPAL52735, PAL23636)
2255 //removedFromClient = _impl->HasShapeToMesh();
2257 // try to find geometry by study reference
2258 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2259 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2260 if ( !meshSO->_is_nil() &&
2261 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2262 geomRefSO->ReferencedObject( geomSO.inout() ))
2264 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2265 mainGO = GEOM::GEOM_Object::_narrow( geomObj );
2268 if ( mainGO->_is_nil() && // geometry removed ==>
2269 !geomRefSO->_is_nil() ) // remove geom dependent data: sub-meshes etc.
2271 // convert geom dependent groups into standalone ones
2272 CheckGeomGroupModif();
2274 _impl->ShapeToMesh( TopoDS_Shape() );
2276 // remove sub-meshes
2277 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2278 while ( i_sm != _mapSubMeshIor.end() )
2280 SMESH::SMESH_subMesh_ptr sm = i_sm->second;
2282 RemoveSubMesh( sm );
2284 // remove all children except groups in the study
2285 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2286 SALOMEDS::SObject_wrap so;
2287 for ( CORBA::Long tag = SMESH::Tag_RefOnShape; tag <= SMESH::Tag_LastSubMesh; ++tag )
2288 if ( meshSO->FindSubObject( tag, so.inout() ))
2289 builder->RemoveObjectWithChildren( so );
2291 _gen_i->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED" );
2297 if ( !_impl->HasShapeToMesh() ) return;
2300 // Update after group modification
2302 if ( mainGO->GetType() == GEOM_GROUP || // is group or not modified
2303 mainGO->GetTick() == _mainShapeTick )
2305 int nb = NbNodes() + NbElements();
2306 CheckGeomGroupModif();
2307 if ( nb != NbNodes() + NbElements() ) // something removed due to hypotheses change
2308 _gen_i->UpdateIcons( me );
2312 // Update after shape modification
2314 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2315 if ( !geomClient ) return;
2316 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( mainGO );
2317 if ( geomGen->_is_nil() ) return;
2318 CORBA::String_var geomComponentType = geomGen->ComponentDataType();
2319 bool isShaper = ( strcmp( geomComponentType.in(), "SHAPERSTUDY" ) == 0 );
2321 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2322 geomClient->RemoveShapeFromBuffer( ior.in() );
2324 // Update data taking into account that if topology doesn't change
2325 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2328 _preMeshInfo->ForgetAllData();
2331 if ( isBreakLink || !isShaper )
2333 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2334 if ( newShape.IsNull() )
2337 _mainShapeTick = mainGO->GetTick();
2339 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2341 // store data of groups on geometry including new TopoDS_Shape's
2342 std::vector< TGroupOnGeomData > groupsData;
2343 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2344 groupsData.reserve( groups.size() );
2345 TopTools_DataMapOfShapeShape old2newShapeMap;
2346 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2347 for ( ; g != groups.end(); ++g )
2349 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2351 groupsData.push_back( TGroupOnGeomData( group ));
2354 SMESH::SMESH_GroupOnGeom_var gog;
2355 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.find( group->GetID() );
2356 if ( i_grp != _mapGroups.end() )
2357 gog = SMESH::SMESH_GroupOnGeom::_narrow( i_grp->second );
2359 GEOM::GEOM_Object_var geom;
2360 if ( !gog->_is_nil() )
2364 SALOMEDS::SObject_wrap grpSO = _gen_i->ObjectToSObject( gog );
2365 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2366 if ( !grpSO->_is_nil() &&
2367 grpSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2368 geomRefSO->ReferencedObject( geomSO.inout() ))
2370 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2371 geom = GEOM::GEOM_Object::_narrow( geomObj );
2376 geom = gog->GetShape();
2379 if ( old2newShapeMap.IsBound( group->GetShape() ))
2381 groupsData.back()._shape = old2newShapeMap( group->GetShape() );
2383 else if ( !geom->_is_nil() )
2385 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2386 if ( meshDS->ShapeToIndex( groupsData.back()._shape ) > 0 )
2388 CORBA::String_var ior = geomGen->GetStringFromIOR( geom );
2389 geomClient->RemoveShapeFromBuffer( ior.in() );
2390 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2392 old2newShapeMap.Bind( group->GetShape(), groupsData.back()._shape );
2397 // store assigned hypotheses
2398 std::vector< pair< int, THypList > > ids2Hyps;
2399 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2400 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2402 const TopoDS_Shape& s = s2hyps.Key();
2403 const THypList& hyps = s2hyps.ChangeValue();
2404 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2407 std::multimap< std::set<int>, int > ii2iMap; // group sub-ids to group id in SMESHDS
2409 // count shapes excluding compounds corresponding to geom groups
2410 int oldNbSubShapes = meshDS->MaxShapeIndex();
2411 for ( ; oldNbSubShapes > 0; --oldNbSubShapes )
2413 const TopoDS_Shape& s = meshDS->IndexToShape( oldNbSubShapes );
2414 if ( s.IsNull() || s.ShapeType() != TopAbs_COMPOUND )
2417 std::set<int> subIds;
2418 for ( TopoDS_Iterator it( s ); it.More(); it.Next() )
2419 subIds.insert( meshDS->ShapeToIndex( it.Value() ));
2420 ii2iMap.insert( std::make_pair( subIds, oldNbSubShapes ));
2423 // check if shape topology changes - save shape type per shape ID
2424 std::vector< TopAbs_ShapeEnum > shapeTypes( Max( oldNbSubShapes + 1, 1 ));
2425 for ( int shapeID = oldNbSubShapes; shapeID > 0; --shapeID )
2426 shapeTypes[ shapeID ] = meshDS->IndexToShape( shapeID ).ShapeType();
2428 // change shape to mesh
2429 _impl->ShapeToMesh( TopoDS_Shape() );
2430 _impl->ShapeToMesh( newShape );
2432 // check if shape topology changes - check new shape types
2433 bool sameTopology = ( oldNbSubShapes == meshDS->MaxShapeIndex() );
2434 for ( int shapeID = oldNbSubShapes; shapeID > 0 && sameTopology; --shapeID )
2436 const TopoDS_Shape& s = meshDS->IndexToShape( shapeID );
2437 sameTopology = ( !s.IsNull() && s.ShapeType() == shapeTypes[ shapeID ]);
2440 // re-add shapes (compounds) of geom groups
2441 typedef std::map< std::vector< int >, TGeomGroupData* > TIndices2GroupData;
2442 TIndices2GroupData ii2grData;
2443 std::vector< int > ii;
2444 std::map< int, int > old2newIDs; // group IDs
2445 std::list<TGeomGroupData>::iterator dataIt = _geomGroupData.begin();
2446 for ( ; dataIt != _geomGroupData.end(); ++dataIt )
2448 TGeomGroupData* data = &(*dataIt);
2449 ii.reserve( data->_indices.size() );
2450 ii.assign( data->_indices.begin(), data->_indices.end() );
2451 TIndices2GroupData::iterator ii2gd = ii2grData.insert( std::make_pair( ii, data )).first;
2452 if ( ii2gd->second != data )
2454 data->_groupEntry = ii2gd->second->_groupEntry;
2455 data->_indices = ii2gd->second->_indices;
2458 const int oldNbSub = data->_indices.size();
2459 const int soleOldID = oldNbSub == 1 ? *data->_indices.begin() : 0;
2461 std::multimap< std::set<int>, int >::iterator ii2i = ii2iMap.find( data->_indices );
2462 if ( ii2i != ii2iMap.end() )
2464 oldID = ii2i->second;
2465 ii2iMap.erase( ii2i );
2467 if ( !oldID && oldNbSub == 1 )
2469 if ( old2newIDs.count( oldID ))
2472 int how = ( isBreakLink || !sameTopology ) ? IS_BREAK_LINK : MAIN_TRANSFORMED;
2473 newShape = newGroupShape( *data, how );
2475 if ( !newShape.IsNull() )
2477 if ( oldNbSub > 1 && meshDS->ShapeToIndex( newShape ) > 0 ) // group reduced to one sub-shape
2479 TopoDS_Compound compound;
2480 BRep_Builder().MakeCompound( compound );
2481 BRep_Builder().Add( compound, newShape );
2482 newShape = compound;
2484 int newID = _impl->GetSubMesh( newShape )->GetId();
2485 if ( oldID /*&& oldID != newID*/ )
2486 old2newIDs.insert( std::make_pair( oldID, newID ));
2487 if ( oldNbSub == 1 )
2488 old2newIDs.insert( std::make_pair( soleOldID, newID ));
2492 // re-assign hypotheses
2493 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2495 int sID = ids2Hyps[i].first;
2496 std::map< int, int >::iterator o2n = old2newIDs.find( sID );
2497 if ( o2n != old2newIDs.end() )
2499 else if ( !sameTopology && sID != 1 )
2501 const TopoDS_Shape& s = meshDS->IndexToShape( sID );
2504 const THypList& hyps = ids2Hyps[i].second;
2505 THypList::const_iterator h = hyps.begin();
2506 for ( ; h != hyps.end(); ++h )
2507 _impl->AddHypothesis( s, (*h)->GetID() );
2511 // restore groups on geometry
2512 for ( size_t i = 0; i < groupsData.size(); ++i )
2514 const TGroupOnGeomData& data = groupsData[i];
2515 if ( data._shape.IsNull() )
2518 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2519 if ( i2g == _mapGroups.end() ) continue;
2521 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2522 if ( !gr_i ) continue;
2524 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape );
2526 _mapGroups.erase( i2g );
2528 g->GetGroupDS()->SetColor( data._color );
2531 if ( !sameTopology )
2533 std::map< int, int >::iterator o2n = old2newIDs.begin();
2534 for ( ; o2n != old2newIDs.end(); ++o2n )
2536 int newID = o2n->second, oldID = o2n->first;
2537 if ( newID == oldID || !_mapSubMesh.count( oldID ))
2541 _mapSubMesh [ newID ] = _impl->GetSubMeshContaining( newID );
2542 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2543 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2545 _mapSubMesh. erase(oldID);
2546 _mapSubMesh_i. erase(oldID);
2547 _mapSubMeshIor.erase(oldID);
2549 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2553 // update _mapSubMesh
2554 std::map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2555 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2556 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2559 if ( !sameTopology )
2561 // remove invalid study sub-objects
2562 CheckGeomGroupModif();
2565 _gen_i->UpdateIcons( me );
2567 if ( !isBreakLink && isShaper )
2569 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2570 if ( !meshSO->_is_nil() )
2571 _gen_i->SetPixMap(meshSO, "ICON_SMESH_TREE_GEOM_MODIF");
2575 //=============================================================================
2577 * \brief Update objects depending on changed geom groups
2579 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2580 * issue 0020210: Update of a smesh group after modification of the associated geom group
2582 //=============================================================================
2584 void SMESH_Mesh_i::CheckGeomGroupModif()
2586 // remove sub-meshes referring a removed sub-shapes (if main shape still exists)
2587 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2588 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2589 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() ));
2590 if ( !mainGO->_is_nil() && !meshSO->_is_nil() )
2592 SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO;
2593 for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag )
2594 if ( meshSO->FindSubObject( tag, rootSO.inout() ))
2596 int nbValid = 0, nbRemoved = 0;
2597 SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO );
2598 for ( ; chItr->More(); chItr->Next() )
2600 SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO
2601 if ( !smSO->_is_nil() &&
2602 smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2603 geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference
2605 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2606 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2607 if ( !geom->_non_existent() )
2610 continue; // keep the sub-mesh
2613 CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO );
2614 SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj );
2615 if ( !sm->_is_nil() && !sm->_non_existent() )
2617 GEOM::GEOM_Object_var smGeom = sm->GetSubShape();
2618 if ( smGeom->_is_nil() )
2620 RemoveSubMesh( sm );
2627 _preMeshInfo->ForgetAllData(); // unknown hypothesis modified
2628 builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH
2632 if ( /*nbRemoved > 0 &&*/ nbValid == 0 )
2633 builder->RemoveObjectWithChildren( rootSO );
2637 // check for removed sub-shapes and convert geom dependent groups into standalone ones
2638 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2639 while ( i_gr != _mapGroups.end())
2641 SMESH::SMESH_GroupBase_ptr group = i_gr->second;
2643 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO, geomSO;
2644 SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group );
2645 SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group );
2646 bool isValidGeom = false;
2647 if ( !onGeom->_is_nil() )
2649 isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() &&
2650 ! groupSO->_is_nil() &&
2651 groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ) &&
2652 refSO->ReferencedObject( geomSO.inout() ) &&
2653 ! geomSO->_is_nil());
2654 isValidGeom = ( isValidGeom && !CORBA::is_nil( CORBA::Object_var( geomSO->GetObject() )));
2656 else if ( !onFilt->_is_nil() )
2658 isValidGeom = isValidGeomFilter( onFilt->GetFilter() );
2662 isValidGeom = ( !groupSO->_is_nil() &&
2663 !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ));
2667 if ( !IsLoaded() || group->IsEmpty() )
2669 RemoveGroup( group );
2671 else if ( !onGeom->_is_nil() || !onFilt->_is_nil() )
2673 SMESH::SMESH_Group_var ( ConvertToStandalone( group ));
2675 else // is it possible?
2677 builder->RemoveObjectWithChildren( refSO );
2683 if ( !_impl->HasShapeToMesh() ) return;
2685 CORBA::Long nbEntities = NbNodes() + NbElements();
2687 // Check if group contents changed
2689 typedef map< string, TopoDS_Shape > TEntry2Geom;
2690 TEntry2Geom newGroupContents;
2692 list<TGeomGroupData>::iterator
2693 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2694 for ( ; data != dataEnd; ++data )
2696 pair< TEntry2Geom::iterator, bool > it_new =
2697 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2698 bool processedGroup = !it_new.second;
2699 TopoDS_Shape& newShape = it_new.first->second;
2700 if ( !processedGroup )
2701 newShape = newGroupShape( *data, ONLY_IF_CHANGED );
2702 if ( newShape.IsNull() )
2703 continue; // no changes
2706 _preMeshInfo->ForgetOrLoad();
2708 if ( processedGroup ) { // update group indices
2709 list<TGeomGroupData>::iterator data2 = data;
2710 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2711 data->_indices = data2->_indices;
2714 // Update SMESH objects according to new GEOM group contents
2716 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2717 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2719 int oldID = submesh->GetId();
2720 if ( !_mapSubMeshIor.count( oldID ))
2722 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2724 // update hypotheses
2725 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2726 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2727 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2729 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2730 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2732 // care of submeshes
2733 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2734 int newID = newSubmesh->GetId();
2735 if ( newID != oldID ) {
2736 _mapSubMesh [ newID ] = newSubmesh;
2737 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2738 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2739 _mapSubMesh. erase(oldID);
2740 _mapSubMesh_i. erase(oldID);
2741 _mapSubMeshIor.erase(oldID);
2742 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2747 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2748 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2749 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2751 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2753 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2754 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2755 ds->SetShape( newShape );
2760 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2761 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2763 // Remove groups and submeshes basing on removed sub-shapes
2765 TopTools_MapOfShape newShapeMap;
2766 TopoDS_Iterator shapeIt( newShape );
2767 for ( ; shapeIt.More(); shapeIt.Next() )
2768 newShapeMap.Add( shapeIt.Value() );
2770 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2771 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2773 if ( newShapeMap.Contains( shapeIt.Value() ))
2775 TopTools_IndexedMapOfShape oldShapeMap;
2776 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2777 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2779 const TopoDS_Shape& oldShape = oldShapeMap(i);
2780 int oldInd = meshDS->ShapeToIndex( oldShape );
2782 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2783 if ( i_smIor != _mapSubMeshIor.end() ) {
2784 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2787 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2788 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2790 // check if a group bases on oldInd shape
2791 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2792 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2793 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2794 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2796 RemoveGroup( i_grp->second ); // several groups can base on same shape
2797 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2802 // Reassign hypotheses and update groups after setting the new shape to mesh
2804 // collect anassigned hypotheses
2805 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2806 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2807 TShapeHypList assignedHyps;
2808 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2810 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2811 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2812 if ( !hyps.empty() ) {
2813 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2814 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2815 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2818 // collect shapes supporting groups
2819 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2820 TShapeTypeList groupData;
2821 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2822 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2823 for ( ; grIt != groups.end(); ++grIt )
2825 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2827 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2829 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2831 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2832 _impl->ShapeToMesh( newShape );
2834 // reassign hypotheses
2835 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2836 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2838 TIndexedShape& geom = indS_hyps->first;
2839 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2840 int oldID = geom._index;
2841 int newID = meshDS->ShapeToIndex( geom._shape );
2842 if ( oldID == 1 ) { // main shape
2844 geom._shape = newShape;
2848 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2849 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2850 // care of sub-meshes
2851 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2852 if ( newID != oldID ) {
2853 _mapSubMesh [ newID ] = newSubmesh;
2854 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2855 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2856 _mapSubMesh. erase(oldID);
2857 _mapSubMesh_i. erase(oldID);
2858 _mapSubMeshIor.erase(oldID);
2859 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2863 TShapeTypeList::iterator geomType = groupData.begin();
2864 for ( ; geomType != groupData.end(); ++geomType )
2866 const TIndexedShape& geom = geomType->first;
2867 int oldID = geom._index;
2868 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2871 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2872 CORBA::String_var name = groupSO->GetName();
2874 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
2875 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
2876 /*id=*/-1, geom._shape ))
2877 group_i->changeLocalId( group->GetID() );
2880 break; // everything has been updated
2883 } // loop on group data
2887 CORBA::Long newNbEntities = NbNodes() + NbElements();
2888 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2889 if ( newNbEntities != nbEntities )
2891 // Add all SObjects with icons to soToUpdateIcons
2892 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2894 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2895 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2896 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2898 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2899 i_gr != _mapGroups.end(); ++i_gr ) // groups
2900 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2903 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2904 for ( ; so != soToUpdateIcons.end(); ++so )
2905 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2908 //=============================================================================
2910 * \brief Create standalone group from a group on geometry or filter
2912 //=============================================================================
2914 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2915 throw (SALOME::SALOME_Exception)
2917 SMESH::SMESH_Group_var aGroup;
2922 _preMeshInfo->FullLoadFromFile();
2924 if ( theGroup->_is_nil() )
2925 return aGroup._retn();
2927 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2929 return aGroup._retn();
2931 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2933 const int anId = aGroupToRem->GetLocalID();
2934 if ( !_impl->ConvertToStandalone( anId ) )
2935 return aGroup._retn();
2936 removeGeomGroupData( theGroup );
2938 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2940 // remove old instance of group from own map
2941 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2942 _mapGroups.erase( anId );
2944 SALOMEDS::StudyBuilder_var builder;
2945 SALOMEDS::SObject_wrap aGroupSO;
2946 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2947 if ( !aStudy->_is_nil() ) {
2948 builder = aStudy->NewBuilder();
2949 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2950 if ( !aGroupSO->_is_nil() )
2952 // remove reference to geometry
2953 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2954 for ( ; chItr->More(); chItr->Next() )
2956 // Remove group's child SObject
2957 SALOMEDS::SObject_wrap so = chItr->Value();
2958 builder->RemoveObject( so );
2960 // Update Python script
2961 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2962 << ".ConvertToStandalone( " << aGroupSO << " )";
2964 // change icon of Group on Filter
2967 // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2968 // const int isEmpty = ( elemTypes->length() == 0 );
2971 SALOMEDS::GenericAttribute_wrap anAttr =
2972 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2973 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2974 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2980 // remember new group in own map
2981 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2982 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2984 // register CORBA object for persistence
2985 _gen_i->RegisterObject( aGroup );
2987 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2988 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2989 //aGroup->Register();
2990 aGroupToRem->UnRegister();
2992 SMESH_CATCH( SMESH::throwCorbaException );
2994 return aGroup._retn();
2997 //=============================================================================
3001 //=============================================================================
3003 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
3005 if(MYDEBUG) MESSAGE( "createSubMesh" );
3006 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
3007 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
3010 SMESH_subMesh_i * subMeshServant;
3013 subMeshId = mySubMesh->GetId();
3014 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
3016 else // "invalid sub-mesh"
3018 // The invalid sub-mesh is created for the case where a valid sub-shape not found
3019 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
3020 if ( _mapSubMesh.empty() )
3023 subMeshId = _mapSubMesh.begin()->first - 1;
3024 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
3027 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
3029 _mapSubMesh [subMeshId] = mySubMesh;
3030 _mapSubMesh_i [subMeshId] = subMeshServant;
3031 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
3033 subMeshServant->Register();
3035 // register CORBA object for persistence
3036 int nextId = _gen_i->RegisterObject( subMesh );
3037 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
3038 else { nextId = 0; } // avoid "unused variable" warning
3040 // to track changes of GEOM groups
3041 if ( subMeshId > 0 )
3042 addGeomGroupData( theSubShapeObject, subMesh );
3044 return subMesh._retn();
3047 //=======================================================================
3048 //function : getSubMesh
3050 //=======================================================================
3052 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
3054 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
3055 if ( it == _mapSubMeshIor.end() )
3056 return SMESH::SMESH_subMesh::_nil();
3058 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
3061 //=============================================================================
3065 //=============================================================================
3067 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
3068 GEOM::GEOM_Object_ptr theSubShapeObject )
3070 bool isHypChanged = false;
3071 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
3072 return isHypChanged;
3074 const int subMeshId = theSubMesh->GetId();
3076 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
3079 if (( _mapSubMesh.count( subMeshId )) &&
3080 ( sm = _impl->GetSubMeshContaining( subMeshId )))
3082 TopoDS_Shape S = sm->GetSubShape();
3085 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
3086 isHypChanged = !hyps.empty();
3087 if ( isHypChanged && _preMeshInfo )
3088 _preMeshInfo->ForgetOrLoad();
3089 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
3090 for ( ; hyp != hyps.end(); ++hyp )
3091 _impl->RemoveHypothesis(S, (*hyp)->GetID());
3098 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
3099 isHypChanged = ( aHypList->length() > 0 );
3100 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
3101 removeHypothesis( theSubShapeObject, aHypList[i] );
3104 catch( const SALOME::SALOME_Exception& ) {
3105 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
3107 removeGeomGroupData( theSubShapeObject );
3111 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
3112 if ( id_smi != _mapSubMesh_i.end() )
3113 id_smi->second->UnRegister();
3115 // remove a CORBA object
3116 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
3117 if ( id_smptr != _mapSubMeshIor.end() )
3118 SMESH::SMESH_subMesh_var( id_smptr->second );
3120 _mapSubMesh.erase(subMeshId);
3121 _mapSubMesh_i.erase(subMeshId);
3122 _mapSubMeshIor.erase(subMeshId);
3124 return isHypChanged;
3127 //=============================================================================
3131 //=============================================================================
3133 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
3134 const char* theName,
3136 const TopoDS_Shape& theShape,
3137 const SMESH_PredicatePtr& thePredicate )
3139 std::string newName;
3140 if ( !theName || !theName[0] )
3142 std::set< std::string > presentNames;
3143 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
3144 for ( ; i_gr != _mapGroups.end(); ++i_gr )
3146 CORBA::String_var name = i_gr->second->GetName();
3147 presentNames.insert( name.in() );
3150 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
3151 } while ( !presentNames.insert( newName ).second );
3152 theName = newName.c_str();
3154 SMESH::SMESH_GroupBase_var aGroup;
3155 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
3156 theID, theShape, thePredicate ))
3158 int anId = g->GetID();
3159 SMESH_GroupBase_i* aGroupImpl;
3160 if ( !theShape.IsNull() )
3161 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3162 else if ( thePredicate )
3163 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
3165 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3167 aGroup = aGroupImpl->_this();
3168 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3169 aGroupImpl->Register();
3171 // register CORBA object for persistence
3172 int nextId = _gen_i->RegisterObject( aGroup );
3173 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
3174 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
3176 // to track changes of GEOM groups
3177 if ( !theShape.IsNull() ) {
3178 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
3179 addGeomGroupData( geom, aGroup );
3182 return aGroup._retn();
3185 //=============================================================================
3187 * SMESH_Mesh_i::removeGroup
3189 * Should be called by ~SMESH_Group_i()
3191 //=============================================================================
3193 void SMESH_Mesh_i::removeGroup( const int theId )
3195 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
3196 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
3197 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
3198 _mapGroups.erase( theId );
3199 removeGeomGroupData( group );
3200 if ( !_impl->RemoveGroup( theId ))
3202 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
3203 RemoveGroup( group );
3205 group->UnRegister();
3209 //=============================================================================
3213 //=============================================================================
3215 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
3216 throw(SALOME::SALOME_Exception)
3218 SMESH::log_array_var aLog;
3222 _preMeshInfo->FullLoadFromFile();
3224 list < SMESHDS_Command * >logDS = _impl->GetLog();
3225 aLog = new SMESH::log_array;
3227 int lg = logDS.size();
3230 list < SMESHDS_Command * >::iterator its = logDS.begin();
3231 while(its != logDS.end()){
3232 SMESHDS_Command *com = *its;
3233 int comType = com->GetType();
3235 int lgcom = com->GetNumber();
3237 const list < int >&intList = com->GetIndexes();
3238 int inum = intList.size();
3240 list < int >::const_iterator ii = intList.begin();
3241 const list < double >&coordList = com->GetCoords();
3242 int rnum = coordList.size();
3244 list < double >::const_iterator ir = coordList.begin();
3245 aLog[indexLog].commandType = comType;
3246 aLog[indexLog].number = lgcom;
3247 aLog[indexLog].coords.length(rnum);
3248 aLog[indexLog].indexes.length(inum);
3249 for(int i = 0; i < rnum; i++){
3250 aLog[indexLog].coords[i] = *ir;
3251 //MESSAGE(" "<<i<<" "<<ir.Value());
3254 for(int i = 0; i < inum; i++){
3255 aLog[indexLog].indexes[i] = *ii;
3256 //MESSAGE(" "<<i<<" "<<ii.Value());
3265 SMESH_CATCH( SMESH::throwCorbaException );
3267 return aLog._retn();
3271 //=============================================================================
3275 //=============================================================================
3277 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
3281 SMESH_CATCH( SMESH::throwCorbaException );
3284 //=============================================================================
3288 //=============================================================================
3290 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
3295 //=============================================================================
3298 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
3299 // issue 0020918: groups removal is caused by hyp modification
3300 // issue 0021208: to forget not loaded mesh data at hyp modification
3301 struct TCallUp_i : public SMESH_Mesh::TCallUp
3303 SMESH_Mesh_i* _mesh;
3304 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
3305 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
3306 virtual void HypothesisModified( int hypID,
3307 bool updIcons) { _mesh->onHypothesisModified( hypID,
3309 virtual void Load () { _mesh->Load(); }
3310 virtual bool IsLoaded() { return _mesh->IsLoaded(); }
3314 //================================================================================
3316 * \brief callback from _impl to
3317 * 1) forget not loaded mesh data (issue 0021208)
3318 * 2) mark hypothesis as valid
3320 //================================================================================
3322 void SMESH_Mesh_i::onHypothesisModified(int theHypID, bool theUpdateIcons)
3325 _preMeshInfo->ForgetOrLoad();
3327 if ( theUpdateIcons )
3329 SMESH::SMESH_Mesh_var mesh = _this();
3330 _gen_i->UpdateIcons( mesh );
3333 if ( _nbInvalidHypos != 0 )
3335 // mark a hypothesis as valid after edition
3337 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
3338 SALOMEDS::SObject_wrap hypRoot;
3339 if ( !smeshComp->_is_nil() &&
3340 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
3342 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
3343 for ( ; anIter->More(); anIter->Next() )
3345 SALOMEDS::SObject_wrap hypSO = anIter->Value();
3346 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
3347 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
3348 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
3349 _gen_i->HighLightInvalid( hyp, false );
3351 nbInvalid += _gen_i->IsInvalid( hypSO );
3354 _nbInvalidHypos = nbInvalid;
3358 //=============================================================================
3362 //=============================================================================
3364 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
3366 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
3369 _impl->SetCallUp( new TCallUp_i(this));
3372 //=============================================================================
3376 //=============================================================================
3378 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
3380 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
3384 //=============================================================================
3386 * Return mesh editor
3388 //=============================================================================
3390 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
3391 throw (SALOME::SALOME_Exception)
3393 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3397 _preMeshInfo->FullLoadFromFile();
3399 // Create MeshEditor
3401 _editor = new SMESH_MeshEditor_i( this, false );
3402 aMeshEdVar = _editor->_this();
3404 // Update Python script
3405 TPythonDump() << _editor << " = "
3406 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
3408 SMESH_CATCH( SMESH::throwCorbaException );
3410 return aMeshEdVar._retn();
3413 //=============================================================================
3415 * Return mesh edition previewer
3417 //=============================================================================
3419 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
3420 throw (SALOME::SALOME_Exception)
3422 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3426 _preMeshInfo->FullLoadFromFile();
3428 if ( !_previewEditor )
3429 _previewEditor = new SMESH_MeshEditor_i( this, true );
3430 aMeshEdVar = _previewEditor->_this();
3432 SMESH_CATCH( SMESH::throwCorbaException );
3434 return aMeshEdVar._retn();
3437 //================================================================================
3439 * \brief Return true if the mesh has been edited since a last total re-compute
3440 * and those modifications may prevent successful partial re-compute
3442 //================================================================================
3444 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
3446 Unexpect aCatch(SALOME_SalomeException);
3447 return _impl->HasModificationsToDiscard();
3450 //================================================================================
3452 * \brief Returns a random unique color
3454 //================================================================================
3456 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
3458 const int MAX_ATTEMPTS = 100;
3460 double tolerance = 0.5;
3461 SALOMEDS::Color col;
3465 // generate random color
3466 double red = (double)rand() / RAND_MAX;
3467 double green = (double)rand() / RAND_MAX;
3468 double blue = (double)rand() / RAND_MAX;
3469 // check existence in the list of the existing colors
3470 bool matched = false;
3471 std::list<SALOMEDS::Color>::const_iterator it;
3472 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3473 SALOMEDS::Color color = *it;
3474 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3475 matched = tol < tolerance;
3477 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3478 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3486 //=============================================================================
3488 * Sets auto-color mode. If it is on, groups get unique random colors
3490 //=============================================================================
3492 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
3494 Unexpect aCatch(SALOME_SalomeException);
3495 _impl->SetAutoColor(theAutoColor);
3497 TPythonDump pyDump; // not to dump group->SetColor() from below code
3498 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3500 std::list<SALOMEDS::Color> aReservedColors;
3501 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3502 for ( ; it != _mapGroups.end(); it++ ) {
3503 if ( CORBA::is_nil( it->second )) continue;
3504 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3505 it->second->SetColor( aColor );
3506 aReservedColors.push_back( aColor );
3510 //=============================================================================
3512 * Returns true if auto-color mode is on
3514 //=============================================================================
3516 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
3518 Unexpect aCatch(SALOME_SalomeException);
3519 return _impl->GetAutoColor();
3522 //=============================================================================
3524 * Checks if there are groups with equal names
3526 //=============================================================================
3528 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3530 return _impl->HasDuplicatedGroupNamesMED();
3533 //================================================================================
3535 * \brief Care of a file before exporting mesh into it
3537 //================================================================================
3539 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3541 SMESH_File aFile( file, false );
3543 if ( aFile.exists() ) {
3544 // existing filesystem node
3545 if ( !aFile.isDirectory() ) {
3546 if ( aFile.openForWriting() ) {
3547 if ( overwrite && ! aFile.remove()) {
3548 msg << "Can't replace " << aFile.getName();
3551 msg << "Can't write into " << aFile.getName();
3554 msg << "Location " << aFile.getName() << " is not a file";
3558 // nonexisting file; check if it can be created
3559 if ( !aFile.openForWriting() ) {
3560 msg << "You cannot create the file "
3562 << ". Check the directory existence and access rights";
3570 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3574 //================================================================================
3576 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
3577 * \param file - file name
3578 * \param overwrite - to erase the file or not
3579 * \retval string - mesh name
3581 //================================================================================
3583 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3584 CORBA::Boolean overwrite)
3587 PrepareForWriting(file, overwrite);
3588 string aMeshName = "Mesh";
3589 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3590 if ( !aStudy->_is_nil() ) {
3591 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3592 if ( !aMeshSO->_is_nil() ) {
3593 CORBA::String_var name = aMeshSO->GetName();
3595 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3596 if ( !aStudy->GetProperties()->IsLocked() )
3598 SALOMEDS::GenericAttribute_wrap anAttr;
3599 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3600 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3601 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3602 ASSERT(!aFileName->_is_nil());
3603 aFileName->SetValue(file);
3604 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3605 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3606 ASSERT(!aFileType->_is_nil());
3607 aFileType->SetValue("FICHIERMED");
3611 // Update Python script
3612 // set name of mesh before export
3613 TPythonDump() << _gen_i << ".SetName("
3614 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3616 // check names of groups
3622 //================================================================================
3624 * \brief Export to MED file
3626 //================================================================================
3628 void SMESH_Mesh_i::ExportMED(const char* file,
3629 CORBA::Boolean auto_groups,
3630 CORBA::Long version,
3631 CORBA::Boolean overwrite,
3632 CORBA::Boolean autoDimension)
3633 throw(SALOME::SALOME_Exception)
3635 //MESSAGE("MED minor version: "<< minor);
3638 _preMeshInfo->FullLoadFromFile();
3640 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3641 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3643 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3645 << "auto_groups=" <<auto_groups << ", "
3646 << "minor=" << version << ", "
3647 << "overwrite=" << overwrite << ", "
3648 << "meshPart=None, "
3649 << "autoDimension=" << autoDimension << " )";
3651 SMESH_CATCH( SMESH::throwCorbaException );
3654 //================================================================================
3656 * \brief Export a mesh to a SAUV file
3658 //================================================================================
3660 void SMESH_Mesh_i::ExportSAUV (const char* file,
3661 CORBA::Boolean auto_groups)
3662 throw(SALOME::SALOME_Exception)
3664 Unexpect aCatch(SALOME_SalomeException);
3666 _preMeshInfo->FullLoadFromFile();
3668 string aMeshName = prepareMeshNameAndGroups(file, true);
3669 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3670 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3671 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3675 //================================================================================
3677 * \brief Export a mesh to a DAT file
3679 //================================================================================
3681 void SMESH_Mesh_i::ExportDAT (const char *file)
3682 throw(SALOME::SALOME_Exception)
3684 Unexpect aCatch(SALOME_SalomeException);
3686 _preMeshInfo->FullLoadFromFile();
3688 // Update Python script
3689 // check names of groups
3691 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3694 PrepareForWriting(file);
3695 _impl->ExportDAT(file);
3698 //================================================================================
3700 * \brief Export a mesh to an UNV file
3702 //================================================================================
3704 void SMESH_Mesh_i::ExportUNV (const char *file)
3705 throw(SALOME::SALOME_Exception)
3707 Unexpect aCatch(SALOME_SalomeException);
3709 _preMeshInfo->FullLoadFromFile();
3711 // Update Python script
3712 // check names of groups
3714 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3717 PrepareForWriting(file);
3718 _impl->ExportUNV(file);
3721 //================================================================================
3723 * \brief Export a mesh to an STL file
3725 //================================================================================
3727 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3728 throw(SALOME::SALOME_Exception)
3730 Unexpect aCatch(SALOME_SalomeException);
3732 _preMeshInfo->FullLoadFromFile();
3734 // Update Python script
3735 // check names of groups
3737 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3738 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3740 CORBA::String_var name;
3741 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3742 if ( !so->_is_nil() )
3743 name = so->GetName();
3746 PrepareForWriting( file );
3747 _impl->ExportSTL( file, isascii, name.in() );
3750 //================================================================================
3752 * \brief Export a part of mesh to a med file
3754 //================================================================================
3756 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3758 CORBA::Boolean auto_groups,
3759 CORBA::Long version,
3760 CORBA::Boolean overwrite,
3761 CORBA::Boolean autoDimension,
3762 const GEOM::ListOfFields& fields,
3763 const char* geomAssocFields,
3764 CORBA::Double ZTolerance)
3765 throw (SALOME::SALOME_Exception)
3767 MESSAGE("MED version: "<< version);
3770 _preMeshInfo->FullLoadFromFile();
3773 bool have0dField = false;
3774 if ( fields.length() > 0 )
3776 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3777 if ( shapeToMesh->_is_nil() )
3778 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3780 for ( size_t i = 0; i < fields.length(); ++i )
3782 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3783 THROW_SALOME_CORBA_EXCEPTION
3784 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3785 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3786 if ( fieldShape->_is_nil() )
3787 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3788 if ( !fieldShape->IsSame( shapeToMesh ) )
3789 THROW_SALOME_CORBA_EXCEPTION
3790 ( "Field defined not on shape", SALOME::BAD_PARAM);
3791 if ( fields[i]->GetDimension() == 0 )
3794 if ( geomAssocFields )
3795 for ( int i = 0; geomAssocFields[i]; ++i )
3796 switch ( geomAssocFields[i] ) {
3797 case 'v':case 'e':case 'f':case 's': break;
3798 case 'V':case 'E':case 'F':case 'S': break;
3799 default: THROW_SALOME_CORBA_EXCEPTION
3800 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3804 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3808 string aMeshName = "Mesh";
3809 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3810 if ( CORBA::is_nil( meshPart ) ||
3811 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3813 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3814 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3815 0, autoDimension, /*addODOnVertices=*/have0dField,
3817 meshDS = _impl->GetMeshDS();
3822 _preMeshInfo->FullLoadFromFile();
3824 PrepareForWriting(file, overwrite);
3826 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3827 if ( !SO->_is_nil() ) {
3828 CORBA::String_var name = SO->GetName();
3832 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3833 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3834 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3835 meshDS = tmpDSDeleter._obj = partDS;
3840 if ( _impl->HasShapeToMesh() )
3842 DriverMED_W_Field fieldWriter;
3843 fieldWriter.SetFile( file );
3844 fieldWriter.SetMeshName( aMeshName );
3845 fieldWriter.AddODOnVertices( have0dField );
3847 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3851 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3852 goList->length( fields.length() );
3853 for ( size_t i = 0; i < fields.length(); ++i )
3855 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3858 TPythonDump() << _this() << ".ExportPartToMED( "
3859 << meshPart << ", r'"
3861 << auto_groups << ", "
3863 << overwrite << ", "
3864 << autoDimension << ", "
3866 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
3867 << TVar( ZTolerance )
3870 SMESH_CATCH( SMESH::throwCorbaException );
3873 //================================================================================
3875 * Write GEOM fields to MED file
3877 //================================================================================
3879 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3880 SMESHDS_Mesh* meshDS,
3881 const GEOM::ListOfFields& fields,
3882 const char* geomAssocFields)
3884 #define METH "SMESH_Mesh_i::exportMEDFields() "
3886 if (( fields.length() < 1 ) &&
3887 ( !geomAssocFields || !geomAssocFields[0] ))
3890 std::vector< std::vector< double > > dblVals;
3891 std::vector< std::vector< int > > intVals;
3892 std::vector< int > subIdsByDim[ 4 ];
3893 const double noneDblValue = 0.;
3894 const double noneIntValue = 0;
3896 for ( size_t iF = 0; iF < fields.length(); ++iF )
3900 int dim = fields[ iF ]->GetDimension();
3901 SMDSAbs_ElementType elemType;
3902 TopAbs_ShapeEnum shapeType;
3904 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3905 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3906 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3907 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3909 continue; // skip fields on whole shape
3911 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3912 if ( dataType == GEOM::FDT_String )
3914 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3915 if ( stepIDs->length() < 1 )
3917 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3918 if ( comps->length() < 1 )
3920 CORBA::String_var name = fields[ iF ]->GetName();
3922 if ( !fieldWriter.Set( meshDS,
3926 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3929 for ( size_t iC = 0; iC < comps->length(); ++iC )
3930 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3932 dblVals.resize( comps->length() );
3933 intVals.resize( comps->length() );
3935 // find sub-shape IDs
3937 std::vector< int >& subIds = subIdsByDim[ dim ];
3938 if ( subIds.empty() )
3939 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3940 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3941 subIds.push_back( id );
3945 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3949 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3951 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3952 if ( step->_is_nil() )
3955 CORBA::Long stamp = step->GetStamp();
3956 CORBA::Long id = step->GetID();
3957 fieldWriter.SetDtIt( int( stamp ), int( id ));
3959 // fill dblVals or intVals
3960 for ( size_t iC = 0; iC < comps->length(); ++iC )
3961 if ( dataType == GEOM::FDT_Double )
3963 dblVals[ iC ].clear();
3964 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3968 intVals[ iC ].clear();
3969 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3973 case GEOM::FDT_Double:
3975 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3976 if ( dblStep->_is_nil() ) continue;
3977 GEOM::ListOfDouble_var vv = dblStep->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 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3987 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3988 if ( intStep->_is_nil() ) continue;
3989 GEOM::ListOfLong_var vv = intStep->GetValues();
3990 if ( vv->length() != subIds.size() * comps->length() )
3991 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3992 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3993 for ( size_t iC = 0; iC < comps->length(); ++iC )
3994 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3997 case GEOM::FDT_Bool:
3999 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
4000 if ( boolStep->_is_nil() ) continue;
4001 GEOM::short_array_var vv = boolStep->GetValues();
4002 if ( vv->length() != subIds.size() * comps->length() )
4003 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
4004 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
4005 for ( size_t iC = 0; iC < comps->length(); ++iC )
4006 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
4012 // pass values to fieldWriter
4013 elemIt = fieldWriter.GetOrderedElems();
4014 if ( dataType == GEOM::FDT_Double )
4015 while ( elemIt->more() )
4017 const SMDS_MeshElement* e = elemIt->next();
4018 const int shapeID = e->getshapeId();
4019 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
4020 for ( size_t iC = 0; iC < comps->length(); ++iC )
4021 fieldWriter.AddValue( noneDblValue );
4023 for ( size_t iC = 0; iC < comps->length(); ++iC )
4024 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
4027 while ( elemIt->more() )
4029 const SMDS_MeshElement* e = elemIt->next();
4030 const int shapeID = e->getshapeId();
4031 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
4032 for ( size_t iC = 0; iC < comps->length(); ++iC )
4033 fieldWriter.AddValue( (double) noneIntValue );
4035 for ( size_t iC = 0; iC < comps->length(); ++iC )
4036 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
4040 fieldWriter.Perform();
4041 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4042 if ( res && res->IsKO() )
4044 if ( res->myComment.empty() )
4045 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4047 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4053 if ( !geomAssocFields || !geomAssocFields[0] )
4056 // write geomAssocFields
4058 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
4059 shapeDim[ TopAbs_COMPOUND ] = 3;
4060 shapeDim[ TopAbs_COMPSOLID ] = 3;
4061 shapeDim[ TopAbs_SOLID ] = 3;
4062 shapeDim[ TopAbs_SHELL ] = 2;
4063 shapeDim[ TopAbs_FACE ] = 2;
4064 shapeDim[ TopAbs_WIRE ] = 1;
4065 shapeDim[ TopAbs_EDGE ] = 1;
4066 shapeDim[ TopAbs_VERTEX ] = 0;
4067 shapeDim[ TopAbs_SHAPE ] = 3;
4069 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
4071 std::vector< std::string > compNames;
4072 switch ( geomAssocFields[ iF ]) {
4074 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
4075 compNames.push_back( "dim" );
4078 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
4081 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
4084 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
4088 compNames.push_back( "id" );
4089 for ( size_t iC = 0; iC < compNames.size(); ++iC )
4090 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
4092 fieldWriter.SetDtIt( -1, -1 );
4094 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
4098 if ( compNames.size() == 2 ) // _vertices_
4099 while ( elemIt->more() )
4101 const SMDS_MeshElement* e = elemIt->next();
4102 const int shapeID = e->getshapeId();
4105 fieldWriter.AddValue( (double) -1 );
4106 fieldWriter.AddValue( (double) -1 );
4110 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
4111 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
4112 fieldWriter.AddValue( (double) shapeID );
4116 while ( elemIt->more() )
4118 const SMDS_MeshElement* e = elemIt->next();
4119 const int shapeID = e->getshapeId();
4121 fieldWriter.AddValue( (double) -1 );
4123 fieldWriter.AddValue( (double) shapeID );
4127 fieldWriter.Perform();
4128 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4129 if ( res && res->IsKO() )
4131 if ( res->myComment.empty() )
4132 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4134 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4137 } // loop on geomAssocFields
4142 //================================================================================
4144 * \brief Export a part of mesh to a DAT file
4146 //================================================================================
4148 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
4150 throw (SALOME::SALOME_Exception)
4152 Unexpect aCatch(SALOME_SalomeException);
4154 _preMeshInfo->FullLoadFromFile();
4156 PrepareForWriting(file);
4158 SMESH_MeshPartDS partDS( meshPart );
4159 _impl->ExportDAT(file,&partDS);
4161 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4162 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
4164 //================================================================================
4166 * \brief Export a part of mesh to an UNV file
4168 //================================================================================
4170 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
4172 throw (SALOME::SALOME_Exception)
4174 Unexpect aCatch(SALOME_SalomeException);
4176 _preMeshInfo->FullLoadFromFile();
4178 PrepareForWriting(file);
4180 SMESH_MeshPartDS partDS( meshPart );
4181 _impl->ExportUNV(file, &partDS);
4183 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4184 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
4186 //================================================================================
4188 * \brief Export a part of mesh to an STL file
4190 //================================================================================
4192 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
4194 ::CORBA::Boolean isascii)
4195 throw (SALOME::SALOME_Exception)
4197 Unexpect aCatch(SALOME_SalomeException);
4199 _preMeshInfo->FullLoadFromFile();
4201 PrepareForWriting(file);
4203 CORBA::String_var name;
4204 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4205 if ( !so->_is_nil() )
4206 name = so->GetName();
4208 SMESH_MeshPartDS partDS( meshPart );
4209 _impl->ExportSTL( file, isascii, name.in(), &partDS );
4211 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
4212 << meshPart<< ", r'" << file << "', " << isascii << ")";
4215 //================================================================================
4217 * \brief Export a part of mesh to an STL file
4219 //================================================================================
4221 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
4223 CORBA::Boolean overwrite,
4224 CORBA::Boolean groupElemsByType)
4225 throw (SALOME::SALOME_Exception)
4228 Unexpect aCatch(SALOME_SalomeException);
4230 _preMeshInfo->FullLoadFromFile();
4232 PrepareForWriting(file,overwrite);
4234 std::string meshName("");
4235 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4236 if ( !so->_is_nil() )
4238 CORBA::String_var name = so->GetName();
4239 meshName = name.in();
4243 SMESH_MeshPartDS partDS( meshPart );
4244 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
4246 SMESH_CATCH( SMESH::throwCorbaException );
4248 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
4249 << meshPart<< ", r'" << file << "', " << overwrite << ")";
4251 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
4255 //================================================================================
4257 * \brief Export a part of mesh to a GMF file
4259 //================================================================================
4261 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
4263 bool withRequiredGroups)
4264 throw (SALOME::SALOME_Exception)
4266 Unexpect aCatch(SALOME_SalomeException);
4268 _preMeshInfo->FullLoadFromFile();
4270 PrepareForWriting(file,/*overwrite=*/true);
4272 SMESH_MeshPartDS partDS( meshPart );
4273 _impl->ExportGMF(file, &partDS, withRequiredGroups);
4275 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
4276 << meshPart<< ", r'"
4278 << withRequiredGroups << ")";
4281 //=============================================================================
4283 * Return computation progress [0.,1]
4285 //=============================================================================
4287 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
4291 return _impl->GetComputeProgress();
4293 SMESH_CATCH( SMESH::doNothing );
4297 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
4299 Unexpect aCatch(SALOME_SalomeException);
4301 return _preMeshInfo->NbNodes();
4303 return _impl->NbNodes();
4306 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
4308 Unexpect aCatch(SALOME_SalomeException);
4310 return _preMeshInfo->NbElements();
4312 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
4315 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
4317 Unexpect aCatch(SALOME_SalomeException);
4319 return _preMeshInfo->Nb0DElements();
4321 return _impl->Nb0DElements();
4324 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
4326 Unexpect aCatch(SALOME_SalomeException);
4328 return _preMeshInfo->NbBalls();
4330 return _impl->NbBalls();
4333 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
4335 Unexpect aCatch(SALOME_SalomeException);
4337 return _preMeshInfo->NbEdges();
4339 return _impl->NbEdges();
4342 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
4343 throw(SALOME::SALOME_Exception)
4345 Unexpect aCatch(SALOME_SalomeException);
4347 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
4349 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
4352 //=============================================================================
4354 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
4356 Unexpect aCatch(SALOME_SalomeException);
4358 return _preMeshInfo->NbFaces();
4360 return _impl->NbFaces();
4363 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
4365 Unexpect aCatch(SALOME_SalomeException);
4367 return _preMeshInfo->NbTriangles();
4369 return _impl->NbTriangles();
4372 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
4374 Unexpect aCatch(SALOME_SalomeException);
4376 return _preMeshInfo->NbBiQuadTriangles();
4378 return _impl->NbBiQuadTriangles();
4381 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
4383 Unexpect aCatch(SALOME_SalomeException);
4385 return _preMeshInfo->NbQuadrangles();
4387 return _impl->NbQuadrangles();
4390 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
4392 Unexpect aCatch(SALOME_SalomeException);
4394 return _preMeshInfo->NbBiQuadQuadrangles();
4396 return _impl->NbBiQuadQuadrangles();
4399 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
4401 Unexpect aCatch(SALOME_SalomeException);
4403 return _preMeshInfo->NbPolygons();
4405 return _impl->NbPolygons();
4408 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
4410 Unexpect aCatch(SALOME_SalomeException);
4412 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
4414 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
4417 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
4418 throw(SALOME::SALOME_Exception)
4420 Unexpect aCatch(SALOME_SalomeException);
4422 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
4424 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
4427 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
4428 throw(SALOME::SALOME_Exception)
4430 Unexpect aCatch(SALOME_SalomeException);
4432 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
4434 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
4437 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
4438 throw(SALOME::SALOME_Exception)
4440 Unexpect aCatch(SALOME_SalomeException);
4442 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
4444 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
4447 //=============================================================================
4449 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
4451 Unexpect aCatch(SALOME_SalomeException);
4453 return _preMeshInfo->NbVolumes();
4455 return _impl->NbVolumes();
4458 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
4460 Unexpect aCatch(SALOME_SalomeException);
4462 return _preMeshInfo->NbTetras();
4464 return _impl->NbTetras();
4467 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
4469 Unexpect aCatch(SALOME_SalomeException);
4471 return _preMeshInfo->NbHexas();
4473 return _impl->NbHexas();
4476 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
4478 Unexpect aCatch(SALOME_SalomeException);
4480 return _preMeshInfo->NbTriQuadHexas();
4482 return _impl->NbTriQuadraticHexas();
4485 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
4487 Unexpect aCatch(SALOME_SalomeException);
4489 return _preMeshInfo->NbPyramids();
4491 return _impl->NbPyramids();
4494 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
4496 Unexpect aCatch(SALOME_SalomeException);
4498 return _preMeshInfo->NbPrisms();
4500 return _impl->NbPrisms();
4503 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
4505 Unexpect aCatch(SALOME_SalomeException);
4507 return _preMeshInfo->NbHexPrisms();
4509 return _impl->NbHexagonalPrisms();
4512 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
4514 Unexpect aCatch(SALOME_SalomeException);
4516 return _preMeshInfo->NbPolyhedrons();
4518 return _impl->NbPolyhedrons();
4521 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4522 throw(SALOME::SALOME_Exception)
4524 Unexpect aCatch(SALOME_SalomeException);
4526 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4528 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4531 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4532 throw(SALOME::SALOME_Exception)
4534 Unexpect aCatch(SALOME_SalomeException);
4536 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4538 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4541 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4542 throw(SALOME::SALOME_Exception)
4544 Unexpect aCatch(SALOME_SalomeException);
4546 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4548 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4551 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4552 throw(SALOME::SALOME_Exception)
4554 Unexpect aCatch(SALOME_SalomeException);
4556 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4558 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4561 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4562 throw(SALOME::SALOME_Exception)
4564 Unexpect aCatch(SALOME_SalomeException);
4566 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4568 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4571 //=============================================================================
4573 * Returns nb of published sub-meshes
4575 //=============================================================================
4577 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4579 Unexpect aCatch(SALOME_SalomeException);
4580 return _mapSubMesh_i.size();
4583 //=============================================================================
4585 * Dumps mesh into a string
4587 //=============================================================================
4589 char* SMESH_Mesh_i::Dump()
4593 return CORBA::string_dup( os.str().c_str() );
4596 //=============================================================================
4598 * Method of SMESH_IDSource interface
4600 //=============================================================================
4602 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4604 return GetElementsId();
4607 //=============================================================================
4609 * Returns ids of all elements
4611 //=============================================================================
4613 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4614 throw (SALOME::SALOME_Exception)
4616 Unexpect aCatch(SALOME_SalomeException);
4618 _preMeshInfo->FullLoadFromFile();
4620 SMESH::long_array_var aResult = new SMESH::long_array();
4621 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4623 if ( aSMESHDS_Mesh == NULL )
4624 return aResult._retn();
4626 long nbElements = NbElements();
4627 aResult->length( nbElements );
4628 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4629 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4630 aResult[i] = anIt->next()->GetID();
4632 return aResult._retn();
4636 //=============================================================================
4638 * Returns ids of all elements of given type
4640 //=============================================================================
4642 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4643 throw (SALOME::SALOME_Exception)
4645 Unexpect aCatch(SALOME_SalomeException);
4647 _preMeshInfo->FullLoadFromFile();
4649 SMESH::long_array_var aResult = new SMESH::long_array();
4650 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4652 if ( aSMESHDS_Mesh == NULL )
4653 return aResult._retn();
4655 long nbElements = NbElements();
4657 // No sense in returning ids of elements along with ids of nodes:
4658 // when theElemType == SMESH::ALL, return node ids only if
4659 // there are no elements
4660 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4661 return GetNodesId();
4663 aResult->length( nbElements );
4667 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4668 while ( i < nbElements && anIt->more() )
4669 aResult[i++] = anIt->next()->GetID();
4671 aResult->length( i );
4673 return aResult._retn();
4676 //=============================================================================
4678 * Returns ids of all nodes
4680 //=============================================================================
4682 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4683 throw (SALOME::SALOME_Exception)
4685 Unexpect aCatch(SALOME_SalomeException);
4687 _preMeshInfo->FullLoadFromFile();
4689 SMESH::long_array_var aResult = new SMESH::long_array();
4690 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4692 if ( aMeshDS == NULL )
4693 return aResult._retn();
4695 long nbNodes = NbNodes();
4696 aResult->length( nbNodes );
4697 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4698 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4699 aResult[i] = anIt->next()->GetID();
4701 return aResult._retn();
4704 //=============================================================================
4708 //=============================================================================
4710 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4711 throw (SALOME::SALOME_Exception)
4713 SMESH::ElementType type = SMESH::ALL;
4717 _preMeshInfo->FullLoadFromFile();
4719 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4721 SMESH_CATCH( SMESH::throwCorbaException );
4726 //=============================================================================
4730 //=============================================================================
4732 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4733 throw (SALOME::SALOME_Exception)
4736 _preMeshInfo->FullLoadFromFile();
4738 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4740 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4742 return ( SMESH::EntityType ) e->GetEntityType();
4745 //=============================================================================
4749 //=============================================================================
4751 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4752 throw (SALOME::SALOME_Exception)
4755 _preMeshInfo->FullLoadFromFile();
4757 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4759 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4761 return ( SMESH::GeometryType ) e->GetGeomType();
4764 //=============================================================================
4766 * Returns ID of elements for given submesh
4768 //=============================================================================
4769 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4770 throw (SALOME::SALOME_Exception)
4772 SMESH::long_array_var aResult = new SMESH::long_array();
4776 _preMeshInfo->FullLoadFromFile();
4778 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4779 if(!SM) return aResult._retn();
4781 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4782 if(!SDSM) return aResult._retn();
4784 aResult->length(SDSM->NbElements());
4786 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4788 while ( eIt->more() ) {
4789 aResult[i++] = eIt->next()->GetID();
4792 SMESH_CATCH( SMESH::throwCorbaException );
4794 return aResult._retn();
4797 //=============================================================================
4799 * Returns ID of nodes for given submesh
4800 * If param all==true - returns all nodes, else -
4801 * returns only nodes on shapes.
4803 //=============================================================================
4805 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4807 throw (SALOME::SALOME_Exception)
4809 SMESH::long_array_var aResult = new SMESH::long_array();
4813 _preMeshInfo->FullLoadFromFile();
4815 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4816 if(!SM) return aResult._retn();
4818 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4819 if(!SDSM) return aResult._retn();
4822 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4823 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4824 while ( nIt->more() ) {
4825 const SMDS_MeshNode* elem = nIt->next();
4826 theElems.insert( elem->GetID() );
4829 else { // all nodes of submesh elements
4830 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4831 while ( eIt->more() ) {
4832 const SMDS_MeshElement* anElem = eIt->next();
4833 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4834 while ( nIt->more() ) {
4835 const SMDS_MeshElement* elem = nIt->next();
4836 theElems.insert( elem->GetID() );
4841 aResult->length(theElems.size());
4842 set<int>::iterator itElem;
4844 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4845 aResult[i++] = *itElem;
4847 SMESH_CATCH( SMESH::throwCorbaException );
4849 return aResult._retn();
4852 //=============================================================================
4854 * Returns type of elements for given submesh
4856 //=============================================================================
4858 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4859 throw (SALOME::SALOME_Exception)
4861 SMESH::ElementType type = SMESH::ALL;
4865 _preMeshInfo->FullLoadFromFile();
4867 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4868 if(!SM) return SMESH::ALL;
4870 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4871 if(!SDSM) return SMESH::ALL;
4873 if(SDSM->NbElements()==0)
4874 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4876 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4877 const SMDS_MeshElement* anElem = eIt->next();
4879 type = ( SMESH::ElementType ) anElem->GetType();
4881 SMESH_CATCH( SMESH::throwCorbaException );
4887 //=============================================================================
4889 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4891 //=============================================================================
4893 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4896 _preMeshInfo->FullLoadFromFile();
4898 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4899 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4904 //=============================================================================
4906 * Get XYZ coordinates of node as list of double
4907 * If there is not node for given ID - returns empty list
4909 //=============================================================================
4911 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4914 _preMeshInfo->FullLoadFromFile();
4916 SMESH::double_array_var aResult = new SMESH::double_array();
4917 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4918 if ( aMeshDS == NULL )
4919 return aResult._retn();
4922 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4924 return aResult._retn();
4928 aResult[0] = aNode->X();
4929 aResult[1] = aNode->Y();
4930 aResult[2] = aNode->Z();
4931 return aResult._retn();
4935 //=============================================================================
4937 * For given node returns list of IDs of inverse elements
4938 * If there is not node for given ID - returns empty list
4940 //=============================================================================
4942 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id,
4943 SMESH::ElementType elemType)
4946 _preMeshInfo->FullLoadFromFile();
4948 SMESH::long_array_var aResult = new SMESH::long_array();
4949 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4950 if ( aMeshDS == NULL )
4951 return aResult._retn();
4954 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
4956 return aResult._retn();
4958 // find inverse elements
4959 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
4960 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
4961 aResult->length( aNode->NbInverseElements( type ));
4962 for( int i = 0; eIt->more(); ++i )
4964 const SMDS_MeshElement* elem = eIt->next();
4965 aResult[ i ] = elem->GetID();
4967 return aResult._retn();
4970 //=============================================================================
4972 * \brief Return position of a node on shape
4974 //=============================================================================
4976 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4979 _preMeshInfo->FullLoadFromFile();
4981 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4982 aNodePosition->shapeID = 0;
4983 aNodePosition->shapeType = GEOM::SHAPE;
4985 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4986 if ( !mesh ) return aNodePosition;
4988 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4990 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4992 aNodePosition->shapeID = aNode->getshapeId();
4993 switch ( pos->GetTypeOfPosition() ) {
4995 aNodePosition->shapeType = GEOM::EDGE;
4996 aNodePosition->params.length(1);
4997 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4999 case SMDS_TOP_FACE: {
5000 SMDS_FacePositionPtr fPos = pos;
5001 aNodePosition->shapeType = GEOM::FACE;
5002 aNodePosition->params.length(2);
5003 aNodePosition->params[0] = fPos->GetUParameter();
5004 aNodePosition->params[1] = fPos->GetVParameter();
5007 case SMDS_TOP_VERTEX:
5008 aNodePosition->shapeType = GEOM::VERTEX;
5010 case SMDS_TOP_3DSPACE:
5011 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
5012 aNodePosition->shapeType = GEOM::SOLID;
5013 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
5014 aNodePosition->shapeType = GEOM::SHELL;
5020 return aNodePosition;
5023 //=============================================================================
5025 * \brief Return position of an element on shape
5027 //=============================================================================
5029 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
5032 _preMeshInfo->FullLoadFromFile();
5034 SMESH::ElementPosition anElementPosition;
5035 anElementPosition.shapeID = 0;
5036 anElementPosition.shapeType = GEOM::SHAPE;
5038 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
5039 if ( !mesh ) return anElementPosition;
5041 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
5043 anElementPosition.shapeID = anElem->getshapeId();
5044 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
5045 if ( !aSp.IsNull() ) {
5046 switch ( aSp.ShapeType() ) {
5048 anElementPosition.shapeType = GEOM::EDGE;
5051 anElementPosition.shapeType = GEOM::FACE;
5054 anElementPosition.shapeType = GEOM::VERTEX;
5057 anElementPosition.shapeType = GEOM::SOLID;
5060 anElementPosition.shapeType = GEOM::SHELL;
5066 return anElementPosition;
5069 //=============================================================================
5071 * If given element is node returns IDs of shape from position
5072 * If there is not node for given ID - returns -1
5074 //=============================================================================
5076 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
5079 _preMeshInfo->FullLoadFromFile();
5081 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5082 if ( aMeshDS == NULL )
5086 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
5088 return aNode->getshapeId();
5095 //=============================================================================
5097 * For given element returns ID of result shape after
5098 * ::FindShape() from SMESH_MeshEditor
5099 * If there is not element for given ID - returns -1
5101 //=============================================================================
5103 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
5106 _preMeshInfo->FullLoadFromFile();
5108 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5109 if ( aMeshDS == NULL )
5112 // try to find element
5113 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5117 ::SMESH_MeshEditor aMeshEditor(_impl);
5118 int index = aMeshEditor.FindShape( elem );
5126 //=============================================================================
5128 * Returns number of nodes for given element
5129 * If there is not element for given ID - returns -1
5131 //=============================================================================
5133 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
5136 _preMeshInfo->FullLoadFromFile();
5138 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5139 if ( aMeshDS == NULL ) return -1;
5140 // try to find element
5141 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5142 if(!elem) return -1;
5143 return elem->NbNodes();
5147 //=============================================================================
5149 * Returns ID of node by given index for given element
5150 * If there is not element for given ID - returns -1
5151 * If there is not node for given index - returns -2
5153 //=============================================================================
5155 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
5158 _preMeshInfo->FullLoadFromFile();
5160 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5161 if ( aMeshDS == NULL ) return -1;
5162 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5163 if(!elem) return -1;
5164 if( index>=elem->NbNodes() || index<0 ) return -1;
5165 return elem->GetNode(index)->GetID();
5168 //=============================================================================
5170 * Returns IDs of nodes of given element
5172 //=============================================================================
5174 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
5177 _preMeshInfo->FullLoadFromFile();
5179 SMESH::long_array_var aResult = new SMESH::long_array();
5180 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5182 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
5184 aResult->length( elem->NbNodes() );
5185 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5186 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
5187 aResult[ i ] = n->GetID();
5190 return aResult._retn();
5193 //=============================================================================
5195 * Returns true if given node is medium node
5196 * in given quadratic element
5198 //=============================================================================
5200 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
5203 _preMeshInfo->FullLoadFromFile();
5205 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5206 if ( aMeshDS == NULL ) return false;
5208 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5209 if(!aNode) return false;
5210 // try to find element
5211 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
5212 if(!elem) return false;
5214 return elem->IsMediumNode(aNode);
5218 //=============================================================================
5220 * Returns true if given node is medium node
5221 * in one of quadratic elements
5223 //=============================================================================
5225 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
5226 SMESH::ElementType theElemType)
5229 _preMeshInfo->FullLoadFromFile();
5231 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5232 if ( aMeshDS == NULL ) return false;
5235 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5236 if(!aNode) return false;
5238 SMESH_MesherHelper aHelper( *(_impl) );
5240 SMDSAbs_ElementType aType;
5241 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
5242 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
5243 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
5244 else aType = SMDSAbs_All;
5246 return aHelper.IsMedium(aNode,aType);
5250 //=============================================================================
5252 * Returns number of edges for given element
5254 //=============================================================================
5256 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
5259 _preMeshInfo->FullLoadFromFile();
5261 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5262 if ( aMeshDS == NULL ) return -1;
5263 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5264 if(!elem) return -1;
5265 return elem->NbEdges();
5269 //=============================================================================
5271 * Returns number of faces for given element
5273 //=============================================================================
5275 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
5278 _preMeshInfo->FullLoadFromFile();
5280 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5281 if ( aMeshDS == NULL ) return -1;
5282 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5283 if(!elem) return -1;
5284 return elem->NbFaces();
5287 //=======================================================================
5288 //function : GetElemFaceNodes
5289 //purpose : Returns nodes of given face (counted from zero) for given element.
5290 //=======================================================================
5292 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
5293 CORBA::Short faceIndex)
5296 _preMeshInfo->FullLoadFromFile();
5298 SMESH::long_array_var aResult = new SMESH::long_array();
5299 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5301 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
5303 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
5304 if ( faceIndex < vtool.NbFaces() )
5306 aResult->length( vtool.NbFaceNodes( faceIndex ));
5307 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
5308 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5309 aResult[ i ] = nn[ i ]->GetID();
5313 return aResult._retn();
5316 //=======================================================================
5317 //function : GetFaceNormal
5318 //purpose : Returns three components of normal of given mesh face.
5319 //=======================================================================
5321 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
5322 CORBA::Boolean normalized)
5325 _preMeshInfo->FullLoadFromFile();
5327 SMESH::double_array_var aResult = new SMESH::double_array();
5329 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5332 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
5334 aResult->length( 3 );
5335 aResult[ 0 ] = normal.X();
5336 aResult[ 1 ] = normal.Y();
5337 aResult[ 2 ] = normal.Z();
5340 return aResult._retn();
5343 //=======================================================================
5344 //function : FindElementByNodes
5345 //purpose : Returns an element based on all given nodes.
5346 //=======================================================================
5348 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
5351 _preMeshInfo->FullLoadFromFile();
5353 CORBA::Long elemID(0);
5354 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5356 vector< const SMDS_MeshNode * > nn( nodes.length() );
5357 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5358 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
5361 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
5362 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
5363 _impl->NbFaces ( ORDER_QUADRATIC ) ||
5364 _impl->NbVolumes( ORDER_QUADRATIC )))
5365 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
5367 if ( elem ) elemID = CORBA::Long( elem->GetID() );
5372 //================================================================================
5374 * \brief Return elements including all given nodes.
5376 //================================================================================
5378 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
5379 SMESH::ElementType elemType)
5382 _preMeshInfo->FullLoadFromFile();
5384 SMESH::long_array_var result = new SMESH::long_array();
5386 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5388 vector< const SMDS_MeshNode * > nn( nodes.length() );
5389 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5390 nn[i] = mesh->FindNode( nodes[i] );
5392 std::vector<const SMDS_MeshElement *> elems;
5393 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
5394 result->length( elems.size() );
5395 for ( size_t i = 0; i < elems.size(); ++i )
5396 result[i] = elems[i]->GetID();
5398 return result._retn();
5401 //=============================================================================
5403 * Returns true if given element is polygon
5405 //=============================================================================
5407 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
5410 _preMeshInfo->FullLoadFromFile();
5412 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5413 if ( aMeshDS == NULL ) return false;
5414 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5415 if(!elem) return false;
5416 return elem->IsPoly();
5420 //=============================================================================
5422 * Returns true if given element is quadratic
5424 //=============================================================================
5426 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
5429 _preMeshInfo->FullLoadFromFile();
5431 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5432 if ( aMeshDS == NULL ) return false;
5433 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5434 if(!elem) return false;
5435 return elem->IsQuadratic();
5438 //=============================================================================
5440 * Returns diameter of ball discrete element or zero in case of an invalid \a id
5442 //=============================================================================
5444 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
5447 _preMeshInfo->FullLoadFromFile();
5449 if ( const SMDS_BallElement* ball =
5450 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
5451 return ball->GetDiameter();
5456 //=============================================================================
5458 * Returns bary center for given element
5460 //=============================================================================
5462 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5465 _preMeshInfo->FullLoadFromFile();
5467 SMESH::double_array_var aResult = new SMESH::double_array();
5468 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5469 if ( aMeshDS == NULL )
5470 return aResult._retn();
5472 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5474 return aResult._retn();
5476 if(elem->GetType()==SMDSAbs_Volume) {
5477 SMDS_VolumeTool aTool;
5478 if(aTool.Set(elem)) {
5480 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5485 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5487 double x=0., y=0., z=0.;
5488 for(; anIt->more(); ) {
5490 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5504 return aResult._retn();
5507 //================================================================================
5509 * \brief Create a group of elements preventing computation of a sub-shape
5511 //================================================================================
5513 SMESH::ListOfGroups*
5514 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5515 const char* theGroupName )
5516 throw ( SALOME::SALOME_Exception )
5518 Unexpect aCatch(SALOME_SalomeException);
5520 if ( !theGroupName || strlen( theGroupName) == 0 )
5521 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5523 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5524 ::SMESH_MeshEditor::ElemFeatures elemType;
5526 // submesh by subshape id
5527 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5528 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5531 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5532 if ( error && error->HasBadElems() )
5534 // sort bad elements by type
5535 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5536 const list<const SMDS_MeshElement*>& badElems =
5537 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5538 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5539 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5540 for ( ; elemIt != elemEnd; ++elemIt )
5542 const SMDS_MeshElement* elem = *elemIt;
5543 if ( !elem ) continue;
5545 if ( elem->GetID() < 1 )
5547 // elem is a temporary element, make a real element
5548 vector< const SMDS_MeshNode* > nodes;
5549 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5550 while ( nIt->more() && elem )
5552 nodes.push_back( nIt->next() );
5553 if ( nodes.back()->GetID() < 1 )
5554 elem = 0; // a temporary element on temporary nodes
5558 ::SMESH_MeshEditor editor( _impl );
5559 elem = editor.AddElement( nodes, elemType.Init( elem ));
5563 elemsByType[ elem->GetType() ].push_back( elem );
5566 // how many groups to create?
5568 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5569 nbTypes += int( !elemsByType[ i ].empty() );
5570 groups->length( nbTypes );
5573 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5575 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5576 if ( elems.empty() ) continue;
5578 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5579 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5581 SMESH::SMESH_Mesh_var mesh = _this();
5582 SALOMEDS::SObject_wrap aSO =
5583 _gen_i->PublishGroup( mesh, groups[ iG ],
5584 GEOM::GEOM_Object::_nil(), theGroupName);
5586 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5587 if ( !grp_i ) continue;
5589 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5590 for ( size_t iE = 0; iE < elems.size(); ++iE )
5591 grpDS->SMDSGroup().Add( elems[ iE ]);
5596 return groups._retn();
5599 //=============================================================================
5601 * Create and publish group servants if any groups were imported or created anyhow
5603 //=============================================================================
5605 void SMESH_Mesh_i::CreateGroupServants()
5607 SMESH::SMESH_Mesh_var aMesh = _this();
5610 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5611 while ( groupIt->more() )
5613 ::SMESH_Group* group = groupIt->next();
5614 int anId = group->GetID();
5616 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5617 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5619 addedIDs.insert( anId );
5621 SMESH_GroupBase_i* aGroupImpl;
5623 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5624 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5626 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5627 shape = groupOnGeom->GetShape();
5630 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5633 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5634 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5635 aGroupImpl->Register();
5637 // register CORBA object for persistence
5638 int nextId = _gen_i->RegisterObject( groupVar );
5639 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5640 else { nextId = 0; } // avoid "unused variable" warning in release mode
5642 // publishing the groups in the study
5643 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5644 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5646 if ( !addedIDs.empty() )
5649 set<int>::iterator id = addedIDs.begin();
5650 for ( ; id != addedIDs.end(); ++id )
5652 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5653 int i = std::distance( _mapGroups.begin(), it );
5654 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5659 //=============================================================================
5661 * \brief Return true if all sub-meshes are computed OK - to update an icon
5663 //=============================================================================
5665 bool SMESH_Mesh_i::IsComputedOK()
5667 return _impl->IsComputedOK();
5670 //=============================================================================
5672 * \brief Return groups cantained in _mapGroups by their IDs
5674 //=============================================================================
5676 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5678 int nbGroups = groupIDs.size();
5679 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5680 aList->length( nbGroups );
5682 list<int>::const_iterator ids = groupIDs.begin();
5683 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5685 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5686 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5687 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5689 aList->length( nbGroups );
5690 return aList._retn();
5693 //=============================================================================
5695 * \brief Return information about imported file
5697 //=============================================================================
5699 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5701 SMESH::MedFileInfo_var res( _medFileInfo );
5702 if ( !res.operator->() ) {
5703 res = new SMESH::MedFileInfo;
5705 res->fileSize = res->major = res->minor = res->release = -1;
5710 //=======================================================================
5711 //function : FileInfoToString
5712 //purpose : Persistence of file info
5713 //=======================================================================
5715 std::string SMESH_Mesh_i::FileInfoToString()
5718 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5720 s = SMESH_Comment( _medFileInfo->fileSize )
5721 << " " << _medFileInfo->major
5722 << " " << _medFileInfo->minor
5723 << " " << _medFileInfo->release
5724 << " " << _medFileInfo->fileName;
5729 //=======================================================================
5730 //function : FileInfoFromString
5731 //purpose : Persistence of file info
5732 //=======================================================================
5734 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5736 std::string size, major, minor, release, fileName;
5737 std::istringstream is(info);
5738 is >> size >> major >> minor >> release;
5739 fileName = info.data() + ( size.size() + 1 +
5742 release.size()+ 1 );
5744 _medFileInfo = new SMESH::MedFileInfo();
5745 _medFileInfo->fileName = fileName.c_str();
5746 _medFileInfo->fileSize = atoi( size.c_str() );
5747 _medFileInfo->major = atoi( major.c_str() );
5748 _medFileInfo->minor = atoi( minor.c_str() );
5749 _medFileInfo->release = atoi( release.c_str() );
5752 //=============================================================================
5754 * \brief Pass names of mesh groups from study to mesh DS
5756 //=============================================================================
5758 void SMESH_Mesh_i::checkGroupNames()
5760 int nbGrp = NbGroups();
5764 SMESH::ListOfGroups* grpList = 0;
5765 // avoid dump of "GetGroups"
5767 // store python dump into a local variable inside local scope
5768 SMESH::TPythonDump pDump; // do not delete this line of code
5769 grpList = GetGroups();
5772 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5773 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5776 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5777 if ( aGrpSO->_is_nil() )
5779 // correct name of the mesh group if necessary
5780 const char* guiName = aGrpSO->GetName();
5781 if ( strcmp(guiName, aGrp->GetName()) )
5782 aGrp->SetName( guiName );
5786 //=============================================================================
5788 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5790 //=============================================================================
5791 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5793 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5797 //=============================================================================
5799 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5801 //=============================================================================
5803 char* SMESH_Mesh_i::GetParameters()
5805 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5808 //=============================================================================
5810 * \brief Returns list of notebook variables used for last Mesh operation
5812 //=============================================================================
5813 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5815 SMESH::string_array_var aResult = new SMESH::string_array();
5816 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5818 CORBA::String_var aParameters = GetParameters();
5819 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5820 if ( aSections->length() > 0 ) {
5821 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5822 aResult->length( aVars.length() );
5823 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5824 aResult[i] = CORBA::string_dup( aVars[i] );
5827 return aResult._retn();
5830 //=======================================================================
5831 //function : GetTypes
5832 //purpose : Returns types of elements it contains
5833 //=======================================================================
5835 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5838 return _preMeshInfo->GetTypes();
5840 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5844 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5845 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5846 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5847 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5848 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5849 if (_impl->NbNodes() &&
5850 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5851 types->length( nbTypes );
5853 return types._retn();
5856 //=======================================================================
5857 //function : GetMesh
5858 //purpose : Returns self
5859 //=======================================================================
5861 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5863 return SMESH::SMESH_Mesh::_duplicate( _this() );
5866 //=======================================================================
5867 //function : IsMeshInfoCorrect
5868 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5869 // * happen if mesh data is not yet fully loaded from the file of study.
5870 //=======================================================================
5872 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5874 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5877 //=============================================================================
5879 * \brief Returns number of mesh elements per each \a EntityType
5881 //=============================================================================
5883 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5886 return _preMeshInfo->GetMeshInfo();
5888 SMESH::long_array_var aRes = new SMESH::long_array();
5889 aRes->length(SMESH::Entity_Last);
5890 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5892 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5894 return aRes._retn();
5895 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5896 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5897 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5898 return aRes._retn();
5901 //=============================================================================
5903 * \brief Returns number of mesh elements per each \a ElementType
5905 //=============================================================================
5907 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5909 SMESH::long_array_var aRes = new SMESH::long_array();
5910 aRes->length(SMESH::NB_ELEMENT_TYPES);
5911 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5914 const SMDS_MeshInfo* meshInfo = 0;
5916 meshInfo = _preMeshInfo;
5917 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5918 meshInfo = & meshDS->GetMeshInfo();
5921 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5922 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5924 return aRes._retn();
5927 //=============================================================================
5929 * Collect statistic of mesh elements given by iterator
5931 //=============================================================================
5933 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5934 SMESH::long_array& theInfo)
5936 if (!theItr) return;
5937 while (theItr->more())
5938 theInfo[ theItr->next()->GetEntityType() ]++;
5940 //=============================================================================
5942 * Returns mesh unstructed grid information.
5944 //=============================================================================
5946 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5948 SALOMEDS::TMPFile_var SeqFile;
5949 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5950 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5952 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5953 aWriter->WriteToOutputStringOn();
5954 aWriter->SetInputData(aGrid);
5955 aWriter->SetFileTypeToBinary();
5957 char* str = aWriter->GetOutputString();
5958 int size = aWriter->GetOutputStringLength();
5960 //Allocate octet buffer of required size
5961 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5962 //Copy ostrstream content to the octet buffer
5963 memcpy(OctetBuf, str, size);
5964 //Create and return TMPFile
5965 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5969 return SeqFile._retn();
5972 //=============================================================================
5973 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5974 * SMESH::ElementType type) */
5976 using namespace SMESH::Controls;
5977 //-----------------------------------------------------------------------------
5978 struct PredicateIterator : public SMDS_ElemIterator
5980 SMDS_ElemIteratorPtr _elemIter;
5981 PredicatePtr _predicate;
5982 const SMDS_MeshElement* _elem;
5983 SMDSAbs_ElementType _type;
5985 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5986 PredicatePtr predicate,
5987 SMDSAbs_ElementType type):
5988 _elemIter(iterator), _predicate(predicate), _type(type)
5996 virtual const SMDS_MeshElement* next()
5998 const SMDS_MeshElement* res = _elem;
6000 while ( _elemIter->more() && !_elem )
6002 if ((_elem = _elemIter->next()) &&
6003 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
6004 ( !_predicate->IsSatisfy( _elem->GetID() ))))
6011 //-----------------------------------------------------------------------------
6012 struct IDSourceIterator : public SMDS_ElemIterator
6014 const CORBA::Long* _idPtr;
6015 const CORBA::Long* _idEndPtr;
6016 SMESH::long_array_var _idArray;
6017 const SMDS_Mesh* _mesh;
6018 const SMDSAbs_ElementType _type;
6019 const SMDS_MeshElement* _elem;
6021 IDSourceIterator( const SMDS_Mesh* mesh,
6022 const CORBA::Long* ids,
6024 SMDSAbs_ElementType type):
6025 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
6027 if ( _idPtr && nbIds && _mesh )
6030 IDSourceIterator( const SMDS_Mesh* mesh,
6031 SMESH::long_array* idArray,
6032 SMDSAbs_ElementType type):
6033 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
6035 if ( idArray && _mesh )
6037 _idPtr = &_idArray[0];
6038 _idEndPtr = _idPtr + _idArray->length();
6046 virtual const SMDS_MeshElement* next()
6048 const SMDS_MeshElement* res = _elem;
6050 while ( _idPtr < _idEndPtr && !_elem )
6052 if ( _type == SMDSAbs_Node )
6054 _elem = _mesh->FindNode( *_idPtr++ );
6056 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
6057 (_elem->GetType() != _type && _type != SMDSAbs_All ))
6065 //-----------------------------------------------------------------------------
6067 struct NodeOfElemIterator : public SMDS_ElemIterator
6069 TColStd_MapOfInteger _checkedNodeIDs;
6070 SMDS_ElemIteratorPtr _elemIter;
6071 SMDS_ElemIteratorPtr _nodeIter;
6072 const SMDS_MeshElement* _node;
6074 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
6076 if ( _elemIter && _elemIter->more() )
6078 _nodeIter = _elemIter->next()->nodesIterator();
6086 virtual const SMDS_MeshElement* next()
6088 const SMDS_MeshElement* res = _node;
6090 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
6092 if ( _nodeIter->more() )
6094 _node = _nodeIter->next();
6095 if ( !_checkedNodeIDs.Add( _node->GetID() ))
6100 _nodeIter = _elemIter->next()->nodesIterator();
6108 //=============================================================================
6110 * Return iterator on elements of given type in given object
6112 //=============================================================================
6114 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
6115 SMESH::ElementType theType)
6117 SMDS_ElemIteratorPtr elemIt;
6118 bool typeOK = ( theType == SMESH::ALL );
6119 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
6121 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
6122 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
6123 if ( !mesh_i ) return elemIt;
6124 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
6126 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
6128 elemIt = meshDS->elementsIterator( elemType );
6131 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
6133 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
6136 elemIt = sm->GetElements();
6137 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6139 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
6140 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
6144 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
6146 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
6147 if ( groupDS && ( elemType == groupDS->GetType() ||
6148 elemType == SMDSAbs_Node ||
6149 elemType == SMDSAbs_All ))
6151 elemIt = groupDS->GetElements();
6152 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
6155 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
6157 if ( filter_i->GetElementType() == theType ||
6158 filter_i->GetElementType() == SMESH::ALL ||
6159 elemType == SMDSAbs_Node ||
6160 elemType == SMDSAbs_All)
6162 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
6163 if ( pred_i && pred_i->GetPredicate() )
6165 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
6166 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
6167 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
6168 elemIt = SMDS_ElemIteratorPtr
6169 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
6170 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
6176 SMESH::array_of_ElementType_var types = theObject->GetTypes();
6177 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
6178 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6180 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
6181 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
6184 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
6185 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
6189 SMESH::long_array_var ids = theObject->GetIDs();
6190 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
6192 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
6195 if ( elemIt && elemIt->more() && !typeOK )
6197 if ( elemType == SMDSAbs_Node )
6199 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
6203 elemIt = SMDS_ElemIteratorPtr();
6209 //=============================================================================
6210 namespace // Finding concurrent hypotheses
6211 //=============================================================================
6215 * \brief mapping of mesh dimension into shape type
6217 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
6219 TopAbs_ShapeEnum aType = TopAbs_SOLID;
6221 case 0: aType = TopAbs_VERTEX; break;
6222 case 1: aType = TopAbs_EDGE; break;
6223 case 2: aType = TopAbs_FACE; break;
6225 default:aType = TopAbs_SOLID; break;
6230 //-----------------------------------------------------------------------------
6232 * \brief Internal structure used to find concurrent submeshes
6234 * It represents a pair < submesh, concurrent dimension >, where
6235 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
6236 * with another submesh. In other words, it is dimension of a hypothesis assigned
6243 int _dim; //!< a dimension the algo can build (concurrent dimension)
6244 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
6245 TopTools_MapOfShape _shapeMap;
6246 SMESH_subMesh* _subMesh;
6247 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
6249 //-----------------------------------------------------------------------------
6250 // Return the algorithm
6251 const SMESH_Algo* GetAlgo() const
6252 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
6254 //-----------------------------------------------------------------------------
6256 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
6258 const TopoDS_Shape& theShape)
6260 _subMesh = (SMESH_subMesh*)theSubMesh;
6261 SetShape( theDim, theShape );
6264 //-----------------------------------------------------------------------------
6266 void SetShape(const int theDim,
6267 const TopoDS_Shape& theShape)
6270 _ownDim = SMESH_Gen::GetShapeDim(theShape);
6271 if (_dim >= _ownDim)
6272 _shapeMap.Add( theShape );
6274 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
6275 for( ; anExp.More(); anExp.Next() )
6276 _shapeMap.Add( anExp.Current() );
6280 //-----------------------------------------------------------------------------
6281 //! Check sharing of sub-shapes
6282 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
6283 const TopTools_MapOfShape& theToFind,
6284 const TopAbs_ShapeEnum theType)
6286 bool isShared = false;
6287 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
6288 for (; !isShared && anItr.More(); anItr.Next() )
6290 const TopoDS_Shape aSubSh = anItr.Key();
6291 // check for case when concurrent dimensions are same
6292 isShared = theToFind.Contains( aSubSh );
6293 // check for sub-shape with concurrent dimension
6294 TopExp_Explorer anExp( aSubSh, theType );
6295 for ( ; !isShared && anExp.More(); anExp.Next() )
6296 isShared = theToFind.Contains( anExp.Current() );
6301 //-----------------------------------------------------------------------------
6302 //! check algorithms
6303 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
6304 const SMESHDS_Hypothesis* theA2)
6306 if ( !theA1 || !theA2 ||
6307 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
6308 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
6309 return false; // one of the hypothesis is not algorithm
6310 // check algorithm names (should be equal)
6311 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
6315 //-----------------------------------------------------------------------------
6316 //! Check if sub-shape hypotheses are concurrent
6317 bool IsConcurrent(const SMESH_DimHyp* theOther) const
6319 if ( _subMesh == theOther->_subMesh )
6320 return false; // same sub-shape - should not be
6322 // if ( <own dim of either of submeshes> == <concurrent dim> &&
6323 // any of the two submeshes is not on COMPOUND shape )
6324 // -> no concurrency
6325 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
6326 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
6327 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
6328 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
6329 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
6332 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
6333 if ( !checkSubShape )
6336 // check algorithms to be same
6337 const SMESH_Algo* a1 = this->GetAlgo();
6338 const SMESH_Algo* a2 = theOther->GetAlgo();
6339 bool isSame = checkAlgo( a1, a2 );
6343 return false; // pb?
6344 return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency !
6347 // check hypothesises for concurrence (skip first as algorithm)
6349 // pointers should be same, because it is referened from mesh hypothesis partition
6350 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
6351 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
6352 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
6353 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
6355 // the submeshes are concurrent if their algorithms has different parameters
6356 return nbSame != theOther->_hypotheses.size() - 1;
6359 // Return true if algorithm of this SMESH_DimHyp is used if no
6360 // sub-mesh order is imposed by the user
6361 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
6363 // NeedDiscreteBoundary() algo has a higher priority
6364 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
6365 theOther->GetAlgo()->NeedDiscreteBoundary() )
6366 return !this->GetAlgo()->NeedDiscreteBoundary();
6368 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
6371 }; // end of SMESH_DimHyp
6372 //-----------------------------------------------------------------------------
6374 typedef list<const SMESH_DimHyp*> TDimHypList;
6376 //-----------------------------------------------------------------------------
6378 void addDimHypInstance(const int theDim,
6379 const TopoDS_Shape& theShape,
6380 const SMESH_Algo* theAlgo,
6381 const SMESH_subMesh* theSubMesh,
6382 const list <const SMESHDS_Hypothesis*>& theHypList,
6383 TDimHypList* theDimHypListArr )
6385 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
6386 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
6387 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
6388 dimHyp->_hypotheses.push_front(theAlgo);
6389 listOfdimHyp.push_back( dimHyp );
6392 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
6393 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
6394 theHypList.begin(), theHypList.end() );
6397 //-----------------------------------------------------------------------------
6398 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
6399 TDimHypList& theListOfConcurr)
6401 if ( theListOfConcurr.empty() )
6403 theListOfConcurr.push_back( theDimHyp );
6407 TDimHypList::iterator hypIt = theListOfConcurr.begin();
6408 while ( hypIt != theListOfConcurr.end() &&
6409 !theDimHyp->IsHigherPriorityThan( *hypIt ))
6411 theListOfConcurr.insert( hypIt, theDimHyp );
6415 //-----------------------------------------------------------------------------
6416 void findConcurrents(const SMESH_DimHyp* theDimHyp,
6417 const TDimHypList& theListOfDimHyp,
6418 TDimHypList& theListOfConcurrHyp,
6419 set<int>& theSetOfConcurrId )
6421 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
6422 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
6424 const SMESH_DimHyp* curDimHyp = *rIt;
6425 if ( curDimHyp == theDimHyp )
6426 break; // meet own dimHyp pointer in same dimension
6428 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
6429 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
6431 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
6436 //-----------------------------------------------------------------------------
6437 void unionLists(TListOfInt& theListOfId,
6438 TListOfListOfInt& theListOfListOfId,
6441 TListOfListOfInt::iterator it = theListOfListOfId.begin();
6442 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
6444 continue; //skip already treated lists
6445 // check if other list has any same submesh object
6446 TListOfInt& otherListOfId = *it;
6447 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
6448 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
6451 // union two lists (from source into target)
6452 TListOfInt::iterator it2 = otherListOfId.begin();
6453 for ( ; it2 != otherListOfId.end(); it2++ ) {
6454 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
6455 theListOfId.push_back(*it2);
6457 // clear source list
6458 otherListOfId.clear();
6461 //-----------------------------------------------------------------------------
6463 //! free memory allocated for dimension-hypothesis objects
6464 void removeDimHyps( TDimHypList* theArrOfList )
6466 for (int i = 0; i < 4; i++ ) {
6467 TDimHypList& listOfdimHyp = theArrOfList[i];
6468 TDimHypList::const_iterator it = listOfdimHyp.begin();
6469 for ( ; it != listOfdimHyp.end(); it++ )
6474 //-----------------------------------------------------------------------------
6476 * \brief find common submeshes with given submesh
6477 * \param theSubMeshList list of already collected submesh to check
6478 * \param theSubMesh given submesh to intersect with other
6479 * \param theCommonSubMeshes collected common submeshes
6481 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6482 const SMESH_subMesh* theSubMesh,
6483 set<const SMESH_subMesh*>& theCommon )
6487 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6488 for ( ; it != theSubMeshList.end(); it++ )
6489 theSubMesh->FindIntersection( *it, theCommon );
6490 theSubMeshList.push_back( theSubMesh );
6491 //theCommon.insert( theSubMesh );
6494 //-----------------------------------------------------------------------------
6495 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6497 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6498 for ( ; listsIt != smLists.end(); ++listsIt )
6500 const TListOfInt& smIDs = *listsIt;
6501 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6509 //=============================================================================
6511 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6513 //=============================================================================
6515 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6517 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6518 if ( isSubMeshInList( submeshID, anOrder ))
6521 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6522 return isSubMeshInList( submeshID, allConurrent );
6525 //=============================================================================
6527 * \brief Return submesh objects list in meshing order
6529 //=============================================================================
6531 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6533 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6535 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6537 return aResult._retn();
6539 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6540 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6541 anOrder.splice( anOrder.end(), allConurrent );
6544 TListOfListOfInt::iterator listIt = anOrder.begin();
6545 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6546 unionLists( *listIt, anOrder, listIndx + 1 );
6548 // convert submesh ids into interface instances
6549 // and dump command into python
6550 convertMeshOrder( anOrder, aResult, false );
6552 return aResult._retn();
6555 //=============================================================================
6557 * \brief Finds concurrent sub-meshes
6559 //=============================================================================
6561 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6563 TListOfListOfInt anOrder;
6564 ::SMESH_Mesh& mesh = GetImpl();
6566 // collect submeshes and detect concurrent algorithms and hypothesises
6567 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6569 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6570 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
6571 ::SMESH_subMesh* sm = (*i_sm).second;
6573 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6575 // list of assigned hypothesises
6576 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6577 // Find out dimensions where the submesh can be concurrent.
6578 // We define the dimensions by algo of each of hypotheses in hypList
6579 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6580 for( ; hypIt != hypList.end(); hypIt++ ) {
6581 SMESH_Algo* anAlgo = 0;
6582 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6583 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6584 // hyp it-self is algo
6585 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6587 // try to find algorithm with help of sub-shapes
6588 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6589 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6590 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6593 continue; // no algorithm assigned to a current submesh
6595 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6596 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
6598 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6599 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6600 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6602 } // end iterations on submesh
6604 // iterate on created dimension-hypotheses and check for concurrents
6605 for ( int i = 0; i < 4; i++ ) {
6606 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6607 // check for concurrents in own and other dimensions (step-by-step)
6608 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6609 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
6610 const SMESH_DimHyp* dimHyp = *dhIt;
6611 TDimHypList listOfConcurr;
6612 set<int> setOfConcurrIds;
6613 // looking for concurrents and collect into own list
6614 for ( int j = i; j < 4; j++ )
6615 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6616 // check if any concurrents found
6617 if ( listOfConcurr.size() > 0 ) {
6618 // add own submesh to list of concurrent
6619 addInOrderOfPriority( dimHyp, listOfConcurr );
6620 list<int> listOfConcurrIds;
6621 TDimHypList::iterator hypIt = listOfConcurr.begin();
6622 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6623 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6624 anOrder.push_back( listOfConcurrIds );
6629 removeDimHyps(dimHypListArr);
6631 // now, minimize the number of concurrent groups
6632 // Here we assume that lists of submeshes can have same submesh
6633 // in case of multi-dimension algorithms, as result
6634 // list with common submesh has to be united into one list
6636 TListOfListOfInt::iterator listIt = anOrder.begin();
6637 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6638 unionLists( *listIt, anOrder, listIndx + 1 );
6644 //=============================================================================
6646 * \brief Set submesh object order
6647 * \param theSubMeshArray submesh array order
6649 //=============================================================================
6651 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6654 _preMeshInfo->ForgetOrLoad();
6657 ::SMESH_Mesh& mesh = GetImpl();
6659 TPythonDump aPythonDump; // prevent dump of called methods
6660 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6662 TListOfListOfInt subMeshOrder;
6663 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6665 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6666 TListOfInt subMeshIds;
6668 aPythonDump << ", ";
6669 aPythonDump << "[ ";
6670 // Collect subMeshes which should be clear
6671 // do it list-by-list, because modification of submesh order
6672 // take effect between concurrent submeshes only
6673 set<const SMESH_subMesh*> subMeshToClear;
6674 list<const SMESH_subMesh*> subMeshList;
6675 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6677 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6679 aPythonDump << ", ";
6680 aPythonDump << subMesh;
6681 subMeshIds.push_back( subMesh->GetId() );
6682 // detect common parts of submeshes
6683 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6684 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6686 aPythonDump << " ]";
6687 subMeshOrder.push_back( subMeshIds );
6689 // clear collected sub-meshes
6690 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6691 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6692 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6694 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6695 if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748
6696 sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo
6699 aPythonDump << " ])";
6701 mesh.SetMeshOrder( subMeshOrder );
6704 SMESH::SMESH_Mesh_var me = _this();
6705 _gen_i->UpdateIcons( me );
6710 //=============================================================================
6712 * \brief Convert submesh ids into submesh interfaces
6714 //=============================================================================
6716 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6717 SMESH::submesh_array_array& theResOrder,
6718 const bool theIsDump)
6720 int nbSet = theIdsOrder.size();
6721 TPythonDump aPythonDump; // prevent dump of called methods
6723 aPythonDump << "[ ";
6724 theResOrder.length(nbSet);
6725 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6727 for( ; it != theIdsOrder.end(); it++ ) {
6728 // translate submesh identificators into submesh objects
6729 // takeing into account real number of concurrent lists
6730 const TListOfInt& aSubOrder = (*it);
6731 if (!aSubOrder.size())
6734 aPythonDump << "[ ";
6735 // convert shape indices into interfaces
6736 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6737 aResSubSet->length(aSubOrder.size());
6738 TListOfInt::const_iterator subIt = aSubOrder.begin();
6740 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6741 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6743 SMESH::SMESH_subMesh_var subMesh =
6744 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6747 aPythonDump << ", ";
6748 aPythonDump << subMesh;
6750 aResSubSet[ j++ ] = subMesh;
6753 aPythonDump << " ]";
6755 theResOrder[ listIndx++ ] = aResSubSet;
6757 // correct number of lists
6758 theResOrder.length( listIndx );
6761 // finilise python dump
6762 aPythonDump << " ]";
6763 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6767 namespace // utils used by SMESH_MeshPartDS
6770 * \brief Class used to access to protected data of SMDS_MeshInfo
6772 struct TMeshInfo : public SMDS_MeshInfo
6774 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6777 * \brief Element holing its ID only
6779 struct TElemID : public SMDS_LinearEdge
6781 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6785 //================================================================================
6787 // Implementation of SMESH_MeshPartDS
6789 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6790 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6792 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6793 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6796 _meshDS = mesh_i->GetImpl().GetMeshDS();
6798 SetPersistentId( _meshDS->GetPersistentId() );
6800 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6802 // <meshPart> is the whole mesh
6803 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6805 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6806 myGroupSet = _meshDS->GetGroups();
6811 SMESH::long_array_var anIDs = meshPart->GetIDs();
6812 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6813 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6815 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6816 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6817 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6822 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6823 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6824 if ( _elements[ e->GetType() ].insert( e ).second )
6827 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6828 while ( nIt->more() )
6830 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6831 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6838 ShapeToMesh( _meshDS->ShapeToMesh() );
6840 _meshDS = 0; // to enforce iteration on _elements and _nodes
6843 // -------------------------------------------------------------------------------------
6844 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6845 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6848 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6849 for ( ; partIt != meshPart.end(); ++partIt )
6850 if ( const SMDS_MeshElement * e = *partIt )
6851 if ( _elements[ e->GetType() ].insert( e ).second )
6854 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6855 while ( nIt->more() )
6857 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6858 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6864 // -------------------------------------------------------------------------------------
6865 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6867 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6869 TElemID elem( IDelem );
6870 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6871 if ( !_elements[ iType ].empty() )
6873 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6874 if ( it != _elements[ iType ].end() )
6879 // -------------------------------------------------------------------------------------
6880 bool SMESH_MeshPartDS::HasNumerationHoles()
6882 if ( _meshDS ) return _meshDS->HasNumerationHoles();
6884 return ( MinNodeID() != 1 ||
6885 MaxNodeID() != NbNodes() ||
6886 MinElementID() != 1 ||
6887 MaxElementID() != NbElements() );
6889 // -------------------------------------------------------------------------------------
6890 int SMESH_MeshPartDS::MaxNodeID() const
6892 if ( _meshDS ) return _meshDS->MaxNodeID();
6893 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID();
6895 // -------------------------------------------------------------------------------------
6896 int SMESH_MeshPartDS::MinNodeID() const
6898 if ( _meshDS ) return _meshDS->MinNodeID();
6899 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID();
6901 // -------------------------------------------------------------------------------------
6902 int SMESH_MeshPartDS::MaxElementID() const
6904 if ( _meshDS ) return _meshDS->MaxElementID();
6906 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6907 if ( !_elements[ iType ].empty() )
6908 maxID = Max( maxID, (*_elements[ iType ].rbegin())->GetID() );
6911 // -------------------------------------------------------------------------------------
6912 int SMESH_MeshPartDS::MinElementID() const
6914 if ( _meshDS ) return _meshDS->MinElementID();
6916 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6917 if ( !_elements[ iType ].empty() )
6918 minID = Min( minID, (*_elements[ iType ].begin())->GetID() );
6921 // -------------------------------------------------------------------------------------
6922 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6924 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6926 typedef SMDS_SetIterator
6927 <const SMDS_MeshElement*,
6928 TIDSortedElemSet::const_iterator,
6929 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6930 SMDS_MeshElement::GeomFilter
6933 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6935 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6936 _elements[type].end(),
6937 SMDS_MeshElement::GeomFilter( geomType )));
6939 // -------------------------------------------------------------------------------------
6940 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6942 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6944 typedef SMDS_SetIterator
6945 <const SMDS_MeshElement*,
6946 TIDSortedElemSet::const_iterator,
6947 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6948 SMDS_MeshElement::EntityFilter
6951 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6953 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6954 _elements[type].end(),
6955 SMDS_MeshElement::EntityFilter( entity )));
6957 // -------------------------------------------------------------------------------------
6958 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6960 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6961 if ( type == SMDSAbs_All && !_meshDS )
6963 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6965 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6966 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6968 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6970 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6971 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6973 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6974 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6976 // -------------------------------------------------------------------------------------
6977 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6978 iterType SMESH_MeshPartDS::methName() const \
6980 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6981 return _meshDS ? _meshDS->methName() : iterType \
6982 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6984 // -------------------------------------------------------------------------------------
6985 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6986 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6987 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6988 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6989 #undef _GET_ITER_DEFINE
6991 // END Implementation of SMESH_MeshPartDS
6993 //================================================================================