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
2128 CORBA::String_var entry = geomGroup->GetStudyEntry();
2129 groupData._groupEntry = entry.in();
2130 groupData._indices = curIndices;
2132 newShape = _gen_i->GeomObjectToShape( geomGroup );
2134 // check if newShape is up-to-date
2135 if ( !newShape.IsNull() && ids->length() > 0 )
2137 bool toUpdate = ! _impl->GetMeshDS()->IsGroupOfSubShapes( newShape );
2140 TopExp_Explorer exp( newShape, (TopAbs_ShapeEnum)( groupOp->GetType( geomGroup )));
2141 for ( ; exp.More() && !toUpdate; exp.Next() )
2143 int ind = _impl->GetMeshDS()->ShapeToIndex( exp.Current() );
2144 toUpdate = ( curIndices.erase( ind ) == 0 );
2146 if ( !curIndices.empty() )
2151 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2152 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
2153 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
2154 newShape = _gen_i->GeomObjectToShape( geomGroup );
2159 // geom group becomes empty - return empty compound
2160 TopoDS_Compound compound;
2161 BRep_Builder().MakeCompound(compound);
2162 newShape = compound;
2170 //-----------------------------------------------------------------------------
2172 * \brief Storage of shape and index used in CheckGeomGroupModif()
2174 struct TIndexedShape
2177 TopoDS_Shape _shape;
2178 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
2180 //-----------------------------------------------------------------------------
2182 * \brief Data to re-create a group on geometry
2184 struct TGroupOnGeomData
2187 TopoDS_Shape _shape;
2188 SMDSAbs_ElementType _type;
2190 Quantity_Color _color;
2192 TGroupOnGeomData( const SMESHDS_GroupOnGeom* group )
2194 _oldID = group->GetID();
2195 _type = group->GetType();
2196 _name = group->GetStoreName();
2197 _color = group->GetColor();
2201 //-----------------------------------------------------------------------------
2203 * \brief Check if a filter is still valid after geometry removal
2205 bool isValidGeomFilter( SMESH::Filter_var theFilter )
2207 if ( theFilter->_is_nil() )
2209 SMESH::Filter::Criteria_var criteria;
2210 theFilter->GetCriteria( criteria.out() );
2212 for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr )
2214 const char* thresholdID = criteria[ iCr ].ThresholdID.in();
2216 switch ( criteria[ iCr ].Type )
2218 case SMESH::FT_BelongToGeom:
2219 case SMESH::FT_BelongToPlane:
2220 case SMESH::FT_BelongToCylinder:
2221 case SMESH::FT_BelongToGenSurface:
2222 case SMESH::FT_LyingOnGeom:
2223 entry = thresholdID;
2225 case SMESH::FT_ConnectedElements:
2228 entry = thresholdID;
2234 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
2235 SALOMEDS::SObject_wrap so = gen->getStudyServant()->FindObjectID( entry.c_str() );
2236 if ( so->_is_nil() )
2238 CORBA::Object_var obj = so->GetObject();
2239 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( obj );
2240 if ( gen->GeomObjectToShape( geom ).IsNull() )
2243 } // loop on criteria
2249 //=============================================================================
2251 * \brief Update data if geometry changes
2255 //=============================================================================
2257 void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink )
2259 SMESH::SMESH_Mesh_var me = _this();
2260 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2262 TPythonDump dumpNothing; // prevent any dump
2264 //bool removedFromClient = false;
2266 if ( mainGO->_is_nil() ) // GEOM_Client cleared or geometry removed? (IPAL52735, PAL23636)
2268 //removedFromClient = _impl->HasShapeToMesh();
2270 // try to find geometry by study reference
2271 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2272 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2273 if ( !meshSO->_is_nil() &&
2274 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2275 geomRefSO->ReferencedObject( geomSO.inout() ))
2277 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2278 mainGO = GEOM::GEOM_Object::_narrow( geomObj );
2281 if ( mainGO->_is_nil() && // geometry removed ==>
2282 !geomRefSO->_is_nil() ) // remove geom dependent data: sub-meshes etc.
2284 // convert geom dependent groups into standalone ones
2285 CheckGeomGroupModif();
2287 _impl->ShapeToMesh( TopoDS_Shape() );
2289 // remove sub-meshes
2290 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2291 while ( i_sm != _mapSubMeshIor.end() )
2293 SMESH::SMESH_subMesh_ptr sm = i_sm->second;
2295 RemoveSubMesh( sm );
2297 // remove all children except groups in the study
2298 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2299 SALOMEDS::SObject_wrap so;
2300 for ( CORBA::Long tag = SMESH::Tag_RefOnShape; tag <= SMESH::Tag_LastSubMesh; ++tag )
2301 if ( meshSO->FindSubObject( tag, so.inout() ))
2302 builder->RemoveObjectWithChildren( so );
2304 _gen_i->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED" );
2310 if ( !_impl->HasShapeToMesh() ) return;
2313 // Update after group modification
2315 if ( mainGO->GetType() == GEOM_GROUP || // is group or not modified
2316 mainGO->GetTick() == _mainShapeTick )
2318 int nb = NbNodes() + NbElements();
2319 CheckGeomGroupModif();
2320 if ( nb != NbNodes() + NbElements() ) // something removed due to hypotheses change
2321 _gen_i->UpdateIcons( me );
2325 // Update after shape modification
2327 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2328 if ( !geomClient ) return;
2329 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( mainGO );
2330 if ( geomGen->_is_nil() ) return;
2331 CORBA::String_var geomComponentType = geomGen->ComponentDataType();
2332 bool isShaper = ( strcmp( geomComponentType.in(), "SHAPERSTUDY" ) == 0 );
2334 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2336 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2337 if ( meshDS->ShapeToIndex( newShape ) == 1 ) // not yet updated
2339 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2340 geomClient->RemoveShapeFromBuffer( ior.in() );
2341 newShape = _gen_i->GeomObjectToShape( mainGO );
2344 // Update data taking into account that if topology doesn't change
2345 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2348 _preMeshInfo->ForgetAllData();
2350 if ( isBreakLink || !isShaper )
2352 if ( newShape.IsNull() )
2355 _mainShapeTick = mainGO->GetTick();
2357 // store data of groups on geometry including new TopoDS_Shape's
2358 std::vector< TGroupOnGeomData > groupsData;
2359 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2360 groupsData.reserve( groups.size() );
2361 TopTools_DataMapOfShapeShape old2newShapeMap;
2362 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2363 for ( ; g != groups.end(); ++g )
2365 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2367 groupsData.push_back( TGroupOnGeomData( group ));
2370 SMESH::SMESH_GroupOnGeom_var gog;
2371 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.find( group->GetID() );
2372 if ( i_grp != _mapGroups.end() )
2373 gog = SMESH::SMESH_GroupOnGeom::_narrow( i_grp->second );
2375 GEOM::GEOM_Object_var geom;
2376 if ( !gog->_is_nil() )
2379 geom = gog->GetShape();
2381 if ( isBreakLink || geom->_is_nil() )
2383 SALOMEDS::SObject_wrap grpSO = _gen_i->ObjectToSObject( gog );
2384 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2385 if ( !grpSO->_is_nil() &&
2386 grpSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2387 geomRefSO->ReferencedObject( geomSO.inout() ))
2389 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2390 geom = GEOM::GEOM_Object::_narrow( geomObj );
2394 if ( old2newShapeMap.IsBound( group->GetShape() ))
2396 groupsData.back()._shape = old2newShapeMap( group->GetShape() );
2398 else if ( !geom->_is_nil() )
2400 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2401 if ( meshDS->IsGroupOfSubShapes( groupsData.back()._shape ))
2403 CORBA::String_var ior = geomGen->GetStringFromIOR( geom );
2404 geomClient->RemoveShapeFromBuffer( ior.in() );
2405 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2407 old2newShapeMap.Bind( group->GetShape(), groupsData.back()._shape );
2412 // store assigned hypotheses
2413 std::vector< pair< int, THypList > > ids2Hyps;
2414 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2415 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2417 const TopoDS_Shape& s = s2hyps.Key();
2418 const THypList& hyps = s2hyps.ChangeValue();
2419 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2422 std::multimap< std::set<int>, int > ii2iMap; // group sub-ids to group id in SMESHDS
2424 // count shapes excluding compounds corresponding to geom groups
2425 int oldNbSubShapes = meshDS->MaxShapeIndex();
2426 for ( ; oldNbSubShapes > 0; --oldNbSubShapes )
2428 const TopoDS_Shape& s = meshDS->IndexToShape( oldNbSubShapes );
2429 if ( s.IsNull() || s.ShapeType() != TopAbs_COMPOUND )
2432 std::set<int> subIds;
2433 for ( TopoDS_Iterator it( s ); it.More(); it.Next() )
2434 subIds.insert( meshDS->ShapeToIndex( it.Value() ));
2435 ii2iMap.insert( std::make_pair( subIds, oldNbSubShapes ));
2438 // check if shape topology changes - save shape type per shape ID
2439 std::vector< TopAbs_ShapeEnum > shapeTypes( Max( oldNbSubShapes + 1, 1 ));
2440 for ( int shapeID = oldNbSubShapes; shapeID > 0; --shapeID )
2441 shapeTypes[ shapeID ] = meshDS->IndexToShape( shapeID ).ShapeType();
2443 // change shape to mesh
2444 _impl->ShapeToMesh( TopoDS_Shape() );
2445 _impl->ShapeToMesh( newShape );
2447 // check if shape topology changes - check new shape types
2448 bool sameTopology = ( oldNbSubShapes == meshDS->MaxShapeIndex() );
2449 for ( int shapeID = oldNbSubShapes; shapeID > 0 && sameTopology; --shapeID )
2451 const TopoDS_Shape& s = meshDS->IndexToShape( shapeID );
2452 sameTopology = ( !s.IsNull() && s.ShapeType() == shapeTypes[ shapeID ]);
2455 // re-add shapes (compounds) of geom groups
2456 typedef std::map< std::vector< int >, TGeomGroupData* > TIndices2GroupData;
2457 TIndices2GroupData ii2grData;
2458 std::vector< int > ii;
2459 std::map< int, int > old2newIDs; // group IDs
2460 std::list<TGeomGroupData>::iterator dataIt = _geomGroupData.begin();
2461 for ( ; dataIt != _geomGroupData.end(); ++dataIt )
2463 TGeomGroupData* data = &(*dataIt);
2464 ii.reserve( data->_indices.size() );
2465 ii.assign( data->_indices.begin(), data->_indices.end() );
2466 TIndices2GroupData::iterator ii2gd = ii2grData.insert( std::make_pair( ii, data )).first;
2467 if ( ii2gd->second != data )
2469 data->_groupEntry = ii2gd->second->_groupEntry;
2470 data->_indices = ii2gd->second->_indices;
2473 const int oldNbSub = data->_indices.size();
2474 const int soleOldID = oldNbSub == 1 ? *data->_indices.begin() : 0;
2476 std::multimap< std::set<int>, int >::iterator ii2i = ii2iMap.find( data->_indices );
2477 if ( ii2i != ii2iMap.end() )
2479 oldID = ii2i->second;
2480 ii2iMap.erase( ii2i );
2482 if ( !oldID && oldNbSub == 1 )
2484 if ( old2newIDs.count( oldID ))
2487 int how = ( isBreakLink || !sameTopology ) ? IS_BREAK_LINK : MAIN_TRANSFORMED;
2488 newShape = newGroupShape( *data, how );
2490 if ( !newShape.IsNull() )
2492 if ( oldNbSub > 1 && meshDS->ShapeToIndex( newShape ) > 0 ) // group reduced to one sub-shape
2494 TopoDS_Compound compound;
2495 BRep_Builder().MakeCompound( compound );
2496 BRep_Builder().Add( compound, newShape );
2497 newShape = compound;
2499 int newID = _impl->GetSubMesh( newShape )->GetId();
2500 if ( oldID /*&& oldID != newID*/ )
2501 old2newIDs.insert( std::make_pair( oldID, newID ));
2502 if ( oldNbSub == 1 )
2503 old2newIDs.insert( std::make_pair( soleOldID, newID ));
2507 // re-assign hypotheses
2508 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2510 int sID = ids2Hyps[i].first;
2511 std::map< int, int >::iterator o2n = old2newIDs.find( sID );
2512 if ( o2n != old2newIDs.end() )
2514 else if ( !sameTopology && sID != 1 )
2516 const TopoDS_Shape& s = meshDS->IndexToShape( sID );
2519 const THypList& hyps = ids2Hyps[i].second;
2520 THypList::const_iterator h = hyps.begin();
2521 for ( ; h != hyps.end(); ++h )
2522 _impl->AddHypothesis( s, (*h)->GetID() );
2526 // restore groups on geometry
2527 for ( size_t i = 0; i < groupsData.size(); ++i )
2529 const TGroupOnGeomData& data = groupsData[i];
2530 if ( data._shape.IsNull() )
2533 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2534 if ( i2g == _mapGroups.end() ) continue;
2536 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2537 if ( !gr_i ) continue;
2539 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape );
2541 _mapGroups.erase( i2g );
2543 g->GetGroupDS()->SetColor( data._color );
2546 if ( !sameTopology )
2548 std::map< int, int >::iterator o2n = old2newIDs.begin();
2549 for ( ; o2n != old2newIDs.end(); ++o2n )
2551 int newID = o2n->second, oldID = o2n->first;
2552 if ( newID == oldID || !_mapSubMesh.count( oldID ))
2556 _mapSubMesh [ newID ] = _impl->GetSubMeshContaining( newID );
2557 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2558 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2560 _mapSubMesh. erase(oldID);
2561 _mapSubMesh_i. erase(oldID);
2562 _mapSubMeshIor.erase(oldID);
2564 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2568 // update _mapSubMesh
2569 std::map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2570 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2571 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2574 if ( !sameTopology )
2576 // remove invalid study sub-objects
2577 CheckGeomGroupModif();
2580 _gen_i->UpdateIcons( me );
2582 if ( !isBreakLink && isShaper )
2584 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2585 if ( !meshSO->_is_nil() )
2586 _gen_i->SetPixMap(meshSO, "ICON_SMESH_TREE_GEOM_MODIF");
2590 //=============================================================================
2592 * \brief Update objects depending on changed geom groups
2594 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2595 * issue 0020210: Update of a smesh group after modification of the associated geom group
2597 //=============================================================================
2599 void SMESH_Mesh_i::CheckGeomGroupModif()
2601 // remove sub-meshes referring a removed sub-shapes (if main shape still exists)
2602 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2603 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2604 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() ));
2605 if ( !mainGO->_is_nil() && !meshSO->_is_nil() )
2607 SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO;
2608 for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag )
2609 if ( meshSO->FindSubObject( tag, rootSO.inout() ))
2611 int nbValid = 0, nbRemoved = 0;
2612 SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO );
2613 for ( ; chItr->More(); chItr->Next() )
2615 SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO
2616 if ( !smSO->_is_nil() &&
2617 smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2618 geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference
2620 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2621 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2622 if ( !geom->_non_existent() )
2625 continue; // keep the sub-mesh
2628 CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO );
2629 SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj );
2630 if ( !sm->_is_nil() && !sm->_non_existent() )
2632 GEOM::GEOM_Object_var smGeom = sm->GetSubShape();
2633 if ( smGeom->_is_nil() )
2635 RemoveSubMesh( sm );
2642 _preMeshInfo->ForgetAllData(); // unknown hypothesis modified
2643 builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH
2647 if ( /*nbRemoved > 0 &&*/ nbValid == 0 )
2648 builder->RemoveObjectWithChildren( rootSO );
2652 // check for removed sub-shapes and convert geom dependent groups into standalone ones
2653 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2654 while ( i_gr != _mapGroups.end())
2656 SMESH::SMESH_GroupBase_ptr group = i_gr->second;
2658 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO, geomSO;
2659 SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group );
2660 SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group );
2661 bool isValidGeom = false;
2662 if ( !onGeom->_is_nil() )
2664 isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() ); // check TopoDS
2665 if ( !isValidGeom ) // check reference
2667 isValidGeom = ( ! groupSO->_is_nil() &&
2668 groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ) &&
2669 refSO->ReferencedObject( geomSO.inout() ) &&
2670 ! geomSO->_is_nil() &&
2671 !CORBA::is_nil( CORBA::Object_var( geomSO->GetObject() )));
2674 else if ( !onFilt->_is_nil() )
2676 isValidGeom = isValidGeomFilter( onFilt->GetFilter() );
2680 isValidGeom = ( !groupSO->_is_nil() &&
2681 !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ));
2685 if ( !IsLoaded() || group->IsEmpty() )
2687 RemoveGroup( group );
2689 else if ( !onGeom->_is_nil() || !onFilt->_is_nil() )
2691 SMESH::SMESH_Group_var ( ConvertToStandalone( group ));
2693 else // is it possible?
2695 builder->RemoveObjectWithChildren( refSO );
2701 if ( !_impl->HasShapeToMesh() ) return;
2703 CORBA::Long nbEntities = NbNodes() + NbElements();
2705 // Check if group contents changed
2707 typedef map< string, TopoDS_Shape > TEntry2Geom;
2708 TEntry2Geom newGroupContents;
2710 list<TGeomGroupData>::iterator
2711 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2712 for ( ; data != dataEnd; ++data )
2714 pair< TEntry2Geom::iterator, bool > it_new =
2715 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2716 bool processedGroup = !it_new.second;
2717 TopoDS_Shape& newShape = it_new.first->second;
2718 if ( !processedGroup )
2719 newShape = newGroupShape( *data, ONLY_IF_CHANGED );
2720 if ( newShape.IsNull() )
2721 continue; // no changes
2724 _preMeshInfo->ForgetOrLoad();
2726 if ( processedGroup ) { // update group indices
2727 list<TGeomGroupData>::iterator data2 = data;
2728 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2729 data->_indices = data2->_indices;
2732 // Update SMESH objects according to new GEOM group contents
2734 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2735 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2737 int oldID = submesh->GetId();
2738 if ( !_mapSubMeshIor.count( oldID ))
2740 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2742 // update hypotheses
2743 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2744 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2745 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2747 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2748 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2750 // care of submeshes
2751 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2752 int newID = newSubmesh->GetId();
2753 if ( newID != oldID ) {
2754 _mapSubMesh [ newID ] = newSubmesh;
2755 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2756 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2757 _mapSubMesh. erase(oldID);
2758 _mapSubMesh_i. erase(oldID);
2759 _mapSubMeshIor.erase(oldID);
2760 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2765 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2766 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2767 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2769 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2771 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2772 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2773 ds->SetShape( newShape );
2778 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2779 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2781 // Remove groups and submeshes basing on removed sub-shapes
2783 TopTools_MapOfShape newShapeMap;
2784 TopoDS_Iterator shapeIt( newShape );
2785 for ( ; shapeIt.More(); shapeIt.Next() )
2786 newShapeMap.Add( shapeIt.Value() );
2788 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2789 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2791 if ( newShapeMap.Contains( shapeIt.Value() ))
2793 TopTools_IndexedMapOfShape oldShapeMap;
2794 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2795 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2797 const TopoDS_Shape& oldShape = oldShapeMap(i);
2798 int oldInd = meshDS->ShapeToIndex( oldShape );
2800 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2801 if ( i_smIor != _mapSubMeshIor.end() ) {
2802 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2805 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2806 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2808 // check if a group bases on oldInd shape
2809 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2810 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2811 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2812 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2814 RemoveGroup( i_grp->second ); // several groups can base on same shape
2815 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2820 // Reassign hypotheses and update groups after setting the new shape to mesh
2822 // collect anassigned hypotheses
2823 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2824 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2825 TShapeHypList assignedHyps;
2826 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2828 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2829 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2830 if ( !hyps.empty() ) {
2831 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2832 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2833 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2836 // collect shapes supporting groups
2837 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2838 TShapeTypeList groupData;
2839 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2840 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2841 for ( ; grIt != groups.end(); ++grIt )
2843 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2845 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2847 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2849 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2850 _impl->ShapeToMesh( newShape );
2852 // reassign hypotheses
2853 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2854 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2856 TIndexedShape& geom = indS_hyps->first;
2857 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2858 int oldID = geom._index;
2859 int newID = meshDS->ShapeToIndex( geom._shape );
2860 if ( oldID == 1 ) { // main shape
2862 geom._shape = newShape;
2866 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2867 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2868 // care of sub-meshes
2869 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2870 if ( newID != oldID ) {
2871 _mapSubMesh [ newID ] = newSubmesh;
2872 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2873 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2874 _mapSubMesh. erase(oldID);
2875 _mapSubMesh_i. erase(oldID);
2876 _mapSubMeshIor.erase(oldID);
2877 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2881 TShapeTypeList::iterator geomType = groupData.begin();
2882 for ( ; geomType != groupData.end(); ++geomType )
2884 const TIndexedShape& geom = geomType->first;
2885 int oldID = geom._index;
2886 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2889 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2890 CORBA::String_var name = groupSO->GetName();
2892 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
2893 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
2894 /*id=*/-1, geom._shape ))
2895 group_i->changeLocalId( group->GetID() );
2898 break; // everything has been updated
2901 } // loop on group data
2905 CORBA::Long newNbEntities = NbNodes() + NbElements();
2906 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2907 if ( newNbEntities != nbEntities )
2909 // Add all SObjects with icons to soToUpdateIcons
2910 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2912 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2913 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2914 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2916 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2917 i_gr != _mapGroups.end(); ++i_gr ) // groups
2918 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2921 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2922 for ( ; so != soToUpdateIcons.end(); ++so )
2923 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2926 //=============================================================================
2928 * \brief Create standalone group from a group on geometry or filter
2930 //=============================================================================
2932 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2933 throw (SALOME::SALOME_Exception)
2935 SMESH::SMESH_Group_var aGroup;
2940 _preMeshInfo->FullLoadFromFile();
2942 if ( theGroup->_is_nil() )
2943 return aGroup._retn();
2945 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2947 return aGroup._retn();
2949 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2951 const int anId = aGroupToRem->GetLocalID();
2952 if ( !_impl->ConvertToStandalone( anId ) )
2953 return aGroup._retn();
2954 removeGeomGroupData( theGroup );
2956 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2958 // remove old instance of group from own map
2959 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2960 _mapGroups.erase( anId );
2962 SALOMEDS::StudyBuilder_var builder;
2963 SALOMEDS::SObject_wrap aGroupSO;
2964 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2965 if ( !aStudy->_is_nil() ) {
2966 builder = aStudy->NewBuilder();
2967 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2968 if ( !aGroupSO->_is_nil() )
2970 // remove reference to geometry
2971 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2972 for ( ; chItr->More(); chItr->Next() )
2974 // Remove group's child SObject
2975 SALOMEDS::SObject_wrap so = chItr->Value();
2976 builder->RemoveObject( so );
2978 // Update Python script
2979 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2980 << ".ConvertToStandalone( " << aGroupSO << " )";
2982 // change icon of Group on Filter
2985 // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2986 // const int isEmpty = ( elemTypes->length() == 0 );
2989 SALOMEDS::GenericAttribute_wrap anAttr =
2990 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2991 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2992 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2998 // remember new group in own map
2999 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
3000 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3002 // register CORBA object for persistence
3003 _gen_i->RegisterObject( aGroup );
3005 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
3006 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
3007 //aGroup->Register();
3008 aGroupToRem->UnRegister();
3010 SMESH_CATCH( SMESH::throwCorbaException );
3012 return aGroup._retn();
3015 //=============================================================================
3019 //=============================================================================
3021 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
3023 if(MYDEBUG) MESSAGE( "createSubMesh" );
3024 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
3025 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
3028 SMESH_subMesh_i * subMeshServant;
3031 subMeshId = mySubMesh->GetId();
3032 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
3034 else // "invalid sub-mesh"
3036 // The invalid sub-mesh is created for the case where a valid sub-shape not found
3037 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
3038 if ( _mapSubMesh.empty() )
3041 subMeshId = _mapSubMesh.begin()->first - 1;
3042 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
3045 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
3047 _mapSubMesh [subMeshId] = mySubMesh;
3048 _mapSubMesh_i [subMeshId] = subMeshServant;
3049 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
3051 subMeshServant->Register();
3053 // register CORBA object for persistence
3054 int nextId = _gen_i->RegisterObject( subMesh );
3055 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
3056 else { nextId = 0; } // avoid "unused variable" warning
3058 // to track changes of GEOM groups
3059 if ( subMeshId > 0 )
3060 addGeomGroupData( theSubShapeObject, subMesh );
3062 return subMesh._retn();
3065 //=======================================================================
3066 //function : getSubMesh
3068 //=======================================================================
3070 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
3072 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
3073 if ( it == _mapSubMeshIor.end() )
3074 return SMESH::SMESH_subMesh::_nil();
3076 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
3079 //=============================================================================
3083 //=============================================================================
3085 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
3086 GEOM::GEOM_Object_ptr theSubShapeObject )
3088 bool isHypChanged = false;
3089 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
3090 return isHypChanged;
3092 const int subMeshId = theSubMesh->GetId();
3094 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
3097 if (( _mapSubMesh.count( subMeshId )) &&
3098 ( sm = _impl->GetSubMeshContaining( subMeshId )))
3100 TopoDS_Shape S = sm->GetSubShape();
3103 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
3104 isHypChanged = !hyps.empty();
3105 if ( isHypChanged && _preMeshInfo )
3106 _preMeshInfo->ForgetOrLoad();
3107 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
3108 for ( ; hyp != hyps.end(); ++hyp )
3109 _impl->RemoveHypothesis(S, (*hyp)->GetID());
3116 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
3117 isHypChanged = ( aHypList->length() > 0 );
3118 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
3119 removeHypothesis( theSubShapeObject, aHypList[i] );
3122 catch( const SALOME::SALOME_Exception& ) {
3123 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
3125 removeGeomGroupData( theSubShapeObject );
3129 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
3130 if ( id_smi != _mapSubMesh_i.end() )
3131 id_smi->second->UnRegister();
3133 // remove a CORBA object
3134 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
3135 if ( id_smptr != _mapSubMeshIor.end() )
3136 SMESH::SMESH_subMesh_var( id_smptr->second );
3138 _mapSubMesh.erase(subMeshId);
3139 _mapSubMesh_i.erase(subMeshId);
3140 _mapSubMeshIor.erase(subMeshId);
3142 return isHypChanged;
3145 //=============================================================================
3149 //=============================================================================
3151 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
3152 const char* theName,
3154 const TopoDS_Shape& theShape,
3155 const SMESH_PredicatePtr& thePredicate )
3157 std::string newName;
3158 if ( !theName || !theName[0] )
3160 std::set< std::string > presentNames;
3161 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
3162 for ( ; i_gr != _mapGroups.end(); ++i_gr )
3164 CORBA::String_var name = i_gr->second->GetName();
3165 presentNames.insert( name.in() );
3168 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
3169 } while ( !presentNames.insert( newName ).second );
3170 theName = newName.c_str();
3172 SMESH::SMESH_GroupBase_var aGroup;
3173 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
3174 theID, theShape, thePredicate ))
3176 int anId = g->GetID();
3177 SMESH_GroupBase_i* aGroupImpl;
3178 if ( !theShape.IsNull() )
3179 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3180 else if ( thePredicate )
3181 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
3183 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3185 aGroup = aGroupImpl->_this();
3186 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3187 aGroupImpl->Register();
3189 // register CORBA object for persistence
3190 int nextId = _gen_i->RegisterObject( aGroup );
3191 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
3192 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
3194 // to track changes of GEOM groups
3195 if ( !theShape.IsNull() ) {
3196 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
3197 addGeomGroupData( geom, aGroup );
3200 return aGroup._retn();
3203 //=============================================================================
3205 * SMESH_Mesh_i::removeGroup
3207 * Should be called by ~SMESH_Group_i()
3209 //=============================================================================
3211 void SMESH_Mesh_i::removeGroup( const int theId )
3213 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
3214 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
3215 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
3216 _mapGroups.erase( theId );
3217 removeGeomGroupData( group );
3218 if ( !_impl->RemoveGroup( theId ))
3220 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
3221 RemoveGroup( group );
3223 group->UnRegister();
3227 //=============================================================================
3231 //=============================================================================
3233 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
3234 throw(SALOME::SALOME_Exception)
3236 SMESH::log_array_var aLog;
3240 _preMeshInfo->FullLoadFromFile();
3242 list < SMESHDS_Command * >logDS = _impl->GetLog();
3243 aLog = new SMESH::log_array;
3245 int lg = logDS.size();
3248 list < SMESHDS_Command * >::iterator its = logDS.begin();
3249 while(its != logDS.end()){
3250 SMESHDS_Command *com = *its;
3251 int comType = com->GetType();
3253 int lgcom = com->GetNumber();
3255 const list < int >&intList = com->GetIndexes();
3256 int inum = intList.size();
3258 list < int >::const_iterator ii = intList.begin();
3259 const list < double >&coordList = com->GetCoords();
3260 int rnum = coordList.size();
3262 list < double >::const_iterator ir = coordList.begin();
3263 aLog[indexLog].commandType = comType;
3264 aLog[indexLog].number = lgcom;
3265 aLog[indexLog].coords.length(rnum);
3266 aLog[indexLog].indexes.length(inum);
3267 for(int i = 0; i < rnum; i++){
3268 aLog[indexLog].coords[i] = *ir;
3269 //MESSAGE(" "<<i<<" "<<ir.Value());
3272 for(int i = 0; i < inum; i++){
3273 aLog[indexLog].indexes[i] = *ii;
3274 //MESSAGE(" "<<i<<" "<<ii.Value());
3283 SMESH_CATCH( SMESH::throwCorbaException );
3285 return aLog._retn();
3289 //=============================================================================
3293 //=============================================================================
3295 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
3299 SMESH_CATCH( SMESH::throwCorbaException );
3302 //=============================================================================
3306 //=============================================================================
3308 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
3313 //=============================================================================
3316 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
3317 // issue 0020918: groups removal is caused by hyp modification
3318 // issue 0021208: to forget not loaded mesh data at hyp modification
3319 struct TCallUp_i : public SMESH_Mesh::TCallUp
3321 SMESH_Mesh_i* _mesh;
3322 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
3323 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
3324 virtual void HypothesisModified( int hypID,
3325 bool updIcons) { _mesh->onHypothesisModified( hypID,
3327 virtual void Load () { _mesh->Load(); }
3328 virtual bool IsLoaded() { return _mesh->IsLoaded(); }
3332 //================================================================================
3334 * \brief callback from _impl to
3335 * 1) forget not loaded mesh data (issue 0021208)
3336 * 2) mark hypothesis as valid
3338 //================================================================================
3340 void SMESH_Mesh_i::onHypothesisModified(int theHypID, bool theUpdateIcons)
3343 _preMeshInfo->ForgetOrLoad();
3345 if ( theUpdateIcons )
3347 SMESH::SMESH_Mesh_var mesh = _this();
3348 _gen_i->UpdateIcons( mesh );
3351 if ( _nbInvalidHypos != 0 )
3353 // mark a hypothesis as valid after edition
3355 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
3356 SALOMEDS::SObject_wrap hypRoot;
3357 if ( !smeshComp->_is_nil() &&
3358 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
3360 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
3361 for ( ; anIter->More(); anIter->Next() )
3363 SALOMEDS::SObject_wrap hypSO = anIter->Value();
3364 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
3365 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
3366 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
3367 _gen_i->HighLightInvalid( hyp, false );
3369 nbInvalid += _gen_i->IsInvalid( hypSO );
3372 _nbInvalidHypos = nbInvalid;
3376 //=============================================================================
3380 //=============================================================================
3382 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
3384 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
3387 _impl->SetCallUp( new TCallUp_i(this));
3390 //=============================================================================
3394 //=============================================================================
3396 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
3398 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
3402 //=============================================================================
3404 * Return mesh editor
3406 //=============================================================================
3408 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
3409 throw (SALOME::SALOME_Exception)
3411 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3415 _preMeshInfo->FullLoadFromFile();
3417 // Create MeshEditor
3419 _editor = new SMESH_MeshEditor_i( this, false );
3420 aMeshEdVar = _editor->_this();
3422 // Update Python script
3423 TPythonDump() << _editor << " = "
3424 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
3426 SMESH_CATCH( SMESH::throwCorbaException );
3428 return aMeshEdVar._retn();
3431 //=============================================================================
3433 * Return mesh edition previewer
3435 //=============================================================================
3437 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
3438 throw (SALOME::SALOME_Exception)
3440 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3444 _preMeshInfo->FullLoadFromFile();
3446 if ( !_previewEditor )
3447 _previewEditor = new SMESH_MeshEditor_i( this, true );
3448 aMeshEdVar = _previewEditor->_this();
3450 SMESH_CATCH( SMESH::throwCorbaException );
3452 return aMeshEdVar._retn();
3455 //================================================================================
3457 * \brief Return true if the mesh has been edited since a last total re-compute
3458 * and those modifications may prevent successful partial re-compute
3460 //================================================================================
3462 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
3464 Unexpect aCatch(SALOME_SalomeException);
3465 return _impl->HasModificationsToDiscard();
3468 //================================================================================
3470 * \brief Returns a random unique color
3472 //================================================================================
3474 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
3476 const int MAX_ATTEMPTS = 100;
3478 double tolerance = 0.5;
3479 SALOMEDS::Color col;
3483 // generate random color
3484 double red = (double)rand() / RAND_MAX;
3485 double green = (double)rand() / RAND_MAX;
3486 double blue = (double)rand() / RAND_MAX;
3487 // check existence in the list of the existing colors
3488 bool matched = false;
3489 std::list<SALOMEDS::Color>::const_iterator it;
3490 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3491 SALOMEDS::Color color = *it;
3492 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3493 matched = tol < tolerance;
3495 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3496 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3504 //=============================================================================
3506 * Sets auto-color mode. If it is on, groups get unique random colors
3508 //=============================================================================
3510 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
3512 Unexpect aCatch(SALOME_SalomeException);
3513 _impl->SetAutoColor(theAutoColor);
3515 TPythonDump pyDump; // not to dump group->SetColor() from below code
3516 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3518 std::list<SALOMEDS::Color> aReservedColors;
3519 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3520 for ( ; it != _mapGroups.end(); it++ ) {
3521 if ( CORBA::is_nil( it->second )) continue;
3522 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3523 it->second->SetColor( aColor );
3524 aReservedColors.push_back( aColor );
3528 //=============================================================================
3530 * Returns true if auto-color mode is on
3532 //=============================================================================
3534 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
3536 Unexpect aCatch(SALOME_SalomeException);
3537 return _impl->GetAutoColor();
3540 //=============================================================================
3542 * Checks if there are groups with equal names
3544 //=============================================================================
3546 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3548 return _impl->HasDuplicatedGroupNamesMED();
3551 //================================================================================
3553 * \brief Care of a file before exporting mesh into it
3555 //================================================================================
3557 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3559 SMESH_File aFile( file, false );
3561 if ( aFile.exists() ) {
3562 // existing filesystem node
3563 if ( !aFile.isDirectory() ) {
3564 if ( aFile.openForWriting() ) {
3565 if ( overwrite && ! aFile.remove()) {
3566 msg << "Can't replace " << aFile.getName();
3569 msg << "Can't write into " << aFile.getName();
3572 msg << "Location " << aFile.getName() << " is not a file";
3576 // nonexisting file; check if it can be created
3577 if ( !aFile.openForWriting() ) {
3578 msg << "You cannot create the file "
3580 << ". Check the directory existence and access rights";
3588 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3592 //================================================================================
3594 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
3595 * \param file - file name
3596 * \param overwrite - to erase the file or not
3597 * \retval string - mesh name
3599 //================================================================================
3601 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3602 CORBA::Boolean overwrite)
3605 PrepareForWriting(file, overwrite);
3606 string aMeshName = "Mesh";
3607 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3608 if ( !aStudy->_is_nil() ) {
3609 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3610 if ( !aMeshSO->_is_nil() ) {
3611 CORBA::String_var name = aMeshSO->GetName();
3613 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3614 if ( !aStudy->GetProperties()->IsLocked() )
3616 SALOMEDS::GenericAttribute_wrap anAttr;
3617 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3618 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3619 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3620 ASSERT(!aFileName->_is_nil());
3621 aFileName->SetValue(file);
3622 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3623 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3624 ASSERT(!aFileType->_is_nil());
3625 aFileType->SetValue("FICHIERMED");
3629 // Update Python script
3630 // set name of mesh before export
3631 TPythonDump() << _gen_i << ".SetName("
3632 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3634 // check names of groups
3640 //================================================================================
3642 * \brief Export to MED file
3644 //================================================================================
3646 void SMESH_Mesh_i::ExportMED(const char* file,
3647 CORBA::Boolean auto_groups,
3648 CORBA::Long version,
3649 CORBA::Boolean overwrite,
3650 CORBA::Boolean autoDimension)
3651 throw(SALOME::SALOME_Exception)
3653 //MESSAGE("MED minor version: "<< minor);
3656 _preMeshInfo->FullLoadFromFile();
3658 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3659 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3661 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3663 << "auto_groups=" <<auto_groups << ", "
3664 << "minor=" << version << ", "
3665 << "overwrite=" << overwrite << ", "
3666 << "meshPart=None, "
3667 << "autoDimension=" << autoDimension << " )";
3669 SMESH_CATCH( SMESH::throwCorbaException );
3672 //================================================================================
3674 * \brief Export a mesh to a SAUV file
3676 //================================================================================
3678 void SMESH_Mesh_i::ExportSAUV (const char* file,
3679 CORBA::Boolean auto_groups)
3680 throw(SALOME::SALOME_Exception)
3682 Unexpect aCatch(SALOME_SalomeException);
3684 _preMeshInfo->FullLoadFromFile();
3686 string aMeshName = prepareMeshNameAndGroups(file, true);
3687 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3688 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3689 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3693 //================================================================================
3695 * \brief Export a mesh to a DAT file
3697 //================================================================================
3699 void SMESH_Mesh_i::ExportDAT (const char *file)
3700 throw(SALOME::SALOME_Exception)
3702 Unexpect aCatch(SALOME_SalomeException);
3704 _preMeshInfo->FullLoadFromFile();
3706 // Update Python script
3707 // check names of groups
3709 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3712 PrepareForWriting(file);
3713 _impl->ExportDAT(file);
3716 //================================================================================
3718 * \brief Export a mesh to an UNV file
3720 //================================================================================
3722 void SMESH_Mesh_i::ExportUNV (const char *file)
3723 throw(SALOME::SALOME_Exception)
3725 Unexpect aCatch(SALOME_SalomeException);
3727 _preMeshInfo->FullLoadFromFile();
3729 // Update Python script
3730 // check names of groups
3732 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3735 PrepareForWriting(file);
3736 _impl->ExportUNV(file);
3739 //================================================================================
3741 * \brief Export a mesh to an STL file
3743 //================================================================================
3745 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3746 throw(SALOME::SALOME_Exception)
3748 Unexpect aCatch(SALOME_SalomeException);
3750 _preMeshInfo->FullLoadFromFile();
3752 // Update Python script
3753 // check names of groups
3755 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3756 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3758 CORBA::String_var name;
3759 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3760 if ( !so->_is_nil() )
3761 name = so->GetName();
3764 PrepareForWriting( file );
3765 _impl->ExportSTL( file, isascii, name.in() );
3768 //================================================================================
3770 * \brief Export a part of mesh to a med file
3772 //================================================================================
3774 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3776 CORBA::Boolean auto_groups,
3777 CORBA::Long version,
3778 CORBA::Boolean overwrite,
3779 CORBA::Boolean autoDimension,
3780 const GEOM::ListOfFields& fields,
3781 const char* geomAssocFields,
3782 CORBA::Double ZTolerance)
3783 throw (SALOME::SALOME_Exception)
3785 MESSAGE("MED version: "<< version);
3788 _preMeshInfo->FullLoadFromFile();
3791 bool have0dField = false;
3792 if ( fields.length() > 0 )
3794 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3795 if ( shapeToMesh->_is_nil() )
3796 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3798 for ( size_t i = 0; i < fields.length(); ++i )
3800 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3801 THROW_SALOME_CORBA_EXCEPTION
3802 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3803 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3804 if ( fieldShape->_is_nil() )
3805 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3806 if ( !fieldShape->IsSame( shapeToMesh ) )
3807 THROW_SALOME_CORBA_EXCEPTION
3808 ( "Field defined not on shape", SALOME::BAD_PARAM);
3809 if ( fields[i]->GetDimension() == 0 )
3812 if ( geomAssocFields )
3813 for ( int i = 0; geomAssocFields[i]; ++i )
3814 switch ( geomAssocFields[i] ) {
3815 case 'v':case 'e':case 'f':case 's': break;
3816 case 'V':case 'E':case 'F':case 'S': break;
3817 default: THROW_SALOME_CORBA_EXCEPTION
3818 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3822 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3826 string aMeshName = "Mesh";
3827 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3828 if ( CORBA::is_nil( meshPart ) ||
3829 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3831 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3832 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3833 0, autoDimension, /*addODOnVertices=*/have0dField,
3835 meshDS = _impl->GetMeshDS();
3840 _preMeshInfo->FullLoadFromFile();
3842 PrepareForWriting(file, overwrite);
3844 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3845 if ( !SO->_is_nil() ) {
3846 CORBA::String_var name = SO->GetName();
3850 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3851 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3852 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3853 meshDS = tmpDSDeleter._obj = partDS;
3858 if ( _impl->HasShapeToMesh() )
3860 DriverMED_W_Field fieldWriter;
3861 fieldWriter.SetFile( file );
3862 fieldWriter.SetMeshName( aMeshName );
3863 fieldWriter.AddODOnVertices( have0dField );
3865 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3869 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3870 goList->length( fields.length() );
3871 for ( size_t i = 0; i < fields.length(); ++i )
3873 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3876 TPythonDump() << _this() << ".ExportPartToMED( "
3877 << meshPart << ", r'"
3879 << auto_groups << ", "
3881 << overwrite << ", "
3882 << autoDimension << ", "
3884 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
3885 << TVar( ZTolerance )
3888 SMESH_CATCH( SMESH::throwCorbaException );
3891 //================================================================================
3893 * Write GEOM fields to MED file
3895 //================================================================================
3897 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3898 SMESHDS_Mesh* meshDS,
3899 const GEOM::ListOfFields& fields,
3900 const char* geomAssocFields)
3902 #define METH "SMESH_Mesh_i::exportMEDFields() "
3904 if (( fields.length() < 1 ) &&
3905 ( !geomAssocFields || !geomAssocFields[0] ))
3908 std::vector< std::vector< double > > dblVals;
3909 std::vector< std::vector< int > > intVals;
3910 std::vector< int > subIdsByDim[ 4 ];
3911 const double noneDblValue = 0.;
3912 const double noneIntValue = 0;
3914 for ( size_t iF = 0; iF < fields.length(); ++iF )
3918 int dim = fields[ iF ]->GetDimension();
3919 SMDSAbs_ElementType elemType;
3920 TopAbs_ShapeEnum shapeType;
3922 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3923 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3924 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3925 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3927 continue; // skip fields on whole shape
3929 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3930 if ( dataType == GEOM::FDT_String )
3932 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3933 if ( stepIDs->length() < 1 )
3935 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3936 if ( comps->length() < 1 )
3938 CORBA::String_var name = fields[ iF ]->GetName();
3940 if ( !fieldWriter.Set( meshDS,
3944 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3947 for ( size_t iC = 0; iC < comps->length(); ++iC )
3948 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3950 dblVals.resize( comps->length() );
3951 intVals.resize( comps->length() );
3953 // find sub-shape IDs
3955 std::vector< int >& subIds = subIdsByDim[ dim ];
3956 if ( subIds.empty() )
3957 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3958 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3959 subIds.push_back( id );
3963 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3967 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3969 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3970 if ( step->_is_nil() )
3973 CORBA::Long stamp = step->GetStamp();
3974 CORBA::Long id = step->GetID();
3975 fieldWriter.SetDtIt( int( stamp ), int( id ));
3977 // fill dblVals or intVals
3978 for ( size_t iC = 0; iC < comps->length(); ++iC )
3979 if ( dataType == GEOM::FDT_Double )
3981 dblVals[ iC ].clear();
3982 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3986 intVals[ iC ].clear();
3987 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3991 case GEOM::FDT_Double:
3993 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3994 if ( dblStep->_is_nil() ) continue;
3995 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3996 if ( vv->length() != subIds.size() * comps->length() )
3997 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3998 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3999 for ( size_t iC = 0; iC < comps->length(); ++iC )
4000 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
4005 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
4006 if ( intStep->_is_nil() ) continue;
4007 GEOM::ListOfLong_var vv = intStep->GetValues();
4008 if ( vv->length() != subIds.size() * comps->length() )
4009 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
4010 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
4011 for ( size_t iC = 0; iC < comps->length(); ++iC )
4012 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
4015 case GEOM::FDT_Bool:
4017 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
4018 if ( boolStep->_is_nil() ) continue;
4019 GEOM::short_array_var vv = boolStep->GetValues();
4020 if ( vv->length() != subIds.size() * comps->length() )
4021 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
4022 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
4023 for ( size_t iC = 0; iC < comps->length(); ++iC )
4024 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
4030 // pass values to fieldWriter
4031 elemIt = fieldWriter.GetOrderedElems();
4032 if ( dataType == GEOM::FDT_Double )
4033 while ( elemIt->more() )
4035 const SMDS_MeshElement* e = elemIt->next();
4036 const int shapeID = e->getshapeId();
4037 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
4038 for ( size_t iC = 0; iC < comps->length(); ++iC )
4039 fieldWriter.AddValue( noneDblValue );
4041 for ( size_t iC = 0; iC < comps->length(); ++iC )
4042 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
4045 while ( elemIt->more() )
4047 const SMDS_MeshElement* e = elemIt->next();
4048 const int shapeID = e->getshapeId();
4049 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
4050 for ( size_t iC = 0; iC < comps->length(); ++iC )
4051 fieldWriter.AddValue( (double) noneIntValue );
4053 for ( size_t iC = 0; iC < comps->length(); ++iC )
4054 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
4058 fieldWriter.Perform();
4059 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4060 if ( res && res->IsKO() )
4062 if ( res->myComment.empty() )
4063 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4065 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4071 if ( !geomAssocFields || !geomAssocFields[0] )
4074 // write geomAssocFields
4076 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
4077 shapeDim[ TopAbs_COMPOUND ] = 3;
4078 shapeDim[ TopAbs_COMPSOLID ] = 3;
4079 shapeDim[ TopAbs_SOLID ] = 3;
4080 shapeDim[ TopAbs_SHELL ] = 2;
4081 shapeDim[ TopAbs_FACE ] = 2;
4082 shapeDim[ TopAbs_WIRE ] = 1;
4083 shapeDim[ TopAbs_EDGE ] = 1;
4084 shapeDim[ TopAbs_VERTEX ] = 0;
4085 shapeDim[ TopAbs_SHAPE ] = 3;
4087 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
4089 std::vector< std::string > compNames;
4090 switch ( geomAssocFields[ iF ]) {
4092 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
4093 compNames.push_back( "dim" );
4096 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
4099 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
4102 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
4106 compNames.push_back( "id" );
4107 for ( size_t iC = 0; iC < compNames.size(); ++iC )
4108 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
4110 fieldWriter.SetDtIt( -1, -1 );
4112 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
4116 if ( compNames.size() == 2 ) // _vertices_
4117 while ( elemIt->more() )
4119 const SMDS_MeshElement* e = elemIt->next();
4120 const int shapeID = e->getshapeId();
4123 fieldWriter.AddValue( (double) -1 );
4124 fieldWriter.AddValue( (double) -1 );
4128 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
4129 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
4130 fieldWriter.AddValue( (double) shapeID );
4134 while ( elemIt->more() )
4136 const SMDS_MeshElement* e = elemIt->next();
4137 const int shapeID = e->getshapeId();
4139 fieldWriter.AddValue( (double) -1 );
4141 fieldWriter.AddValue( (double) shapeID );
4145 fieldWriter.Perform();
4146 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4147 if ( res && res->IsKO() )
4149 if ( res->myComment.empty() )
4150 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4152 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4155 } // loop on geomAssocFields
4160 //================================================================================
4162 * \brief Export a part of mesh to a DAT file
4164 //================================================================================
4166 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
4168 throw (SALOME::SALOME_Exception)
4170 Unexpect aCatch(SALOME_SalomeException);
4172 _preMeshInfo->FullLoadFromFile();
4174 PrepareForWriting(file);
4176 SMESH_MeshPartDS partDS( meshPart );
4177 _impl->ExportDAT(file,&partDS);
4179 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4180 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
4182 //================================================================================
4184 * \brief Export a part of mesh to an UNV file
4186 //================================================================================
4188 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
4190 throw (SALOME::SALOME_Exception)
4192 Unexpect aCatch(SALOME_SalomeException);
4194 _preMeshInfo->FullLoadFromFile();
4196 PrepareForWriting(file);
4198 SMESH_MeshPartDS partDS( meshPart );
4199 _impl->ExportUNV(file, &partDS);
4201 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4202 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
4204 //================================================================================
4206 * \brief Export a part of mesh to an STL file
4208 //================================================================================
4210 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
4212 ::CORBA::Boolean isascii)
4213 throw (SALOME::SALOME_Exception)
4215 Unexpect aCatch(SALOME_SalomeException);
4217 _preMeshInfo->FullLoadFromFile();
4219 PrepareForWriting(file);
4221 CORBA::String_var name;
4222 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4223 if ( !so->_is_nil() )
4224 name = so->GetName();
4226 SMESH_MeshPartDS partDS( meshPart );
4227 _impl->ExportSTL( file, isascii, name.in(), &partDS );
4229 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
4230 << meshPart<< ", r'" << file << "', " << isascii << ")";
4233 //================================================================================
4235 * \brief Export a part of mesh to an STL file
4237 //================================================================================
4239 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
4241 CORBA::Boolean overwrite,
4242 CORBA::Boolean groupElemsByType)
4243 throw (SALOME::SALOME_Exception)
4246 Unexpect aCatch(SALOME_SalomeException);
4248 _preMeshInfo->FullLoadFromFile();
4250 PrepareForWriting(file,overwrite);
4252 std::string meshName("");
4253 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4254 if ( !so->_is_nil() )
4256 CORBA::String_var name = so->GetName();
4257 meshName = name.in();
4261 SMESH_MeshPartDS partDS( meshPart );
4262 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
4264 SMESH_CATCH( SMESH::throwCorbaException );
4266 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
4267 << meshPart<< ", r'" << file << "', " << overwrite << ")";
4269 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
4273 //================================================================================
4275 * \brief Export a part of mesh to a GMF file
4277 //================================================================================
4279 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
4281 bool withRequiredGroups)
4282 throw (SALOME::SALOME_Exception)
4284 Unexpect aCatch(SALOME_SalomeException);
4286 _preMeshInfo->FullLoadFromFile();
4288 PrepareForWriting(file,/*overwrite=*/true);
4290 SMESH_MeshPartDS partDS( meshPart );
4291 _impl->ExportGMF(file, &partDS, withRequiredGroups);
4293 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
4294 << meshPart<< ", r'"
4296 << withRequiredGroups << ")";
4299 //=============================================================================
4301 * Return computation progress [0.,1]
4303 //=============================================================================
4305 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
4309 return _impl->GetComputeProgress();
4311 SMESH_CATCH( SMESH::doNothing );
4315 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
4317 Unexpect aCatch(SALOME_SalomeException);
4319 return _preMeshInfo->NbNodes();
4321 return _impl->NbNodes();
4324 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
4326 Unexpect aCatch(SALOME_SalomeException);
4328 return _preMeshInfo->NbElements();
4330 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
4333 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
4335 Unexpect aCatch(SALOME_SalomeException);
4337 return _preMeshInfo->Nb0DElements();
4339 return _impl->Nb0DElements();
4342 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
4344 Unexpect aCatch(SALOME_SalomeException);
4346 return _preMeshInfo->NbBalls();
4348 return _impl->NbBalls();
4351 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
4353 Unexpect aCatch(SALOME_SalomeException);
4355 return _preMeshInfo->NbEdges();
4357 return _impl->NbEdges();
4360 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
4361 throw(SALOME::SALOME_Exception)
4363 Unexpect aCatch(SALOME_SalomeException);
4365 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
4367 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
4370 //=============================================================================
4372 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
4374 Unexpect aCatch(SALOME_SalomeException);
4376 return _preMeshInfo->NbFaces();
4378 return _impl->NbFaces();
4381 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
4383 Unexpect aCatch(SALOME_SalomeException);
4385 return _preMeshInfo->NbTriangles();
4387 return _impl->NbTriangles();
4390 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
4392 Unexpect aCatch(SALOME_SalomeException);
4394 return _preMeshInfo->NbBiQuadTriangles();
4396 return _impl->NbBiQuadTriangles();
4399 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
4401 Unexpect aCatch(SALOME_SalomeException);
4403 return _preMeshInfo->NbQuadrangles();
4405 return _impl->NbQuadrangles();
4408 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
4410 Unexpect aCatch(SALOME_SalomeException);
4412 return _preMeshInfo->NbBiQuadQuadrangles();
4414 return _impl->NbBiQuadQuadrangles();
4417 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
4419 Unexpect aCatch(SALOME_SalomeException);
4421 return _preMeshInfo->NbPolygons();
4423 return _impl->NbPolygons();
4426 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
4428 Unexpect aCatch(SALOME_SalomeException);
4430 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
4432 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
4435 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
4436 throw(SALOME::SALOME_Exception)
4438 Unexpect aCatch(SALOME_SalomeException);
4440 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
4442 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
4445 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
4446 throw(SALOME::SALOME_Exception)
4448 Unexpect aCatch(SALOME_SalomeException);
4450 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
4452 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
4455 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
4456 throw(SALOME::SALOME_Exception)
4458 Unexpect aCatch(SALOME_SalomeException);
4460 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
4462 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
4465 //=============================================================================
4467 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
4469 Unexpect aCatch(SALOME_SalomeException);
4471 return _preMeshInfo->NbVolumes();
4473 return _impl->NbVolumes();
4476 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
4478 Unexpect aCatch(SALOME_SalomeException);
4480 return _preMeshInfo->NbTetras();
4482 return _impl->NbTetras();
4485 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
4487 Unexpect aCatch(SALOME_SalomeException);
4489 return _preMeshInfo->NbHexas();
4491 return _impl->NbHexas();
4494 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
4496 Unexpect aCatch(SALOME_SalomeException);
4498 return _preMeshInfo->NbTriQuadHexas();
4500 return _impl->NbTriQuadraticHexas();
4503 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
4505 Unexpect aCatch(SALOME_SalomeException);
4507 return _preMeshInfo->NbPyramids();
4509 return _impl->NbPyramids();
4512 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
4514 Unexpect aCatch(SALOME_SalomeException);
4516 return _preMeshInfo->NbPrisms();
4518 return _impl->NbPrisms();
4521 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
4523 Unexpect aCatch(SALOME_SalomeException);
4525 return _preMeshInfo->NbHexPrisms();
4527 return _impl->NbHexagonalPrisms();
4530 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
4532 Unexpect aCatch(SALOME_SalomeException);
4534 return _preMeshInfo->NbPolyhedrons();
4536 return _impl->NbPolyhedrons();
4539 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4540 throw(SALOME::SALOME_Exception)
4542 Unexpect aCatch(SALOME_SalomeException);
4544 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4546 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4549 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4550 throw(SALOME::SALOME_Exception)
4552 Unexpect aCatch(SALOME_SalomeException);
4554 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4556 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4559 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4560 throw(SALOME::SALOME_Exception)
4562 Unexpect aCatch(SALOME_SalomeException);
4564 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4566 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4569 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4570 throw(SALOME::SALOME_Exception)
4572 Unexpect aCatch(SALOME_SalomeException);
4574 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4576 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4579 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4580 throw(SALOME::SALOME_Exception)
4582 Unexpect aCatch(SALOME_SalomeException);
4584 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4586 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4589 //=============================================================================
4591 * Returns nb of published sub-meshes
4593 //=============================================================================
4595 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4597 Unexpect aCatch(SALOME_SalomeException);
4598 return _mapSubMesh_i.size();
4601 //=============================================================================
4603 * Dumps mesh into a string
4605 //=============================================================================
4607 char* SMESH_Mesh_i::Dump()
4611 return CORBA::string_dup( os.str().c_str() );
4614 //=============================================================================
4616 * Method of SMESH_IDSource interface
4618 //=============================================================================
4620 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4622 return GetElementsId();
4625 //=============================================================================
4627 * Returns ids of all elements
4629 //=============================================================================
4631 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4632 throw (SALOME::SALOME_Exception)
4634 Unexpect aCatch(SALOME_SalomeException);
4636 _preMeshInfo->FullLoadFromFile();
4638 SMESH::long_array_var aResult = new SMESH::long_array();
4639 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4641 if ( aSMESHDS_Mesh == NULL )
4642 return aResult._retn();
4644 long nbElements = NbElements();
4645 aResult->length( nbElements );
4646 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4647 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4648 aResult[i] = anIt->next()->GetID();
4650 return aResult._retn();
4654 //=============================================================================
4656 * Returns ids of all elements of given type
4658 //=============================================================================
4660 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4661 throw (SALOME::SALOME_Exception)
4663 Unexpect aCatch(SALOME_SalomeException);
4665 _preMeshInfo->FullLoadFromFile();
4667 SMESH::long_array_var aResult = new SMESH::long_array();
4668 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4670 if ( aSMESHDS_Mesh == NULL )
4671 return aResult._retn();
4673 long nbElements = NbElements();
4675 // No sense in returning ids of elements along with ids of nodes:
4676 // when theElemType == SMESH::ALL, return node ids only if
4677 // there are no elements
4678 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4679 return GetNodesId();
4681 aResult->length( nbElements );
4685 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4686 while ( i < nbElements && anIt->more() )
4687 aResult[i++] = anIt->next()->GetID();
4689 aResult->length( i );
4691 return aResult._retn();
4694 //=============================================================================
4696 * Returns ids of all nodes
4698 //=============================================================================
4700 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4701 throw (SALOME::SALOME_Exception)
4703 Unexpect aCatch(SALOME_SalomeException);
4705 _preMeshInfo->FullLoadFromFile();
4707 SMESH::long_array_var aResult = new SMESH::long_array();
4708 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4710 if ( aMeshDS == NULL )
4711 return aResult._retn();
4713 long nbNodes = NbNodes();
4714 aResult->length( nbNodes );
4715 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4716 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4717 aResult[i] = anIt->next()->GetID();
4719 return aResult._retn();
4722 //=============================================================================
4726 //=============================================================================
4728 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4729 throw (SALOME::SALOME_Exception)
4731 SMESH::ElementType type = SMESH::ALL;
4735 _preMeshInfo->FullLoadFromFile();
4737 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4739 SMESH_CATCH( SMESH::throwCorbaException );
4744 //=============================================================================
4748 //=============================================================================
4750 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4751 throw (SALOME::SALOME_Exception)
4754 _preMeshInfo->FullLoadFromFile();
4756 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4758 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4760 return ( SMESH::EntityType ) e->GetEntityType();
4763 //=============================================================================
4767 //=============================================================================
4769 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4770 throw (SALOME::SALOME_Exception)
4773 _preMeshInfo->FullLoadFromFile();
4775 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4777 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4779 return ( SMESH::GeometryType ) e->GetGeomType();
4782 //=============================================================================
4784 * Returns ID of elements for given submesh
4786 //=============================================================================
4787 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4788 throw (SALOME::SALOME_Exception)
4790 SMESH::long_array_var aResult = new SMESH::long_array();
4794 _preMeshInfo->FullLoadFromFile();
4796 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4797 if(!SM) return aResult._retn();
4799 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4800 if(!SDSM) return aResult._retn();
4802 aResult->length(SDSM->NbElements());
4804 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4806 while ( eIt->more() ) {
4807 aResult[i++] = eIt->next()->GetID();
4810 SMESH_CATCH( SMESH::throwCorbaException );
4812 return aResult._retn();
4815 //=============================================================================
4817 * Returns ID of nodes for given submesh
4818 * If param all==true - returns all nodes, else -
4819 * returns only nodes on shapes.
4821 //=============================================================================
4823 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4825 throw (SALOME::SALOME_Exception)
4827 SMESH::long_array_var aResult = new SMESH::long_array();
4831 _preMeshInfo->FullLoadFromFile();
4833 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4834 if(!SM) return aResult._retn();
4836 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4837 if(!SDSM) return aResult._retn();
4840 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4841 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4842 while ( nIt->more() ) {
4843 const SMDS_MeshNode* elem = nIt->next();
4844 theElems.insert( elem->GetID() );
4847 else { // all nodes of submesh elements
4848 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4849 while ( eIt->more() ) {
4850 const SMDS_MeshElement* anElem = eIt->next();
4851 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4852 while ( nIt->more() ) {
4853 const SMDS_MeshElement* elem = nIt->next();
4854 theElems.insert( elem->GetID() );
4859 aResult->length(theElems.size());
4860 set<int>::iterator itElem;
4862 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4863 aResult[i++] = *itElem;
4865 SMESH_CATCH( SMESH::throwCorbaException );
4867 return aResult._retn();
4870 //=============================================================================
4872 * Returns type of elements for given submesh
4874 //=============================================================================
4876 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4877 throw (SALOME::SALOME_Exception)
4879 SMESH::ElementType type = SMESH::ALL;
4883 _preMeshInfo->FullLoadFromFile();
4885 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4886 if(!SM) return SMESH::ALL;
4888 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4889 if(!SDSM) return SMESH::ALL;
4891 if(SDSM->NbElements()==0)
4892 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4894 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4895 const SMDS_MeshElement* anElem = eIt->next();
4897 type = ( SMESH::ElementType ) anElem->GetType();
4899 SMESH_CATCH( SMESH::throwCorbaException );
4905 //=============================================================================
4907 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4909 //=============================================================================
4911 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4914 _preMeshInfo->FullLoadFromFile();
4916 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4917 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4922 //=============================================================================
4924 * Get XYZ coordinates of node as list of double
4925 * If there is not node for given ID - returns empty list
4927 //=============================================================================
4929 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4932 _preMeshInfo->FullLoadFromFile();
4934 SMESH::double_array_var aResult = new SMESH::double_array();
4935 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4936 if ( aMeshDS == NULL )
4937 return aResult._retn();
4940 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4942 return aResult._retn();
4946 aResult[0] = aNode->X();
4947 aResult[1] = aNode->Y();
4948 aResult[2] = aNode->Z();
4949 return aResult._retn();
4953 //=============================================================================
4955 * For given node returns list of IDs of inverse elements
4956 * If there is not node for given ID - returns empty list
4958 //=============================================================================
4960 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id,
4961 SMESH::ElementType elemType)
4964 _preMeshInfo->FullLoadFromFile();
4966 SMESH::long_array_var aResult = new SMESH::long_array();
4967 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4968 if ( aMeshDS == NULL )
4969 return aResult._retn();
4972 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
4974 return aResult._retn();
4976 // find inverse elements
4977 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
4978 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
4979 aResult->length( aNode->NbInverseElements( type ));
4980 for( int i = 0; eIt->more(); ++i )
4982 const SMDS_MeshElement* elem = eIt->next();
4983 aResult[ i ] = elem->GetID();
4985 return aResult._retn();
4988 //=============================================================================
4990 * \brief Return position of a node on shape
4992 //=============================================================================
4994 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4997 _preMeshInfo->FullLoadFromFile();
4999 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
5000 aNodePosition->shapeID = 0;
5001 aNodePosition->shapeType = GEOM::SHAPE;
5003 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
5004 if ( !mesh ) return aNodePosition;
5006 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
5008 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
5010 aNodePosition->shapeID = aNode->getshapeId();
5011 switch ( pos->GetTypeOfPosition() ) {
5013 aNodePosition->shapeType = GEOM::EDGE;
5014 aNodePosition->params.length(1);
5015 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
5017 case SMDS_TOP_FACE: {
5018 SMDS_FacePositionPtr fPos = pos;
5019 aNodePosition->shapeType = GEOM::FACE;
5020 aNodePosition->params.length(2);
5021 aNodePosition->params[0] = fPos->GetUParameter();
5022 aNodePosition->params[1] = fPos->GetVParameter();
5025 case SMDS_TOP_VERTEX:
5026 aNodePosition->shapeType = GEOM::VERTEX;
5028 case SMDS_TOP_3DSPACE:
5029 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
5030 aNodePosition->shapeType = GEOM::SOLID;
5031 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
5032 aNodePosition->shapeType = GEOM::SHELL;
5038 return aNodePosition;
5041 //=============================================================================
5043 * \brief Return position of an element on shape
5045 //=============================================================================
5047 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
5050 _preMeshInfo->FullLoadFromFile();
5052 SMESH::ElementPosition anElementPosition;
5053 anElementPosition.shapeID = 0;
5054 anElementPosition.shapeType = GEOM::SHAPE;
5056 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
5057 if ( !mesh ) return anElementPosition;
5059 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
5061 anElementPosition.shapeID = anElem->getshapeId();
5062 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
5063 if ( !aSp.IsNull() ) {
5064 switch ( aSp.ShapeType() ) {
5066 anElementPosition.shapeType = GEOM::EDGE;
5069 anElementPosition.shapeType = GEOM::FACE;
5072 anElementPosition.shapeType = GEOM::VERTEX;
5075 anElementPosition.shapeType = GEOM::SOLID;
5078 anElementPosition.shapeType = GEOM::SHELL;
5084 return anElementPosition;
5087 //=============================================================================
5089 * If given element is node returns IDs of shape from position
5090 * If there is not node for given ID - returns -1
5092 //=============================================================================
5094 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
5097 _preMeshInfo->FullLoadFromFile();
5099 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5100 if ( aMeshDS == NULL )
5104 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
5106 return aNode->getshapeId();
5113 //=============================================================================
5115 * For given element returns ID of result shape after
5116 * ::FindShape() from SMESH_MeshEditor
5117 * If there is not element for given ID - returns -1
5119 //=============================================================================
5121 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
5124 _preMeshInfo->FullLoadFromFile();
5126 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5127 if ( aMeshDS == NULL )
5130 // try to find element
5131 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5135 ::SMESH_MeshEditor aMeshEditor(_impl);
5136 int index = aMeshEditor.FindShape( elem );
5144 //=============================================================================
5146 * Returns number of nodes for given element
5147 * If there is not element for given ID - returns -1
5149 //=============================================================================
5151 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
5154 _preMeshInfo->FullLoadFromFile();
5156 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5157 if ( aMeshDS == NULL ) return -1;
5158 // try to find element
5159 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5160 if(!elem) return -1;
5161 return elem->NbNodes();
5165 //=============================================================================
5167 * Returns ID of node by given index for given element
5168 * If there is not element for given ID - returns -1
5169 * If there is not node for given index - returns -2
5171 //=============================================================================
5173 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
5176 _preMeshInfo->FullLoadFromFile();
5178 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5179 if ( aMeshDS == NULL ) return -1;
5180 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5181 if(!elem) return -1;
5182 if( index>=elem->NbNodes() || index<0 ) return -1;
5183 return elem->GetNode(index)->GetID();
5186 //=============================================================================
5188 * Returns IDs of nodes of given element
5190 //=============================================================================
5192 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
5195 _preMeshInfo->FullLoadFromFile();
5197 SMESH::long_array_var aResult = new SMESH::long_array();
5198 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5200 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
5202 aResult->length( elem->NbNodes() );
5203 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5204 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
5205 aResult[ i ] = n->GetID();
5208 return aResult._retn();
5211 //=============================================================================
5213 * Returns true if given node is medium node
5214 * in given quadratic element
5216 //=============================================================================
5218 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
5221 _preMeshInfo->FullLoadFromFile();
5223 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5224 if ( aMeshDS == NULL ) return false;
5226 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5227 if(!aNode) return false;
5228 // try to find element
5229 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
5230 if(!elem) return false;
5232 return elem->IsMediumNode(aNode);
5236 //=============================================================================
5238 * Returns true if given node is medium node
5239 * in one of quadratic elements
5241 //=============================================================================
5243 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
5244 SMESH::ElementType theElemType)
5247 _preMeshInfo->FullLoadFromFile();
5249 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5250 if ( aMeshDS == NULL ) return false;
5253 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5254 if(!aNode) return false;
5256 SMESH_MesherHelper aHelper( *(_impl) );
5258 SMDSAbs_ElementType aType;
5259 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
5260 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
5261 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
5262 else aType = SMDSAbs_All;
5264 return aHelper.IsMedium(aNode,aType);
5268 //=============================================================================
5270 * Returns number of edges for given element
5272 //=============================================================================
5274 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
5277 _preMeshInfo->FullLoadFromFile();
5279 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5280 if ( aMeshDS == NULL ) return -1;
5281 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5282 if(!elem) return -1;
5283 return elem->NbEdges();
5287 //=============================================================================
5289 * Returns number of faces for given element
5291 //=============================================================================
5293 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
5296 _preMeshInfo->FullLoadFromFile();
5298 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5299 if ( aMeshDS == NULL ) return -1;
5300 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5301 if(!elem) return -1;
5302 return elem->NbFaces();
5305 //=======================================================================
5306 //function : GetElemFaceNodes
5307 //purpose : Returns nodes of given face (counted from zero) for given element.
5308 //=======================================================================
5310 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
5311 CORBA::Short faceIndex)
5314 _preMeshInfo->FullLoadFromFile();
5316 SMESH::long_array_var aResult = new SMESH::long_array();
5317 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5319 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
5321 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
5322 if ( faceIndex < vtool.NbFaces() )
5324 aResult->length( vtool.NbFaceNodes( faceIndex ));
5325 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
5326 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5327 aResult[ i ] = nn[ i ]->GetID();
5331 return aResult._retn();
5334 //=======================================================================
5335 //function : GetFaceNormal
5336 //purpose : Returns three components of normal of given mesh face.
5337 //=======================================================================
5339 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
5340 CORBA::Boolean normalized)
5343 _preMeshInfo->FullLoadFromFile();
5345 SMESH::double_array_var aResult = new SMESH::double_array();
5347 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5350 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
5352 aResult->length( 3 );
5353 aResult[ 0 ] = normal.X();
5354 aResult[ 1 ] = normal.Y();
5355 aResult[ 2 ] = normal.Z();
5358 return aResult._retn();
5361 //=======================================================================
5362 //function : FindElementByNodes
5363 //purpose : Returns an element based on all given nodes.
5364 //=======================================================================
5366 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
5369 _preMeshInfo->FullLoadFromFile();
5371 CORBA::Long elemID(0);
5372 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5374 vector< const SMDS_MeshNode * > nn( nodes.length() );
5375 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5376 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
5379 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
5380 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
5381 _impl->NbFaces ( ORDER_QUADRATIC ) ||
5382 _impl->NbVolumes( ORDER_QUADRATIC )))
5383 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
5385 if ( elem ) elemID = CORBA::Long( elem->GetID() );
5390 //================================================================================
5392 * \brief Return elements including all given nodes.
5394 //================================================================================
5396 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
5397 SMESH::ElementType elemType)
5400 _preMeshInfo->FullLoadFromFile();
5402 SMESH::long_array_var result = new SMESH::long_array();
5404 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5406 vector< const SMDS_MeshNode * > nn( nodes.length() );
5407 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5408 nn[i] = mesh->FindNode( nodes[i] );
5410 std::vector<const SMDS_MeshElement *> elems;
5411 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
5412 result->length( elems.size() );
5413 for ( size_t i = 0; i < elems.size(); ++i )
5414 result[i] = elems[i]->GetID();
5416 return result._retn();
5419 //=============================================================================
5421 * Returns true if given element is polygon
5423 //=============================================================================
5425 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
5428 _preMeshInfo->FullLoadFromFile();
5430 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5431 if ( aMeshDS == NULL ) return false;
5432 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5433 if(!elem) return false;
5434 return elem->IsPoly();
5438 //=============================================================================
5440 * Returns true if given element is quadratic
5442 //=============================================================================
5444 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
5447 _preMeshInfo->FullLoadFromFile();
5449 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5450 if ( aMeshDS == NULL ) return false;
5451 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5452 if(!elem) return false;
5453 return elem->IsQuadratic();
5456 //=============================================================================
5458 * Returns diameter of ball discrete element or zero in case of an invalid \a id
5460 //=============================================================================
5462 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
5465 _preMeshInfo->FullLoadFromFile();
5467 if ( const SMDS_BallElement* ball =
5468 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
5469 return ball->GetDiameter();
5474 //=============================================================================
5476 * Returns bary center for given element
5478 //=============================================================================
5480 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5483 _preMeshInfo->FullLoadFromFile();
5485 SMESH::double_array_var aResult = new SMESH::double_array();
5486 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5487 if ( aMeshDS == NULL )
5488 return aResult._retn();
5490 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5492 return aResult._retn();
5494 if(elem->GetType()==SMDSAbs_Volume) {
5495 SMDS_VolumeTool aTool;
5496 if(aTool.Set(elem)) {
5498 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5503 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5505 double x=0., y=0., z=0.;
5506 for(; anIt->more(); ) {
5508 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5522 return aResult._retn();
5525 //================================================================================
5527 * \brief Create a group of elements preventing computation of a sub-shape
5529 //================================================================================
5531 SMESH::ListOfGroups*
5532 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5533 const char* theGroupName )
5534 throw ( SALOME::SALOME_Exception )
5536 Unexpect aCatch(SALOME_SalomeException);
5538 if ( !theGroupName || strlen( theGroupName) == 0 )
5539 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5541 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5542 ::SMESH_MeshEditor::ElemFeatures elemType;
5544 // submesh by subshape id
5545 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5546 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5549 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5550 if ( error && error->HasBadElems() )
5552 // sort bad elements by type
5553 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5554 const list<const SMDS_MeshElement*>& badElems =
5555 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5556 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5557 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5558 for ( ; elemIt != elemEnd; ++elemIt )
5560 const SMDS_MeshElement* elem = *elemIt;
5561 if ( !elem ) continue;
5563 if ( elem->GetID() < 1 )
5565 // elem is a temporary element, make a real element
5566 vector< const SMDS_MeshNode* > nodes;
5567 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5568 while ( nIt->more() && elem )
5570 nodes.push_back( nIt->next() );
5571 if ( nodes.back()->GetID() < 1 )
5572 elem = 0; // a temporary element on temporary nodes
5576 ::SMESH_MeshEditor editor( _impl );
5577 elem = editor.AddElement( nodes, elemType.Init( elem ));
5581 elemsByType[ elem->GetType() ].push_back( elem );
5584 // how many groups to create?
5586 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5587 nbTypes += int( !elemsByType[ i ].empty() );
5588 groups->length( nbTypes );
5591 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5593 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5594 if ( elems.empty() ) continue;
5596 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5597 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5599 SMESH::SMESH_Mesh_var mesh = _this();
5600 SALOMEDS::SObject_wrap aSO =
5601 _gen_i->PublishGroup( mesh, groups[ iG ],
5602 GEOM::GEOM_Object::_nil(), theGroupName);
5604 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5605 if ( !grp_i ) continue;
5607 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5608 for ( size_t iE = 0; iE < elems.size(); ++iE )
5609 grpDS->SMDSGroup().Add( elems[ iE ]);
5614 return groups._retn();
5617 //=============================================================================
5619 * Create and publish group servants if any groups were imported or created anyhow
5621 //=============================================================================
5623 void SMESH_Mesh_i::CreateGroupServants()
5625 SMESH::SMESH_Mesh_var aMesh = _this();
5628 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5629 while ( groupIt->more() )
5631 ::SMESH_Group* group = groupIt->next();
5632 int anId = group->GetID();
5634 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5635 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5637 addedIDs.insert( anId );
5639 SMESH_GroupBase_i* aGroupImpl;
5641 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5642 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5644 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5645 shape = groupOnGeom->GetShape();
5648 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5651 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5652 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5653 aGroupImpl->Register();
5655 // register CORBA object for persistence
5656 int nextId = _gen_i->RegisterObject( groupVar );
5657 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5658 else { nextId = 0; } // avoid "unused variable" warning in release mode
5660 // publishing the groups in the study
5661 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5662 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5664 if ( !addedIDs.empty() )
5667 set<int>::iterator id = addedIDs.begin();
5668 for ( ; id != addedIDs.end(); ++id )
5670 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5671 int i = std::distance( _mapGroups.begin(), it );
5672 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5677 //=============================================================================
5679 * \brief Return true if all sub-meshes are computed OK - to update an icon
5681 //=============================================================================
5683 bool SMESH_Mesh_i::IsComputedOK()
5685 return _impl->IsComputedOK();
5688 //=============================================================================
5690 * \brief Return groups cantained in _mapGroups by their IDs
5692 //=============================================================================
5694 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5696 int nbGroups = groupIDs.size();
5697 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5698 aList->length( nbGroups );
5700 list<int>::const_iterator ids = groupIDs.begin();
5701 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5703 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5704 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5705 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5707 aList->length( nbGroups );
5708 return aList._retn();
5711 //=============================================================================
5713 * \brief Return information about imported file
5715 //=============================================================================
5717 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5719 SMESH::MedFileInfo_var res( _medFileInfo );
5720 if ( !res.operator->() ) {
5721 res = new SMESH::MedFileInfo;
5723 res->fileSize = res->major = res->minor = res->release = -1;
5728 //=======================================================================
5729 //function : FileInfoToString
5730 //purpose : Persistence of file info
5731 //=======================================================================
5733 std::string SMESH_Mesh_i::FileInfoToString()
5736 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5738 s = SMESH_Comment( _medFileInfo->fileSize )
5739 << " " << _medFileInfo->major
5740 << " " << _medFileInfo->minor
5741 << " " << _medFileInfo->release
5742 << " " << _medFileInfo->fileName;
5747 //=======================================================================
5748 //function : FileInfoFromString
5749 //purpose : Persistence of file info
5750 //=======================================================================
5752 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5754 std::string size, major, minor, release, fileName;
5755 std::istringstream is(info);
5756 is >> size >> major >> minor >> release;
5757 fileName = info.data() + ( size.size() + 1 +
5760 release.size()+ 1 );
5762 _medFileInfo = new SMESH::MedFileInfo();
5763 _medFileInfo->fileName = fileName.c_str();
5764 _medFileInfo->fileSize = atoi( size.c_str() );
5765 _medFileInfo->major = atoi( major.c_str() );
5766 _medFileInfo->minor = atoi( minor.c_str() );
5767 _medFileInfo->release = atoi( release.c_str() );
5770 //=============================================================================
5772 * \brief Pass names of mesh groups from study to mesh DS
5774 //=============================================================================
5776 void SMESH_Mesh_i::checkGroupNames()
5778 int nbGrp = NbGroups();
5782 SMESH::ListOfGroups* grpList = 0;
5783 // avoid dump of "GetGroups"
5785 // store python dump into a local variable inside local scope
5786 SMESH::TPythonDump pDump; // do not delete this line of code
5787 grpList = GetGroups();
5790 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5791 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5794 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5795 if ( aGrpSO->_is_nil() )
5797 // correct name of the mesh group if necessary
5798 const char* guiName = aGrpSO->GetName();
5799 if ( strcmp(guiName, aGrp->GetName()) )
5800 aGrp->SetName( guiName );
5804 //=============================================================================
5806 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5808 //=============================================================================
5809 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5811 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5815 //=============================================================================
5817 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5819 //=============================================================================
5821 char* SMESH_Mesh_i::GetParameters()
5823 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5826 //=============================================================================
5828 * \brief Returns list of notebook variables used for last Mesh operation
5830 //=============================================================================
5831 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5833 SMESH::string_array_var aResult = new SMESH::string_array();
5834 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5836 CORBA::String_var aParameters = GetParameters();
5837 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5838 if ( aSections->length() > 0 ) {
5839 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5840 aResult->length( aVars.length() );
5841 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5842 aResult[i] = CORBA::string_dup( aVars[i] );
5845 return aResult._retn();
5848 //=======================================================================
5849 //function : GetTypes
5850 //purpose : Returns types of elements it contains
5851 //=======================================================================
5853 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5856 return _preMeshInfo->GetTypes();
5858 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5862 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5863 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5864 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5865 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5866 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5867 if (_impl->NbNodes() &&
5868 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5869 types->length( nbTypes );
5871 return types._retn();
5874 //=======================================================================
5875 //function : GetMesh
5876 //purpose : Returns self
5877 //=======================================================================
5879 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5881 return SMESH::SMESH_Mesh::_duplicate( _this() );
5884 //=======================================================================
5885 //function : IsMeshInfoCorrect
5886 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5887 // * happen if mesh data is not yet fully loaded from the file of study.
5888 //=======================================================================
5890 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5892 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5895 //=============================================================================
5897 * \brief Returns number of mesh elements per each \a EntityType
5899 //=============================================================================
5901 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5904 return _preMeshInfo->GetMeshInfo();
5906 SMESH::long_array_var aRes = new SMESH::long_array();
5907 aRes->length(SMESH::Entity_Last);
5908 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5910 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5912 return aRes._retn();
5913 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5914 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5915 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5916 return aRes._retn();
5919 //=============================================================================
5921 * \brief Returns number of mesh elements per each \a ElementType
5923 //=============================================================================
5925 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5927 SMESH::long_array_var aRes = new SMESH::long_array();
5928 aRes->length(SMESH::NB_ELEMENT_TYPES);
5929 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5932 const SMDS_MeshInfo* meshInfo = 0;
5934 meshInfo = _preMeshInfo;
5935 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5936 meshInfo = & meshDS->GetMeshInfo();
5939 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5940 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5942 return aRes._retn();
5945 //=============================================================================
5947 * Collect statistic of mesh elements given by iterator
5949 //=============================================================================
5951 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5952 SMESH::long_array& theInfo)
5954 if (!theItr) return;
5955 while (theItr->more())
5956 theInfo[ theItr->next()->GetEntityType() ]++;
5958 //=============================================================================
5960 * Returns mesh unstructed grid information.
5962 //=============================================================================
5964 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5966 SALOMEDS::TMPFile_var SeqFile;
5967 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5968 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5970 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5971 aWriter->WriteToOutputStringOn();
5972 aWriter->SetInputData(aGrid);
5973 aWriter->SetFileTypeToBinary();
5975 char* str = aWriter->GetOutputString();
5976 int size = aWriter->GetOutputStringLength();
5978 //Allocate octet buffer of required size
5979 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5980 //Copy ostrstream content to the octet buffer
5981 memcpy(OctetBuf, str, size);
5982 //Create and return TMPFile
5983 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5987 return SeqFile._retn();
5990 //=============================================================================
5991 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5992 * SMESH::ElementType type) */
5994 using namespace SMESH::Controls;
5995 //-----------------------------------------------------------------------------
5996 struct PredicateIterator : public SMDS_ElemIterator
5998 SMDS_ElemIteratorPtr _elemIter;
5999 PredicatePtr _predicate;
6000 const SMDS_MeshElement* _elem;
6001 SMDSAbs_ElementType _type;
6003 PredicateIterator( SMDS_ElemIteratorPtr iterator,
6004 PredicatePtr predicate,
6005 SMDSAbs_ElementType type):
6006 _elemIter(iterator), _predicate(predicate), _type(type)
6014 virtual const SMDS_MeshElement* next()
6016 const SMDS_MeshElement* res = _elem;
6018 while ( _elemIter->more() && !_elem )
6020 if ((_elem = _elemIter->next()) &&
6021 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
6022 ( !_predicate->IsSatisfy( _elem->GetID() ))))
6029 //-----------------------------------------------------------------------------
6030 struct IDSourceIterator : public SMDS_ElemIterator
6032 const CORBA::Long* _idPtr;
6033 const CORBA::Long* _idEndPtr;
6034 SMESH::long_array_var _idArray;
6035 const SMDS_Mesh* _mesh;
6036 const SMDSAbs_ElementType _type;
6037 const SMDS_MeshElement* _elem;
6039 IDSourceIterator( const SMDS_Mesh* mesh,
6040 const CORBA::Long* ids,
6042 SMDSAbs_ElementType type):
6043 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
6045 if ( _idPtr && nbIds && _mesh )
6048 IDSourceIterator( const SMDS_Mesh* mesh,
6049 SMESH::long_array* idArray,
6050 SMDSAbs_ElementType type):
6051 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
6053 if ( idArray && _mesh )
6055 _idPtr = &_idArray[0];
6056 _idEndPtr = _idPtr + _idArray->length();
6064 virtual const SMDS_MeshElement* next()
6066 const SMDS_MeshElement* res = _elem;
6068 while ( _idPtr < _idEndPtr && !_elem )
6070 if ( _type == SMDSAbs_Node )
6072 _elem = _mesh->FindNode( *_idPtr++ );
6074 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
6075 (_elem->GetType() != _type && _type != SMDSAbs_All ))
6083 //-----------------------------------------------------------------------------
6085 struct NodeOfElemIterator : public SMDS_ElemIterator
6087 TColStd_MapOfInteger _checkedNodeIDs;
6088 SMDS_ElemIteratorPtr _elemIter;
6089 SMDS_ElemIteratorPtr _nodeIter;
6090 const SMDS_MeshElement* _node;
6092 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
6094 if ( _elemIter && _elemIter->more() )
6096 _nodeIter = _elemIter->next()->nodesIterator();
6104 virtual const SMDS_MeshElement* next()
6106 const SMDS_MeshElement* res = _node;
6108 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
6110 if ( _nodeIter->more() )
6112 _node = _nodeIter->next();
6113 if ( !_checkedNodeIDs.Add( _node->GetID() ))
6118 _nodeIter = _elemIter->next()->nodesIterator();
6126 //=============================================================================
6128 * Return iterator on elements of given type in given object
6130 //=============================================================================
6132 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
6133 SMESH::ElementType theType)
6135 SMDS_ElemIteratorPtr elemIt;
6136 bool typeOK = ( theType == SMESH::ALL );
6137 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
6139 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
6140 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
6141 if ( !mesh_i ) return elemIt;
6142 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
6144 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
6146 elemIt = meshDS->elementsIterator( elemType );
6149 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
6151 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
6154 elemIt = sm->GetElements();
6155 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6157 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
6158 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
6162 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
6164 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
6165 if ( groupDS && ( elemType == groupDS->GetType() ||
6166 elemType == SMDSAbs_Node ||
6167 elemType == SMDSAbs_All ))
6169 elemIt = groupDS->GetElements();
6170 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
6173 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
6175 if ( filter_i->GetElementType() == theType ||
6176 filter_i->GetElementType() == SMESH::ALL ||
6177 elemType == SMDSAbs_Node ||
6178 elemType == SMDSAbs_All)
6180 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
6181 if ( pred_i && pred_i->GetPredicate() )
6183 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
6184 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
6185 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
6186 elemIt = SMDS_ElemIteratorPtr
6187 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
6188 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
6194 SMESH::array_of_ElementType_var types = theObject->GetTypes();
6195 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
6196 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6198 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
6199 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
6202 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
6203 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
6207 SMESH::long_array_var ids = theObject->GetIDs();
6208 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
6210 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
6213 if ( elemIt && elemIt->more() && !typeOK )
6215 if ( elemType == SMDSAbs_Node )
6217 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
6221 elemIt = SMDS_ElemIteratorPtr();
6227 //=============================================================================
6228 namespace // Finding concurrent hypotheses
6229 //=============================================================================
6233 * \brief mapping of mesh dimension into shape type
6235 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
6237 TopAbs_ShapeEnum aType = TopAbs_SOLID;
6239 case 0: aType = TopAbs_VERTEX; break;
6240 case 1: aType = TopAbs_EDGE; break;
6241 case 2: aType = TopAbs_FACE; break;
6243 default:aType = TopAbs_SOLID; break;
6248 //-----------------------------------------------------------------------------
6250 * \brief Internal structure used to find concurrent submeshes
6252 * It represents a pair < submesh, concurrent dimension >, where
6253 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
6254 * with another submesh. In other words, it is dimension of a hypothesis assigned
6261 int _dim; //!< a dimension the algo can build (concurrent dimension)
6262 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
6263 TopTools_MapOfShape _shapeMap;
6264 SMESH_subMesh* _subMesh;
6265 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
6267 //-----------------------------------------------------------------------------
6268 // Return the algorithm
6269 const SMESH_Algo* GetAlgo() const
6270 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
6272 //-----------------------------------------------------------------------------
6274 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
6276 const TopoDS_Shape& theShape)
6278 _subMesh = (SMESH_subMesh*)theSubMesh;
6279 SetShape( theDim, theShape );
6282 //-----------------------------------------------------------------------------
6284 void SetShape(const int theDim,
6285 const TopoDS_Shape& theShape)
6288 _ownDim = SMESH_Gen::GetShapeDim(theShape);
6289 if (_dim >= _ownDim)
6290 _shapeMap.Add( theShape );
6292 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
6293 for( ; anExp.More(); anExp.Next() )
6294 _shapeMap.Add( anExp.Current() );
6298 //-----------------------------------------------------------------------------
6299 //! Check sharing of sub-shapes
6300 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
6301 const TopTools_MapOfShape& theToFind,
6302 const TopAbs_ShapeEnum theType)
6304 bool isShared = false;
6305 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
6306 for (; !isShared && anItr.More(); anItr.Next() )
6308 const TopoDS_Shape aSubSh = anItr.Key();
6309 // check for case when concurrent dimensions are same
6310 isShared = theToFind.Contains( aSubSh );
6311 // check for sub-shape with concurrent dimension
6312 TopExp_Explorer anExp( aSubSh, theType );
6313 for ( ; !isShared && anExp.More(); anExp.Next() )
6314 isShared = theToFind.Contains( anExp.Current() );
6319 //-----------------------------------------------------------------------------
6320 //! check algorithms
6321 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
6322 const SMESHDS_Hypothesis* theA2)
6324 if ( !theA1 || !theA2 ||
6325 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
6326 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
6327 return false; // one of the hypothesis is not algorithm
6328 // check algorithm names (should be equal)
6329 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
6333 //-----------------------------------------------------------------------------
6334 //! Check if sub-shape hypotheses are concurrent
6335 bool IsConcurrent(const SMESH_DimHyp* theOther) const
6337 if ( _subMesh == theOther->_subMesh )
6338 return false; // same sub-shape - should not be
6340 // if ( <own dim of either of submeshes> == <concurrent dim> &&
6341 // any of the two submeshes is not on COMPOUND shape )
6342 // -> no concurrency
6343 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
6344 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
6345 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
6346 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
6347 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
6350 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
6351 if ( !checkSubShape )
6354 // check algorithms to be same
6355 const SMESH_Algo* a1 = this->GetAlgo();
6356 const SMESH_Algo* a2 = theOther->GetAlgo();
6357 bool isSame = checkAlgo( a1, a2 );
6361 return false; // pb?
6362 return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency !
6365 // check hypothesises for concurrence (skip first as algorithm)
6367 // pointers should be same, because it is referened from mesh hypothesis partition
6368 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
6369 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
6370 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
6371 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
6373 // the submeshes are concurrent if their algorithms has different parameters
6374 return nbSame != theOther->_hypotheses.size() - 1;
6377 // Return true if algorithm of this SMESH_DimHyp is used if no
6378 // sub-mesh order is imposed by the user
6379 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
6381 // NeedDiscreteBoundary() algo has a higher priority
6382 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
6383 theOther->GetAlgo()->NeedDiscreteBoundary() )
6384 return !this->GetAlgo()->NeedDiscreteBoundary();
6386 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
6389 }; // end of SMESH_DimHyp
6390 //-----------------------------------------------------------------------------
6392 typedef list<const SMESH_DimHyp*> TDimHypList;
6394 //-----------------------------------------------------------------------------
6396 void addDimHypInstance(const int theDim,
6397 const TopoDS_Shape& theShape,
6398 const SMESH_Algo* theAlgo,
6399 const SMESH_subMesh* theSubMesh,
6400 const list <const SMESHDS_Hypothesis*>& theHypList,
6401 TDimHypList* theDimHypListArr )
6403 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
6404 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
6405 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
6406 dimHyp->_hypotheses.push_front(theAlgo);
6407 listOfdimHyp.push_back( dimHyp );
6410 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
6411 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
6412 theHypList.begin(), theHypList.end() );
6415 //-----------------------------------------------------------------------------
6416 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
6417 TDimHypList& theListOfConcurr)
6419 if ( theListOfConcurr.empty() )
6421 theListOfConcurr.push_back( theDimHyp );
6425 TDimHypList::iterator hypIt = theListOfConcurr.begin();
6426 while ( hypIt != theListOfConcurr.end() &&
6427 !theDimHyp->IsHigherPriorityThan( *hypIt ))
6429 theListOfConcurr.insert( hypIt, theDimHyp );
6433 //-----------------------------------------------------------------------------
6434 void findConcurrents(const SMESH_DimHyp* theDimHyp,
6435 const TDimHypList& theListOfDimHyp,
6436 TDimHypList& theListOfConcurrHyp,
6437 set<int>& theSetOfConcurrId )
6439 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
6440 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
6442 const SMESH_DimHyp* curDimHyp = *rIt;
6443 if ( curDimHyp == theDimHyp )
6444 break; // meet own dimHyp pointer in same dimension
6446 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
6447 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
6449 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
6454 //-----------------------------------------------------------------------------
6455 void unionLists(TListOfInt& theListOfId,
6456 TListOfListOfInt& theListOfListOfId,
6459 TListOfListOfInt::iterator it = theListOfListOfId.begin();
6460 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
6462 continue; //skip already treated lists
6463 // check if other list has any same submesh object
6464 TListOfInt& otherListOfId = *it;
6465 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
6466 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
6469 // union two lists (from source into target)
6470 TListOfInt::iterator it2 = otherListOfId.begin();
6471 for ( ; it2 != otherListOfId.end(); it2++ ) {
6472 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
6473 theListOfId.push_back(*it2);
6475 // clear source list
6476 otherListOfId.clear();
6479 //-----------------------------------------------------------------------------
6481 //! free memory allocated for dimension-hypothesis objects
6482 void removeDimHyps( TDimHypList* theArrOfList )
6484 for (int i = 0; i < 4; i++ ) {
6485 TDimHypList& listOfdimHyp = theArrOfList[i];
6486 TDimHypList::const_iterator it = listOfdimHyp.begin();
6487 for ( ; it != listOfdimHyp.end(); it++ )
6492 //-----------------------------------------------------------------------------
6494 * \brief find common submeshes with given submesh
6495 * \param theSubMeshList list of already collected submesh to check
6496 * \param theSubMesh given submesh to intersect with other
6497 * \param theCommonSubMeshes collected common submeshes
6499 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6500 const SMESH_subMesh* theSubMesh,
6501 set<const SMESH_subMesh*>& theCommon )
6505 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6506 for ( ; it != theSubMeshList.end(); it++ )
6507 theSubMesh->FindIntersection( *it, theCommon );
6508 theSubMeshList.push_back( theSubMesh );
6509 //theCommon.insert( theSubMesh );
6512 //-----------------------------------------------------------------------------
6513 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6515 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6516 for ( ; listsIt != smLists.end(); ++listsIt )
6518 const TListOfInt& smIDs = *listsIt;
6519 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6527 //=============================================================================
6529 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6531 //=============================================================================
6533 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6535 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6536 if ( isSubMeshInList( submeshID, anOrder ))
6539 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6540 return isSubMeshInList( submeshID, allConurrent );
6543 //=============================================================================
6545 * \brief Return submesh objects list in meshing order
6547 //=============================================================================
6549 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6551 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6553 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6555 return aResult._retn();
6557 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6558 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6559 anOrder.splice( anOrder.end(), allConurrent );
6562 TListOfListOfInt::iterator listIt = anOrder.begin();
6563 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6564 unionLists( *listIt, anOrder, listIndx + 1 );
6566 // convert submesh ids into interface instances
6567 // and dump command into python
6568 convertMeshOrder( anOrder, aResult, false );
6570 return aResult._retn();
6573 //=============================================================================
6575 * \brief Finds concurrent sub-meshes
6577 //=============================================================================
6579 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6581 TListOfListOfInt anOrder;
6582 ::SMESH_Mesh& mesh = GetImpl();
6584 // collect submeshes and detect concurrent algorithms and hypothesises
6585 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6587 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6588 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
6589 ::SMESH_subMesh* sm = (*i_sm).second;
6591 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6593 // list of assigned hypothesises
6594 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6595 // Find out dimensions where the submesh can be concurrent.
6596 // We define the dimensions by algo of each of hypotheses in hypList
6597 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6598 for( ; hypIt != hypList.end(); hypIt++ ) {
6599 SMESH_Algo* anAlgo = 0;
6600 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6601 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6602 // hyp it-self is algo
6603 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6605 // try to find algorithm with help of sub-shapes
6606 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6607 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6608 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6611 continue; // no algorithm assigned to a current submesh
6613 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6614 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
6616 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6617 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6618 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6620 } // end iterations on submesh
6622 // iterate on created dimension-hypotheses and check for concurrents
6623 for ( int i = 0; i < 4; i++ ) {
6624 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6625 // check for concurrents in own and other dimensions (step-by-step)
6626 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6627 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
6628 const SMESH_DimHyp* dimHyp = *dhIt;
6629 TDimHypList listOfConcurr;
6630 set<int> setOfConcurrIds;
6631 // looking for concurrents and collect into own list
6632 for ( int j = i; j < 4; j++ )
6633 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6634 // check if any concurrents found
6635 if ( listOfConcurr.size() > 0 ) {
6636 // add own submesh to list of concurrent
6637 addInOrderOfPriority( dimHyp, listOfConcurr );
6638 list<int> listOfConcurrIds;
6639 TDimHypList::iterator hypIt = listOfConcurr.begin();
6640 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6641 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6642 anOrder.push_back( listOfConcurrIds );
6647 removeDimHyps(dimHypListArr);
6649 // now, minimize the number of concurrent groups
6650 // Here we assume that lists of submeshes can have same submesh
6651 // in case of multi-dimension algorithms, as result
6652 // list with common submesh has to be united into one list
6654 TListOfListOfInt::iterator listIt = anOrder.begin();
6655 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6656 unionLists( *listIt, anOrder, listIndx + 1 );
6662 //=============================================================================
6664 * \brief Set submesh object order
6665 * \param theSubMeshArray submesh array order
6667 //=============================================================================
6669 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6672 _preMeshInfo->ForgetOrLoad();
6675 ::SMESH_Mesh& mesh = GetImpl();
6677 TPythonDump aPythonDump; // prevent dump of called methods
6678 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6680 TListOfListOfInt subMeshOrder;
6681 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6683 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6684 TListOfInt subMeshIds;
6686 aPythonDump << ", ";
6687 aPythonDump << "[ ";
6688 // Collect subMeshes which should be clear
6689 // do it list-by-list, because modification of submesh order
6690 // take effect between concurrent submeshes only
6691 set<const SMESH_subMesh*> subMeshToClear;
6692 list<const SMESH_subMesh*> subMeshList;
6693 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6695 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6697 aPythonDump << ", ";
6698 aPythonDump << subMesh;
6699 subMeshIds.push_back( subMesh->GetId() );
6700 // detect common parts of submeshes
6701 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6702 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6704 aPythonDump << " ]";
6705 subMeshOrder.push_back( subMeshIds );
6707 // clear collected sub-meshes
6708 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6709 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6710 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6712 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6713 if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748
6714 sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo
6717 aPythonDump << " ])";
6719 mesh.SetMeshOrder( subMeshOrder );
6722 SMESH::SMESH_Mesh_var me = _this();
6723 _gen_i->UpdateIcons( me );
6728 //=============================================================================
6730 * \brief Convert submesh ids into submesh interfaces
6732 //=============================================================================
6734 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6735 SMESH::submesh_array_array& theResOrder,
6736 const bool theIsDump)
6738 int nbSet = theIdsOrder.size();
6739 TPythonDump aPythonDump; // prevent dump of called methods
6741 aPythonDump << "[ ";
6742 theResOrder.length(nbSet);
6743 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6745 for( ; it != theIdsOrder.end(); it++ ) {
6746 // translate submesh identificators into submesh objects
6747 // takeing into account real number of concurrent lists
6748 const TListOfInt& aSubOrder = (*it);
6749 if (!aSubOrder.size())
6752 aPythonDump << "[ ";
6753 // convert shape indices into interfaces
6754 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6755 aResSubSet->length(aSubOrder.size());
6756 TListOfInt::const_iterator subIt = aSubOrder.begin();
6758 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6759 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6761 SMESH::SMESH_subMesh_var subMesh =
6762 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6765 aPythonDump << ", ";
6766 aPythonDump << subMesh;
6768 aResSubSet[ j++ ] = subMesh;
6771 aPythonDump << " ]";
6773 theResOrder[ listIndx++ ] = aResSubSet;
6775 // correct number of lists
6776 theResOrder.length( listIndx );
6779 // finilise python dump
6780 aPythonDump << " ]";
6781 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6785 namespace // utils used by SMESH_MeshPartDS
6788 * \brief Class used to access to protected data of SMDS_MeshInfo
6790 struct TMeshInfo : public SMDS_MeshInfo
6792 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6795 * \brief Element holing its ID only
6797 struct TElemID : public SMDS_LinearEdge
6799 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6803 //================================================================================
6805 // Implementation of SMESH_MeshPartDS
6807 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6808 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6810 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6811 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6814 _meshDS = mesh_i->GetImpl().GetMeshDS();
6816 SetPersistentId( _meshDS->GetPersistentId() );
6818 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6820 // <meshPart> is the whole mesh
6821 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6823 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6824 myGroupSet = _meshDS->GetGroups();
6829 SMESH::long_array_var anIDs = meshPart->GetIDs();
6830 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6831 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6833 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6834 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6835 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6840 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6841 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6842 if ( _elements[ e->GetType() ].insert( e ).second )
6845 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6846 while ( nIt->more() )
6848 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6849 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6856 ShapeToMesh( _meshDS->ShapeToMesh() );
6858 _meshDS = 0; // to enforce iteration on _elements and _nodes
6861 // -------------------------------------------------------------------------------------
6862 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6863 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6866 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6867 for ( ; partIt != meshPart.end(); ++partIt )
6868 if ( const SMDS_MeshElement * e = *partIt )
6869 if ( _elements[ e->GetType() ].insert( e ).second )
6872 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6873 while ( nIt->more() )
6875 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6876 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6882 // -------------------------------------------------------------------------------------
6883 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6885 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6887 TElemID elem( IDelem );
6888 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6889 if ( !_elements[ iType ].empty() )
6891 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6892 if ( it != _elements[ iType ].end() )
6897 // -------------------------------------------------------------------------------------
6898 bool SMESH_MeshPartDS::HasNumerationHoles()
6900 if ( _meshDS ) return _meshDS->HasNumerationHoles();
6902 return ( MinNodeID() != 1 ||
6903 MaxNodeID() != NbNodes() ||
6904 MinElementID() != 1 ||
6905 MaxElementID() != NbElements() );
6907 // -------------------------------------------------------------------------------------
6908 int SMESH_MeshPartDS::MaxNodeID() const
6910 if ( _meshDS ) return _meshDS->MaxNodeID();
6911 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID();
6913 // -------------------------------------------------------------------------------------
6914 int SMESH_MeshPartDS::MinNodeID() const
6916 if ( _meshDS ) return _meshDS->MinNodeID();
6917 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID();
6919 // -------------------------------------------------------------------------------------
6920 int SMESH_MeshPartDS::MaxElementID() const
6922 if ( _meshDS ) return _meshDS->MaxElementID();
6924 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6925 if ( !_elements[ iType ].empty() )
6926 maxID = Max( maxID, (*_elements[ iType ].rbegin())->GetID() );
6929 // -------------------------------------------------------------------------------------
6930 int SMESH_MeshPartDS::MinElementID() const
6932 if ( _meshDS ) return _meshDS->MinElementID();
6934 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6935 if ( !_elements[ iType ].empty() )
6936 minID = Min( minID, (*_elements[ iType ].begin())->GetID() );
6939 // -------------------------------------------------------------------------------------
6940 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6942 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6944 typedef SMDS_SetIterator
6945 <const SMDS_MeshElement*,
6946 TIDSortedElemSet::const_iterator,
6947 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6948 SMDS_MeshElement::GeomFilter
6951 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6953 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6954 _elements[type].end(),
6955 SMDS_MeshElement::GeomFilter( geomType )));
6957 // -------------------------------------------------------------------------------------
6958 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6960 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6962 typedef SMDS_SetIterator
6963 <const SMDS_MeshElement*,
6964 TIDSortedElemSet::const_iterator,
6965 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6966 SMDS_MeshElement::EntityFilter
6969 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6971 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6972 _elements[type].end(),
6973 SMDS_MeshElement::EntityFilter( entity )));
6975 // -------------------------------------------------------------------------------------
6976 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6978 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6979 if ( type == SMDSAbs_All && !_meshDS )
6981 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6983 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6984 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6986 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6988 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6989 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6991 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6992 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6994 // -------------------------------------------------------------------------------------
6995 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6996 iterType SMESH_MeshPartDS::methName() const \
6998 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6999 return _meshDS ? _meshDS->methName() : iterType \
7000 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
7002 // -------------------------------------------------------------------------------------
7003 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
7004 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
7005 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
7006 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
7007 #undef _GET_ITER_DEFINE
7009 // END Implementation of SMESH_MeshPartDS
7011 //================================================================================