1 // Copyright (C) 2007-2019 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_Mesh_i.cxx
23 // Author : Paul RASCLE, EDF
26 #include "SMESH_Mesh_i.hxx"
28 #include "DriverMED_R_SMESHDS_Mesh.h"
29 #include "DriverMED_W_Field.h"
30 #include "DriverMED_W_SMESHDS_Mesh.h"
31 #include "MED_Factory.hxx"
32 #include "SMDS_LinearEdge.hxx"
33 #include "SMDS_EdgePosition.hxx"
34 #include "SMDS_ElemIterator.hxx"
35 #include "SMDS_FacePosition.hxx"
36 #include "SMDS_IteratorOnIterators.hxx"
37 #include "SMDS_MeshGroup.hxx"
38 #include "SMDS_SetIterator.hxx"
39 #include "SMDS_StdIterator.hxx"
40 #include "SMDS_VolumeTool.hxx"
41 #include "SMESHDS_Command.hxx"
42 #include "SMESHDS_CommandType.hxx"
43 #include "SMESHDS_Group.hxx"
44 #include "SMESHDS_GroupOnGeom.hxx"
45 #include "SMESH_Controls.hxx"
46 #include "SMESH_File.hxx"
47 #include "SMESH_Filter_i.hxx"
48 #include "SMESH_Gen_i.hxx"
49 #include "SMESH_Group.hxx"
50 #include "SMESH_Group_i.hxx"
51 #include "SMESH_Mesh.hxx"
52 #include "SMESH_MeshAlgos.hxx"
53 #include "SMESH_MeshEditor.hxx"
54 #include "SMESH_MeshEditor_i.hxx"
55 #include "SMESH_MeshPartDS.hxx"
56 #include "SMESH_MesherHelper.hxx"
57 #include "SMESH_PreMeshInfo.hxx"
58 #include "SMESH_PythonDump.hxx"
59 #include "SMESH_subMesh_i.hxx"
61 #include <SALOMEDS_Attributes_wrap.hxx>
62 #include <SALOMEDS_wrap.hxx>
63 #include <Utils_ExceptHandlers.hxx>
64 #include <utilities.h>
66 #include <GEOMImpl_Types.hxx>
67 #include <GEOM_wrap.hxx>
70 #include <BRep_Builder.hxx>
71 #include <Standard_ErrorHandler.hxx>
72 #include <TColStd_MapOfInteger.hxx>
74 #include <TopExp_Explorer.hxx>
75 #include <TopTools_MapIteratorOfMapOfShape.hxx>
76 #include <TopTools_MapOfShape.hxx>
77 #include <TopoDS_Compound.hxx>
84 #include <vtkUnstructuredGridWriter.h>
86 // to pass CORBA exception through SMESH_TRY
87 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
89 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
92 static int MYDEBUG = 0;
94 static int MYDEBUG = 0;
98 using SMESH::TPythonDump;
101 int SMESH_Mesh_i::_idGenerator = 0;
103 //=============================================================================
107 //=============================================================================
109 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
111 : SALOME::GenericObj_i( thePOA )
115 _id = _idGenerator++;
117 _previewEditor = NULL;
122 //=============================================================================
126 //=============================================================================
128 SMESH_Mesh_i::~SMESH_Mesh_i()
131 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
132 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
133 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
135 aGroup->UnRegister();
136 SMESH::SMESH_GroupBase_var( itGr->second );
141 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
142 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
143 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
145 aSubMesh->UnRegister();
146 SMESH::SMESH_subMesh_var( itSM->second );
148 _mapSubMeshIor.clear();
150 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
151 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
152 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
153 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
154 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
155 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
158 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
162 // clear cached shapes if no more meshes remain; (the cache is blame,
163 // together with publishing, of spent time increasing in issue 22874)
164 if ( _impl->NbMeshes() == 1 )
165 _gen_i->GetShapeReader()->ClearClientBuffer();
167 delete _editor; _editor = NULL;
168 delete _previewEditor; _previewEditor = NULL;
169 delete _impl; _impl = NULL;
170 delete _preMeshInfo; _preMeshInfo = NULL;
173 //=============================================================================
177 * Associates <this> mesh with <theShape> and puts a reference
178 * to <theShape> into the current study;
179 * the previous shape is substituted by the new one.
181 //=============================================================================
183 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
184 throw (SALOME::SALOME_Exception)
186 Unexpect aCatch(SALOME_SalomeException);
188 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
190 catch(SALOME_Exception & S_ex) {
191 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
193 // to track changes of GEOM groups
194 SMESH::SMESH_Mesh_var mesh = _this();
195 addGeomGroupData( theShapeObject, mesh );
196 if ( !CORBA::is_nil( theShapeObject ))
197 _mainShapeTick = theShapeObject->GetTick();
200 //================================================================================
202 * \brief return true if mesh has a shape to build a shape on
204 //================================================================================
206 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
207 throw (SALOME::SALOME_Exception)
209 Unexpect aCatch(SALOME_SalomeException);
212 res = _impl->HasShapeToMesh();
214 catch(SALOME_Exception & S_ex) {
215 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
220 //=======================================================================
221 //function : GetShapeToMesh
223 //=======================================================================
225 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
226 throw (SALOME::SALOME_Exception)
228 Unexpect aCatch(SALOME_SalomeException);
229 GEOM::GEOM_Object_var aShapeObj;
231 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
234 aShapeObj = _gen_i->ShapeToGeomObject( S );
235 if ( aShapeObj->_is_nil() )
237 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
238 // find GEOM_Object by entry (IPAL52735)
239 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
240 for ( ; data != _geomGroupData.end(); ++data )
241 if ( data->_smeshObject->_is_equivalent( _this() ))
243 SALOMEDS::SObject_wrap so = _gen_i->getStudyServant()->FindObjectID( data->_groupEntry.c_str() );
244 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
245 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
251 catch(SALOME_Exception & S_ex) {
252 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
254 return aShapeObj._retn();
257 //================================================================================
259 * \brief Replaces a shape in the mesh
261 //================================================================================
262 void SMESH_Mesh_i::ReplaceShape(GEOM::GEOM_Object_ptr theNewGeom)
263 throw (SALOME::SALOME_Exception)
265 TopoDS_Shape S = _impl->GetShapeToMesh();
266 GEOM_Client* geomClient = _gen_i->GetShapeReader();
267 TCollection_AsciiString aIOR;
268 if (geomClient->Find(S, aIOR)) {
269 geomClient->RemoveShapeFromBuffer(aIOR);
272 // re-assign global hypotheses to the new shape
273 _mainShapeTick = theNewGeom->GetTick() + 1;
277 //================================================================================
279 * \brief Return false if the mesh is not yet fully loaded from the study file
281 //================================================================================
283 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
285 Unexpect aCatch(SALOME_SalomeException);
286 return !_preMeshInfo;
289 //================================================================================
291 * \brief Load full mesh data from the study file
293 //================================================================================
295 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
297 Unexpect aCatch(SALOME_SalomeException);
299 _preMeshInfo->FullLoadFromFile();
302 //================================================================================
304 * \brief Remove all nodes and elements
306 //================================================================================
308 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
310 Unexpect aCatch(SALOME_SalomeException);
312 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
316 //CheckGeomGroupModif(); // issue 20145
318 catch(SALOME_Exception & S_ex) {
319 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
322 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
324 SMESH::SMESH_Mesh_var mesh = _this();
325 _gen_i->UpdateIcons( mesh );
328 //================================================================================
330 * \brief Remove all nodes and elements for indicated shape
332 //================================================================================
334 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
335 throw (SALOME::SALOME_Exception)
337 Unexpect aCatch(SALOME_SalomeException);
339 _preMeshInfo->FullLoadFromFile();
342 _impl->ClearSubMesh( ShapeID );
344 catch(SALOME_Exception & S_ex) {
345 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
347 _impl->GetMeshDS()->Modified();
349 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
352 //=============================================================================
354 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
356 //=============================================================================
358 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
360 SMESH::DriverMED_ReadStatus res;
363 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
364 res = SMESH::DRS_OK; break;
365 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
366 res = SMESH::DRS_EMPTY; break;
367 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
368 res = SMESH::DRS_WARN_RENUMBER; break;
369 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
370 res = SMESH::DRS_WARN_SKIP_ELEM; break;
371 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
372 res = SMESH::DRS_WARN_DESCENDING; break;
373 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
375 res = SMESH::DRS_FAIL; break;
380 //=============================================================================
382 * Convert ::SMESH_ComputeError to SMESH::ComputeError
384 //=============================================================================
386 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
388 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
389 errVar->subShapeID = -1;
390 errVar->hasBadMesh = false;
392 if ( !errorPtr || errorPtr->IsOK() )
394 errVar->code = SMESH::COMPERR_OK;
398 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
399 errVar->comment = errorPtr->myComment.c_str();
401 return errVar._retn();
404 //=============================================================================
408 * Imports mesh data from MED file
410 //=============================================================================
412 SMESH::DriverMED_ReadStatus
413 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
414 throw ( SALOME::SALOME_Exception )
416 Unexpect aCatch(SALOME_SalomeException);
419 status = _impl->MEDToMesh( theFileName, theMeshName );
421 catch( SALOME_Exception& S_ex ) {
422 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
425 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
428 CreateGroupServants();
430 int major, minor, release;
431 major = minor = release = 0;
432 MED::GetMEDVersion(theFileName, major, minor, release);
433 _medFileInfo = new SMESH::MedFileInfo();
434 _medFileInfo->fileName = theFileName;
435 _medFileInfo->fileSize = 0;
436 _medFileInfo->major = major;
437 _medFileInfo->minor = minor;
438 _medFileInfo->release = release;
439 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
441 return ConvertDriverMEDReadStatus(status);
444 //================================================================================
446 * \brief Imports mesh data from the CGNS file
448 //================================================================================
450 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
451 const int theMeshIndex,
452 std::string& theMeshName )
453 throw ( SALOME::SALOME_Exception )
455 Unexpect aCatch(SALOME_SalomeException);
458 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
460 catch( SALOME_Exception& S_ex ) {
461 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
464 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
467 CreateGroupServants();
469 _medFileInfo = new SMESH::MedFileInfo();
470 _medFileInfo->fileName = theFileName;
471 _medFileInfo->major = 0;
472 _medFileInfo->minor = 0;
473 _medFileInfo->release = 0;
474 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
476 return ConvertDriverMEDReadStatus(status);
479 //================================================================================
481 * \brief Return string representation of a MED file version comprising nbDigits
483 //================================================================================
485 char* SMESH_Mesh_i::GetVersionString(CORBA::Long minor, CORBA::Short nbDigits)
487 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(minor,
489 return CORBA::string_dup( ver.c_str() );
492 //================================================================================
494 * Return the list of med versions compatibles for write/append,
495 * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32)
497 //================================================================================
498 SMESH::long_array* SMESH_Mesh_i::GetMEDVersionsCompatibleForAppend()
500 SMESH::long_array_var aResult = new SMESH::long_array();
501 std::vector<int> mvok = MED::GetMEDVersionsAppendCompatible();
502 long nbver = mvok.size();
503 aResult->length( nbver );
504 for ( int i = 0; i < nbver; i++ )
505 aResult[i] = mvok[i];
506 return aResult._retn();
509 //=============================================================================
513 * Imports mesh data from MED file
515 //=============================================================================
517 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
518 throw ( SALOME::SALOME_Exception )
522 // Read mesh with name = <theMeshName> into SMESH_Mesh
523 _impl->UNVToMesh( theFileName );
525 CreateGroupServants();
527 _medFileInfo = new SMESH::MedFileInfo();
528 _medFileInfo->fileName = theFileName;
529 _medFileInfo->major = 0;
530 _medFileInfo->minor = 0;
531 _medFileInfo->release = 0;
532 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
534 SMESH_CATCH( SMESH::throwCorbaException );
539 //=============================================================================
543 * Imports mesh data from STL file
545 //=============================================================================
546 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
547 throw ( SALOME::SALOME_Exception )
551 // Read mesh with name = <theMeshName> into SMESH_Mesh
552 std::string name = _impl->STLToMesh( theFileName );
555 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
556 _gen_i->SetName( meshSO, name.c_str() );
558 _medFileInfo = new SMESH::MedFileInfo();
559 _medFileInfo->fileName = theFileName;
560 _medFileInfo->major = 0;
561 _medFileInfo->minor = 0;
562 _medFileInfo->release = 0;
563 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
565 SMESH_CATCH( SMESH::throwCorbaException );
570 //================================================================================
572 * \brief Function used in SMESH_CATCH by ImportGMFFile()
574 //================================================================================
578 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
580 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
584 //================================================================================
586 * \brief Imports data from a GMF file and returns an error description
588 //================================================================================
590 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
591 bool theMakeRequiredGroups )
592 throw (SALOME::SALOME_Exception)
594 SMESH_ComputeErrorPtr error;
597 #define SMESH_CAUGHT error =
600 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
602 _medFileInfo = new SMESH::MedFileInfo();
603 _medFileInfo->fileName = theFileName;
604 _medFileInfo->major = 0;
605 _medFileInfo->minor = 0;
606 _medFileInfo->release = 0;
607 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
609 SMESH_CATCH( exceptionToComputeError );
613 CreateGroupServants();
615 return ConvertComputeError( error );
618 //=============================================================================
622 //=============================================================================
624 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
626 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
627 (SMESH_Hypothesis::Hypothesis_Status theStatus)
630 RETURNCASE( HYP_OK );
631 RETURNCASE( HYP_MISSING );
632 RETURNCASE( HYP_CONCURRENT );
633 RETURNCASE( HYP_BAD_PARAMETER );
634 RETURNCASE( HYP_HIDDEN_ALGO );
635 RETURNCASE( HYP_HIDING_ALGO );
636 RETURNCASE( HYP_UNKNOWN_FATAL );
637 RETURNCASE( HYP_INCOMPATIBLE );
638 RETURNCASE( HYP_NOTCONFORM );
639 RETURNCASE( HYP_ALREADY_EXIST );
640 RETURNCASE( HYP_BAD_DIM );
641 RETURNCASE( HYP_BAD_SUBSHAPE );
642 RETURNCASE( HYP_BAD_GEOMETRY );
643 RETURNCASE( HYP_NEED_SHAPE );
644 RETURNCASE( HYP_INCOMPAT_HYPS );
647 return SMESH::HYP_UNKNOWN_FATAL;
650 //=============================================================================
654 * calls internal addHypothesis() and then adds a reference to <anHyp> under
655 * the SObject actually having a reference to <aSubShape>.
656 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
658 //=============================================================================
660 SMESH::Hypothesis_Status
661 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
662 SMESH::SMESH_Hypothesis_ptr anHyp,
663 CORBA::String_out anErrorText)
664 throw(SALOME::SALOME_Exception)
666 Unexpect aCatch(SALOME_SalomeException);
668 _preMeshInfo->ForgetOrLoad();
671 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
672 anErrorText = error.c_str();
674 SMESH::SMESH_Mesh_var mesh( _this() );
675 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
677 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
678 _gen_i->UpdateIcons( mesh );
680 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
682 // Update Python script
683 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
684 << aSubShape << ", " << anHyp << " )";
686 return ConvertHypothesisStatus(status);
689 //=============================================================================
693 //=============================================================================
695 SMESH_Hypothesis::Hypothesis_Status
696 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
697 SMESH::SMESH_Hypothesis_ptr anHyp,
698 std::string* anErrorText)
700 if(MYDEBUG) MESSAGE("addHypothesis");
702 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
703 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
705 if (CORBA::is_nil( anHyp ))
706 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
708 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
711 TopoDS_Shape myLocSubShape;
712 //use PseudoShape in case if mesh has no shape
714 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
716 myLocSubShape = _impl->GetShapeToMesh();
718 const int hypId = anHyp->GetId();
720 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
721 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
723 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
725 // assure there is a corresponding submesh
726 if ( !_impl->IsMainShape( myLocSubShape )) {
727 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
728 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
729 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
732 else if ( anErrorText )
734 *anErrorText = error;
737 catch(SALOME_Exception & S_ex)
739 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
744 //=============================================================================
748 //=============================================================================
750 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
751 SMESH::SMESH_Hypothesis_ptr anHyp)
752 throw(SALOME::SALOME_Exception)
754 Unexpect aCatch(SALOME_SalomeException);
756 _preMeshInfo->ForgetOrLoad();
758 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
759 SMESH::SMESH_Mesh_var mesh = _this();
761 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
763 _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
764 _gen_i->UpdateIcons( mesh );
766 // Update Python script
767 if(_impl->HasShapeToMesh())
768 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
769 << aSubShape << ", " << anHyp << " )";
771 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
774 return ConvertHypothesisStatus(status);
777 //=============================================================================
781 //=============================================================================
783 SMESH_Hypothesis::Hypothesis_Status
784 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
785 SMESH::SMESH_Hypothesis_ptr anHyp)
787 if(MYDEBUG) MESSAGE("removeHypothesis()");
789 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
790 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
792 if (CORBA::is_nil( anHyp ))
793 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
796 _preMeshInfo->ForgetOrLoad();
798 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
801 TopoDS_Shape myLocSubShape;
802 //use PseudoShape in case if mesh has no shape
803 if( _impl->HasShapeToMesh() )
804 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
806 myLocSubShape = _impl->GetShapeToMesh();
808 const int hypId = anHyp->GetId();
809 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
810 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
812 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
816 catch(SALOME_Exception & S_ex)
818 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
823 //=============================================================================
827 //=============================================================================
829 SMESH::ListOfHypothesis *
830 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
831 throw(SALOME::SALOME_Exception)
833 Unexpect aCatch(SALOME_SalomeException);
834 if (MYDEBUG) MESSAGE("GetHypothesisList");
835 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
836 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
838 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
841 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
842 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
843 myLocSubShape = _impl->GetShapeToMesh();
844 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
845 int i = 0, n = aLocalList.size();
848 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
849 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
850 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
852 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
853 if ( id_hypptr != _mapHypo.end() )
854 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
858 catch(SALOME_Exception & S_ex) {
859 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
862 return aList._retn();
865 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
867 Unexpect aCatch(SALOME_SalomeException);
868 if (MYDEBUG) MESSAGE("GetSubMeshes");
870 SMESH::submesh_array_var aList = new SMESH::submesh_array();
873 TPythonDump aPythonDump;
874 if ( !_mapSubMeshIor.empty() )
878 aList->length( _mapSubMeshIor.size() );
880 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
881 for ( ; it != _mapSubMeshIor.end(); it++ ) {
882 if ( CORBA::is_nil( it->second )) continue;
883 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
885 if (i > 1) aPythonDump << ", ";
886 aPythonDump << it->second;
890 catch(SALOME_Exception & S_ex) {
891 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
894 // Update Python script
895 if ( !_mapSubMeshIor.empty() )
896 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
898 return aList._retn();
901 //=============================================================================
905 //=============================================================================
907 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
908 const char* theName )
909 throw(SALOME::SALOME_Exception)
911 Unexpect aCatch(SALOME_SalomeException);
912 if (CORBA::is_nil(aSubShape))
913 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
915 SMESH::SMESH_subMesh_var subMesh;
916 SMESH::SMESH_Mesh_var aMesh = _this();
918 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
920 //Get or Create the SMESH_subMesh object implementation
922 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
924 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
926 TopoDS_Iterator it( myLocSubShape );
928 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
930 subMesh = getSubMesh( subMeshId );
932 // create a new subMesh object servant if there is none for the shape
933 if ( subMesh->_is_nil() )
934 subMesh = createSubMesh( aSubShape );
935 if ( _gen_i->CanPublishInStudy( subMesh ))
937 SALOMEDS::SObject_wrap aSO =
938 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
939 if ( !aSO->_is_nil()) {
940 // Update Python script
941 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
942 << aSubShape << ", '" << theName << "' )";
946 catch(SALOME_Exception & S_ex) {
947 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
949 return subMesh._retn();
952 //=============================================================================
956 //=============================================================================
958 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
959 throw (SALOME::SALOME_Exception)
963 if ( theSubMesh->_is_nil() )
966 GEOM::GEOM_Object_var aSubShape;
967 // Remove submesh's SObject
968 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
969 if ( !anSO->_is_nil() ) {
970 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
971 SALOMEDS::SObject_wrap anObj, aRef;
972 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
973 anObj->ReferencedObject( aRef.inout() ))
975 CORBA::Object_var obj = aRef->GetObject();
976 aSubShape = GEOM::GEOM_Object::_narrow( obj );
978 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
979 // aSubShape = theSubMesh->GetSubShape();
981 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
982 builder->RemoveObjectWithChildren( anSO );
984 // Update Python script
985 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
988 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
990 _preMeshInfo->ForgetOrLoad();
992 SMESH_CATCH( SMESH::throwCorbaException );
995 //=============================================================================
999 //=============================================================================
1001 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
1002 const char* theName )
1003 throw(SALOME::SALOME_Exception)
1005 Unexpect aCatch(SALOME_SalomeException);
1007 _preMeshInfo->FullLoadFromFile();
1009 SMESH::SMESH_Group_var aNewGroup =
1010 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
1012 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1014 SMESH::SMESH_Mesh_var mesh = _this();
1015 SALOMEDS::SObject_wrap aSO =
1016 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
1017 if ( !aSO->_is_nil())
1018 // Update Python script
1019 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
1020 << theElemType << ", '" << theName << "' )";
1022 return aNewGroup._retn();
1025 //=============================================================================
1029 //=============================================================================
1030 SMESH::SMESH_GroupOnGeom_ptr
1031 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
1032 const char* theName,
1033 GEOM::GEOM_Object_ptr theGeomObj)
1034 throw(SALOME::SALOME_Exception)
1036 Unexpect aCatch(SALOME_SalomeException);
1038 _preMeshInfo->FullLoadFromFile();
1040 SMESH::SMESH_GroupOnGeom_var aNewGroup;
1042 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
1043 if ( !aShape.IsNull() )
1046 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, /*id=*/-1, aShape ));
1048 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1050 SMESH::SMESH_Mesh_var mesh = _this();
1051 SALOMEDS::SObject_wrap aSO =
1052 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
1053 if ( !aSO->_is_nil())
1054 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
1055 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
1059 return aNewGroup._retn();
1062 //================================================================================
1064 * \brief Creates a group whose contents is defined by filter
1065 * \param theElemType - group type
1066 * \param theName - group name
1067 * \param theFilter - the filter
1068 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1070 //================================================================================
1072 SMESH::SMESH_GroupOnFilter_ptr
1073 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1074 const char* theName,
1075 SMESH::Filter_ptr theFilter )
1076 throw (SALOME::SALOME_Exception)
1078 Unexpect aCatch(SALOME_SalomeException);
1080 _preMeshInfo->FullLoadFromFile();
1082 if ( CORBA::is_nil( theFilter ))
1083 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1085 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1087 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1089 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1090 ( createGroup( theElemType, theName, /*id=*/-1, TopoDS_Shape(), predicate ));
1093 if ( !aNewGroup->_is_nil() )
1094 aNewGroup->SetFilter( theFilter );
1096 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1098 SMESH::SMESH_Mesh_var mesh = _this();
1099 SALOMEDS::SObject_wrap aSO =
1100 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1102 if ( !aSO->_is_nil())
1103 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1104 << theElemType << ", '" << theName << "', " << theFilter << " )";
1106 return aNewGroup._retn();
1109 //=============================================================================
1113 //=============================================================================
1115 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1116 throw (SALOME::SALOME_Exception)
1118 if ( theGroup->_is_nil() )
1123 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1127 if ( aGroup->GetMeshServant() != this )
1128 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroup(): group does not belong to this mesh",
1129 SALOME::BAD_PARAM );
1131 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1132 if ( !aGroupSO->_is_nil() )
1134 // Update Python script
1135 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1137 // Remove group's SObject
1138 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1139 builder->RemoveObjectWithChildren( aGroupSO );
1141 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1143 // Remove the group from SMESH data structures
1144 removeGroup( aGroup->GetLocalID() );
1146 SMESH_CATCH( SMESH::throwCorbaException );
1149 //=============================================================================
1151 * Remove group with its contents
1153 //=============================================================================
1155 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1156 throw (SALOME::SALOME_Exception)
1160 _preMeshInfo->FullLoadFromFile();
1162 if ( theGroup->_is_nil() )
1165 SMESH_GroupBase_i* groupImpl = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup );
1166 if ( !groupImpl || groupImpl->GetMeshServant() != this )
1167 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroupWithContents(): group does not belong to this mesh",
1170 vector<int> nodeIds; // to remove nodes becoming free
1171 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1172 if ( !isNodal && !theGroup->IsEmpty() )
1174 CORBA::Long elemID = theGroup->GetID( 1 );
1175 int nbElemNodes = GetElemNbNodes( elemID );
1176 if ( nbElemNodes > 0 )
1177 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1180 // Retrieve contents
1181 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1182 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1183 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1184 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1185 elems.assign( elemBeg, elemEnd );
1187 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1190 RemoveGroup( theGroup );
1193 for ( size_t i = 0; i < elems.size(); ++i )
1195 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1199 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1200 nodeIds.push_back( nIt->next()->GetID() );
1202 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1206 _impl->GetMeshDS()->RemoveElement( elems[i] );
1210 // Remove free nodes
1211 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1212 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1213 if ( n->NbInverseElements() == 0 )
1214 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1216 // Update Python script (theGroup must be alive for this)
1217 pyDump << SMESH::SMESH_Mesh_var(_this())
1218 << ".RemoveGroupWithContents( " << theGroup << " )";
1220 SMESH_CATCH( SMESH::throwCorbaException );
1223 //================================================================================
1225 * \brief Get the list of groups existing in the mesh
1226 * \retval SMESH::ListOfGroups * - list of groups
1228 //================================================================================
1230 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1232 Unexpect aCatch(SALOME_SalomeException);
1233 if (MYDEBUG) MESSAGE("GetGroups");
1235 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1238 TPythonDump aPythonDump;
1239 if ( !_mapGroups.empty() )
1241 aPythonDump << "[ ";
1243 aList->length( _mapGroups.size() );
1245 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1246 for ( ; it != _mapGroups.end(); it++ ) {
1247 if ( CORBA::is_nil( it->second )) continue;
1248 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1250 if (i > 1) aPythonDump << ", ";
1251 aPythonDump << it->second;
1255 catch(SALOME_Exception & S_ex) {
1256 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1258 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1260 return aList._retn();
1263 //=============================================================================
1265 * Get number of groups existing in the mesh
1267 //=============================================================================
1269 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1271 Unexpect aCatch(SALOME_SalomeException);
1272 return _mapGroups.size();
1275 //=============================================================================
1277 * New group including all mesh elements present in initial groups is created.
1279 //=============================================================================
1281 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1282 SMESH::SMESH_GroupBase_ptr theGroup2,
1283 const char* theName )
1284 throw (SALOME::SALOME_Exception)
1286 SMESH::SMESH_Group_var aResGrp;
1290 _preMeshInfo->FullLoadFromFile();
1292 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1293 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1295 if ( theGroup1->GetType() != theGroup2->GetType() )
1296 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1301 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1302 if ( aResGrp->_is_nil() )
1303 return SMESH::SMESH_Group::_nil();
1305 aResGrp->AddFrom( theGroup1 );
1306 aResGrp->AddFrom( theGroup2 );
1308 // Update Python script
1309 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1310 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1312 SMESH_CATCH( SMESH::throwCorbaException );
1314 return aResGrp._retn();
1317 //=============================================================================
1319 * \brief New group including all mesh elements present in initial groups is created.
1320 * \param theGroups list of groups
1321 * \param theName name of group to be created
1322 * \return pointer to the new group
1324 //=============================================================================
1326 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1327 const char* theName )
1328 throw (SALOME::SALOME_Exception)
1330 SMESH::SMESH_Group_var aResGrp;
1333 _preMeshInfo->FullLoadFromFile();
1336 return SMESH::SMESH_Group::_nil();
1341 SMESH::ElementType aType = SMESH::ALL;
1342 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1344 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1345 if ( CORBA::is_nil( aGrp ) )
1347 if ( aType == SMESH::ALL )
1348 aType = aGrp->GetType();
1349 else if ( aType != aGrp->GetType() )
1350 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1353 if ( aType == SMESH::ALL )
1354 return SMESH::SMESH_Group::_nil();
1359 aResGrp = CreateGroup( aType, theName );
1360 if ( aResGrp->_is_nil() )
1361 return SMESH::SMESH_Group::_nil();
1363 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1364 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1366 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1367 if ( !CORBA::is_nil( aGrp ) )
1369 aResGrp->AddFrom( aGrp );
1370 if ( g > 0 ) pyDump << ", ";
1374 pyDump << " ], '" << theName << "' )";
1376 SMESH_CATCH( SMESH::throwCorbaException );
1378 return aResGrp._retn();
1381 //=============================================================================
1383 * New group is created. All mesh elements that are
1384 * present in both initial groups are added to the new one.
1386 //=============================================================================
1388 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1389 SMESH::SMESH_GroupBase_ptr theGroup2,
1390 const char* theName )
1391 throw (SALOME::SALOME_Exception)
1393 SMESH::SMESH_Group_var aResGrp;
1398 _preMeshInfo->FullLoadFromFile();
1400 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1401 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1403 if ( theGroup1->GetType() != theGroup2->GetType() )
1404 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1408 // Create Intersection
1409 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1410 if ( aResGrp->_is_nil() )
1411 return aResGrp._retn();
1413 SMESHDS_GroupBase* groupDS1 = 0;
1414 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1415 groupDS1 = grp_i->GetGroupDS();
1417 SMESHDS_GroupBase* groupDS2 = 0;
1418 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1419 groupDS2 = grp_i->GetGroupDS();
1421 SMESHDS_Group* resGroupDS = 0;
1422 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1423 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1425 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1427 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1428 while ( elemIt1->more() )
1430 const SMDS_MeshElement* e = elemIt1->next();
1431 if ( groupDS2->Contains( e ))
1432 resGroupDS->SMDSGroup().Add( e );
1435 // Update Python script
1436 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1437 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1439 SMESH_CATCH( SMESH::throwCorbaException );
1441 return aResGrp._retn();
1444 //=============================================================================
1446 \brief Intersect list of groups. New group is created. All mesh elements that
1447 are present in all initial groups simultaneously are added to the new one.
1448 \param theGroups list of groups
1449 \param theName name of group to be created
1450 \return pointer on the group
1452 //=============================================================================
1453 SMESH::SMESH_Group_ptr
1454 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1455 const char* theName )
1456 throw (SALOME::SALOME_Exception)
1458 SMESH::SMESH_Group_var aResGrp;
1463 _preMeshInfo->FullLoadFromFile();
1466 return SMESH::SMESH_Group::_nil();
1468 // check types and get SMESHDS_GroupBase's
1469 SMESH::ElementType aType = SMESH::ALL;
1470 vector< SMESHDS_GroupBase* > groupVec;
1471 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1473 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1474 if ( CORBA::is_nil( aGrp ) )
1476 if ( aType == SMESH::ALL )
1477 aType = aGrp->GetType();
1478 else if ( aType != aGrp->GetType() )
1479 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1482 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1483 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1485 if ( grpDS->IsEmpty() )
1490 groupVec.push_back( grpDS );
1493 if ( aType == SMESH::ALL ) // all groups are nil
1494 return SMESH::SMESH_Group::_nil();
1499 aResGrp = CreateGroup( aType, theName );
1501 SMESHDS_Group* resGroupDS = 0;
1502 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1503 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1504 if ( !resGroupDS || groupVec.empty() )
1505 return aResGrp._retn();
1508 size_t i, nb = groupVec.size();
1509 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1510 while ( elemIt1->more() )
1512 const SMDS_MeshElement* e = elemIt1->next();
1514 for ( i = 1; ( i < nb && inAll ); ++i )
1515 inAll = groupVec[i]->Contains( e );
1518 resGroupDS->SMDSGroup().Add( e );
1521 // Update Python script
1522 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1523 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1525 SMESH_CATCH( SMESH::throwCorbaException );
1527 return aResGrp._retn();
1530 //=============================================================================
1532 * New group is created. All mesh elements that are present in
1533 * a main group but is not present in a tool group are added to the new one
1535 //=============================================================================
1537 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1538 SMESH::SMESH_GroupBase_ptr theGroup2,
1539 const char* theName )
1540 throw (SALOME::SALOME_Exception)
1542 SMESH::SMESH_Group_var aResGrp;
1547 _preMeshInfo->FullLoadFromFile();
1549 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1550 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1552 if ( theGroup1->GetType() != theGroup2->GetType() )
1553 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1557 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1558 if ( aResGrp->_is_nil() )
1559 return aResGrp._retn();
1561 SMESHDS_GroupBase* groupDS1 = 0;
1562 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1563 groupDS1 = grp_i->GetGroupDS();
1565 SMESHDS_GroupBase* groupDS2 = 0;
1566 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1567 groupDS2 = grp_i->GetGroupDS();
1569 SMESHDS_Group* resGroupDS = 0;
1570 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1571 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1573 if ( groupDS1 && groupDS2 && resGroupDS )
1575 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1576 while ( elemIt1->more() )
1578 const SMDS_MeshElement* e = elemIt1->next();
1579 if ( !groupDS2->Contains( e ))
1580 resGroupDS->SMDSGroup().Add( e );
1583 // Update Python script
1584 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1585 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1587 SMESH_CATCH( SMESH::throwCorbaException );
1589 return aResGrp._retn();
1592 //=============================================================================
1594 \brief Cut lists of groups. New group is created. All mesh elements that are
1595 present in main groups but do not present in tool groups are added to the new one
1596 \param theMainGroups list of main groups
1597 \param theToolGroups list of tool groups
1598 \param theName name of group to be created
1599 \return pointer on the group
1601 //=============================================================================
1602 SMESH::SMESH_Group_ptr
1603 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1604 const SMESH::ListOfGroups& theToolGroups,
1605 const char* theName )
1606 throw (SALOME::SALOME_Exception)
1608 SMESH::SMESH_Group_var aResGrp;
1613 _preMeshInfo->FullLoadFromFile();
1616 return SMESH::SMESH_Group::_nil();
1618 // check types and get SMESHDS_GroupBase's
1619 SMESH::ElementType aType = SMESH::ALL;
1620 vector< SMESHDS_GroupBase* > toolGroupVec;
1621 vector< SMDS_ElemIteratorPtr > mainIterVec;
1623 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1625 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1626 if ( CORBA::is_nil( aGrp ) )
1628 if ( aType == SMESH::ALL )
1629 aType = aGrp->GetType();
1630 else if ( aType != aGrp->GetType() )
1631 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1633 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1634 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1635 if ( !grpDS->IsEmpty() )
1636 mainIterVec.push_back( grpDS->GetElements() );
1638 if ( aType == SMESH::ALL ) // all main groups are nil
1639 return SMESH::SMESH_Group::_nil();
1640 if ( mainIterVec.empty() ) // all main groups are empty
1641 return aResGrp._retn();
1643 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1645 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1646 if ( CORBA::is_nil( aGrp ) )
1648 if ( aType != aGrp->GetType() )
1649 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1651 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1652 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1653 toolGroupVec.push_back( grpDS );
1659 aResGrp = CreateGroup( aType, theName );
1661 SMESHDS_Group* resGroupDS = 0;
1662 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1663 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1665 return aResGrp._retn();
1668 size_t i, nb = toolGroupVec.size();
1669 SMDS_ElemIteratorPtr mainElemIt
1670 ( new SMDS_IteratorOnIterators
1671 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1672 while ( mainElemIt->more() )
1674 const SMDS_MeshElement* e = mainElemIt->next();
1676 for ( i = 0; ( i < nb && !isIn ); ++i )
1677 isIn = toolGroupVec[i]->Contains( e );
1680 resGroupDS->SMDSGroup().Add( e );
1683 // Update Python script
1684 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1685 << ".CutListOfGroups( " << theMainGroups << ", "
1686 << theToolGroups << ", '" << theName << "' )";
1688 SMESH_CATCH( SMESH::throwCorbaException );
1690 return aResGrp._retn();
1693 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1695 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1696 bool & toStopChecking )
1698 toStopChecking = ( nbCommon < nbChecked );
1699 return nbCommon == nbNodes;
1701 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1702 bool & toStopChecking )
1704 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1705 return nbCommon == nbCorners;
1707 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1708 bool & toStopChecking )
1710 return nbCommon > 0;
1712 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1713 bool & toStopChecking )
1715 return nbCommon >= (nbNodes+1) / 2;
1719 //=============================================================================
1721 * Create a group of entities basing on nodes of other groups.
1722 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1723 * \param [in] anElemType - a type of elements to include to the new group.
1724 * \param [in] theName - a name of the new group.
1725 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1726 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1727 * new group provided that it is based on nodes of an element of \a aListOfGroups
1728 * \return SMESH_Group - the created group
1730 // IMP 19939, bug 22010, IMP 22635
1731 //=============================================================================
1733 SMESH::SMESH_Group_ptr
1734 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1735 SMESH::ElementType theElemType,
1736 const char* theName,
1737 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1738 CORBA::Boolean theUnderlyingOnly)
1739 throw (SALOME::SALOME_Exception)
1741 SMESH::SMESH_Group_var aResGrp;
1745 _preMeshInfo->FullLoadFromFile();
1747 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1749 if ( !theName || !aMeshDS )
1750 return SMESH::SMESH_Group::_nil();
1752 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1754 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1755 SMESH_Comment nbCoNoStr( "SMESH.");
1756 switch ( theNbCommonNodes ) {
1757 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1758 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1759 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1760 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1761 default: return aResGrp._retn();
1763 int nbChecked, nbCommon, nbNodes, nbCorners;
1769 aResGrp = CreateGroup( theElemType, theName );
1770 if ( aResGrp->_is_nil() )
1771 return SMESH::SMESH_Group::_nil();
1773 SMESHDS_GroupBase* groupBaseDS =
1774 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1775 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1777 vector<bool> isNodeInGroups;
1779 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1781 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1782 if ( CORBA::is_nil( aGrp ) )
1784 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1785 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1788 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1789 if ( !elIt ) continue;
1791 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1793 while ( elIt->more() ) {
1794 const SMDS_MeshElement* el = elIt->next();
1795 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1796 while ( nIt->more() )
1797 resGroupCore.Add( nIt->next() );
1800 // get elements of theElemType based on nodes of every element of group
1801 else if ( theUnderlyingOnly )
1803 while ( elIt->more() )
1805 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1806 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1807 TIDSortedElemSet checkedElems;
1808 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1809 while ( nIt->more() )
1811 const SMDS_MeshNode* n = nIt->next();
1812 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1813 // check nodes of elements of theElemType around el
1814 while ( elOfTypeIt->more() )
1816 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1817 if ( !checkedElems.insert( elOfType ).second ) continue;
1818 nbNodes = elOfType->NbNodes();
1819 nbCorners = elOfType->NbCornerNodes();
1821 bool toStopChecking = false;
1822 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1823 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1824 if ( elNodes.count( nIt2->next() ) &&
1825 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1827 resGroupCore.Add( elOfType );
1834 // get all nodes of elements of groups
1837 while ( elIt->more() )
1839 const SMDS_MeshElement* el = elIt->next(); // an element of group
1840 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1841 while ( nIt->more() )
1843 const SMDS_MeshNode* n = nIt->next();
1844 if ( n->GetID() >= (int) isNodeInGroups.size() )
1845 isNodeInGroups.resize( n->GetID() + 1, false );
1846 isNodeInGroups[ n->GetID() ] = true;
1852 // Get elements of theElemType based on a certain number of nodes of elements of groups
1853 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1855 const SMDS_MeshNode* n;
1856 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1857 const int isNodeInGroupsSize = isNodeInGroups.size();
1858 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1860 if ( !isNodeInGroups[ iN ] ||
1861 !( n = aMeshDS->FindNode( iN )))
1864 // check nodes of elements of theElemType around n
1865 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1866 while ( elOfTypeIt->more() )
1868 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1869 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1874 nbNodes = elOfType->NbNodes();
1875 nbCorners = elOfType->NbCornerNodes();
1877 bool toStopChecking = false;
1878 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1879 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1881 const int nID = nIt->next()->GetID();
1882 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1883 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1885 resGroupCore.Add( elOfType );
1893 // Update Python script
1894 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1895 << ".CreateDimGroup( "
1896 << theGroups << ", " << theElemType << ", '" << theName << "', "
1897 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1899 SMESH_CATCH( SMESH::throwCorbaException );
1901 return aResGrp._retn();
1904 //================================================================================
1906 * \brief Distribute all faces of the mesh between groups using sharp edges and optionally
1907 * existing 1D elements as group boundaries.
1908 * \param [in] theSharpAngle - edge is considered sharp if an angle between normals of
1909 * adjacent faces is more than \a sharpAngle in degrees.
1910 * \param [in] theCreateEdges - to create 1D elements for detected sharp edges.
1911 * \param [in] theUseExistingEdges - to use existing edges as group boundaries
1912 * \return ListOfGroups - the created groups
1914 //================================================================================
1916 SMESH::ListOfGroups*
1917 SMESH_Mesh_i::FaceGroupsSeparatedByEdges( CORBA::Double theSharpAngle,
1918 CORBA::Boolean theCreateEdges,
1919 CORBA::Boolean theUseExistingEdges )
1920 throw (SALOME::SALOME_Exception)
1922 if ( theSharpAngle < 0 || theSharpAngle > 180 )
1923 THROW_SALOME_CORBA_EXCEPTION("Invalid sharp angle, it must be between 0 and 180 degrees",
1926 SMESH::ListOfGroups_var resultGroups = new SMESH::ListOfGroups;
1932 _preMeshInfo->FullLoadFromFile();
1934 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1936 std::vector< SMESH_MeshAlgos::Edge > edges =
1937 SMESH_MeshAlgos::FindSharpEdges( meshDS, theSharpAngle, theUseExistingEdges );
1939 if ( theCreateEdges )
1941 std::vector<const SMDS_MeshNode *> nodes(2);
1942 for ( size_t i = 0; i < edges.size(); ++i )
1944 nodes[0] = edges[i]._node1;
1945 nodes[1] = edges[i]._node2;
1946 if ( meshDS->FindElement( nodes, SMDSAbs_Edge ))
1948 if ( edges[i]._medium )
1949 meshDS->AddEdge( edges[i]._node1, edges[i]._node2, edges[i]._medium );
1951 meshDS->AddEdge( edges[i]._node1, edges[i]._node2 );
1955 std::vector< std::vector< const SMDS_MeshElement* > > faceGroups =
1956 SMESH_MeshAlgos::SeparateFacesByEdges( meshDS, edges );
1958 SMESH::SMESH_MeshEditor_var editor = GetMeshEditor(); // create _editor
1960 resultGroups->length( faceGroups.size() );
1961 for ( size_t iG = 0; iG < faceGroups.size(); ++iG )
1963 SMESH::SMESH_Group_var group = CreateGroup( SMESH::FACE,
1964 _editor->GenerateGroupName("Group").c_str());
1965 resultGroups[iG] = SMESH::SMESH_Group::_duplicate( group );
1967 SMESHDS_GroupBase* groupBaseDS =
1968 SMESH::DownCast<SMESH_GroupBase_i*>( group )->GetGroupDS();
1969 SMDS_MeshGroup& groupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1971 std::vector< const SMDS_MeshElement* >& faces = faceGroups[ iG ];
1972 for ( size_t i = 0; i < faces.size(); ++i )
1973 groupCore.Add( faces[i] );
1976 pyDump << resultGroups << " = " << SMESH::SMESH_Mesh_var(_this())
1977 << ".FaceGroupsSeparatedByEdges( "
1978 << TVar( theSharpAngle ) << ", "
1979 << theCreateEdges << ", "
1980 << theUseExistingEdges << " )";
1982 SMESH_CATCH( SMESH::throwCorbaException );
1983 return resultGroups._retn();
1987 //================================================================================
1989 * \brief Remember GEOM group data
1991 //================================================================================
1993 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1994 CORBA::Object_ptr theSmeshObj)
1996 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1999 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
2000 if ( groupSO->_is_nil() )
2003 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( theGeomObj );
2004 GEOM::GEOM_IGroupOperations_ptr groupOp =
2005 geomGen->GetIGroupOperations();
2006 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
2009 _geomGroupData.push_back( TGeomGroupData() );
2010 TGeomGroupData & groupData = _geomGroupData.back();
2012 CORBA::String_var entry = groupSO->GetID();
2013 groupData._groupEntry = entry.in();
2015 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2016 groupData._indices.insert( ids[i] );
2018 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
2019 // shape index in SMESHDS
2020 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
2021 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
2024 //================================================================================
2026 * Remove GEOM group data relating to removed smesh object
2028 //================================================================================
2030 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
2032 list<TGeomGroupData>::iterator
2033 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2034 for ( ; data != dataEnd; ++data ) {
2035 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
2036 _geomGroupData.erase( data );
2042 //================================================================================
2044 * \brief Return new group contents if it has been changed and update group data
2046 //================================================================================
2048 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
2050 TopoDS_Shape newShape;
2053 SALOMEDS::SObject_wrap groupSO = SMESH_Gen_i::getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
2054 if ( !groupSO->_is_nil() )
2056 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
2057 if ( CORBA::is_nil( groupObj )) return newShape;
2058 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
2060 // get indices of group items
2061 set<int> curIndices;
2062 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( geomGroup );
2063 GEOM::GEOM_IGroupOperations_ptr groupOp =
2064 geomGen->GetIGroupOperations();
2065 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
2066 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2067 curIndices.insert( ids[i] );
2069 if ( groupData._indices == curIndices )
2070 return newShape; // group not changed
2073 groupData._indices = curIndices;
2075 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2076 if ( !geomClient ) return newShape;
2077 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
2078 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
2079 newShape = _gen_i->GeomObjectToShape( geomGroup );
2082 if ( newShape.IsNull() ) {
2083 // geom group becomes empty - return empty compound
2084 TopoDS_Compound compound;
2085 BRep_Builder().MakeCompound(compound);
2086 newShape = compound;
2093 //-----------------------------------------------------------------------------
2095 * \brief Storage of shape and index used in CheckGeomGroupModif()
2097 struct TIndexedShape
2100 TopoDS_Shape _shape;
2101 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
2103 //-----------------------------------------------------------------------------
2105 * \brief Data to re-create a group on geometry
2107 struct TGroupOnGeomData
2110 TopoDS_Shape _shape;
2111 SMDSAbs_ElementType _type;
2113 Quantity_Color _color;
2115 TGroupOnGeomData( const SMESHDS_GroupOnGeom* group )
2117 _oldID = group->GetID();
2118 _type = group->GetType();
2119 _name = group->GetStoreName();
2120 _color = group->GetColor();
2124 //-----------------------------------------------------------------------------
2126 * \brief Check if a filter is still valid after geometry removal
2128 bool isValidGeomFilter( SMESH::Filter_var theFilter )
2130 if ( theFilter->_is_nil() )
2132 SMESH::Filter::Criteria_var criteria;
2133 theFilter->GetCriteria( criteria.out() );
2135 for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr )
2137 const char* thresholdID = criteria[ iCr ].ThresholdID.in();
2139 switch ( criteria[ iCr ].Type )
2141 case SMESH::FT_BelongToGeom:
2142 case SMESH::FT_BelongToPlane:
2143 case SMESH::FT_BelongToCylinder:
2144 case SMESH::FT_BelongToGenSurface:
2145 case SMESH::FT_LyingOnGeom:
2146 entry = thresholdID;
2148 case SMESH::FT_ConnectedElements:
2151 entry = thresholdID;
2157 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
2158 SALOMEDS::SObject_wrap so = gen->getStudyServant()->FindObjectID( entry.c_str() );
2159 if ( so->_is_nil() )
2161 CORBA::Object_var obj = so->GetObject();
2162 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( obj );
2163 if ( gen->GeomObjectToShape( geom ).IsNull() )
2166 } // loop on criteria
2172 //=============================================================================
2174 * \brief Update data if geometry changes
2178 //=============================================================================
2180 void SMESH_Mesh_i::CheckGeomModif()
2182 SMESH::SMESH_Mesh_var me = _this();
2183 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2185 //bool removedFromClient = false;
2187 if ( mainGO->_is_nil() ) // GEOM_Client cleared or geometry removed? (IPAL52735, PAL23636)
2189 //removedFromClient = _impl->HasShapeToMesh();
2191 // try to find geometry by study reference
2192 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2193 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2194 if ( !meshSO->_is_nil() &&
2195 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2196 geomRefSO->ReferencedObject( geomSO.inout() ))
2198 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2199 mainGO = GEOM::GEOM_Object::_narrow( geomObj );
2202 if ( mainGO->_is_nil() && // geometry removed ==>
2203 !geomRefSO->_is_nil() ) // remove geom dependent data: sub-meshes etc.
2205 // convert geom dependent groups into standalone ones
2206 CheckGeomGroupModif();
2208 _impl->ShapeToMesh( TopoDS_Shape() );
2210 // remove sub-meshes
2211 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2212 while ( i_sm != _mapSubMeshIor.end() )
2214 SMESH::SMESH_subMesh_ptr sm = i_sm->second;
2216 RemoveSubMesh( sm );
2218 // remove all children except groups in the study
2219 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2220 SALOMEDS::SObject_wrap so;
2221 for ( CORBA::Long tag = SMESH::Tag_RefOnShape; tag <= SMESH::Tag_LastSubMesh; ++tag )
2222 if ( meshSO->FindSubObject( tag, so.inout() ))
2223 builder->RemoveObjectWithChildren( so );
2225 _gen_i->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED" );
2231 if ( !_impl->HasShapeToMesh() ) return;
2234 // Update after group modification
2236 if ( mainGO->GetType() == GEOM_GROUP || // is group or not modified
2237 mainGO->GetTick() == _mainShapeTick )
2239 int nb = NbNodes() + NbElements();
2240 CheckGeomGroupModif();
2241 if ( nb != NbNodes() + NbElements() ) // something removed due to hypotheses change
2242 _gen_i->UpdateIcons( me );
2246 // Update after shape transformation like Translate
2248 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2249 if ( !geomClient ) return;
2250 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( mainGO );
2251 if ( geomGen->_is_nil() ) return;
2253 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2254 geomClient->RemoveShapeFromBuffer( ior.in() );
2256 // Update data taking into account that
2257 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2260 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2261 if ( newShape.IsNull() )
2264 // for the SHAPER-STUDY: the geometry may be updated, so, add a warning icon
2265 if (_mainShapeTick != mainGO->GetTick()) {
2266 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2267 if ( !meshSO->_is_nil())
2268 _gen_i->SetPixMap(meshSO, "ICON_SMESH_TREE_MESH_WARN");
2271 _mainShapeTick = mainGO->GetTick();
2273 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2275 // store data of groups on geometry
2276 std::vector< TGroupOnGeomData > groupsData;
2277 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2278 groupsData.reserve( groups.size() );
2279 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2280 for ( ; g != groups.end(); ++g )
2282 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2284 groupsData.push_back( TGroupOnGeomData( group ));
2287 SMESH::SMESH_GroupOnGeom_var gog;
2288 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.find( group->GetID() );
2289 if ( i_grp != _mapGroups.end() )
2290 gog = SMESH::SMESH_GroupOnGeom::_narrow( i_grp->second );
2292 GEOM::GEOM_Object_var geom;
2293 if ( !gog->_is_nil() )
2294 geom = gog->GetShape();
2295 if ( !geom->_is_nil() )
2297 CORBA::String_var ior = geomGen->GetStringFromIOR( geom );
2298 geomClient->RemoveShapeFromBuffer( ior.in() );
2299 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2303 // store assigned hypotheses
2304 std::vector< pair< int, THypList > > ids2Hyps;
2305 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2306 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2308 const TopoDS_Shape& s = s2hyps.Key();
2309 const THypList& hyps = s2hyps.ChangeValue();
2310 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2313 // change shape to mesh
2314 int oldNbSubShapes = meshDS->MaxShapeIndex();
2315 _impl->ShapeToMesh( TopoDS_Shape() );
2316 _impl->ShapeToMesh( newShape );
2318 // re-add shapes of geom groups
2319 std::list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2320 for ( ; data != _geomGroupData.end(); ++data )
2322 TopoDS_Shape newShape = newGroupShape( *data );
2323 if ( !newShape.IsNull() )
2325 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2327 TopoDS_Compound compound;
2328 BRep_Builder().MakeCompound( compound );
2329 BRep_Builder().Add( compound, newShape );
2330 newShape = compound;
2332 _impl->GetSubMesh( newShape );
2335 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2336 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2337 SALOME::INTERNAL_ERROR );
2339 // re-assign hypotheses
2340 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2342 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2343 const THypList& hyps = ids2Hyps[i].second;
2344 THypList::const_iterator h = hyps.begin();
2345 for ( ; h != hyps.end(); ++h )
2346 _impl->AddHypothesis( s, (*h)->GetID() );
2349 // restore groups on geometry
2350 for ( size_t i = 0; i < groupsData.size(); ++i )
2352 const TGroupOnGeomData& data = groupsData[i];
2353 if ( data._shape.IsNull() )
2356 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2357 if ( i2g == _mapGroups.end() ) continue;
2359 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2360 if ( !gr_i ) continue;
2362 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape );
2364 _mapGroups.erase( i2g );
2366 g->GetGroupDS()->SetColor( data._color );
2369 // update _mapSubMesh
2370 std::map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2371 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2372 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2376 //=============================================================================
2378 * \brief Update objects depending on changed geom groups
2380 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2381 * issue 0020210: Update of a smesh group after modification of the associated geom group
2383 //=============================================================================
2385 void SMESH_Mesh_i::CheckGeomGroupModif()
2387 // remove sub-meshes referring a removed sub-shapes (if main shape still exists)
2388 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2389 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2390 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() ));
2391 if ( !mainGO->_is_nil() && !meshSO->_is_nil() )
2393 SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO;
2394 for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag )
2395 if ( meshSO->FindSubObject( tag, rootSO.inout() ))
2397 int nbValid = 0, nbRemoved = 0;
2398 SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO );
2399 for ( ; chItr->More(); chItr->Next() )
2401 SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO
2402 if ( !smSO->_is_nil() &&
2403 smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2404 geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference
2406 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2407 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2408 if ( !geom->_non_existent() )
2411 continue; // keep the sub-mesh
2414 CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO );
2415 SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj );
2416 if ( !sm->_is_nil() && !sm->_non_existent() )
2418 GEOM::GEOM_Object_var smGeom = sm->GetSubShape();
2419 if ( smGeom->_is_nil() )
2421 RemoveSubMesh( sm );
2428 _preMeshInfo->ForgetAllData(); // unknown hypothesis modified
2429 builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH
2433 if ( /*nbRemoved > 0 &&*/ nbValid == 0 )
2434 builder->RemoveObjectWithChildren( rootSO );
2438 // check for removed sub-shapes and convert geom dependent groups into standalone ones
2439 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2440 while ( i_gr != _mapGroups.end())
2442 SMESH::SMESH_GroupBase_ptr group = i_gr->second;
2444 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO;
2445 SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group );
2446 SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group );
2447 bool isValidGeom = false;
2448 if ( !onGeom->_is_nil() )
2450 isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() );
2452 else if ( !onFilt->_is_nil() )
2454 isValidGeom = isValidGeomFilter( onFilt->GetFilter() );
2458 isValidGeom = ( !groupSO->_is_nil() &&
2459 !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ));
2463 if ( !IsLoaded() || group->IsEmpty() )
2465 RemoveGroup( group );
2467 else if ( !onGeom->_is_nil() || !onFilt->_is_nil() )
2469 SMESH::SMESH_Group_var ( ConvertToStandalone( group ));
2471 else // is it possible?
2473 builder->RemoveObjectWithChildren( refSO );
2479 if ( !_impl->HasShapeToMesh() ) return;
2481 CORBA::Long nbEntities = NbNodes() + NbElements();
2483 // Check if group contents changed
2485 typedef map< string, TopoDS_Shape > TEntry2Geom;
2486 TEntry2Geom newGroupContents;
2488 list<TGeomGroupData>::iterator
2489 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2490 for ( ; data != dataEnd; ++data )
2492 pair< TEntry2Geom::iterator, bool > it_new =
2493 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2494 bool processedGroup = !it_new.second;
2495 TopoDS_Shape& newShape = it_new.first->second;
2496 if ( !processedGroup )
2497 newShape = newGroupShape( *data );
2498 if ( newShape.IsNull() )
2499 continue; // no changes
2502 _preMeshInfo->ForgetOrLoad();
2504 if ( processedGroup ) { // update group indices
2505 list<TGeomGroupData>::iterator data2 = data;
2506 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2507 data->_indices = data2->_indices;
2510 // Update SMESH objects according to new GEOM group contents
2512 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2513 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2515 int oldID = submesh->GetId();
2516 if ( !_mapSubMeshIor.count( oldID ))
2518 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2520 // update hypotheses
2521 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2522 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2523 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2525 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2526 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2528 // care of submeshes
2529 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2530 int newID = newSubmesh->GetId();
2531 if ( newID != oldID ) {
2532 _mapSubMesh [ newID ] = newSubmesh;
2533 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2534 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2535 _mapSubMesh. erase(oldID);
2536 _mapSubMesh_i. erase(oldID);
2537 _mapSubMeshIor.erase(oldID);
2538 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2543 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2544 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2545 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2547 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2549 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2550 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2551 ds->SetShape( newShape );
2556 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2557 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2559 // Remove groups and submeshes basing on removed sub-shapes
2561 TopTools_MapOfShape newShapeMap;
2562 TopoDS_Iterator shapeIt( newShape );
2563 for ( ; shapeIt.More(); shapeIt.Next() )
2564 newShapeMap.Add( shapeIt.Value() );
2566 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2567 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2569 if ( newShapeMap.Contains( shapeIt.Value() ))
2571 TopTools_IndexedMapOfShape oldShapeMap;
2572 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2573 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2575 const TopoDS_Shape& oldShape = oldShapeMap(i);
2576 int oldInd = meshDS->ShapeToIndex( oldShape );
2578 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2579 if ( i_smIor != _mapSubMeshIor.end() ) {
2580 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2583 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2584 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2586 // check if a group bases on oldInd shape
2587 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2588 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2589 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2590 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2592 RemoveGroup( i_grp->second ); // several groups can base on same shape
2593 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2598 // Reassign hypotheses and update groups after setting the new shape to mesh
2600 // collect anassigned hypotheses
2601 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2602 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2603 TShapeHypList assignedHyps;
2604 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2606 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2607 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2608 if ( !hyps.empty() ) {
2609 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2610 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2611 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2614 // collect shapes supporting groups
2615 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2616 TShapeTypeList groupData;
2617 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2618 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2619 for ( ; grIt != groups.end(); ++grIt )
2621 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2623 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2625 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2627 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2628 _impl->ShapeToMesh( newShape );
2630 // reassign hypotheses
2631 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2632 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2634 TIndexedShape& geom = indS_hyps->first;
2635 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2636 int oldID = geom._index;
2637 int newID = meshDS->ShapeToIndex( geom._shape );
2638 if ( oldID == 1 ) { // main shape
2640 geom._shape = newShape;
2644 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2645 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2646 // care of sub-meshes
2647 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2648 if ( newID != oldID ) {
2649 _mapSubMesh [ newID ] = newSubmesh;
2650 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2651 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2652 _mapSubMesh. erase(oldID);
2653 _mapSubMesh_i. erase(oldID);
2654 _mapSubMeshIor.erase(oldID);
2655 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2659 TShapeTypeList::iterator geomType = groupData.begin();
2660 for ( ; geomType != groupData.end(); ++geomType )
2662 const TIndexedShape& geom = geomType->first;
2663 int oldID = geom._index;
2664 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2667 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2668 CORBA::String_var name = groupSO->GetName();
2670 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
2671 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
2672 /*id=*/-1, geom._shape ))
2673 group_i->changeLocalId( group->GetID() );
2676 break; // everything has been updated
2679 } // loop on group data
2683 CORBA::Long newNbEntities = NbNodes() + NbElements();
2684 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2685 if ( newNbEntities != nbEntities )
2687 // Add all SObjects with icons to soToUpdateIcons
2688 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2690 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2691 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2692 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2694 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2695 i_gr != _mapGroups.end(); ++i_gr ) // groups
2696 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2699 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2700 for ( ; so != soToUpdateIcons.end(); ++so )
2701 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2704 //=============================================================================
2706 * \brief Create standalone group from a group on geometry or filter
2708 //=============================================================================
2710 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2711 throw (SALOME::SALOME_Exception)
2713 SMESH::SMESH_Group_var aGroup;
2718 _preMeshInfo->FullLoadFromFile();
2720 if ( theGroup->_is_nil() )
2721 return aGroup._retn();
2723 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2725 return aGroup._retn();
2727 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2729 const int anId = aGroupToRem->GetLocalID();
2730 if ( !_impl->ConvertToStandalone( anId ) )
2731 return aGroup._retn();
2732 removeGeomGroupData( theGroup );
2734 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2736 // remove old instance of group from own map
2737 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2738 _mapGroups.erase( anId );
2740 SALOMEDS::StudyBuilder_var builder;
2741 SALOMEDS::SObject_wrap aGroupSO;
2742 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2743 if ( !aStudy->_is_nil() ) {
2744 builder = aStudy->NewBuilder();
2745 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2746 if ( !aGroupSO->_is_nil() )
2748 // remove reference to geometry
2749 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2750 for ( ; chItr->More(); chItr->Next() )
2752 // Remove group's child SObject
2753 SALOMEDS::SObject_wrap so = chItr->Value();
2754 builder->RemoveObject( so );
2756 // Update Python script
2757 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2758 << ".ConvertToStandalone( " << aGroupSO << " )";
2760 // change icon of Group on Filter
2763 // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2764 // const int isEmpty = ( elemTypes->length() == 0 );
2767 SALOMEDS::GenericAttribute_wrap anAttr =
2768 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2769 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2770 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2776 // remember new group in own map
2777 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2778 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2780 // register CORBA object for persistence
2781 _gen_i->RegisterObject( aGroup );
2783 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2784 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2785 //aGroup->Register();
2786 aGroupToRem->UnRegister();
2788 SMESH_CATCH( SMESH::throwCorbaException );
2790 return aGroup._retn();
2793 //=============================================================================
2797 //=============================================================================
2799 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2801 if(MYDEBUG) MESSAGE( "createSubMesh" );
2802 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2803 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2806 SMESH_subMesh_i * subMeshServant;
2809 subMeshId = mySubMesh->GetId();
2810 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2812 else // "invalid sub-mesh"
2814 // The invalid sub-mesh is created for the case where a valid sub-shape not found
2815 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
2816 if ( _mapSubMesh.empty() )
2819 subMeshId = _mapSubMesh.begin()->first - 1;
2820 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
2823 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2825 _mapSubMesh [subMeshId] = mySubMesh;
2826 _mapSubMesh_i [subMeshId] = subMeshServant;
2827 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2829 subMeshServant->Register();
2831 // register CORBA object for persistence
2832 int nextId = _gen_i->RegisterObject( subMesh );
2833 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2834 else { nextId = 0; } // avoid "unused variable" warning
2836 // to track changes of GEOM groups
2837 if ( subMeshId > 0 )
2838 addGeomGroupData( theSubShapeObject, subMesh );
2840 return subMesh._retn();
2843 //=======================================================================
2844 //function : getSubMesh
2846 //=======================================================================
2848 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2850 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2851 if ( it == _mapSubMeshIor.end() )
2852 return SMESH::SMESH_subMesh::_nil();
2854 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2857 //=============================================================================
2861 //=============================================================================
2863 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2864 GEOM::GEOM_Object_ptr theSubShapeObject )
2866 bool isHypChanged = false;
2867 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2868 return isHypChanged;
2870 const int subMeshId = theSubMesh->GetId();
2872 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2875 if (( _mapSubMesh.count( subMeshId )) &&
2876 ( sm = _impl->GetSubMeshContaining( subMeshId )))
2878 TopoDS_Shape S = sm->GetSubShape();
2881 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2882 isHypChanged = !hyps.empty();
2883 if ( isHypChanged && _preMeshInfo )
2884 _preMeshInfo->ForgetOrLoad();
2885 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2886 for ( ; hyp != hyps.end(); ++hyp )
2887 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2894 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2895 isHypChanged = ( aHypList->length() > 0 );
2896 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2897 removeHypothesis( theSubShapeObject, aHypList[i] );
2900 catch( const SALOME::SALOME_Exception& ) {
2901 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2903 removeGeomGroupData( theSubShapeObject );
2907 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2908 if ( id_smi != _mapSubMesh_i.end() )
2909 id_smi->second->UnRegister();
2911 // remove a CORBA object
2912 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2913 if ( id_smptr != _mapSubMeshIor.end() )
2914 SMESH::SMESH_subMesh_var( id_smptr->second );
2916 _mapSubMesh.erase(subMeshId);
2917 _mapSubMesh_i.erase(subMeshId);
2918 _mapSubMeshIor.erase(subMeshId);
2920 return isHypChanged;
2923 //=============================================================================
2927 //=============================================================================
2929 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2930 const char* theName,
2932 const TopoDS_Shape& theShape,
2933 const SMESH_PredicatePtr& thePredicate )
2935 std::string newName;
2936 if ( !theName || !theName[0] )
2938 std::set< std::string > presentNames;
2939 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2940 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2942 CORBA::String_var name = i_gr->second->GetName();
2943 presentNames.insert( name.in() );
2946 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2947 } while ( !presentNames.insert( newName ).second );
2948 theName = newName.c_str();
2950 SMESH::SMESH_GroupBase_var aGroup;
2951 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
2952 theID, theShape, thePredicate ))
2954 int anId = g->GetID();
2955 SMESH_GroupBase_i* aGroupImpl;
2956 if ( !theShape.IsNull() )
2957 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2958 else if ( thePredicate )
2959 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2961 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2963 aGroup = aGroupImpl->_this();
2964 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2965 aGroupImpl->Register();
2967 // register CORBA object for persistence
2968 int nextId = _gen_i->RegisterObject( aGroup );
2969 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2970 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
2972 // to track changes of GEOM groups
2973 if ( !theShape.IsNull() ) {
2974 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2975 addGeomGroupData( geom, aGroup );
2978 return aGroup._retn();
2981 //=============================================================================
2983 * SMESH_Mesh_i::removeGroup
2985 * Should be called by ~SMESH_Group_i()
2987 //=============================================================================
2989 void SMESH_Mesh_i::removeGroup( const int theId )
2991 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2992 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2993 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2994 _mapGroups.erase( theId );
2995 removeGeomGroupData( group );
2996 if ( !_impl->RemoveGroup( theId ))
2998 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2999 RemoveGroup( group );
3001 group->UnRegister();
3005 //=============================================================================
3009 //=============================================================================
3011 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
3012 throw(SALOME::SALOME_Exception)
3014 SMESH::log_array_var aLog;
3018 _preMeshInfo->FullLoadFromFile();
3020 list < SMESHDS_Command * >logDS = _impl->GetLog();
3021 aLog = new SMESH::log_array;
3023 int lg = logDS.size();
3026 list < SMESHDS_Command * >::iterator its = logDS.begin();
3027 while(its != logDS.end()){
3028 SMESHDS_Command *com = *its;
3029 int comType = com->GetType();
3031 int lgcom = com->GetNumber();
3033 const list < int >&intList = com->GetIndexes();
3034 int inum = intList.size();
3036 list < int >::const_iterator ii = intList.begin();
3037 const list < double >&coordList = com->GetCoords();
3038 int rnum = coordList.size();
3040 list < double >::const_iterator ir = coordList.begin();
3041 aLog[indexLog].commandType = comType;
3042 aLog[indexLog].number = lgcom;
3043 aLog[indexLog].coords.length(rnum);
3044 aLog[indexLog].indexes.length(inum);
3045 for(int i = 0; i < rnum; i++){
3046 aLog[indexLog].coords[i] = *ir;
3047 //MESSAGE(" "<<i<<" "<<ir.Value());
3050 for(int i = 0; i < inum; i++){
3051 aLog[indexLog].indexes[i] = *ii;
3052 //MESSAGE(" "<<i<<" "<<ii.Value());
3061 SMESH_CATCH( SMESH::throwCorbaException );
3063 return aLog._retn();
3067 //=============================================================================
3071 //=============================================================================
3073 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
3077 SMESH_CATCH( SMESH::throwCorbaException );
3080 //=============================================================================
3084 //=============================================================================
3086 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
3091 //=============================================================================
3094 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
3095 // issue 0020918: groups removal is caused by hyp modification
3096 // issue 0021208: to forget not loaded mesh data at hyp modification
3097 struct TCallUp_i : public SMESH_Mesh::TCallUp
3099 SMESH_Mesh_i* _mesh;
3100 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
3101 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
3102 virtual void HypothesisModified (int theHypID) { _mesh->onHypothesisModified( theHypID ); }
3103 virtual void Load () { _mesh->Load(); }
3107 //================================================================================
3109 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
3111 //================================================================================
3113 void SMESH_Mesh_i::onHypothesisModified(int theHypID)
3116 _preMeshInfo->ForgetOrLoad();
3118 SMESH::SMESH_Mesh_var mesh = _this();
3119 _gen_i->UpdateIcons( mesh );
3121 // mark a hypothesis as valid after edition
3122 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
3123 SALOMEDS::SObject_wrap hypRoot;
3124 if ( !smeshComp->_is_nil() &&
3125 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
3127 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
3128 for ( ; anIter->More(); anIter->Next() )
3130 SALOMEDS::SObject_wrap hypSO = anIter->Value();
3131 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
3132 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
3133 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
3134 _gen_i->HighLightInvalid( hyp, false );
3139 //=============================================================================
3143 //=============================================================================
3145 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
3147 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
3150 _impl->SetCallUp( new TCallUp_i(this));
3153 //=============================================================================
3157 //=============================================================================
3159 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
3161 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
3165 //=============================================================================
3167 * Return mesh editor
3169 //=============================================================================
3171 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
3172 throw (SALOME::SALOME_Exception)
3174 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3178 _preMeshInfo->FullLoadFromFile();
3180 // Create MeshEditor
3182 _editor = new SMESH_MeshEditor_i( this, false );
3183 aMeshEdVar = _editor->_this();
3185 // Update Python script
3186 TPythonDump() << _editor << " = "
3187 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
3189 SMESH_CATCH( SMESH::throwCorbaException );
3191 return aMeshEdVar._retn();
3194 //=============================================================================
3196 * Return mesh edition previewer
3198 //=============================================================================
3200 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
3201 throw (SALOME::SALOME_Exception)
3203 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3207 _preMeshInfo->FullLoadFromFile();
3209 if ( !_previewEditor )
3210 _previewEditor = new SMESH_MeshEditor_i( this, true );
3211 aMeshEdVar = _previewEditor->_this();
3213 SMESH_CATCH( SMESH::throwCorbaException );
3215 return aMeshEdVar._retn();
3218 //================================================================================
3220 * \brief Return true if the mesh has been edited since a last total re-compute
3221 * and those modifications may prevent successful partial re-compute
3223 //================================================================================
3225 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
3227 Unexpect aCatch(SALOME_SalomeException);
3228 return _impl->HasModificationsToDiscard();
3231 //================================================================================
3233 * \brief Returns a random unique color
3235 //================================================================================
3237 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
3239 const int MAX_ATTEMPTS = 100;
3241 double tolerance = 0.5;
3242 SALOMEDS::Color col;
3246 // generate random color
3247 double red = (double)rand() / RAND_MAX;
3248 double green = (double)rand() / RAND_MAX;
3249 double blue = (double)rand() / RAND_MAX;
3250 // check existence in the list of the existing colors
3251 bool matched = false;
3252 std::list<SALOMEDS::Color>::const_iterator it;
3253 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3254 SALOMEDS::Color color = *it;
3255 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3256 matched = tol < tolerance;
3258 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3259 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3267 //=============================================================================
3269 * Sets auto-color mode. If it is on, groups get unique random colors
3271 //=============================================================================
3273 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
3275 Unexpect aCatch(SALOME_SalomeException);
3276 _impl->SetAutoColor(theAutoColor);
3278 TPythonDump pyDump; // not to dump group->SetColor() from below code
3279 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3281 std::list<SALOMEDS::Color> aReservedColors;
3282 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3283 for ( ; it != _mapGroups.end(); it++ ) {
3284 if ( CORBA::is_nil( it->second )) continue;
3285 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3286 it->second->SetColor( aColor );
3287 aReservedColors.push_back( aColor );
3291 //=============================================================================
3293 * Returns true if auto-color mode is on
3295 //=============================================================================
3297 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
3299 Unexpect aCatch(SALOME_SalomeException);
3300 return _impl->GetAutoColor();
3303 //=============================================================================
3305 * Checks if there are groups with equal names
3307 //=============================================================================
3309 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3311 return _impl->HasDuplicatedGroupNamesMED();
3314 //================================================================================
3316 * \brief Care of a file before exporting mesh into it
3318 //================================================================================
3320 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3322 SMESH_File aFile( file, false );
3324 if ( aFile.exists() ) {
3325 // existing filesystem node
3326 if ( !aFile.isDirectory() ) {
3327 if ( aFile.openForWriting() ) {
3328 if ( overwrite && ! aFile.remove()) {
3329 msg << "Can't replace " << aFile.getName();
3332 msg << "Can't write into " << aFile.getName();
3335 msg << "Location " << aFile.getName() << " is not a file";
3339 // nonexisting file; check if it can be created
3340 if ( !aFile.openForWriting() ) {
3341 msg << "You cannot create the file "
3343 << ". Check the directory existence and access rights";
3351 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3355 //================================================================================
3357 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
3358 * \param file - file name
3359 * \param overwrite - to erase the file or not
3360 * \retval string - mesh name
3362 //================================================================================
3364 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3365 CORBA::Boolean overwrite)
3368 PrepareForWriting(file, overwrite);
3369 string aMeshName = "Mesh";
3370 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3371 if ( !aStudy->_is_nil() ) {
3372 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3373 if ( !aMeshSO->_is_nil() ) {
3374 CORBA::String_var name = aMeshSO->GetName();
3376 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3377 if ( !aStudy->GetProperties()->IsLocked() )
3379 SALOMEDS::GenericAttribute_wrap anAttr;
3380 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3381 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3382 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3383 ASSERT(!aFileName->_is_nil());
3384 aFileName->SetValue(file);
3385 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3386 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3387 ASSERT(!aFileType->_is_nil());
3388 aFileType->SetValue("FICHIERMED");
3392 // Update Python script
3393 // set name of mesh before export
3394 TPythonDump() << _gen_i << ".SetName("
3395 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3397 // check names of groups
3403 //================================================================================
3405 * \brief Export to MED file
3407 //================================================================================
3409 void SMESH_Mesh_i::ExportMED(const char* file,
3410 CORBA::Boolean auto_groups,
3411 CORBA::Long version,
3412 CORBA::Boolean overwrite,
3413 CORBA::Boolean autoDimension)
3414 throw(SALOME::SALOME_Exception)
3416 //MESSAGE("MED minor version: "<< minor);
3419 _preMeshInfo->FullLoadFromFile();
3421 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3422 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3424 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3426 << "auto_groups=" <<auto_groups << ", "
3427 << "minor=" << version << ", "
3428 << "overwrite=" << overwrite << ", "
3429 << "meshPart=None, "
3430 << "autoDimension=" << autoDimension << " )";
3432 SMESH_CATCH( SMESH::throwCorbaException );
3435 //================================================================================
3437 * \brief Export a mesh to a SAUV file
3439 //================================================================================
3441 void SMESH_Mesh_i::ExportSAUV (const char* file,
3442 CORBA::Boolean auto_groups)
3443 throw(SALOME::SALOME_Exception)
3445 Unexpect aCatch(SALOME_SalomeException);
3447 _preMeshInfo->FullLoadFromFile();
3449 string aMeshName = prepareMeshNameAndGroups(file, true);
3450 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3451 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3452 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3456 //================================================================================
3458 * \brief Export a mesh to a DAT file
3460 //================================================================================
3462 void SMESH_Mesh_i::ExportDAT (const char *file)
3463 throw(SALOME::SALOME_Exception)
3465 Unexpect aCatch(SALOME_SalomeException);
3467 _preMeshInfo->FullLoadFromFile();
3469 // Update Python script
3470 // check names of groups
3472 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3475 PrepareForWriting(file);
3476 _impl->ExportDAT(file);
3479 //================================================================================
3481 * \brief Export a mesh to an UNV file
3483 //================================================================================
3485 void SMESH_Mesh_i::ExportUNV (const char *file)
3486 throw(SALOME::SALOME_Exception)
3488 Unexpect aCatch(SALOME_SalomeException);
3490 _preMeshInfo->FullLoadFromFile();
3492 // Update Python script
3493 // check names of groups
3495 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3498 PrepareForWriting(file);
3499 _impl->ExportUNV(file);
3502 //================================================================================
3504 * \brief Export a mesh to an STL file
3506 //================================================================================
3508 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3509 throw(SALOME::SALOME_Exception)
3511 Unexpect aCatch(SALOME_SalomeException);
3513 _preMeshInfo->FullLoadFromFile();
3515 // Update Python script
3516 // check names of groups
3518 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3519 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3521 CORBA::String_var name;
3522 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3523 if ( !so->_is_nil() )
3524 name = so->GetName();
3527 PrepareForWriting( file );
3528 _impl->ExportSTL( file, isascii, name.in() );
3531 //================================================================================
3533 * \brief Export a part of mesh to a med file
3535 //================================================================================
3537 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3539 CORBA::Boolean auto_groups,
3540 CORBA::Long version,
3541 CORBA::Boolean overwrite,
3542 CORBA::Boolean autoDimension,
3543 const GEOM::ListOfFields& fields,
3544 const char* geomAssocFields,
3545 CORBA::Double ZTolerance)
3546 throw (SALOME::SALOME_Exception)
3548 MESSAGE("MED version: "<< version);
3551 _preMeshInfo->FullLoadFromFile();
3554 bool have0dField = false;
3555 if ( fields.length() > 0 )
3557 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3558 if ( shapeToMesh->_is_nil() )
3559 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3561 for ( size_t i = 0; i < fields.length(); ++i )
3563 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3564 THROW_SALOME_CORBA_EXCEPTION
3565 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3566 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3567 if ( fieldShape->_is_nil() )
3568 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3569 if ( !fieldShape->IsSame( shapeToMesh ) )
3570 THROW_SALOME_CORBA_EXCEPTION
3571 ( "Field defined not on shape", SALOME::BAD_PARAM);
3572 if ( fields[i]->GetDimension() == 0 )
3575 if ( geomAssocFields )
3576 for ( int i = 0; geomAssocFields[i]; ++i )
3577 switch ( geomAssocFields[i] ) {
3578 case 'v':case 'e':case 'f':case 's': break;
3579 case 'V':case 'E':case 'F':case 'S': break;
3580 default: THROW_SALOME_CORBA_EXCEPTION
3581 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3585 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3589 string aMeshName = "Mesh";
3590 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3591 if ( CORBA::is_nil( meshPart ) ||
3592 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3594 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3595 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3596 0, autoDimension, /*addODOnVertices=*/have0dField,
3598 meshDS = _impl->GetMeshDS();
3603 _preMeshInfo->FullLoadFromFile();
3605 PrepareForWriting(file, overwrite);
3607 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3608 if ( !SO->_is_nil() ) {
3609 CORBA::String_var name = SO->GetName();
3613 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3614 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3615 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3616 meshDS = tmpDSDeleter._obj = partDS;
3621 if ( _impl->HasShapeToMesh() )
3623 DriverMED_W_Field fieldWriter;
3624 fieldWriter.SetFile( file );
3625 fieldWriter.SetMeshName( aMeshName );
3626 fieldWriter.AddODOnVertices( have0dField );
3628 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3632 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3633 goList->length( fields.length() );
3634 for ( size_t i = 0; i < fields.length(); ++i )
3636 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3639 TPythonDump() << _this() << ".ExportPartToMED( "
3640 << meshPart << ", r'"
3642 << auto_groups << ", "
3644 << overwrite << ", "
3645 << autoDimension << ", "
3647 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
3648 << TVar( ZTolerance )
3651 SMESH_CATCH( SMESH::throwCorbaException );
3654 //================================================================================
3656 * Write GEOM fields to MED file
3658 //================================================================================
3660 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3661 SMESHDS_Mesh* meshDS,
3662 const GEOM::ListOfFields& fields,
3663 const char* geomAssocFields)
3665 #define METH "SMESH_Mesh_i::exportMEDFields() "
3667 if (( fields.length() < 1 ) &&
3668 ( !geomAssocFields || !geomAssocFields[0] ))
3671 std::vector< std::vector< double > > dblVals;
3672 std::vector< std::vector< int > > intVals;
3673 std::vector< int > subIdsByDim[ 4 ];
3674 const double noneDblValue = 0.;
3675 const double noneIntValue = 0;
3677 for ( size_t iF = 0; iF < fields.length(); ++iF )
3681 int dim = fields[ iF ]->GetDimension();
3682 SMDSAbs_ElementType elemType;
3683 TopAbs_ShapeEnum shapeType;
3685 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3686 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3687 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3688 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3690 continue; // skip fields on whole shape
3692 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3693 if ( dataType == GEOM::FDT_String )
3695 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3696 if ( stepIDs->length() < 1 )
3698 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3699 if ( comps->length() < 1 )
3701 CORBA::String_var name = fields[ iF ]->GetName();
3703 if ( !fieldWriter.Set( meshDS,
3707 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3710 for ( size_t iC = 0; iC < comps->length(); ++iC )
3711 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3713 dblVals.resize( comps->length() );
3714 intVals.resize( comps->length() );
3716 // find sub-shape IDs
3718 std::vector< int >& subIds = subIdsByDim[ dim ];
3719 if ( subIds.empty() )
3720 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3721 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3722 subIds.push_back( id );
3726 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3730 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3732 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3733 if ( step->_is_nil() )
3736 CORBA::Long stamp = step->GetStamp();
3737 CORBA::Long id = step->GetID();
3738 fieldWriter.SetDtIt( int( stamp ), int( id ));
3740 // fill dblVals or intVals
3741 for ( size_t iC = 0; iC < comps->length(); ++iC )
3742 if ( dataType == GEOM::FDT_Double )
3744 dblVals[ iC ].clear();
3745 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3749 intVals[ iC ].clear();
3750 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3754 case GEOM::FDT_Double:
3756 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3757 if ( dblStep->_is_nil() ) continue;
3758 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3759 if ( vv->length() != subIds.size() * comps->length() )
3760 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3761 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3762 for ( size_t iC = 0; iC < comps->length(); ++iC )
3763 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3768 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3769 if ( intStep->_is_nil() ) continue;
3770 GEOM::ListOfLong_var vv = intStep->GetValues();
3771 if ( vv->length() != subIds.size() * comps->length() )
3772 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3773 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3774 for ( size_t iC = 0; iC < comps->length(); ++iC )
3775 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3778 case GEOM::FDT_Bool:
3780 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3781 if ( boolStep->_is_nil() ) continue;
3782 GEOM::short_array_var vv = boolStep->GetValues();
3783 if ( vv->length() != subIds.size() * comps->length() )
3784 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3785 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3786 for ( size_t iC = 0; iC < comps->length(); ++iC )
3787 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3793 // pass values to fieldWriter
3794 elemIt = fieldWriter.GetOrderedElems();
3795 if ( dataType == GEOM::FDT_Double )
3796 while ( elemIt->more() )
3798 const SMDS_MeshElement* e = elemIt->next();
3799 const int shapeID = e->getshapeId();
3800 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3801 for ( size_t iC = 0; iC < comps->length(); ++iC )
3802 fieldWriter.AddValue( noneDblValue );
3804 for ( size_t iC = 0; iC < comps->length(); ++iC )
3805 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3808 while ( elemIt->more() )
3810 const SMDS_MeshElement* e = elemIt->next();
3811 const int shapeID = e->getshapeId();
3812 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3813 for ( size_t iC = 0; iC < comps->length(); ++iC )
3814 fieldWriter.AddValue( (double) noneIntValue );
3816 for ( size_t iC = 0; iC < comps->length(); ++iC )
3817 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3821 fieldWriter.Perform();
3822 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3823 if ( res && res->IsKO() )
3825 if ( res->myComment.empty() )
3826 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3828 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3834 if ( !geomAssocFields || !geomAssocFields[0] )
3837 // write geomAssocFields
3839 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3840 shapeDim[ TopAbs_COMPOUND ] = 3;
3841 shapeDim[ TopAbs_COMPSOLID ] = 3;
3842 shapeDim[ TopAbs_SOLID ] = 3;
3843 shapeDim[ TopAbs_SHELL ] = 2;
3844 shapeDim[ TopAbs_FACE ] = 2;
3845 shapeDim[ TopAbs_WIRE ] = 1;
3846 shapeDim[ TopAbs_EDGE ] = 1;
3847 shapeDim[ TopAbs_VERTEX ] = 0;
3848 shapeDim[ TopAbs_SHAPE ] = 3;
3850 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3852 std::vector< std::string > compNames;
3853 switch ( geomAssocFields[ iF ]) {
3855 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3856 compNames.push_back( "dim" );
3859 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3862 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3865 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3869 compNames.push_back( "id" );
3870 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3871 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3873 fieldWriter.SetDtIt( -1, -1 );
3875 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3879 if ( compNames.size() == 2 ) // _vertices_
3880 while ( elemIt->more() )
3882 const SMDS_MeshElement* e = elemIt->next();
3883 const int shapeID = e->getshapeId();
3886 fieldWriter.AddValue( (double) -1 );
3887 fieldWriter.AddValue( (double) -1 );
3891 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3892 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3893 fieldWriter.AddValue( (double) shapeID );
3897 while ( elemIt->more() )
3899 const SMDS_MeshElement* e = elemIt->next();
3900 const int shapeID = e->getshapeId();
3902 fieldWriter.AddValue( (double) -1 );
3904 fieldWriter.AddValue( (double) shapeID );
3908 fieldWriter.Perform();
3909 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3910 if ( res && res->IsKO() )
3912 if ( res->myComment.empty() )
3913 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3915 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3918 } // loop on geomAssocFields
3923 //================================================================================
3925 * \brief Export a part of mesh to a DAT file
3927 //================================================================================
3929 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3931 throw (SALOME::SALOME_Exception)
3933 Unexpect aCatch(SALOME_SalomeException);
3935 _preMeshInfo->FullLoadFromFile();
3937 PrepareForWriting(file);
3939 SMESH_MeshPartDS partDS( meshPart );
3940 _impl->ExportDAT(file,&partDS);
3942 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3943 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3945 //================================================================================
3947 * \brief Export a part of mesh to an UNV file
3949 //================================================================================
3951 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3953 throw (SALOME::SALOME_Exception)
3955 Unexpect aCatch(SALOME_SalomeException);
3957 _preMeshInfo->FullLoadFromFile();
3959 PrepareForWriting(file);
3961 SMESH_MeshPartDS partDS( meshPart );
3962 _impl->ExportUNV(file, &partDS);
3964 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3965 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3967 //================================================================================
3969 * \brief Export a part of mesh to an STL file
3971 //================================================================================
3973 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3975 ::CORBA::Boolean isascii)
3976 throw (SALOME::SALOME_Exception)
3978 Unexpect aCatch(SALOME_SalomeException);
3980 _preMeshInfo->FullLoadFromFile();
3982 PrepareForWriting(file);
3984 CORBA::String_var name;
3985 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3986 if ( !so->_is_nil() )
3987 name = so->GetName();
3989 SMESH_MeshPartDS partDS( meshPart );
3990 _impl->ExportSTL( file, isascii, name.in(), &partDS );
3992 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3993 << meshPart<< ", r'" << file << "', " << isascii << ")";
3996 //================================================================================
3998 * \brief Export a part of mesh to an STL file
4000 //================================================================================
4002 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
4004 CORBA::Boolean overwrite,
4005 CORBA::Boolean groupElemsByType)
4006 throw (SALOME::SALOME_Exception)
4009 Unexpect aCatch(SALOME_SalomeException);
4011 _preMeshInfo->FullLoadFromFile();
4013 PrepareForWriting(file,overwrite);
4015 std::string meshName("");
4016 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4017 if ( !so->_is_nil() )
4019 CORBA::String_var name = so->GetName();
4020 meshName = name.in();
4024 SMESH_MeshPartDS partDS( meshPart );
4025 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
4027 SMESH_CATCH( SMESH::throwCorbaException );
4029 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
4030 << meshPart<< ", r'" << file << "', " << overwrite << ")";
4032 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
4036 //================================================================================
4038 * \brief Export a part of mesh to a GMF file
4040 //================================================================================
4042 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
4044 bool withRequiredGroups)
4045 throw (SALOME::SALOME_Exception)
4047 Unexpect aCatch(SALOME_SalomeException);
4049 _preMeshInfo->FullLoadFromFile();
4051 PrepareForWriting(file,/*overwrite=*/true);
4053 SMESH_MeshPartDS partDS( meshPart );
4054 _impl->ExportGMF(file, &partDS, withRequiredGroups);
4056 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
4057 << meshPart<< ", r'"
4059 << withRequiredGroups << ")";
4062 //=============================================================================
4064 * Return computation progress [0.,1]
4066 //=============================================================================
4068 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
4072 return _impl->GetComputeProgress();
4074 SMESH_CATCH( SMESH::doNothing );
4078 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
4080 Unexpect aCatch(SALOME_SalomeException);
4082 return _preMeshInfo->NbNodes();
4084 return _impl->NbNodes();
4087 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
4089 Unexpect aCatch(SALOME_SalomeException);
4091 return _preMeshInfo->NbElements();
4093 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
4096 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
4098 Unexpect aCatch(SALOME_SalomeException);
4100 return _preMeshInfo->Nb0DElements();
4102 return _impl->Nb0DElements();
4105 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
4107 Unexpect aCatch(SALOME_SalomeException);
4109 return _preMeshInfo->NbBalls();
4111 return _impl->NbBalls();
4114 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
4116 Unexpect aCatch(SALOME_SalomeException);
4118 return _preMeshInfo->NbEdges();
4120 return _impl->NbEdges();
4123 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
4124 throw(SALOME::SALOME_Exception)
4126 Unexpect aCatch(SALOME_SalomeException);
4128 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
4130 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
4133 //=============================================================================
4135 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
4137 Unexpect aCatch(SALOME_SalomeException);
4139 return _preMeshInfo->NbFaces();
4141 return _impl->NbFaces();
4144 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
4146 Unexpect aCatch(SALOME_SalomeException);
4148 return _preMeshInfo->NbTriangles();
4150 return _impl->NbTriangles();
4153 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
4155 Unexpect aCatch(SALOME_SalomeException);
4157 return _preMeshInfo->NbBiQuadTriangles();
4159 return _impl->NbBiQuadTriangles();
4162 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
4164 Unexpect aCatch(SALOME_SalomeException);
4166 return _preMeshInfo->NbQuadrangles();
4168 return _impl->NbQuadrangles();
4171 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
4173 Unexpect aCatch(SALOME_SalomeException);
4175 return _preMeshInfo->NbBiQuadQuadrangles();
4177 return _impl->NbBiQuadQuadrangles();
4180 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
4182 Unexpect aCatch(SALOME_SalomeException);
4184 return _preMeshInfo->NbPolygons();
4186 return _impl->NbPolygons();
4189 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
4191 Unexpect aCatch(SALOME_SalomeException);
4193 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
4195 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
4198 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
4199 throw(SALOME::SALOME_Exception)
4201 Unexpect aCatch(SALOME_SalomeException);
4203 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
4205 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
4208 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
4209 throw(SALOME::SALOME_Exception)
4211 Unexpect aCatch(SALOME_SalomeException);
4213 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
4215 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
4218 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
4219 throw(SALOME::SALOME_Exception)
4221 Unexpect aCatch(SALOME_SalomeException);
4223 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
4225 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
4228 //=============================================================================
4230 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
4232 Unexpect aCatch(SALOME_SalomeException);
4234 return _preMeshInfo->NbVolumes();
4236 return _impl->NbVolumes();
4239 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
4241 Unexpect aCatch(SALOME_SalomeException);
4243 return _preMeshInfo->NbTetras();
4245 return _impl->NbTetras();
4248 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
4250 Unexpect aCatch(SALOME_SalomeException);
4252 return _preMeshInfo->NbHexas();
4254 return _impl->NbHexas();
4257 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
4259 Unexpect aCatch(SALOME_SalomeException);
4261 return _preMeshInfo->NbTriQuadHexas();
4263 return _impl->NbTriQuadraticHexas();
4266 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
4268 Unexpect aCatch(SALOME_SalomeException);
4270 return _preMeshInfo->NbPyramids();
4272 return _impl->NbPyramids();
4275 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
4277 Unexpect aCatch(SALOME_SalomeException);
4279 return _preMeshInfo->NbPrisms();
4281 return _impl->NbPrisms();
4284 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
4286 Unexpect aCatch(SALOME_SalomeException);
4288 return _preMeshInfo->NbHexPrisms();
4290 return _impl->NbHexagonalPrisms();
4293 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
4295 Unexpect aCatch(SALOME_SalomeException);
4297 return _preMeshInfo->NbPolyhedrons();
4299 return _impl->NbPolyhedrons();
4302 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4303 throw(SALOME::SALOME_Exception)
4305 Unexpect aCatch(SALOME_SalomeException);
4307 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4309 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4312 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4313 throw(SALOME::SALOME_Exception)
4315 Unexpect aCatch(SALOME_SalomeException);
4317 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4319 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4322 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4323 throw(SALOME::SALOME_Exception)
4325 Unexpect aCatch(SALOME_SalomeException);
4327 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4329 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4332 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4333 throw(SALOME::SALOME_Exception)
4335 Unexpect aCatch(SALOME_SalomeException);
4337 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4339 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4342 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4343 throw(SALOME::SALOME_Exception)
4345 Unexpect aCatch(SALOME_SalomeException);
4347 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4349 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4352 //=============================================================================
4354 * Returns nb of published sub-meshes
4356 //=============================================================================
4358 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4360 Unexpect aCatch(SALOME_SalomeException);
4361 return _mapSubMesh_i.size();
4364 //=============================================================================
4366 * Dumps mesh into a string
4368 //=============================================================================
4370 char* SMESH_Mesh_i::Dump()
4374 return CORBA::string_dup( os.str().c_str() );
4377 //=============================================================================
4379 * Method of SMESH_IDSource interface
4381 //=============================================================================
4383 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4385 return GetElementsId();
4388 //=============================================================================
4390 * Returns ids of all elements
4392 //=============================================================================
4394 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4395 throw (SALOME::SALOME_Exception)
4397 Unexpect aCatch(SALOME_SalomeException);
4399 _preMeshInfo->FullLoadFromFile();
4401 SMESH::long_array_var aResult = new SMESH::long_array();
4402 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4404 if ( aSMESHDS_Mesh == NULL )
4405 return aResult._retn();
4407 long nbElements = NbElements();
4408 aResult->length( nbElements );
4409 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4410 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4411 aResult[i] = anIt->next()->GetID();
4413 return aResult._retn();
4417 //=============================================================================
4419 * Returns ids of all elements of given type
4421 //=============================================================================
4423 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4424 throw (SALOME::SALOME_Exception)
4426 Unexpect aCatch(SALOME_SalomeException);
4428 _preMeshInfo->FullLoadFromFile();
4430 SMESH::long_array_var aResult = new SMESH::long_array();
4431 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4433 if ( aSMESHDS_Mesh == NULL )
4434 return aResult._retn();
4436 long nbElements = NbElements();
4438 // No sense in returning ids of elements along with ids of nodes:
4439 // when theElemType == SMESH::ALL, return node ids only if
4440 // there are no elements
4441 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4442 return GetNodesId();
4444 aResult->length( nbElements );
4448 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4449 while ( i < nbElements && anIt->more() )
4450 aResult[i++] = anIt->next()->GetID();
4452 aResult->length( i );
4454 return aResult._retn();
4457 //=============================================================================
4459 * Returns ids of all nodes
4461 //=============================================================================
4463 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4464 throw (SALOME::SALOME_Exception)
4466 Unexpect aCatch(SALOME_SalomeException);
4468 _preMeshInfo->FullLoadFromFile();
4470 SMESH::long_array_var aResult = new SMESH::long_array();
4471 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4473 if ( aMeshDS == NULL )
4474 return aResult._retn();
4476 long nbNodes = NbNodes();
4477 aResult->length( nbNodes );
4478 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4479 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4480 aResult[i] = anIt->next()->GetID();
4482 return aResult._retn();
4485 //=============================================================================
4489 //=============================================================================
4491 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4492 throw (SALOME::SALOME_Exception)
4494 SMESH::ElementType type = SMESH::ALL;
4498 _preMeshInfo->FullLoadFromFile();
4500 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4502 SMESH_CATCH( SMESH::throwCorbaException );
4507 //=============================================================================
4511 //=============================================================================
4513 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4514 throw (SALOME::SALOME_Exception)
4517 _preMeshInfo->FullLoadFromFile();
4519 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4521 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4523 return ( SMESH::EntityType ) e->GetEntityType();
4526 //=============================================================================
4530 //=============================================================================
4532 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4533 throw (SALOME::SALOME_Exception)
4536 _preMeshInfo->FullLoadFromFile();
4538 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4540 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4542 return ( SMESH::GeometryType ) e->GetGeomType();
4545 //=============================================================================
4547 * Returns ID of elements for given submesh
4549 //=============================================================================
4550 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4551 throw (SALOME::SALOME_Exception)
4553 SMESH::long_array_var aResult = new SMESH::long_array();
4557 _preMeshInfo->FullLoadFromFile();
4559 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4560 if(!SM) return aResult._retn();
4562 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4563 if(!SDSM) return aResult._retn();
4565 aResult->length(SDSM->NbElements());
4567 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4569 while ( eIt->more() ) {
4570 aResult[i++] = eIt->next()->GetID();
4573 SMESH_CATCH( SMESH::throwCorbaException );
4575 return aResult._retn();
4578 //=============================================================================
4580 * Returns ID of nodes for given submesh
4581 * If param all==true - returns all nodes, else -
4582 * returns only nodes on shapes.
4584 //=============================================================================
4586 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4588 throw (SALOME::SALOME_Exception)
4590 SMESH::long_array_var aResult = new SMESH::long_array();
4594 _preMeshInfo->FullLoadFromFile();
4596 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4597 if(!SM) return aResult._retn();
4599 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4600 if(!SDSM) return aResult._retn();
4603 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4604 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4605 while ( nIt->more() ) {
4606 const SMDS_MeshNode* elem = nIt->next();
4607 theElems.insert( elem->GetID() );
4610 else { // all nodes of submesh elements
4611 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4612 while ( eIt->more() ) {
4613 const SMDS_MeshElement* anElem = eIt->next();
4614 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4615 while ( nIt->more() ) {
4616 const SMDS_MeshElement* elem = nIt->next();
4617 theElems.insert( elem->GetID() );
4622 aResult->length(theElems.size());
4623 set<int>::iterator itElem;
4625 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4626 aResult[i++] = *itElem;
4628 SMESH_CATCH( SMESH::throwCorbaException );
4630 return aResult._retn();
4633 //=============================================================================
4635 * Returns type of elements for given submesh
4637 //=============================================================================
4639 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4640 throw (SALOME::SALOME_Exception)
4642 SMESH::ElementType type = SMESH::ALL;
4646 _preMeshInfo->FullLoadFromFile();
4648 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4649 if(!SM) return SMESH::ALL;
4651 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4652 if(!SDSM) return SMESH::ALL;
4654 if(SDSM->NbElements()==0)
4655 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4657 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4658 const SMDS_MeshElement* anElem = eIt->next();
4660 type = ( SMESH::ElementType ) anElem->GetType();
4662 SMESH_CATCH( SMESH::throwCorbaException );
4668 //=============================================================================
4670 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4672 //=============================================================================
4674 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4677 _preMeshInfo->FullLoadFromFile();
4679 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4680 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4685 //=============================================================================
4687 * Get XYZ coordinates of node as list of double
4688 * If there is not node for given ID - returns empty list
4690 //=============================================================================
4692 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4695 _preMeshInfo->FullLoadFromFile();
4697 SMESH::double_array_var aResult = new SMESH::double_array();
4698 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4699 if ( aMeshDS == NULL )
4700 return aResult._retn();
4703 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4705 return aResult._retn();
4709 aResult[0] = aNode->X();
4710 aResult[1] = aNode->Y();
4711 aResult[2] = aNode->Z();
4712 return aResult._retn();
4716 //=============================================================================
4718 * For given node returns list of IDs of inverse elements
4719 * If there is not node for given ID - returns empty list
4721 //=============================================================================
4723 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id,
4724 SMESH::ElementType elemType)
4727 _preMeshInfo->FullLoadFromFile();
4729 SMESH::long_array_var aResult = new SMESH::long_array();
4730 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4731 if ( aMeshDS == NULL )
4732 return aResult._retn();
4735 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
4737 return aResult._retn();
4739 // find inverse elements
4740 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
4741 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
4742 aResult->length( aNode->NbInverseElements( type ));
4743 for( int i = 0; eIt->more(); ++i )
4745 const SMDS_MeshElement* elem = eIt->next();
4746 aResult[ i ] = elem->GetID();
4748 return aResult._retn();
4751 //=============================================================================
4753 * \brief Return position of a node on shape
4755 //=============================================================================
4757 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4760 _preMeshInfo->FullLoadFromFile();
4762 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4763 aNodePosition->shapeID = 0;
4764 aNodePosition->shapeType = GEOM::SHAPE;
4766 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4767 if ( !mesh ) return aNodePosition;
4769 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4771 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4773 aNodePosition->shapeID = aNode->getshapeId();
4774 switch ( pos->GetTypeOfPosition() ) {
4776 aNodePosition->shapeType = GEOM::EDGE;
4777 aNodePosition->params.length(1);
4778 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4780 case SMDS_TOP_FACE: {
4781 SMDS_FacePositionPtr fPos = pos;
4782 aNodePosition->shapeType = GEOM::FACE;
4783 aNodePosition->params.length(2);
4784 aNodePosition->params[0] = fPos->GetUParameter();
4785 aNodePosition->params[1] = fPos->GetVParameter();
4788 case SMDS_TOP_VERTEX:
4789 aNodePosition->shapeType = GEOM::VERTEX;
4791 case SMDS_TOP_3DSPACE:
4792 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4793 aNodePosition->shapeType = GEOM::SOLID;
4794 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4795 aNodePosition->shapeType = GEOM::SHELL;
4801 return aNodePosition;
4804 //=============================================================================
4806 * \brief Return position of an element on shape
4808 //=============================================================================
4810 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4813 _preMeshInfo->FullLoadFromFile();
4815 SMESH::ElementPosition anElementPosition;
4816 anElementPosition.shapeID = 0;
4817 anElementPosition.shapeType = GEOM::SHAPE;
4819 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4820 if ( !mesh ) return anElementPosition;
4822 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4824 anElementPosition.shapeID = anElem->getshapeId();
4825 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4826 if ( !aSp.IsNull() ) {
4827 switch ( aSp.ShapeType() ) {
4829 anElementPosition.shapeType = GEOM::EDGE;
4832 anElementPosition.shapeType = GEOM::FACE;
4835 anElementPosition.shapeType = GEOM::VERTEX;
4838 anElementPosition.shapeType = GEOM::SOLID;
4841 anElementPosition.shapeType = GEOM::SHELL;
4847 return anElementPosition;
4850 //=============================================================================
4852 * If given element is node returns IDs of shape from position
4853 * If there is not node for given ID - returns -1
4855 //=============================================================================
4857 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4860 _preMeshInfo->FullLoadFromFile();
4862 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4863 if ( aMeshDS == NULL )
4867 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4869 return aNode->getshapeId();
4876 //=============================================================================
4878 * For given element returns ID of result shape after
4879 * ::FindShape() from SMESH_MeshEditor
4880 * If there is not element for given ID - returns -1
4882 //=============================================================================
4884 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4887 _preMeshInfo->FullLoadFromFile();
4889 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4890 if ( aMeshDS == NULL )
4893 // try to find element
4894 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4898 ::SMESH_MeshEditor aMeshEditor(_impl);
4899 int index = aMeshEditor.FindShape( elem );
4907 //=============================================================================
4909 * Returns number of nodes for given element
4910 * If there is not element for given ID - returns -1
4912 //=============================================================================
4914 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4917 _preMeshInfo->FullLoadFromFile();
4919 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4920 if ( aMeshDS == NULL ) return -1;
4921 // try to find element
4922 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4923 if(!elem) return -1;
4924 return elem->NbNodes();
4928 //=============================================================================
4930 * Returns ID of node by given index for given element
4931 * If there is not element for given ID - returns -1
4932 * If there is not node for given index - returns -2
4934 //=============================================================================
4936 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4939 _preMeshInfo->FullLoadFromFile();
4941 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4942 if ( aMeshDS == NULL ) return -1;
4943 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4944 if(!elem) return -1;
4945 if( index>=elem->NbNodes() || index<0 ) return -1;
4946 return elem->GetNode(index)->GetID();
4949 //=============================================================================
4951 * Returns IDs of nodes of given element
4953 //=============================================================================
4955 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4958 _preMeshInfo->FullLoadFromFile();
4960 SMESH::long_array_var aResult = new SMESH::long_array();
4961 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4963 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
4965 aResult->length( elem->NbNodes() );
4966 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4967 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
4968 aResult[ i ] = n->GetID();
4971 return aResult._retn();
4974 //=============================================================================
4976 * Returns true if given node is medium node
4977 * in given quadratic element
4979 //=============================================================================
4981 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4984 _preMeshInfo->FullLoadFromFile();
4986 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4987 if ( aMeshDS == NULL ) return false;
4989 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4990 if(!aNode) return false;
4991 // try to find element
4992 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
4993 if(!elem) return false;
4995 return elem->IsMediumNode(aNode);
4999 //=============================================================================
5001 * Returns true if given node is medium node
5002 * in one of quadratic elements
5004 //=============================================================================
5006 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
5007 SMESH::ElementType theElemType)
5010 _preMeshInfo->FullLoadFromFile();
5012 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5013 if ( aMeshDS == NULL ) return false;
5016 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5017 if(!aNode) return false;
5019 SMESH_MesherHelper aHelper( *(_impl) );
5021 SMDSAbs_ElementType aType;
5022 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
5023 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
5024 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
5025 else aType = SMDSAbs_All;
5027 return aHelper.IsMedium(aNode,aType);
5031 //=============================================================================
5033 * Returns number of edges for given element
5035 //=============================================================================
5037 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
5040 _preMeshInfo->FullLoadFromFile();
5042 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5043 if ( aMeshDS == NULL ) return -1;
5044 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5045 if(!elem) return -1;
5046 return elem->NbEdges();
5050 //=============================================================================
5052 * Returns number of faces for given element
5054 //=============================================================================
5056 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
5059 _preMeshInfo->FullLoadFromFile();
5061 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5062 if ( aMeshDS == NULL ) return -1;
5063 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5064 if(!elem) return -1;
5065 return elem->NbFaces();
5068 //=======================================================================
5069 //function : GetElemFaceNodes
5070 //purpose : Returns nodes of given face (counted from zero) for given element.
5071 //=======================================================================
5073 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
5074 CORBA::Short faceIndex)
5077 _preMeshInfo->FullLoadFromFile();
5079 SMESH::long_array_var aResult = new SMESH::long_array();
5080 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5082 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
5084 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
5085 if ( faceIndex < vtool.NbFaces() )
5087 aResult->length( vtool.NbFaceNodes( faceIndex ));
5088 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
5089 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5090 aResult[ i ] = nn[ i ]->GetID();
5094 return aResult._retn();
5097 //=======================================================================
5098 //function : GetFaceNormal
5099 //purpose : Returns three components of normal of given mesh face.
5100 //=======================================================================
5102 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
5103 CORBA::Boolean normalized)
5106 _preMeshInfo->FullLoadFromFile();
5108 SMESH::double_array_var aResult = new SMESH::double_array();
5110 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5113 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
5115 aResult->length( 3 );
5116 aResult[ 0 ] = normal.X();
5117 aResult[ 1 ] = normal.Y();
5118 aResult[ 2 ] = normal.Z();
5121 return aResult._retn();
5124 //=======================================================================
5125 //function : FindElementByNodes
5126 //purpose : Returns an element based on all given nodes.
5127 //=======================================================================
5129 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
5132 _preMeshInfo->FullLoadFromFile();
5134 CORBA::Long elemID(0);
5135 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5137 vector< const SMDS_MeshNode * > nn( nodes.length() );
5138 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5139 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
5142 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
5143 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
5144 _impl->NbFaces ( ORDER_QUADRATIC ) ||
5145 _impl->NbVolumes( ORDER_QUADRATIC )))
5146 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
5148 if ( elem ) elemID = CORBA::Long( elem->GetID() );
5153 //================================================================================
5155 * \brief Return elements including all given nodes.
5157 //================================================================================
5159 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
5160 SMESH::ElementType elemType)
5163 _preMeshInfo->FullLoadFromFile();
5165 SMESH::long_array_var result = new SMESH::long_array();
5167 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5169 vector< const SMDS_MeshNode * > nn( nodes.length() );
5170 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5171 nn[i] = mesh->FindNode( nodes[i] );
5173 std::vector<const SMDS_MeshElement *> elems;
5174 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
5175 result->length( elems.size() );
5176 for ( size_t i = 0; i < elems.size(); ++i )
5177 result[i] = elems[i]->GetID();
5179 return result._retn();
5182 //=============================================================================
5184 * Returns true if given element is polygon
5186 //=============================================================================
5188 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
5191 _preMeshInfo->FullLoadFromFile();
5193 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5194 if ( aMeshDS == NULL ) return false;
5195 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5196 if(!elem) return false;
5197 return elem->IsPoly();
5201 //=============================================================================
5203 * Returns true if given element is quadratic
5205 //=============================================================================
5207 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
5210 _preMeshInfo->FullLoadFromFile();
5212 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5213 if ( aMeshDS == NULL ) return false;
5214 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5215 if(!elem) return false;
5216 return elem->IsQuadratic();
5219 //=============================================================================
5221 * Returns diameter of ball discrete element or zero in case of an invalid \a id
5223 //=============================================================================
5225 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
5228 _preMeshInfo->FullLoadFromFile();
5230 if ( const SMDS_BallElement* ball =
5231 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
5232 return ball->GetDiameter();
5237 //=============================================================================
5239 * Returns bary center for given element
5241 //=============================================================================
5243 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5246 _preMeshInfo->FullLoadFromFile();
5248 SMESH::double_array_var aResult = new SMESH::double_array();
5249 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5250 if ( aMeshDS == NULL )
5251 return aResult._retn();
5253 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5255 return aResult._retn();
5257 if(elem->GetType()==SMDSAbs_Volume) {
5258 SMDS_VolumeTool aTool;
5259 if(aTool.Set(elem)) {
5261 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5266 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5268 double x=0., y=0., z=0.;
5269 for(; anIt->more(); ) {
5271 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5285 return aResult._retn();
5288 //================================================================================
5290 * \brief Create a group of elements preventing computation of a sub-shape
5292 //================================================================================
5294 SMESH::ListOfGroups*
5295 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5296 const char* theGroupName )
5297 throw ( SALOME::SALOME_Exception )
5299 Unexpect aCatch(SALOME_SalomeException);
5301 if ( !theGroupName || strlen( theGroupName) == 0 )
5302 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5304 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5305 ::SMESH_MeshEditor::ElemFeatures elemType;
5307 // submesh by subshape id
5308 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5309 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5312 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5313 if ( error && error->HasBadElems() )
5315 // sort bad elements by type
5316 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5317 const list<const SMDS_MeshElement*>& badElems =
5318 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5319 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5320 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5321 for ( ; elemIt != elemEnd; ++elemIt )
5323 const SMDS_MeshElement* elem = *elemIt;
5324 if ( !elem ) continue;
5326 if ( elem->GetID() < 1 )
5328 // elem is a temporary element, make a real element
5329 vector< const SMDS_MeshNode* > nodes;
5330 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5331 while ( nIt->more() && elem )
5333 nodes.push_back( nIt->next() );
5334 if ( nodes.back()->GetID() < 1 )
5335 elem = 0; // a temporary element on temporary nodes
5339 ::SMESH_MeshEditor editor( _impl );
5340 elem = editor.AddElement( nodes, elemType.Init( elem ));
5344 elemsByType[ elem->GetType() ].push_back( elem );
5347 // how many groups to create?
5349 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5350 nbTypes += int( !elemsByType[ i ].empty() );
5351 groups->length( nbTypes );
5354 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5356 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5357 if ( elems.empty() ) continue;
5359 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5360 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5362 SMESH::SMESH_Mesh_var mesh = _this();
5363 SALOMEDS::SObject_wrap aSO =
5364 _gen_i->PublishGroup( mesh, groups[ iG ],
5365 GEOM::GEOM_Object::_nil(), theGroupName);
5367 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5368 if ( !grp_i ) continue;
5370 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5371 for ( size_t iE = 0; iE < elems.size(); ++iE )
5372 grpDS->SMDSGroup().Add( elems[ iE ]);
5377 return groups._retn();
5380 //=============================================================================
5382 * Create and publish group servants if any groups were imported or created anyhow
5384 //=============================================================================
5386 void SMESH_Mesh_i::CreateGroupServants()
5388 SMESH::SMESH_Mesh_var aMesh = _this();
5391 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5392 while ( groupIt->more() )
5394 ::SMESH_Group* group = groupIt->next();
5395 int anId = group->GetID();
5397 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5398 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5400 addedIDs.insert( anId );
5402 SMESH_GroupBase_i* aGroupImpl;
5404 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5405 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5407 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5408 shape = groupOnGeom->GetShape();
5411 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5414 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5415 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5416 aGroupImpl->Register();
5418 // register CORBA object for persistence
5419 int nextId = _gen_i->RegisterObject( groupVar );
5420 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5421 else { nextId = 0; } // avoid "unused variable" warning in release mode
5423 // publishing the groups in the study
5424 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5425 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5427 if ( !addedIDs.empty() )
5430 set<int>::iterator id = addedIDs.begin();
5431 for ( ; id != addedIDs.end(); ++id )
5433 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5434 int i = std::distance( _mapGroups.begin(), it );
5435 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5440 //=============================================================================
5442 * \brief Return true if all sub-meshes are computed OK - to update an icon
5444 //=============================================================================
5446 bool SMESH_Mesh_i::IsComputedOK()
5448 return _impl->IsComputedOK();
5451 //=============================================================================
5453 * \brief Return groups cantained in _mapGroups by their IDs
5455 //=============================================================================
5457 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5459 int nbGroups = groupIDs.size();
5460 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5461 aList->length( nbGroups );
5463 list<int>::const_iterator ids = groupIDs.begin();
5464 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5466 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5467 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5468 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5470 aList->length( nbGroups );
5471 return aList._retn();
5474 //=============================================================================
5476 * \brief Return information about imported file
5478 //=============================================================================
5480 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5482 SMESH::MedFileInfo_var res( _medFileInfo );
5483 if ( !res.operator->() ) {
5484 res = new SMESH::MedFileInfo;
5486 res->fileSize = res->major = res->minor = res->release = -1;
5491 //=======================================================================
5492 //function : FileInfoToString
5493 //purpose : Persistence of file info
5494 //=======================================================================
5496 std::string SMESH_Mesh_i::FileInfoToString()
5499 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5501 s = SMESH_Comment( _medFileInfo->fileSize )
5502 << " " << _medFileInfo->major
5503 << " " << _medFileInfo->minor
5504 << " " << _medFileInfo->release
5505 << " " << _medFileInfo->fileName;
5510 //=======================================================================
5511 //function : FileInfoFromString
5512 //purpose : Persistence of file info
5513 //=======================================================================
5515 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5517 std::string size, major, minor, release, fileName;
5518 std::istringstream is(info);
5519 is >> size >> major >> minor >> release;
5520 fileName = info.data() + ( size.size() + 1 +
5523 release.size()+ 1 );
5525 _medFileInfo = new SMESH::MedFileInfo();
5526 _medFileInfo->fileName = fileName.c_str();
5527 _medFileInfo->fileSize = atoi( size.c_str() );
5528 _medFileInfo->major = atoi( major.c_str() );
5529 _medFileInfo->minor = atoi( minor.c_str() );
5530 _medFileInfo->release = atoi( release.c_str() );
5533 //=============================================================================
5535 * \brief Pass names of mesh groups from study to mesh DS
5537 //=============================================================================
5539 void SMESH_Mesh_i::checkGroupNames()
5541 int nbGrp = NbGroups();
5545 SMESH::ListOfGroups* grpList = 0;
5546 // avoid dump of "GetGroups"
5548 // store python dump into a local variable inside local scope
5549 SMESH::TPythonDump pDump; // do not delete this line of code
5550 grpList = GetGroups();
5553 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5554 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5557 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5558 if ( aGrpSO->_is_nil() )
5560 // correct name of the mesh group if necessary
5561 const char* guiName = aGrpSO->GetName();
5562 if ( strcmp(guiName, aGrp->GetName()) )
5563 aGrp->SetName( guiName );
5567 //=============================================================================
5569 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5571 //=============================================================================
5572 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5574 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5578 //=============================================================================
5580 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5582 //=============================================================================
5584 char* SMESH_Mesh_i::GetParameters()
5586 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5589 //=============================================================================
5591 * \brief Returns list of notebook variables used for last Mesh operation
5593 //=============================================================================
5594 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5596 SMESH::string_array_var aResult = new SMESH::string_array();
5597 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5599 CORBA::String_var aParameters = GetParameters();
5600 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5601 if ( aSections->length() > 0 ) {
5602 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5603 aResult->length( aVars.length() );
5604 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5605 aResult[i] = CORBA::string_dup( aVars[i] );
5608 return aResult._retn();
5611 //=======================================================================
5612 //function : GetTypes
5613 //purpose : Returns types of elements it contains
5614 //=======================================================================
5616 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5619 return _preMeshInfo->GetTypes();
5621 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5625 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5626 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5627 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5628 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5629 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5630 if (_impl->NbNodes() &&
5631 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5632 types->length( nbTypes );
5634 return types._retn();
5637 //=======================================================================
5638 //function : GetMesh
5639 //purpose : Returns self
5640 //=======================================================================
5642 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5644 return SMESH::SMESH_Mesh::_duplicate( _this() );
5647 //=======================================================================
5648 //function : IsMeshInfoCorrect
5649 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5650 // * happen if mesh data is not yet fully loaded from the file of study.
5651 //=======================================================================
5653 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5655 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5658 //=============================================================================
5660 * \brief Returns number of mesh elements per each \a EntityType
5662 //=============================================================================
5664 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5667 return _preMeshInfo->GetMeshInfo();
5669 SMESH::long_array_var aRes = new SMESH::long_array();
5670 aRes->length(SMESH::Entity_Last);
5671 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5673 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5675 return aRes._retn();
5676 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5677 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5678 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5679 return aRes._retn();
5682 //=============================================================================
5684 * \brief Returns number of mesh elements per each \a ElementType
5686 //=============================================================================
5688 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5690 SMESH::long_array_var aRes = new SMESH::long_array();
5691 aRes->length(SMESH::NB_ELEMENT_TYPES);
5692 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5695 const SMDS_MeshInfo* meshInfo = 0;
5697 meshInfo = _preMeshInfo;
5698 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5699 meshInfo = & meshDS->GetMeshInfo();
5702 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5703 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5705 return aRes._retn();
5708 //=============================================================================
5710 * Collect statistic of mesh elements given by iterator
5712 //=============================================================================
5714 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5715 SMESH::long_array& theInfo)
5717 if (!theItr) return;
5718 while (theItr->more())
5719 theInfo[ theItr->next()->GetEntityType() ]++;
5721 //=============================================================================
5723 * Returns mesh unstructed grid information.
5725 //=============================================================================
5727 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5729 SALOMEDS::TMPFile_var SeqFile;
5730 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5731 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5733 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5734 aWriter->WriteToOutputStringOn();
5735 aWriter->SetInputData(aGrid);
5736 aWriter->SetFileTypeToBinary();
5738 char* str = aWriter->GetOutputString();
5739 int size = aWriter->GetOutputStringLength();
5741 //Allocate octet buffer of required size
5742 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5743 //Copy ostrstream content to the octet buffer
5744 memcpy(OctetBuf, str, size);
5745 //Create and return TMPFile
5746 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5750 return SeqFile._retn();
5753 //=============================================================================
5754 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5755 * SMESH::ElementType type) */
5757 using namespace SMESH::Controls;
5758 //-----------------------------------------------------------------------------
5759 struct PredicateIterator : public SMDS_ElemIterator
5761 SMDS_ElemIteratorPtr _elemIter;
5762 PredicatePtr _predicate;
5763 const SMDS_MeshElement* _elem;
5764 SMDSAbs_ElementType _type;
5766 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5767 PredicatePtr predicate,
5768 SMDSAbs_ElementType type):
5769 _elemIter(iterator), _predicate(predicate), _type(type)
5777 virtual const SMDS_MeshElement* next()
5779 const SMDS_MeshElement* res = _elem;
5781 while ( _elemIter->more() && !_elem )
5783 if ((_elem = _elemIter->next()) &&
5784 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
5785 ( !_predicate->IsSatisfy( _elem->GetID() ))))
5792 //-----------------------------------------------------------------------------
5793 struct IDSourceIterator : public SMDS_ElemIterator
5795 const CORBA::Long* _idPtr;
5796 const CORBA::Long* _idEndPtr;
5797 SMESH::long_array_var _idArray;
5798 const SMDS_Mesh* _mesh;
5799 const SMDSAbs_ElementType _type;
5800 const SMDS_MeshElement* _elem;
5802 IDSourceIterator( const SMDS_Mesh* mesh,
5803 const CORBA::Long* ids,
5805 SMDSAbs_ElementType type):
5806 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5808 if ( _idPtr && nbIds && _mesh )
5811 IDSourceIterator( const SMDS_Mesh* mesh,
5812 SMESH::long_array* idArray,
5813 SMDSAbs_ElementType type):
5814 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5816 if ( idArray && _mesh )
5818 _idPtr = &_idArray[0];
5819 _idEndPtr = _idPtr + _idArray->length();
5827 virtual const SMDS_MeshElement* next()
5829 const SMDS_MeshElement* res = _elem;
5831 while ( _idPtr < _idEndPtr && !_elem )
5833 if ( _type == SMDSAbs_Node )
5835 _elem = _mesh->FindNode( *_idPtr++ );
5837 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5838 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5846 //-----------------------------------------------------------------------------
5848 struct NodeOfElemIterator : public SMDS_ElemIterator
5850 TColStd_MapOfInteger _checkedNodeIDs;
5851 SMDS_ElemIteratorPtr _elemIter;
5852 SMDS_ElemIteratorPtr _nodeIter;
5853 const SMDS_MeshElement* _node;
5855 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5857 if ( _elemIter && _elemIter->more() )
5859 _nodeIter = _elemIter->next()->nodesIterator();
5867 virtual const SMDS_MeshElement* next()
5869 const SMDS_MeshElement* res = _node;
5871 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
5873 if ( _nodeIter->more() )
5875 _node = _nodeIter->next();
5876 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5881 _nodeIter = _elemIter->next()->nodesIterator();
5889 //=============================================================================
5891 * Return iterator on elements of given type in given object
5893 //=============================================================================
5895 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5896 SMESH::ElementType theType)
5898 SMDS_ElemIteratorPtr elemIt;
5899 bool typeOK = ( theType == SMESH::ALL );
5900 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5902 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5903 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5904 if ( !mesh_i ) return elemIt;
5905 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5907 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5909 elemIt = meshDS->elementsIterator( elemType );
5912 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5914 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5917 elemIt = sm->GetElements();
5918 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5920 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5921 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5925 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5927 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5928 if ( groupDS && ( elemType == groupDS->GetType() ||
5929 elemType == SMDSAbs_Node ||
5930 elemType == SMDSAbs_All ))
5932 elemIt = groupDS->GetElements();
5933 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5936 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5938 if ( filter_i->GetElementType() == theType ||
5939 filter_i->GetElementType() == SMESH::ALL ||
5940 elemType == SMDSAbs_Node ||
5941 elemType == SMDSAbs_All)
5943 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5944 if ( pred_i && pred_i->GetPredicate() )
5946 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5947 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5948 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
5949 elemIt = SMDS_ElemIteratorPtr
5950 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
5951 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
5957 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5958 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5959 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5961 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
5962 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5965 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5966 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
5970 SMESH::long_array_var ids = theObject->GetIDs();
5971 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
5973 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5976 if ( elemIt && elemIt->more() && !typeOK )
5978 if ( elemType == SMDSAbs_Node )
5980 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5984 elemIt = SMDS_ElemIteratorPtr();
5990 //=============================================================================
5991 namespace // Finding concurrent hypotheses
5992 //=============================================================================
5996 * \brief mapping of mesh dimension into shape type
5998 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
6000 TopAbs_ShapeEnum aType = TopAbs_SOLID;
6002 case 0: aType = TopAbs_VERTEX; break;
6003 case 1: aType = TopAbs_EDGE; break;
6004 case 2: aType = TopAbs_FACE; break;
6006 default:aType = TopAbs_SOLID; break;
6011 //-----------------------------------------------------------------------------
6013 * \brief Internal structure used to find concurrent submeshes
6015 * It represents a pair < submesh, concurrent dimension >, where
6016 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
6017 * with another submesh. In other words, it is dimension of a hypothesis assigned
6024 int _dim; //!< a dimension the algo can build (concurrent dimension)
6025 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
6026 TopTools_MapOfShape _shapeMap;
6027 SMESH_subMesh* _subMesh;
6028 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
6030 //-----------------------------------------------------------------------------
6031 // Return the algorithm
6032 const SMESH_Algo* GetAlgo() const
6033 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
6035 //-----------------------------------------------------------------------------
6037 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
6039 const TopoDS_Shape& theShape)
6041 _subMesh = (SMESH_subMesh*)theSubMesh;
6042 SetShape( theDim, theShape );
6045 //-----------------------------------------------------------------------------
6047 void SetShape(const int theDim,
6048 const TopoDS_Shape& theShape)
6051 _ownDim = SMESH_Gen::GetShapeDim(theShape);
6052 if (_dim >= _ownDim)
6053 _shapeMap.Add( theShape );
6055 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
6056 for( ; anExp.More(); anExp.Next() )
6057 _shapeMap.Add( anExp.Current() );
6061 //-----------------------------------------------------------------------------
6062 //! Check sharing of sub-shapes
6063 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
6064 const TopTools_MapOfShape& theToFind,
6065 const TopAbs_ShapeEnum theType)
6067 bool isShared = false;
6068 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
6069 for (; !isShared && anItr.More(); anItr.Next() )
6071 const TopoDS_Shape aSubSh = anItr.Key();
6072 // check for case when concurrent dimensions are same
6073 isShared = theToFind.Contains( aSubSh );
6074 // check for sub-shape with concurrent dimension
6075 TopExp_Explorer anExp( aSubSh, theType );
6076 for ( ; !isShared && anExp.More(); anExp.Next() )
6077 isShared = theToFind.Contains( anExp.Current() );
6082 //-----------------------------------------------------------------------------
6083 //! check algorithms
6084 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
6085 const SMESHDS_Hypothesis* theA2)
6087 if ( !theA1 || !theA2 ||
6088 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
6089 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
6090 return false; // one of the hypothesis is not algorithm
6091 // check algorithm names (should be equal)
6092 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
6096 //-----------------------------------------------------------------------------
6097 //! Check if sub-shape hypotheses are concurrent
6098 bool IsConcurrent(const SMESH_DimHyp* theOther) const
6100 if ( _subMesh == theOther->_subMesh )
6101 return false; // same sub-shape - should not be
6103 // if ( <own dim of either of submeshes> == <concurrent dim> &&
6104 // any of the two submeshes is not on COMPOUND shape )
6105 // -> no concurrency
6106 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
6107 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
6108 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
6109 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
6110 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
6113 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
6114 if ( !checkSubShape )
6117 // check algorithms to be same
6118 const SMESH_Algo* a1 = this->GetAlgo();
6119 const SMESH_Algo* a2 = theOther->GetAlgo();
6120 bool isSame = checkAlgo( a1, a2 );
6124 return false; // pb?
6125 return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency !
6128 // check hypothesises for concurrence (skip first as algorithm)
6130 // pointers should be same, because it is referened from mesh hypothesis partition
6131 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
6132 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
6133 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
6134 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
6136 // the submeshes are concurrent if their algorithms has different parameters
6137 return nbSame != theOther->_hypotheses.size() - 1;
6140 // Return true if algorithm of this SMESH_DimHyp is used if no
6141 // sub-mesh order is imposed by the user
6142 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
6144 // NeedDiscreteBoundary() algo has a higher priority
6145 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
6146 theOther->GetAlgo()->NeedDiscreteBoundary() )
6147 return !this->GetAlgo()->NeedDiscreteBoundary();
6149 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
6152 }; // end of SMESH_DimHyp
6153 //-----------------------------------------------------------------------------
6155 typedef list<const SMESH_DimHyp*> TDimHypList;
6157 //-----------------------------------------------------------------------------
6159 void addDimHypInstance(const int theDim,
6160 const TopoDS_Shape& theShape,
6161 const SMESH_Algo* theAlgo,
6162 const SMESH_subMesh* theSubMesh,
6163 const list <const SMESHDS_Hypothesis*>& theHypList,
6164 TDimHypList* theDimHypListArr )
6166 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
6167 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
6168 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
6169 dimHyp->_hypotheses.push_front(theAlgo);
6170 listOfdimHyp.push_back( dimHyp );
6173 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
6174 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
6175 theHypList.begin(), theHypList.end() );
6178 //-----------------------------------------------------------------------------
6179 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
6180 TDimHypList& theListOfConcurr)
6182 if ( theListOfConcurr.empty() )
6184 theListOfConcurr.push_back( theDimHyp );
6188 TDimHypList::iterator hypIt = theListOfConcurr.begin();
6189 while ( hypIt != theListOfConcurr.end() &&
6190 !theDimHyp->IsHigherPriorityThan( *hypIt ))
6192 theListOfConcurr.insert( hypIt, theDimHyp );
6196 //-----------------------------------------------------------------------------
6197 void findConcurrents(const SMESH_DimHyp* theDimHyp,
6198 const TDimHypList& theListOfDimHyp,
6199 TDimHypList& theListOfConcurrHyp,
6200 set<int>& theSetOfConcurrId )
6202 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
6203 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
6205 const SMESH_DimHyp* curDimHyp = *rIt;
6206 if ( curDimHyp == theDimHyp )
6207 break; // meet own dimHyp pointer in same dimension
6209 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
6210 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
6212 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
6217 //-----------------------------------------------------------------------------
6218 void unionLists(TListOfInt& theListOfId,
6219 TListOfListOfInt& theListOfListOfId,
6222 TListOfListOfInt::iterator it = theListOfListOfId.begin();
6223 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
6225 continue; //skip already treated lists
6226 // check if other list has any same submesh object
6227 TListOfInt& otherListOfId = *it;
6228 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
6229 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
6232 // union two lists (from source into target)
6233 TListOfInt::iterator it2 = otherListOfId.begin();
6234 for ( ; it2 != otherListOfId.end(); it2++ ) {
6235 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
6236 theListOfId.push_back(*it2);
6238 // clear source list
6239 otherListOfId.clear();
6242 //-----------------------------------------------------------------------------
6244 //! free memory allocated for dimension-hypothesis objects
6245 void removeDimHyps( TDimHypList* theArrOfList )
6247 for (int i = 0; i < 4; i++ ) {
6248 TDimHypList& listOfdimHyp = theArrOfList[i];
6249 TDimHypList::const_iterator it = listOfdimHyp.begin();
6250 for ( ; it != listOfdimHyp.end(); it++ )
6255 //-----------------------------------------------------------------------------
6257 * \brief find common submeshes with given submesh
6258 * \param theSubMeshList list of already collected submesh to check
6259 * \param theSubMesh given submesh to intersect with other
6260 * \param theCommonSubMeshes collected common submeshes
6262 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6263 const SMESH_subMesh* theSubMesh,
6264 set<const SMESH_subMesh*>& theCommon )
6268 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6269 for ( ; it != theSubMeshList.end(); it++ )
6270 theSubMesh->FindIntersection( *it, theCommon );
6271 theSubMeshList.push_back( theSubMesh );
6272 //theCommon.insert( theSubMesh );
6275 //-----------------------------------------------------------------------------
6276 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6278 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6279 for ( ; listsIt != smLists.end(); ++listsIt )
6281 const TListOfInt& smIDs = *listsIt;
6282 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6290 //=============================================================================
6292 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6294 //=============================================================================
6296 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6298 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6299 if ( isSubMeshInList( submeshID, anOrder ))
6302 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6303 return isSubMeshInList( submeshID, allConurrent );
6306 //=============================================================================
6308 * \brief Return submesh objects list in meshing order
6310 //=============================================================================
6312 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6314 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6316 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6318 return aResult._retn();
6320 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6321 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6322 anOrder.splice( anOrder.end(), allConurrent );
6325 TListOfListOfInt::iterator listIt = anOrder.begin();
6326 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6327 unionLists( *listIt, anOrder, listIndx + 1 );
6329 // convert submesh ids into interface instances
6330 // and dump command into python
6331 convertMeshOrder( anOrder, aResult, false );
6333 return aResult._retn();
6336 //=============================================================================
6338 * \brief Finds concurrent sub-meshes
6340 //=============================================================================
6342 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6344 TListOfListOfInt anOrder;
6345 ::SMESH_Mesh& mesh = GetImpl();
6347 // collect submeshes and detect concurrent algorithms and hypothesises
6348 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6350 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6351 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
6352 ::SMESH_subMesh* sm = (*i_sm).second;
6354 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6356 // list of assigned hypothesises
6357 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6358 // Find out dimensions where the submesh can be concurrent.
6359 // We define the dimensions by algo of each of hypotheses in hypList
6360 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6361 for( ; hypIt != hypList.end(); hypIt++ ) {
6362 SMESH_Algo* anAlgo = 0;
6363 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6364 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6365 // hyp it-self is algo
6366 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6368 // try to find algorithm with help of sub-shapes
6369 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6370 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6371 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6374 continue; // no algorithm assigned to a current submesh
6376 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6377 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
6379 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6380 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6381 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6383 } // end iterations on submesh
6385 // iterate on created dimension-hypotheses and check for concurrents
6386 for ( int i = 0; i < 4; i++ ) {
6387 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6388 // check for concurrents in own and other dimensions (step-by-step)
6389 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6390 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
6391 const SMESH_DimHyp* dimHyp = *dhIt;
6392 TDimHypList listOfConcurr;
6393 set<int> setOfConcurrIds;
6394 // looking for concurrents and collect into own list
6395 for ( int j = i; j < 4; j++ )
6396 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6397 // check if any concurrents found
6398 if ( listOfConcurr.size() > 0 ) {
6399 // add own submesh to list of concurrent
6400 addInOrderOfPriority( dimHyp, listOfConcurr );
6401 list<int> listOfConcurrIds;
6402 TDimHypList::iterator hypIt = listOfConcurr.begin();
6403 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6404 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6405 anOrder.push_back( listOfConcurrIds );
6410 removeDimHyps(dimHypListArr);
6412 // now, minimize the number of concurrent groups
6413 // Here we assume that lists of submeshes can have same submesh
6414 // in case of multi-dimension algorithms, as result
6415 // list with common submesh has to be united into one list
6417 TListOfListOfInt::iterator listIt = anOrder.begin();
6418 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6419 unionLists( *listIt, anOrder, listIndx + 1 );
6425 //=============================================================================
6427 * \brief Set submesh object order
6428 * \param theSubMeshArray submesh array order
6430 //=============================================================================
6432 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6435 _preMeshInfo->ForgetOrLoad();
6438 ::SMESH_Mesh& mesh = GetImpl();
6440 TPythonDump aPythonDump; // prevent dump of called methods
6441 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6443 TListOfListOfInt subMeshOrder;
6444 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6446 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6447 TListOfInt subMeshIds;
6449 aPythonDump << ", ";
6450 aPythonDump << "[ ";
6451 // Collect subMeshes which should be clear
6452 // do it list-by-list, because modification of submesh order
6453 // take effect between concurrent submeshes only
6454 set<const SMESH_subMesh*> subMeshToClear;
6455 list<const SMESH_subMesh*> subMeshList;
6456 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6458 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6460 aPythonDump << ", ";
6461 aPythonDump << subMesh;
6462 subMeshIds.push_back( subMesh->GetId() );
6463 // detect common parts of submeshes
6464 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6465 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6467 aPythonDump << " ]";
6468 subMeshOrder.push_back( subMeshIds );
6470 // clear collected sub-meshes
6471 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6472 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6473 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6475 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6476 if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748
6477 sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo
6480 aPythonDump << " ])";
6482 mesh.SetMeshOrder( subMeshOrder );
6485 SMESH::SMESH_Mesh_var me = _this();
6486 _gen_i->UpdateIcons( me );
6491 //=============================================================================
6493 * \brief Convert submesh ids into submesh interfaces
6495 //=============================================================================
6497 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6498 SMESH::submesh_array_array& theResOrder,
6499 const bool theIsDump)
6501 int nbSet = theIdsOrder.size();
6502 TPythonDump aPythonDump; // prevent dump of called methods
6504 aPythonDump << "[ ";
6505 theResOrder.length(nbSet);
6506 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6508 for( ; it != theIdsOrder.end(); it++ ) {
6509 // translate submesh identificators into submesh objects
6510 // takeing into account real number of concurrent lists
6511 const TListOfInt& aSubOrder = (*it);
6512 if (!aSubOrder.size())
6515 aPythonDump << "[ ";
6516 // convert shape indices into interfaces
6517 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6518 aResSubSet->length(aSubOrder.size());
6519 TListOfInt::const_iterator subIt = aSubOrder.begin();
6521 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6522 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6524 SMESH::SMESH_subMesh_var subMesh =
6525 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6528 aPythonDump << ", ";
6529 aPythonDump << subMesh;
6531 aResSubSet[ j++ ] = subMesh;
6534 aPythonDump << " ]";
6536 theResOrder[ listIndx++ ] = aResSubSet;
6538 // correct number of lists
6539 theResOrder.length( listIndx );
6542 // finilise python dump
6543 aPythonDump << " ]";
6544 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6548 namespace // utils used by SMESH_MeshPartDS
6551 * \brief Class used to access to protected data of SMDS_MeshInfo
6553 struct TMeshInfo : public SMDS_MeshInfo
6555 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6558 * \brief Element holing its ID only
6560 struct TElemID : public SMDS_LinearEdge
6562 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6566 //================================================================================
6568 // Implementation of SMESH_MeshPartDS
6570 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6571 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6573 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6574 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6577 _meshDS = mesh_i->GetImpl().GetMeshDS();
6579 SetPersistentId( _meshDS->GetPersistentId() );
6581 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6583 // <meshPart> is the whole mesh
6584 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6586 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6587 myGroupSet = _meshDS->GetGroups();
6592 SMESH::long_array_var anIDs = meshPart->GetIDs();
6593 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6594 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6596 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6597 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6598 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6603 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6604 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6605 if ( _elements[ e->GetType() ].insert( e ).second )
6608 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6609 while ( nIt->more() )
6611 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6612 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6619 ShapeToMesh( _meshDS->ShapeToMesh() );
6621 _meshDS = 0; // to enforce iteration on _elements and _nodes
6624 // -------------------------------------------------------------------------------------
6625 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6626 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6629 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6630 for ( ; partIt != meshPart.end(); ++partIt )
6631 if ( const SMDS_MeshElement * e = *partIt )
6632 if ( _elements[ e->GetType() ].insert( e ).second )
6635 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6636 while ( nIt->more() )
6638 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6639 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6645 // -------------------------------------------------------------------------------------
6646 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6648 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6650 TElemID elem( IDelem );
6651 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6652 if ( !_elements[ iType ].empty() )
6654 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6655 if ( it != _elements[ iType ].end() )
6660 // -------------------------------------------------------------------------------------
6661 bool SMESH_MeshPartDS::HasNumerationHoles()
6663 if ( _meshDS ) return _meshDS->HasNumerationHoles();
6665 return ( MinNodeID() != 1 ||
6666 MaxNodeID() != NbNodes() ||
6667 MinElementID() != 1 ||
6668 MaxElementID() != NbElements() );
6670 // -------------------------------------------------------------------------------------
6671 int SMESH_MeshPartDS::MaxNodeID() const
6673 if ( _meshDS ) return _meshDS->MaxNodeID();
6674 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID();
6676 // -------------------------------------------------------------------------------------
6677 int SMESH_MeshPartDS::MinNodeID() const
6679 if ( _meshDS ) return _meshDS->MinNodeID();
6680 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID();
6682 // -------------------------------------------------------------------------------------
6683 int SMESH_MeshPartDS::MaxElementID() const
6685 if ( _meshDS ) return _meshDS->MaxElementID();
6687 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6688 if ( !_elements[ iType ].empty() )
6689 maxID = Max( maxID, (*_elements[ iType ].rbegin())->GetID() );
6692 // -------------------------------------------------------------------------------------
6693 int SMESH_MeshPartDS::MinElementID() const
6695 if ( _meshDS ) return _meshDS->MinElementID();
6697 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6698 if ( !_elements[ iType ].empty() )
6699 minID = Min( minID, (*_elements[ iType ].begin())->GetID() );
6702 // -------------------------------------------------------------------------------------
6703 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6705 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6707 typedef SMDS_SetIterator
6708 <const SMDS_MeshElement*,
6709 TIDSortedElemSet::const_iterator,
6710 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6711 SMDS_MeshElement::GeomFilter
6714 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6716 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6717 _elements[type].end(),
6718 SMDS_MeshElement::GeomFilter( geomType )));
6720 // -------------------------------------------------------------------------------------
6721 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6723 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6725 typedef SMDS_SetIterator
6726 <const SMDS_MeshElement*,
6727 TIDSortedElemSet::const_iterator,
6728 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6729 SMDS_MeshElement::EntityFilter
6732 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6734 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6735 _elements[type].end(),
6736 SMDS_MeshElement::EntityFilter( entity )));
6738 // -------------------------------------------------------------------------------------
6739 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6741 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6742 if ( type == SMDSAbs_All && !_meshDS )
6744 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6746 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6747 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6749 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6751 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6752 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6754 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6755 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6757 // -------------------------------------------------------------------------------------
6758 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6759 iterType SMESH_MeshPartDS::methName() const \
6761 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6762 return _meshDS ? _meshDS->methName() : iterType \
6763 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6765 // -------------------------------------------------------------------------------------
6766 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6767 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6768 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6769 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6770 #undef _GET_ITER_DEFINE
6772 // END Implementation of SMESH_MeshPartDS
6774 //================================================================================