1 // Copyright (C) 2007-2023 CEA, EDF, 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 and TooLargeForExport exception through SMESH_TRY
88 #define SMY_OWN_CATCH \
89 catch( SALOME::SALOME_Exception& se ) { throw se; } \
90 catch( ::SMESH_Mesh::TooLargeForExport& ex ) \
91 { SALOME::ExceptionStruct se = { \
93 CORBA::string_dup(SMESH_Comment("Mesh is too large for export in format ") << ex.what()), \
94 CORBA::string_dup(SMESH_Comment("format=") << ex.what() ), 0 }; \
95 throw SALOME::SALOME_Exception( se ); }
97 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
100 using SMESH::TPythonDump;
103 int SMESH_Mesh_i::_idGenerator = 0;
105 //=============================================================================
109 //=============================================================================
111 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
113 : SALOME::GenericObj_i( thePOA )
117 _id = _idGenerator++;
120 _previewEditor = NULL;
125 //=============================================================================
129 //=============================================================================
131 SMESH_Mesh_i::~SMESH_Mesh_i()
134 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
135 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
136 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
138 aGroup->UnRegister();
139 SMESH::SMESH_GroupBase_var( itGr->second );
144 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
145 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
146 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
148 aSubMesh->UnRegister();
149 SMESH::SMESH_subMesh_var( itSM->second );
151 _mapSubMeshIor.clear();
153 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
154 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
155 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
156 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
157 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
158 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
161 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
165 // clear cached shapes if no more meshes remain; (the cache is blame,
166 // together with publishing, of spent time increasing in issue 22874)
167 if ( _impl->NbMeshes() == 1 )
168 _gen_i->GetShapeReader()->ClearClientBuffer();
170 delete _editor; _editor = NULL;
171 delete _previewEditor; _previewEditor = NULL;
172 delete _impl; _impl = NULL;
173 delete _preMeshInfo; _preMeshInfo = NULL;
176 //=============================================================================
180 * Associate <this> mesh with <theShape> and put a reference
181 * to <theShape> into the current study;
182 * the previous shape is substituted by the new one.
184 //=============================================================================
186 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
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()
210 Unexpect aCatch(SALOME_SalomeException);
213 res = _impl->HasShapeToMesh();
215 catch(SALOME_Exception & S_ex) {
216 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
221 //================================================================================
223 * \brief Return the shape to mesh
225 //================================================================================
227 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
229 Unexpect aCatch(SALOME_SalomeException);
230 GEOM::GEOM_Object_var aShapeObj;
232 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
235 aShapeObj = _gen_i->ShapeToGeomObject( S );
236 if ( aShapeObj->_is_nil() )
238 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
239 // find GEOM_Object by entry (IPAL52735)
240 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
241 for ( ; data != _geomGroupData.end(); ++data )
242 if ( data->_smeshObject->_is_equivalent( _this() ))
244 SALOMEDS::SObject_wrap so = _gen_i->getStudyServant()->FindObjectID( data->_groupEntry.c_str() );
245 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
246 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
252 catch(SALOME_Exception & S_ex) {
253 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
255 return aShapeObj._retn();
258 //================================================================================
260 * \brief Return false if the mesh is not yet fully loaded from the study file
262 //================================================================================
264 CORBA::Boolean SMESH_Mesh_i::IsLoaded()
266 Unexpect aCatch(SALOME_SalomeException);
267 return !_preMeshInfo;
270 //================================================================================
272 * \brief Load full mesh data from the study file
274 //================================================================================
276 void SMESH_Mesh_i::Load()
278 Unexpect aCatch(SALOME_SalomeException);
280 _preMeshInfo->FullLoadFromFile();
283 //================================================================================
285 * \brief Remove all nodes and elements
287 //================================================================================
289 void SMESH_Mesh_i::Clear()
291 Unexpect aCatch(SALOME_SalomeException);
293 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
297 //CheckGeomGroupModif(); // issue 20145
299 catch(SALOME_Exception & S_ex) {
300 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
303 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
305 SMESH::SMESH_Mesh_var mesh = _this();
306 _gen_i->UpdateIcons( mesh );
309 //================================================================================
311 * \brief Remove all nodes and elements for indicated shape
313 //================================================================================
315 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
317 Unexpect aCatch(SALOME_SalomeException);
319 _preMeshInfo->FullLoadFromFile();
322 _impl->ClearSubMesh( ShapeID );
324 catch(SALOME_Exception & S_ex) {
325 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
327 _impl->GetMeshDS()->Modified();
329 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
332 //=============================================================================
334 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
336 //=============================================================================
338 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
340 SMESH::DriverMED_ReadStatus res;
343 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
344 res = SMESH::DRS_OK; break;
345 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
346 res = SMESH::DRS_EMPTY; break;
347 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
348 res = SMESH::DRS_WARN_RENUMBER; break;
349 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
350 res = SMESH::DRS_WARN_SKIP_ELEM; break;
351 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
352 res = SMESH::DRS_WARN_DESCENDING; break;
353 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
355 res = SMESH::DRS_FAIL; break;
360 //=============================================================================
362 * Convert ::SMESH_ComputeError to SMESH::ComputeError
364 //=============================================================================
366 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
368 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
369 errVar->subShapeID = -1;
370 errVar->hasBadMesh = false;
372 if ( !errorPtr || errorPtr->IsOK() )
374 errVar->code = SMESH::COMPERR_OK;
378 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
379 errVar->comment = errorPtr->myComment.c_str();
381 return errVar._retn();
384 //=============================================================================
388 * Import mesh data from MED file
390 //=============================================================================
392 SMESH::DriverMED_ReadStatus
393 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
395 Unexpect aCatch(SALOME_SalomeException);
398 status = _impl->MEDToMesh( theFileName, theMeshName );
400 catch( SALOME_Exception& S_ex ) {
401 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
404 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
407 CreateGroupServants();
409 int major, minor, release;
410 major = minor = release = 0;
411 MED::GetMEDVersion(theFileName, major, minor, release);
412 _medFileInfo = new SMESH::MedFileInfo();
413 _medFileInfo->fileName = theFileName;
414 _medFileInfo->fileSize = 0;
415 _medFileInfo->major = major;
416 _medFileInfo->minor = minor;
417 _medFileInfo->release = release;
418 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
420 return ConvertDriverMEDReadStatus(status);
423 //================================================================================
425 * \brief Import mesh data from the CGNS file
427 //================================================================================
429 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
430 const int theMeshIndex,
431 std::string& theMeshName )
433 Unexpect aCatch(SALOME_SalomeException);
436 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
438 catch( SALOME_Exception& S_ex ) {
439 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
442 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
445 CreateGroupServants();
447 _medFileInfo = new SMESH::MedFileInfo();
448 _medFileInfo->fileName = theFileName;
449 _medFileInfo->major = 0;
450 _medFileInfo->minor = 0;
451 _medFileInfo->release = 0;
452 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
454 return ConvertDriverMEDReadStatus(status);
457 //================================================================================
459 * \brief Return string representation of a MED file version comprising nbDigits
461 //================================================================================
463 char* SMESH_Mesh_i::GetVersionString(CORBA::Long minor, CORBA::Short nbDigits)
465 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(minor, nbDigits);
466 return CORBA::string_dup( ver.c_str() );
469 //================================================================================
471 * Return the list of med versions compatibles for write/append,
472 * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32)
474 //================================================================================
476 SMESH::long_array* SMESH_Mesh_i::GetMEDVersionsCompatibleForAppend()
478 SMESH::long_array_var aResult = new SMESH::long_array();
479 std::vector<int> mvok = MED::GetMEDVersionsAppendCompatible();
480 long nbver = mvok.size();
481 aResult->length( nbver );
482 for ( int i = 0; i < nbver; i++ )
483 aResult[i] = mvok[i];
484 return aResult._retn();
487 //=============================================================================
491 * Import mesh data from MED file
493 //=============================================================================
495 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
499 // Read mesh with name = <theMeshName> into SMESH_Mesh
500 _impl->UNVToMesh( theFileName );
502 CreateGroupServants();
504 _medFileInfo = new SMESH::MedFileInfo();
505 _medFileInfo->fileName = theFileName;
506 _medFileInfo->major = 0;
507 _medFileInfo->minor = 0;
508 _medFileInfo->release = 0;
509 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
511 SMESH_CATCH( SMESH::throwCorbaException );
516 //=============================================================================
520 * Import mesh data from STL file
522 //=============================================================================
524 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
528 // Read mesh with name = <theMeshName> into SMESH_Mesh
529 std::string name = _impl->STLToMesh( theFileName );
532 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
533 _gen_i->SetName( meshSO, name.c_str() );
535 _medFileInfo = new SMESH::MedFileInfo();
536 _medFileInfo->fileName = theFileName;
537 _medFileInfo->major = 0;
538 _medFileInfo->minor = 0;
539 _medFileInfo->release = 0;
540 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
542 SMESH_CATCH( SMESH::throwCorbaException );
547 //================================================================================
549 * \brief Function used in SMESH_CATCH by ImportGMFFile()
551 //================================================================================
555 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
557 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
561 //================================================================================
563 * \brief Import data from a GMF file and return an error description
565 //================================================================================
567 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
568 bool theMakeRequiredGroups )
570 SMESH_ComputeErrorPtr error;
573 #define SMESH_CAUGHT error =
576 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
578 _medFileInfo = new SMESH::MedFileInfo();
579 _medFileInfo->fileName = theFileName;
580 _medFileInfo->major = 0;
581 _medFileInfo->minor = 0;
582 _medFileInfo->release = 0;
583 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
585 SMESH_CATCH( exceptionToComputeError );
589 CreateGroupServants();
591 return ConvertComputeError( error );
594 //=============================================================================
596 * \brief Convert SMESH_Hypothesis::Hypothesis_Status into SMESH::Hypothesis_Status
598 //=============================================================================
600 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
602 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
603 (SMESH_Hypothesis::Hypothesis_Status theStatus)
606 RETURNCASE( HYP_OK );
607 RETURNCASE( HYP_MISSING );
608 RETURNCASE( HYP_CONCURRENT );
609 RETURNCASE( HYP_BAD_PARAMETER );
610 RETURNCASE( HYP_HIDDEN_ALGO );
611 RETURNCASE( HYP_HIDING_ALGO );
612 RETURNCASE( HYP_UNKNOWN_FATAL );
613 RETURNCASE( HYP_INCOMPATIBLE );
614 RETURNCASE( HYP_NOTCONFORM );
615 RETURNCASE( HYP_ALREADY_EXIST );
616 RETURNCASE( HYP_BAD_DIM );
617 RETURNCASE( HYP_BAD_SUBSHAPE );
618 RETURNCASE( HYP_BAD_GEOMETRY );
619 RETURNCASE( HYP_NEED_SHAPE );
620 RETURNCASE( HYP_INCOMPAT_HYPS );
623 return SMESH::HYP_UNKNOWN_FATAL;
626 //=============================================================================
630 * Call internal addHypothesis() and then add a reference to <anHyp> under
631 * the SObject actually having a reference to <aSubShape>.
632 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
634 //=============================================================================
636 SMESH::Hypothesis_Status
637 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
638 SMESH::SMESH_Hypothesis_ptr anHyp,
639 CORBA::String_out anErrorText)
641 Unexpect aCatch(SALOME_SalomeException);
643 const smIdType prevNbMeshEnt = NbNodes() + NbElements();
646 _preMeshInfo->ForgetOrLoad();
649 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
650 anErrorText = error.c_str();
652 SMESH::SMESH_Mesh_var mesh( _this() );
653 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
655 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
657 //int newNbMeshEnt = _impl->NbNodes() + _impl->GetMeshDS()->NbElements();
658 if ( prevNbMeshEnt > 0 /*newNbMeshEnt != prevNbMeshEnt*/ )
659 _gen_i->UpdateIcons( mesh );
661 MESSAGE( " AddHypothesis(): status = " << status );
663 // Update Python script
664 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
665 << aSubShape << ", " << anHyp << " )";
667 return ConvertHypothesisStatus(status);
670 //================================================================================
672 * \brief Create a sub-mesh and add a hypothesis to it
674 //================================================================================
676 SMESH_Hypothesis::Hypothesis_Status
677 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
678 SMESH::SMESH_Hypothesis_ptr anHyp,
679 std::string* anErrorText)
681 MESSAGE("addHypothesis");
683 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
684 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
686 if (CORBA::is_nil( anHyp ))
687 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
689 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
692 TopoDS_Shape myLocSubShape;
693 //use PseudoShape in case if mesh has no shape
695 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
697 myLocSubShape = _impl->GetShapeToMesh();
699 const int hypId = anHyp->GetId();
701 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
702 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
704 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
706 // assure there is a corresponding submesh
707 if ( !_impl->IsMainShape( myLocSubShape )) {
708 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
709 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
710 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
713 else if ( anErrorText )
715 *anErrorText = error;
718 catch(SALOME_Exception & S_ex)
720 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
725 //================================================================================
727 * \brief Un-assign a hypothesis from a sub-mesh dedicate to the given sub-shape
729 //================================================================================
731 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
732 SMESH::SMESH_Hypothesis_ptr anHyp)
734 Unexpect aCatch(SALOME_SalomeException);
736 _preMeshInfo->ForgetOrLoad();
738 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
739 SMESH::SMESH_Mesh_var mesh = _this();
741 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
743 _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
744 _gen_i->UpdateIcons( mesh );
746 // Update Python script
747 if(_impl->HasShapeToMesh())
748 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
749 << aSubShape << ", " << anHyp << " )";
751 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
754 return ConvertHypothesisStatus(status);
757 //=============================================================================
759 * \brief Un-assign a hypothesis from a sub-mesh dedicate to the given sub-shape
761 //=============================================================================
763 SMESH_Hypothesis::Hypothesis_Status
764 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
765 SMESH::SMESH_Hypothesis_ptr anHyp)
767 MESSAGE("removeHypothesis()");
769 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
770 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
772 if (CORBA::is_nil( anHyp ))
773 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
776 _preMeshInfo->ForgetOrLoad();
778 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
781 TopoDS_Shape myLocSubShape;
782 //use PseudoShape in case if mesh has no shape
783 if( _impl->HasShapeToMesh() )
784 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
786 myLocSubShape = _impl->GetShapeToMesh();
788 const int hypId = anHyp->GetId();
789 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
790 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
792 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
796 catch(SALOME_Exception & S_ex)
798 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
803 //================================================================================
805 * \brief Return hypotheses assigned to a given sub-shape
807 //================================================================================
809 SMESH::ListOfHypothesis *
810 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
812 Unexpect aCatch(SALOME_SalomeException);
813 MESSAGE("GetHypothesisList");
814 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
815 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
817 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
820 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
821 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
822 myLocSubShape = _impl->GetShapeToMesh();
823 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
824 int i = 0, n = aLocalList.size();
827 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
828 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
829 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
831 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
832 if ( id_hypptr != _mapHypo.end() )
833 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
837 catch(SALOME_Exception & S_ex) {
838 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
841 return aList._retn();
844 //================================================================================
846 * \brief Return sub-meshes
848 //================================================================================
850 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes()
852 Unexpect aCatch(SALOME_SalomeException);
853 MESSAGE("GetSubMeshes");
855 SMESH::submesh_array_var aList = new SMESH::submesh_array();
858 TPythonDump aPythonDump;
859 if ( !_mapSubMeshIor.empty() )
863 aList->length( _mapSubMeshIor.size() );
865 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
866 for ( ; it != _mapSubMeshIor.end(); it++ ) {
867 if ( CORBA::is_nil( it->second )) continue;
868 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
870 if (i > 1) aPythonDump << ", ";
871 aPythonDump << it->second;
875 catch(SALOME_Exception & S_ex) {
876 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
879 // Update Python script
880 if ( !_mapSubMeshIor.empty() )
881 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
883 return aList._retn();
886 //================================================================================
888 * \brief Create and return a sub-mesh on the given sub-shape
890 //================================================================================
892 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
893 const char* theName )
895 Unexpect aCatch(SALOME_SalomeException);
896 if (CORBA::is_nil(aSubShape))
897 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
899 SMESH::SMESH_subMesh_var subMesh;
900 SMESH::SMESH_Mesh_var aMesh = _this();
902 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
904 //Get or Create the SMESH_subMesh object implementation
906 TopoDS_Iterator it( myLocSubShape );
907 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
908 bool isValidSub = ( subMeshId || _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ));
909 if ( isValidSub && myLocSubShape.ShapeType() == TopAbs_COMPOUND )
910 isValidSub = !it.Value().IsSame( _impl->GetShapeToMesh() );
914 THROW_SALOME_CORBA_EXCEPTION("Not a sub-shape of the main shape", SALOME::BAD_PARAM);
916 subMesh = getSubMesh( subMeshId );
918 // create a new subMesh object servant if there is none for the shape
919 if ( subMesh->_is_nil() )
920 subMesh = createSubMesh( aSubShape );
921 if ( _gen_i->CanPublishInStudy( subMesh ))
923 SALOMEDS::SObject_wrap aSO =
924 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
925 if ( !aSO->_is_nil()) {
926 // Update Python script
927 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
928 << aSubShape << ", '" << theName << "' )";
932 catch(SALOME_Exception & S_ex) {
933 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
935 return subMesh._retn();
938 //================================================================================
940 * \brief Remove a sub-mesh
942 //================================================================================
944 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
948 if ( theSubMesh->_is_nil() )
951 GEOM::GEOM_Object_var aSubShape;
952 // Remove submesh's SObject
953 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
954 if ( !anSO->_is_nil() ) {
955 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
956 SALOMEDS::SObject_wrap anObj, aRef;
957 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
958 anObj->ReferencedObject( aRef.inout() ))
960 CORBA::Object_var obj = aRef->GetObject();
961 aSubShape = GEOM::GEOM_Object::_narrow( obj );
963 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
964 // aSubShape = theSubMesh->GetSubShape();
966 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
967 builder->RemoveObjectWithChildren( anSO );
969 // Update Python script
970 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
973 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
975 _preMeshInfo->ForgetOrLoad();
977 SMESH_CATCH( SMESH::throwCorbaException );
980 //================================================================================
982 * \brief Create a standalone group
984 //================================================================================
986 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
987 const char* theName )
989 Unexpect aCatch(SALOME_SalomeException);
991 _preMeshInfo->FullLoadFromFile();
993 SMESH::SMESH_Group_var aNewGroup =
994 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
996 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
998 SMESH::SMESH_Mesh_var mesh = _this();
999 SALOMEDS::SObject_wrap aSO =
1000 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
1001 if ( !aSO->_is_nil())
1002 // Update Python script
1003 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
1004 << theElemType << ", '" << theName << "' )";
1006 return aNewGroup._retn();
1009 //================================================================================
1011 * \brief Create a group based on the given geometry
1013 //================================================================================
1015 SMESH::SMESH_GroupOnGeom_ptr
1016 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
1017 const char* theName,
1018 GEOM::GEOM_Object_ptr theGeomObj)
1020 Unexpect aCatch(SALOME_SalomeException);
1022 _preMeshInfo->FullLoadFromFile();
1024 SMESH::SMESH_GroupOnGeom_var aNewGroup;
1026 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
1027 if ( !aShape.IsNull() )
1030 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, /*id=*/-1, aShape ));
1032 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1034 SMESH::SMESH_Mesh_var mesh = _this();
1035 SALOMEDS::SObject_wrap aSO =
1036 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
1037 if ( !aSO->_is_nil())
1038 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
1039 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
1043 return aNewGroup._retn();
1046 //================================================================================
1048 * \brief Creates a group whose contents is defined by filter
1049 * \param theElemType - group type
1050 * \param theName - group name
1051 * \param theFilter - the filter
1052 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1054 //================================================================================
1056 SMESH::SMESH_GroupOnFilter_ptr
1057 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1058 const char* theName,
1059 SMESH::Filter_ptr theFilter )
1061 Unexpect aCatch(SALOME_SalomeException);
1063 _preMeshInfo->FullLoadFromFile();
1065 if ( CORBA::is_nil( theFilter ))
1066 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1068 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1070 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1072 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1073 ( createGroup( theElemType, theName, /*id=*/-1, TopoDS_Shape(), predicate ));
1076 if ( !aNewGroup->_is_nil() )
1077 aNewGroup->SetFilter( theFilter );
1079 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1081 SMESH::SMESH_Mesh_var mesh = _this();
1082 SALOMEDS::SObject_wrap aSO =
1083 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1085 if ( !aSO->_is_nil())
1086 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1087 << theElemType << ", '" << theName << "', " << theFilter << " )";
1089 return aNewGroup._retn();
1092 //================================================================================
1094 * \brief Remove a group
1096 //================================================================================
1098 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1100 if ( theGroup->_is_nil() )
1105 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1109 if ( aGroup->GetMeshServant() != this )
1110 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroup(): group does not belong to this mesh",
1111 SALOME::BAD_PARAM );
1113 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1114 if ( !aGroupSO->_is_nil() )
1116 // Update Python script
1117 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1119 // Remove group's SObject
1120 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::GetSMESHGen()->getStudyServant()->NewBuilder();
1121 builder->RemoveObjectWithChildren( aGroupSO );
1123 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1125 // Remove the group from SMESH data structures
1126 removeGroup( aGroup->GetLocalID() );
1128 SMESH_CATCH( SMESH::throwCorbaException );
1131 //=============================================================================
1133 * Remove group with its contents
1135 //=============================================================================
1137 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1141 _preMeshInfo->FullLoadFromFile();
1143 if ( theGroup->_is_nil() )
1146 SMESH_GroupBase_i* groupImpl = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup );
1147 if ( !groupImpl || groupImpl->GetMeshServant() != this )
1148 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroupWithContents(): group does not belong to this mesh",
1151 vector<smIdType> nodeIds; // to remove nodes becoming free
1152 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1153 if ( !isNodal && !theGroup->IsEmpty() )
1155 SMESH::smIdType elemID = theGroup->GetID( 1 );
1156 int nbElemNodes = GetElemNbNodes( elemID );
1157 if ( nbElemNodes > 0 )
1158 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1161 // Retrieve contents
1162 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1163 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1164 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1165 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1166 elems.assign( elemBeg, elemEnd );
1168 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1171 RemoveGroup( theGroup );
1174 for ( size_t i = 0; i < elems.size(); ++i )
1176 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1180 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1181 nodeIds.push_back( nIt->next()->GetID() );
1183 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1187 _impl->GetMeshDS()->RemoveElement( elems[i] );
1191 // Remove free nodes
1192 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1193 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1194 if ( n->NbInverseElements() == 0 )
1195 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1197 _impl->GetMeshDS()->Modified();
1198 _impl->SetIsModified( true );
1200 // Update Python script (theGroup must be alive for this)
1201 pyDump << SMESH::SMESH_Mesh_var(_this())
1202 << ".RemoveGroupWithContents( " << theGroup << " )";
1204 SMESH_CATCH( SMESH::throwCorbaException );
1207 //================================================================================
1209 * \brief Get the list of groups existing in the mesh
1210 * \retval SMESH::ListOfGroups * - list of groups
1212 //================================================================================
1214 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups()
1216 Unexpect aCatch(SALOME_SalomeException);
1217 MESSAGE("GetGroups");
1219 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1222 TPythonDump aPythonDump;
1223 if ( !_mapGroups.empty() )
1225 aPythonDump << "[ ";
1227 aList->length( _mapGroups.size() );
1229 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1230 for ( ; it != _mapGroups.end(); it++ ) {
1231 if ( CORBA::is_nil( it->second )) continue;
1232 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1234 if (i > 1) aPythonDump << ", ";
1235 aPythonDump << it->second;
1239 catch(SALOME_Exception & S_ex) {
1240 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1242 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1244 return aList._retn();
1247 //=============================================================================
1249 * Get number of groups existing in the mesh
1251 //=============================================================================
1253 CORBA::Long SMESH_Mesh_i::NbGroups()
1255 Unexpect aCatch(SALOME_SalomeException);
1256 return _mapGroups.size();
1259 //=============================================================================
1261 * New group including all mesh elements present in initial groups is created.
1263 //=============================================================================
1265 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1266 SMESH::SMESH_GroupBase_ptr theGroup2,
1267 const char* theName )
1269 SMESH::SMESH_Group_var aResGrp;
1273 _preMeshInfo->FullLoadFromFile();
1275 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1276 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1278 if ( theGroup1->GetType() != theGroup2->GetType() )
1279 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1284 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1285 if ( aResGrp->_is_nil() )
1286 return SMESH::SMESH_Group::_nil();
1288 aResGrp->AddFrom( theGroup1 );
1289 aResGrp->AddFrom( theGroup2 );
1291 // Update Python script
1292 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1293 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1295 SMESH_CATCH( SMESH::throwCorbaException );
1297 return aResGrp._retn();
1300 //=============================================================================
1302 * \brief New group including all mesh elements present in initial groups is created.
1303 * \param theGroups list of groups
1304 * \param theName name of group to be created
1305 * \return pointer to the new group
1307 //=============================================================================
1309 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1310 const char* theName )
1312 SMESH::SMESH_Group_var aResGrp;
1315 _preMeshInfo->FullLoadFromFile();
1318 return SMESH::SMESH_Group::_nil();
1323 SMESH::ElementType aType = SMESH::ALL;
1324 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1326 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1327 if ( CORBA::is_nil( aGrp ) )
1329 if ( aType == SMESH::ALL )
1330 aType = aGrp->GetType();
1331 else if ( aType != aGrp->GetType() )
1332 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1335 if ( aType == SMESH::ALL )
1336 return SMESH::SMESH_Group::_nil();
1341 aResGrp = CreateGroup( aType, theName );
1342 if ( aResGrp->_is_nil() )
1343 return SMESH::SMESH_Group::_nil();
1345 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1346 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1348 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1349 if ( !CORBA::is_nil( aGrp ) )
1351 aResGrp->AddFrom( aGrp );
1352 if ( g > 0 ) pyDump << ", ";
1356 pyDump << " ], '" << theName << "' )";
1358 SMESH_CATCH( SMESH::throwCorbaException );
1360 return aResGrp._retn();
1363 //=============================================================================
1365 * New group is created. All mesh elements that are
1366 * present in both initial groups are added to the new one.
1368 //=============================================================================
1370 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1371 SMESH::SMESH_GroupBase_ptr theGroup2,
1372 const char* theName )
1374 SMESH::SMESH_Group_var aResGrp;
1379 _preMeshInfo->FullLoadFromFile();
1381 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1382 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1384 if ( theGroup1->GetType() != theGroup2->GetType() )
1385 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1389 // Create Intersection
1390 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1391 if ( aResGrp->_is_nil() )
1392 return aResGrp._retn();
1394 SMESHDS_GroupBase* groupDS1 = 0;
1395 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1396 groupDS1 = grp_i->GetGroupDS();
1398 SMESHDS_GroupBase* groupDS2 = 0;
1399 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1400 groupDS2 = grp_i->GetGroupDS();
1402 SMESHDS_Group* resGroupDS = 0;
1403 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1404 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1406 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1408 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1409 while ( elemIt1->more() )
1411 const SMDS_MeshElement* e = elemIt1->next();
1412 if ( groupDS2->Contains( e ))
1413 resGroupDS->SMDSGroup().Add( e );
1416 // Update Python script
1417 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1418 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1420 SMESH_CATCH( SMESH::throwCorbaException );
1422 return aResGrp._retn();
1425 //=============================================================================
1427 \brief Intersect list of groups. New group is created. All mesh elements that
1428 are present in all initial groups simultaneously are added to the new one.
1429 \param theGroups list of groups
1430 \param theName name of group to be created
1431 \return pointer on the group
1433 //=============================================================================
1435 SMESH::SMESH_Group_ptr
1436 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1437 const char* theName )
1439 SMESH::SMESH_Group_var aResGrp;
1444 _preMeshInfo->FullLoadFromFile();
1447 return SMESH::SMESH_Group::_nil();
1449 // check types and get SMESHDS_GroupBase's
1450 SMESH::ElementType aType = SMESH::ALL;
1451 vector< SMESHDS_GroupBase* > groupVec;
1452 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1454 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1455 if ( CORBA::is_nil( aGrp ) )
1457 if ( aType == SMESH::ALL )
1458 aType = aGrp->GetType();
1459 else if ( aType != aGrp->GetType() )
1460 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1463 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1464 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1466 if ( grpDS->IsEmpty() )
1471 groupVec.push_back( grpDS );
1474 if ( aType == SMESH::ALL ) // all groups are nil
1475 return SMESH::SMESH_Group::_nil();
1480 aResGrp = CreateGroup( aType, theName );
1482 SMESHDS_Group* resGroupDS = 0;
1483 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1484 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1485 if ( !resGroupDS || groupVec.empty() )
1486 return aResGrp._retn();
1489 size_t i, nb = groupVec.size();
1490 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1491 while ( elemIt1->more() )
1493 const SMDS_MeshElement* e = elemIt1->next();
1495 for ( i = 1; ( i < nb && inAll ); ++i )
1496 inAll = groupVec[i]->Contains( e );
1499 resGroupDS->SMDSGroup().Add( e );
1502 // Update Python script
1503 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1504 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1506 SMESH_CATCH( SMESH::throwCorbaException );
1508 return aResGrp._retn();
1511 //=============================================================================
1513 * New group is created. All mesh elements that are present in
1514 * a main group but is not present in a tool group are added to the new one
1516 //=============================================================================
1518 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1519 SMESH::SMESH_GroupBase_ptr theGroup2,
1520 const char* theName )
1522 SMESH::SMESH_Group_var aResGrp;
1527 _preMeshInfo->FullLoadFromFile();
1529 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1530 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1532 if ( theGroup1->GetType() != theGroup2->GetType() )
1533 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1537 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1538 if ( aResGrp->_is_nil() )
1539 return aResGrp._retn();
1541 SMESHDS_GroupBase* groupDS1 = 0;
1542 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1543 groupDS1 = grp_i->GetGroupDS();
1545 SMESHDS_GroupBase* groupDS2 = 0;
1546 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1547 groupDS2 = grp_i->GetGroupDS();
1549 SMESHDS_Group* resGroupDS = 0;
1550 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1551 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1553 if ( groupDS1 && groupDS2 && resGroupDS )
1555 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1556 while ( elemIt1->more() )
1558 const SMDS_MeshElement* e = elemIt1->next();
1559 if ( !groupDS2->Contains( e ))
1560 resGroupDS->SMDSGroup().Add( e );
1563 // Update Python script
1564 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1565 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1567 SMESH_CATCH( SMESH::throwCorbaException );
1569 return aResGrp._retn();
1572 //=============================================================================
1574 \brief Cut lists of groups. New group is created. All mesh elements that are
1575 present in main groups but do not present in tool groups are added to the new one
1576 \param theMainGroups list of main groups
1577 \param theToolGroups list of tool groups
1578 \param theName name of group to be created
1579 \return pointer on the group
1581 //=============================================================================
1583 SMESH::SMESH_Group_ptr
1584 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1585 const SMESH::ListOfGroups& theToolGroups,
1586 const char* theName )
1588 SMESH::SMESH_Group_var aResGrp;
1593 _preMeshInfo->FullLoadFromFile();
1596 return SMESH::SMESH_Group::_nil();
1598 // check types and get SMESHDS_GroupBase's
1599 SMESH::ElementType aType = SMESH::ALL;
1600 vector< SMESHDS_GroupBase* > toolGroupVec;
1601 vector< SMDS_ElemIteratorPtr > mainIterVec;
1603 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1605 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1606 if ( CORBA::is_nil( aGrp ) )
1608 if ( aType == SMESH::ALL )
1609 aType = aGrp->GetType();
1610 else if ( aType != aGrp->GetType() )
1611 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1613 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1614 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1615 if ( !grpDS->IsEmpty() )
1616 mainIterVec.push_back( grpDS->GetElements() );
1618 if ( aType == SMESH::ALL ) // all main groups are nil
1619 return SMESH::SMESH_Group::_nil();
1620 if ( mainIterVec.empty() ) // all main groups are empty
1621 return aResGrp._retn();
1623 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1625 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1626 if ( CORBA::is_nil( aGrp ) )
1628 if ( aType != aGrp->GetType() )
1629 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1631 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1632 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1633 toolGroupVec.push_back( grpDS );
1639 aResGrp = CreateGroup( aType, theName );
1641 SMESHDS_Group* resGroupDS = 0;
1642 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1643 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1645 return aResGrp._retn();
1648 size_t i, nb = toolGroupVec.size();
1649 SMDS_ElemIteratorPtr mainElemIt
1650 ( new SMDS_IteratorOnIterators
1651 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1652 while ( mainElemIt->more() )
1654 const SMDS_MeshElement* e = mainElemIt->next();
1656 for ( i = 0; ( i < nb && !isIn ); ++i )
1657 isIn = toolGroupVec[i]->Contains( e );
1660 resGroupDS->SMDSGroup().Add( e );
1663 // Update Python script
1664 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1665 << ".CutListOfGroups( " << theMainGroups << ", "
1666 << theToolGroups << ", '" << theName << "' )";
1668 SMESH_CATCH( SMESH::throwCorbaException );
1670 return aResGrp._retn();
1673 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1675 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int /*nbCorners*/,
1676 bool & toStopChecking )
1678 toStopChecking = ( nbCommon < nbChecked );
1679 return nbCommon == nbNodes;
1681 bool isMainNodesCommon(int nbChecked, int nbCommon, int /*nbNodes*/, int nbCorners,
1682 bool & toStopChecking )
1684 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1685 return nbCommon == nbCorners;
1687 bool isAtLeastOneNodeCommon(int /*nbChecked*/, int nbCommon, int /*nbNodes*/, int /*nbCorners*/,
1688 bool & /*toStopChecking*/ )
1690 return nbCommon > 0;
1692 bool isMajorityOfNodesCommon(int /*nbChecked*/, int nbCommon, int nbNodes, int /*nbCorners*/,
1693 bool & /*toStopChecking*/ )
1695 return nbCommon >= (nbNodes+1) / 2;
1699 //=============================================================================
1701 * Create a group of entities basing on nodes of other groups.
1702 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1703 * \param [in] anElemType - a type of elements to include to the new group.
1704 * \param [in] theName - a name of the new group.
1705 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1706 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1707 * new group provided that it is based on nodes of an element of \a aListOfGroups
1708 * \return SMESH_Group - the created group
1710 // IMP 19939, bug 22010, IMP 22635
1711 //=============================================================================
1713 SMESH::SMESH_Group_ptr
1714 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1715 SMESH::ElementType theElemType,
1716 const char* theName,
1717 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1718 CORBA::Boolean theUnderlyingOnly)
1720 SMESH::SMESH_Group_var aResGrp;
1724 _preMeshInfo->FullLoadFromFile();
1726 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1728 if ( !theName || !aMeshDS )
1729 return SMESH::SMESH_Group::_nil();
1731 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1733 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1734 SMESH_Comment nbCoNoStr( "SMESH.");
1735 switch ( theNbCommonNodes ) {
1736 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1737 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1738 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1739 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1740 default: return aResGrp._retn();
1742 int nbChecked, nbCommon, nbNodes, nbCorners;
1748 aResGrp = CreateGroup( theElemType, theName );
1749 if ( aResGrp->_is_nil() )
1750 return SMESH::SMESH_Group::_nil();
1752 SMESHDS_GroupBase* groupBaseDS =
1753 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1754 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1756 vector<bool> isNodeInGroups;
1758 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1760 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1761 if ( CORBA::is_nil( aGrp ) )
1763 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1764 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1767 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1768 if ( !elIt ) continue;
1770 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1772 while ( elIt->more() ) {
1773 const SMDS_MeshElement* el = elIt->next();
1774 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1775 while ( nIt->more() )
1776 resGroupCore.Add( nIt->next() );
1779 // get elements of theElemType based on nodes of every element of group
1780 else if ( theUnderlyingOnly )
1782 while ( elIt->more() )
1784 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1785 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1786 TIDSortedElemSet checkedElems;
1787 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1788 while ( nIt->more() )
1790 const SMDS_MeshNode* n = nIt->next();
1791 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1792 // check nodes of elements of theElemType around el
1793 while ( elOfTypeIt->more() )
1795 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1796 if ( !checkedElems.insert( elOfType ).second ) continue;
1797 nbNodes = elOfType->NbNodes();
1798 nbCorners = elOfType->NbCornerNodes();
1800 bool toStopChecking = false;
1801 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1802 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1803 if ( elNodes.count( nIt2->next() ) &&
1804 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1806 resGroupCore.Add( elOfType );
1813 // get all nodes of elements of groups
1816 while ( elIt->more() )
1818 const SMDS_MeshElement* el = elIt->next(); // an element of group
1819 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1820 while ( nIt->more() )
1822 const SMDS_MeshNode* n = nIt->next();
1823 if ( n->GetID() >= (int) isNodeInGroups.size() )
1824 isNodeInGroups.resize( n->GetID() + 1, false );
1825 isNodeInGroups[ n->GetID() ] = true;
1831 // Get elements of theElemType based on a certain number of nodes of elements of groups
1832 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1834 const SMDS_MeshNode* n;
1835 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1836 const int isNodeInGroupsSize = isNodeInGroups.size();
1837 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1839 if ( !isNodeInGroups[ iN ] ||
1840 !( n = aMeshDS->FindNode( iN )))
1843 // check nodes of elements of theElemType around n
1844 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1845 while ( elOfTypeIt->more() )
1847 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1848 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1853 nbNodes = elOfType->NbNodes();
1854 nbCorners = elOfType->NbCornerNodes();
1856 bool toStopChecking = false;
1857 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1858 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1860 const smIdType nID = nIt->next()->GetID();
1861 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1862 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1864 resGroupCore.Add( elOfType );
1872 // Update Python script
1873 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1874 << ".CreateDimGroup( "
1875 << theGroups << ", " << theElemType << ", '" << theName << "', "
1876 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1878 SMESH_CATCH( SMESH::throwCorbaException );
1880 return aResGrp._retn();
1883 //================================================================================
1885 * \brief Distribute all faces of the mesh between groups using sharp edges and optionally
1886 * existing 1D elements as group boundaries.
1887 * \param [in] theSharpAngle - edge is considered sharp if an angle between normals of
1888 * adjacent faces is more than \a sharpAngle in degrees.
1889 * \param [in] theCreateEdges - to create 1D elements for detected sharp edges.
1890 * \param [in] theUseExistingEdges - to use existing edges as group boundaries
1891 * \return ListOfGroups - the created groups
1893 //================================================================================
1895 SMESH::ListOfGroups*
1896 SMESH_Mesh_i::FaceGroupsSeparatedByEdges( CORBA::Double theSharpAngle,
1897 CORBA::Boolean theCreateEdges,
1898 CORBA::Boolean theUseExistingEdges )
1900 if ( theSharpAngle < 0 || theSharpAngle > 180 )
1901 THROW_SALOME_CORBA_EXCEPTION("Invalid sharp angle, it must be between 0 and 180 degrees",
1904 SMESH::ListOfGroups_var resultGroups = new SMESH::ListOfGroups;
1910 _preMeshInfo->FullLoadFromFile();
1912 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1914 std::vector< SMESH_MeshAlgos::Edge > edges =
1915 SMESH_MeshAlgos::FindSharpEdges( meshDS, theSharpAngle, theUseExistingEdges );
1917 if ( theCreateEdges )
1919 std::vector<const SMDS_MeshNode *> nodes(2);
1920 for ( size_t i = 0; i < edges.size(); ++i )
1922 nodes[0] = edges[i]._node1;
1923 nodes[1] = edges[i]._node2;
1924 if ( meshDS->FindElement( nodes, SMDSAbs_Edge ))
1926 if ( edges[i]._medium )
1927 meshDS->AddEdge( edges[i]._node1, edges[i]._node2, edges[i]._medium );
1929 meshDS->AddEdge( edges[i]._node1, edges[i]._node2 );
1933 std::vector< std::vector< const SMDS_MeshElement* > > faceGroups =
1934 SMESH_MeshAlgos::SeparateFacesByEdges( meshDS, edges );
1936 SMESH::SMESH_MeshEditor_var editor = GetMeshEditor(); // create _editor
1938 resultGroups->length( faceGroups.size() );
1939 for ( size_t iG = 0; iG < faceGroups.size(); ++iG )
1941 SMESH::SMESH_Group_var group = CreateGroup( SMESH::FACE,
1942 _editor->GenerateGroupName("Group").c_str());
1943 resultGroups[iG] = SMESH::SMESH_Group::_duplicate( group );
1945 SMESHDS_GroupBase* groupBaseDS =
1946 SMESH::DownCast<SMESH_GroupBase_i*>( group )->GetGroupDS();
1947 SMDS_MeshGroup& groupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1949 std::vector< const SMDS_MeshElement* >& faces = faceGroups[ iG ];
1950 for ( size_t i = 0; i < faces.size(); ++i )
1951 groupCore.Add( faces[i] );
1954 pyDump << resultGroups << " = " << SMESH::SMESH_Mesh_var(_this())
1955 << ".FaceGroupsSeparatedByEdges( "
1956 << TVar( theSharpAngle ) << ", "
1957 << theCreateEdges << ", "
1958 << theUseExistingEdges << " )";
1960 SMESH_CATCH( SMESH::throwCorbaException );
1961 return resultGroups._retn();
1965 //================================================================================
1967 * \brief Remember GEOM group data
1969 //================================================================================
1971 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1972 CORBA::Object_ptr theSmeshObj)
1974 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1977 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
1978 if ( groupSO->_is_nil() )
1981 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( theGeomObj );
1982 GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations();
1983 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1986 _geomGroupData.push_back( TGeomGroupData() );
1987 TGeomGroupData & groupData = _geomGroupData.back();
1989 CORBA::String_var entry = groupSO->GetID();
1990 groupData._groupEntry = entry.in();
1992 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1993 groupData._indices.insert( ids[i] );
1995 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1996 // shape index in SMESHDS
1997 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1998 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
2001 //================================================================================
2003 * Remove GEOM group data relating to removed smesh object
2005 //================================================================================
2007 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
2009 list<TGeomGroupData>::iterator
2010 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2011 for ( ; data != dataEnd; ++data ) {
2012 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
2013 _geomGroupData.erase( data );
2019 //================================================================================
2021 * \brief Replace a shape in the mesh upon Break Link
2023 //================================================================================
2025 void SMESH_Mesh_i::ReplaceShape(GEOM::GEOM_Object_ptr theNewGeom)
2027 // check if geometry changed
2028 bool geomChanged = true;
2029 GEOM::GEOM_Object_var oldGeom = GetShapeToMesh();
2030 if ( !theNewGeom->_is_nil() && !oldGeom->_is_nil() )
2031 geomChanged = ( oldGeom->GetTick() != theNewGeom->GetTick() );
2033 TopoDS_Shape S = _impl->GetShapeToMesh();
2034 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2035 TCollection_AsciiString aIOR;
2036 if ( geomClient->Find( S, aIOR ))
2037 geomClient->RemoveShapeFromBuffer( aIOR );
2039 // clear buffer also for sub-groups
2040 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2041 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2042 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2043 for (; g != groups.end(); ++g)
2044 if (const SMESHDS_GroupOnGeom* group = dynamic_cast<SMESHDS_GroupOnGeom*>(*g))
2046 const TopoDS_Shape& s = group->GetShape();
2047 if ( geomClient->Find( s, aIOR ))
2048 geomClient->RemoveShapeFromBuffer( aIOR );
2051 // clear buffer also for sub-meshes
2052 std::map<int, SMESH_subMesh_i*>::const_iterator aSubMeshIter = _mapSubMesh_i.cbegin();
2053 for(; aSubMeshIter != _mapSubMesh_i.cend(); aSubMeshIter++) {
2054 int aShapeID = aSubMeshIter->first;
2055 const TopoDS_Shape& aSubShape = meshDS->IndexToShape(aShapeID);
2056 TCollection_AsciiString aShapeIOR;
2057 if ( geomClient->Find( aSubShape, aShapeIOR ))
2058 geomClient->RemoveShapeFromBuffer( aShapeIOR );
2062 int shapeID; smIdType fromID, toID; // indices of elements of a sub-mesh
2064 std::vector< TRange > elemRanges, nodeRanges; // elements of sub-meshes
2065 std::vector< SMDS_PositionPtr > positions; // node positions
2068 // store positions of elements on geometry
2070 if ( meshDS->MaxNodeID() > meshDS->NbNodes() ||
2071 meshDS->MaxElementID() > meshDS->NbElements() )
2074 meshDS->CompactMesh();
2076 positions.resize( meshDS->NbNodes() + 1 );
2077 for ( SMDS_NodeIteratorPtr nodeIt = meshDS->nodesIterator(); nodeIt->more(); )
2079 const SMDS_MeshNode* n = nodeIt->next();
2080 positions[ n->GetID() ] = n->GetPosition();
2083 // remove elements from sub-meshes to avoid their removal at hypotheses addition
2084 for ( int isNode = 0; isNode < 2; ++isNode )
2086 std::vector< TRange > & ranges = isNode ? nodeRanges : elemRanges;
2087 ranges.reserve( meshDS->MaxShapeIndex() + 10 );
2088 ranges.push_back( TRange{ 0,0,0 });
2089 SMDS_ElemIteratorPtr elemIt = meshDS->elementsIterator( isNode ? SMDSAbs_Node : SMDSAbs_All );
2090 while ( elemIt->more() )
2092 const SMDS_MeshElement* e = elemIt->next();
2093 const smIdType elemID = e->GetID();
2094 const int shapeID = e->GetShapeID();
2095 TRange & lastRange = ranges.back();
2096 if ( lastRange.shapeID != shapeID ||
2097 lastRange.toID != elemID )
2098 ranges.push_back( TRange{ shapeID, elemID, elemID + 1 });
2100 lastRange.toID = elemID + 1;
2102 if ( SMESHDS_SubMesh* sm = meshDS->MeshElements( shapeID ))
2104 if ( isNode ) sm->RemoveNode( static_cast< const SMDS_MeshNode *>( e ));
2105 else sm->RemoveElement( e );
2112 // update the reference to theNewGeom (needed for correct execution of a dumped python script)
2113 SMESH::SMESH_Mesh_var me = _this();
2114 SALOMEDS::SObject_wrap aSO = _gen_i->ObjectToSObject( me );
2115 CORBA::String_var entry = theNewGeom->GetStudyEntry();
2116 if ( !aSO->_is_nil() )
2118 SALOMEDS::SObject_wrap aShapeRefSO;
2119 if ( aSO->FindSubObject( _gen_i->GetRefOnShapeTag(), aShapeRefSO.inout() ))
2121 SALOMEDS::SObject_wrap aShapeSO = _gen_i->getStudyServant()->FindObjectID( entry );
2122 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2123 builder->Addreference( aShapeRefSO, aShapeSO );
2127 // re-assign global hypotheses to the new shape
2128 _mainShapeTick = geomChanged ? -1 : theNewGeom->GetTick();
2129 CheckGeomModif( true );
2133 // restore positions of elements on geometry
2134 for ( int isNode = 0; isNode < 2; ++isNode )
2136 std::vector< TRange > & ranges = isNode ? nodeRanges : elemRanges;
2137 for ( size_t i = 1; i < ranges.size(); ++i )
2139 int elemID = ranges[ i ].fromID;
2140 int toID = ranges[ i ].toID;
2141 SMESHDS_SubMesh * smDS = meshDS->NewSubMesh( ranges[ i ].shapeID );
2143 for ( ; elemID < toID; ++elemID )
2144 smDS->AddNode( meshDS->FindNode( elemID ));
2146 for ( ; elemID < toID; ++elemID )
2147 smDS->AddElement( meshDS->FindElement( elemID ));
2149 if ( SMESH_subMesh* sm = _impl->GetSubMeshContaining( ranges[ i ].shapeID ))
2150 sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
2153 for ( unsigned int nodeID = 1; nodeID < positions.size(); ++nodeID )
2154 if ( positions[ nodeID ])
2155 if ( SMDS_MeshNode* n = const_cast< SMDS_MeshNode*>( meshDS->FindNode( nodeID )))
2156 n->SetPosition( positions[ nodeID ], n->GetShapeID() );
2159 _gen_i->UpdateIcons( SMESH::SMESH_Mesh_var( _this() ));
2162 TPythonDump() << "SHAPERSTUDY.breakLinkForSubElements(salome.ObjectToSObject("
2163 << me <<".GetMesh()), " << entry.in() << ")";
2165 TPythonDump() << me << ".ReplaceShape( " << entry.in() << " )";
2169 //================================================================================
2171 * \brief Return new group contents if it has been changed and update group data
2173 //================================================================================
2175 enum { ONLY_IF_CHANGED, IS_BREAK_LINK, MAIN_TRANSFORMED };
2177 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData, int how )
2179 TopoDS_Shape newShape;
2180 SALOMEDS::SObject_wrap groupSO;
2182 if ( how == IS_BREAK_LINK )
2184 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( groupData._smeshObject );
2185 SALOMEDS::SObject_wrap geomRefSO;
2186 if ( !meshSO->_is_nil() &&
2187 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ))
2189 geomRefSO->ReferencedObject( groupSO.inout() );
2195 groupSO = _gen_i->getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
2198 if ( groupSO->_is_nil() )
2201 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
2202 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
2203 if ( geomGroup->_is_nil() )
2206 // get indices of group items
2207 set<int> curIndices;
2208 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( geomGroup );
2209 GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations();
2210 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
2211 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2212 curIndices.insert( ids[i] );
2214 bool sameIndices = ( groupData._indices == curIndices );
2215 if ( how == ONLY_IF_CHANGED && sameIndices )
2216 return newShape; // group not changed
2219 CORBA::String_var entry = geomGroup->GetStudyEntry();
2220 groupData._groupEntry = entry.in();
2221 groupData._indices = curIndices;
2223 newShape = _gen_i->GeomObjectToShape( geomGroup );
2225 // check if newShape is up-to-date
2226 if ( !newShape.IsNull() && ids->length() > 0 )
2228 bool toUpdate = ! _impl->GetMeshDS()->IsGroupOfSubShapes( newShape );
2231 TopExp_Explorer exp( newShape, (TopAbs_ShapeEnum)( groupOp->GetType( geomGroup )));
2232 for ( ; exp.More() && !toUpdate; exp.Next() )
2234 int ind = _impl->GetMeshDS()->ShapeToIndex( exp.Current() );
2235 toUpdate = ( curIndices.erase( ind ) == 0 );
2237 if ( !curIndices.empty() )
2242 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2243 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
2244 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
2245 newShape = _gen_i->GeomObjectToShape( geomGroup );
2250 // geom group becomes empty - return empty compound
2251 TopoDS_Compound compound;
2252 BRep_Builder().MakeCompound(compound);
2253 newShape = compound;
2261 //-----------------------------------------------------------------------------
2263 * \brief Storage of shape and index used in CheckGeomGroupModif()
2265 struct TIndexedShape
2268 TopoDS_Shape _shape;
2269 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
2271 //-----------------------------------------------------------------------------
2273 * \brief Data to re-create a group on geometry
2275 struct TGroupOnGeomData
2278 TopoDS_Shape _shape;
2279 SMDSAbs_ElementType _type;
2281 Quantity_Color _color;
2283 TGroupOnGeomData( const SMESHDS_GroupOnGeom* group )
2285 _oldID = group->GetID();
2286 _type = group->GetType();
2287 _name = group->GetStoreName();
2288 _color = group->GetColor();
2292 //-----------------------------------------------------------------------------
2294 * \brief Check if a filter is still valid after geometry removal
2296 bool isValidGeomFilter( SMESH::Filter_var theFilter )
2298 if ( theFilter->_is_nil() )
2300 SMESH::Filter::Criteria_var criteria;
2301 theFilter->GetCriteria( criteria.out() );
2303 for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr )
2305 const char* thresholdID = criteria[ iCr ].ThresholdID.in();
2307 switch ( criteria[ iCr ].Type )
2309 case SMESH::FT_BelongToGeom:
2310 case SMESH::FT_BelongToPlane:
2311 case SMESH::FT_BelongToCylinder:
2312 case SMESH::FT_BelongToGenSurface:
2313 case SMESH::FT_LyingOnGeom:
2314 entry = thresholdID;
2316 case SMESH::FT_ConnectedElements:
2319 entry = thresholdID;
2325 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
2326 SALOMEDS::SObject_wrap so = gen->getStudyServant()->FindObjectID( entry.c_str() );
2327 if ( so->_is_nil() )
2329 CORBA::Object_var obj = so->GetObject();
2330 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( obj );
2331 if ( gen->GeomObjectToShape( geom ).IsNull() )
2334 } // loop on criteria
2340 //=============================================================================
2342 * \brief Update data if geometry changes
2346 //=============================================================================
2348 void SMESH_Mesh_i::CheckGeomModif( bool theIsBreakLink )
2350 SMESH::SMESH_Mesh_var me = _this();
2351 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2353 TPythonDump dumpNothing; // prevent any dump
2355 //bool removedFromClient = false;
2357 if ( mainGO->_is_nil() ) // GEOM_Client cleared or geometry removed? (IPAL52735, PAL23636)
2359 //removedFromClient = _impl->HasShapeToMesh();
2361 // try to find geometry by study reference
2362 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2363 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2364 if ( !meshSO->_is_nil() &&
2365 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2366 geomRefSO->ReferencedObject( geomSO.inout() ))
2368 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2369 mainGO = GEOM::GEOM_Object::_narrow( geomObj );
2372 if ( mainGO->_is_nil() && // geometry removed ==>
2373 !geomRefSO->_is_nil() ) // remove geom dependent data: sub-meshes etc.
2375 // convert geom dependent groups into standalone ones
2376 CheckGeomGroupModif();
2378 _impl->ShapeToMesh( TopoDS_Shape() );
2380 // remove sub-meshes
2381 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2382 while ( i_sm != _mapSubMeshIor.end() )
2384 SMESH::SMESH_subMesh_ptr sm = i_sm->second;
2386 RemoveSubMesh( sm );
2388 // remove all children except groups in the study
2389 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2390 SALOMEDS::SObject_wrap so;
2391 for ( CORBA::Long tag = SMESH::Tag_RefOnShape; tag <= SMESH::Tag_LastSubMesh; ++tag )
2392 if ( meshSO->FindSubObject( tag, so.inout() ))
2393 builder->RemoveObjectWithChildren( so );
2395 _gen_i->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED" );
2401 if ( !_impl->HasShapeToMesh() ) return;
2404 // Update after group modification
2406 const bool geomChanged = ( mainGO->GetTick() != _mainShapeTick );
2407 if ( !theIsBreakLink )
2408 if ( mainGO->GetType() == GEOM_GROUP || !geomChanged ) // is group or not modified
2410 smIdType nb = NbNodes() + NbElements();
2411 CheckGeomGroupModif();
2412 bool updated = ( nb != NbNodes() + NbElements() );
2413 if ( updated ) // something removed due to hypotheses change
2414 _gen_i->UpdateIcons( me );
2415 if ( updated == geomChanged || nb == 0 )
2419 // Update after shape modification or breakLink w/o geometry change
2421 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2422 if ( !geomClient ) return;
2423 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( mainGO );
2424 if ( geomGen->_is_nil() ) return;
2425 CORBA::String_var geomComponentType = geomGen->ComponentDataType();
2426 bool isShaper = ( strcmp( geomComponentType.in(), "SHAPERSTUDY" ) == 0 );
2428 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2430 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2431 if ( meshDS->ShapeToIndex( newShape ) == 1 ) // not yet updated
2433 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2434 geomClient->RemoveShapeFromBuffer( ior.in() );
2435 newShape = _gen_i->GeomObjectToShape( mainGO );
2438 // Update data taking into account that if topology doesn't change
2439 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2442 _preMeshInfo->ForgetAllData();
2444 if ( geomChanged || !isShaper )
2446 if ( newShape.IsNull() )
2449 _mainShapeTick = mainGO->GetTick();
2451 // store data of groups on geometry including new TopoDS_Shape's
2452 std::vector< TGroupOnGeomData > groupsData;
2453 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2454 groupsData.reserve( groups.size() );
2455 TopTools_DataMapOfShapeShape old2newShapeMap;
2456 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2457 for ( ; g != groups.end(); ++g )
2459 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2461 groupsData.push_back( TGroupOnGeomData( group ));
2464 SMESH::SMESH_GroupOnGeom_var gog;
2465 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.find( group->GetID() );
2466 if ( i_grp != _mapGroups.end() )
2467 gog = SMESH::SMESH_GroupOnGeom::_narrow( i_grp->second );
2469 GEOM::GEOM_Object_var geom;
2470 if ( !gog->_is_nil() )
2472 if ( !theIsBreakLink )
2473 geom = gog->GetShape();
2475 if ( theIsBreakLink || geom->_is_nil() )
2477 SALOMEDS::SObject_wrap grpSO = _gen_i->ObjectToSObject( gog );
2478 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2479 if ( !grpSO->_is_nil() &&
2480 grpSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2481 geomRefSO->ReferencedObject( geomSO.inout() ))
2483 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2484 geom = GEOM::GEOM_Object::_narrow( geomObj );
2488 if ( old2newShapeMap.IsBound( group->GetShape() ))
2490 groupsData.back()._shape = old2newShapeMap( group->GetShape() );
2492 else if ( !geom->_is_nil() )
2494 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2495 if ( meshDS->IsGroupOfSubShapes( groupsData.back()._shape ))
2497 CORBA::String_var ior = geomGen->GetStringFromIOR( geom );
2498 geomClient->RemoveShapeFromBuffer( ior.in() );
2499 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2501 old2newShapeMap.Bind( group->GetShape(), groupsData.back()._shape );
2506 // store assigned hypotheses
2507 std::vector< pair< int, THypList > > ids2Hyps;
2508 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2509 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2511 const TopoDS_Shape& s = s2hyps.Key();
2512 const THypList& hyps = s2hyps.ChangeValue();
2513 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2516 std::multimap< std::set<int>, int > ii2iMap; // group sub-ids to group id in SMESHDS
2518 // count shapes excluding compounds corresponding to geom groups
2519 int oldNbSubShapes = meshDS->MaxShapeIndex();
2520 for ( ; oldNbSubShapes > 0; --oldNbSubShapes )
2522 const TopoDS_Shape& s = meshDS->IndexToShape( oldNbSubShapes );
2523 if ( s.IsNull() || s.ShapeType() != TopAbs_COMPOUND )
2526 std::set<int> subIds;
2527 for ( TopoDS_Iterator it( s ); it.More(); it.Next() )
2528 subIds.insert( meshDS->ShapeToIndex( it.Value() ));
2529 ii2iMap.insert( std::make_pair( subIds, oldNbSubShapes ));
2532 // check if shape topology changes - save shape type per shape ID
2533 std::vector< TopAbs_ShapeEnum > shapeTypes( Max( oldNbSubShapes + 1, 1 ));
2534 for ( int shapeID = oldNbSubShapes; shapeID > 0; --shapeID )
2535 shapeTypes[ shapeID ] = meshDS->IndexToShape( shapeID ).ShapeType();
2537 // change shape to mesh
2538 _impl->ShapeToMesh( TopoDS_Shape() );
2539 _impl->ShapeToMesh( newShape );
2541 // check if shape topology changes - check new shape types
2542 bool sameTopology = ( oldNbSubShapes == meshDS->MaxShapeIndex() );
2543 for ( int shapeID = oldNbSubShapes; shapeID > 0 && sameTopology; --shapeID )
2545 const TopoDS_Shape& s = meshDS->IndexToShape( shapeID );
2546 sameTopology = ( !s.IsNull() && s.ShapeType() == shapeTypes[ shapeID ]);
2549 // re-add shapes (compounds) of geom groups
2550 typedef std::map< std::vector< int >, TGeomGroupData* > TIndices2GroupData;
2551 TIndices2GroupData ii2grData;
2552 std::vector< int > ii;
2553 std::map< int, int > old2newIDs; // group IDs
2554 std::list<TGeomGroupData>::iterator dataIt = _geomGroupData.begin();
2555 for ( ; dataIt != _geomGroupData.end(); ++dataIt )
2557 TGeomGroupData* data = &(*dataIt);
2558 ii.reserve( data->_indices.size() );
2559 ii.assign( data->_indices.begin(), data->_indices.end() );
2560 TIndices2GroupData::iterator ii2gd = ii2grData.insert( std::make_pair( ii, data )).first;
2561 if ( ii2gd->second != data )
2563 data->_groupEntry = ii2gd->second->_groupEntry;
2564 data->_indices = ii2gd->second->_indices;
2567 const int oldNbSub = data->_indices.size();
2568 const int soleOldID = oldNbSub == 1 ? *data->_indices.begin() : 0;
2570 std::multimap< std::set<int>, int >::iterator ii2i = ii2iMap.find( data->_indices );
2571 if ( ii2i != ii2iMap.end() )
2573 oldID = ii2i->second;
2574 ii2iMap.erase( ii2i );
2576 if ( !oldID && oldNbSub == 1 )
2578 if ( old2newIDs.count( oldID ))
2581 int how = ( theIsBreakLink || !sameTopology ) ? IS_BREAK_LINK : MAIN_TRANSFORMED;
2582 newShape = newGroupShape( *data, how );
2584 if ( !newShape.IsNull() )
2586 if ( oldNbSub > 1 && meshDS->ShapeToIndex( newShape ) > 0 ) // group reduced to one sub-shape
2588 TopoDS_Compound compound;
2589 BRep_Builder().MakeCompound( compound );
2590 BRep_Builder().Add( compound, newShape );
2591 newShape = compound;
2593 int newID = _impl->GetSubMesh( newShape )->GetId();
2594 if ( oldID /*&& oldID != newID*/ )
2595 old2newIDs.insert( std::make_pair( oldID, newID ));
2596 if ( oldNbSub == 1 )
2597 old2newIDs.insert( std::make_pair( soleOldID, newID ));
2601 // re-assign hypotheses
2602 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2604 int sID = ids2Hyps[i].first;
2607 std::map< int, int >::iterator o2n = old2newIDs.find( sID );
2608 if ( o2n != old2newIDs.end() )
2610 else if ( !sameTopology )
2613 const TopoDS_Shape& s = meshDS->IndexToShape( sID );
2616 const THypList& hyps = ids2Hyps[i].second;
2617 THypList::const_iterator h = hyps.begin();
2618 for ( ; h != hyps.end(); ++h )
2619 _impl->AddHypothesis( s, (*h)->GetID() );
2623 // restore groups on geometry
2624 for ( size_t i = 0; i < groupsData.size(); ++i )
2626 const TGroupOnGeomData& data = groupsData[i];
2627 if ( data._shape.IsNull() )
2630 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2631 if ( i2g == _mapGroups.end() ) continue;
2633 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2634 if ( !gr_i ) continue;
2636 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape );
2638 _mapGroups.erase( i2g );
2640 g->GetGroupDS()->SetColor( data._color );
2643 if ( !sameTopology )
2645 std::map< int, int >::iterator o2n = old2newIDs.begin();
2646 for ( ; o2n != old2newIDs.end(); ++o2n )
2648 int newID = o2n->second, oldID = o2n->first;
2649 if ( newID == oldID || !_mapSubMesh.count( oldID ))
2653 _mapSubMesh [ newID ] = _impl->GetSubMeshContaining( newID );
2654 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2655 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2657 _mapSubMesh. erase(oldID);
2658 _mapSubMesh_i. erase(oldID);
2659 _mapSubMeshIor.erase(oldID);
2661 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2665 // update _mapSubMesh
2666 std::map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2667 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2668 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2671 if ( !sameTopology )
2673 // remove invalid study sub-objects
2674 CheckGeomGroupModif();
2677 _gen_i->UpdateIcons( me );
2679 if ( !theIsBreakLink && isShaper )
2681 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2682 if ( !meshSO->_is_nil() )
2683 _gen_i->SetPixMap(meshSO, "ICON_SMESH_TREE_GEOM_MODIF");
2687 //=============================================================================
2689 * \brief Update objects depending on changed geom groups
2691 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2692 * issue 0020210: Update of a smesh group after modification of the associated geom group
2694 //=============================================================================
2696 void SMESH_Mesh_i::CheckGeomGroupModif()
2698 // remove sub-meshes referring a removed sub-shapes (if main shape still exists)
2699 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2700 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2701 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() ));
2702 if ( !mainGO->_is_nil() && !meshSO->_is_nil() )
2704 SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO;
2705 for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag )
2706 if ( meshSO->FindSubObject( tag, rootSO.inout() ))
2708 int nbValid = 0, nbRemoved = 0;
2709 SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO );
2710 for ( ; chItr->More(); chItr->Next() )
2712 SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO
2713 if ( !smSO->_is_nil() &&
2714 smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2715 geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference
2717 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2718 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2719 if ( !geom->_non_existent() )
2722 continue; // keep the sub-mesh
2725 CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO );
2726 SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj );
2727 if ( !sm->_is_nil() && !sm->_non_existent() )
2729 GEOM::GEOM_Object_var smGeom = sm->GetSubShape();
2730 if ( smGeom->_is_nil() )
2732 RemoveSubMesh( sm );
2739 _preMeshInfo->ForgetAllData(); // unknown hypothesis modified
2740 builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH
2744 if ( /*nbRemoved > 0 &&*/ nbValid == 0 )
2745 builder->RemoveObjectWithChildren( rootSO );
2749 // check for removed sub-shapes and convert geom dependent groups into standalone ones
2750 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2751 while ( i_gr != _mapGroups.end())
2753 SMESH::SMESH_GroupBase_ptr group = i_gr->second;
2755 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO, geomSO;
2756 SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group );
2757 SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group );
2758 bool isValidGeom = false;
2759 if ( !onGeom->_is_nil() )
2761 isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() ); // check TopoDS
2762 if ( !isValidGeom ) // check reference
2764 isValidGeom = ( ! groupSO->_is_nil() &&
2765 groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ) &&
2766 refSO->ReferencedObject( geomSO.inout() ) &&
2767 ! geomSO->_is_nil() &&
2768 !CORBA::is_nil( CORBA::Object_var( geomSO->GetObject() )));
2771 else if ( !onFilt->_is_nil() )
2773 isValidGeom = isValidGeomFilter( onFilt->GetFilter() );
2777 isValidGeom = ( !groupSO->_is_nil() &&
2778 !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ));
2782 if ( !IsLoaded() || group->IsEmpty() )
2784 RemoveGroup( group );
2786 else if ( !onGeom->_is_nil() || !onFilt->_is_nil() )
2788 SMESH::SMESH_Group_var ( ConvertToStandalone( group ));
2790 else // is it possible?
2792 builder->RemoveObjectWithChildren( refSO );
2798 if ( !_impl->HasShapeToMesh() ) return;
2800 SMESH::smIdType nbEntities = NbNodes() + NbElements();
2802 // Check if group contents changed
2804 typedef map< string, TopoDS_Shape > TEntry2Geom;
2805 TEntry2Geom newGroupContents;
2807 list<TGeomGroupData>::iterator
2808 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2809 for ( ; data != dataEnd; ++data )
2811 pair< TEntry2Geom::iterator, bool > it_new =
2812 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2813 bool processedGroup = !it_new.second;
2814 TopoDS_Shape& newShape = it_new.first->second;
2815 if ( !processedGroup )
2816 newShape = newGroupShape( *data, ONLY_IF_CHANGED );
2817 if ( newShape.IsNull() )
2818 continue; // no changes
2821 _preMeshInfo->ForgetOrLoad();
2823 if ( processedGroup ) { // update group indices
2824 list<TGeomGroupData>::iterator data2 = data;
2825 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2826 data->_indices = data2->_indices;
2829 // Update SMESH objects according to new GEOM group contents
2831 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2832 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2834 int oldID = submesh->GetId();
2835 if ( !_mapSubMeshIor.count( oldID ))
2837 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2839 // update hypotheses
2840 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2841 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2842 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2844 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2845 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2847 // care of submeshes
2848 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2849 int newID = newSubmesh->GetId();
2850 if ( newID != oldID ) {
2851 _mapSubMesh [ newID ] = newSubmesh;
2852 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2853 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2854 _mapSubMesh. erase(oldID);
2855 _mapSubMesh_i. erase(oldID);
2856 _mapSubMeshIor.erase(oldID);
2857 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2862 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2863 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2864 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2866 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2868 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2869 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2870 ds->SetShape( newShape );
2875 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2876 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2878 // Remove groups and submeshes basing on removed sub-shapes
2880 TopTools_MapOfShape newShapeMap;
2881 TopoDS_Iterator shapeIt( newShape );
2882 for ( ; shapeIt.More(); shapeIt.Next() )
2883 newShapeMap.Add( shapeIt.Value() );
2885 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2886 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2888 if ( newShapeMap.Contains( shapeIt.Value() ))
2890 TopTools_IndexedMapOfShape oldShapeMap;
2891 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2892 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2894 const TopoDS_Shape& oldShape = oldShapeMap(i);
2895 int oldInd = meshDS->ShapeToIndex( oldShape );
2897 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2898 if ( i_smIor != _mapSubMeshIor.end() ) {
2899 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2902 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2903 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2905 // check if a group bases on oldInd shape
2906 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2907 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2908 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2909 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2911 RemoveGroup( i_grp->second ); // several groups can base on same shape
2912 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2917 // Reassign hypotheses and update groups after setting the new shape to mesh
2919 // collect anassigned hypotheses
2920 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2921 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2922 TShapeHypList assignedHyps;
2923 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2925 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2926 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2927 if ( !hyps.empty() ) {
2928 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2929 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2930 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2933 // collect shapes supporting groups
2934 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2935 TShapeTypeList groupData;
2936 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2937 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2938 for ( ; grIt != groups.end(); ++grIt )
2940 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2942 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2944 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2946 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2947 _impl->ShapeToMesh( newShape );
2949 // reassign hypotheses
2950 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2951 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2953 TIndexedShape& geom = indS_hyps->first;
2954 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2955 int oldID = geom._index;
2956 int newID = meshDS->ShapeToIndex( geom._shape );
2957 if ( oldID == 1 ) { // main shape
2959 geom._shape = newShape;
2963 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2964 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2965 // care of sub-meshes
2966 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2967 if ( newID != oldID ) {
2968 _mapSubMesh [ newID ] = newSubmesh;
2969 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2970 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2971 _mapSubMesh. erase(oldID);
2972 _mapSubMesh_i. erase(oldID);
2973 _mapSubMeshIor.erase(oldID);
2974 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2978 TShapeTypeList::iterator geomType = groupData.begin();
2979 for ( ; geomType != groupData.end(); ++geomType )
2981 const TIndexedShape& geom = geomType->first;
2982 int oldID = geom._index;
2983 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2986 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2987 CORBA::String_var name = groupSO->GetName();
2989 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
2990 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
2991 /*id=*/-1, geom._shape ))
2992 group_i->changeLocalId( group->GetID() );
2995 break; // everything has been updated
2998 } // loop on group data
3002 SMESH::smIdType newNbEntities = NbNodes() + NbElements();
3003 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
3004 if ( newNbEntities != nbEntities )
3006 // Add all SObjects with icons to soToUpdateIcons
3007 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
3009 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
3010 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
3011 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
3013 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
3014 i_gr != _mapGroups.end(); ++i_gr ) // groups
3015 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
3018 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
3019 for ( ; so != soToUpdateIcons.end(); ++so )
3020 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
3023 //=============================================================================
3025 * \brief Create standalone group from a group on geometry or filter
3027 //=============================================================================
3029 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
3031 SMESH::SMESH_Group_var aGroup;
3036 _preMeshInfo->FullLoadFromFile();
3038 if ( theGroup->_is_nil() )
3039 return aGroup._retn();
3041 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
3043 return aGroup._retn();
3045 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
3047 const int anId = aGroupToRem->GetLocalID();
3048 if ( !_impl->ConvertToStandalone( anId ) )
3049 return aGroup._retn();
3050 removeGeomGroupData( theGroup );
3052 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3054 // remove old instance of group from own map
3055 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
3056 _mapGroups.erase( anId );
3058 SALOMEDS::StudyBuilder_var builder;
3059 SALOMEDS::SObject_wrap aGroupSO;
3060 SALOMEDS::Study_var aStudy = SMESH_Gen_i::GetSMESHGen()->getStudyServant();
3061 if ( !aStudy->_is_nil() ) {
3062 builder = aStudy->NewBuilder();
3063 aGroupSO = _gen_i->ObjectToSObject( theGroup );
3064 if ( !aGroupSO->_is_nil() )
3066 // remove reference to geometry
3067 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
3068 for ( ; chItr->More(); chItr->Next() )
3070 // Remove group's child SObject
3071 SALOMEDS::SObject_wrap so = chItr->Value();
3072 builder->RemoveObject( so );
3074 // Update Python script
3075 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
3076 << ".ConvertToStandalone( " << aGroupSO << " )";
3078 // change icon of Group on Filter
3081 // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
3082 // const int isEmpty = ( elemTypes->length() == 0 );
3085 SALOMEDS::GenericAttribute_wrap anAttr =
3086 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
3087 SALOMEDS::AttributePixMap_wrap pm = anAttr;
3088 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
3094 // remember new group in own map
3095 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
3096 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3098 // register CORBA object for persistence
3099 _gen_i->RegisterObject( aGroup );
3101 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
3102 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
3103 //aGroup->Register();
3104 aGroupToRem->UnRegister();
3106 SMESH_CATCH( SMESH::throwCorbaException );
3108 return aGroup._retn();
3111 //================================================================================
3113 * \brief Create a sub-mesh on a given sub-shape
3115 //================================================================================
3117 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
3119 MESSAGE( "createSubMesh" );
3120 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
3121 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
3124 SMESH_subMesh_i * subMeshServant;
3127 subMeshId = mySubMesh->GetId();
3128 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
3130 else // "invalid sub-mesh"
3132 // The invalid sub-mesh is created for the case where a valid sub-shape not found
3133 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
3134 if ( _mapSubMesh.empty() )
3137 subMeshId = _mapSubMesh.begin()->first - 1;
3138 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
3141 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
3143 _mapSubMesh [subMeshId] = mySubMesh;
3144 _mapSubMesh_i [subMeshId] = subMeshServant;
3145 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
3147 subMeshServant->Register();
3149 // register CORBA object for persistence
3150 int nextId = _gen_i->RegisterObject( subMesh );
3151 MESSAGE( "Add submesh to map with id = "<< nextId);
3153 // to track changes of GEOM groups
3154 if ( subMeshId > 0 )
3155 addGeomGroupData( theSubShapeObject, subMesh );
3157 return subMesh._retn();
3160 //================================================================================
3162 * \brief Return an existing sub-mesh based on a sub-shape with the given ID
3164 //================================================================================
3166 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
3168 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
3169 if ( it == _mapSubMeshIor.end() )
3170 return SMESH::SMESH_subMesh::_nil();
3172 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
3175 //================================================================================
3177 * \brief Remove a sub-mesh based on the given sub-shape
3179 //================================================================================
3181 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
3182 GEOM::GEOM_Object_ptr theSubShapeObject )
3184 bool isHypChanged = false;
3185 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
3186 return isHypChanged;
3188 const int subMeshId = theSubMesh->GetId();
3190 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
3193 if (( _mapSubMesh.count( subMeshId )) &&
3194 ( sm = _impl->GetSubMeshContaining( subMeshId )))
3196 TopoDS_Shape S = sm->GetSubShape();
3199 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
3200 isHypChanged = !hyps.empty();
3201 if ( isHypChanged && _preMeshInfo )
3202 _preMeshInfo->ForgetOrLoad();
3203 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
3204 for ( ; hyp != hyps.end(); ++hyp )
3205 _impl->RemoveHypothesis(S, (*hyp)->GetID());
3212 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
3213 isHypChanged = ( aHypList->length() > 0 );
3214 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
3215 removeHypothesis( theSubShapeObject, aHypList[i] );
3218 catch( const SALOME::SALOME_Exception& ) {
3219 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
3221 removeGeomGroupData( theSubShapeObject );
3225 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
3226 if ( id_smi != _mapSubMesh_i.end() )
3227 id_smi->second->UnRegister();
3229 // remove a CORBA object
3230 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
3231 if ( id_smptr != _mapSubMeshIor.end() )
3232 SMESH::SMESH_subMesh_var( id_smptr->second );
3234 _mapSubMesh.erase(subMeshId);
3235 _mapSubMesh_i.erase(subMeshId);
3236 _mapSubMeshIor.erase(subMeshId);
3238 return isHypChanged;
3241 //================================================================================
3243 * \brief Create a group. Group type depends on given arguments
3245 //================================================================================
3247 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
3248 const char* theName,
3250 const TopoDS_Shape& theShape,
3251 const SMESH_PredicatePtr& thePredicate )
3253 std::string newName;
3254 if ( !theName || !theName[0] )
3256 std::set< std::string > presentNames;
3257 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
3258 for ( ; i_gr != _mapGroups.end(); ++i_gr )
3260 CORBA::String_var name = i_gr->second->GetName();
3261 presentNames.insert( name.in() );
3264 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
3265 } while ( !presentNames.insert( newName ).second );
3266 theName = newName.c_str();
3268 SMESH::SMESH_GroupBase_var aGroup;
3269 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
3270 theID, theShape, thePredicate ))
3272 int anId = g->GetID();
3273 SMESH_GroupBase_i* aGroupImpl;
3274 if ( !theShape.IsNull() )
3275 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3276 else if ( thePredicate )
3277 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
3279 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3281 aGroup = aGroupImpl->_this();
3282 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3283 aGroupImpl->Register();
3285 // register CORBA object for persistence
3286 int nextId = _gen_i->RegisterObject( aGroup );
3287 MESSAGE( "Add group to map with id = "<< nextId);
3289 // to track changes of GEOM groups
3290 if ( !theShape.IsNull() ) {
3291 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
3292 addGeomGroupData( geom, aGroup );
3295 return aGroup._retn();
3298 //=============================================================================
3300 * SMESH_Mesh_i::removeGroup
3302 * Should be called by ~SMESH_Group_i()
3304 //=============================================================================
3306 void SMESH_Mesh_i::removeGroup( const int theId )
3308 MESSAGE("SMESH_Mesh_i::removeGroup()");
3309 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
3310 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
3311 _mapGroups.erase( theId );
3312 removeGeomGroupData( group );
3313 if ( !_impl->RemoveGroup( theId ))
3315 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
3316 RemoveGroup( group );
3318 group->UnRegister();
3322 //================================================================================
3324 * \brief Return a log that can be used to move another mesh to the same state as this one
3326 //================================================================================
3328 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
3330 SMESH::log_array_var aLog;
3334 _preMeshInfo->FullLoadFromFile();
3336 list < SMESHDS_Command * >logDS = _impl->GetLog();
3337 aLog = new SMESH::log_array;
3339 int lg = logDS.size();
3341 list < SMESHDS_Command * >::iterator its = logDS.begin();
3342 while(its != logDS.end()){
3343 SMESHDS_Command *com = *its;
3344 int comType = com->GetType();
3345 smIdType lgcom = com->GetNumber();
3346 const list < smIdType >&intList = com->GetIndexes();
3347 int inum = intList.size();
3348 list < smIdType >::const_iterator ii = intList.begin();
3349 const list < double >&coordList = com->GetCoords();
3350 int rnum = coordList.size();
3351 list < double >::const_iterator ir = coordList.begin();
3352 aLog[indexLog].commandType = comType;
3353 aLog[indexLog].number = lgcom;
3354 aLog[indexLog].coords.length(rnum);
3355 aLog[indexLog].indexes.length(inum);
3356 for(int i = 0; i < rnum; i++){
3357 aLog[indexLog].coords[i] = *ir;
3360 for(int i = 0; i < inum; i++){
3361 aLog[indexLog].indexes[i] = *ii;
3370 SMESH_CATCH( SMESH::throwCorbaException );
3372 return aLog._retn();
3375 //================================================================================
3377 * \brief Remove the log of commands
3379 //================================================================================
3381 void SMESH_Mesh_i::ClearLog()
3385 SMESH_CATCH( SMESH::throwCorbaException );
3388 //================================================================================
3390 * \brief Return a mesh ID
3392 //================================================================================
3394 CORBA::Long SMESH_Mesh_i::GetId()
3399 //=============================================================================
3402 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
3403 // issue 0020918: groups removal is caused by hyp modification
3404 // issue 0021208: to forget not loaded mesh data at hyp modification
3405 struct TCallUp_i : public SMESH_Mesh::TCallUp
3407 SMESH_Mesh_i* _mesh;
3408 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
3409 void RemoveGroup (const int theGroupID) override { _mesh->removeGroup( theGroupID ); }
3410 void HypothesisModified( int hypID,
3411 bool updIcons) override { _mesh->onHypothesisModified( hypID,
3413 void Load () override { _mesh->Load(); }
3414 bool IsLoaded() override { return _mesh->IsLoaded(); }
3415 TopoDS_Shape GetShapeByEntry(const std::string& entry) override
3417 GEOM::GEOM_Object_var go = SMESH_Gen_i::GetGeomObjectByEntry( entry );
3418 return SMESH_Gen_i::GeomObjectToShape( go );
3423 //================================================================================
3425 * \brief callback from _impl to
3426 * 1) forget not loaded mesh data (issue 0021208)
3427 * 2) mark hypothesis as valid
3429 //================================================================================
3431 void SMESH_Mesh_i::onHypothesisModified(int theHypID, bool theUpdateIcons)
3434 _preMeshInfo->ForgetOrLoad();
3436 if ( theUpdateIcons )
3438 SMESH::SMESH_Mesh_var mesh = _this();
3439 _gen_i->UpdateIcons( mesh );
3442 if ( _nbInvalidHypos != 0 )
3444 // mark a hypothesis as valid after edition
3446 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
3447 SALOMEDS::SObject_wrap hypRoot;
3448 if ( !smeshComp->_is_nil() &&
3449 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
3451 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
3452 for ( ; anIter->More(); anIter->Next() )
3454 SALOMEDS::SObject_wrap hypSO = anIter->Value();
3455 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
3456 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
3457 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
3458 _gen_i->HighLightInvalid( hyp, false );
3460 nbInvalid += _gen_i->IsInvalid( hypSO );
3463 _nbInvalidHypos = nbInvalid;
3467 //================================================================================
3469 * \brief Set mesh implementation
3471 //================================================================================
3473 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
3475 MESSAGE("SMESH_Mesh_i::SetImpl");
3478 _impl->SetCallUp( new TCallUp_i(this));
3481 //=============================================================================
3483 * Return a mesh implementation
3485 //=============================================================================
3487 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
3489 MESSAGE("SMESH_Mesh_i::GetImpl()");
3493 //=============================================================================
3495 * Return mesh editor
3497 //=============================================================================
3499 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
3501 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3505 _preMeshInfo->FullLoadFromFile();
3507 // Create MeshEditor
3509 _editor = new SMESH_MeshEditor_i( this, false );
3510 aMeshEdVar = _editor->_this();
3512 // Update Python script
3513 TPythonDump() << _editor << " = "
3514 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
3516 SMESH_CATCH( SMESH::throwCorbaException );
3518 return aMeshEdVar._retn();
3521 //=============================================================================
3523 * Return mesh edition previewer
3525 //=============================================================================
3527 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
3529 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3533 _preMeshInfo->FullLoadFromFile();
3535 if ( !_previewEditor )
3536 _previewEditor = new SMESH_MeshEditor_i( this, true );
3537 aMeshEdVar = _previewEditor->_this();
3539 SMESH_CATCH( SMESH::throwCorbaException );
3541 return aMeshEdVar._retn();
3544 //================================================================================
3546 * \brief Return true if the mesh has been edited since a last total re-compute
3547 * and those modifications may prevent successful partial re-compute
3549 //================================================================================
3551 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard()
3553 Unexpect aCatch(SALOME_SalomeException);
3554 return _impl->HasModificationsToDiscard();
3557 //================================================================================
3559 * \brief Return a random unique color
3561 //================================================================================
3563 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
3565 const int MAX_ATTEMPTS = 100;
3567 double tolerance = 0.5;
3568 SALOMEDS::Color col;
3572 // generate random color
3573 double red = (double)rand() / RAND_MAX;
3574 double green = (double)rand() / RAND_MAX;
3575 double blue = (double)rand() / RAND_MAX;
3576 // check existence in the list of the existing colors
3577 bool matched = false;
3578 std::list<SALOMEDS::Color>::const_iterator it;
3579 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3580 SALOMEDS::Color color = *it;
3581 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3582 matched = tol < tolerance;
3584 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3585 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3593 //=============================================================================
3595 * Set auto-color mode. If it is on, groups get unique random colors
3597 //=============================================================================
3599 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor)
3601 Unexpect aCatch(SALOME_SalomeException);
3602 _impl->SetAutoColor(theAutoColor);
3604 TPythonDump pyDump; // not to dump group->SetColor() from below code
3605 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3607 std::list<SALOMEDS::Color> aReservedColors;
3608 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3609 for ( ; it != _mapGroups.end(); it++ ) {
3610 if ( CORBA::is_nil( it->second )) continue;
3611 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3612 it->second->SetColor( aColor );
3613 aReservedColors.push_back( aColor );
3617 //=============================================================================
3619 * Return true if auto-color mode is on
3621 //=============================================================================
3623 CORBA::Boolean SMESH_Mesh_i::GetAutoColor()
3625 Unexpect aCatch(SALOME_SalomeException);
3626 return _impl->GetAutoColor();
3629 //=============================================================================
3631 * Check if there are groups with equal names
3633 //=============================================================================
3635 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3637 return _impl->HasDuplicatedGroupNamesMED();
3640 //================================================================================
3642 * \brief Care of a file before exporting mesh into it
3644 //================================================================================
3646 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3648 SMESH_File aFile( file, false );
3650 if ( aFile.exists() ) {
3651 // existing filesystem node
3652 if ( !aFile.isDirectory() ) {
3653 if ( aFile.openForWriting() ) {
3654 if ( overwrite && ! aFile.remove()) {
3655 msg << "Can't replace " << aFile.getName();
3658 msg << "Can't write into " << aFile.getName();
3661 msg << "Location " << aFile.getName() << " is not a file";
3665 // nonexisting file; check if it can be created
3666 if ( !aFile.openForWriting() ) {
3667 msg << "You cannot create the file "
3669 << ". Check the directory existence and access rights";
3677 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3684 std::string SMESH_Mesh_i::generateMeshName()
3686 string aMeshName = "Mesh";
3687 SALOMEDS::Study_var aStudy = SMESH_Gen_i::GetSMESHGen()->getStudyServant();
3688 if ( !aStudy->_is_nil() )
3690 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3691 if ( !aMeshSO->_is_nil() )
3693 CORBA::String_var name = aMeshSO->GetName();
3700 //================================================================================
3702 * \brief Prepare a file for export and pass names of mesh groups from study to mesh DS
3703 * \param file - file name
3704 * \param overwrite - to erase the file or not
3705 * \retval string - mesh name
3707 //================================================================================
3709 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3710 CORBA::Boolean overwrite)
3713 PrepareForWriting(file, overwrite);
3714 string aMeshName(this->generateMeshName());
3715 SALOMEDS::Study_var aStudy = SMESH_Gen_i::GetSMESHGen()->getStudyServant();
3716 if ( !aStudy->_is_nil() ) {
3717 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3718 if ( !aMeshSO->_is_nil() ) {
3719 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3720 if ( !aStudy->GetProperties()->IsLocked() )
3722 SALOMEDS::GenericAttribute_wrap anAttr;
3723 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3724 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3725 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3726 ASSERT(!aFileName->_is_nil());
3727 aFileName->SetValue(file);
3728 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3729 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3730 ASSERT(!aFileType->_is_nil());
3731 aFileType->SetValue("FICHIERMED");
3735 // Update Python script
3736 // set name of mesh before export
3737 TPythonDump() << _gen_i << ".SetName("
3738 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3740 // check names of groups
3746 //================================================================================
3748 * \brief Export to MED file
3750 //================================================================================
3752 void SMESH_Mesh_i::ExportMED(const char* file,
3753 CORBA::Boolean auto_groups,
3754 CORBA::Long version,
3755 CORBA::Boolean overwrite,
3756 CORBA::Boolean autoDimension)
3758 //MESSAGE("MED minor version: "<< minor);
3761 _preMeshInfo->FullLoadFromFile();
3763 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3764 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3766 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3768 << "auto_groups=" <<auto_groups << ", "
3769 << "version=" << version << ", "
3770 << "overwrite=" << overwrite << ", "
3771 << "meshPart=None, "
3772 << "autoDimension=" << autoDimension << " )";
3774 SMESH_CATCH( SMESH::throwCorbaException );
3777 CORBA::LongLong SMESH_Mesh_i::ExportMEDCoupling(CORBA::Boolean auto_groups, CORBA::Boolean autoDimension)
3779 MEDCoupling::MCAuto<MEDCoupling::DataArrayByte> data;
3781 // TODO : Fix me ! 2 next lines are required
3782 if( !this->_gen_i->isSSLMode() )
3783 SMESH::throwCorbaException("SMESH_Mesh_i::ExportMEDCoupling : only for embedded mode !");
3785 _preMeshInfo->FullLoadFromFile();
3787 string aMeshName = this->generateMeshName();
3788 data = _impl->ExportMEDCoupling( aMeshName.c_str(), auto_groups, 0, autoDimension );
3789 SMESH_CATCH( SMESH::throwCorbaException );
3790 MEDCoupling::DataArrayByte *ret(data.retn());
3791 return reinterpret_cast<CORBA::LongLong>(ret);
3794 //================================================================================
3796 * \brief Export a mesh to a DAT file
3798 //================================================================================
3800 void SMESH_Mesh_i::ExportDAT (const char *file, CORBA::Boolean renumber )
3804 _preMeshInfo->FullLoadFromFile();
3806 // check names of groups
3808 // Update Python script
3809 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3810 << ".ExportDAT( r'" << file<< ", " << renumber << "' )";
3813 PrepareForWriting( file );
3814 _impl->ExportDAT( file, /*part=*/nullptr, renumber );
3816 SMESH_CATCH( SMESH::throwCorbaException );
3819 //================================================================================
3821 * \brief Export a mesh to an UNV file
3823 //================================================================================
3825 void SMESH_Mesh_i::ExportUNV (const char *file, CORBA::Boolean renumber)
3829 _preMeshInfo->FullLoadFromFile();
3831 // check names of groups
3833 // Update Python script
3834 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3835 << ".ExportUNV( r'" << file << "', " << renumber << " )";
3838 PrepareForWriting( file );
3839 _impl->ExportUNV( file, /*part=*/nullptr, renumber );
3841 SMESH_CATCH( SMESH::throwCorbaException );
3844 //================================================================================
3846 * \brief Export a mesh to an STL file
3848 //================================================================================
3850 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3854 _preMeshInfo->FullLoadFromFile();
3856 // check names of groups
3858 // Update Python script
3859 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3860 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3862 CORBA::String_var name;
3863 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3864 if ( !so->_is_nil() )
3865 name = so->GetName();
3868 PrepareForWriting( file );
3869 _impl->ExportSTL( file, isascii, name.in() );
3871 SMESH_CATCH( SMESH::throwCorbaException );
3874 //================================================================================
3879 MEDFileSpeCls(const char * file,
3880 CORBA::Boolean overwrite,
3881 CORBA::Long version)
3882 :_file(file), _overwrite(overwrite), _version(version)
3884 std::string prepareMeshNameAndGroups(SMESH_Mesh_i& self)
3886 return self.prepareMeshNameAndGroups(_file.c_str(),_overwrite);
3889 void exportTo(SMESH_Mesh *mesh, const std::string& aMeshName, CORBA::Boolean auto_groups,
3890 SMESH_MeshPartDS* partDS, CORBA::Boolean autoDimension, bool have0dField,
3891 CORBA::Double ZTolerance, CORBA::Boolean saveNumbers )
3893 mesh->ExportMED( _file.c_str(), aMeshName.c_str(), auto_groups, _version,
3894 partDS, autoDimension, have0dField, ZTolerance, saveNumbers );
3897 void exportField(SMESH_Mesh_i& self, const std::string& aMeshName, bool have0dField,
3898 SMESHDS_Mesh *meshDS, const GEOM::ListOfFields& fields,
3899 const char*geomAssocFields)
3901 DriverMED_W_Field fieldWriter;
3902 fieldWriter.SetFile( _file.c_str() );
3903 fieldWriter.SetMeshName( aMeshName );
3904 fieldWriter.AddODOnVertices( have0dField );
3905 self.exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3908 void prepareForWriting(SMESH_Mesh_i& self) { self.PrepareForWriting(_file.c_str(), _overwrite); }
3912 CORBA::Boolean _overwrite;
3913 CORBA::Long _version;
3916 //================================================================================
3918 * \brief Export a part of mesh to a med file
3920 //================================================================================
3922 template<class SPECLS>
3923 void SMESH_Mesh_i::ExportPartToMEDCommon(SPECLS& speCls,
3924 SMESH::SMESH_IDSource_ptr meshPart,
3925 CORBA::Boolean auto_groups,
3926 CORBA::Boolean autoDimension,
3927 const GEOM::ListOfFields& fields,
3928 const char* geomAssocFields,
3929 CORBA::Double ZTolerance,
3930 CORBA::Boolean saveNumbers)
3934 _preMeshInfo->FullLoadFromFile();
3937 bool have0dField = false;
3938 if ( fields.length() > 0 )
3940 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3941 if ( shapeToMesh->_is_nil() )
3942 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3944 for ( size_t i = 0; i < fields.length(); ++i )
3946 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3947 THROW_SALOME_CORBA_EXCEPTION
3948 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3949 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3950 if ( fieldShape->_is_nil() )
3951 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3952 if ( !fieldShape->IsSame( shapeToMesh ) )
3953 THROW_SALOME_CORBA_EXCEPTION( "Field defined not on shape", SALOME::BAD_PARAM);
3954 if ( fields[i]->GetDimension() == 0 )
3957 if ( geomAssocFields )
3958 for ( int i = 0; geomAssocFields[i]; ++i )
3959 switch ( geomAssocFields[i] ) {
3960 case 'v':case 'e':case 'f':case 's': break;
3961 case 'V':case 'E':case 'F':case 'S': break;
3962 default: THROW_SALOME_CORBA_EXCEPTION
3963 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3967 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3971 string aMeshName = "Mesh";
3972 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3973 if ( CORBA::is_nil( meshPart ) ||
3974 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3976 aMeshName = speCls.prepareMeshNameAndGroups(*this);
3977 speCls.exportTo(_impl, aMeshName, auto_groups, nullptr, autoDimension,
3978 have0dField, ZTolerance, saveNumbers );
3979 meshDS = _impl->GetMeshDS();
3984 _preMeshInfo->FullLoadFromFile();
3986 speCls.prepareForWriting(*this);
3988 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3989 if ( !SO->_is_nil() ) {
3990 CORBA::String_var name = SO->GetName();
3994 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3995 speCls.exportTo(_impl, aMeshName, auto_groups, partDS, autoDimension,
3996 have0dField, ZTolerance, saveNumbers);
3997 meshDS = tmpDSDeleter._obj = partDS;
4002 if ( _impl->HasShapeToMesh() )
4004 speCls.exportField( *this, aMeshName, have0dField, meshDS, fields, geomAssocFields);
4006 SMESH_CATCH( SMESH::throwCorbaException );
4009 //================================================================================
4011 * \brief Export a part of mesh to a med file
4013 //================================================================================
4015 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
4017 CORBA::Boolean auto_groups,
4018 CORBA::Long version,
4019 CORBA::Boolean overwrite,
4020 CORBA::Boolean autoDimension,
4021 const GEOM::ListOfFields& fields,
4022 const char* geomAssocFields,
4023 CORBA::Double ZTolerance,
4024 CORBA::Boolean saveNumbers)
4026 MESSAGE("MED version: "<< version);
4028 MEDFileSpeCls spe( file, overwrite, version );
4029 this->ExportPartToMEDCommon( spe, meshPart, auto_groups, autoDimension, fields,
4030 geomAssocFields, ZTolerance, saveNumbers );
4033 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
4034 goList->length( fields.length() );
4035 for ( size_t i = 0; i < fields.length(); ++i )
4037 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
4040 TPythonDump() << _this() << ".ExportPartToMED( "
4041 << meshPart << ", r'"
4043 << auto_groups << ", "
4045 << overwrite << ", "
4046 << autoDimension << ", "
4048 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
4049 << TVar( ZTolerance ) << ", "
4052 SMESH_CATCH( SMESH::throwCorbaException );
4055 //================================================================================
4057 class MEDFileMemSpeCls
4060 std::string prepareMeshNameAndGroups(SMESH_Mesh_i& self) { return self.generateMeshName(); }
4062 void exportTo(SMESH_Mesh *mesh, const std::string& aMeshName, CORBA::Boolean auto_groups,
4063 SMESH_MeshPartDS* partDS, CORBA::Boolean autoDimension, bool have0dField,
4064 CORBA::Double ZTolerance, CORBA::Boolean saveNumbers )
4066 _res = mesh->ExportMEDCoupling(aMeshName.c_str(), auto_groups, partDS,
4067 autoDimension, have0dField, ZTolerance, saveNumbers );
4069 void prepareForWriting(SMESH_Mesh_i& /*self*/) { /* nothing here */ }
4071 void exportField(SMESH_Mesh_i& self, const std::string& aMeshName, bool have0dField,
4072 SMESHDS_Mesh *meshDS, const GEOM::ListOfFields& fields,
4073 const char*geomAssocFields)
4075 DriverMED_W_Field_Mem fieldWriter(_res);
4076 fieldWriter.SetMeshName( aMeshName );
4077 fieldWriter.AddODOnVertices( have0dField );
4078 self.exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
4079 _res = fieldWriter.getData();
4082 MEDCoupling::MCAuto<MEDCoupling::DataArrayByte> getData() { return _res; }
4085 MEDCoupling::MCAuto<MEDCoupling::DataArrayByte> _res;
4088 //================================================================================
4090 * \brief Export a part of mesh to a MEDCoupling DS
4092 //================================================================================
4094 CORBA::LongLong SMESH_Mesh_i::ExportPartToMEDCoupling(SMESH::SMESH_IDSource_ptr meshPart,
4095 CORBA::Boolean auto_groups,
4096 CORBA::Boolean autoDimension,
4097 const GEOM::ListOfFields& fields,
4098 const char* geomAssocFields,
4099 CORBA::Double ZTolerance,
4100 CORBA::Boolean saveNumbers)
4102 MEDCoupling::MCAuto<MEDCoupling::DataArrayByte> data;
4105 if( !this->_gen_i->isSSLMode() )
4106 SMESH::throwCorbaException("SMESH_Mesh_i::ExportPartToMEDCoupling : only for embedded mode !");
4108 MEDFileMemSpeCls spe;
4109 this->ExportPartToMEDCommon( spe, meshPart, auto_groups, autoDimension, fields, geomAssocFields,
4110 ZTolerance, saveNumbers );
4111 data = spe.getData();
4113 SMESH_CATCH( SMESH::throwCorbaException );
4115 MEDCoupling::DataArrayByte *ret(data.retn());
4116 return reinterpret_cast<CORBA::LongLong>(ret);
4119 //================================================================================
4121 * Write GEOM fields to MED file
4123 //================================================================================
4125 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
4126 SMESHDS_Mesh* meshDS,
4127 const GEOM::ListOfFields& fields,
4128 const char* geomAssocFields)
4130 #define METH "SMESH_Mesh_i::exportMEDFields() "
4132 if (( fields.length() < 1 ) &&
4133 ( !geomAssocFields || !geomAssocFields[0] ))
4136 std::vector< std::vector< double > > dblVals;
4137 std::vector< std::vector< int > > intVals;
4138 std::vector< int > subIdsByDim[ 4 ];
4139 const double noneDblValue = 0.;
4140 const double noneIntValue = 0;
4142 for ( size_t iF = 0; iF < fields.length(); ++iF )
4146 int dim = fields[ iF ]->GetDimension();
4147 SMDSAbs_ElementType elemType;
4148 TopAbs_ShapeEnum shapeType;
4150 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
4151 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
4152 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
4153 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
4155 continue; // skip fields on whole shape
4157 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
4158 if ( dataType == GEOM::FDT_String )
4160 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
4161 if ( stepIDs->length() < 1 )
4163 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
4164 if ( comps->length() < 1 )
4166 CORBA::String_var name = fields[ iF ]->GetName();
4168 if ( !fieldWriter.Set( meshDS,
4172 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
4175 for ( size_t iC = 0; iC < comps->length(); ++iC )
4176 fieldWriter.SetCompName( iC, comps[ iC ].in() );
4178 dblVals.resize( comps->length() );
4179 intVals.resize( comps->length() );
4181 // find sub-shape IDs
4183 std::vector< int >& subIds = subIdsByDim[ dim ];
4184 if ( subIds.empty() )
4185 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
4186 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
4187 subIds.push_back( id );
4191 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
4195 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
4197 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
4198 if ( step->_is_nil() )
4201 CORBA::Long stamp = step->GetStamp();
4202 CORBA::Long id = step->GetID();
4203 fieldWriter.SetDtIt( int( stamp ), int( id ));
4205 // fill dblVals or intVals
4206 for ( size_t iC = 0; iC < comps->length(); ++iC )
4207 if ( dataType == GEOM::FDT_Double )
4209 dblVals[ iC ].clear();
4210 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
4214 intVals[ iC ].clear();
4215 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
4219 case GEOM::FDT_Double:
4221 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
4222 if ( dblStep->_is_nil() ) continue;
4223 GEOM::ListOfDouble_var vv = dblStep->GetValues();
4224 if ( vv->length() != subIds.size() * comps->length() )
4225 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
4226 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
4227 for ( size_t iC = 0; iC < comps->length(); ++iC )
4228 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
4233 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
4234 if ( intStep->_is_nil() ) continue;
4235 GEOM::ListOfLong_var vv = intStep->GetValues();
4236 if ( vv->length() != subIds.size() * comps->length() )
4237 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
4238 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
4239 for ( size_t iC = 0; iC < comps->length(); ++iC )
4240 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
4243 case GEOM::FDT_Bool:
4245 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
4246 if ( boolStep->_is_nil() ) continue;
4247 GEOM::short_array_var vv = boolStep->GetValues();
4248 if ( vv->length() != subIds.size() * comps->length() )
4249 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
4250 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
4251 for ( size_t iC = 0; iC < comps->length(); ++iC )
4252 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
4258 // pass values to fieldWriter
4259 elemIt = fieldWriter.GetOrderedElems();
4260 if ( dataType == GEOM::FDT_Double )
4261 while ( elemIt->more() )
4263 const SMDS_MeshElement* e = elemIt->next();
4264 const int shapeID = e->getshapeId();
4265 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
4266 for ( size_t iC = 0; iC < comps->length(); ++iC )
4267 fieldWriter.AddValue( noneDblValue );
4269 for ( size_t iC = 0; iC < comps->length(); ++iC )
4270 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
4273 while ( elemIt->more() )
4275 const SMDS_MeshElement* e = elemIt->next();
4276 const int shapeID = e->getshapeId();
4277 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
4278 for ( size_t iC = 0; iC < comps->length(); ++iC )
4279 fieldWriter.AddValue( (double) noneIntValue );
4281 for ( size_t iC = 0; iC < comps->length(); ++iC )
4282 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
4286 fieldWriter.Perform();
4287 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4288 if ( res && res->IsKO() )
4290 if ( res->myComment.empty() )
4291 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4293 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4299 if ( !geomAssocFields || !geomAssocFields[0] )
4302 // write geomAssocFields
4304 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
4305 shapeDim[ TopAbs_COMPOUND ] = 3;
4306 shapeDim[ TopAbs_COMPSOLID ] = 3;
4307 shapeDim[ TopAbs_SOLID ] = 3;
4308 shapeDim[ TopAbs_SHELL ] = 2;
4309 shapeDim[ TopAbs_FACE ] = 2;
4310 shapeDim[ TopAbs_WIRE ] = 1;
4311 shapeDim[ TopAbs_EDGE ] = 1;
4312 shapeDim[ TopAbs_VERTEX ] = 0;
4313 shapeDim[ TopAbs_SHAPE ] = 3;
4315 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
4317 std::vector< std::string > compNames;
4318 switch ( geomAssocFields[ iF ]) {
4320 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
4321 compNames.push_back( "dim" );
4324 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
4327 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
4330 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
4334 compNames.push_back( "id" );
4335 for ( size_t iC = 0; iC < compNames.size(); ++iC )
4336 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
4338 fieldWriter.SetDtIt( -1, -1 );
4340 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
4344 if ( compNames.size() == 2 ) // _vertices_
4345 while ( elemIt->more() )
4347 const SMDS_MeshElement* e = elemIt->next();
4348 const int shapeID = e->getshapeId();
4351 fieldWriter.AddValue( (double) -1 );
4352 fieldWriter.AddValue( (double) -1 );
4356 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
4357 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
4358 fieldWriter.AddValue( (double) shapeID );
4362 while ( elemIt->more() )
4364 const SMDS_MeshElement* e = elemIt->next();
4365 const int shapeID = e->getshapeId();
4367 fieldWriter.AddValue( (double) -1 );
4369 fieldWriter.AddValue( (double) shapeID );
4373 fieldWriter.Perform();
4374 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4375 if ( res && res->IsKO() )
4377 if ( res->myComment.empty() )
4378 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4380 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4383 } // loop on geomAssocFields
4388 //================================================================================
4390 * \brief Export a part of mesh to a DAT file
4392 //================================================================================
4394 void SMESH_Mesh_i::ExportPartToDAT(SMESH::SMESH_IDSource_ptr meshPart,
4396 CORBA::Boolean renumber )
4400 SMESH_MeshPartDS partDS( meshPart );
4401 _impl->ExportDAT( file, &partDS, renumber );
4403 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4404 << ".ExportPartToDAT( " << meshPart << ", r'" << file << ", " << renumber << "' )";
4406 SMESH_CATCH( SMESH::throwCorbaException );
4408 //================================================================================
4410 * \brief Export a part of mesh to an UNV file
4412 //================================================================================
4414 void SMESH_Mesh_i::ExportPartToUNV(SMESH::SMESH_IDSource_ptr meshPart,
4416 CORBA::Boolean renumber)
4420 _preMeshInfo->FullLoadFromFile();
4422 PrepareForWriting(file);
4424 SMESH_MeshPartDS partDS( meshPart );
4425 _impl->ExportUNV(file, &partDS, renumber );
4427 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4428 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << ", " << renumber << "' )";
4430 SMESH_CATCH( SMESH::throwCorbaException );
4432 //================================================================================
4434 * \brief Export a part of mesh to an STL file
4436 //================================================================================
4438 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
4440 ::CORBA::Boolean isascii)
4444 _preMeshInfo->FullLoadFromFile();
4446 PrepareForWriting(file);
4448 CORBA::String_var name;
4449 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4450 if ( !so->_is_nil() )
4451 name = so->GetName();
4453 SMESH_MeshPartDS partDS( meshPart );
4454 _impl->ExportSTL( file, isascii, name.in(), &partDS );
4456 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
4457 << meshPart<< ", r'" << file << "', " << isascii << ")";
4459 SMESH_CATCH( SMESH::throwCorbaException );
4462 //================================================================================
4464 * \brief Export a part of mesh to an STL file
4466 //================================================================================
4468 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
4470 CORBA::Boolean overwrite,
4471 CORBA::Boolean groupElemsByType)
4476 _preMeshInfo->FullLoadFromFile();
4478 PrepareForWriting(file,overwrite);
4480 std::string meshName("");
4481 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4482 if ( !so->_is_nil() )
4484 CORBA::String_var name = so->GetName();
4485 meshName = name.in();
4489 SMESH_MeshPartDS partDS( meshPart );
4490 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
4492 SMESH_CATCH( SMESH::throwCorbaException );
4494 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
4495 << meshPart<< ", r'" << file << "', " << overwrite << ")";
4497 SMESH_CATCH( SMESH::throwCorbaException );
4500 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
4504 //================================================================================
4506 * \brief Export a part of mesh to a GMF file
4508 //================================================================================
4510 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
4512 bool withRequiredGroups)
4516 _preMeshInfo->FullLoadFromFile();
4518 PrepareForWriting(file,/*overwrite=*/true);
4520 SMESH_MeshPartDS partDS( meshPart );
4521 _impl->ExportGMF(file, &partDS, withRequiredGroups);
4523 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
4524 << meshPart<< ", r'"
4526 << withRequiredGroups << ")";
4528 SMESH_CATCH( SMESH::throwCorbaException );
4531 //=============================================================================
4533 * Return computation progress [0.,1]
4535 //=============================================================================
4537 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
4541 return _impl->GetComputeProgress();
4543 SMESH_CATCH( SMESH::doNothing );
4547 //================================================================================
4549 * \brief Return nb of nodes
4551 //================================================================================
4553 SMESH::smIdType SMESH_Mesh_i::NbNodes()
4555 Unexpect aCatch(SALOME_SalomeException);
4557 return _preMeshInfo->NbNodes();
4559 return _impl->NbNodes();
4562 //================================================================================
4564 * \brief Return nb of elements
4566 //================================================================================
4568 SMESH::smIdType SMESH_Mesh_i::NbElements()
4570 Unexpect aCatch(SALOME_SalomeException);
4572 return _preMeshInfo->NbElements();
4574 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
4577 //================================================================================
4579 * \brief Return nb of 0D elements
4581 //================================================================================
4583 SMESH::smIdType SMESH_Mesh_i::Nb0DElements()
4585 Unexpect aCatch(SALOME_SalomeException);
4587 return _preMeshInfo->Nb0DElements();
4589 return _impl->Nb0DElements();
4592 //================================================================================
4594 * \brief Return nb of BALL elements
4596 //================================================================================
4598 SMESH::smIdType SMESH_Mesh_i::NbBalls()
4600 Unexpect aCatch(SALOME_SalomeException);
4602 return _preMeshInfo->NbBalls();
4604 return _impl->NbBalls();
4607 //================================================================================
4609 * \brief Return nb of 1D elements
4611 //================================================================================
4613 SMESH::smIdType SMESH_Mesh_i::NbEdges()
4615 Unexpect aCatch(SALOME_SalomeException);
4617 return _preMeshInfo->NbEdges();
4619 return _impl->NbEdges();
4622 //================================================================================
4624 * \brief Return nb of edges
4626 //================================================================================
4628 SMESH::smIdType SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
4630 Unexpect aCatch(SALOME_SalomeException);
4632 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
4634 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
4637 //================================================================================
4639 * \brief Return nb of faces
4641 //================================================================================
4643 SMESH::smIdType SMESH_Mesh_i::NbFaces()
4645 Unexpect aCatch(SALOME_SalomeException);
4647 return _preMeshInfo->NbFaces();
4649 return _impl->NbFaces();
4652 //================================================================================
4654 * \brief Return nb of tringles
4656 //================================================================================
4658 SMESH::smIdType SMESH_Mesh_i::NbTriangles()
4660 Unexpect aCatch(SALOME_SalomeException);
4662 return _preMeshInfo->NbTriangles();
4664 return _impl->NbTriangles();
4667 //================================================================================
4669 * \brief Return nb of bi-quadratic triangles
4671 //================================================================================
4673 SMESH::smIdType SMESH_Mesh_i::NbBiQuadTriangles()
4675 Unexpect aCatch(SALOME_SalomeException);
4677 return _preMeshInfo->NbBiQuadTriangles();
4679 return _impl->NbBiQuadTriangles();
4682 SMESH::smIdType SMESH_Mesh_i::NbQuadrangles()
4684 Unexpect aCatch(SALOME_SalomeException);
4686 return _preMeshInfo->NbQuadrangles();
4688 return _impl->NbQuadrangles();
4691 SMESH::smIdType SMESH_Mesh_i::NbBiQuadQuadrangles()
4693 Unexpect aCatch(SALOME_SalomeException);
4695 return _preMeshInfo->NbBiQuadQuadrangles();
4697 return _impl->NbBiQuadQuadrangles();
4700 SMESH::smIdType SMESH_Mesh_i::NbPolygons()
4702 Unexpect aCatch(SALOME_SalomeException);
4704 return _preMeshInfo->NbPolygons();
4706 return _impl->NbPolygons();
4709 SMESH::smIdType SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order)
4711 Unexpect aCatch(SALOME_SalomeException);
4713 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
4715 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
4718 SMESH::smIdType SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
4720 Unexpect aCatch(SALOME_SalomeException);
4722 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
4724 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
4727 SMESH::smIdType SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
4729 Unexpect aCatch(SALOME_SalomeException);
4731 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
4733 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
4736 SMESH::smIdType SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
4738 Unexpect aCatch(SALOME_SalomeException);
4740 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
4742 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
4745 //=============================================================================
4747 SMESH::smIdType SMESH_Mesh_i::NbVolumes()
4749 Unexpect aCatch(SALOME_SalomeException);
4751 return _preMeshInfo->NbVolumes();
4753 return _impl->NbVolumes();
4756 SMESH::smIdType SMESH_Mesh_i::NbTetras()
4758 Unexpect aCatch(SALOME_SalomeException);
4760 return _preMeshInfo->NbTetras();
4762 return _impl->NbTetras();
4765 SMESH::smIdType SMESH_Mesh_i::NbHexas()
4767 Unexpect aCatch(SALOME_SalomeException);
4769 return _preMeshInfo->NbHexas();
4771 return _impl->NbHexas();
4774 SMESH::smIdType SMESH_Mesh_i::NbTriQuadraticHexas()
4776 Unexpect aCatch(SALOME_SalomeException);
4778 return _preMeshInfo->NbTriQuadHexas();
4780 return _impl->NbTriQuadraticHexas();
4783 SMESH::smIdType SMESH_Mesh_i::NbPyramids()
4785 Unexpect aCatch(SALOME_SalomeException);
4787 return _preMeshInfo->NbPyramids();
4789 return _impl->NbPyramids();
4792 SMESH::smIdType SMESH_Mesh_i::NbPrisms()
4794 Unexpect aCatch(SALOME_SalomeException);
4796 return _preMeshInfo->NbPrisms();
4798 return _impl->NbPrisms();
4801 SMESH::smIdType SMESH_Mesh_i::NbHexagonalPrisms()
4803 Unexpect aCatch(SALOME_SalomeException);
4805 return _preMeshInfo->NbHexPrisms();
4807 return _impl->NbHexagonalPrisms();
4810 SMESH::smIdType SMESH_Mesh_i::NbPolyhedrons()
4812 Unexpect aCatch(SALOME_SalomeException);
4814 return _preMeshInfo->NbPolyhedrons();
4816 return _impl->NbPolyhedrons();
4819 SMESH::smIdType SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4821 Unexpect aCatch(SALOME_SalomeException);
4823 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4825 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4828 SMESH::smIdType SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4830 Unexpect aCatch(SALOME_SalomeException);
4832 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4834 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4837 SMESH::smIdType SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4839 Unexpect aCatch(SALOME_SalomeException);
4841 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4843 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4846 SMESH::smIdType SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4848 Unexpect aCatch(SALOME_SalomeException);
4850 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4852 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4855 SMESH::smIdType SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4857 Unexpect aCatch(SALOME_SalomeException);
4859 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4861 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4864 //=============================================================================
4866 * Return nb of published sub-meshes
4868 //=============================================================================
4870 SMESH::smIdType SMESH_Mesh_i::NbSubMesh()
4872 Unexpect aCatch(SALOME_SalomeException);
4873 return _mapSubMesh_i.size();
4876 //=============================================================================
4878 * Dumps mesh into a string
4880 //=============================================================================
4882 char* SMESH_Mesh_i::Dump()
4886 return CORBA::string_dup( os.str().c_str() );
4889 //=============================================================================
4891 * Method of SMESH_IDSource interface
4893 //=============================================================================
4895 SMESH::smIdType_array* SMESH_Mesh_i::GetIDs()
4897 return GetElementsId();
4900 //=============================================================================
4902 * Return ids of all elements
4904 //=============================================================================
4906 SMESH::smIdType_array* SMESH_Mesh_i::GetElementsId()
4908 Unexpect aCatch(SALOME_SalomeException);
4910 _preMeshInfo->FullLoadFromFile();
4912 SMESH::smIdType_array_var aResult = new SMESH::smIdType_array();
4913 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4915 if ( aSMESHDS_Mesh == NULL )
4916 return aResult._retn();
4918 smIdType nbElements = NbElements();
4919 aResult->length( nbElements );
4920 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4921 for ( smIdType i = 0, n = nbElements; i < n && anIt->more(); i++ )
4922 aResult[i] = anIt->next()->GetID();
4924 return aResult._retn();
4928 //=============================================================================
4930 * Return ids of all elements of given type
4932 //=============================================================================
4934 SMESH::smIdType_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4936 Unexpect aCatch(SALOME_SalomeException);
4938 _preMeshInfo->FullLoadFromFile();
4940 SMESH::smIdType_array_var aResult = new SMESH::smIdType_array();
4941 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4943 if ( aSMESHDS_Mesh == NULL )
4944 return aResult._retn();
4946 smIdType nbElements = NbElements();
4948 // No sense in returning ids of elements along with ids of nodes:
4949 // when theElemType == SMESH::ALL, return node ids only if
4950 // there are no elements
4951 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4952 return GetNodesId();
4954 aResult->length( nbElements );
4958 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4959 while ( i < nbElements && anIt->more() )
4960 aResult[i++] = anIt->next()->GetID();
4962 aResult->length( i );
4964 return aResult._retn();
4967 //=============================================================================
4969 * Return ids of all nodes
4971 //=============================================================================
4973 SMESH::smIdType_array* SMESH_Mesh_i::GetNodesId()
4975 Unexpect aCatch(SALOME_SalomeException);
4977 _preMeshInfo->FullLoadFromFile();
4979 SMESH::smIdType_array_var aResult = new SMESH::smIdType_array();
4980 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4982 if ( aMeshDS == NULL )
4983 return aResult._retn();
4985 smIdType nbNodes = NbNodes();
4986 aResult->length( nbNodes );
4987 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4988 for ( smIdType i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4989 aResult[i] = anIt->next()->GetID();
4991 return aResult._retn();
4994 //=============================================================================
4996 * Return type of the given element
4998 //=============================================================================
5000 SMESH::ElementType SMESH_Mesh_i::GetElementType( const SMESH::smIdType id, const bool iselem )
5002 SMESH::ElementType type = SMESH::ALL;
5006 _preMeshInfo->FullLoadFromFile();
5008 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
5010 SMESH_CATCH( SMESH::throwCorbaException );
5015 //=============================================================================
5017 * Return geometric type of the given element
5019 //=============================================================================
5021 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const SMESH::smIdType id )
5024 _preMeshInfo->FullLoadFromFile();
5026 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
5028 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
5030 return ( SMESH::EntityType ) e->GetEntityType();
5033 //=============================================================================
5035 * Return type of the given element
5037 //=============================================================================
5039 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const SMESH::smIdType id )
5042 _preMeshInfo->FullLoadFromFile();
5044 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
5046 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
5048 return ( SMESH::GeometryType ) e->GetGeomType();
5051 //=============================================================================
5053 * Return ID of elements for given submesh
5055 //=============================================================================
5057 SMESH::smIdType_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
5059 SMESH::smIdType_array_var aResult = new SMESH::smIdType_array();
5063 _preMeshInfo->FullLoadFromFile();
5065 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
5066 if(!SM) return aResult._retn();
5068 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
5069 if(!SDSM) return aResult._retn();
5071 aResult->length(SDSM->NbElements());
5073 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
5075 while ( eIt->more() ) {
5076 aResult[i++] = eIt->next()->GetID();
5079 SMESH_CATCH( SMESH::throwCorbaException );
5081 return aResult._retn();
5084 //=============================================================================
5086 * Return ID of nodes for given sub-mesh
5087 * If param all==true - return all nodes, else -
5088 * Return only nodes on shapes.
5090 //=============================================================================
5092 SMESH::smIdType_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
5095 SMESH::smIdType_array_var aResult = new SMESH::smIdType_array();
5099 _preMeshInfo->FullLoadFromFile();
5101 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
5102 if(!SM) return aResult._retn();
5104 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
5105 if(!SDSM) return aResult._retn();
5107 set<smIdType> theElems;
5108 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
5109 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
5110 while ( nIt->more() ) {
5111 const SMDS_MeshNode* elem = nIt->next();
5112 theElems.insert( elem->GetID() );
5115 else { // all nodes of submesh elements
5116 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
5117 while ( eIt->more() ) {
5118 const SMDS_MeshElement* anElem = eIt->next();
5119 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
5120 while ( nIt->more() ) {
5121 const SMDS_MeshElement* elem = nIt->next();
5122 theElems.insert( elem->GetID() );
5127 aResult->length(theElems.size());
5128 set<smIdType>::iterator itElem;
5130 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
5131 aResult[i++] = *itElem;
5133 SMESH_CATCH( SMESH::throwCorbaException );
5135 return aResult._retn();
5138 //=============================================================================
5140 * Return type of elements for given sub-mesh
5142 //=============================================================================
5144 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
5146 SMESH::ElementType type = SMESH::ALL;
5150 _preMeshInfo->FullLoadFromFile();
5152 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
5153 if(!SM) return SMESH::ALL;
5155 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
5156 if(!SDSM) return SMESH::ALL;
5158 if(SDSM->NbElements()==0)
5159 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
5161 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
5162 const SMDS_MeshElement* anElem = eIt->next();
5164 type = ( SMESH::ElementType ) anElem->GetType();
5166 SMESH_CATCH( SMESH::throwCorbaException );
5172 //=============================================================================
5174 * Return pointer to _impl as an integer value. Is called from constructor of SMESH_Client
5176 //=============================================================================
5178 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
5181 _preMeshInfo->FullLoadFromFile();
5183 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
5184 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
5189 //=============================================================================
5191 * Get XYZ coordinates of node as list of double
5192 * If there is not node for given ID - return empty list
5194 //=============================================================================
5196 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const SMESH::smIdType id)
5199 _preMeshInfo->FullLoadFromFile();
5201 SMESH::double_array_var aResult = new SMESH::double_array();
5202 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5203 if ( aMeshDS == NULL )
5204 return aResult._retn();
5207 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
5209 return aResult._retn();
5213 aResult[0] = aNode->X();
5214 aResult[1] = aNode->Y();
5215 aResult[2] = aNode->Z();
5216 return aResult._retn();
5220 //=============================================================================
5222 * For given node return list of IDs of inverse elements
5223 * If there is not node for given ID - return empty list
5225 //=============================================================================
5227 SMESH::smIdType_array* SMESH_Mesh_i::GetNodeInverseElements(const SMESH::smIdType id,
5228 SMESH::ElementType elemType)
5231 _preMeshInfo->FullLoadFromFile();
5233 SMESH::smIdType_array_var aResult = new SMESH::smIdType_array();
5234 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5235 if ( aMeshDS == NULL )
5236 return aResult._retn();
5239 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
5241 return aResult._retn();
5243 // find inverse elements
5244 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
5245 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
5246 aResult->length( aNode->NbInverseElements( type ));
5247 for( smIdType i = 0; eIt->more(); ++i )
5249 const SMDS_MeshElement* elem = eIt->next();
5250 aResult[ i ] = elem->GetID();
5252 return aResult._retn();
5255 //=============================================================================
5257 * \brief Return position of a node on shape
5259 //=============================================================================
5261 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(SMESH::smIdType NodeID)
5264 _preMeshInfo->FullLoadFromFile();
5266 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
5267 aNodePosition->shapeID = 0;
5268 aNodePosition->shapeType = GEOM::SHAPE;
5270 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
5271 if ( !mesh ) return aNodePosition;
5273 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
5275 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
5277 aNodePosition->shapeID = aNode->getshapeId();
5278 switch ( pos->GetTypeOfPosition() ) {
5280 aNodePosition->shapeType = GEOM::EDGE;
5281 aNodePosition->params.length(1);
5282 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
5284 case SMDS_TOP_FACE: {
5285 SMDS_FacePositionPtr fPos = pos;
5286 aNodePosition->shapeType = GEOM::FACE;
5287 aNodePosition->params.length(2);
5288 aNodePosition->params[0] = fPos->GetUParameter();
5289 aNodePosition->params[1] = fPos->GetVParameter();
5292 case SMDS_TOP_VERTEX:
5293 aNodePosition->shapeType = GEOM::VERTEX;
5295 case SMDS_TOP_3DSPACE:
5296 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
5297 aNodePosition->shapeType = GEOM::SOLID;
5298 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
5299 aNodePosition->shapeType = GEOM::SHELL;
5305 return aNodePosition;
5308 //=============================================================================
5310 * \brief Return position of an element on shape
5312 //=============================================================================
5314 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(SMESH::smIdType ElemID)
5317 _preMeshInfo->FullLoadFromFile();
5319 SMESH::ElementPosition anElementPosition;
5320 anElementPosition.shapeID = 0;
5321 anElementPosition.shapeType = GEOM::SHAPE;
5323 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
5324 if ( !mesh ) return anElementPosition;
5326 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
5328 anElementPosition.shapeID = anElem->getshapeId();
5329 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
5330 if ( !aSp.IsNull() ) {
5331 switch ( aSp.ShapeType() ) {
5333 anElementPosition.shapeType = GEOM::EDGE;
5336 anElementPosition.shapeType = GEOM::FACE;
5339 anElementPosition.shapeType = GEOM::VERTEX;
5342 anElementPosition.shapeType = GEOM::SOLID;
5345 anElementPosition.shapeType = GEOM::SHELL;
5351 return anElementPosition;
5354 //=============================================================================
5356 * If given element is node return IDs of shape from position
5357 * If there is not node for given ID - return -1
5359 //=============================================================================
5361 CORBA::Long SMESH_Mesh_i::GetShapeID(const SMESH::smIdType id)
5364 _preMeshInfo->FullLoadFromFile();
5366 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5367 if ( aMeshDS == NULL )
5371 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
5373 return aNode->getshapeId();
5380 //=============================================================================
5382 * For given element return ID of result shape after
5383 * ::FindShape() from SMESH_MeshEditor
5384 * If there is not element for given ID - return -1
5386 //=============================================================================
5388 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const SMESH::smIdType id)
5391 _preMeshInfo->FullLoadFromFile();
5393 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5394 if ( aMeshDS == NULL )
5397 // try to find element
5398 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5402 ::SMESH_MeshEditor aMeshEditor(_impl);
5403 int index = aMeshEditor.FindShape( elem );
5411 //=============================================================================
5413 * Return number of nodes for given element
5414 * If there is not element for given ID - return -1
5416 //=============================================================================
5418 CORBA::Short SMESH_Mesh_i::GetElemNbNodes(const SMESH::smIdType id)
5421 _preMeshInfo->FullLoadFromFile();
5423 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5424 if ( aMeshDS == NULL ) return -1;
5425 // try to find element
5426 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5427 if(!elem) return -1;
5428 return elem->NbNodes();
5432 //=============================================================================
5434 * Return ID of node by given index for given element
5435 * If there is not element for given ID - return -1
5436 * If there is not node for given index - return -2
5438 //=============================================================================
5440 SMESH::smIdType SMESH_Mesh_i::GetElemNode(const SMESH::smIdType id, const CORBA::Short index)
5443 _preMeshInfo->FullLoadFromFile();
5445 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5446 if ( aMeshDS == NULL ) return -1;
5447 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5448 if(!elem) return -1;
5449 if( index>=elem->NbNodes() || index<0 ) return -1;
5450 return elem->GetNode(index)->GetID();
5453 //=============================================================================
5455 * Return IDs of nodes of given element
5457 //=============================================================================
5459 SMESH::smIdType_array* SMESH_Mesh_i::GetElemNodes(const SMESH::smIdType id)
5462 _preMeshInfo->FullLoadFromFile();
5464 SMESH::smIdType_array_var aResult = new SMESH::smIdType_array();
5465 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5467 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
5469 aResult->length( elem->NbNodes() );
5470 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5471 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
5472 aResult[ i ] = n->GetID();
5475 return aResult._retn();
5478 //=============================================================================
5480 * Return true if given node is medium node
5481 * in given quadratic element
5483 //=============================================================================
5485 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const SMESH::smIdType ide, const SMESH::smIdType idn)
5488 _preMeshInfo->FullLoadFromFile();
5490 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5491 if ( aMeshDS == NULL ) return false;
5493 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5494 if(!aNode) return false;
5495 // try to find element
5496 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
5497 if(!elem) return false;
5499 return elem->IsMediumNode(aNode);
5503 //=============================================================================
5505 * Return true if given node is medium node
5506 * in one of quadratic elements
5508 //=============================================================================
5510 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const SMESH::smIdType idn,
5511 SMESH::ElementType theElemType)
5514 _preMeshInfo->FullLoadFromFile();
5516 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5517 if ( aMeshDS == NULL ) return false;
5520 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5521 if(!aNode) return false;
5523 SMESH_MesherHelper aHelper( *(_impl) );
5525 SMDSAbs_ElementType aType;
5526 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
5527 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
5528 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
5529 else aType = SMDSAbs_All;
5531 return aHelper.IsMedium(aNode,aType);
5535 //=============================================================================
5537 * Return number of edges for given element
5539 //=============================================================================
5541 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const SMESH::smIdType id)
5544 _preMeshInfo->FullLoadFromFile();
5546 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5547 if ( aMeshDS == NULL ) return -1;
5548 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5549 if(!elem) return -1;
5550 return elem->NbEdges();
5554 //=============================================================================
5556 * Return number of faces for given element
5558 //=============================================================================
5560 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const SMESH::smIdType id)
5563 _preMeshInfo->FullLoadFromFile();
5565 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5566 if ( aMeshDS == NULL ) return -1;
5567 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5568 if(!elem) return -1;
5569 return elem->NbFaces();
5572 //================================================================================
5574 * \brief Return nodes of given face (counted from zero) for given element.
5576 //================================================================================
5578 SMESH::smIdType_array* SMESH_Mesh_i::GetElemFaceNodes(SMESH::smIdType elemId,
5579 CORBA::Short faceIndex)
5582 _preMeshInfo->FullLoadFromFile();
5584 SMESH::smIdType_array_var aResult = new SMESH::smIdType_array();
5585 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5587 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
5589 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
5590 if ( faceIndex < vtool.NbFaces() )
5592 aResult->length( vtool.NbFaceNodes( faceIndex ));
5593 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
5594 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5595 aResult[ i ] = nn[ i ]->GetID();
5599 return aResult._retn();
5602 //================================================================================
5604 * \brief Return three components of normal of given mesh face.
5606 //================================================================================
5608 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
5609 CORBA::Boolean normalized)
5612 _preMeshInfo->FullLoadFromFile();
5614 SMESH::double_array_var aResult = new SMESH::double_array();
5616 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5619 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
5621 aResult->length( 3 );
5622 aResult[ 0 ] = normal.X();
5623 aResult[ 1 ] = normal.Y();
5624 aResult[ 2 ] = normal.Z();
5627 return aResult._retn();
5630 //================================================================================
5632 * \brief Return an element based on all given nodes.
5634 //================================================================================
5636 SMESH::smIdType SMESH_Mesh_i::FindElementByNodes(const SMESH::smIdType_array& nodes)
5639 _preMeshInfo->FullLoadFromFile();
5641 CORBA::Long elemID(0);
5642 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5644 vector< const SMDS_MeshNode * > nn( nodes.length() );
5645 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5646 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
5649 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
5650 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
5651 _impl->NbFaces ( ORDER_QUADRATIC ) ||
5652 _impl->NbVolumes( ORDER_QUADRATIC )))
5653 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
5655 if ( elem ) elemID = CORBA::Long( elem->GetID() );
5660 //================================================================================
5662 * \brief Return elements including all given nodes.
5664 //================================================================================
5666 SMESH::smIdType_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::smIdType_array& nodes,
5667 SMESH::ElementType elemType)
5670 _preMeshInfo->FullLoadFromFile();
5672 SMESH::smIdType_array_var result = new SMESH::smIdType_array();
5674 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5676 vector< const SMDS_MeshNode * > nn( nodes.length() );
5677 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5678 nn[i] = mesh->FindNode( nodes[i] );
5680 std::vector<const SMDS_MeshElement *> elems;
5681 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
5682 result->length( elems.size() );
5683 for ( size_t i = 0; i < elems.size(); ++i )
5684 result[i] = elems[i]->GetID();
5686 return result._retn();
5689 //=============================================================================
5691 * Return true if given element is polygon
5693 //=============================================================================
5695 CORBA::Boolean SMESH_Mesh_i::IsPoly(const SMESH::smIdType id)
5698 _preMeshInfo->FullLoadFromFile();
5700 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5701 if ( aMeshDS == NULL ) return false;
5702 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5703 if(!elem) return false;
5704 return elem->IsPoly();
5708 //=============================================================================
5710 * Return true if given element is quadratic
5712 //=============================================================================
5714 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const SMESH::smIdType id)
5717 _preMeshInfo->FullLoadFromFile();
5719 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5720 if ( aMeshDS == NULL ) return false;
5721 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5722 if(!elem) return false;
5723 return elem->IsQuadratic();
5726 //=============================================================================
5728 * Return diameter of ball discrete element or zero in case of an invalid \a id
5730 //=============================================================================
5732 CORBA::Double SMESH_Mesh_i::GetBallDiameter(SMESH::smIdType id)
5735 _preMeshInfo->FullLoadFromFile();
5737 if ( const SMDS_BallElement* ball =
5738 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
5739 return ball->GetDiameter();
5744 //=============================================================================
5746 * Return bary center for given element
5748 //=============================================================================
5750 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const SMESH::smIdType id)
5753 _preMeshInfo->FullLoadFromFile();
5755 SMESH::double_array_var aResult = new SMESH::double_array();
5756 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5757 if ( aMeshDS == NULL )
5758 return aResult._retn();
5760 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5762 return aResult._retn();
5764 if(elem->GetType()==SMDSAbs_Volume) {
5765 SMDS_VolumeTool aTool;
5766 if(aTool.Set(elem)) {
5768 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5773 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5775 double x=0., y=0., z=0.;
5776 for(; anIt->more(); ) {
5778 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5792 return aResult._retn();
5795 //================================================================================
5797 * \brief Create a group of elements preventing computation of a sub-shape
5799 //================================================================================
5801 SMESH::ListOfGroups*
5802 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5803 const char* theGroupName )
5805 Unexpect aCatch(SALOME_SalomeException);
5807 if ( !theGroupName || strlen( theGroupName) == 0 )
5808 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5810 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5811 ::SMESH_MeshEditor::ElemFeatures elemType;
5813 // submesh by subshape id
5814 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5815 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5818 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5819 if ( error && error->HasBadElems() )
5821 // sort bad elements by type
5822 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5823 const list<const SMDS_MeshElement*>& badElems =
5824 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5825 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5826 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5827 for ( ; elemIt != elemEnd; ++elemIt )
5829 const SMDS_MeshElement* elem = *elemIt;
5830 if ( !elem ) continue;
5832 if ( elem->GetID() < 1 )
5834 // elem is a temporary element, make a real element
5835 vector< const SMDS_MeshNode* > nodes;
5836 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5837 while ( nIt->more() && elem )
5839 nodes.push_back( nIt->next() );
5840 if ( nodes.back()->GetID() < 1 )
5841 elem = 0; // a temporary element on temporary nodes
5845 ::SMESH_MeshEditor editor( _impl );
5846 elem = editor.AddElement( nodes, elemType.Init( elem ));
5850 elemsByType[ elem->GetType() ].push_back( elem );
5853 // how many groups to create?
5855 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5856 nbTypes += int( !elemsByType[ i ].empty() );
5857 groups->length( nbTypes );
5860 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5862 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5863 if ( elems.empty() ) continue;
5865 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5866 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5868 SMESH::SMESH_Mesh_var mesh = _this();
5869 SALOMEDS::SObject_wrap aSO =
5870 _gen_i->PublishGroup( mesh, groups[ iG ],
5871 GEOM::GEOM_Object::_nil(), theGroupName);
5873 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5874 if ( !grp_i ) continue;
5876 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5877 for ( size_t iE = 0; iE < elems.size(); ++iE )
5878 grpDS->SMDSGroup().Add( elems[ iE ]);
5883 return groups._retn();
5886 //=============================================================================
5888 * Create and publish group servants if any groups were imported or created anyhow
5890 //=============================================================================
5892 void SMESH_Mesh_i::CreateGroupServants()
5894 SMESH::SMESH_Mesh_var aMesh = _this();
5897 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5898 while ( groupIt->more() )
5900 ::SMESH_Group* group = groupIt->next();
5901 int anId = group->GetID();
5903 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5904 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5906 addedIDs.insert( anId );
5908 SMESH_GroupBase_i* aGroupImpl;
5910 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5911 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5913 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5914 shape = groupOnGeom->GetShape();
5917 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5920 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5921 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5922 aGroupImpl->Register();
5924 // register CORBA object for persistence
5925 int nextId = _gen_i->RegisterObject( groupVar );
5926 MESSAGE( "Add group to map with id = "<< nextId);
5928 // publishing the groups in the study
5929 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5930 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5933 if ( !addedIDs.empty() )
5936 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
5937 for ( int index = 0; i_grp != _mapGroups.end(); ++index, ++i_grp )
5939 set<int>::iterator it = addedIDs.find( i_grp->first );
5940 if ( it != addedIDs.end() )
5942 TPythonDump() << i_grp->second << " = " << aMesh << ".GetGroups()[ "<< index << " ]";
5943 addedIDs.erase( it );
5944 if ( addedIDs.empty() )
5951 //=============================================================================
5953 * \brief Return true if all sub-meshes are computed OK - to update an icon
5955 //=============================================================================
5957 bool SMESH_Mesh_i::IsComputedOK()
5959 return _impl->IsComputedOK();
5962 //=============================================================================
5964 * \brief Return groups cantained in _mapGroups by their IDs
5966 //=============================================================================
5968 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5970 int nbGroups = groupIDs.size();
5971 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5972 aList->length( nbGroups );
5974 list<int>::const_iterator ids = groupIDs.begin();
5975 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5977 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5978 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5979 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5981 aList->length( nbGroups );
5982 return aList._retn();
5985 //=============================================================================
5987 * \brief Return information about imported file
5989 //=============================================================================
5991 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5993 SMESH::MedFileInfo_var res( _medFileInfo );
5994 if ( !res.operator->() ) {
5995 res = new SMESH::MedFileInfo;
5997 res->fileSize = res->major = res->minor = res->release = -1;
6002 //=======================================================================
6003 //function : FileInfoToString
6004 //purpose : Persistence of file info
6005 //=======================================================================
6007 std::string SMESH_Mesh_i::FileInfoToString()
6010 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
6012 s = SMESH_Comment( _medFileInfo->fileSize )
6013 << " " << _medFileInfo->major
6014 << " " << _medFileInfo->minor
6015 << " " << _medFileInfo->release
6016 << " " << _medFileInfo->fileName;
6021 //=======================================================================
6022 //function : FileInfoFromString
6023 //purpose : Persistence of file info
6024 //=======================================================================
6026 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
6028 std::string size, major, minor, release, fileName;
6029 std::istringstream is(info);
6030 is >> size >> major >> minor >> release;
6031 fileName = info.data() + ( size.size() + 1 +
6034 release.size()+ 1 );
6036 _medFileInfo = new SMESH::MedFileInfo();
6037 _medFileInfo->fileName = fileName.c_str();
6038 _medFileInfo->fileSize = atoi( size.c_str() );
6039 _medFileInfo->major = atoi( major.c_str() );
6040 _medFileInfo->minor = atoi( minor.c_str() );
6041 _medFileInfo->release = atoi( release.c_str() );
6044 //=============================================================================
6046 * \brief Pass names of mesh groups from study to mesh DS
6048 //=============================================================================
6050 void SMESH_Mesh_i::checkGroupNames()
6052 int nbGrp = NbGroups();
6056 SMESH::ListOfGroups* grpList = 0;
6057 // avoid dump of "GetGroups"
6059 // store python dump into a local variable inside local scope
6060 SMESH::TPythonDump pDump; // do not delete this line of code
6061 grpList = GetGroups();
6064 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
6065 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
6068 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
6069 if ( aGrpSO->_is_nil() )
6071 // correct name of the mesh group if necessary
6072 const char* guiName = aGrpSO->GetName();
6073 if ( strcmp(guiName, aGrp->GetName()) )
6074 aGrp->SetName( guiName );
6078 //=============================================================================
6080 * \brief Set list of notebook variables used for Mesh operations separated by ":" symbol
6082 //=============================================================================
6083 void SMESH_Mesh_i::SetParameters(const char* theParameters)
6085 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
6089 //=============================================================================
6091 * \brief Return list of notebook variables used for Mesh operations separated by ":" symbol
6093 //=============================================================================
6095 char* SMESH_Mesh_i::GetParameters()
6097 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
6100 //=============================================================================
6102 * \brief Return list of notebook variables used for last Mesh operation
6104 //=============================================================================
6105 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
6107 SMESH::string_array_var aResult = new SMESH::string_array();
6108 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
6110 CORBA::String_var aParameters = GetParameters();
6111 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::GetSMESHGen()->getStudyServant()->ParseVariables(aParameters);
6112 if ( aSections->length() > 0 ) {
6113 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
6114 aResult->length( aVars.length() );
6115 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
6116 aResult[i] = CORBA::string_dup( aVars[i] );
6119 return aResult._retn();
6122 //================================================================================
6124 * \brief Return types of elements it contains
6126 //================================================================================
6128 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
6131 return _preMeshInfo->GetTypes();
6133 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
6137 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
6138 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
6139 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
6140 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
6141 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
6142 if (_impl->NbNodes() &&
6143 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
6144 types->length( nbTypes );
6146 return types._retn();
6149 //================================================================================
6151 * \brief Return self
6153 //================================================================================
6155 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
6157 return SMESH::SMESH_Mesh::_duplicate( _this() );
6160 //================================================================================
6162 * \brief Return false if GetMeshInfo() return incorrect information that may
6163 * happen if mesh data is not yet fully loaded from the file of study.
6167 //================================================================================
6169 bool SMESH_Mesh_i::IsMeshInfoCorrect()
6171 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
6174 //=============================================================================
6176 * \brief Return number of mesh elements per each \a EntityType
6178 //=============================================================================
6180 SMESH::smIdType_array* SMESH_Mesh_i::GetMeshInfo()
6183 return _preMeshInfo->GetMeshInfo();
6185 SMESH::smIdType_array_var aRes = new SMESH::smIdType_array();
6186 aRes->length(SMESH::Entity_Last);
6187 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
6189 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6191 return aRes._retn();
6192 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
6193 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
6194 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
6195 return aRes._retn();
6198 //=============================================================================
6200 * \brief Return number of mesh elements per each \a ElementType
6202 //=============================================================================
6204 SMESH::smIdType_array* SMESH_Mesh_i::GetNbElementsByType()
6206 SMESH::smIdType_array_var aRes = new SMESH::smIdType_array();
6207 aRes->length(SMESH::NB_ELEMENT_TYPES);
6208 for (smIdType i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
6211 const SMDS_MeshInfo* meshInfo = 0;
6213 meshInfo = _preMeshInfo;
6214 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
6215 meshInfo = & meshDS->GetMeshInfo();
6218 for (smIdType i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
6219 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
6221 return aRes._retn();
6224 //=============================================================================
6226 * Collect statistic of mesh elements given by iterator
6228 //=============================================================================
6230 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
6231 SMESH::smIdType_array& theInfo)
6233 if (!theItr) return;
6234 while (theItr->more())
6235 theInfo[ theItr->next()->GetEntityType() ]++;
6237 //=============================================================================
6239 * Return mesh unstructed grid information.
6241 //=============================================================================
6243 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
6245 SALOMEDS::TMPFile_var SeqFile;
6246 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
6247 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
6249 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
6250 aWriter->WriteToOutputStringOn();
6251 aWriter->SetInputData(aGrid);
6252 aWriter->SetFileTypeToBinary();
6254 char* str = aWriter->GetOutputString();
6255 int size = aWriter->GetOutputStringLength();
6257 //Allocate octet buffer of required size
6258 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
6259 //Copy ostrstream content to the octet buffer
6260 memcpy(OctetBuf, str, size);
6261 //Create and return TMPFile
6262 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
6266 return SeqFile._retn();
6269 //=============================================================================
6270 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
6271 * SMESH::ElementType type) */
6273 using namespace SMESH::Controls;
6274 //-----------------------------------------------------------------------------
6275 struct PredicateIterator : public SMDS_ElemIterator
6277 SMDS_ElemIteratorPtr _elemIter;
6278 PredicatePtr _predicate;
6279 const SMDS_MeshElement* _elem;
6280 SMDSAbs_ElementType _type;
6282 PredicateIterator( SMDS_ElemIteratorPtr iterator,
6283 PredicatePtr predicate,
6284 SMDSAbs_ElementType type):
6285 _elemIter(iterator), _predicate(predicate), _type(type)
6293 virtual const SMDS_MeshElement* next()
6295 const SMDS_MeshElement* res = _elem;
6297 while ( _elemIter->more() && !_elem )
6299 if ((_elem = _elemIter->next()) &&
6300 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
6301 ( !_predicate->IsSatisfy( _elem->GetID() ))))
6308 //-----------------------------------------------------------------------------
6309 struct IDSourceIterator : public SMDS_ElemIterator
6311 const SMESH::smIdType* _idPtr;
6312 const SMESH::smIdType* _idEndPtr;
6313 SMESH::smIdType_array_var _idArray;
6314 const SMDS_Mesh* _mesh;
6315 const SMDSAbs_ElementType _type;
6316 const SMDS_MeshElement* _elem;
6318 IDSourceIterator( const SMDS_Mesh* mesh,
6319 const SMESH::smIdType* ids,
6320 const smIdType nbIds,
6321 SMDSAbs_ElementType type):
6322 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
6324 if ( _idPtr && nbIds && _mesh )
6327 IDSourceIterator( const SMDS_Mesh* mesh,
6328 SMESH::smIdType_array* idArray,
6329 SMDSAbs_ElementType type):
6330 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
6332 if ( idArray && _mesh )
6334 _idPtr = &_idArray[0];
6335 _idEndPtr = _idPtr + _idArray->length();
6343 virtual const SMDS_MeshElement* next()
6345 const SMDS_MeshElement* res = _elem;
6347 while ( _idPtr < _idEndPtr && !_elem )
6349 if ( _type == SMDSAbs_Node )
6351 _elem = _mesh->FindNode( *_idPtr++ );
6353 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
6354 (_elem->GetType() != _type && _type != SMDSAbs_All ))
6362 //-----------------------------------------------------------------------------
6364 struct NodeOfElemIterator : public SMDS_ElemIterator
6366 TColStd_MapOfInteger _checkedNodeIDs;
6367 SMDS_ElemIteratorPtr _elemIter;
6368 SMDS_ElemIteratorPtr _nodeIter;
6369 const SMDS_MeshElement* _node;
6371 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
6373 if ( _elemIter && _elemIter->more() )
6375 _nodeIter = _elemIter->next()->nodesIterator();
6383 virtual const SMDS_MeshElement* next()
6385 const SMDS_MeshElement* res = _node;
6387 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
6389 if ( _nodeIter->more() )
6391 _node = _nodeIter->next();
6392 if ( !_checkedNodeIDs.Add( _node->GetID() ))
6397 _nodeIter = _elemIter->next()->nodesIterator();
6405 //=============================================================================
6407 * Return iterator on elements of given type in given object
6409 //=============================================================================
6411 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
6412 SMESH::ElementType theType)
6414 SMDS_ElemIteratorPtr elemIt;
6415 bool typeOK = ( theType == SMESH::ALL );
6416 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
6418 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
6419 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
6420 if ( !mesh_i ) return elemIt;
6421 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
6423 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
6425 elemIt = meshDS->elementsIterator( elemType );
6428 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
6430 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
6433 elemIt = sm->GetElements();
6434 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6436 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
6437 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
6441 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
6443 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
6444 if ( groupDS && ( elemType == groupDS->GetType() ||
6445 elemType == SMDSAbs_Node ||
6446 elemType == SMDSAbs_All ))
6448 elemIt = groupDS->GetElements();
6449 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
6452 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
6454 if ( filter_i->GetElementType() == theType ||
6455 filter_i->GetElementType() == SMESH::ALL ||
6456 elemType == SMDSAbs_Node ||
6457 elemType == SMDSAbs_All)
6459 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
6460 if ( pred_i && pred_i->GetPredicate() )
6462 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
6463 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
6464 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
6465 elemIt = SMDS_ElemIteratorPtr
6466 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
6467 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
6473 SMESH::array_of_ElementType_var types = theObject->GetTypes();
6474 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
6475 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6477 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
6478 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
6480 SMESH::smIdType nbIds;
6481 if ( SMESH::smIdType* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
6482 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
6486 SMESH::smIdType_array_var ids = theObject->GetIDs();
6487 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
6489 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
6492 if ( elemIt && elemIt->more() && !typeOK )
6494 if ( elemType == SMDSAbs_Node )
6496 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
6500 elemIt = SMDS_ElemIteratorPtr();
6506 //=============================================================================
6507 namespace // Finding concurrent hypotheses
6508 //=============================================================================
6512 * \brief mapping of mesh dimension into shape type
6514 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
6516 TopAbs_ShapeEnum aType = TopAbs_SOLID;
6518 case 0: aType = TopAbs_VERTEX; break;
6519 case 1: aType = TopAbs_EDGE; break;
6520 case 2: aType = TopAbs_FACE; break;
6522 default:aType = TopAbs_SOLID; break;
6527 //-----------------------------------------------------------------------------
6529 * \brief Internal structure used to find concurrent submeshes
6531 * It represents a pair < submesh, concurrent dimension >, where
6532 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
6533 * with another submesh. In other words, it is dimension of a hypothesis assigned
6540 int _dim; //!< a dimension the algo can build (concurrent dimension)
6541 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
6542 TopTools_MapOfShape _shapeMap; //!< [sub-]shapes of dimension == _dim
6543 const SMESH_subMesh* _subMesh;
6544 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
6546 //-----------------------------------------------------------------------------
6547 // Return the algorithm
6548 const SMESH_Algo* GetAlgo() const
6549 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
6551 //-----------------------------------------------------------------------------
6553 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
6555 const TopoDS_Shape& theShape)
6557 _subMesh = theSubMesh;
6558 SetShape( theDim, theShape );
6561 //-----------------------------------------------------------------------------
6563 void SetShape(const int theDim,
6564 const TopoDS_Shape& theShape)
6567 _ownDim = SMESH_Gen::GetShapeDim(theShape);
6568 if (_dim >= _ownDim)
6569 _shapeMap.Add( theShape );
6571 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
6572 for( ; anExp.More(); anExp.Next() )
6573 _shapeMap.Add( anExp.Current() );
6577 //-----------------------------------------------------------------------------
6578 //! Check sharing of sub-shapes
6579 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
6580 const TopTools_MapOfShape& theToFind,
6581 const TopAbs_ShapeEnum theType)
6583 bool isShared = false;
6584 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
6585 for (; !isShared && anItr.More(); anItr.Next() )
6587 const TopoDS_Shape& aSubSh = anItr.Key();
6588 // check for case when concurrent dimensions are same
6589 isShared = theToFind.Contains( aSubSh );
6590 // check for sub-shape with concurrent dimension
6591 TopExp_Explorer anExp( aSubSh, theType );
6592 for ( ; !isShared && anExp.More(); anExp.Next() )
6593 isShared = theToFind.Contains( anExp.Current() );
6598 //-----------------------------------------------------------------------------
6599 //! check algorithms
6600 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
6601 const SMESHDS_Hypothesis* theA2)
6603 if ( !theA1 || !theA2 ||
6604 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
6605 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
6606 return false; // one of the hypothesis is not algorithm
6607 // check algorithm names (should be equal)
6608 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
6612 //-----------------------------------------------------------------------------
6613 //! Check if sub-shape hypotheses are concurrent
6614 bool IsConcurrent(const SMESH_DimHyp* theOther) const
6616 if ( _subMesh == theOther->_subMesh )
6617 return false; // same sub-shape - should not be
6619 // if ( <own dim of either of submeshes> == <concurrent dim> &&
6620 // any of the two submeshes is not on COMPOUND shape )
6621 // -> no concurrency
6622 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
6623 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
6624 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
6625 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
6626 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
6629 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
6630 if ( !checkSubShape )
6633 // check algorithms to be same
6634 const SMESH_Algo* a1 = this->GetAlgo();
6635 const SMESH_Algo* a2 = theOther->GetAlgo();
6636 bool isSame = checkAlgo( a1, a2 );
6640 // commented off for IPAL54678
6641 // if ( !a1 || !a2 )
6642 // return false; // pb?
6643 // return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency !
6646 // check hypothesises for concurrence (skip first as algorithm)
6648 // pointers should be same, because it is referened from mesh hypothesis partition
6649 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
6650 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
6651 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
6652 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
6654 // the submeshes are concurrent if their algorithms has different parameters
6655 return nbSame != theOther->_hypotheses.size() - 1;
6658 // Return true if algorithm of this SMESH_DimHyp is used if no
6659 // sub-mesh order is imposed by the user
6660 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
6662 // NeedDiscreteBoundary() algo has a higher priority
6663 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
6664 theOther->GetAlgo()->NeedDiscreteBoundary() )
6665 return !this->GetAlgo()->NeedDiscreteBoundary();
6667 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
6670 }; // end of SMESH_DimHyp
6671 //-----------------------------------------------------------------------------
6673 typedef list<const SMESH_DimHyp*> TDimHypList;
6675 //-----------------------------------------------------------------------------
6677 void addDimHypInstance(const int theDim,
6678 const TopoDS_Shape& theShape,
6679 const SMESH_Algo* theAlgo,
6680 const SMESH_subMesh* theSubMesh,
6681 const list <const SMESHDS_Hypothesis*>& theHypList,
6682 TDimHypList* theDimHypListArr )
6684 if ( !theAlgo->NeedDiscreteBoundary() &&
6685 theAlgo->NeedLowerHyps( theDim )) // IPAL54678
6687 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
6688 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh )
6690 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
6691 dimHyp->_hypotheses.push_front(theAlgo);
6692 listOfdimHyp.push_back( dimHyp );
6695 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
6696 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
6697 theHypList.begin(), theHypList.end() );
6700 //-----------------------------------------------------------------------------
6701 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
6702 TDimHypList& theListOfConcurr)
6704 if ( theListOfConcurr.empty() )
6706 theListOfConcurr.push_back( theDimHyp );
6710 TDimHypList::iterator hypIt = theListOfConcurr.begin();
6711 while ( hypIt != theListOfConcurr.end() &&
6712 !theDimHyp->IsHigherPriorityThan( *hypIt ))
6714 theListOfConcurr.insert( hypIt, theDimHyp );
6718 //-----------------------------------------------------------------------------
6719 void findConcurrents(const SMESH_DimHyp* theDimHyp,
6720 const TDimHypList& theListOfDimHyp,
6721 TDimHypList& theListOfConcurrHyp,
6722 set<int>& theSetOfConcurrId )
6724 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
6725 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
6727 const SMESH_DimHyp* curDimHyp = *rIt;
6728 if ( curDimHyp == theDimHyp )
6729 break; // meet own dimHyp pointer in same dimension
6731 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
6732 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
6734 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
6739 //-----------------------------------------------------------------------------
6740 bool unionLists(TListOfInt& theListOfId,
6741 TListOfListOfInt& theListOfListOfId,
6744 bool changed = false;
6745 if ( theListOfId.empty() )
6747 TListOfListOfInt::iterator it = theListOfListOfId.begin();
6748 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ )
6751 continue; //skip already treated lists
6752 // check if other list has any same submesh object
6753 TListOfInt& otherListOfId = *it;
6754 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
6755 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
6758 // union two lists (from source into target)
6759 TListOfInt::iterator it2 = otherListOfId.begin();
6760 for ( ; it2 != otherListOfId.end(); it2++ ) {
6761 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
6763 theListOfId.push_back(*it2);
6767 // clear source list
6768 otherListOfId.clear();
6772 //-----------------------------------------------------------------------------
6774 //! free memory allocated for dimension-hypothesis objects
6775 void removeDimHyps( TDimHypList* theArrOfList )
6777 for (int i = 0; i < 4; i++ ) {
6778 TDimHypList& listOfdimHyp = theArrOfList[i];
6779 TDimHypList::const_iterator it = listOfdimHyp.begin();
6780 for ( ; it != listOfdimHyp.end(); it++ )
6785 //-----------------------------------------------------------------------------
6787 * \brief find common submeshes with given submesh
6788 * \param theSubMeshList list of already collected submesh to check
6789 * \param theSubMesh given submesh to intersect with other
6790 * \param theCommonSubMeshes collected common submeshes
6792 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6793 const SMESH_subMesh* theSubMesh,
6794 set<const SMESH_subMesh*>& theCommon )
6798 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6799 for ( ; it != theSubMeshList.end(); it++ )
6800 theSubMesh->FindIntersection( *it, theCommon );
6801 theSubMeshList.push_back( theSubMesh );
6802 //theCommon.insert( theSubMesh );
6805 //-----------------------------------------------------------------------------
6806 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6808 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6809 for ( ; listsIt != smLists.end(); ++listsIt )
6811 const TListOfInt& smIDs = *listsIt;
6812 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6820 //=============================================================================
6822 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6824 //=============================================================================
6826 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6828 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6829 if ( isSubMeshInList( submeshID, anOrder ))
6832 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6833 return isSubMeshInList( submeshID, allConurrent );
6836 //=============================================================================
6838 * \brief Return sub-mesh objects list in meshing order
6840 //=============================================================================
6842 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6844 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6846 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6848 return aResult._retn();
6850 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6851 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6852 anOrder.splice( anOrder.end(), allConurrent );
6857 TListOfListOfInt::iterator listIt = anOrder.begin();
6858 for ( int listIndx = 1; listIt != anOrder.end(); listIt++, listIndx++ )
6859 if ( unionLists( *listIt, anOrder, listIndx ))
6864 // convert submesh ids into interface instances
6865 // and dump command into python
6866 convertMeshOrder( anOrder, aResult, false );
6868 return aResult._retn();
6871 //=============================================================================
6873 * \brief Finds concurrent sub-meshes
6875 //=============================================================================
6877 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6879 TListOfListOfInt anOrder;
6880 ::SMESH_Mesh& mesh = GetImpl();
6882 // collect submeshes and detect concurrent algorithms and hypothesises
6883 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6885 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6886 for ( ; i_sm != _mapSubMesh.end(); i_sm++ )
6888 ::SMESH_subMesh* sm = (*i_sm).second;
6890 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6892 // list of assigned hypothesises
6893 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6894 // Find out dimensions where the submesh can be concurrent.
6895 // We define the dimensions by algo of each of hypotheses in hypList
6896 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6897 for( ; hypIt != hypList.end(); hypIt++ )
6899 SMESH_Algo* anAlgo = 0;
6900 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6901 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6902 // hyp it-self is algo
6903 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6905 // try to find algorithm with help of sub-shapes
6906 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6907 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6908 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6911 continue; // no algorithm assigned to a current submesh
6913 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6914 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary()
6915 // and !anAlgo->NeedLowerHyps( dim ))
6917 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6918 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6919 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6921 } // end iterations on submesh
6923 // iterate on created dimension-hypotheses and check for concurrents
6924 for ( int i = 0; i < 4; i++ )
6926 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6927 // check for concurrents in own and other dimensions (step-by-step)
6928 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6929 for ( ; dhIt != listOfDimHyp.end(); dhIt++ )
6931 const SMESH_DimHyp* dimHyp = *dhIt;
6932 TDimHypList listOfConcurr;
6933 set<int> setOfConcurrIds;
6934 // looking for concurrents and collect into own list
6935 for ( int j = i; j < 4; j++ )
6936 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6937 // check if any concurrents found
6938 if ( listOfConcurr.size() > 0 )
6940 // add own submesh to list of concurrent
6941 addInOrderOfPriority( dimHyp, listOfConcurr );
6942 list<int> listOfConcurrIds;
6943 TDimHypList::iterator hypIt = listOfConcurr.begin();
6944 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6945 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6946 anOrder.push_back( listOfConcurrIds );
6951 removeDimHyps(dimHypListArr);
6953 // now, minimize the number of concurrent groups
6954 // Here we assume that lists of submeshes can have same submesh
6955 // in case of multi-dimension algorithms, as result
6956 // list with common submesh has to be united into one list
6958 TListOfListOfInt::iterator listIt = anOrder.begin();
6959 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6960 unionLists( *listIt, anOrder, listIndx + 1 );
6965 //=============================================================================
6967 * \brief Set submesh object order
6968 * \param theSubMeshArray submesh array order
6970 //=============================================================================
6972 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6975 _preMeshInfo->ForgetOrLoad();
6978 ::SMESH_Mesh& mesh = GetImpl();
6980 TPythonDump aPythonDump; // prevent dump of called methods
6981 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6983 TListOfListOfInt subMeshOrder;
6984 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6986 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6987 TListOfInt subMeshIds;
6989 aPythonDump << ", ";
6990 aPythonDump << "[ ";
6991 // Collect subMeshes which should be clear
6992 // do it list-by-list, because modification of submesh order
6993 // take effect between concurrent submeshes only
6994 set<const SMESH_subMesh*> subMeshToClear;
6995 list<const SMESH_subMesh*> subMeshList;
6996 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6998 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
7000 aPythonDump << ", ";
7001 aPythonDump << subMesh;
7002 subMeshIds.push_back( subMesh->GetId() );
7003 // detect common parts of submeshes
7004 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
7005 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
7007 aPythonDump << " ]";
7008 subMeshOrder.push_back( subMeshIds );
7010 // clear collected sub-meshes
7011 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
7012 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
7013 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
7015 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
7016 if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748
7017 sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo
7020 aPythonDump << " ])";
7022 mesh.SetMeshOrder( subMeshOrder );
7025 SMESH::SMESH_Mesh_var me = _this();
7026 _gen_i->UpdateIcons( me );
7031 //=============================================================================
7033 * \brief Set the number of threads for a parallel computation
7035 //=============================================================================
7036 void SMESH_Mesh_i::SetNbThreads(CORBA::Long nbThreads){
7037 _impl->SetNbThreads(nbThreads);
7040 //=============================================================================
7042 * \brief Get the number of threads for a parallel computation
7044 //=============================================================================
7045 CORBA::Long SMESH_Mesh_i::GetNbThreads(){
7046 return _impl->GetNbThreads();
7050 //=============================================================================
7052 * \brief Convert submesh ids into submesh interfaces
7054 //=============================================================================
7056 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
7057 SMESH::submesh_array_array& theResOrder,
7058 const bool theIsDump)
7060 int nbSet = theIdsOrder.size();
7061 TPythonDump aPythonDump; // prevent dump of called methods
7063 aPythonDump << "[ ";
7064 theResOrder.length(nbSet);
7065 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
7067 for( ; it != theIdsOrder.end(); it++ )
7069 // translate submesh identificators into submesh objects
7070 // takeing into account real number of concurrent lists
7071 const TListOfInt& aSubOrder = (*it);
7072 if (!aSubOrder.size())
7075 aPythonDump << "[ ";
7076 // convert shape indices into interfaces
7077 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
7078 aResSubSet->length(aSubOrder.size());
7079 TListOfInt::const_iterator subIt = aSubOrder.begin();
7081 for( j = 0; subIt != aSubOrder.end(); subIt++ )
7083 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
7085 SMESH::SMESH_subMesh_var subMesh =
7086 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
7089 aPythonDump << ", ";
7090 aPythonDump << subMesh;
7092 aResSubSet[ j++ ] = subMesh;
7095 aPythonDump << " ]";
7097 theResOrder[ listIndx++ ] = aResSubSet;
7099 // correct number of lists
7100 theResOrder.length( listIndx );
7103 // finilise python dump
7104 aPythonDump << " ]";
7105 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
7109 namespace // utils used by SMESH_MeshPartDS
7112 * \brief Class used to access to protected data of SMDS_MeshInfo
7114 struct TMeshInfo : public SMDS_MeshInfo
7116 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
7119 * \brief Element holing its ID only
7121 struct TElemID : public SMDS_LinearEdge
7123 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
7127 //================================================================================
7129 // Implementation of SMESH_MeshPartDS
7131 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
7132 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
7134 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
7135 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
7138 _meshDS = mesh_i->GetImpl().GetMeshDS();
7140 SetPersistentId( _meshDS->GetPersistentId() );
7142 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
7144 // <meshPart> is the whole mesh
7145 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
7147 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
7148 myGroupSet = _meshDS->GetGroups();
7153 SMESH::smIdType_array_var anIDs = meshPart->GetIDs();
7154 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
7155 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
7157 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
7158 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
7159 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
7164 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
7165 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
7166 if ( _elements[ e->GetType() ].insert( e ).second )
7169 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
7170 while ( nIt->more() )
7172 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
7173 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
7180 ShapeToMesh( _meshDS->ShapeToMesh() );
7182 _meshDS = 0; // to enforce iteration on _elements and _nodes
7185 // -------------------------------------------------------------------------------------
7186 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
7187 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
7190 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
7191 for ( ; partIt != meshPart.end(); ++partIt )
7192 if ( const SMDS_MeshElement * e = *partIt )
7193 if ( _elements[ e->GetType() ].insert( e ).second )
7196 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
7197 while ( nIt->more() )
7199 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
7200 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
7206 // -------------------------------------------------------------------------------------
7207 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
7209 if ( _meshDS ) return _meshDS->FindElement( IDelem );
7211 TElemID elem( IDelem );
7212 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
7213 if ( !_elements[ iType ].empty() )
7215 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
7216 if ( it != _elements[ iType ].end() )
7221 // -------------------------------------------------------------------------------------
7222 bool SMESH_MeshPartDS::HasNumerationHoles()
7224 if ( _meshDS ) return _meshDS->HasNumerationHoles();
7226 return ( MinNodeID() != 1 ||
7227 MaxNodeID() != NbNodes() ||
7228 MinElementID() != 1 ||
7229 MaxElementID() != NbElements() );
7231 // -------------------------------------------------------------------------------------
7232 smIdType SMESH_MeshPartDS::MaxNodeID() const
7234 if ( _meshDS ) return _meshDS->MaxNodeID();
7235 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID();
7237 // -------------------------------------------------------------------------------------
7238 smIdType SMESH_MeshPartDS::MinNodeID() const
7240 if ( _meshDS ) return _meshDS->MinNodeID();
7241 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID();
7243 // -------------------------------------------------------------------------------------
7244 smIdType SMESH_MeshPartDS::MaxElementID() const
7246 if ( _meshDS ) return _meshDS->MaxElementID();
7248 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
7249 if ( !_elements[ iType ].empty() )
7250 maxID = std::max( maxID, (*_elements[ iType ].rbegin())->GetID() );
7253 // -------------------------------------------------------------------------------------
7254 smIdType SMESH_MeshPartDS::MinElementID() const
7256 if ( _meshDS ) return _meshDS->MinElementID();
7258 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
7259 if ( !_elements[ iType ].empty() )
7260 minID = std::min( minID, (*_elements[ iType ].begin())->GetID() );
7263 // -------------------------------------------------------------------------------------
7264 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
7266 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
7268 typedef SMDS_SetIterator
7269 <const SMDS_MeshElement*,
7270 TIDSortedElemSet::const_iterator,
7271 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
7272 SMDS_MeshElement::GeomFilter
7275 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
7277 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
7278 _elements[type].end(),
7279 SMDS_MeshElement::GeomFilter( geomType )));
7281 // -------------------------------------------------------------------------------------
7282 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
7284 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
7286 typedef SMDS_SetIterator
7287 <const SMDS_MeshElement*,
7288 TIDSortedElemSet::const_iterator,
7289 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
7290 SMDS_MeshElement::EntityFilter
7293 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
7295 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
7296 _elements[type].end(),
7297 SMDS_MeshElement::EntityFilter( entity )));
7299 // -------------------------------------------------------------------------------------
7300 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
7302 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
7303 if ( type == SMDSAbs_All && !_meshDS )
7305 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
7307 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
7308 if ( !_elements[i].empty() && i != SMDSAbs_Node )
7310 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
7312 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
7313 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
7315 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
7316 ( new TIter( _elements[type].begin(), _elements[type].end() ));
7318 // -------------------------------------------------------------------------------------
7319 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
7320 iterType SMESH_MeshPartDS::methName() const \
7322 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
7323 return _meshDS ? _meshDS->methName() : iterType \
7324 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
7326 // -------------------------------------------------------------------------------------
7327 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
7328 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
7329 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
7330 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
7331 #undef _GET_ITER_DEFINE
7333 // END Implementation of SMESH_MeshPartDS
7335 //================================================================================