1 // Copyright (C) 2007-2020 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 TopoDS_Iterator it( myLocSubShape );
961 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
962 bool isValidSub = ( subMeshId || _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ));
963 if ( isValidSub && myLocSubShape.ShapeType() == TopAbs_COMPOUND )
964 isValidSub = !it.Value().IsSame( _impl->GetShapeToMesh() );
968 THROW_SALOME_CORBA_EXCEPTION("Not a sub-shape of the main shape", SALOME::BAD_PARAM);
970 subMesh = getSubMesh( subMeshId );
972 // create a new subMesh object servant if there is none for the shape
973 if ( subMesh->_is_nil() )
974 subMesh = createSubMesh( aSubShape );
975 if ( _gen_i->CanPublishInStudy( subMesh ))
977 SALOMEDS::SObject_wrap aSO =
978 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
979 if ( !aSO->_is_nil()) {
980 // Update Python script
981 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
982 << aSubShape << ", '" << theName << "' )";
986 catch(SALOME_Exception & S_ex) {
987 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
989 return subMesh._retn();
992 //=============================================================================
996 //=============================================================================
998 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
999 throw (SALOME::SALOME_Exception)
1003 if ( theSubMesh->_is_nil() )
1006 GEOM::GEOM_Object_var aSubShape;
1007 // Remove submesh's SObject
1008 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
1009 if ( !anSO->_is_nil() ) {
1010 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
1011 SALOMEDS::SObject_wrap anObj, aRef;
1012 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
1013 anObj->ReferencedObject( aRef.inout() ))
1015 CORBA::Object_var obj = aRef->GetObject();
1016 aSubShape = GEOM::GEOM_Object::_narrow( obj );
1018 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
1019 // aSubShape = theSubMesh->GetSubShape();
1021 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
1022 builder->RemoveObjectWithChildren( anSO );
1024 // Update Python script
1025 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
1028 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
1030 _preMeshInfo->ForgetOrLoad();
1032 SMESH_CATCH( SMESH::throwCorbaException );
1035 //=============================================================================
1039 //=============================================================================
1041 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
1042 const char* theName )
1043 throw(SALOME::SALOME_Exception)
1045 Unexpect aCatch(SALOME_SalomeException);
1047 _preMeshInfo->FullLoadFromFile();
1049 SMESH::SMESH_Group_var aNewGroup =
1050 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
1052 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1054 SMESH::SMESH_Mesh_var mesh = _this();
1055 SALOMEDS::SObject_wrap aSO =
1056 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
1057 if ( !aSO->_is_nil())
1058 // Update Python script
1059 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
1060 << theElemType << ", '" << theName << "' )";
1062 return aNewGroup._retn();
1065 //=============================================================================
1069 //=============================================================================
1070 SMESH::SMESH_GroupOnGeom_ptr
1071 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
1072 const char* theName,
1073 GEOM::GEOM_Object_ptr theGeomObj)
1074 throw(SALOME::SALOME_Exception)
1076 Unexpect aCatch(SALOME_SalomeException);
1078 _preMeshInfo->FullLoadFromFile();
1080 SMESH::SMESH_GroupOnGeom_var aNewGroup;
1082 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
1083 if ( !aShape.IsNull() )
1086 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, /*id=*/-1, aShape ));
1088 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1090 SMESH::SMESH_Mesh_var mesh = _this();
1091 SALOMEDS::SObject_wrap aSO =
1092 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
1093 if ( !aSO->_is_nil())
1094 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
1095 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
1099 return aNewGroup._retn();
1102 //================================================================================
1104 * \brief Creates a group whose contents is defined by filter
1105 * \param theElemType - group type
1106 * \param theName - group name
1107 * \param theFilter - the filter
1108 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1110 //================================================================================
1112 SMESH::SMESH_GroupOnFilter_ptr
1113 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1114 const char* theName,
1115 SMESH::Filter_ptr theFilter )
1116 throw (SALOME::SALOME_Exception)
1118 Unexpect aCatch(SALOME_SalomeException);
1120 _preMeshInfo->FullLoadFromFile();
1122 if ( CORBA::is_nil( theFilter ))
1123 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1125 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1127 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1129 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1130 ( createGroup( theElemType, theName, /*id=*/-1, TopoDS_Shape(), predicate ));
1133 if ( !aNewGroup->_is_nil() )
1134 aNewGroup->SetFilter( theFilter );
1136 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1138 SMESH::SMESH_Mesh_var mesh = _this();
1139 SALOMEDS::SObject_wrap aSO =
1140 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1142 if ( !aSO->_is_nil())
1143 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1144 << theElemType << ", '" << theName << "', " << theFilter << " )";
1146 return aNewGroup._retn();
1149 //=============================================================================
1153 //=============================================================================
1155 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1156 throw (SALOME::SALOME_Exception)
1158 if ( theGroup->_is_nil() )
1163 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1167 if ( aGroup->GetMeshServant() != this )
1168 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroup(): group does not belong to this mesh",
1169 SALOME::BAD_PARAM );
1171 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1172 if ( !aGroupSO->_is_nil() )
1174 // Update Python script
1175 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1177 // Remove group's SObject
1178 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1179 builder->RemoveObjectWithChildren( aGroupSO );
1181 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1183 // Remove the group from SMESH data structures
1184 removeGroup( aGroup->GetLocalID() );
1186 SMESH_CATCH( SMESH::throwCorbaException );
1189 //=============================================================================
1191 * Remove group with its contents
1193 //=============================================================================
1195 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1196 throw (SALOME::SALOME_Exception)
1200 _preMeshInfo->FullLoadFromFile();
1202 if ( theGroup->_is_nil() )
1205 SMESH_GroupBase_i* groupImpl = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup );
1206 if ( !groupImpl || groupImpl->GetMeshServant() != this )
1207 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroupWithContents(): group does not belong to this mesh",
1210 vector<int> nodeIds; // to remove nodes becoming free
1211 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1212 if ( !isNodal && !theGroup->IsEmpty() )
1214 CORBA::Long elemID = theGroup->GetID( 1 );
1215 int nbElemNodes = GetElemNbNodes( elemID );
1216 if ( nbElemNodes > 0 )
1217 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1220 // Retrieve contents
1221 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1222 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1223 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1224 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1225 elems.assign( elemBeg, elemEnd );
1227 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1230 RemoveGroup( theGroup );
1233 for ( size_t i = 0; i < elems.size(); ++i )
1235 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1239 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1240 nodeIds.push_back( nIt->next()->GetID() );
1242 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1246 _impl->GetMeshDS()->RemoveElement( elems[i] );
1250 // Remove free nodes
1251 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1252 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1253 if ( n->NbInverseElements() == 0 )
1254 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1256 // Update Python script (theGroup must be alive for this)
1257 pyDump << SMESH::SMESH_Mesh_var(_this())
1258 << ".RemoveGroupWithContents( " << theGroup << " )";
1260 SMESH_CATCH( SMESH::throwCorbaException );
1263 //================================================================================
1265 * \brief Get the list of groups existing in the mesh
1266 * \retval SMESH::ListOfGroups * - list of groups
1268 //================================================================================
1270 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1272 Unexpect aCatch(SALOME_SalomeException);
1273 if (MYDEBUG) MESSAGE("GetGroups");
1275 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1278 TPythonDump aPythonDump;
1279 if ( !_mapGroups.empty() )
1281 aPythonDump << "[ ";
1283 aList->length( _mapGroups.size() );
1285 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1286 for ( ; it != _mapGroups.end(); it++ ) {
1287 if ( CORBA::is_nil( it->second )) continue;
1288 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1290 if (i > 1) aPythonDump << ", ";
1291 aPythonDump << it->second;
1295 catch(SALOME_Exception & S_ex) {
1296 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1298 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1300 return aList._retn();
1303 //=============================================================================
1305 * Get number of groups existing in the mesh
1307 //=============================================================================
1309 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1311 Unexpect aCatch(SALOME_SalomeException);
1312 return _mapGroups.size();
1315 //=============================================================================
1317 * New group including all mesh elements present in initial groups is created.
1319 //=============================================================================
1321 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1322 SMESH::SMESH_GroupBase_ptr theGroup2,
1323 const char* theName )
1324 throw (SALOME::SALOME_Exception)
1326 SMESH::SMESH_Group_var aResGrp;
1330 _preMeshInfo->FullLoadFromFile();
1332 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1333 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1335 if ( theGroup1->GetType() != theGroup2->GetType() )
1336 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1341 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1342 if ( aResGrp->_is_nil() )
1343 return SMESH::SMESH_Group::_nil();
1345 aResGrp->AddFrom( theGroup1 );
1346 aResGrp->AddFrom( theGroup2 );
1348 // Update Python script
1349 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1350 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1352 SMESH_CATCH( SMESH::throwCorbaException );
1354 return aResGrp._retn();
1357 //=============================================================================
1359 * \brief New group including all mesh elements present in initial groups is created.
1360 * \param theGroups list of groups
1361 * \param theName name of group to be created
1362 * \return pointer to the new group
1364 //=============================================================================
1366 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1367 const char* theName )
1368 throw (SALOME::SALOME_Exception)
1370 SMESH::SMESH_Group_var aResGrp;
1373 _preMeshInfo->FullLoadFromFile();
1376 return SMESH::SMESH_Group::_nil();
1381 SMESH::ElementType aType = SMESH::ALL;
1382 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1384 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1385 if ( CORBA::is_nil( aGrp ) )
1387 if ( aType == SMESH::ALL )
1388 aType = aGrp->GetType();
1389 else if ( aType != aGrp->GetType() )
1390 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1393 if ( aType == SMESH::ALL )
1394 return SMESH::SMESH_Group::_nil();
1399 aResGrp = CreateGroup( aType, theName );
1400 if ( aResGrp->_is_nil() )
1401 return SMESH::SMESH_Group::_nil();
1403 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1404 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1406 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1407 if ( !CORBA::is_nil( aGrp ) )
1409 aResGrp->AddFrom( aGrp );
1410 if ( g > 0 ) pyDump << ", ";
1414 pyDump << " ], '" << theName << "' )";
1416 SMESH_CATCH( SMESH::throwCorbaException );
1418 return aResGrp._retn();
1421 //=============================================================================
1423 * New group is created. All mesh elements that are
1424 * present in both initial groups are added to the new one.
1426 //=============================================================================
1428 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1429 SMESH::SMESH_GroupBase_ptr theGroup2,
1430 const char* theName )
1431 throw (SALOME::SALOME_Exception)
1433 SMESH::SMESH_Group_var aResGrp;
1438 _preMeshInfo->FullLoadFromFile();
1440 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1441 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1443 if ( theGroup1->GetType() != theGroup2->GetType() )
1444 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1448 // Create Intersection
1449 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1450 if ( aResGrp->_is_nil() )
1451 return aResGrp._retn();
1453 SMESHDS_GroupBase* groupDS1 = 0;
1454 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1455 groupDS1 = grp_i->GetGroupDS();
1457 SMESHDS_GroupBase* groupDS2 = 0;
1458 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1459 groupDS2 = grp_i->GetGroupDS();
1461 SMESHDS_Group* resGroupDS = 0;
1462 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1463 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1465 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1467 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1468 while ( elemIt1->more() )
1470 const SMDS_MeshElement* e = elemIt1->next();
1471 if ( groupDS2->Contains( e ))
1472 resGroupDS->SMDSGroup().Add( e );
1475 // Update Python script
1476 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1477 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1479 SMESH_CATCH( SMESH::throwCorbaException );
1481 return aResGrp._retn();
1484 //=============================================================================
1486 \brief Intersect list of groups. New group is created. All mesh elements that
1487 are present in all initial groups simultaneously are added to the new one.
1488 \param theGroups list of groups
1489 \param theName name of group to be created
1490 \return pointer on the group
1492 //=============================================================================
1493 SMESH::SMESH_Group_ptr
1494 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1495 const char* theName )
1496 throw (SALOME::SALOME_Exception)
1498 SMESH::SMESH_Group_var aResGrp;
1503 _preMeshInfo->FullLoadFromFile();
1506 return SMESH::SMESH_Group::_nil();
1508 // check types and get SMESHDS_GroupBase's
1509 SMESH::ElementType aType = SMESH::ALL;
1510 vector< SMESHDS_GroupBase* > groupVec;
1511 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1513 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1514 if ( CORBA::is_nil( aGrp ) )
1516 if ( aType == SMESH::ALL )
1517 aType = aGrp->GetType();
1518 else if ( aType != aGrp->GetType() )
1519 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1522 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1523 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1525 if ( grpDS->IsEmpty() )
1530 groupVec.push_back( grpDS );
1533 if ( aType == SMESH::ALL ) // all groups are nil
1534 return SMESH::SMESH_Group::_nil();
1539 aResGrp = CreateGroup( aType, theName );
1541 SMESHDS_Group* resGroupDS = 0;
1542 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1543 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1544 if ( !resGroupDS || groupVec.empty() )
1545 return aResGrp._retn();
1548 size_t i, nb = groupVec.size();
1549 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1550 while ( elemIt1->more() )
1552 const SMDS_MeshElement* e = elemIt1->next();
1554 for ( i = 1; ( i < nb && inAll ); ++i )
1555 inAll = groupVec[i]->Contains( e );
1558 resGroupDS->SMDSGroup().Add( e );
1561 // Update Python script
1562 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1563 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1565 SMESH_CATCH( SMESH::throwCorbaException );
1567 return aResGrp._retn();
1570 //=============================================================================
1572 * New group is created. All mesh elements that are present in
1573 * a main group but is not present in a tool group are added to the new one
1575 //=============================================================================
1577 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1578 SMESH::SMESH_GroupBase_ptr theGroup2,
1579 const char* theName )
1580 throw (SALOME::SALOME_Exception)
1582 SMESH::SMESH_Group_var aResGrp;
1587 _preMeshInfo->FullLoadFromFile();
1589 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1590 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1592 if ( theGroup1->GetType() != theGroup2->GetType() )
1593 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1597 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1598 if ( aResGrp->_is_nil() )
1599 return aResGrp._retn();
1601 SMESHDS_GroupBase* groupDS1 = 0;
1602 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1603 groupDS1 = grp_i->GetGroupDS();
1605 SMESHDS_GroupBase* groupDS2 = 0;
1606 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1607 groupDS2 = grp_i->GetGroupDS();
1609 SMESHDS_Group* resGroupDS = 0;
1610 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1611 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1613 if ( groupDS1 && groupDS2 && resGroupDS )
1615 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1616 while ( elemIt1->more() )
1618 const SMDS_MeshElement* e = elemIt1->next();
1619 if ( !groupDS2->Contains( e ))
1620 resGroupDS->SMDSGroup().Add( e );
1623 // Update Python script
1624 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1625 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1627 SMESH_CATCH( SMESH::throwCorbaException );
1629 return aResGrp._retn();
1632 //=============================================================================
1634 \brief Cut lists of groups. New group is created. All mesh elements that are
1635 present in main groups but do not present in tool groups are added to the new one
1636 \param theMainGroups list of main groups
1637 \param theToolGroups list of tool groups
1638 \param theName name of group to be created
1639 \return pointer on the group
1641 //=============================================================================
1642 SMESH::SMESH_Group_ptr
1643 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1644 const SMESH::ListOfGroups& theToolGroups,
1645 const char* theName )
1646 throw (SALOME::SALOME_Exception)
1648 SMESH::SMESH_Group_var aResGrp;
1653 _preMeshInfo->FullLoadFromFile();
1656 return SMESH::SMESH_Group::_nil();
1658 // check types and get SMESHDS_GroupBase's
1659 SMESH::ElementType aType = SMESH::ALL;
1660 vector< SMESHDS_GroupBase* > toolGroupVec;
1661 vector< SMDS_ElemIteratorPtr > mainIterVec;
1663 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1665 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1666 if ( CORBA::is_nil( aGrp ) )
1668 if ( aType == SMESH::ALL )
1669 aType = aGrp->GetType();
1670 else if ( aType != aGrp->GetType() )
1671 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1673 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1674 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1675 if ( !grpDS->IsEmpty() )
1676 mainIterVec.push_back( grpDS->GetElements() );
1678 if ( aType == SMESH::ALL ) // all main groups are nil
1679 return SMESH::SMESH_Group::_nil();
1680 if ( mainIterVec.empty() ) // all main groups are empty
1681 return aResGrp._retn();
1683 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1685 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1686 if ( CORBA::is_nil( aGrp ) )
1688 if ( aType != aGrp->GetType() )
1689 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1691 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1692 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1693 toolGroupVec.push_back( grpDS );
1699 aResGrp = CreateGroup( aType, theName );
1701 SMESHDS_Group* resGroupDS = 0;
1702 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1703 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1705 return aResGrp._retn();
1708 size_t i, nb = toolGroupVec.size();
1709 SMDS_ElemIteratorPtr mainElemIt
1710 ( new SMDS_IteratorOnIterators
1711 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1712 while ( mainElemIt->more() )
1714 const SMDS_MeshElement* e = mainElemIt->next();
1716 for ( i = 0; ( i < nb && !isIn ); ++i )
1717 isIn = toolGroupVec[i]->Contains( e );
1720 resGroupDS->SMDSGroup().Add( e );
1723 // Update Python script
1724 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1725 << ".CutListOfGroups( " << theMainGroups << ", "
1726 << theToolGroups << ", '" << theName << "' )";
1728 SMESH_CATCH( SMESH::throwCorbaException );
1730 return aResGrp._retn();
1733 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1735 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1736 bool & toStopChecking )
1738 toStopChecking = ( nbCommon < nbChecked );
1739 return nbCommon == nbNodes;
1741 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1742 bool & toStopChecking )
1744 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1745 return nbCommon == nbCorners;
1747 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1748 bool & toStopChecking )
1750 return nbCommon > 0;
1752 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1753 bool & toStopChecking )
1755 return nbCommon >= (nbNodes+1) / 2;
1759 //=============================================================================
1761 * Create a group of entities basing on nodes of other groups.
1762 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1763 * \param [in] anElemType - a type of elements to include to the new group.
1764 * \param [in] theName - a name of the new group.
1765 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1766 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1767 * new group provided that it is based on nodes of an element of \a aListOfGroups
1768 * \return SMESH_Group - the created group
1770 // IMP 19939, bug 22010, IMP 22635
1771 //=============================================================================
1773 SMESH::SMESH_Group_ptr
1774 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1775 SMESH::ElementType theElemType,
1776 const char* theName,
1777 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1778 CORBA::Boolean theUnderlyingOnly)
1779 throw (SALOME::SALOME_Exception)
1781 SMESH::SMESH_Group_var aResGrp;
1785 _preMeshInfo->FullLoadFromFile();
1787 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1789 if ( !theName || !aMeshDS )
1790 return SMESH::SMESH_Group::_nil();
1792 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1794 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1795 SMESH_Comment nbCoNoStr( "SMESH.");
1796 switch ( theNbCommonNodes ) {
1797 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1798 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1799 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1800 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1801 default: return aResGrp._retn();
1803 int nbChecked, nbCommon, nbNodes, nbCorners;
1809 aResGrp = CreateGroup( theElemType, theName );
1810 if ( aResGrp->_is_nil() )
1811 return SMESH::SMESH_Group::_nil();
1813 SMESHDS_GroupBase* groupBaseDS =
1814 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1815 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1817 vector<bool> isNodeInGroups;
1819 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1821 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1822 if ( CORBA::is_nil( aGrp ) )
1824 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1825 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1828 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1829 if ( !elIt ) continue;
1831 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1833 while ( elIt->more() ) {
1834 const SMDS_MeshElement* el = elIt->next();
1835 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1836 while ( nIt->more() )
1837 resGroupCore.Add( nIt->next() );
1840 // get elements of theElemType based on nodes of every element of group
1841 else if ( theUnderlyingOnly )
1843 while ( elIt->more() )
1845 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1846 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1847 TIDSortedElemSet checkedElems;
1848 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1849 while ( nIt->more() )
1851 const SMDS_MeshNode* n = nIt->next();
1852 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1853 // check nodes of elements of theElemType around el
1854 while ( elOfTypeIt->more() )
1856 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1857 if ( !checkedElems.insert( elOfType ).second ) continue;
1858 nbNodes = elOfType->NbNodes();
1859 nbCorners = elOfType->NbCornerNodes();
1861 bool toStopChecking = false;
1862 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1863 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1864 if ( elNodes.count( nIt2->next() ) &&
1865 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1867 resGroupCore.Add( elOfType );
1874 // get all nodes of elements of groups
1877 while ( elIt->more() )
1879 const SMDS_MeshElement* el = elIt->next(); // an element of group
1880 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1881 while ( nIt->more() )
1883 const SMDS_MeshNode* n = nIt->next();
1884 if ( n->GetID() >= (int) isNodeInGroups.size() )
1885 isNodeInGroups.resize( n->GetID() + 1, false );
1886 isNodeInGroups[ n->GetID() ] = true;
1892 // Get elements of theElemType based on a certain number of nodes of elements of groups
1893 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1895 const SMDS_MeshNode* n;
1896 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1897 const int isNodeInGroupsSize = isNodeInGroups.size();
1898 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1900 if ( !isNodeInGroups[ iN ] ||
1901 !( n = aMeshDS->FindNode( iN )))
1904 // check nodes of elements of theElemType around n
1905 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1906 while ( elOfTypeIt->more() )
1908 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1909 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1914 nbNodes = elOfType->NbNodes();
1915 nbCorners = elOfType->NbCornerNodes();
1917 bool toStopChecking = false;
1918 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1919 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1921 const int nID = nIt->next()->GetID();
1922 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1923 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1925 resGroupCore.Add( elOfType );
1933 // Update Python script
1934 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1935 << ".CreateDimGroup( "
1936 << theGroups << ", " << theElemType << ", '" << theName << "', "
1937 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1939 SMESH_CATCH( SMESH::throwCorbaException );
1941 return aResGrp._retn();
1944 //================================================================================
1946 * \brief Distribute all faces of the mesh between groups using sharp edges and optionally
1947 * existing 1D elements as group boundaries.
1948 * \param [in] theSharpAngle - edge is considered sharp if an angle between normals of
1949 * adjacent faces is more than \a sharpAngle in degrees.
1950 * \param [in] theCreateEdges - to create 1D elements for detected sharp edges.
1951 * \param [in] theUseExistingEdges - to use existing edges as group boundaries
1952 * \return ListOfGroups - the created groups
1954 //================================================================================
1956 SMESH::ListOfGroups*
1957 SMESH_Mesh_i::FaceGroupsSeparatedByEdges( CORBA::Double theSharpAngle,
1958 CORBA::Boolean theCreateEdges,
1959 CORBA::Boolean theUseExistingEdges )
1960 throw (SALOME::SALOME_Exception)
1962 if ( theSharpAngle < 0 || theSharpAngle > 180 )
1963 THROW_SALOME_CORBA_EXCEPTION("Invalid sharp angle, it must be between 0 and 180 degrees",
1966 SMESH::ListOfGroups_var resultGroups = new SMESH::ListOfGroups;
1972 _preMeshInfo->FullLoadFromFile();
1974 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1976 std::vector< SMESH_MeshAlgos::Edge > edges =
1977 SMESH_MeshAlgos::FindSharpEdges( meshDS, theSharpAngle, theUseExistingEdges );
1979 if ( theCreateEdges )
1981 std::vector<const SMDS_MeshNode *> nodes(2);
1982 for ( size_t i = 0; i < edges.size(); ++i )
1984 nodes[0] = edges[i]._node1;
1985 nodes[1] = edges[i]._node2;
1986 if ( meshDS->FindElement( nodes, SMDSAbs_Edge ))
1988 if ( edges[i]._medium )
1989 meshDS->AddEdge( edges[i]._node1, edges[i]._node2, edges[i]._medium );
1991 meshDS->AddEdge( edges[i]._node1, edges[i]._node2 );
1995 std::vector< std::vector< const SMDS_MeshElement* > > faceGroups =
1996 SMESH_MeshAlgos::SeparateFacesByEdges( meshDS, edges );
1998 SMESH::SMESH_MeshEditor_var editor = GetMeshEditor(); // create _editor
2000 resultGroups->length( faceGroups.size() );
2001 for ( size_t iG = 0; iG < faceGroups.size(); ++iG )
2003 SMESH::SMESH_Group_var group = CreateGroup( SMESH::FACE,
2004 _editor->GenerateGroupName("Group").c_str());
2005 resultGroups[iG] = SMESH::SMESH_Group::_duplicate( group );
2007 SMESHDS_GroupBase* groupBaseDS =
2008 SMESH::DownCast<SMESH_GroupBase_i*>( group )->GetGroupDS();
2009 SMDS_MeshGroup& groupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
2011 std::vector< const SMDS_MeshElement* >& faces = faceGroups[ iG ];
2012 for ( size_t i = 0; i < faces.size(); ++i )
2013 groupCore.Add( faces[i] );
2016 pyDump << resultGroups << " = " << SMESH::SMESH_Mesh_var(_this())
2017 << ".FaceGroupsSeparatedByEdges( "
2018 << TVar( theSharpAngle ) << ", "
2019 << theCreateEdges << ", "
2020 << theUseExistingEdges << " )";
2022 SMESH_CATCH( SMESH::throwCorbaException );
2023 return resultGroups._retn();
2027 //================================================================================
2029 * \brief Remember GEOM group data
2031 //================================================================================
2033 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
2034 CORBA::Object_ptr theSmeshObj)
2036 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
2039 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
2040 if ( groupSO->_is_nil() )
2043 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( theGeomObj );
2044 GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations();
2045 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
2048 _geomGroupData.push_back( TGeomGroupData() );
2049 TGeomGroupData & groupData = _geomGroupData.back();
2051 CORBA::String_var entry = groupSO->GetID();
2052 groupData._groupEntry = entry.in();
2054 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2055 groupData._indices.insert( ids[i] );
2057 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
2058 // shape index in SMESHDS
2059 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
2060 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
2063 //================================================================================
2065 * Remove GEOM group data relating to removed smesh object
2067 //================================================================================
2069 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
2071 list<TGeomGroupData>::iterator
2072 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2073 for ( ; data != dataEnd; ++data ) {
2074 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
2075 _geomGroupData.erase( data );
2081 //================================================================================
2083 * \brief Return new group contents if it has been changed and update group data
2085 //================================================================================
2086 enum { ONLY_IF_CHANGED, IS_BREAK_LINK, MAIN_TRANSFORMED };
2088 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData, int how )
2090 TopoDS_Shape newShape;
2091 SALOMEDS::SObject_wrap groupSO;
2093 if ( how == IS_BREAK_LINK )
2095 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( groupData._smeshObject );
2096 SALOMEDS::SObject_wrap geomRefSO;
2097 if ( !meshSO->_is_nil() &&
2098 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ))
2100 geomRefSO->ReferencedObject( groupSO.inout() );
2106 groupSO = _gen_i->getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
2109 if ( groupSO->_is_nil() )
2112 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
2113 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
2114 if ( geomGroup->_is_nil() )
2117 // get indices of group items
2118 set<int> curIndices;
2119 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( geomGroup );
2120 GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations();
2121 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
2122 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2123 curIndices.insert( ids[i] );
2125 bool sameIndices = ( groupData._indices == curIndices );
2126 if ( how == ONLY_IF_CHANGED && sameIndices )
2127 return newShape; // group not changed
2130 CORBA::String_var entry = geomGroup->GetStudyEntry();
2131 groupData._groupEntry = entry.in();
2132 groupData._indices = curIndices;
2134 newShape = _gen_i->GeomObjectToShape( geomGroup );
2136 // check if newShape is up-to-date
2137 if ( !newShape.IsNull() && ids->length() > 0 )
2139 bool toUpdate = ! _impl->GetMeshDS()->IsGroupOfSubShapes( newShape );
2142 TopExp_Explorer exp( newShape, (TopAbs_ShapeEnum)( groupOp->GetType( geomGroup )));
2143 for ( ; exp.More() && !toUpdate; exp.Next() )
2145 int ind = _impl->GetMeshDS()->ShapeToIndex( exp.Current() );
2146 toUpdate = ( curIndices.erase( ind ) == 0 );
2148 if ( !curIndices.empty() )
2153 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2154 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
2155 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
2156 newShape = _gen_i->GeomObjectToShape( geomGroup );
2161 // geom group becomes empty - return empty compound
2162 TopoDS_Compound compound;
2163 BRep_Builder().MakeCompound(compound);
2164 newShape = compound;
2172 //-----------------------------------------------------------------------------
2174 * \brief Storage of shape and index used in CheckGeomGroupModif()
2176 struct TIndexedShape
2179 TopoDS_Shape _shape;
2180 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
2182 //-----------------------------------------------------------------------------
2184 * \brief Data to re-create a group on geometry
2186 struct TGroupOnGeomData
2189 TopoDS_Shape _shape;
2190 SMDSAbs_ElementType _type;
2192 Quantity_Color _color;
2194 TGroupOnGeomData( const SMESHDS_GroupOnGeom* group )
2196 _oldID = group->GetID();
2197 _type = group->GetType();
2198 _name = group->GetStoreName();
2199 _color = group->GetColor();
2203 //-----------------------------------------------------------------------------
2205 * \brief Check if a filter is still valid after geometry removal
2207 bool isValidGeomFilter( SMESH::Filter_var theFilter )
2209 if ( theFilter->_is_nil() )
2211 SMESH::Filter::Criteria_var criteria;
2212 theFilter->GetCriteria( criteria.out() );
2214 for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr )
2216 const char* thresholdID = criteria[ iCr ].ThresholdID.in();
2218 switch ( criteria[ iCr ].Type )
2220 case SMESH::FT_BelongToGeom:
2221 case SMESH::FT_BelongToPlane:
2222 case SMESH::FT_BelongToCylinder:
2223 case SMESH::FT_BelongToGenSurface:
2224 case SMESH::FT_LyingOnGeom:
2225 entry = thresholdID;
2227 case SMESH::FT_ConnectedElements:
2230 entry = thresholdID;
2236 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
2237 SALOMEDS::SObject_wrap so = gen->getStudyServant()->FindObjectID( entry.c_str() );
2238 if ( so->_is_nil() )
2240 CORBA::Object_var obj = so->GetObject();
2241 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( obj );
2242 if ( gen->GeomObjectToShape( geom ).IsNull() )
2245 } // loop on criteria
2251 //=============================================================================
2253 * \brief Update data if geometry changes
2257 //=============================================================================
2259 void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink )
2261 SMESH::SMESH_Mesh_var me = _this();
2262 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2264 TPythonDump dumpNothing; // prevent any dump
2266 //bool removedFromClient = false;
2268 if ( mainGO->_is_nil() ) // GEOM_Client cleared or geometry removed? (IPAL52735, PAL23636)
2270 //removedFromClient = _impl->HasShapeToMesh();
2272 // try to find geometry by study reference
2273 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2274 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2275 if ( !meshSO->_is_nil() &&
2276 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2277 geomRefSO->ReferencedObject( geomSO.inout() ))
2279 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2280 mainGO = GEOM::GEOM_Object::_narrow( geomObj );
2283 if ( mainGO->_is_nil() && // geometry removed ==>
2284 !geomRefSO->_is_nil() ) // remove geom dependent data: sub-meshes etc.
2286 // convert geom dependent groups into standalone ones
2287 CheckGeomGroupModif();
2289 _impl->ShapeToMesh( TopoDS_Shape() );
2291 // remove sub-meshes
2292 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2293 while ( i_sm != _mapSubMeshIor.end() )
2295 SMESH::SMESH_subMesh_ptr sm = i_sm->second;
2297 RemoveSubMesh( sm );
2299 // remove all children except groups in the study
2300 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2301 SALOMEDS::SObject_wrap so;
2302 for ( CORBA::Long tag = SMESH::Tag_RefOnShape; tag <= SMESH::Tag_LastSubMesh; ++tag )
2303 if ( meshSO->FindSubObject( tag, so.inout() ))
2304 builder->RemoveObjectWithChildren( so );
2306 _gen_i->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED" );
2312 if ( !_impl->HasShapeToMesh() ) return;
2315 // Update after group modification
2317 if ( mainGO->GetType() == GEOM_GROUP || // is group or not modified
2318 mainGO->GetTick() == _mainShapeTick )
2320 int nb = NbNodes() + NbElements();
2321 CheckGeomGroupModif();
2322 if ( nb != NbNodes() + NbElements() ) // something removed due to hypotheses change
2323 _gen_i->UpdateIcons( me );
2327 // Update after shape modification
2329 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2330 if ( !geomClient ) return;
2331 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( mainGO );
2332 if ( geomGen->_is_nil() ) return;
2333 CORBA::String_var geomComponentType = geomGen->ComponentDataType();
2334 bool isShaper = ( strcmp( geomComponentType.in(), "SHAPERSTUDY" ) == 0 );
2336 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2338 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2339 if ( meshDS->ShapeToIndex( newShape ) == 1 ) // not yet updated
2341 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2342 geomClient->RemoveShapeFromBuffer( ior.in() );
2343 newShape = _gen_i->GeomObjectToShape( mainGO );
2346 // Update data taking into account that if topology doesn't change
2347 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2350 _preMeshInfo->ForgetAllData();
2352 if ( isBreakLink || !isShaper )
2354 if ( newShape.IsNull() )
2357 _mainShapeTick = mainGO->GetTick();
2359 // store data of groups on geometry including new TopoDS_Shape's
2360 std::vector< TGroupOnGeomData > groupsData;
2361 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2362 groupsData.reserve( groups.size() );
2363 TopTools_DataMapOfShapeShape old2newShapeMap;
2364 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2365 for ( ; g != groups.end(); ++g )
2367 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2369 groupsData.push_back( TGroupOnGeomData( group ));
2372 SMESH::SMESH_GroupOnGeom_var gog;
2373 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.find( group->GetID() );
2374 if ( i_grp != _mapGroups.end() )
2375 gog = SMESH::SMESH_GroupOnGeom::_narrow( i_grp->second );
2377 GEOM::GEOM_Object_var geom;
2378 if ( !gog->_is_nil() )
2381 geom = gog->GetShape();
2383 if ( isBreakLink || geom->_is_nil() )
2385 SALOMEDS::SObject_wrap grpSO = _gen_i->ObjectToSObject( gog );
2386 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2387 if ( !grpSO->_is_nil() &&
2388 grpSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2389 geomRefSO->ReferencedObject( geomSO.inout() ))
2391 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2392 geom = GEOM::GEOM_Object::_narrow( geomObj );
2396 if ( old2newShapeMap.IsBound( group->GetShape() ))
2398 groupsData.back()._shape = old2newShapeMap( group->GetShape() );
2400 else if ( !geom->_is_nil() )
2402 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2403 if ( meshDS->IsGroupOfSubShapes( groupsData.back()._shape ))
2405 CORBA::String_var ior = geomGen->GetStringFromIOR( geom );
2406 geomClient->RemoveShapeFromBuffer( ior.in() );
2407 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2409 old2newShapeMap.Bind( group->GetShape(), groupsData.back()._shape );
2414 // store assigned hypotheses
2415 std::vector< pair< int, THypList > > ids2Hyps;
2416 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2417 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2419 const TopoDS_Shape& s = s2hyps.Key();
2420 const THypList& hyps = s2hyps.ChangeValue();
2421 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2424 std::multimap< std::set<int>, int > ii2iMap; // group sub-ids to group id in SMESHDS
2426 // count shapes excluding compounds corresponding to geom groups
2427 int oldNbSubShapes = meshDS->MaxShapeIndex();
2428 for ( ; oldNbSubShapes > 0; --oldNbSubShapes )
2430 const TopoDS_Shape& s = meshDS->IndexToShape( oldNbSubShapes );
2431 if ( s.IsNull() || s.ShapeType() != TopAbs_COMPOUND )
2434 std::set<int> subIds;
2435 for ( TopoDS_Iterator it( s ); it.More(); it.Next() )
2436 subIds.insert( meshDS->ShapeToIndex( it.Value() ));
2437 ii2iMap.insert( std::make_pair( subIds, oldNbSubShapes ));
2440 // check if shape topology changes - save shape type per shape ID
2441 std::vector< TopAbs_ShapeEnum > shapeTypes( Max( oldNbSubShapes + 1, 1 ));
2442 for ( int shapeID = oldNbSubShapes; shapeID > 0; --shapeID )
2443 shapeTypes[ shapeID ] = meshDS->IndexToShape( shapeID ).ShapeType();
2445 // change shape to mesh
2446 _impl->ShapeToMesh( TopoDS_Shape() );
2447 _impl->ShapeToMesh( newShape );
2449 // check if shape topology changes - check new shape types
2450 bool sameTopology = ( oldNbSubShapes == meshDS->MaxShapeIndex() );
2451 for ( int shapeID = oldNbSubShapes; shapeID > 0 && sameTopology; --shapeID )
2453 const TopoDS_Shape& s = meshDS->IndexToShape( shapeID );
2454 sameTopology = ( !s.IsNull() && s.ShapeType() == shapeTypes[ shapeID ]);
2457 // re-add shapes (compounds) of geom groups
2458 typedef std::map< std::vector< int >, TGeomGroupData* > TIndices2GroupData;
2459 TIndices2GroupData ii2grData;
2460 std::vector< int > ii;
2461 std::map< int, int > old2newIDs; // group IDs
2462 std::list<TGeomGroupData>::iterator dataIt = _geomGroupData.begin();
2463 for ( ; dataIt != _geomGroupData.end(); ++dataIt )
2465 TGeomGroupData* data = &(*dataIt);
2466 ii.reserve( data->_indices.size() );
2467 ii.assign( data->_indices.begin(), data->_indices.end() );
2468 TIndices2GroupData::iterator ii2gd = ii2grData.insert( std::make_pair( ii, data )).first;
2469 if ( ii2gd->second != data )
2471 data->_groupEntry = ii2gd->second->_groupEntry;
2472 data->_indices = ii2gd->second->_indices;
2475 const int oldNbSub = data->_indices.size();
2476 const int soleOldID = oldNbSub == 1 ? *data->_indices.begin() : 0;
2478 std::multimap< std::set<int>, int >::iterator ii2i = ii2iMap.find( data->_indices );
2479 if ( ii2i != ii2iMap.end() )
2481 oldID = ii2i->second;
2482 ii2iMap.erase( ii2i );
2484 if ( !oldID && oldNbSub == 1 )
2486 if ( old2newIDs.count( oldID ))
2489 int how = ( isBreakLink || !sameTopology ) ? IS_BREAK_LINK : MAIN_TRANSFORMED;
2490 newShape = newGroupShape( *data, how );
2492 if ( !newShape.IsNull() )
2494 if ( oldNbSub > 1 && meshDS->ShapeToIndex( newShape ) > 0 ) // group reduced to one sub-shape
2496 TopoDS_Compound compound;
2497 BRep_Builder().MakeCompound( compound );
2498 BRep_Builder().Add( compound, newShape );
2499 newShape = compound;
2501 int newID = _impl->GetSubMesh( newShape )->GetId();
2502 if ( oldID /*&& oldID != newID*/ )
2503 old2newIDs.insert( std::make_pair( oldID, newID ));
2504 if ( oldNbSub == 1 )
2505 old2newIDs.insert( std::make_pair( soleOldID, newID ));
2509 // re-assign hypotheses
2510 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2512 int sID = ids2Hyps[i].first;
2515 std::map< int, int >::iterator o2n = old2newIDs.find( sID );
2516 if ( o2n != old2newIDs.end() )
2518 else if ( !sameTopology )
2521 const TopoDS_Shape& s = meshDS->IndexToShape( sID );
2524 const THypList& hyps = ids2Hyps[i].second;
2525 THypList::const_iterator h = hyps.begin();
2526 for ( ; h != hyps.end(); ++h )
2527 _impl->AddHypothesis( s, (*h)->GetID() );
2531 // restore groups on geometry
2532 for ( size_t i = 0; i < groupsData.size(); ++i )
2534 const TGroupOnGeomData& data = groupsData[i];
2535 if ( data._shape.IsNull() )
2538 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2539 if ( i2g == _mapGroups.end() ) continue;
2541 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2542 if ( !gr_i ) continue;
2544 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape );
2546 _mapGroups.erase( i2g );
2548 g->GetGroupDS()->SetColor( data._color );
2551 if ( !sameTopology )
2553 std::map< int, int >::iterator o2n = old2newIDs.begin();
2554 for ( ; o2n != old2newIDs.end(); ++o2n )
2556 int newID = o2n->second, oldID = o2n->first;
2557 if ( newID == oldID || !_mapSubMesh.count( oldID ))
2561 _mapSubMesh [ newID ] = _impl->GetSubMeshContaining( newID );
2562 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2563 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2565 _mapSubMesh. erase(oldID);
2566 _mapSubMesh_i. erase(oldID);
2567 _mapSubMeshIor.erase(oldID);
2569 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2573 // update _mapSubMesh
2574 std::map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2575 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2576 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2579 if ( !sameTopology )
2581 // remove invalid study sub-objects
2582 CheckGeomGroupModif();
2585 _gen_i->UpdateIcons( me );
2587 if ( !isBreakLink && isShaper )
2589 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2590 if ( !meshSO->_is_nil() )
2591 _gen_i->SetPixMap(meshSO, "ICON_SMESH_TREE_GEOM_MODIF");
2595 //=============================================================================
2597 * \brief Update objects depending on changed geom groups
2599 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2600 * issue 0020210: Update of a smesh group after modification of the associated geom group
2602 //=============================================================================
2604 void SMESH_Mesh_i::CheckGeomGroupModif()
2606 // remove sub-meshes referring a removed sub-shapes (if main shape still exists)
2607 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2608 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2609 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() ));
2610 if ( !mainGO->_is_nil() && !meshSO->_is_nil() )
2612 SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO;
2613 for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag )
2614 if ( meshSO->FindSubObject( tag, rootSO.inout() ))
2616 int nbValid = 0, nbRemoved = 0;
2617 SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO );
2618 for ( ; chItr->More(); chItr->Next() )
2620 SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO
2621 if ( !smSO->_is_nil() &&
2622 smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2623 geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference
2625 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2626 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2627 if ( !geom->_non_existent() )
2630 continue; // keep the sub-mesh
2633 CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO );
2634 SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj );
2635 if ( !sm->_is_nil() && !sm->_non_existent() )
2637 GEOM::GEOM_Object_var smGeom = sm->GetSubShape();
2638 if ( smGeom->_is_nil() )
2640 RemoveSubMesh( sm );
2647 _preMeshInfo->ForgetAllData(); // unknown hypothesis modified
2648 builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH
2652 if ( /*nbRemoved > 0 &&*/ nbValid == 0 )
2653 builder->RemoveObjectWithChildren( rootSO );
2657 // check for removed sub-shapes and convert geom dependent groups into standalone ones
2658 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2659 while ( i_gr != _mapGroups.end())
2661 SMESH::SMESH_GroupBase_ptr group = i_gr->second;
2663 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO, geomSO;
2664 SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group );
2665 SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group );
2666 bool isValidGeom = false;
2667 if ( !onGeom->_is_nil() )
2669 isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() ); // check TopoDS
2670 if ( !isValidGeom ) // check reference
2672 isValidGeom = ( ! groupSO->_is_nil() &&
2673 groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ) &&
2674 refSO->ReferencedObject( geomSO.inout() ) &&
2675 ! geomSO->_is_nil() &&
2676 !CORBA::is_nil( CORBA::Object_var( geomSO->GetObject() )));
2679 else if ( !onFilt->_is_nil() )
2681 isValidGeom = isValidGeomFilter( onFilt->GetFilter() );
2685 isValidGeom = ( !groupSO->_is_nil() &&
2686 !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ));
2690 if ( !IsLoaded() || group->IsEmpty() )
2692 RemoveGroup( group );
2694 else if ( !onGeom->_is_nil() || !onFilt->_is_nil() )
2696 SMESH::SMESH_Group_var ( ConvertToStandalone( group ));
2698 else // is it possible?
2700 builder->RemoveObjectWithChildren( refSO );
2706 if ( !_impl->HasShapeToMesh() ) return;
2708 CORBA::Long nbEntities = NbNodes() + NbElements();
2710 // Check if group contents changed
2712 typedef map< string, TopoDS_Shape > TEntry2Geom;
2713 TEntry2Geom newGroupContents;
2715 list<TGeomGroupData>::iterator
2716 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2717 for ( ; data != dataEnd; ++data )
2719 pair< TEntry2Geom::iterator, bool > it_new =
2720 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2721 bool processedGroup = !it_new.second;
2722 TopoDS_Shape& newShape = it_new.first->second;
2723 if ( !processedGroup )
2724 newShape = newGroupShape( *data, ONLY_IF_CHANGED );
2725 if ( newShape.IsNull() )
2726 continue; // no changes
2729 _preMeshInfo->ForgetOrLoad();
2731 if ( processedGroup ) { // update group indices
2732 list<TGeomGroupData>::iterator data2 = data;
2733 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2734 data->_indices = data2->_indices;
2737 // Update SMESH objects according to new GEOM group contents
2739 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2740 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2742 int oldID = submesh->GetId();
2743 if ( !_mapSubMeshIor.count( oldID ))
2745 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2747 // update hypotheses
2748 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2749 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2750 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2752 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2753 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2755 // care of submeshes
2756 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2757 int newID = newSubmesh->GetId();
2758 if ( newID != oldID ) {
2759 _mapSubMesh [ newID ] = newSubmesh;
2760 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2761 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2762 _mapSubMesh. erase(oldID);
2763 _mapSubMesh_i. erase(oldID);
2764 _mapSubMeshIor.erase(oldID);
2765 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2770 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2771 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2772 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2774 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2776 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2777 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2778 ds->SetShape( newShape );
2783 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2784 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2786 // Remove groups and submeshes basing on removed sub-shapes
2788 TopTools_MapOfShape newShapeMap;
2789 TopoDS_Iterator shapeIt( newShape );
2790 for ( ; shapeIt.More(); shapeIt.Next() )
2791 newShapeMap.Add( shapeIt.Value() );
2793 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2794 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2796 if ( newShapeMap.Contains( shapeIt.Value() ))
2798 TopTools_IndexedMapOfShape oldShapeMap;
2799 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2800 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2802 const TopoDS_Shape& oldShape = oldShapeMap(i);
2803 int oldInd = meshDS->ShapeToIndex( oldShape );
2805 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2806 if ( i_smIor != _mapSubMeshIor.end() ) {
2807 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2810 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2811 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2813 // check if a group bases on oldInd shape
2814 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2815 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2816 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2817 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2819 RemoveGroup( i_grp->second ); // several groups can base on same shape
2820 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2825 // Reassign hypotheses and update groups after setting the new shape to mesh
2827 // collect anassigned hypotheses
2828 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2829 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2830 TShapeHypList assignedHyps;
2831 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2833 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2834 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2835 if ( !hyps.empty() ) {
2836 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2837 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2838 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2841 // collect shapes supporting groups
2842 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2843 TShapeTypeList groupData;
2844 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2845 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2846 for ( ; grIt != groups.end(); ++grIt )
2848 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2850 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2852 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2854 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2855 _impl->ShapeToMesh( newShape );
2857 // reassign hypotheses
2858 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2859 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2861 TIndexedShape& geom = indS_hyps->first;
2862 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2863 int oldID = geom._index;
2864 int newID = meshDS->ShapeToIndex( geom._shape );
2865 if ( oldID == 1 ) { // main shape
2867 geom._shape = newShape;
2871 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2872 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2873 // care of sub-meshes
2874 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2875 if ( newID != oldID ) {
2876 _mapSubMesh [ newID ] = newSubmesh;
2877 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2878 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2879 _mapSubMesh. erase(oldID);
2880 _mapSubMesh_i. erase(oldID);
2881 _mapSubMeshIor.erase(oldID);
2882 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2886 TShapeTypeList::iterator geomType = groupData.begin();
2887 for ( ; geomType != groupData.end(); ++geomType )
2889 const TIndexedShape& geom = geomType->first;
2890 int oldID = geom._index;
2891 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2894 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2895 CORBA::String_var name = groupSO->GetName();
2897 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
2898 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
2899 /*id=*/-1, geom._shape ))
2900 group_i->changeLocalId( group->GetID() );
2903 break; // everything has been updated
2906 } // loop on group data
2910 CORBA::Long newNbEntities = NbNodes() + NbElements();
2911 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2912 if ( newNbEntities != nbEntities )
2914 // Add all SObjects with icons to soToUpdateIcons
2915 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2917 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2918 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2919 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2921 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2922 i_gr != _mapGroups.end(); ++i_gr ) // groups
2923 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2926 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2927 for ( ; so != soToUpdateIcons.end(); ++so )
2928 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2931 //=============================================================================
2933 * \brief Create standalone group from a group on geometry or filter
2935 //=============================================================================
2937 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2938 throw (SALOME::SALOME_Exception)
2940 SMESH::SMESH_Group_var aGroup;
2945 _preMeshInfo->FullLoadFromFile();
2947 if ( theGroup->_is_nil() )
2948 return aGroup._retn();
2950 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2952 return aGroup._retn();
2954 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2956 const int anId = aGroupToRem->GetLocalID();
2957 if ( !_impl->ConvertToStandalone( anId ) )
2958 return aGroup._retn();
2959 removeGeomGroupData( theGroup );
2961 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2963 // remove old instance of group from own map
2964 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2965 _mapGroups.erase( anId );
2967 SALOMEDS::StudyBuilder_var builder;
2968 SALOMEDS::SObject_wrap aGroupSO;
2969 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2970 if ( !aStudy->_is_nil() ) {
2971 builder = aStudy->NewBuilder();
2972 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2973 if ( !aGroupSO->_is_nil() )
2975 // remove reference to geometry
2976 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2977 for ( ; chItr->More(); chItr->Next() )
2979 // Remove group's child SObject
2980 SALOMEDS::SObject_wrap so = chItr->Value();
2981 builder->RemoveObject( so );
2983 // Update Python script
2984 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2985 << ".ConvertToStandalone( " << aGroupSO << " )";
2987 // change icon of Group on Filter
2990 // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2991 // const int isEmpty = ( elemTypes->length() == 0 );
2994 SALOMEDS::GenericAttribute_wrap anAttr =
2995 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2996 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2997 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
3003 // remember new group in own map
3004 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
3005 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3007 // register CORBA object for persistence
3008 _gen_i->RegisterObject( aGroup );
3010 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
3011 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
3012 //aGroup->Register();
3013 aGroupToRem->UnRegister();
3015 SMESH_CATCH( SMESH::throwCorbaException );
3017 return aGroup._retn();
3020 //=============================================================================
3024 //=============================================================================
3026 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
3028 if(MYDEBUG) MESSAGE( "createSubMesh" );
3029 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
3030 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
3033 SMESH_subMesh_i * subMeshServant;
3036 subMeshId = mySubMesh->GetId();
3037 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
3039 else // "invalid sub-mesh"
3041 // The invalid sub-mesh is created for the case where a valid sub-shape not found
3042 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
3043 if ( _mapSubMesh.empty() )
3046 subMeshId = _mapSubMesh.begin()->first - 1;
3047 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
3050 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
3052 _mapSubMesh [subMeshId] = mySubMesh;
3053 _mapSubMesh_i [subMeshId] = subMeshServant;
3054 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
3056 subMeshServant->Register();
3058 // register CORBA object for persistence
3059 int nextId = _gen_i->RegisterObject( subMesh );
3060 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
3061 else { nextId = 0; } // avoid "unused variable" warning
3063 // to track changes of GEOM groups
3064 if ( subMeshId > 0 )
3065 addGeomGroupData( theSubShapeObject, subMesh );
3067 return subMesh._retn();
3070 //=======================================================================
3071 //function : getSubMesh
3073 //=======================================================================
3075 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
3077 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
3078 if ( it == _mapSubMeshIor.end() )
3079 return SMESH::SMESH_subMesh::_nil();
3081 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
3084 //=============================================================================
3088 //=============================================================================
3090 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
3091 GEOM::GEOM_Object_ptr theSubShapeObject )
3093 bool isHypChanged = false;
3094 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
3095 return isHypChanged;
3097 const int subMeshId = theSubMesh->GetId();
3099 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
3102 if (( _mapSubMesh.count( subMeshId )) &&
3103 ( sm = _impl->GetSubMeshContaining( subMeshId )))
3105 TopoDS_Shape S = sm->GetSubShape();
3108 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
3109 isHypChanged = !hyps.empty();
3110 if ( isHypChanged && _preMeshInfo )
3111 _preMeshInfo->ForgetOrLoad();
3112 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
3113 for ( ; hyp != hyps.end(); ++hyp )
3114 _impl->RemoveHypothesis(S, (*hyp)->GetID());
3121 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
3122 isHypChanged = ( aHypList->length() > 0 );
3123 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
3124 removeHypothesis( theSubShapeObject, aHypList[i] );
3127 catch( const SALOME::SALOME_Exception& ) {
3128 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
3130 removeGeomGroupData( theSubShapeObject );
3134 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
3135 if ( id_smi != _mapSubMesh_i.end() )
3136 id_smi->second->UnRegister();
3138 // remove a CORBA object
3139 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
3140 if ( id_smptr != _mapSubMeshIor.end() )
3141 SMESH::SMESH_subMesh_var( id_smptr->second );
3143 _mapSubMesh.erase(subMeshId);
3144 _mapSubMesh_i.erase(subMeshId);
3145 _mapSubMeshIor.erase(subMeshId);
3147 return isHypChanged;
3150 //=============================================================================
3154 //=============================================================================
3156 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
3157 const char* theName,
3159 const TopoDS_Shape& theShape,
3160 const SMESH_PredicatePtr& thePredicate )
3162 std::string newName;
3163 if ( !theName || !theName[0] )
3165 std::set< std::string > presentNames;
3166 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
3167 for ( ; i_gr != _mapGroups.end(); ++i_gr )
3169 CORBA::String_var name = i_gr->second->GetName();
3170 presentNames.insert( name.in() );
3173 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
3174 } while ( !presentNames.insert( newName ).second );
3175 theName = newName.c_str();
3177 SMESH::SMESH_GroupBase_var aGroup;
3178 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
3179 theID, theShape, thePredicate ))
3181 int anId = g->GetID();
3182 SMESH_GroupBase_i* aGroupImpl;
3183 if ( !theShape.IsNull() )
3184 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3185 else if ( thePredicate )
3186 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
3188 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3190 aGroup = aGroupImpl->_this();
3191 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3192 aGroupImpl->Register();
3194 // register CORBA object for persistence
3195 int nextId = _gen_i->RegisterObject( aGroup );
3196 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
3197 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
3199 // to track changes of GEOM groups
3200 if ( !theShape.IsNull() ) {
3201 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
3202 addGeomGroupData( geom, aGroup );
3205 return aGroup._retn();
3208 //=============================================================================
3210 * SMESH_Mesh_i::removeGroup
3212 * Should be called by ~SMESH_Group_i()
3214 //=============================================================================
3216 void SMESH_Mesh_i::removeGroup( const int theId )
3218 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
3219 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
3220 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
3221 _mapGroups.erase( theId );
3222 removeGeomGroupData( group );
3223 if ( !_impl->RemoveGroup( theId ))
3225 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
3226 RemoveGroup( group );
3228 group->UnRegister();
3232 //=============================================================================
3236 //=============================================================================
3238 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
3239 throw(SALOME::SALOME_Exception)
3241 SMESH::log_array_var aLog;
3245 _preMeshInfo->FullLoadFromFile();
3247 list < SMESHDS_Command * >logDS = _impl->GetLog();
3248 aLog = new SMESH::log_array;
3250 int lg = logDS.size();
3253 list < SMESHDS_Command * >::iterator its = logDS.begin();
3254 while(its != logDS.end()){
3255 SMESHDS_Command *com = *its;
3256 int comType = com->GetType();
3258 int lgcom = com->GetNumber();
3260 const list < int >&intList = com->GetIndexes();
3261 int inum = intList.size();
3263 list < int >::const_iterator ii = intList.begin();
3264 const list < double >&coordList = com->GetCoords();
3265 int rnum = coordList.size();
3267 list < double >::const_iterator ir = coordList.begin();
3268 aLog[indexLog].commandType = comType;
3269 aLog[indexLog].number = lgcom;
3270 aLog[indexLog].coords.length(rnum);
3271 aLog[indexLog].indexes.length(inum);
3272 for(int i = 0; i < rnum; i++){
3273 aLog[indexLog].coords[i] = *ir;
3274 //MESSAGE(" "<<i<<" "<<ir.Value());
3277 for(int i = 0; i < inum; i++){
3278 aLog[indexLog].indexes[i] = *ii;
3279 //MESSAGE(" "<<i<<" "<<ii.Value());
3288 SMESH_CATCH( SMESH::throwCorbaException );
3290 return aLog._retn();
3294 //=============================================================================
3298 //=============================================================================
3300 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
3304 SMESH_CATCH( SMESH::throwCorbaException );
3307 //=============================================================================
3311 //=============================================================================
3313 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
3318 //=============================================================================
3321 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
3322 // issue 0020918: groups removal is caused by hyp modification
3323 // issue 0021208: to forget not loaded mesh data at hyp modification
3324 struct TCallUp_i : public SMESH_Mesh::TCallUp
3326 SMESH_Mesh_i* _mesh;
3327 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
3328 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
3329 virtual void HypothesisModified( int hypID,
3330 bool updIcons) { _mesh->onHypothesisModified( hypID,
3332 virtual void Load () { _mesh->Load(); }
3333 virtual bool IsLoaded() { return _mesh->IsLoaded(); }
3337 //================================================================================
3339 * \brief callback from _impl to
3340 * 1) forget not loaded mesh data (issue 0021208)
3341 * 2) mark hypothesis as valid
3343 //================================================================================
3345 void SMESH_Mesh_i::onHypothesisModified(int theHypID, bool theUpdateIcons)
3348 _preMeshInfo->ForgetOrLoad();
3350 if ( theUpdateIcons )
3352 SMESH::SMESH_Mesh_var mesh = _this();
3353 _gen_i->UpdateIcons( mesh );
3356 if ( _nbInvalidHypos != 0 )
3358 // mark a hypothesis as valid after edition
3360 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
3361 SALOMEDS::SObject_wrap hypRoot;
3362 if ( !smeshComp->_is_nil() &&
3363 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
3365 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
3366 for ( ; anIter->More(); anIter->Next() )
3368 SALOMEDS::SObject_wrap hypSO = anIter->Value();
3369 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
3370 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
3371 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
3372 _gen_i->HighLightInvalid( hyp, false );
3374 nbInvalid += _gen_i->IsInvalid( hypSO );
3377 _nbInvalidHypos = nbInvalid;
3381 //=============================================================================
3385 //=============================================================================
3387 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
3389 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
3392 _impl->SetCallUp( new TCallUp_i(this));
3395 //=============================================================================
3399 //=============================================================================
3401 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
3403 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
3407 //=============================================================================
3409 * Return mesh editor
3411 //=============================================================================
3413 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
3414 throw (SALOME::SALOME_Exception)
3416 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3420 _preMeshInfo->FullLoadFromFile();
3422 // Create MeshEditor
3424 _editor = new SMESH_MeshEditor_i( this, false );
3425 aMeshEdVar = _editor->_this();
3427 // Update Python script
3428 TPythonDump() << _editor << " = "
3429 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
3431 SMESH_CATCH( SMESH::throwCorbaException );
3433 return aMeshEdVar._retn();
3436 //=============================================================================
3438 * Return mesh edition previewer
3440 //=============================================================================
3442 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
3443 throw (SALOME::SALOME_Exception)
3445 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3449 _preMeshInfo->FullLoadFromFile();
3451 if ( !_previewEditor )
3452 _previewEditor = new SMESH_MeshEditor_i( this, true );
3453 aMeshEdVar = _previewEditor->_this();
3455 SMESH_CATCH( SMESH::throwCorbaException );
3457 return aMeshEdVar._retn();
3460 //================================================================================
3462 * \brief Return true if the mesh has been edited since a last total re-compute
3463 * and those modifications may prevent successful partial re-compute
3465 //================================================================================
3467 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
3469 Unexpect aCatch(SALOME_SalomeException);
3470 return _impl->HasModificationsToDiscard();
3473 //================================================================================
3475 * \brief Returns a random unique color
3477 //================================================================================
3479 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
3481 const int MAX_ATTEMPTS = 100;
3483 double tolerance = 0.5;
3484 SALOMEDS::Color col;
3488 // generate random color
3489 double red = (double)rand() / RAND_MAX;
3490 double green = (double)rand() / RAND_MAX;
3491 double blue = (double)rand() / RAND_MAX;
3492 // check existence in the list of the existing colors
3493 bool matched = false;
3494 std::list<SALOMEDS::Color>::const_iterator it;
3495 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3496 SALOMEDS::Color color = *it;
3497 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3498 matched = tol < tolerance;
3500 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3501 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3509 //=============================================================================
3511 * Sets auto-color mode. If it is on, groups get unique random colors
3513 //=============================================================================
3515 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
3517 Unexpect aCatch(SALOME_SalomeException);
3518 _impl->SetAutoColor(theAutoColor);
3520 TPythonDump pyDump; // not to dump group->SetColor() from below code
3521 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3523 std::list<SALOMEDS::Color> aReservedColors;
3524 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3525 for ( ; it != _mapGroups.end(); it++ ) {
3526 if ( CORBA::is_nil( it->second )) continue;
3527 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3528 it->second->SetColor( aColor );
3529 aReservedColors.push_back( aColor );
3533 //=============================================================================
3535 * Returns true if auto-color mode is on
3537 //=============================================================================
3539 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
3541 Unexpect aCatch(SALOME_SalomeException);
3542 return _impl->GetAutoColor();
3545 //=============================================================================
3547 * Checks if there are groups with equal names
3549 //=============================================================================
3551 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3553 return _impl->HasDuplicatedGroupNamesMED();
3556 //================================================================================
3558 * \brief Care of a file before exporting mesh into it
3560 //================================================================================
3562 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3564 SMESH_File aFile( file, false );
3566 if ( aFile.exists() ) {
3567 // existing filesystem node
3568 if ( !aFile.isDirectory() ) {
3569 if ( aFile.openForWriting() ) {
3570 if ( overwrite && ! aFile.remove()) {
3571 msg << "Can't replace " << aFile.getName();
3574 msg << "Can't write into " << aFile.getName();
3577 msg << "Location " << aFile.getName() << " is not a file";
3581 // nonexisting file; check if it can be created
3582 if ( !aFile.openForWriting() ) {
3583 msg << "You cannot create the file "
3585 << ". Check the directory existence and access rights";
3593 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3597 //================================================================================
3599 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
3600 * \param file - file name
3601 * \param overwrite - to erase the file or not
3602 * \retval string - mesh name
3604 //================================================================================
3606 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3607 CORBA::Boolean overwrite)
3610 PrepareForWriting(file, overwrite);
3611 string aMeshName = "Mesh";
3612 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3613 if ( !aStudy->_is_nil() ) {
3614 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3615 if ( !aMeshSO->_is_nil() ) {
3616 CORBA::String_var name = aMeshSO->GetName();
3618 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3619 if ( !aStudy->GetProperties()->IsLocked() )
3621 SALOMEDS::GenericAttribute_wrap anAttr;
3622 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3623 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3624 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3625 ASSERT(!aFileName->_is_nil());
3626 aFileName->SetValue(file);
3627 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3628 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3629 ASSERT(!aFileType->_is_nil());
3630 aFileType->SetValue("FICHIERMED");
3634 // Update Python script
3635 // set name of mesh before export
3636 TPythonDump() << _gen_i << ".SetName("
3637 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3639 // check names of groups
3645 //================================================================================
3647 * \brief Export to MED file
3649 //================================================================================
3651 void SMESH_Mesh_i::ExportMED(const char* file,
3652 CORBA::Boolean auto_groups,
3653 CORBA::Long version,
3654 CORBA::Boolean overwrite,
3655 CORBA::Boolean autoDimension)
3656 throw(SALOME::SALOME_Exception)
3658 //MESSAGE("MED minor version: "<< minor);
3661 _preMeshInfo->FullLoadFromFile();
3663 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3664 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3666 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3668 << "auto_groups=" <<auto_groups << ", "
3669 << "minor=" << version << ", "
3670 << "overwrite=" << overwrite << ", "
3671 << "meshPart=None, "
3672 << "autoDimension=" << autoDimension << " )";
3674 SMESH_CATCH( SMESH::throwCorbaException );
3677 //================================================================================
3679 * \brief Export a mesh to a SAUV file
3681 //================================================================================
3683 void SMESH_Mesh_i::ExportSAUV (const char* file,
3684 CORBA::Boolean auto_groups)
3685 throw(SALOME::SALOME_Exception)
3687 Unexpect aCatch(SALOME_SalomeException);
3689 _preMeshInfo->FullLoadFromFile();
3691 string aMeshName = prepareMeshNameAndGroups(file, true);
3692 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3693 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3694 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3698 //================================================================================
3700 * \brief Export a mesh to a DAT file
3702 //================================================================================
3704 void SMESH_Mesh_i::ExportDAT (const char *file)
3705 throw(SALOME::SALOME_Exception)
3707 Unexpect aCatch(SALOME_SalomeException);
3709 _preMeshInfo->FullLoadFromFile();
3711 // Update Python script
3712 // check names of groups
3714 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3717 PrepareForWriting(file);
3718 _impl->ExportDAT(file);
3721 //================================================================================
3723 * \brief Export a mesh to an UNV file
3725 //================================================================================
3727 void SMESH_Mesh_i::ExportUNV (const char *file)
3728 throw(SALOME::SALOME_Exception)
3730 Unexpect aCatch(SALOME_SalomeException);
3732 _preMeshInfo->FullLoadFromFile();
3734 // Update Python script
3735 // check names of groups
3737 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3740 PrepareForWriting(file);
3741 _impl->ExportUNV(file);
3744 //================================================================================
3746 * \brief Export a mesh to an STL file
3748 //================================================================================
3750 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3751 throw(SALOME::SALOME_Exception)
3753 Unexpect aCatch(SALOME_SalomeException);
3755 _preMeshInfo->FullLoadFromFile();
3757 // Update Python script
3758 // check names of groups
3760 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3761 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3763 CORBA::String_var name;
3764 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3765 if ( !so->_is_nil() )
3766 name = so->GetName();
3769 PrepareForWriting( file );
3770 _impl->ExportSTL( file, isascii, name.in() );
3773 //================================================================================
3775 * \brief Export a part of mesh to a med file
3777 //================================================================================
3779 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3781 CORBA::Boolean auto_groups,
3782 CORBA::Long version,
3783 CORBA::Boolean overwrite,
3784 CORBA::Boolean autoDimension,
3785 const GEOM::ListOfFields& fields,
3786 const char* geomAssocFields,
3787 CORBA::Double ZTolerance)
3788 throw (SALOME::SALOME_Exception)
3790 MESSAGE("MED version: "<< version);
3793 _preMeshInfo->FullLoadFromFile();
3796 bool have0dField = false;
3797 if ( fields.length() > 0 )
3799 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3800 if ( shapeToMesh->_is_nil() )
3801 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3803 for ( size_t i = 0; i < fields.length(); ++i )
3805 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3806 THROW_SALOME_CORBA_EXCEPTION
3807 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3808 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3809 if ( fieldShape->_is_nil() )
3810 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3811 if ( !fieldShape->IsSame( shapeToMesh ) )
3812 THROW_SALOME_CORBA_EXCEPTION
3813 ( "Field defined not on shape", SALOME::BAD_PARAM);
3814 if ( fields[i]->GetDimension() == 0 )
3817 if ( geomAssocFields )
3818 for ( int i = 0; geomAssocFields[i]; ++i )
3819 switch ( geomAssocFields[i] ) {
3820 case 'v':case 'e':case 'f':case 's': break;
3821 case 'V':case 'E':case 'F':case 'S': break;
3822 default: THROW_SALOME_CORBA_EXCEPTION
3823 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3827 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3831 string aMeshName = "Mesh";
3832 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3833 if ( CORBA::is_nil( meshPart ) ||
3834 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3836 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3837 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3838 0, autoDimension, /*addODOnVertices=*/have0dField,
3840 meshDS = _impl->GetMeshDS();
3845 _preMeshInfo->FullLoadFromFile();
3847 PrepareForWriting(file, overwrite);
3849 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3850 if ( !SO->_is_nil() ) {
3851 CORBA::String_var name = SO->GetName();
3855 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3856 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3857 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3858 meshDS = tmpDSDeleter._obj = partDS;
3863 if ( _impl->HasShapeToMesh() )
3865 DriverMED_W_Field fieldWriter;
3866 fieldWriter.SetFile( file );
3867 fieldWriter.SetMeshName( aMeshName );
3868 fieldWriter.AddODOnVertices( have0dField );
3870 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3874 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3875 goList->length( fields.length() );
3876 for ( size_t i = 0; i < fields.length(); ++i )
3878 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3881 TPythonDump() << _this() << ".ExportPartToMED( "
3882 << meshPart << ", r'"
3884 << auto_groups << ", "
3886 << overwrite << ", "
3887 << autoDimension << ", "
3889 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
3890 << TVar( ZTolerance )
3893 SMESH_CATCH( SMESH::throwCorbaException );
3896 //================================================================================
3898 * Write GEOM fields to MED file
3900 //================================================================================
3902 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3903 SMESHDS_Mesh* meshDS,
3904 const GEOM::ListOfFields& fields,
3905 const char* geomAssocFields)
3907 #define METH "SMESH_Mesh_i::exportMEDFields() "
3909 if (( fields.length() < 1 ) &&
3910 ( !geomAssocFields || !geomAssocFields[0] ))
3913 std::vector< std::vector< double > > dblVals;
3914 std::vector< std::vector< int > > intVals;
3915 std::vector< int > subIdsByDim[ 4 ];
3916 const double noneDblValue = 0.;
3917 const double noneIntValue = 0;
3919 for ( size_t iF = 0; iF < fields.length(); ++iF )
3923 int dim = fields[ iF ]->GetDimension();
3924 SMDSAbs_ElementType elemType;
3925 TopAbs_ShapeEnum shapeType;
3927 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3928 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3929 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3930 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3932 continue; // skip fields on whole shape
3934 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3935 if ( dataType == GEOM::FDT_String )
3937 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3938 if ( stepIDs->length() < 1 )
3940 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3941 if ( comps->length() < 1 )
3943 CORBA::String_var name = fields[ iF ]->GetName();
3945 if ( !fieldWriter.Set( meshDS,
3949 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3952 for ( size_t iC = 0; iC < comps->length(); ++iC )
3953 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3955 dblVals.resize( comps->length() );
3956 intVals.resize( comps->length() );
3958 // find sub-shape IDs
3960 std::vector< int >& subIds = subIdsByDim[ dim ];
3961 if ( subIds.empty() )
3962 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3963 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3964 subIds.push_back( id );
3968 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3972 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3974 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3975 if ( step->_is_nil() )
3978 CORBA::Long stamp = step->GetStamp();
3979 CORBA::Long id = step->GetID();
3980 fieldWriter.SetDtIt( int( stamp ), int( id ));
3982 // fill dblVals or intVals
3983 for ( size_t iC = 0; iC < comps->length(); ++iC )
3984 if ( dataType == GEOM::FDT_Double )
3986 dblVals[ iC ].clear();
3987 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3991 intVals[ iC ].clear();
3992 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3996 case GEOM::FDT_Double:
3998 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3999 if ( dblStep->_is_nil() ) continue;
4000 GEOM::ListOfDouble_var vv = dblStep->GetValues();
4001 if ( vv->length() != subIds.size() * comps->length() )
4002 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
4003 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
4004 for ( size_t iC = 0; iC < comps->length(); ++iC )
4005 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
4010 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
4011 if ( intStep->_is_nil() ) continue;
4012 GEOM::ListOfLong_var vv = intStep->GetValues();
4013 if ( vv->length() != subIds.size() * comps->length() )
4014 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
4015 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
4016 for ( size_t iC = 0; iC < comps->length(); ++iC )
4017 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
4020 case GEOM::FDT_Bool:
4022 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
4023 if ( boolStep->_is_nil() ) continue;
4024 GEOM::short_array_var vv = boolStep->GetValues();
4025 if ( vv->length() != subIds.size() * comps->length() )
4026 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
4027 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
4028 for ( size_t iC = 0; iC < comps->length(); ++iC )
4029 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
4035 // pass values to fieldWriter
4036 elemIt = fieldWriter.GetOrderedElems();
4037 if ( dataType == GEOM::FDT_Double )
4038 while ( elemIt->more() )
4040 const SMDS_MeshElement* e = elemIt->next();
4041 const int shapeID = e->getshapeId();
4042 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
4043 for ( size_t iC = 0; iC < comps->length(); ++iC )
4044 fieldWriter.AddValue( noneDblValue );
4046 for ( size_t iC = 0; iC < comps->length(); ++iC )
4047 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
4050 while ( elemIt->more() )
4052 const SMDS_MeshElement* e = elemIt->next();
4053 const int shapeID = e->getshapeId();
4054 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
4055 for ( size_t iC = 0; iC < comps->length(); ++iC )
4056 fieldWriter.AddValue( (double) noneIntValue );
4058 for ( size_t iC = 0; iC < comps->length(); ++iC )
4059 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
4063 fieldWriter.Perform();
4064 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4065 if ( res && res->IsKO() )
4067 if ( res->myComment.empty() )
4068 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4070 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4076 if ( !geomAssocFields || !geomAssocFields[0] )
4079 // write geomAssocFields
4081 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
4082 shapeDim[ TopAbs_COMPOUND ] = 3;
4083 shapeDim[ TopAbs_COMPSOLID ] = 3;
4084 shapeDim[ TopAbs_SOLID ] = 3;
4085 shapeDim[ TopAbs_SHELL ] = 2;
4086 shapeDim[ TopAbs_FACE ] = 2;
4087 shapeDim[ TopAbs_WIRE ] = 1;
4088 shapeDim[ TopAbs_EDGE ] = 1;
4089 shapeDim[ TopAbs_VERTEX ] = 0;
4090 shapeDim[ TopAbs_SHAPE ] = 3;
4092 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
4094 std::vector< std::string > compNames;
4095 switch ( geomAssocFields[ iF ]) {
4097 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
4098 compNames.push_back( "dim" );
4101 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
4104 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
4107 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
4111 compNames.push_back( "id" );
4112 for ( size_t iC = 0; iC < compNames.size(); ++iC )
4113 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
4115 fieldWriter.SetDtIt( -1, -1 );
4117 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
4121 if ( compNames.size() == 2 ) // _vertices_
4122 while ( elemIt->more() )
4124 const SMDS_MeshElement* e = elemIt->next();
4125 const int shapeID = e->getshapeId();
4128 fieldWriter.AddValue( (double) -1 );
4129 fieldWriter.AddValue( (double) -1 );
4133 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
4134 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
4135 fieldWriter.AddValue( (double) shapeID );
4139 while ( elemIt->more() )
4141 const SMDS_MeshElement* e = elemIt->next();
4142 const int shapeID = e->getshapeId();
4144 fieldWriter.AddValue( (double) -1 );
4146 fieldWriter.AddValue( (double) shapeID );
4150 fieldWriter.Perform();
4151 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4152 if ( res && res->IsKO() )
4154 if ( res->myComment.empty() )
4155 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4157 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4160 } // loop on geomAssocFields
4165 //================================================================================
4167 * \brief Export a part of mesh to a DAT file
4169 //================================================================================
4171 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
4173 throw (SALOME::SALOME_Exception)
4175 Unexpect aCatch(SALOME_SalomeException);
4177 _preMeshInfo->FullLoadFromFile();
4179 PrepareForWriting(file);
4181 SMESH_MeshPartDS partDS( meshPart );
4182 _impl->ExportDAT(file,&partDS);
4184 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4185 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
4187 //================================================================================
4189 * \brief Export a part of mesh to an UNV file
4191 //================================================================================
4193 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
4195 throw (SALOME::SALOME_Exception)
4197 Unexpect aCatch(SALOME_SalomeException);
4199 _preMeshInfo->FullLoadFromFile();
4201 PrepareForWriting(file);
4203 SMESH_MeshPartDS partDS( meshPart );
4204 _impl->ExportUNV(file, &partDS);
4206 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4207 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
4209 //================================================================================
4211 * \brief Export a part of mesh to an STL file
4213 //================================================================================
4215 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
4217 ::CORBA::Boolean isascii)
4218 throw (SALOME::SALOME_Exception)
4220 Unexpect aCatch(SALOME_SalomeException);
4222 _preMeshInfo->FullLoadFromFile();
4224 PrepareForWriting(file);
4226 CORBA::String_var name;
4227 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4228 if ( !so->_is_nil() )
4229 name = so->GetName();
4231 SMESH_MeshPartDS partDS( meshPart );
4232 _impl->ExportSTL( file, isascii, name.in(), &partDS );
4234 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
4235 << meshPart<< ", r'" << file << "', " << isascii << ")";
4238 //================================================================================
4240 * \brief Export a part of mesh to an STL file
4242 //================================================================================
4244 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
4246 CORBA::Boolean overwrite,
4247 CORBA::Boolean groupElemsByType)
4248 throw (SALOME::SALOME_Exception)
4251 Unexpect aCatch(SALOME_SalomeException);
4253 _preMeshInfo->FullLoadFromFile();
4255 PrepareForWriting(file,overwrite);
4257 std::string meshName("");
4258 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4259 if ( !so->_is_nil() )
4261 CORBA::String_var name = so->GetName();
4262 meshName = name.in();
4266 SMESH_MeshPartDS partDS( meshPart );
4267 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
4269 SMESH_CATCH( SMESH::throwCorbaException );
4271 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
4272 << meshPart<< ", r'" << file << "', " << overwrite << ")";
4274 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
4278 //================================================================================
4280 * \brief Export a part of mesh to a GMF file
4282 //================================================================================
4284 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
4286 bool withRequiredGroups)
4287 throw (SALOME::SALOME_Exception)
4289 Unexpect aCatch(SALOME_SalomeException);
4291 _preMeshInfo->FullLoadFromFile();
4293 PrepareForWriting(file,/*overwrite=*/true);
4295 SMESH_MeshPartDS partDS( meshPart );
4296 _impl->ExportGMF(file, &partDS, withRequiredGroups);
4298 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
4299 << meshPart<< ", r'"
4301 << withRequiredGroups << ")";
4304 //=============================================================================
4306 * Return computation progress [0.,1]
4308 //=============================================================================
4310 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
4314 return _impl->GetComputeProgress();
4316 SMESH_CATCH( SMESH::doNothing );
4320 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
4322 Unexpect aCatch(SALOME_SalomeException);
4324 return _preMeshInfo->NbNodes();
4326 return _impl->NbNodes();
4329 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
4331 Unexpect aCatch(SALOME_SalomeException);
4333 return _preMeshInfo->NbElements();
4335 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
4338 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
4340 Unexpect aCatch(SALOME_SalomeException);
4342 return _preMeshInfo->Nb0DElements();
4344 return _impl->Nb0DElements();
4347 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
4349 Unexpect aCatch(SALOME_SalomeException);
4351 return _preMeshInfo->NbBalls();
4353 return _impl->NbBalls();
4356 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
4358 Unexpect aCatch(SALOME_SalomeException);
4360 return _preMeshInfo->NbEdges();
4362 return _impl->NbEdges();
4365 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
4366 throw(SALOME::SALOME_Exception)
4368 Unexpect aCatch(SALOME_SalomeException);
4370 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
4372 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
4375 //=============================================================================
4377 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
4379 Unexpect aCatch(SALOME_SalomeException);
4381 return _preMeshInfo->NbFaces();
4383 return _impl->NbFaces();
4386 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
4388 Unexpect aCatch(SALOME_SalomeException);
4390 return _preMeshInfo->NbTriangles();
4392 return _impl->NbTriangles();
4395 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
4397 Unexpect aCatch(SALOME_SalomeException);
4399 return _preMeshInfo->NbBiQuadTriangles();
4401 return _impl->NbBiQuadTriangles();
4404 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
4406 Unexpect aCatch(SALOME_SalomeException);
4408 return _preMeshInfo->NbQuadrangles();
4410 return _impl->NbQuadrangles();
4413 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
4415 Unexpect aCatch(SALOME_SalomeException);
4417 return _preMeshInfo->NbBiQuadQuadrangles();
4419 return _impl->NbBiQuadQuadrangles();
4422 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
4424 Unexpect aCatch(SALOME_SalomeException);
4426 return _preMeshInfo->NbPolygons();
4428 return _impl->NbPolygons();
4431 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
4433 Unexpect aCatch(SALOME_SalomeException);
4435 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
4437 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
4440 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
4441 throw(SALOME::SALOME_Exception)
4443 Unexpect aCatch(SALOME_SalomeException);
4445 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
4447 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
4450 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
4451 throw(SALOME::SALOME_Exception)
4453 Unexpect aCatch(SALOME_SalomeException);
4455 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
4457 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
4460 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
4461 throw(SALOME::SALOME_Exception)
4463 Unexpect aCatch(SALOME_SalomeException);
4465 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
4467 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
4470 //=============================================================================
4472 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
4474 Unexpect aCatch(SALOME_SalomeException);
4476 return _preMeshInfo->NbVolumes();
4478 return _impl->NbVolumes();
4481 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
4483 Unexpect aCatch(SALOME_SalomeException);
4485 return _preMeshInfo->NbTetras();
4487 return _impl->NbTetras();
4490 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
4492 Unexpect aCatch(SALOME_SalomeException);
4494 return _preMeshInfo->NbHexas();
4496 return _impl->NbHexas();
4499 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
4501 Unexpect aCatch(SALOME_SalomeException);
4503 return _preMeshInfo->NbTriQuadHexas();
4505 return _impl->NbTriQuadraticHexas();
4508 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
4510 Unexpect aCatch(SALOME_SalomeException);
4512 return _preMeshInfo->NbPyramids();
4514 return _impl->NbPyramids();
4517 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
4519 Unexpect aCatch(SALOME_SalomeException);
4521 return _preMeshInfo->NbPrisms();
4523 return _impl->NbPrisms();
4526 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
4528 Unexpect aCatch(SALOME_SalomeException);
4530 return _preMeshInfo->NbHexPrisms();
4532 return _impl->NbHexagonalPrisms();
4535 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
4537 Unexpect aCatch(SALOME_SalomeException);
4539 return _preMeshInfo->NbPolyhedrons();
4541 return _impl->NbPolyhedrons();
4544 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4545 throw(SALOME::SALOME_Exception)
4547 Unexpect aCatch(SALOME_SalomeException);
4549 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4551 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4554 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4555 throw(SALOME::SALOME_Exception)
4557 Unexpect aCatch(SALOME_SalomeException);
4559 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4561 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4564 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4565 throw(SALOME::SALOME_Exception)
4567 Unexpect aCatch(SALOME_SalomeException);
4569 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4571 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4574 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4575 throw(SALOME::SALOME_Exception)
4577 Unexpect aCatch(SALOME_SalomeException);
4579 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4581 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4584 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4585 throw(SALOME::SALOME_Exception)
4587 Unexpect aCatch(SALOME_SalomeException);
4589 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4591 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4594 //=============================================================================
4596 * Returns nb of published sub-meshes
4598 //=============================================================================
4600 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4602 Unexpect aCatch(SALOME_SalomeException);
4603 return _mapSubMesh_i.size();
4606 //=============================================================================
4608 * Dumps mesh into a string
4610 //=============================================================================
4612 char* SMESH_Mesh_i::Dump()
4616 return CORBA::string_dup( os.str().c_str() );
4619 //=============================================================================
4621 * Method of SMESH_IDSource interface
4623 //=============================================================================
4625 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4627 return GetElementsId();
4630 //=============================================================================
4632 * Returns ids of all elements
4634 //=============================================================================
4636 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4637 throw (SALOME::SALOME_Exception)
4639 Unexpect aCatch(SALOME_SalomeException);
4641 _preMeshInfo->FullLoadFromFile();
4643 SMESH::long_array_var aResult = new SMESH::long_array();
4644 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4646 if ( aSMESHDS_Mesh == NULL )
4647 return aResult._retn();
4649 long nbElements = NbElements();
4650 aResult->length( nbElements );
4651 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4652 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4653 aResult[i] = anIt->next()->GetID();
4655 return aResult._retn();
4659 //=============================================================================
4661 * Returns ids of all elements of given type
4663 //=============================================================================
4665 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4666 throw (SALOME::SALOME_Exception)
4668 Unexpect aCatch(SALOME_SalomeException);
4670 _preMeshInfo->FullLoadFromFile();
4672 SMESH::long_array_var aResult = new SMESH::long_array();
4673 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4675 if ( aSMESHDS_Mesh == NULL )
4676 return aResult._retn();
4678 long nbElements = NbElements();
4680 // No sense in returning ids of elements along with ids of nodes:
4681 // when theElemType == SMESH::ALL, return node ids only if
4682 // there are no elements
4683 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4684 return GetNodesId();
4686 aResult->length( nbElements );
4690 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4691 while ( i < nbElements && anIt->more() )
4692 aResult[i++] = anIt->next()->GetID();
4694 aResult->length( i );
4696 return aResult._retn();
4699 //=============================================================================
4701 * Returns ids of all nodes
4703 //=============================================================================
4705 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4706 throw (SALOME::SALOME_Exception)
4708 Unexpect aCatch(SALOME_SalomeException);
4710 _preMeshInfo->FullLoadFromFile();
4712 SMESH::long_array_var aResult = new SMESH::long_array();
4713 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4715 if ( aMeshDS == NULL )
4716 return aResult._retn();
4718 long nbNodes = NbNodes();
4719 aResult->length( nbNodes );
4720 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4721 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4722 aResult[i] = anIt->next()->GetID();
4724 return aResult._retn();
4727 //=============================================================================
4731 //=============================================================================
4733 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4734 throw (SALOME::SALOME_Exception)
4736 SMESH::ElementType type = SMESH::ALL;
4740 _preMeshInfo->FullLoadFromFile();
4742 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4744 SMESH_CATCH( SMESH::throwCorbaException );
4749 //=============================================================================
4753 //=============================================================================
4755 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4756 throw (SALOME::SALOME_Exception)
4759 _preMeshInfo->FullLoadFromFile();
4761 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4763 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4765 return ( SMESH::EntityType ) e->GetEntityType();
4768 //=============================================================================
4772 //=============================================================================
4774 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4775 throw (SALOME::SALOME_Exception)
4778 _preMeshInfo->FullLoadFromFile();
4780 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4782 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4784 return ( SMESH::GeometryType ) e->GetGeomType();
4787 //=============================================================================
4789 * Returns ID of elements for given submesh
4791 //=============================================================================
4792 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4793 throw (SALOME::SALOME_Exception)
4795 SMESH::long_array_var aResult = new SMESH::long_array();
4799 _preMeshInfo->FullLoadFromFile();
4801 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4802 if(!SM) return aResult._retn();
4804 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4805 if(!SDSM) return aResult._retn();
4807 aResult->length(SDSM->NbElements());
4809 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4811 while ( eIt->more() ) {
4812 aResult[i++] = eIt->next()->GetID();
4815 SMESH_CATCH( SMESH::throwCorbaException );
4817 return aResult._retn();
4820 //=============================================================================
4822 * Returns ID of nodes for given submesh
4823 * If param all==true - returns all nodes, else -
4824 * returns only nodes on shapes.
4826 //=============================================================================
4828 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4830 throw (SALOME::SALOME_Exception)
4832 SMESH::long_array_var aResult = new SMESH::long_array();
4836 _preMeshInfo->FullLoadFromFile();
4838 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4839 if(!SM) return aResult._retn();
4841 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4842 if(!SDSM) return aResult._retn();
4845 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4846 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4847 while ( nIt->more() ) {
4848 const SMDS_MeshNode* elem = nIt->next();
4849 theElems.insert( elem->GetID() );
4852 else { // all nodes of submesh elements
4853 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4854 while ( eIt->more() ) {
4855 const SMDS_MeshElement* anElem = eIt->next();
4856 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4857 while ( nIt->more() ) {
4858 const SMDS_MeshElement* elem = nIt->next();
4859 theElems.insert( elem->GetID() );
4864 aResult->length(theElems.size());
4865 set<int>::iterator itElem;
4867 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4868 aResult[i++] = *itElem;
4870 SMESH_CATCH( SMESH::throwCorbaException );
4872 return aResult._retn();
4875 //=============================================================================
4877 * Returns type of elements for given submesh
4879 //=============================================================================
4881 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4882 throw (SALOME::SALOME_Exception)
4884 SMESH::ElementType type = SMESH::ALL;
4888 _preMeshInfo->FullLoadFromFile();
4890 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4891 if(!SM) return SMESH::ALL;
4893 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4894 if(!SDSM) return SMESH::ALL;
4896 if(SDSM->NbElements()==0)
4897 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4899 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4900 const SMDS_MeshElement* anElem = eIt->next();
4902 type = ( SMESH::ElementType ) anElem->GetType();
4904 SMESH_CATCH( SMESH::throwCorbaException );
4910 //=============================================================================
4912 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4914 //=============================================================================
4916 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4919 _preMeshInfo->FullLoadFromFile();
4921 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4922 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4927 //=============================================================================
4929 * Get XYZ coordinates of node as list of double
4930 * If there is not node for given ID - returns empty list
4932 //=============================================================================
4934 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4937 _preMeshInfo->FullLoadFromFile();
4939 SMESH::double_array_var aResult = new SMESH::double_array();
4940 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4941 if ( aMeshDS == NULL )
4942 return aResult._retn();
4945 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4947 return aResult._retn();
4951 aResult[0] = aNode->X();
4952 aResult[1] = aNode->Y();
4953 aResult[2] = aNode->Z();
4954 return aResult._retn();
4958 //=============================================================================
4960 * For given node returns list of IDs of inverse elements
4961 * If there is not node for given ID - returns empty list
4963 //=============================================================================
4965 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id,
4966 SMESH::ElementType elemType)
4969 _preMeshInfo->FullLoadFromFile();
4971 SMESH::long_array_var aResult = new SMESH::long_array();
4972 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4973 if ( aMeshDS == NULL )
4974 return aResult._retn();
4977 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
4979 return aResult._retn();
4981 // find inverse elements
4982 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
4983 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
4984 aResult->length( aNode->NbInverseElements( type ));
4985 for( int i = 0; eIt->more(); ++i )
4987 const SMDS_MeshElement* elem = eIt->next();
4988 aResult[ i ] = elem->GetID();
4990 return aResult._retn();
4993 //=============================================================================
4995 * \brief Return position of a node on shape
4997 //=============================================================================
4999 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
5002 _preMeshInfo->FullLoadFromFile();
5004 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
5005 aNodePosition->shapeID = 0;
5006 aNodePosition->shapeType = GEOM::SHAPE;
5008 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
5009 if ( !mesh ) return aNodePosition;
5011 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
5013 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
5015 aNodePosition->shapeID = aNode->getshapeId();
5016 switch ( pos->GetTypeOfPosition() ) {
5018 aNodePosition->shapeType = GEOM::EDGE;
5019 aNodePosition->params.length(1);
5020 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
5022 case SMDS_TOP_FACE: {
5023 SMDS_FacePositionPtr fPos = pos;
5024 aNodePosition->shapeType = GEOM::FACE;
5025 aNodePosition->params.length(2);
5026 aNodePosition->params[0] = fPos->GetUParameter();
5027 aNodePosition->params[1] = fPos->GetVParameter();
5030 case SMDS_TOP_VERTEX:
5031 aNodePosition->shapeType = GEOM::VERTEX;
5033 case SMDS_TOP_3DSPACE:
5034 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
5035 aNodePosition->shapeType = GEOM::SOLID;
5036 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
5037 aNodePosition->shapeType = GEOM::SHELL;
5043 return aNodePosition;
5046 //=============================================================================
5048 * \brief Return position of an element on shape
5050 //=============================================================================
5052 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
5055 _preMeshInfo->FullLoadFromFile();
5057 SMESH::ElementPosition anElementPosition;
5058 anElementPosition.shapeID = 0;
5059 anElementPosition.shapeType = GEOM::SHAPE;
5061 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
5062 if ( !mesh ) return anElementPosition;
5064 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
5066 anElementPosition.shapeID = anElem->getshapeId();
5067 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
5068 if ( !aSp.IsNull() ) {
5069 switch ( aSp.ShapeType() ) {
5071 anElementPosition.shapeType = GEOM::EDGE;
5074 anElementPosition.shapeType = GEOM::FACE;
5077 anElementPosition.shapeType = GEOM::VERTEX;
5080 anElementPosition.shapeType = GEOM::SOLID;
5083 anElementPosition.shapeType = GEOM::SHELL;
5089 return anElementPosition;
5092 //=============================================================================
5094 * If given element is node returns IDs of shape from position
5095 * If there is not node for given ID - returns -1
5097 //=============================================================================
5099 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
5102 _preMeshInfo->FullLoadFromFile();
5104 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5105 if ( aMeshDS == NULL )
5109 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
5111 return aNode->getshapeId();
5118 //=============================================================================
5120 * For given element returns ID of result shape after
5121 * ::FindShape() from SMESH_MeshEditor
5122 * If there is not element for given ID - returns -1
5124 //=============================================================================
5126 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
5129 _preMeshInfo->FullLoadFromFile();
5131 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5132 if ( aMeshDS == NULL )
5135 // try to find element
5136 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5140 ::SMESH_MeshEditor aMeshEditor(_impl);
5141 int index = aMeshEditor.FindShape( elem );
5149 //=============================================================================
5151 * Returns number of nodes for given element
5152 * If there is not element for given ID - returns -1
5154 //=============================================================================
5156 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
5159 _preMeshInfo->FullLoadFromFile();
5161 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5162 if ( aMeshDS == NULL ) return -1;
5163 // try to find element
5164 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5165 if(!elem) return -1;
5166 return elem->NbNodes();
5170 //=============================================================================
5172 * Returns ID of node by given index for given element
5173 * If there is not element for given ID - returns -1
5174 * If there is not node for given index - returns -2
5176 //=============================================================================
5178 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
5181 _preMeshInfo->FullLoadFromFile();
5183 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5184 if ( aMeshDS == NULL ) return -1;
5185 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5186 if(!elem) return -1;
5187 if( index>=elem->NbNodes() || index<0 ) return -1;
5188 return elem->GetNode(index)->GetID();
5191 //=============================================================================
5193 * Returns IDs of nodes of given element
5195 //=============================================================================
5197 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
5200 _preMeshInfo->FullLoadFromFile();
5202 SMESH::long_array_var aResult = new SMESH::long_array();
5203 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5205 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
5207 aResult->length( elem->NbNodes() );
5208 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5209 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
5210 aResult[ i ] = n->GetID();
5213 return aResult._retn();
5216 //=============================================================================
5218 * Returns true if given node is medium node
5219 * in given quadratic element
5221 //=============================================================================
5223 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
5226 _preMeshInfo->FullLoadFromFile();
5228 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5229 if ( aMeshDS == NULL ) return false;
5231 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5232 if(!aNode) return false;
5233 // try to find element
5234 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
5235 if(!elem) return false;
5237 return elem->IsMediumNode(aNode);
5241 //=============================================================================
5243 * Returns true if given node is medium node
5244 * in one of quadratic elements
5246 //=============================================================================
5248 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
5249 SMESH::ElementType theElemType)
5252 _preMeshInfo->FullLoadFromFile();
5254 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5255 if ( aMeshDS == NULL ) return false;
5258 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5259 if(!aNode) return false;
5261 SMESH_MesherHelper aHelper( *(_impl) );
5263 SMDSAbs_ElementType aType;
5264 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
5265 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
5266 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
5267 else aType = SMDSAbs_All;
5269 return aHelper.IsMedium(aNode,aType);
5273 //=============================================================================
5275 * Returns number of edges for given element
5277 //=============================================================================
5279 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
5282 _preMeshInfo->FullLoadFromFile();
5284 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5285 if ( aMeshDS == NULL ) return -1;
5286 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5287 if(!elem) return -1;
5288 return elem->NbEdges();
5292 //=============================================================================
5294 * Returns number of faces for given element
5296 //=============================================================================
5298 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
5301 _preMeshInfo->FullLoadFromFile();
5303 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5304 if ( aMeshDS == NULL ) return -1;
5305 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5306 if(!elem) return -1;
5307 return elem->NbFaces();
5310 //=======================================================================
5311 //function : GetElemFaceNodes
5312 //purpose : Returns nodes of given face (counted from zero) for given element.
5313 //=======================================================================
5315 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
5316 CORBA::Short faceIndex)
5319 _preMeshInfo->FullLoadFromFile();
5321 SMESH::long_array_var aResult = new SMESH::long_array();
5322 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5324 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
5326 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
5327 if ( faceIndex < vtool.NbFaces() )
5329 aResult->length( vtool.NbFaceNodes( faceIndex ));
5330 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
5331 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5332 aResult[ i ] = nn[ i ]->GetID();
5336 return aResult._retn();
5339 //=======================================================================
5340 //function : GetFaceNormal
5341 //purpose : Returns three components of normal of given mesh face.
5342 //=======================================================================
5344 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
5345 CORBA::Boolean normalized)
5348 _preMeshInfo->FullLoadFromFile();
5350 SMESH::double_array_var aResult = new SMESH::double_array();
5352 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5355 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
5357 aResult->length( 3 );
5358 aResult[ 0 ] = normal.X();
5359 aResult[ 1 ] = normal.Y();
5360 aResult[ 2 ] = normal.Z();
5363 return aResult._retn();
5366 //=======================================================================
5367 //function : FindElementByNodes
5368 //purpose : Returns an element based on all given nodes.
5369 //=======================================================================
5371 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
5374 _preMeshInfo->FullLoadFromFile();
5376 CORBA::Long elemID(0);
5377 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5379 vector< const SMDS_MeshNode * > nn( nodes.length() );
5380 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5381 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
5384 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
5385 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
5386 _impl->NbFaces ( ORDER_QUADRATIC ) ||
5387 _impl->NbVolumes( ORDER_QUADRATIC )))
5388 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
5390 if ( elem ) elemID = CORBA::Long( elem->GetID() );
5395 //================================================================================
5397 * \brief Return elements including all given nodes.
5399 //================================================================================
5401 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
5402 SMESH::ElementType elemType)
5405 _preMeshInfo->FullLoadFromFile();
5407 SMESH::long_array_var result = new SMESH::long_array();
5409 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5411 vector< const SMDS_MeshNode * > nn( nodes.length() );
5412 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5413 nn[i] = mesh->FindNode( nodes[i] );
5415 std::vector<const SMDS_MeshElement *> elems;
5416 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
5417 result->length( elems.size() );
5418 for ( size_t i = 0; i < elems.size(); ++i )
5419 result[i] = elems[i]->GetID();
5421 return result._retn();
5424 //=============================================================================
5426 * Returns true if given element is polygon
5428 //=============================================================================
5430 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
5433 _preMeshInfo->FullLoadFromFile();
5435 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5436 if ( aMeshDS == NULL ) return false;
5437 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5438 if(!elem) return false;
5439 return elem->IsPoly();
5443 //=============================================================================
5445 * Returns true if given element is quadratic
5447 //=============================================================================
5449 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
5452 _preMeshInfo->FullLoadFromFile();
5454 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5455 if ( aMeshDS == NULL ) return false;
5456 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5457 if(!elem) return false;
5458 return elem->IsQuadratic();
5461 //=============================================================================
5463 * Returns diameter of ball discrete element or zero in case of an invalid \a id
5465 //=============================================================================
5467 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
5470 _preMeshInfo->FullLoadFromFile();
5472 if ( const SMDS_BallElement* ball =
5473 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
5474 return ball->GetDiameter();
5479 //=============================================================================
5481 * Returns bary center for given element
5483 //=============================================================================
5485 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5488 _preMeshInfo->FullLoadFromFile();
5490 SMESH::double_array_var aResult = new SMESH::double_array();
5491 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5492 if ( aMeshDS == NULL )
5493 return aResult._retn();
5495 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5497 return aResult._retn();
5499 if(elem->GetType()==SMDSAbs_Volume) {
5500 SMDS_VolumeTool aTool;
5501 if(aTool.Set(elem)) {
5503 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5508 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5510 double x=0., y=0., z=0.;
5511 for(; anIt->more(); ) {
5513 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5527 return aResult._retn();
5530 //================================================================================
5532 * \brief Create a group of elements preventing computation of a sub-shape
5534 //================================================================================
5536 SMESH::ListOfGroups*
5537 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5538 const char* theGroupName )
5539 throw ( SALOME::SALOME_Exception )
5541 Unexpect aCatch(SALOME_SalomeException);
5543 if ( !theGroupName || strlen( theGroupName) == 0 )
5544 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5546 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5547 ::SMESH_MeshEditor::ElemFeatures elemType;
5549 // submesh by subshape id
5550 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5551 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5554 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5555 if ( error && error->HasBadElems() )
5557 // sort bad elements by type
5558 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5559 const list<const SMDS_MeshElement*>& badElems =
5560 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5561 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5562 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5563 for ( ; elemIt != elemEnd; ++elemIt )
5565 const SMDS_MeshElement* elem = *elemIt;
5566 if ( !elem ) continue;
5568 if ( elem->GetID() < 1 )
5570 // elem is a temporary element, make a real element
5571 vector< const SMDS_MeshNode* > nodes;
5572 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5573 while ( nIt->more() && elem )
5575 nodes.push_back( nIt->next() );
5576 if ( nodes.back()->GetID() < 1 )
5577 elem = 0; // a temporary element on temporary nodes
5581 ::SMESH_MeshEditor editor( _impl );
5582 elem = editor.AddElement( nodes, elemType.Init( elem ));
5586 elemsByType[ elem->GetType() ].push_back( elem );
5589 // how many groups to create?
5591 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5592 nbTypes += int( !elemsByType[ i ].empty() );
5593 groups->length( nbTypes );
5596 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5598 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5599 if ( elems.empty() ) continue;
5601 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5602 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5604 SMESH::SMESH_Mesh_var mesh = _this();
5605 SALOMEDS::SObject_wrap aSO =
5606 _gen_i->PublishGroup( mesh, groups[ iG ],
5607 GEOM::GEOM_Object::_nil(), theGroupName);
5609 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5610 if ( !grp_i ) continue;
5612 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5613 for ( size_t iE = 0; iE < elems.size(); ++iE )
5614 grpDS->SMDSGroup().Add( elems[ iE ]);
5619 return groups._retn();
5622 //=============================================================================
5624 * Create and publish group servants if any groups were imported or created anyhow
5626 //=============================================================================
5628 void SMESH_Mesh_i::CreateGroupServants()
5630 SMESH::SMESH_Mesh_var aMesh = _this();
5633 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5634 while ( groupIt->more() )
5636 ::SMESH_Group* group = groupIt->next();
5637 int anId = group->GetID();
5639 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5640 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5642 addedIDs.insert( anId );
5644 SMESH_GroupBase_i* aGroupImpl;
5646 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5647 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5649 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5650 shape = groupOnGeom->GetShape();
5653 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5656 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5657 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5658 aGroupImpl->Register();
5660 // register CORBA object for persistence
5661 int nextId = _gen_i->RegisterObject( groupVar );
5662 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5663 else { nextId = 0; } // avoid "unused variable" warning in release mode
5665 // publishing the groups in the study
5666 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5667 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5669 if ( !addedIDs.empty() )
5672 set<int>::iterator id = addedIDs.begin();
5673 for ( ; id != addedIDs.end(); ++id )
5675 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5676 int i = std::distance( _mapGroups.begin(), it );
5677 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5682 //=============================================================================
5684 * \brief Return true if all sub-meshes are computed OK - to update an icon
5686 //=============================================================================
5688 bool SMESH_Mesh_i::IsComputedOK()
5690 return _impl->IsComputedOK();
5693 //=============================================================================
5695 * \brief Return groups cantained in _mapGroups by their IDs
5697 //=============================================================================
5699 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5701 int nbGroups = groupIDs.size();
5702 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5703 aList->length( nbGroups );
5705 list<int>::const_iterator ids = groupIDs.begin();
5706 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5708 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5709 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5710 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5712 aList->length( nbGroups );
5713 return aList._retn();
5716 //=============================================================================
5718 * \brief Return information about imported file
5720 //=============================================================================
5722 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5724 SMESH::MedFileInfo_var res( _medFileInfo );
5725 if ( !res.operator->() ) {
5726 res = new SMESH::MedFileInfo;
5728 res->fileSize = res->major = res->minor = res->release = -1;
5733 //=======================================================================
5734 //function : FileInfoToString
5735 //purpose : Persistence of file info
5736 //=======================================================================
5738 std::string SMESH_Mesh_i::FileInfoToString()
5741 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5743 s = SMESH_Comment( _medFileInfo->fileSize )
5744 << " " << _medFileInfo->major
5745 << " " << _medFileInfo->minor
5746 << " " << _medFileInfo->release
5747 << " " << _medFileInfo->fileName;
5752 //=======================================================================
5753 //function : FileInfoFromString
5754 //purpose : Persistence of file info
5755 //=======================================================================
5757 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5759 std::string size, major, minor, release, fileName;
5760 std::istringstream is(info);
5761 is >> size >> major >> minor >> release;
5762 fileName = info.data() + ( size.size() + 1 +
5765 release.size()+ 1 );
5767 _medFileInfo = new SMESH::MedFileInfo();
5768 _medFileInfo->fileName = fileName.c_str();
5769 _medFileInfo->fileSize = atoi( size.c_str() );
5770 _medFileInfo->major = atoi( major.c_str() );
5771 _medFileInfo->minor = atoi( minor.c_str() );
5772 _medFileInfo->release = atoi( release.c_str() );
5775 //=============================================================================
5777 * \brief Pass names of mesh groups from study to mesh DS
5779 //=============================================================================
5781 void SMESH_Mesh_i::checkGroupNames()
5783 int nbGrp = NbGroups();
5787 SMESH::ListOfGroups* grpList = 0;
5788 // avoid dump of "GetGroups"
5790 // store python dump into a local variable inside local scope
5791 SMESH::TPythonDump pDump; // do not delete this line of code
5792 grpList = GetGroups();
5795 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5796 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5799 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5800 if ( aGrpSO->_is_nil() )
5802 // correct name of the mesh group if necessary
5803 const char* guiName = aGrpSO->GetName();
5804 if ( strcmp(guiName, aGrp->GetName()) )
5805 aGrp->SetName( guiName );
5809 //=============================================================================
5811 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5813 //=============================================================================
5814 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5816 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5820 //=============================================================================
5822 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5824 //=============================================================================
5826 char* SMESH_Mesh_i::GetParameters()
5828 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5831 //=============================================================================
5833 * \brief Returns list of notebook variables used for last Mesh operation
5835 //=============================================================================
5836 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5838 SMESH::string_array_var aResult = new SMESH::string_array();
5839 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5841 CORBA::String_var aParameters = GetParameters();
5842 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5843 if ( aSections->length() > 0 ) {
5844 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5845 aResult->length( aVars.length() );
5846 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5847 aResult[i] = CORBA::string_dup( aVars[i] );
5850 return aResult._retn();
5853 //=======================================================================
5854 //function : GetTypes
5855 //purpose : Returns types of elements it contains
5856 //=======================================================================
5858 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5861 return _preMeshInfo->GetTypes();
5863 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5867 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5868 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5869 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5870 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5871 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5872 if (_impl->NbNodes() &&
5873 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5874 types->length( nbTypes );
5876 return types._retn();
5879 //=======================================================================
5880 //function : GetMesh
5881 //purpose : Returns self
5882 //=======================================================================
5884 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5886 return SMESH::SMESH_Mesh::_duplicate( _this() );
5889 //=======================================================================
5890 //function : IsMeshInfoCorrect
5891 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5892 // * happen if mesh data is not yet fully loaded from the file of study.
5893 //=======================================================================
5895 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5897 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5900 //=============================================================================
5902 * \brief Returns number of mesh elements per each \a EntityType
5904 //=============================================================================
5906 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5909 return _preMeshInfo->GetMeshInfo();
5911 SMESH::long_array_var aRes = new SMESH::long_array();
5912 aRes->length(SMESH::Entity_Last);
5913 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5915 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5917 return aRes._retn();
5918 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5919 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5920 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5921 return aRes._retn();
5924 //=============================================================================
5926 * \brief Returns number of mesh elements per each \a ElementType
5928 //=============================================================================
5930 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5932 SMESH::long_array_var aRes = new SMESH::long_array();
5933 aRes->length(SMESH::NB_ELEMENT_TYPES);
5934 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5937 const SMDS_MeshInfo* meshInfo = 0;
5939 meshInfo = _preMeshInfo;
5940 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5941 meshInfo = & meshDS->GetMeshInfo();
5944 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5945 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5947 return aRes._retn();
5950 //=============================================================================
5952 * Collect statistic of mesh elements given by iterator
5954 //=============================================================================
5956 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5957 SMESH::long_array& theInfo)
5959 if (!theItr) return;
5960 while (theItr->more())
5961 theInfo[ theItr->next()->GetEntityType() ]++;
5963 //=============================================================================
5965 * Returns mesh unstructed grid information.
5967 //=============================================================================
5969 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5971 SALOMEDS::TMPFile_var SeqFile;
5972 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5973 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5975 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5976 aWriter->WriteToOutputStringOn();
5977 aWriter->SetInputData(aGrid);
5978 aWriter->SetFileTypeToBinary();
5980 char* str = aWriter->GetOutputString();
5981 int size = aWriter->GetOutputStringLength();
5983 //Allocate octet buffer of required size
5984 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5985 //Copy ostrstream content to the octet buffer
5986 memcpy(OctetBuf, str, size);
5987 //Create and return TMPFile
5988 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5992 return SeqFile._retn();
5995 //=============================================================================
5996 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5997 * SMESH::ElementType type) */
5999 using namespace SMESH::Controls;
6000 //-----------------------------------------------------------------------------
6001 struct PredicateIterator : public SMDS_ElemIterator
6003 SMDS_ElemIteratorPtr _elemIter;
6004 PredicatePtr _predicate;
6005 const SMDS_MeshElement* _elem;
6006 SMDSAbs_ElementType _type;
6008 PredicateIterator( SMDS_ElemIteratorPtr iterator,
6009 PredicatePtr predicate,
6010 SMDSAbs_ElementType type):
6011 _elemIter(iterator), _predicate(predicate), _type(type)
6019 virtual const SMDS_MeshElement* next()
6021 const SMDS_MeshElement* res = _elem;
6023 while ( _elemIter->more() && !_elem )
6025 if ((_elem = _elemIter->next()) &&
6026 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
6027 ( !_predicate->IsSatisfy( _elem->GetID() ))))
6034 //-----------------------------------------------------------------------------
6035 struct IDSourceIterator : public SMDS_ElemIterator
6037 const CORBA::Long* _idPtr;
6038 const CORBA::Long* _idEndPtr;
6039 SMESH::long_array_var _idArray;
6040 const SMDS_Mesh* _mesh;
6041 const SMDSAbs_ElementType _type;
6042 const SMDS_MeshElement* _elem;
6044 IDSourceIterator( const SMDS_Mesh* mesh,
6045 const CORBA::Long* ids,
6047 SMDSAbs_ElementType type):
6048 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
6050 if ( _idPtr && nbIds && _mesh )
6053 IDSourceIterator( const SMDS_Mesh* mesh,
6054 SMESH::long_array* idArray,
6055 SMDSAbs_ElementType type):
6056 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
6058 if ( idArray && _mesh )
6060 _idPtr = &_idArray[0];
6061 _idEndPtr = _idPtr + _idArray->length();
6069 virtual const SMDS_MeshElement* next()
6071 const SMDS_MeshElement* res = _elem;
6073 while ( _idPtr < _idEndPtr && !_elem )
6075 if ( _type == SMDSAbs_Node )
6077 _elem = _mesh->FindNode( *_idPtr++ );
6079 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
6080 (_elem->GetType() != _type && _type != SMDSAbs_All ))
6088 //-----------------------------------------------------------------------------
6090 struct NodeOfElemIterator : public SMDS_ElemIterator
6092 TColStd_MapOfInteger _checkedNodeIDs;
6093 SMDS_ElemIteratorPtr _elemIter;
6094 SMDS_ElemIteratorPtr _nodeIter;
6095 const SMDS_MeshElement* _node;
6097 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
6099 if ( _elemIter && _elemIter->more() )
6101 _nodeIter = _elemIter->next()->nodesIterator();
6109 virtual const SMDS_MeshElement* next()
6111 const SMDS_MeshElement* res = _node;
6113 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
6115 if ( _nodeIter->more() )
6117 _node = _nodeIter->next();
6118 if ( !_checkedNodeIDs.Add( _node->GetID() ))
6123 _nodeIter = _elemIter->next()->nodesIterator();
6131 //=============================================================================
6133 * Return iterator on elements of given type in given object
6135 //=============================================================================
6137 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
6138 SMESH::ElementType theType)
6140 SMDS_ElemIteratorPtr elemIt;
6141 bool typeOK = ( theType == SMESH::ALL );
6142 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
6144 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
6145 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
6146 if ( !mesh_i ) return elemIt;
6147 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
6149 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
6151 elemIt = meshDS->elementsIterator( elemType );
6154 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
6156 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
6159 elemIt = sm->GetElements();
6160 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6162 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
6163 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
6167 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
6169 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
6170 if ( groupDS && ( elemType == groupDS->GetType() ||
6171 elemType == SMDSAbs_Node ||
6172 elemType == SMDSAbs_All ))
6174 elemIt = groupDS->GetElements();
6175 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
6178 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
6180 if ( filter_i->GetElementType() == theType ||
6181 filter_i->GetElementType() == SMESH::ALL ||
6182 elemType == SMDSAbs_Node ||
6183 elemType == SMDSAbs_All)
6185 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
6186 if ( pred_i && pred_i->GetPredicate() )
6188 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
6189 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
6190 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
6191 elemIt = SMDS_ElemIteratorPtr
6192 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
6193 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
6199 SMESH::array_of_ElementType_var types = theObject->GetTypes();
6200 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
6201 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6203 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
6204 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
6207 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
6208 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
6212 SMESH::long_array_var ids = theObject->GetIDs();
6213 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
6215 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
6218 if ( elemIt && elemIt->more() && !typeOK )
6220 if ( elemType == SMDSAbs_Node )
6222 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
6226 elemIt = SMDS_ElemIteratorPtr();
6232 //=============================================================================
6233 namespace // Finding concurrent hypotheses
6234 //=============================================================================
6238 * \brief mapping of mesh dimension into shape type
6240 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
6242 TopAbs_ShapeEnum aType = TopAbs_SOLID;
6244 case 0: aType = TopAbs_VERTEX; break;
6245 case 1: aType = TopAbs_EDGE; break;
6246 case 2: aType = TopAbs_FACE; break;
6248 default:aType = TopAbs_SOLID; break;
6253 //-----------------------------------------------------------------------------
6255 * \brief Internal structure used to find concurrent submeshes
6257 * It represents a pair < submesh, concurrent dimension >, where
6258 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
6259 * with another submesh. In other words, it is dimension of a hypothesis assigned
6266 int _dim; //!< a dimension the algo can build (concurrent dimension)
6267 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
6268 TopTools_MapOfShape _shapeMap;
6269 SMESH_subMesh* _subMesh;
6270 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
6272 //-----------------------------------------------------------------------------
6273 // Return the algorithm
6274 const SMESH_Algo* GetAlgo() const
6275 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
6277 //-----------------------------------------------------------------------------
6279 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
6281 const TopoDS_Shape& theShape)
6283 _subMesh = (SMESH_subMesh*)theSubMesh;
6284 SetShape( theDim, theShape );
6287 //-----------------------------------------------------------------------------
6289 void SetShape(const int theDim,
6290 const TopoDS_Shape& theShape)
6293 _ownDim = SMESH_Gen::GetShapeDim(theShape);
6294 if (_dim >= _ownDim)
6295 _shapeMap.Add( theShape );
6297 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
6298 for( ; anExp.More(); anExp.Next() )
6299 _shapeMap.Add( anExp.Current() );
6303 //-----------------------------------------------------------------------------
6304 //! Check sharing of sub-shapes
6305 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
6306 const TopTools_MapOfShape& theToFind,
6307 const TopAbs_ShapeEnum theType)
6309 bool isShared = false;
6310 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
6311 for (; !isShared && anItr.More(); anItr.Next() )
6313 const TopoDS_Shape aSubSh = anItr.Key();
6314 // check for case when concurrent dimensions are same
6315 isShared = theToFind.Contains( aSubSh );
6316 // check for sub-shape with concurrent dimension
6317 TopExp_Explorer anExp( aSubSh, theType );
6318 for ( ; !isShared && anExp.More(); anExp.Next() )
6319 isShared = theToFind.Contains( anExp.Current() );
6324 //-----------------------------------------------------------------------------
6325 //! check algorithms
6326 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
6327 const SMESHDS_Hypothesis* theA2)
6329 if ( !theA1 || !theA2 ||
6330 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
6331 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
6332 return false; // one of the hypothesis is not algorithm
6333 // check algorithm names (should be equal)
6334 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
6338 //-----------------------------------------------------------------------------
6339 //! Check if sub-shape hypotheses are concurrent
6340 bool IsConcurrent(const SMESH_DimHyp* theOther) const
6342 if ( _subMesh == theOther->_subMesh )
6343 return false; // same sub-shape - should not be
6345 // if ( <own dim of either of submeshes> == <concurrent dim> &&
6346 // any of the two submeshes is not on COMPOUND shape )
6347 // -> no concurrency
6348 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
6349 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
6350 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
6351 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
6352 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
6355 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
6356 if ( !checkSubShape )
6359 // check algorithms to be same
6360 const SMESH_Algo* a1 = this->GetAlgo();
6361 const SMESH_Algo* a2 = theOther->GetAlgo();
6362 bool isSame = checkAlgo( a1, a2 );
6366 return false; // pb?
6367 return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency !
6370 // check hypothesises for concurrence (skip first as algorithm)
6372 // pointers should be same, because it is referened from mesh hypothesis partition
6373 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
6374 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
6375 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
6376 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
6378 // the submeshes are concurrent if their algorithms has different parameters
6379 return nbSame != theOther->_hypotheses.size() - 1;
6382 // Return true if algorithm of this SMESH_DimHyp is used if no
6383 // sub-mesh order is imposed by the user
6384 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
6386 // NeedDiscreteBoundary() algo has a higher priority
6387 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
6388 theOther->GetAlgo()->NeedDiscreteBoundary() )
6389 return !this->GetAlgo()->NeedDiscreteBoundary();
6391 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
6394 }; // end of SMESH_DimHyp
6395 //-----------------------------------------------------------------------------
6397 typedef list<const SMESH_DimHyp*> TDimHypList;
6399 //-----------------------------------------------------------------------------
6401 void addDimHypInstance(const int theDim,
6402 const TopoDS_Shape& theShape,
6403 const SMESH_Algo* theAlgo,
6404 const SMESH_subMesh* theSubMesh,
6405 const list <const SMESHDS_Hypothesis*>& theHypList,
6406 TDimHypList* theDimHypListArr )
6408 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
6409 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
6410 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
6411 dimHyp->_hypotheses.push_front(theAlgo);
6412 listOfdimHyp.push_back( dimHyp );
6415 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
6416 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
6417 theHypList.begin(), theHypList.end() );
6420 //-----------------------------------------------------------------------------
6421 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
6422 TDimHypList& theListOfConcurr)
6424 if ( theListOfConcurr.empty() )
6426 theListOfConcurr.push_back( theDimHyp );
6430 TDimHypList::iterator hypIt = theListOfConcurr.begin();
6431 while ( hypIt != theListOfConcurr.end() &&
6432 !theDimHyp->IsHigherPriorityThan( *hypIt ))
6434 theListOfConcurr.insert( hypIt, theDimHyp );
6438 //-----------------------------------------------------------------------------
6439 void findConcurrents(const SMESH_DimHyp* theDimHyp,
6440 const TDimHypList& theListOfDimHyp,
6441 TDimHypList& theListOfConcurrHyp,
6442 set<int>& theSetOfConcurrId )
6444 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
6445 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
6447 const SMESH_DimHyp* curDimHyp = *rIt;
6448 if ( curDimHyp == theDimHyp )
6449 break; // meet own dimHyp pointer in same dimension
6451 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
6452 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
6454 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
6459 //-----------------------------------------------------------------------------
6460 void unionLists(TListOfInt& theListOfId,
6461 TListOfListOfInt& theListOfListOfId,
6464 TListOfListOfInt::iterator it = theListOfListOfId.begin();
6465 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
6467 continue; //skip already treated lists
6468 // check if other list has any same submesh object
6469 TListOfInt& otherListOfId = *it;
6470 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
6471 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
6474 // union two lists (from source into target)
6475 TListOfInt::iterator it2 = otherListOfId.begin();
6476 for ( ; it2 != otherListOfId.end(); it2++ ) {
6477 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
6478 theListOfId.push_back(*it2);
6480 // clear source list
6481 otherListOfId.clear();
6484 //-----------------------------------------------------------------------------
6486 //! free memory allocated for dimension-hypothesis objects
6487 void removeDimHyps( TDimHypList* theArrOfList )
6489 for (int i = 0; i < 4; i++ ) {
6490 TDimHypList& listOfdimHyp = theArrOfList[i];
6491 TDimHypList::const_iterator it = listOfdimHyp.begin();
6492 for ( ; it != listOfdimHyp.end(); it++ )
6497 //-----------------------------------------------------------------------------
6499 * \brief find common submeshes with given submesh
6500 * \param theSubMeshList list of already collected submesh to check
6501 * \param theSubMesh given submesh to intersect with other
6502 * \param theCommonSubMeshes collected common submeshes
6504 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6505 const SMESH_subMesh* theSubMesh,
6506 set<const SMESH_subMesh*>& theCommon )
6510 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6511 for ( ; it != theSubMeshList.end(); it++ )
6512 theSubMesh->FindIntersection( *it, theCommon );
6513 theSubMeshList.push_back( theSubMesh );
6514 //theCommon.insert( theSubMesh );
6517 //-----------------------------------------------------------------------------
6518 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6520 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6521 for ( ; listsIt != smLists.end(); ++listsIt )
6523 const TListOfInt& smIDs = *listsIt;
6524 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6532 //=============================================================================
6534 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6536 //=============================================================================
6538 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6540 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6541 if ( isSubMeshInList( submeshID, anOrder ))
6544 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6545 return isSubMeshInList( submeshID, allConurrent );
6548 //=============================================================================
6550 * \brief Return submesh objects list in meshing order
6552 //=============================================================================
6554 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6556 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6558 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6560 return aResult._retn();
6562 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6563 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6564 anOrder.splice( anOrder.end(), allConurrent );
6567 TListOfListOfInt::iterator listIt = anOrder.begin();
6568 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6569 unionLists( *listIt, anOrder, listIndx + 1 );
6571 // convert submesh ids into interface instances
6572 // and dump command into python
6573 convertMeshOrder( anOrder, aResult, false );
6575 return aResult._retn();
6578 //=============================================================================
6580 * \brief Finds concurrent sub-meshes
6582 //=============================================================================
6584 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6586 TListOfListOfInt anOrder;
6587 ::SMESH_Mesh& mesh = GetImpl();
6589 // collect submeshes and detect concurrent algorithms and hypothesises
6590 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6592 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6593 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
6594 ::SMESH_subMesh* sm = (*i_sm).second;
6596 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6598 // list of assigned hypothesises
6599 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6600 // Find out dimensions where the submesh can be concurrent.
6601 // We define the dimensions by algo of each of hypotheses in hypList
6602 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6603 for( ; hypIt != hypList.end(); hypIt++ ) {
6604 SMESH_Algo* anAlgo = 0;
6605 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6606 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6607 // hyp it-self is algo
6608 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6610 // try to find algorithm with help of sub-shapes
6611 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6612 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6613 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6616 continue; // no algorithm assigned to a current submesh
6618 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6619 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
6621 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6622 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6623 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6625 } // end iterations on submesh
6627 // iterate on created dimension-hypotheses and check for concurrents
6628 for ( int i = 0; i < 4; i++ ) {
6629 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6630 // check for concurrents in own and other dimensions (step-by-step)
6631 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6632 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
6633 const SMESH_DimHyp* dimHyp = *dhIt;
6634 TDimHypList listOfConcurr;
6635 set<int> setOfConcurrIds;
6636 // looking for concurrents and collect into own list
6637 for ( int j = i; j < 4; j++ )
6638 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6639 // check if any concurrents found
6640 if ( listOfConcurr.size() > 0 ) {
6641 // add own submesh to list of concurrent
6642 addInOrderOfPriority( dimHyp, listOfConcurr );
6643 list<int> listOfConcurrIds;
6644 TDimHypList::iterator hypIt = listOfConcurr.begin();
6645 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6646 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6647 anOrder.push_back( listOfConcurrIds );
6652 removeDimHyps(dimHypListArr);
6654 // now, minimize the number of concurrent groups
6655 // Here we assume that lists of submeshes can have same submesh
6656 // in case of multi-dimension algorithms, as result
6657 // list with common submesh has to be united into one list
6659 TListOfListOfInt::iterator listIt = anOrder.begin();
6660 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6661 unionLists( *listIt, anOrder, listIndx + 1 );
6667 //=============================================================================
6669 * \brief Set submesh object order
6670 * \param theSubMeshArray submesh array order
6672 //=============================================================================
6674 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6677 _preMeshInfo->ForgetOrLoad();
6680 ::SMESH_Mesh& mesh = GetImpl();
6682 TPythonDump aPythonDump; // prevent dump of called methods
6683 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6685 TListOfListOfInt subMeshOrder;
6686 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6688 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6689 TListOfInt subMeshIds;
6691 aPythonDump << ", ";
6692 aPythonDump << "[ ";
6693 // Collect subMeshes which should be clear
6694 // do it list-by-list, because modification of submesh order
6695 // take effect between concurrent submeshes only
6696 set<const SMESH_subMesh*> subMeshToClear;
6697 list<const SMESH_subMesh*> subMeshList;
6698 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6700 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6702 aPythonDump << ", ";
6703 aPythonDump << subMesh;
6704 subMeshIds.push_back( subMesh->GetId() );
6705 // detect common parts of submeshes
6706 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6707 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6709 aPythonDump << " ]";
6710 subMeshOrder.push_back( subMeshIds );
6712 // clear collected sub-meshes
6713 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6714 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6715 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6717 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6718 if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748
6719 sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo
6722 aPythonDump << " ])";
6724 mesh.SetMeshOrder( subMeshOrder );
6727 SMESH::SMESH_Mesh_var me = _this();
6728 _gen_i->UpdateIcons( me );
6733 //=============================================================================
6735 * \brief Convert submesh ids into submesh interfaces
6737 //=============================================================================
6739 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6740 SMESH::submesh_array_array& theResOrder,
6741 const bool theIsDump)
6743 int nbSet = theIdsOrder.size();
6744 TPythonDump aPythonDump; // prevent dump of called methods
6746 aPythonDump << "[ ";
6747 theResOrder.length(nbSet);
6748 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6750 for( ; it != theIdsOrder.end(); it++ ) {
6751 // translate submesh identificators into submesh objects
6752 // takeing into account real number of concurrent lists
6753 const TListOfInt& aSubOrder = (*it);
6754 if (!aSubOrder.size())
6757 aPythonDump << "[ ";
6758 // convert shape indices into interfaces
6759 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6760 aResSubSet->length(aSubOrder.size());
6761 TListOfInt::const_iterator subIt = aSubOrder.begin();
6763 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6764 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6766 SMESH::SMESH_subMesh_var subMesh =
6767 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6770 aPythonDump << ", ";
6771 aPythonDump << subMesh;
6773 aResSubSet[ j++ ] = subMesh;
6776 aPythonDump << " ]";
6778 theResOrder[ listIndx++ ] = aResSubSet;
6780 // correct number of lists
6781 theResOrder.length( listIndx );
6784 // finilise python dump
6785 aPythonDump << " ]";
6786 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6790 namespace // utils used by SMESH_MeshPartDS
6793 * \brief Class used to access to protected data of SMDS_MeshInfo
6795 struct TMeshInfo : public SMDS_MeshInfo
6797 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6800 * \brief Element holing its ID only
6802 struct TElemID : public SMDS_LinearEdge
6804 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6808 //================================================================================
6810 // Implementation of SMESH_MeshPartDS
6812 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6813 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6815 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6816 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6819 _meshDS = mesh_i->GetImpl().GetMeshDS();
6821 SetPersistentId( _meshDS->GetPersistentId() );
6823 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6825 // <meshPart> is the whole mesh
6826 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6828 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6829 myGroupSet = _meshDS->GetGroups();
6834 SMESH::long_array_var anIDs = meshPart->GetIDs();
6835 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6836 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6838 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6839 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6840 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6845 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6846 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6847 if ( _elements[ e->GetType() ].insert( e ).second )
6850 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6851 while ( nIt->more() )
6853 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6854 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6861 ShapeToMesh( _meshDS->ShapeToMesh() );
6863 _meshDS = 0; // to enforce iteration on _elements and _nodes
6866 // -------------------------------------------------------------------------------------
6867 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6868 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6871 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6872 for ( ; partIt != meshPart.end(); ++partIt )
6873 if ( const SMDS_MeshElement * e = *partIt )
6874 if ( _elements[ e->GetType() ].insert( e ).second )
6877 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6878 while ( nIt->more() )
6880 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6881 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6887 // -------------------------------------------------------------------------------------
6888 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6890 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6892 TElemID elem( IDelem );
6893 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6894 if ( !_elements[ iType ].empty() )
6896 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6897 if ( it != _elements[ iType ].end() )
6902 // -------------------------------------------------------------------------------------
6903 bool SMESH_MeshPartDS::HasNumerationHoles()
6905 if ( _meshDS ) return _meshDS->HasNumerationHoles();
6907 return ( MinNodeID() != 1 ||
6908 MaxNodeID() != NbNodes() ||
6909 MinElementID() != 1 ||
6910 MaxElementID() != NbElements() );
6912 // -------------------------------------------------------------------------------------
6913 int SMESH_MeshPartDS::MaxNodeID() const
6915 if ( _meshDS ) return _meshDS->MaxNodeID();
6916 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID();
6918 // -------------------------------------------------------------------------------------
6919 int SMESH_MeshPartDS::MinNodeID() const
6921 if ( _meshDS ) return _meshDS->MinNodeID();
6922 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID();
6924 // -------------------------------------------------------------------------------------
6925 int SMESH_MeshPartDS::MaxElementID() const
6927 if ( _meshDS ) return _meshDS->MaxElementID();
6929 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6930 if ( !_elements[ iType ].empty() )
6931 maxID = Max( maxID, (*_elements[ iType ].rbegin())->GetID() );
6934 // -------------------------------------------------------------------------------------
6935 int SMESH_MeshPartDS::MinElementID() const
6937 if ( _meshDS ) return _meshDS->MinElementID();
6939 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6940 if ( !_elements[ iType ].empty() )
6941 minID = Min( minID, (*_elements[ iType ].begin())->GetID() );
6944 // -------------------------------------------------------------------------------------
6945 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6947 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6949 typedef SMDS_SetIterator
6950 <const SMDS_MeshElement*,
6951 TIDSortedElemSet::const_iterator,
6952 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6953 SMDS_MeshElement::GeomFilter
6956 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6958 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6959 _elements[type].end(),
6960 SMDS_MeshElement::GeomFilter( geomType )));
6962 // -------------------------------------------------------------------------------------
6963 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6965 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6967 typedef SMDS_SetIterator
6968 <const SMDS_MeshElement*,
6969 TIDSortedElemSet::const_iterator,
6970 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6971 SMDS_MeshElement::EntityFilter
6974 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6976 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6977 _elements[type].end(),
6978 SMDS_MeshElement::EntityFilter( entity )));
6980 // -------------------------------------------------------------------------------------
6981 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6983 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6984 if ( type == SMDSAbs_All && !_meshDS )
6986 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6988 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6989 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6991 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6993 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6994 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6996 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6997 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6999 // -------------------------------------------------------------------------------------
7000 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
7001 iterType SMESH_MeshPartDS::methName() const \
7003 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
7004 return _meshDS ? _meshDS->methName() : iterType \
7005 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
7007 // -------------------------------------------------------------------------------------
7008 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
7009 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
7010 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
7011 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
7012 #undef _GET_ITER_DEFINE
7014 // END Implementation of SMESH_MeshPartDS
7016 //================================================================================