1 // Copyright (C) 2007-2014 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_EdgePosition.hxx"
33 #include "SMDS_ElemIterator.hxx"
34 #include "SMDS_FacePosition.hxx"
35 #include "SMDS_IteratorOnIterators.hxx"
36 #include "SMDS_MeshGroup.hxx"
37 #include "SMDS_SetIterator.hxx"
38 #include "SMDS_VolumeTool.hxx"
39 #include "SMESHDS_Command.hxx"
40 #include "SMESHDS_CommandType.hxx"
41 #include "SMESHDS_Group.hxx"
42 #include "SMESHDS_GroupOnGeom.hxx"
43 #include "SMESH_Controls.hxx"
44 #include "SMESH_File.hxx"
45 #include "SMESH_Filter_i.hxx"
46 #include "SMESH_Gen_i.hxx"
47 #include "SMESH_Group.hxx"
48 #include "SMESH_Group_i.hxx"
49 #include "SMESH_Mesh.hxx"
50 #include "SMESH_MeshAlgos.hxx"
51 #include "SMESH_MeshEditor.hxx"
52 #include "SMESH_MeshEditor_i.hxx"
53 #include "SMESH_MeshPartDS.hxx"
54 #include "SMESH_MesherHelper.hxx"
55 #include "SMESH_PreMeshInfo.hxx"
56 #include "SMESH_PythonDump.hxx"
57 #include "SMESH_subMesh_i.hxx"
59 #include <SALOMEDS_Attributes_wrap.hxx>
60 #include <SALOMEDS_wrap.hxx>
61 #include <Utils_ExceptHandlers.hxx>
62 #include <utilities.h>
64 #include <GEOMImpl_Types.hxx>
65 #include <GEOM_wrap.hxx>
68 #include <BRep_Builder.hxx>
69 #include <Standard_ErrorHandler.hxx>
70 #include <TColStd_MapOfInteger.hxx>
72 #include <TopExp_Explorer.hxx>
73 #include <TopTools_MapIteratorOfMapOfShape.hxx>
74 #include <TopTools_MapOfShape.hxx>
75 #include <TopoDS_Compound.hxx>
82 // to pass CORBA exception through SMESH_TRY
83 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
85 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
88 static int MYDEBUG = 0;
90 static int MYDEBUG = 0;
94 using SMESH::TPythonDump;
96 int SMESH_Mesh_i::_idGenerator = 0;
98 //=============================================================================
102 //=============================================================================
104 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
106 CORBA::Long studyId )
107 : SALOME::GenericObj_i( thePOA )
109 MESSAGE("SMESH_Mesh_i");
112 _id = _idGenerator++;
115 _previewEditor = NULL;
120 //=============================================================================
124 //=============================================================================
126 SMESH_Mesh_i::~SMESH_Mesh_i()
128 MESSAGE("~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 delete _editor; _editor = NULL;
163 delete _previewEditor; _previewEditor = NULL;
164 delete _impl; _impl = NULL;
165 delete _preMeshInfo; _preMeshInfo = NULL;
168 //=============================================================================
172 * Associates <this> mesh with <theShape> and puts a reference
173 * to <theShape> into the current study;
174 * the previous shape is substituted by the new one.
176 //=============================================================================
178 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
179 throw (SALOME::SALOME_Exception)
181 Unexpect aCatch(SALOME_SalomeException);
183 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
185 catch(SALOME_Exception & S_ex) {
186 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
188 // to track changes of GEOM groups
189 SMESH::SMESH_Mesh_var mesh = _this();
190 addGeomGroupData( theShapeObject, mesh );
191 if ( !CORBA::is_nil( theShapeObject ))
192 _mainShapeTick = theShapeObject->GetTick();
195 //================================================================================
197 * \brief return true if mesh has a shape to build a shape on
199 //================================================================================
201 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
202 throw (SALOME::SALOME_Exception)
204 Unexpect aCatch(SALOME_SalomeException);
207 res = _impl->HasShapeToMesh();
209 catch(SALOME_Exception & S_ex) {
210 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
215 //=======================================================================
216 //function : GetShapeToMesh
218 //=======================================================================
220 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
221 throw (SALOME::SALOME_Exception)
223 Unexpect aCatch(SALOME_SalomeException);
224 GEOM::GEOM_Object_var aShapeObj;
226 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
228 aShapeObj = _gen_i->ShapeToGeomObject( S );
230 catch(SALOME_Exception & S_ex) {
231 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
233 return aShapeObj._retn();
236 //================================================================================
238 * \brief Return false if the mesh is not yet fully loaded from the study file
240 //================================================================================
242 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
244 Unexpect aCatch(SALOME_SalomeException);
245 return !_preMeshInfo;
248 //================================================================================
250 * \brief Load full mesh data from the study file
252 //================================================================================
254 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
256 Unexpect aCatch(SALOME_SalomeException);
258 _preMeshInfo->FullLoadFromFile();
261 //================================================================================
263 * \brief Remove all nodes and elements
265 //================================================================================
267 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
269 Unexpect aCatch(SALOME_SalomeException);
271 _preMeshInfo->ForgetAllData();
275 //CheckGeomGroupModif(); // issue 20145
277 catch(SALOME_Exception & S_ex) {
278 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
280 _impl->GetMeshDS()->Modified();
282 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
285 //================================================================================
287 * \brief Remove all nodes and elements for indicated shape
289 //================================================================================
291 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
292 throw (SALOME::SALOME_Exception)
294 Unexpect aCatch(SALOME_SalomeException);
296 _preMeshInfo->FullLoadFromFile();
299 _impl->ClearSubMesh( ShapeID );
301 catch(SALOME_Exception & S_ex) {
302 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
304 _impl->GetMeshDS()->Modified();
306 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
309 //=============================================================================
311 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
313 //=============================================================================
315 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
317 SMESH::DriverMED_ReadStatus res;
320 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
321 res = SMESH::DRS_OK; break;
322 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
323 res = SMESH::DRS_EMPTY; break;
324 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
325 res = SMESH::DRS_WARN_RENUMBER; break;
326 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
327 res = SMESH::DRS_WARN_SKIP_ELEM; break;
328 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
329 res = SMESH::DRS_WARN_DESCENDING; break;
330 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
332 res = SMESH::DRS_FAIL; break;
337 //=============================================================================
339 * Convert ::SMESH_ComputeError to SMESH::ComputeError
341 //=============================================================================
343 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
345 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
346 errVar->subShapeID = -1;
347 errVar->hasBadMesh = false;
349 if ( !errorPtr || errorPtr->IsOK() )
351 errVar->code = SMESH::COMPERR_OK;
355 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
356 errVar->comment = errorPtr->myComment.c_str();
358 return errVar._retn();
361 //=============================================================================
365 * Imports mesh data from MED file
367 //=============================================================================
369 SMESH::DriverMED_ReadStatus
370 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
371 throw ( SALOME::SALOME_Exception )
373 Unexpect aCatch(SALOME_SalomeException);
376 status = _impl->MEDToMesh( theFileName, theMeshName );
378 catch( SALOME_Exception& S_ex ) {
379 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
382 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
385 CreateGroupServants();
387 int major, minor, release;
388 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
389 major = minor = release = -1;
390 _medFileInfo = new SMESH::MedFileInfo();
391 _medFileInfo->fileName = theFileName;
392 _medFileInfo->fileSize = 0;
393 _medFileInfo->major = major;
394 _medFileInfo->minor = minor;
395 _medFileInfo->release = release;
396 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
398 return ConvertDriverMEDReadStatus(status);
401 //================================================================================
403 * \brief Imports mesh data from the CGNS file
405 //================================================================================
407 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
408 const int theMeshIndex,
409 std::string& theMeshName )
410 throw ( SALOME::SALOME_Exception )
412 Unexpect aCatch(SALOME_SalomeException);
415 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
417 catch( SALOME_Exception& S_ex ) {
418 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
421 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
424 CreateGroupServants();
426 return ConvertDriverMEDReadStatus(status);
429 //================================================================================
431 * \brief Return string representation of a MED file version comprising nbDigits
433 //================================================================================
435 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
437 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
439 return CORBA::string_dup( ver.c_str() );
442 //=============================================================================
446 * Imports mesh data from MED file
448 //=============================================================================
450 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
451 throw ( SALOME::SALOME_Exception )
455 // Read mesh with name = <theMeshName> into SMESH_Mesh
456 _impl->UNVToMesh( theFileName );
458 CreateGroupServants();
460 SMESH_CATCH( SMESH::throwCorbaException );
465 //=============================================================================
469 * Imports mesh data from STL file
471 //=============================================================================
472 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
473 throw ( SALOME::SALOME_Exception )
477 // Read mesh with name = <theMeshName> into SMESH_Mesh
478 _impl->STLToMesh( theFileName );
480 SMESH_CATCH( SMESH::throwCorbaException );
485 //================================================================================
487 * \brief Function used in SMESH_CATCH by ImportGMFFile()
489 //================================================================================
493 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
495 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
499 //================================================================================
501 * \brief Imports data from a GMF file and returns an error description
503 //================================================================================
505 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
506 bool theMakeRequiredGroups )
507 throw (SALOME::SALOME_Exception)
509 SMESH_ComputeErrorPtr error;
512 #define SMESH_CAUGHT error =
515 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
517 SMESH_CATCH( exceptionToComputeError );
521 CreateGroupServants();
523 return ConvertComputeError( error );
526 //=============================================================================
530 //=============================================================================
532 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
534 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
535 (SMESH_Hypothesis::Hypothesis_Status theStatus)
538 RETURNCASE( HYP_OK );
539 RETURNCASE( HYP_MISSING );
540 RETURNCASE( HYP_CONCURENT );
541 RETURNCASE( HYP_BAD_PARAMETER );
542 RETURNCASE( HYP_HIDDEN_ALGO );
543 RETURNCASE( HYP_HIDING_ALGO );
544 RETURNCASE( HYP_UNKNOWN_FATAL );
545 RETURNCASE( HYP_INCOMPATIBLE );
546 RETURNCASE( HYP_NOTCONFORM );
547 RETURNCASE( HYP_ALREADY_EXIST );
548 RETURNCASE( HYP_BAD_DIM );
549 RETURNCASE( HYP_BAD_SUBSHAPE );
550 RETURNCASE( HYP_BAD_GEOMETRY );
551 RETURNCASE( HYP_NEED_SHAPE );
554 return SMESH::HYP_UNKNOWN_FATAL;
557 //=============================================================================
561 * calls internal addHypothesis() and then adds a reference to <anHyp> under
562 * the SObject actually having a reference to <aSubShape>.
563 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
565 //=============================================================================
567 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
568 SMESH::SMESH_Hypothesis_ptr anHyp)
569 throw(SALOME::SALOME_Exception)
571 Unexpect aCatch(SALOME_SalomeException);
573 _preMeshInfo->ForgetOrLoad();
575 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
577 SMESH::SMESH_Mesh_var mesh( _this() );
578 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
580 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
581 _gen_i->AddHypothesisToShape( study, mesh, aSubShapeObject, anHyp );
583 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
585 // Update Python script
586 //if(_impl->HasShapeToMesh())
588 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
589 << aSubShapeObject << ", " << anHyp << " )";
592 // TPythonDump() << "status = " << mesh << ".AddHypothesis( "<< anHyp << " )";
595 return ConvertHypothesisStatus(status);
598 //=============================================================================
602 //=============================================================================
604 SMESH_Hypothesis::Hypothesis_Status
605 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
606 SMESH::SMESH_Hypothesis_ptr anHyp)
608 if(MYDEBUG) MESSAGE("addHypothesis");
610 if (CORBA::is_nil( aSubShapeObject ) && HasShapeToMesh())
611 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
613 if (CORBA::is_nil( anHyp ))
614 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
616 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
619 TopoDS_Shape myLocSubShape;
620 //use PseudoShape in case if mesh has no shape
622 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
624 myLocSubShape = _impl->GetShapeToMesh();
626 const int hypId = anHyp->GetId();
627 status = _impl->AddHypothesis(myLocSubShape, hypId);
628 if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
629 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
631 // assure there is a corresponding submesh
632 if ( !_impl->IsMainShape( myLocSubShape )) {
633 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
634 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
635 SMESH::SMESH_subMesh_var( createSubMesh( aSubShapeObject ));
639 catch(SALOME_Exception & S_ex)
641 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
646 //=============================================================================
650 //=============================================================================
652 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
653 SMESH::SMESH_Hypothesis_ptr anHyp)
654 throw(SALOME::SALOME_Exception)
656 Unexpect aCatch(SALOME_SalomeException);
658 _preMeshInfo->ForgetOrLoad();
660 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
661 SMESH::SMESH_Mesh_var mesh = _this();
663 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
665 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
666 _gen_i->RemoveHypothesisFromShape( study, mesh, aSubShapeObject, anHyp );
668 // Update Python script
669 if(_impl->HasShapeToMesh())
670 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
671 << aSubShapeObject << ", " << anHyp << " )";
673 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
676 return ConvertHypothesisStatus(status);
679 //=============================================================================
683 //=============================================================================
685 SMESH_Hypothesis::Hypothesis_Status
686 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
687 SMESH::SMESH_Hypothesis_ptr anHyp)
689 if(MYDEBUG) MESSAGE("removeHypothesis()");
691 if (CORBA::is_nil( aSubShapeObject ) && HasShapeToMesh())
692 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
694 if (CORBA::is_nil( anHyp ))
695 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
697 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
700 TopoDS_Shape myLocSubShape;
701 //use PseudoShape in case if mesh has no shape
702 if( _impl->HasShapeToMesh() )
703 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject );
705 myLocSubShape = _impl->GetShapeToMesh();
707 const int hypId = anHyp->GetId();
708 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
709 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
711 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
715 catch(SALOME_Exception & S_ex)
717 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
722 //=============================================================================
726 //=============================================================================
728 SMESH::ListOfHypothesis *
729 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
730 throw(SALOME::SALOME_Exception)
732 Unexpect aCatch(SALOME_SalomeException);
733 if (MYDEBUG) MESSAGE("GetHypothesisList");
734 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
735 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
737 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
740 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
741 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
742 myLocSubShape = _impl->GetShapeToMesh();
743 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
744 int i = 0, n = aLocalList.size();
747 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
748 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
749 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
751 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
752 if ( id_hypptr != _mapHypo.end() )
753 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
757 catch(SALOME_Exception & S_ex) {
758 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
761 return aList._retn();
764 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
766 Unexpect aCatch(SALOME_SalomeException);
767 if (MYDEBUG) MESSAGE("GetSubMeshes");
769 SMESH::submesh_array_var aList = new SMESH::submesh_array();
772 TPythonDump aPythonDump;
773 if ( !_mapSubMeshIor.empty() )
777 aList->length( _mapSubMeshIor.size() );
779 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
780 for ( ; it != _mapSubMeshIor.end(); it++ ) {
781 if ( CORBA::is_nil( it->second )) continue;
782 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
784 if (i > 1) aPythonDump << ", ";
785 aPythonDump << it->second;
789 catch(SALOME_Exception & S_ex) {
790 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
793 // Update Python script
794 if ( !_mapSubMeshIor.empty() )
795 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
797 return aList._retn();
800 //=============================================================================
804 //=============================================================================
806 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
807 const char* theName )
808 throw(SALOME::SALOME_Exception)
810 Unexpect aCatch(SALOME_SalomeException);
811 if (CORBA::is_nil(aSubShapeObject))
812 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
814 SMESH::SMESH_subMesh_var subMesh;
815 SMESH::SMESH_Mesh_var aMesh = _this();
817 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
819 //Get or Create the SMESH_subMesh object implementation
821 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
823 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
825 TopoDS_Iterator it( myLocSubShape );
827 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
829 subMesh = getSubMesh( subMeshId );
831 // create a new subMesh object servant if there is none for the shape
832 if ( subMesh->_is_nil() )
833 subMesh = createSubMesh( aSubShapeObject );
834 if ( _gen_i->CanPublishInStudy( subMesh ))
836 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
837 SALOMEDS::SObject_wrap aSO =
838 _gen_i->PublishSubMesh( study, aMesh, subMesh, aSubShapeObject, theName );
839 if ( !aSO->_is_nil()) {
840 // Update Python script
841 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
842 << aSubShapeObject << ", '" << theName << "' )";
846 catch(SALOME_Exception & S_ex) {
847 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
849 return subMesh._retn();
852 //=============================================================================
856 //=============================================================================
858 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
859 throw (SALOME::SALOME_Exception)
863 if ( theSubMesh->_is_nil() )
866 GEOM::GEOM_Object_var aSubShapeObject;
867 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
868 if ( !aStudy->_is_nil() ) {
869 // Remove submesh's SObject
870 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
871 if ( !anSO->_is_nil() ) {
872 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
873 SALOMEDS::SObject_wrap anObj, aRef;
874 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
875 anObj->ReferencedObject( aRef.inout() ))
877 CORBA::Object_var obj = aRef->GetObject();
878 aSubShapeObject = GEOM::GEOM_Object::_narrow( obj );
880 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
881 // aSubShapeObject = theSubMesh->GetSubShape();
883 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
884 builder->RemoveObjectWithChildren( anSO );
886 // Update Python script
887 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
891 if ( removeSubMesh( theSubMesh, aSubShapeObject.in() ))
893 _preMeshInfo->ForgetOrLoad();
895 SMESH_CATCH( SMESH::throwCorbaException );
898 //=============================================================================
902 //=============================================================================
904 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
905 const char* theName )
906 throw(SALOME::SALOME_Exception)
908 Unexpect aCatch(SALOME_SalomeException);
910 _preMeshInfo->FullLoadFromFile();
912 SMESH::SMESH_Group_var aNewGroup =
913 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
915 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
917 SMESH::SMESH_Mesh_var mesh = _this();
918 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
919 SALOMEDS::SObject_wrap aSO =
920 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
921 if ( !aSO->_is_nil())
922 // Update Python script
923 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
924 << theElemType << ", '" << theName << "' )";
926 return aNewGroup._retn();
929 //=============================================================================
933 //=============================================================================
934 SMESH::SMESH_GroupOnGeom_ptr
935 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
937 GEOM::GEOM_Object_ptr theGeomObj)
938 throw(SALOME::SALOME_Exception)
940 Unexpect aCatch(SALOME_SalomeException);
942 _preMeshInfo->FullLoadFromFile();
944 SMESH::SMESH_GroupOnGeom_var aNewGroup;
946 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
947 if ( !aShape.IsNull() )
950 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
952 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
954 SMESH::SMESH_Mesh_var mesh = _this();
955 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
956 SALOMEDS::SObject_wrap aSO =
957 _gen_i->PublishGroup( study, mesh, aNewGroup, theGeomObj, theName );
958 if ( !aSO->_is_nil())
959 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
960 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
964 return aNewGroup._retn();
967 //================================================================================
969 * \brief Creates a group whose contents is defined by filter
970 * \param theElemType - group type
971 * \param theName - group name
972 * \param theFilter - the filter
973 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
975 //================================================================================
977 SMESH::SMESH_GroupOnFilter_ptr
978 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
980 SMESH::Filter_ptr theFilter )
981 throw (SALOME::SALOME_Exception)
983 Unexpect aCatch(SALOME_SalomeException);
985 _preMeshInfo->FullLoadFromFile();
987 if ( CORBA::is_nil( theFilter ))
988 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
990 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
992 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
994 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
995 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
998 if ( !aNewGroup->_is_nil() )
999 aNewGroup->SetFilter( theFilter );
1001 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1003 SMESH::SMESH_Mesh_var mesh = _this();
1004 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1005 SALOMEDS::SObject_wrap aSO =
1006 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1008 if ( !aSO->_is_nil())
1009 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1010 << theElemType << ", '" << theName << "', " << theFilter << " )";
1012 return aNewGroup._retn();
1015 //=============================================================================
1019 //=============================================================================
1021 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1022 throw (SALOME::SALOME_Exception)
1024 if ( theGroup->_is_nil() )
1029 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1033 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
1034 if ( !aStudy->_is_nil() )
1036 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1037 if ( !aGroupSO->_is_nil() )
1039 // Update Python script
1040 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1042 // Remove group's SObject
1043 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
1044 builder->RemoveObjectWithChildren( aGroupSO );
1048 // Remove the group from SMESH data structures
1049 removeGroup( aGroup->GetLocalID() );
1051 SMESH_CATCH( SMESH::throwCorbaException );
1054 //=============================================================================
1056 * Remove group with its contents
1058 //=============================================================================
1060 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1061 throw (SALOME::SALOME_Exception)
1065 _preMeshInfo->FullLoadFromFile();
1067 if ( theGroup->_is_nil() )
1071 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1072 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1073 while ( elemIt->more() )
1074 _impl->GetMeshDS()->RemoveElement( elemIt->next() );
1076 TPythonDump pyDump; // Supress dump from RemoveGroup()
1078 // Update Python script (theGroup must be alive for this)
1079 pyDump << SMESH::SMESH_Mesh_var(_this())
1080 << ".RemoveGroupWithContents( " << theGroup << " )";
1083 RemoveGroup( theGroup );
1085 SMESH_CATCH( SMESH::throwCorbaException );
1088 //================================================================================
1090 * \brief Get the list of groups existing in the mesh
1091 * \retval SMESH::ListOfGroups * - list of groups
1093 //================================================================================
1095 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1097 Unexpect aCatch(SALOME_SalomeException);
1098 if (MYDEBUG) MESSAGE("GetGroups");
1100 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1103 TPythonDump aPythonDump;
1104 if ( !_mapGroups.empty() )
1106 aPythonDump << "[ ";
1108 aList->length( _mapGroups.size() );
1110 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1111 for ( ; it != _mapGroups.end(); it++ ) {
1112 if ( CORBA::is_nil( it->second )) continue;
1113 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1115 if (i > 1) aPythonDump << ", ";
1116 aPythonDump << it->second;
1120 catch(SALOME_Exception & S_ex) {
1121 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1123 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1125 return aList._retn();
1128 //=============================================================================
1130 * Get number of groups existing in the mesh
1132 //=============================================================================
1134 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1136 Unexpect aCatch(SALOME_SalomeException);
1137 return _mapGroups.size();
1140 //=============================================================================
1142 * New group including all mesh elements present in initial groups is created.
1144 //=============================================================================
1146 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1147 SMESH::SMESH_GroupBase_ptr theGroup2,
1148 const char* theName )
1149 throw (SALOME::SALOME_Exception)
1151 SMESH::SMESH_Group_var aResGrp;
1155 _preMeshInfo->FullLoadFromFile();
1157 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1158 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1160 if ( theGroup1->GetType() != theGroup2->GetType() )
1161 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1166 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1167 if ( aResGrp->_is_nil() )
1168 return SMESH::SMESH_Group::_nil();
1170 aResGrp->AddFrom( theGroup1 );
1171 aResGrp->AddFrom( theGroup2 );
1173 // Update Python script
1174 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1175 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1177 SMESH_CATCH( SMESH::throwCorbaException );
1179 return aResGrp._retn();
1182 //=============================================================================
1184 * \brief New group including all mesh elements present in initial groups is created.
1185 * \param theGroups list of groups
1186 * \param theName name of group to be created
1187 * \return pointer to the new group
1189 //=============================================================================
1191 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1192 const char* theName )
1193 throw (SALOME::SALOME_Exception)
1195 SMESH::SMESH_Group_var aResGrp;
1198 _preMeshInfo->FullLoadFromFile();
1201 return SMESH::SMESH_Group::_nil();
1206 SMESH::ElementType aType = SMESH::ALL;
1207 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1209 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1210 if ( CORBA::is_nil( aGrp ) )
1212 if ( aType == SMESH::ALL )
1213 aType = aGrp->GetType();
1214 else if ( aType != aGrp->GetType() )
1215 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1218 if ( aType == SMESH::ALL )
1219 return SMESH::SMESH_Group::_nil();
1224 aResGrp = CreateGroup( aType, theName );
1225 if ( aResGrp->_is_nil() )
1226 return SMESH::SMESH_Group::_nil();
1228 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1229 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1231 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1232 if ( !CORBA::is_nil( aGrp ) )
1234 aResGrp->AddFrom( aGrp );
1235 if ( g > 0 ) pyDump << ", ";
1239 pyDump << " ], '" << theName << "' )";
1241 SMESH_CATCH( SMESH::throwCorbaException );
1243 return aResGrp._retn();
1246 //=============================================================================
1248 * New group is created. All mesh elements that are
1249 * present in both initial groups are added to the new one.
1251 //=============================================================================
1253 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1254 SMESH::SMESH_GroupBase_ptr theGroup2,
1255 const char* theName )
1256 throw (SALOME::SALOME_Exception)
1258 SMESH::SMESH_Group_var aResGrp;
1263 _preMeshInfo->FullLoadFromFile();
1265 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1266 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1268 if ( theGroup1->GetType() != theGroup2->GetType() )
1269 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1273 // Create Intersection
1274 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1275 if ( aResGrp->_is_nil() )
1276 return aResGrp._retn();
1278 SMESHDS_GroupBase* groupDS1 = 0;
1279 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1280 groupDS1 = grp_i->GetGroupDS();
1282 SMESHDS_GroupBase* groupDS2 = 0;
1283 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1284 groupDS2 = grp_i->GetGroupDS();
1286 SMESHDS_Group* resGroupDS = 0;
1287 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1288 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1290 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1292 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1293 while ( elemIt1->more() )
1295 const SMDS_MeshElement* e = elemIt1->next();
1296 if ( groupDS2->Contains( e ))
1297 resGroupDS->SMDSGroup().Add( e );
1300 // Update Python script
1301 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1302 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1304 SMESH_CATCH( SMESH::throwCorbaException );
1306 return aResGrp._retn();
1309 //=============================================================================
1311 \brief Intersect list of groups. New group is created. All mesh elements that
1312 are present in all initial groups simultaneously are added to the new one.
1313 \param theGroups list of groups
1314 \param theName name of group to be created
1315 \return pointer on the group
1317 //=============================================================================
1318 SMESH::SMESH_Group_ptr
1319 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1320 const char* theName )
1321 throw (SALOME::SALOME_Exception)
1323 SMESH::SMESH_Group_var aResGrp;
1328 _preMeshInfo->FullLoadFromFile();
1331 return SMESH::SMESH_Group::_nil();
1333 // check types and get SMESHDS_GroupBase's
1334 SMESH::ElementType aType = SMESH::ALL;
1335 vector< SMESHDS_GroupBase* > groupVec;
1336 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1338 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1339 if ( CORBA::is_nil( aGrp ) )
1341 if ( aType == SMESH::ALL )
1342 aType = aGrp->GetType();
1343 else if ( aType != aGrp->GetType() )
1344 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1347 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1348 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1350 if ( grpDS->IsEmpty() )
1355 groupVec.push_back( grpDS );
1358 if ( aType == SMESH::ALL ) // all groups are nil
1359 return SMESH::SMESH_Group::_nil();
1364 aResGrp = CreateGroup( aType, theName );
1366 SMESHDS_Group* resGroupDS = 0;
1367 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1368 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1369 if ( !resGroupDS || groupVec.empty() )
1370 return aResGrp._retn();
1373 size_t i, nb = groupVec.size();
1374 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1375 while ( elemIt1->more() )
1377 const SMDS_MeshElement* e = elemIt1->next();
1379 for ( i = 1; ( i < nb && inAll ); ++i )
1380 inAll = groupVec[i]->Contains( e );
1383 resGroupDS->SMDSGroup().Add( e );
1386 // Update Python script
1387 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1388 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1390 SMESH_CATCH( SMESH::throwCorbaException );
1392 return aResGrp._retn();
1395 //=============================================================================
1397 * New group is created. All mesh elements that are present in
1398 * a main group but is not present in a tool group are added to the new one
1400 //=============================================================================
1402 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1403 SMESH::SMESH_GroupBase_ptr theGroup2,
1404 const char* theName )
1405 throw (SALOME::SALOME_Exception)
1407 SMESH::SMESH_Group_var aResGrp;
1412 _preMeshInfo->FullLoadFromFile();
1414 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1415 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1417 if ( theGroup1->GetType() != theGroup2->GetType() )
1418 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1422 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1423 if ( aResGrp->_is_nil() )
1424 return aResGrp._retn();
1426 SMESHDS_GroupBase* groupDS1 = 0;
1427 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1428 groupDS1 = grp_i->GetGroupDS();
1430 SMESHDS_GroupBase* groupDS2 = 0;
1431 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1432 groupDS2 = grp_i->GetGroupDS();
1434 SMESHDS_Group* resGroupDS = 0;
1435 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1436 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1438 if ( groupDS1 && groupDS2 && resGroupDS )
1440 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1441 while ( elemIt1->more() )
1443 const SMDS_MeshElement* e = elemIt1->next();
1444 if ( !groupDS2->Contains( e ))
1445 resGroupDS->SMDSGroup().Add( e );
1448 // Update Python script
1449 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1450 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1452 SMESH_CATCH( SMESH::throwCorbaException );
1454 return aResGrp._retn();
1457 //=============================================================================
1459 \brief Cut lists of groups. New group is created. All mesh elements that are
1460 present in main groups but do not present in tool groups are added to the new one
1461 \param theMainGroups list of main groups
1462 \param theToolGroups list of tool groups
1463 \param theName name of group to be created
1464 \return pointer on the group
1466 //=============================================================================
1467 SMESH::SMESH_Group_ptr
1468 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1469 const SMESH::ListOfGroups& theToolGroups,
1470 const char* theName )
1471 throw (SALOME::SALOME_Exception)
1473 SMESH::SMESH_Group_var aResGrp;
1478 _preMeshInfo->FullLoadFromFile();
1481 return SMESH::SMESH_Group::_nil();
1483 // check types and get SMESHDS_GroupBase's
1484 SMESH::ElementType aType = SMESH::ALL;
1485 vector< SMESHDS_GroupBase* > toolGroupVec;
1486 vector< SMDS_ElemIteratorPtr > mainIterVec;
1488 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1490 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1491 if ( CORBA::is_nil( aGrp ) )
1493 if ( aType == SMESH::ALL )
1494 aType = aGrp->GetType();
1495 else if ( aType != aGrp->GetType() )
1496 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1498 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1499 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1500 if ( !grpDS->IsEmpty() )
1501 mainIterVec.push_back( grpDS->GetElements() );
1503 if ( aType == SMESH::ALL ) // all main groups are nil
1504 return SMESH::SMESH_Group::_nil();
1505 if ( mainIterVec.empty() ) // all main groups are empty
1506 return aResGrp._retn();
1508 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1510 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1511 if ( CORBA::is_nil( aGrp ) )
1513 if ( aType != aGrp->GetType() )
1514 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1516 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1517 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1518 toolGroupVec.push_back( grpDS );
1524 aResGrp = CreateGroup( aType, theName );
1526 SMESHDS_Group* resGroupDS = 0;
1527 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1528 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1530 return aResGrp._retn();
1533 size_t i, nb = toolGroupVec.size();
1534 SMDS_ElemIteratorPtr mainElemIt
1535 ( new SMDS_IteratorOnIterators
1536 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1537 while ( mainElemIt->more() )
1539 const SMDS_MeshElement* e = mainElemIt->next();
1541 for ( i = 0; ( i < nb && !isIn ); ++i )
1542 isIn = toolGroupVec[i]->Contains( e );
1545 resGroupDS->SMDSGroup().Add( e );
1548 // Update Python script
1549 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1550 << ".CutListOfGroups( " << theMainGroups
1551 << theToolGroups << ", '" << theName << "' )";
1553 SMESH_CATCH( SMESH::throwCorbaException );
1555 return aResGrp._retn();
1558 //=============================================================================
1560 \brief Create groups of entities from existing groups of superior dimensions
1562 1) extract all nodes from each group,
1563 2) combine all elements of specified dimension laying on these nodes.
1564 \param theGroups list of source groups
1565 \param theElemType dimension of elements
1566 \param theName name of new group
1567 \return pointer on new group
1571 //=============================================================================
1573 SMESH::SMESH_Group_ptr
1574 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups,
1575 SMESH::ElementType theElemType,
1576 const char* theName )
1577 throw (SALOME::SALOME_Exception)
1579 SMESH::SMESH_Group_var aResGrp;
1583 _preMeshInfo->FullLoadFromFile();
1585 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1587 if ( !theName || !aMeshDS )
1588 return SMESH::SMESH_Group::_nil();
1590 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1596 aResGrp = CreateGroup( theElemType, theName );
1597 if ( aResGrp->_is_nil() )
1598 return SMESH::SMESH_Group::_nil();
1600 SMESHDS_GroupBase* groupBaseDS =
1601 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1602 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1604 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1606 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1607 if ( CORBA::is_nil( aGrp ) )
1610 groupBaseDS = SMESH::DownCast<SMESH_GroupBase_i*>( aGrp )->GetGroupDS();
1611 SMDS_ElemIteratorPtr elIt = groupBaseDS->GetElements();
1613 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1615 while ( elIt->more() ) {
1616 const SMDS_MeshElement* el = elIt->next();
1617 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1618 while ( nIt->more() )
1619 resGroupCore.Add( nIt->next() );
1622 else // get elements of theElemType based on nodes of every element of group
1624 while ( elIt->more() )
1626 const SMDS_MeshElement* el = elIt->next(); // an element of group
1627 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1628 TIDSortedElemSet checkedElems;
1629 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1630 while ( nIt->more() )
1632 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nIt->next() );
1633 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1634 // check nodes of elements of theElemType around el
1635 while ( elOfTypeIt->more() )
1637 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1638 if ( !checkedElems.insert( elOfType ).second ) continue;
1640 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1641 bool allNodesOK = true;
1642 while ( nIt2->more() && allNodesOK )
1643 allNodesOK = elNodes.count( nIt2->next() );
1645 resGroupCore.Add( elOfType );
1652 // Update Python script
1653 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1654 << ".CreateDimGroup( "
1655 << theGroups << ", " << theElemType << ", '" << theName << "' )";
1657 SMESH_CATCH( SMESH::throwCorbaException );
1659 return aResGrp._retn();
1662 //================================================================================
1664 * \brief Remember GEOM group data
1666 //================================================================================
1668 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1669 CORBA::Object_ptr theSmeshObj)
1671 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1674 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1675 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1676 if ( groupSO->_is_nil() )
1679 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1680 GEOM::GEOM_IGroupOperations_wrap groupOp =
1681 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1682 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1685 _geomGroupData.push_back( TGeomGroupData() );
1686 TGeomGroupData & groupData = _geomGroupData.back();
1688 CORBA::String_var entry = groupSO->GetID();
1689 groupData._groupEntry = entry.in();
1691 for ( int i = 0; i < ids->length(); ++i )
1692 groupData._indices.insert( ids[i] );
1694 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1695 // shape index in SMESHDS
1696 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1697 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1700 //================================================================================
1702 * Remove GEOM group data relating to removed smesh object
1704 //================================================================================
1706 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1708 list<TGeomGroupData>::iterator
1709 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1710 for ( ; data != dataEnd; ++data ) {
1711 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1712 _geomGroupData.erase( data );
1718 //================================================================================
1720 * \brief Return new group contents if it has been changed and update group data
1722 //================================================================================
1724 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1726 TopoDS_Shape newShape;
1729 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1730 if ( study->_is_nil() ) return newShape; // means "not changed"
1731 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1732 if ( !groupSO->_is_nil() )
1734 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1735 if ( CORBA::is_nil( groupObj )) return newShape;
1736 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1738 // get indices of group items
1739 set<int> curIndices;
1740 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1741 GEOM::GEOM_IGroupOperations_wrap groupOp =
1742 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1743 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1744 for ( int i = 0; i < ids->length(); ++i )
1745 curIndices.insert( ids[i] );
1747 if ( groupData._indices == curIndices )
1748 return newShape; // group not changed
1751 groupData._indices = curIndices;
1753 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1754 if ( !geomClient ) return newShape;
1755 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1756 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1757 newShape = _gen_i->GeomObjectToShape( geomGroup );
1760 if ( newShape.IsNull() ) {
1761 // geom group becomes empty - return empty compound
1762 TopoDS_Compound compound;
1763 BRep_Builder().MakeCompound(compound);
1764 newShape = compound;
1771 //-----------------------------------------------------------------------------
1773 * \brief Storage of shape and index used in CheckGeomGroupModif()
1775 struct TIndexedShape
1778 TopoDS_Shape _shape;
1779 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1781 //-----------------------------------------------------------------------------
1783 * \brief Data to re-create a group on geometry
1785 struct TGroupOnGeomData
1789 SMDSAbs_ElementType _type;
1791 Quantity_Color _color;
1795 //=============================================================================
1797 * \brief Update data if geometry changes
1801 //=============================================================================
1803 void SMESH_Mesh_i::CheckGeomModif()
1805 if ( !_impl->HasShapeToMesh() ) return;
1807 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1808 if ( study->_is_nil() ) return;
1810 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
1811 if ( mainGO->_is_nil() ) return;
1813 if ( mainGO->GetType() == GEOM_GROUP ||
1814 mainGO->GetTick() == _mainShapeTick )
1816 CheckGeomGroupModif();
1820 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1821 if ( !geomClient ) return;
1822 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1823 if ( geomGen->_is_nil() ) return;
1825 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
1826 geomClient->RemoveShapeFromBuffer( ior.in() );
1828 // Update data taking into account that
1829 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
1832 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
1833 if ( newShape.IsNull() )
1836 _mainShapeTick = mainGO->GetTick();
1838 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
1840 // store data of groups on geometry
1841 vector< TGroupOnGeomData > groupsData;
1842 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1843 groupsData.reserve( groups.size() );
1844 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
1845 for ( ; g != groups.end(); ++g )
1846 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
1848 TGroupOnGeomData data;
1849 data._oldID = group->GetID();
1850 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
1851 data._type = group->GetType();
1852 data._name = group->GetStoreName();
1853 data._color = group->GetColor();
1854 groupsData.push_back( data );
1856 // store assigned hypotheses
1857 vector< pair< int, THypList > > ids2Hyps;
1858 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
1859 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
1861 const TopoDS_Shape& s = s2hyps.Key();
1862 const THypList& hyps = s2hyps.ChangeValue();
1863 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
1866 // change shape to mesh
1867 int oldNbSubShapes = meshDS->MaxShapeIndex();
1868 _impl->ShapeToMesh( TopoDS_Shape() );
1869 _impl->ShapeToMesh( newShape );
1871 // re-add shapes of geom groups
1872 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
1873 for ( ; data != _geomGroupData.end(); ++data )
1875 TopoDS_Shape newShape = newGroupShape( *data );
1876 if ( !newShape.IsNull() )
1878 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
1880 TopoDS_Compound compound;
1881 BRep_Builder().MakeCompound( compound );
1882 BRep_Builder().Add( compound, newShape );
1883 newShape = compound;
1885 _impl->GetSubMesh( newShape );
1888 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
1889 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
1890 SALOME::INTERNAL_ERROR );
1892 // re-assign hypotheses
1893 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
1895 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
1896 const THypList& hyps = ids2Hyps[i].second;
1897 THypList::const_iterator h = hyps.begin();
1898 for ( ; h != hyps.end(); ++h )
1899 _impl->AddHypothesis( s, (*h)->GetID() );
1903 for ( size_t i = 0; i < groupsData.size(); ++i )
1905 const TGroupOnGeomData& data = groupsData[i];
1907 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
1908 if ( i2g == _mapGroups.end() ) continue;
1910 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
1911 if ( !gr_i ) continue;
1914 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
1915 meshDS->IndexToShape( data._shapeID ));
1918 _mapGroups.erase( i2g );
1922 g->GetGroupDS()->SetColor( data._color );
1923 gr_i->changeLocalId( id );
1924 _mapGroups[ id ] = i2g->second;
1925 if ( data._oldID != id )
1926 _mapGroups.erase( i2g );
1930 // update _mapSubMesh
1931 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
1932 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
1933 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
1937 //=============================================================================
1939 * \brief Update objects depending on changed geom groups
1941 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1942 * issue 0020210: Update of a smesh group after modification of the associated geom group
1944 //=============================================================================
1946 void SMESH_Mesh_i::CheckGeomGroupModif()
1948 if ( !_impl->HasShapeToMesh() ) return;
1950 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1951 if ( study->_is_nil() ) return;
1953 CORBA::Long nbEntities = NbNodes() + NbElements();
1955 // Check if group contents changed
1957 typedef map< string, TopoDS_Shape > TEntry2Geom;
1958 TEntry2Geom newGroupContents;
1960 list<TGeomGroupData>::iterator
1961 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1962 for ( ; data != dataEnd; ++data )
1964 pair< TEntry2Geom::iterator, bool > it_new =
1965 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1966 bool processedGroup = !it_new.second;
1967 TopoDS_Shape& newShape = it_new.first->second;
1968 if ( !processedGroup )
1969 newShape = newGroupShape( *data );
1970 if ( newShape.IsNull() )
1971 continue; // no changes
1974 _preMeshInfo->ForgetOrLoad();
1976 if ( processedGroup ) { // update group indices
1977 list<TGeomGroupData>::iterator data2 = data;
1978 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1979 data->_indices = data2->_indices;
1982 // Update SMESH objects according to new GEOM group contents
1984 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1985 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1987 int oldID = submesh->GetId();
1988 if ( !_mapSubMeshIor.count( oldID ))
1990 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1992 // update hypotheses
1993 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1994 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1995 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1997 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1998 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2000 // care of submeshes
2001 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2002 int newID = newSubmesh->GetId();
2003 if ( newID != oldID ) {
2004 _mapSubMesh [ newID ] = newSubmesh;
2005 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2006 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2007 _mapSubMesh. erase(oldID);
2008 _mapSubMesh_i. erase(oldID);
2009 _mapSubMeshIor.erase(oldID);
2010 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2015 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2016 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2017 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2019 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2021 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2022 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2023 ds->SetShape( newShape );
2028 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2029 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2031 // Remove groups and submeshes basing on removed sub-shapes
2033 TopTools_MapOfShape newShapeMap;
2034 TopoDS_Iterator shapeIt( newShape );
2035 for ( ; shapeIt.More(); shapeIt.Next() )
2036 newShapeMap.Add( shapeIt.Value() );
2038 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2039 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2041 if ( newShapeMap.Contains( shapeIt.Value() ))
2043 TopTools_IndexedMapOfShape oldShapeMap;
2044 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2045 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2047 const TopoDS_Shape& oldShape = oldShapeMap(i);
2048 int oldInd = meshDS->ShapeToIndex( oldShape );
2050 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2051 if ( i_smIor != _mapSubMeshIor.end() ) {
2052 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2055 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2056 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2058 // check if a group bases on oldInd shape
2059 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2060 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2061 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2062 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2064 RemoveGroup( i_grp->second ); // several groups can base on same shape
2065 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2070 // Reassign hypotheses and update groups after setting the new shape to mesh
2072 // collect anassigned hypotheses
2073 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2074 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2075 TShapeHypList assignedHyps;
2076 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2078 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2079 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2080 if ( !hyps.empty() ) {
2081 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2082 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2083 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2086 // collect shapes supporting groups
2087 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2088 TShapeTypeList groupData;
2089 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2090 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2091 for ( ; grIt != groups.end(); ++grIt )
2093 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2095 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2097 // set new shape to mesh -> DS of submeshes and geom groups is deleted
2098 _impl->ShapeToMesh( newShape );
2100 // reassign hypotheses
2101 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2102 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2104 TIndexedShape& geom = indS_hyps->first;
2105 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2106 int oldID = geom._index;
2107 int newID = meshDS->ShapeToIndex( geom._shape );
2108 if ( oldID == 1 ) { // main shape
2110 geom._shape = newShape;
2114 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2115 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2116 // care of submeshes
2117 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2118 if ( newID != oldID ) {
2119 _mapSubMesh [ newID ] = newSubmesh;
2120 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2121 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2122 _mapSubMesh. erase(oldID);
2123 _mapSubMesh_i. erase(oldID);
2124 _mapSubMeshIor.erase(oldID);
2125 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2129 TShapeTypeList::iterator geomType = groupData.begin();
2130 for ( ; geomType != groupData.end(); ++geomType )
2132 const TIndexedShape& geom = geomType->first;
2133 int oldID = geom._index;
2134 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2137 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2138 CORBA::String_var name = groupSO->GetName();
2140 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2142 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2143 group_i->changeLocalId( newID );
2146 break; // everything has been updated
2149 } // loop on group data
2153 CORBA::Long newNbEntities = NbNodes() + NbElements();
2154 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2155 if ( newNbEntities != nbEntities )
2157 // Add all SObjects with icons to soToUpdateIcons
2158 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2160 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2161 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2162 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2164 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2165 i_gr != _mapGroups.end(); ++i_gr ) // groups
2166 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2169 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2170 for ( ; so != soToUpdateIcons.end(); ++so )
2171 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2174 //=============================================================================
2176 * \brief Create standalone group from a group on geometry or filter
2178 //=============================================================================
2180 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2181 throw (SALOME::SALOME_Exception)
2183 SMESH::SMESH_Group_var aGroup;
2188 _preMeshInfo->FullLoadFromFile();
2190 if ( theGroup->_is_nil() )
2191 return aGroup._retn();
2193 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2195 return aGroup._retn();
2197 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2199 const int anId = aGroupToRem->GetLocalID();
2200 if ( !_impl->ConvertToStandalone( anId ) )
2201 return aGroup._retn();
2202 removeGeomGroupData( theGroup );
2204 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2206 // remove old instance of group from own map
2207 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2208 _mapGroups.erase( anId );
2210 SALOMEDS::StudyBuilder_var builder;
2211 SALOMEDS::SObject_wrap aGroupSO;
2212 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2213 if ( !aStudy->_is_nil() ) {
2214 builder = aStudy->NewBuilder();
2215 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2216 if ( !aGroupSO->_is_nil() )
2218 // remove reference to geometry
2219 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2220 for ( ; chItr->More(); chItr->Next() )
2221 // Remove group's child SObject
2222 builder->RemoveObject( chItr->Value() );
2224 // Update Python script
2225 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2226 << ".ConvertToStandalone( " << aGroupSO << " )";
2228 // change icon of Group on Filter
2231 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2232 const int isEmpty = ( elemTypes->length() == 0 );
2235 SALOMEDS::GenericAttribute_wrap anAttr =
2236 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2237 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2238 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2244 // remember new group in own map
2245 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2246 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2248 // register CORBA object for persistence
2249 _gen_i->RegisterObject( aGroup );
2251 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2252 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2253 //aGroup->Register();
2254 aGroupToRem->UnRegister();
2256 SMESH_CATCH( SMESH::throwCorbaException );
2258 return aGroup._retn();
2261 //=============================================================================
2265 //=============================================================================
2267 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2269 if(MYDEBUG) MESSAGE( "createSubMesh" );
2270 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2271 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2272 const int subMeshId = mySubMesh->GetId();
2274 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2275 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2277 _mapSubMesh [subMeshId] = mySubMesh;
2278 _mapSubMesh_i [subMeshId] = subMeshServant;
2279 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2281 subMeshServant->Register();
2283 // register CORBA object for persistence
2284 int nextId = _gen_i->RegisterObject( subMesh );
2285 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2286 else { nextId = 0; } // avoid "unused variable" warning
2288 // to track changes of GEOM groups
2289 addGeomGroupData( theSubShapeObject, subMesh );
2291 return subMesh._retn();
2294 //=======================================================================
2295 //function : getSubMesh
2297 //=======================================================================
2299 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2301 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2302 if ( it == _mapSubMeshIor.end() )
2303 return SMESH::SMESH_subMesh::_nil();
2305 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2308 //=============================================================================
2312 //=============================================================================
2314 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2315 GEOM::GEOM_Object_ptr theSubShapeObject )
2317 bool isHypChanged = false;
2318 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2319 return isHypChanged;
2321 const int subMeshId = theSubMesh->GetId();
2323 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2325 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2327 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2330 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2331 isHypChanged = !hyps.empty();
2332 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2333 for ( ; hyp != hyps.end(); ++hyp )
2334 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2341 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2342 isHypChanged = ( aHypList->length() > 0 );
2343 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2344 removeHypothesis( theSubShapeObject, aHypList[i] );
2347 catch( const SALOME::SALOME_Exception& ) {
2348 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2350 removeGeomGroupData( theSubShapeObject );
2354 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2355 if ( id_smi != _mapSubMesh_i.end() )
2356 id_smi->second->UnRegister();
2358 // remove a CORBA object
2359 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2360 if ( id_smptr != _mapSubMeshIor.end() )
2361 SMESH::SMESH_subMesh_var( id_smptr->second );
2363 _mapSubMesh.erase(subMeshId);
2364 _mapSubMesh_i.erase(subMeshId);
2365 _mapSubMeshIor.erase(subMeshId);
2367 return isHypChanged;
2370 //=============================================================================
2374 //=============================================================================
2376 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2377 const char* theName,
2378 const TopoDS_Shape& theShape,
2379 const SMESH_PredicatePtr& thePredicate )
2381 std::string newName;
2382 if ( !theName || strlen( theName ) == 0 )
2384 std::set< std::string > presentNames;
2385 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2386 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2388 CORBA::String_var name = i_gr->second->GetName();
2389 presentNames.insert( name.in() );
2392 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2393 } while ( !presentNames.insert( newName ).second );
2394 theName = newName.c_str();
2397 SMESH::SMESH_GroupBase_var aGroup;
2398 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2400 SMESH_GroupBase_i* aGroupImpl;
2401 if ( !theShape.IsNull() )
2402 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2403 else if ( thePredicate )
2404 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2406 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2408 aGroup = aGroupImpl->_this();
2409 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2410 aGroupImpl->Register();
2412 // register CORBA object for persistence
2413 int nextId = _gen_i->RegisterObject( aGroup );
2414 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2415 else { nextId = 0; } // avoid "unused variable" warning in release mode
2417 // to track changes of GEOM groups
2418 if ( !theShape.IsNull() ) {
2419 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2420 addGeomGroupData( geom, aGroup );
2423 return aGroup._retn();
2426 //=============================================================================
2428 * SMESH_Mesh_i::removeGroup
2430 * Should be called by ~SMESH_Group_i()
2432 //=============================================================================
2434 void SMESH_Mesh_i::removeGroup( const int theId )
2436 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2437 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2438 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2439 _mapGroups.erase( theId );
2440 removeGeomGroupData( group );
2441 if ( !_impl->RemoveGroup( theId ))
2443 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2444 RemoveGroup( group );
2446 group->UnRegister();
2450 //=============================================================================
2454 //=============================================================================
2456 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2457 throw(SALOME::SALOME_Exception)
2459 SMESH::log_array_var aLog;
2463 _preMeshInfo->FullLoadFromFile();
2465 list < SMESHDS_Command * >logDS = _impl->GetLog();
2466 aLog = new SMESH::log_array;
2468 int lg = logDS.size();
2471 list < SMESHDS_Command * >::iterator its = logDS.begin();
2472 while(its != logDS.end()){
2473 SMESHDS_Command *com = *its;
2474 int comType = com->GetType();
2476 int lgcom = com->GetNumber();
2478 const list < int >&intList = com->GetIndexes();
2479 int inum = intList.size();
2481 list < int >::const_iterator ii = intList.begin();
2482 const list < double >&coordList = com->GetCoords();
2483 int rnum = coordList.size();
2485 list < double >::const_iterator ir = coordList.begin();
2486 aLog[indexLog].commandType = comType;
2487 aLog[indexLog].number = lgcom;
2488 aLog[indexLog].coords.length(rnum);
2489 aLog[indexLog].indexes.length(inum);
2490 for(int i = 0; i < rnum; i++){
2491 aLog[indexLog].coords[i] = *ir;
2492 //MESSAGE(" "<<i<<" "<<ir.Value());
2495 for(int i = 0; i < inum; i++){
2496 aLog[indexLog].indexes[i] = *ii;
2497 //MESSAGE(" "<<i<<" "<<ii.Value());
2506 SMESH_CATCH( SMESH::throwCorbaException );
2508 return aLog._retn();
2512 //=============================================================================
2516 //=============================================================================
2518 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2522 SMESH_CATCH( SMESH::throwCorbaException );
2525 //=============================================================================
2529 //=============================================================================
2531 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2536 //=============================================================================
2540 //=============================================================================
2542 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2547 //=============================================================================
2550 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2551 // issue 0020918: groups removal is caused by hyp modification
2552 // issue 0021208: to forget not loaded mesh data at hyp modification
2553 struct TCallUp_i : public SMESH_Mesh::TCallUp
2555 SMESH_Mesh_i* _mesh;
2556 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2557 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2558 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2559 virtual void Load () { _mesh->Load(); }
2563 //================================================================================
2565 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2567 //================================================================================
2569 void SMESH_Mesh_i::onHypothesisModified()
2572 _preMeshInfo->ForgetOrLoad();
2575 //=============================================================================
2579 //=============================================================================
2581 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2583 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2586 _impl->SetCallUp( new TCallUp_i(this));
2589 //=============================================================================
2593 //=============================================================================
2595 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2597 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2601 //=============================================================================
2603 * Return mesh editor
2605 //=============================================================================
2607 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2608 throw (SALOME::SALOME_Exception)
2610 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2614 _preMeshInfo->FullLoadFromFile();
2616 // Create MeshEditor
2618 _editor = new SMESH_MeshEditor_i( this, false );
2619 aMeshEdVar = _editor->_this();
2621 // Update Python script
2622 TPythonDump() << _editor << " = "
2623 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2625 SMESH_CATCH( SMESH::throwCorbaException );
2627 return aMeshEdVar._retn();
2630 //=============================================================================
2632 * Return mesh edition previewer
2634 //=============================================================================
2636 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2637 throw (SALOME::SALOME_Exception)
2639 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2643 _preMeshInfo->FullLoadFromFile();
2645 if ( !_previewEditor )
2646 _previewEditor = new SMESH_MeshEditor_i( this, true );
2647 aMeshEdVar = _previewEditor->_this();
2649 SMESH_CATCH( SMESH::throwCorbaException );
2651 return aMeshEdVar._retn();
2654 //================================================================================
2656 * \brief Return true if the mesh has been edited since a last total re-compute
2657 * and those modifications may prevent successful partial re-compute
2659 //================================================================================
2661 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2663 Unexpect aCatch(SALOME_SalomeException);
2664 return _impl->HasModificationsToDiscard();
2667 //================================================================================
2669 * \brief Returns a random unique color
2671 //================================================================================
2673 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2675 const int MAX_ATTEMPTS = 100;
2677 double tolerance = 0.5;
2678 SALOMEDS::Color col;
2682 // generate random color
2683 double red = (double)rand() / RAND_MAX;
2684 double green = (double)rand() / RAND_MAX;
2685 double blue = (double)rand() / RAND_MAX;
2686 // check existence in the list of the existing colors
2687 bool matched = false;
2688 std::list<SALOMEDS::Color>::const_iterator it;
2689 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2690 SALOMEDS::Color color = *it;
2691 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2692 matched = tol < tolerance;
2694 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2695 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2703 //=============================================================================
2705 * Sets auto-color mode. If it is on, groups get unique random colors
2707 //=============================================================================
2709 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2711 Unexpect aCatch(SALOME_SalomeException);
2712 _impl->SetAutoColor(theAutoColor);
2714 TPythonDump pyDump; // not to dump group->SetColor() from below code
2715 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2717 std::list<SALOMEDS::Color> aReservedColors;
2718 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2719 for ( ; it != _mapGroups.end(); it++ ) {
2720 if ( CORBA::is_nil( it->second )) continue;
2721 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2722 it->second->SetColor( aColor );
2723 aReservedColors.push_back( aColor );
2727 //=============================================================================
2729 * Returns true if auto-color mode is on
2731 //=============================================================================
2733 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2735 Unexpect aCatch(SALOME_SalomeException);
2736 return _impl->GetAutoColor();
2739 //=============================================================================
2741 * Checks if there are groups with equal names
2743 //=============================================================================
2745 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2747 return _impl->HasDuplicatedGroupNamesMED();
2750 //================================================================================
2752 * \brief Care of a file before exporting mesh into it
2754 //================================================================================
2756 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2758 SMESH_File aFile( file );
2760 if (aFile.exists()) {
2761 // existing filesystem node
2762 if ( !aFile.isDirectory() ) {
2763 if ( aFile.openForWriting() ) {
2764 if ( overwrite && ! aFile.remove()) {
2765 msg << "Can't replace " << aFile.getName();
2768 msg << "Can't write into " << aFile.getName();
2771 msg << "Location " << aFile.getName() << " is not a file";
2775 // nonexisting file; check if it can be created
2776 if ( !aFile.openForWriting() ) {
2777 msg << "You cannot create the file "
2779 << ". Check the directory existance and access rights";
2787 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
2791 //================================================================================
2793 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2794 * \param file - file name
2795 * \param overwrite - to erase the file or not
2796 * \retval string - mesh name
2798 //================================================================================
2800 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2801 CORBA::Boolean overwrite)
2804 PrepareForWriting(file, overwrite);
2805 string aMeshName = "Mesh";
2806 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2807 if ( !aStudy->_is_nil() ) {
2808 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2809 if ( !aMeshSO->_is_nil() ) {
2810 CORBA::String_var name = aMeshSO->GetName();
2812 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2813 if ( !aStudy->GetProperties()->IsLocked() )
2815 SALOMEDS::GenericAttribute_wrap anAttr;
2816 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2817 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2818 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2819 ASSERT(!aFileName->_is_nil());
2820 aFileName->SetValue(file);
2821 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2822 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2823 ASSERT(!aFileType->_is_nil());
2824 aFileType->SetValue("FICHIERMED");
2828 // Update Python script
2829 // set name of mesh before export
2830 TPythonDump() << _gen_i << ".SetName("
2831 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
2833 // check names of groups
2839 //================================================================================
2841 * \brief Export to med file
2843 //================================================================================
2845 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2846 CORBA::Boolean auto_groups,
2847 SMESH::MED_VERSION theVersion,
2848 CORBA::Boolean overwrite,
2849 CORBA::Boolean autoDimension)
2850 throw(SALOME::SALOME_Exception)
2854 _preMeshInfo->FullLoadFromFile();
2856 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
2857 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
2859 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
2860 << file << "', " << auto_groups << ", "
2861 << theVersion << ", " << overwrite << ", "
2862 << autoDimension << " )";
2864 SMESH_CATCH( SMESH::throwCorbaException );
2867 //================================================================================
2869 * \brief Export a mesh to a med file
2871 //================================================================================
2873 void SMESH_Mesh_i::ExportToMED (const char* file,
2874 CORBA::Boolean auto_groups,
2875 SMESH::MED_VERSION theVersion)
2876 throw(SALOME::SALOME_Exception)
2878 ExportToMEDX(file,auto_groups,theVersion,true);
2881 //================================================================================
2883 * \brief Export a mesh to a med file
2885 //================================================================================
2887 void SMESH_Mesh_i::ExportMED (const char* file,
2888 CORBA::Boolean auto_groups)
2889 throw(SALOME::SALOME_Exception)
2891 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
2894 //================================================================================
2896 * \brief Export a mesh to a SAUV file
2898 //================================================================================
2900 void SMESH_Mesh_i::ExportSAUV (const char* file,
2901 CORBA::Boolean auto_groups)
2902 throw(SALOME::SALOME_Exception)
2904 Unexpect aCatch(SALOME_SalomeException);
2906 _preMeshInfo->FullLoadFromFile();
2908 string aMeshName = prepareMeshNameAndGroups(file, true);
2909 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
2910 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
2911 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
2915 //================================================================================
2917 * \brief Export a mesh to a DAT file
2919 //================================================================================
2921 void SMESH_Mesh_i::ExportDAT (const char *file)
2922 throw(SALOME::SALOME_Exception)
2924 Unexpect aCatch(SALOME_SalomeException);
2926 _preMeshInfo->FullLoadFromFile();
2928 // Update Python script
2929 // check names of groups
2931 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
2934 PrepareForWriting(file);
2935 _impl->ExportDAT(file);
2938 //================================================================================
2940 * \brief Export a mesh to an UNV file
2942 //================================================================================
2944 void SMESH_Mesh_i::ExportUNV (const char *file)
2945 throw(SALOME::SALOME_Exception)
2947 Unexpect aCatch(SALOME_SalomeException);
2949 _preMeshInfo->FullLoadFromFile();
2951 // Update Python script
2952 // check names of groups
2954 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
2957 PrepareForWriting(file);
2958 _impl->ExportUNV(file);
2961 //================================================================================
2963 * \brief Export a mesh to an STL file
2965 //================================================================================
2967 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2968 throw(SALOME::SALOME_Exception)
2970 Unexpect aCatch(SALOME_SalomeException);
2972 _preMeshInfo->FullLoadFromFile();
2974 // Update Python script
2975 // check names of groups
2977 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
2978 << ".ExportSTL( r'" << file << "', " << isascii << " )";
2981 PrepareForWriting(file);
2982 _impl->ExportSTL(file, isascii);
2985 //================================================================================
2987 * \brief Export a part of mesh to a med file
2989 //================================================================================
2991 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
2993 CORBA::Boolean auto_groups,
2994 SMESH::MED_VERSION version,
2995 CORBA::Boolean overwrite,
2996 CORBA::Boolean autoDimension,
2997 const GEOM::ListOfFields& fields,
2998 const char* geomAssocFields)
2999 throw (SALOME::SALOME_Exception)
3003 _preMeshInfo->FullLoadFromFile();
3006 bool have0dField = false;
3007 if ( fields.length() > 0 )
3009 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3010 if ( shapeToMesh->_is_nil() )
3011 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3013 for ( size_t i = 0; i < fields.length(); ++i )
3015 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3016 THROW_SALOME_CORBA_EXCEPTION
3017 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3018 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3019 if ( fieldShape->_is_nil() )
3020 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3021 if ( !fieldShape->IsSame( shapeToMesh ) )
3022 THROW_SALOME_CORBA_EXCEPTION
3023 ( "Field defined not on shape", SALOME::BAD_PARAM);
3024 if ( fields[i]->GetDimension() == 0 )
3027 if ( geomAssocFields )
3028 for ( int i = 0; geomAssocFields[i]; ++i )
3029 switch ( geomAssocFields[i] ) {
3030 case 'v':case 'e':case 'f':case 's': break;
3031 case 'V':case 'E':case 'F':case 'S': break;
3032 default: THROW_SALOME_CORBA_EXCEPTION
3033 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3037 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3041 string aMeshName = "Mesh";
3042 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3043 if ( CORBA::is_nil( meshPart ) ||
3044 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3046 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3047 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3048 version, 0, autoDimension, /*addODOnVertices=*/have0dField);
3049 meshDS = _impl->GetMeshDS();
3054 _preMeshInfo->FullLoadFromFile();
3056 PrepareForWriting(file, overwrite);
3058 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
3059 if ( !aStudy->_is_nil() ) {
3060 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
3061 if ( !SO->_is_nil() ) {
3062 CORBA::String_var name = SO->GetName();
3066 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3067 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3068 version, partDS, autoDimension, /*addODOnVertices=*/have0dField);
3069 meshDS = tmpDSDeleter._obj = partDS;
3074 if ( _impl->HasShapeToMesh() )
3076 DriverMED_W_Field fieldWriter;
3077 fieldWriter.SetFile( file );
3078 fieldWriter.SetMeshName( aMeshName );
3079 fieldWriter.AddODOnVertices( have0dField );
3081 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3085 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3086 goList->length( fields.length() );
3087 for ( size_t i = 0; i < fields.length(); ++i )
3089 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3092 TPythonDump() << _this() << ".ExportPartToMED( "
3093 << meshPart << ", r'" << file << "', "
3094 << auto_groups << ", " << version << ", " << overwrite << ", "
3095 << autoDimension << ", " << goList
3096 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3098 SMESH_CATCH( SMESH::throwCorbaException );
3101 //================================================================================
3103 * Write GEOM fields to MED file
3105 //================================================================================
3107 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3108 SMESHDS_Mesh* meshDS,
3109 const GEOM::ListOfFields& fields,
3110 const char* geomAssocFields)
3112 #define METH "SMESH_Mesh_i::exportMEDFields() "
3114 if (( fields.length() < 1 ) &&
3115 ( !geomAssocFields || !geomAssocFields[0] ))
3118 std::vector< double > dblVals( meshDS->MaxShapeIndex()+1 );
3119 std::vector< int > intVals( meshDS->MaxShapeIndex()+1 );
3120 std::vector< int > subIdsByDim[ 4 ];
3121 const double noneDblValue = 0.;
3122 const double noneIntValue = 0;
3124 for ( size_t iF = 0; iF < fields.length(); ++iF )
3128 int dim = fields[ iF ]->GetDimension();
3129 SMDSAbs_ElementType elemType;
3130 TopAbs_ShapeEnum shapeType;
3132 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3133 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3134 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3135 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3137 continue; // skip fields on whole shape
3139 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3140 if ( dataType == GEOM::FDT_String )
3142 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3143 if ( stepIDs->length() < 1 )
3145 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3146 if ( comps->length() < 1 )
3148 CORBA::String_var name = fields[ iF ]->GetName();
3150 if ( !fieldWriter.Set( meshDS,
3154 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3157 for ( size_t iC = 0; iC < comps->length(); ++iC )
3158 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3160 // find sub-shape IDs
3162 std::vector< int >& subIds = subIdsByDim[ dim ];
3163 if ( subIds.empty() )
3164 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3165 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3166 subIds.push_back( id );
3170 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3174 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3176 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3177 if ( step->_is_nil() )
3180 CORBA::Long stamp = step->GetStamp();
3181 CORBA::Long id = step->GetID();
3182 fieldWriter.SetDtIt( int( stamp ), int( id ));
3184 // fill dblVals or intVals
3187 case GEOM::FDT_Double:
3189 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3190 if ( dblStep->_is_nil() ) continue;
3191 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3192 if ( vv->length() != subIds.size() )
3193 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3194 for ( size_t i = 0; i < vv->length(); ++i )
3195 dblVals[ subIds[ i ]] = vv[ i ];
3200 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3201 if ( intStep->_is_nil() ) continue;
3202 GEOM::ListOfLong_var vv = intStep->GetValues();
3203 if ( vv->length() != subIds.size() )
3204 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3205 for ( size_t i = 0; i < vv->length(); ++i )
3206 intVals[ subIds[ i ]] = (int) vv[ i ];
3209 case GEOM::FDT_Bool:
3211 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3212 if ( boolStep->_is_nil() ) continue;
3213 GEOM::short_array_var vv = boolStep->GetValues();
3214 if ( vv->length() != subIds.size() )
3215 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3216 for ( size_t i = 0; i < vv->length(); ++i )
3217 intVals[ subIds[ i ]] = (int) vv[ i ];
3223 // pass values to fieldWriter
3224 elemIt = fieldWriter.GetOrderedElems();
3225 if ( dataType == GEOM::FDT_Double )
3226 while ( elemIt->more() )
3228 const SMDS_MeshElement* e = elemIt->next();
3229 const int shapeID = e->getshapeId();
3230 if ( shapeID < 1 || shapeID >= dblVals.size() )
3231 fieldWriter.AddValue( noneDblValue );
3233 fieldWriter.AddValue( dblVals[ shapeID ]);
3236 while ( elemIt->more() )
3238 const SMDS_MeshElement* e = elemIt->next();
3239 const int shapeID = e->getshapeId();
3240 if ( shapeID < 1 || shapeID >= intVals.size() )
3241 fieldWriter.AddValue( (double) noneIntValue );
3243 fieldWriter.AddValue( (double) intVals[ shapeID ]);
3247 fieldWriter.Perform();
3248 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3249 if ( res && res->IsKO() )
3251 if ( res->myComment.empty() )
3252 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3254 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3260 if ( !geomAssocFields || !geomAssocFields[0] )
3263 // write geomAssocFields
3265 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3266 shapeDim[ TopAbs_COMPOUND ] = 3;
3267 shapeDim[ TopAbs_COMPSOLID ] = 3;
3268 shapeDim[ TopAbs_SOLID ] = 3;
3269 shapeDim[ TopAbs_SHELL ] = 2;
3270 shapeDim[ TopAbs_FACE ] = 2;
3271 shapeDim[ TopAbs_WIRE ] = 1;
3272 shapeDim[ TopAbs_EDGE ] = 1;
3273 shapeDim[ TopAbs_VERTEX ] = 0;
3274 shapeDim[ TopAbs_SHAPE ] = 3;
3276 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3278 std::vector< std::string > compNames;
3279 switch ( geomAssocFields[ iF ]) {
3281 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3282 compNames.push_back( "dim" );
3285 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3288 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3291 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3295 compNames.push_back( "id" );
3296 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3297 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3299 fieldWriter.SetDtIt( -1, -1 );
3301 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3305 if ( compNames.size() == 2 ) // _vertices_
3306 while ( elemIt->more() )
3308 const SMDS_MeshElement* e = elemIt->next();
3309 const int shapeID = e->getshapeId();
3312 fieldWriter.AddValue( (double) -1 );
3313 fieldWriter.AddValue( (double) -1 );
3317 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3318 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3319 fieldWriter.AddValue( (double) shapeID );
3323 while ( elemIt->more() )
3325 const SMDS_MeshElement* e = elemIt->next();
3326 const int shapeID = e->getshapeId();
3328 fieldWriter.AddValue( (double) -1 );
3330 fieldWriter.AddValue( (double) shapeID );
3334 fieldWriter.Perform();
3335 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3336 if ( res && res->IsKO() )
3338 if ( res->myComment.empty() )
3339 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3341 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3344 } // loop on geomAssocFields
3349 //================================================================================
3351 * \brief Export a part of mesh to a DAT file
3353 //================================================================================
3355 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3357 throw (SALOME::SALOME_Exception)
3359 Unexpect aCatch(SALOME_SalomeException);
3361 _preMeshInfo->FullLoadFromFile();
3363 PrepareForWriting(file);
3365 SMESH_MeshPartDS partDS( meshPart );
3366 _impl->ExportDAT(file,&partDS);
3368 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3369 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3371 //================================================================================
3373 * \brief Export a part of mesh to an UNV file
3375 //================================================================================
3377 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3379 throw (SALOME::SALOME_Exception)
3381 Unexpect aCatch(SALOME_SalomeException);
3383 _preMeshInfo->FullLoadFromFile();
3385 PrepareForWriting(file);
3387 SMESH_MeshPartDS partDS( meshPart );
3388 _impl->ExportUNV(file, &partDS);
3390 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3391 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3393 //================================================================================
3395 * \brief Export a part of mesh to an STL file
3397 //================================================================================
3399 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3401 ::CORBA::Boolean isascii)
3402 throw (SALOME::SALOME_Exception)
3404 Unexpect aCatch(SALOME_SalomeException);
3406 _preMeshInfo->FullLoadFromFile();
3408 PrepareForWriting(file);
3410 SMESH_MeshPartDS partDS( meshPart );
3411 _impl->ExportSTL(file, isascii, &partDS);
3413 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3414 << meshPart<< ", r'" << file << "', " << isascii << ")";
3417 //================================================================================
3419 * \brief Export a part of mesh to an STL file
3421 //================================================================================
3423 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3425 CORBA::Boolean overwrite)
3426 throw (SALOME::SALOME_Exception)
3429 Unexpect aCatch(SALOME_SalomeException);
3431 _preMeshInfo->FullLoadFromFile();
3433 PrepareForWriting(file,overwrite);
3435 SMESH_MeshPartDS partDS( meshPart );
3436 _impl->ExportCGNS(file, &partDS);
3438 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3439 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3441 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3445 //================================================================================
3447 * \brief Export a part of mesh to a GMF file
3449 //================================================================================
3451 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3453 bool withRequiredGroups)
3454 throw (SALOME::SALOME_Exception)
3456 Unexpect aCatch(SALOME_SalomeException);
3458 _preMeshInfo->FullLoadFromFile();
3460 PrepareForWriting(file,/*overwrite=*/true);
3462 SMESH_MeshPartDS partDS( meshPart );
3463 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3465 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3466 << meshPart<< ", r'"
3468 << withRequiredGroups << ")";
3471 //=============================================================================
3473 * Return computation progress [0.,1]
3475 //=============================================================================
3477 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3481 return _impl->GetComputeProgress();
3483 SMESH_CATCH( SMESH::doNothing );
3487 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3489 Unexpect aCatch(SALOME_SalomeException);
3491 return _preMeshInfo->NbNodes();
3493 return _impl->NbNodes();
3496 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3498 Unexpect aCatch(SALOME_SalomeException);
3500 return _preMeshInfo->NbElements();
3502 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3505 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3507 Unexpect aCatch(SALOME_SalomeException);
3509 return _preMeshInfo->Nb0DElements();
3511 return _impl->Nb0DElements();
3514 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3516 Unexpect aCatch(SALOME_SalomeException);
3518 return _preMeshInfo->NbBalls();
3520 return _impl->NbBalls();
3523 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3525 Unexpect aCatch(SALOME_SalomeException);
3527 return _preMeshInfo->NbEdges();
3529 return _impl->NbEdges();
3532 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3533 throw(SALOME::SALOME_Exception)
3535 Unexpect aCatch(SALOME_SalomeException);
3537 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3539 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3542 //=============================================================================
3544 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3546 Unexpect aCatch(SALOME_SalomeException);
3548 return _preMeshInfo->NbFaces();
3550 return _impl->NbFaces();
3553 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3555 Unexpect aCatch(SALOME_SalomeException);
3557 return _preMeshInfo->NbTriangles();
3559 return _impl->NbTriangles();
3562 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3564 Unexpect aCatch(SALOME_SalomeException);
3566 return _preMeshInfo->NbBiQuadTriangles();
3568 return _impl->NbBiQuadTriangles();
3571 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3573 Unexpect aCatch(SALOME_SalomeException);
3575 return _preMeshInfo->NbQuadrangles();
3577 return _impl->NbQuadrangles();
3580 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3582 Unexpect aCatch(SALOME_SalomeException);
3584 return _preMeshInfo->NbBiQuadQuadrangles();
3586 return _impl->NbBiQuadQuadrangles();
3589 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
3591 Unexpect aCatch(SALOME_SalomeException);
3593 return _preMeshInfo->NbPolygons();
3595 return _impl->NbPolygons();
3598 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3599 throw(SALOME::SALOME_Exception)
3601 Unexpect aCatch(SALOME_SalomeException);
3603 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3605 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3608 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3609 throw(SALOME::SALOME_Exception)
3611 Unexpect aCatch(SALOME_SalomeException);
3613 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3615 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3618 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3619 throw(SALOME::SALOME_Exception)
3621 Unexpect aCatch(SALOME_SalomeException);
3623 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3625 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3628 //=============================================================================
3630 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3632 Unexpect aCatch(SALOME_SalomeException);
3634 return _preMeshInfo->NbVolumes();
3636 return _impl->NbVolumes();
3639 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3641 Unexpect aCatch(SALOME_SalomeException);
3643 return _preMeshInfo->NbTetras();
3645 return _impl->NbTetras();
3648 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3650 Unexpect aCatch(SALOME_SalomeException);
3652 return _preMeshInfo->NbHexas();
3654 return _impl->NbHexas();
3657 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3659 Unexpect aCatch(SALOME_SalomeException);
3661 return _preMeshInfo->NbTriQuadHexas();
3663 return _impl->NbTriQuadraticHexas();
3666 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3668 Unexpect aCatch(SALOME_SalomeException);
3670 return _preMeshInfo->NbPyramids();
3672 return _impl->NbPyramids();
3675 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3677 Unexpect aCatch(SALOME_SalomeException);
3679 return _preMeshInfo->NbPrisms();
3681 return _impl->NbPrisms();
3684 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3686 Unexpect aCatch(SALOME_SalomeException);
3688 return _preMeshInfo->NbHexPrisms();
3690 return _impl->NbHexagonalPrisms();
3693 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3695 Unexpect aCatch(SALOME_SalomeException);
3697 return _preMeshInfo->NbPolyhedrons();
3699 return _impl->NbPolyhedrons();
3702 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3703 throw(SALOME::SALOME_Exception)
3705 Unexpect aCatch(SALOME_SalomeException);
3707 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3709 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3712 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3713 throw(SALOME::SALOME_Exception)
3715 Unexpect aCatch(SALOME_SalomeException);
3717 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3719 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3722 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3723 throw(SALOME::SALOME_Exception)
3725 Unexpect aCatch(SALOME_SalomeException);
3727 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3729 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3732 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3733 throw(SALOME::SALOME_Exception)
3735 Unexpect aCatch(SALOME_SalomeException);
3737 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3739 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3742 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3743 throw(SALOME::SALOME_Exception)
3745 Unexpect aCatch(SALOME_SalomeException);
3747 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3749 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3752 //=============================================================================
3754 * Returns nb of published sub-meshes
3756 //=============================================================================
3758 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3760 Unexpect aCatch(SALOME_SalomeException);
3761 return _mapSubMesh_i.size();
3764 //=============================================================================
3766 * Dumps mesh into a string
3768 //=============================================================================
3770 char* SMESH_Mesh_i::Dump()
3774 return CORBA::string_dup( os.str().c_str() );
3777 //=============================================================================
3779 * Method of SMESH_IDSource interface
3781 //=============================================================================
3783 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3785 return GetElementsId();
3788 //=============================================================================
3790 * Returns ids of all elements
3792 //=============================================================================
3794 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3795 throw (SALOME::SALOME_Exception)
3797 Unexpect aCatch(SALOME_SalomeException);
3799 _preMeshInfo->FullLoadFromFile();
3801 SMESH::long_array_var aResult = new SMESH::long_array();
3802 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3804 if ( aSMESHDS_Mesh == NULL )
3805 return aResult._retn();
3807 long nbElements = NbElements();
3808 aResult->length( nbElements );
3809 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3810 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3811 aResult[i] = anIt->next()->GetID();
3813 return aResult._retn();
3817 //=============================================================================
3819 * Returns ids of all elements of given type
3821 //=============================================================================
3823 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3824 throw (SALOME::SALOME_Exception)
3826 Unexpect aCatch(SALOME_SalomeException);
3828 _preMeshInfo->FullLoadFromFile();
3830 SMESH::long_array_var aResult = new SMESH::long_array();
3831 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3833 if ( aSMESHDS_Mesh == NULL )
3834 return aResult._retn();
3836 long nbElements = NbElements();
3838 // No sense in returning ids of elements along with ids of nodes:
3839 // when theElemType == SMESH::ALL, return node ids only if
3840 // there are no elements
3841 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3842 return GetNodesId();
3844 aResult->length( nbElements );
3848 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
3849 while ( i < nbElements && anIt->more() )
3850 aResult[i++] = anIt->next()->GetID();
3852 aResult->length( i );
3854 return aResult._retn();
3857 //=============================================================================
3859 * Returns ids of all nodes
3861 //=============================================================================
3863 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3864 throw (SALOME::SALOME_Exception)
3866 Unexpect aCatch(SALOME_SalomeException);
3868 _preMeshInfo->FullLoadFromFile();
3870 SMESH::long_array_var aResult = new SMESH::long_array();
3871 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3873 if ( aSMESHDS_Mesh == NULL )
3874 return aResult._retn();
3876 long nbNodes = NbNodes();
3877 aResult->length( nbNodes );
3878 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3879 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3880 aResult[i] = anIt->next()->GetID();
3882 return aResult._retn();
3885 //=============================================================================
3889 //=============================================================================
3891 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3892 throw (SALOME::SALOME_Exception)
3894 SMESH::ElementType type;
3898 _preMeshInfo->FullLoadFromFile();
3900 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
3902 SMESH_CATCH( SMESH::throwCorbaException );
3907 //=============================================================================
3911 //=============================================================================
3913 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3914 throw (SALOME::SALOME_Exception)
3917 _preMeshInfo->FullLoadFromFile();
3919 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3921 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3923 return ( SMESH::EntityType ) e->GetEntityType();
3926 //=============================================================================
3930 //=============================================================================
3932 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
3933 throw (SALOME::SALOME_Exception)
3936 _preMeshInfo->FullLoadFromFile();
3938 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3940 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3942 return ( SMESH::GeometryType ) e->GetGeomType();
3945 //=============================================================================
3947 * Returns ID of elements for given submesh
3949 //=============================================================================
3950 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3951 throw (SALOME::SALOME_Exception)
3953 SMESH::long_array_var aResult = new SMESH::long_array();
3957 _preMeshInfo->FullLoadFromFile();
3959 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3960 if(!SM) return aResult._retn();
3962 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3963 if(!SDSM) return aResult._retn();
3965 aResult->length(SDSM->NbElements());
3967 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3969 while ( eIt->more() ) {
3970 aResult[i++] = eIt->next()->GetID();
3973 SMESH_CATCH( SMESH::throwCorbaException );
3975 return aResult._retn();
3978 //=============================================================================
3980 * Returns ID of nodes for given submesh
3981 * If param all==true - returns all nodes, else -
3982 * returns only nodes on shapes.
3984 //=============================================================================
3986 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
3988 throw (SALOME::SALOME_Exception)
3990 SMESH::long_array_var aResult = new SMESH::long_array();
3994 _preMeshInfo->FullLoadFromFile();
3996 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3997 if(!SM) return aResult._retn();
3999 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4000 if(!SDSM) return aResult._retn();
4003 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4004 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4005 while ( nIt->more() ) {
4006 const SMDS_MeshNode* elem = nIt->next();
4007 theElems.insert( elem->GetID() );
4010 else { // all nodes of submesh elements
4011 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4012 while ( eIt->more() ) {
4013 const SMDS_MeshElement* anElem = eIt->next();
4014 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4015 while ( nIt->more() ) {
4016 const SMDS_MeshElement* elem = nIt->next();
4017 theElems.insert( elem->GetID() );
4022 aResult->length(theElems.size());
4023 set<int>::iterator itElem;
4025 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4026 aResult[i++] = *itElem;
4028 SMESH_CATCH( SMESH::throwCorbaException );
4030 return aResult._retn();
4033 //=============================================================================
4035 * Returns type of elements for given submesh
4037 //=============================================================================
4039 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4040 throw (SALOME::SALOME_Exception)
4042 SMESH::ElementType type;
4046 _preMeshInfo->FullLoadFromFile();
4048 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4049 if(!SM) return SMESH::ALL;
4051 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4052 if(!SDSM) return SMESH::ALL;
4054 if(SDSM->NbElements()==0)
4055 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4057 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4058 const SMDS_MeshElement* anElem = eIt->next();
4060 type = ( SMESH::ElementType ) anElem->GetType();
4062 SMESH_CATCH( SMESH::throwCorbaException );
4068 //=============================================================================
4070 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4072 //=============================================================================
4074 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4077 _preMeshInfo->FullLoadFromFile();
4079 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4081 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4086 //=============================================================================
4088 * Get XYZ coordinates of node as list of double
4089 * If there is not node for given ID - returns empty list
4091 //=============================================================================
4093 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4096 _preMeshInfo->FullLoadFromFile();
4098 SMESH::double_array_var aResult = new SMESH::double_array();
4099 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4100 if ( aSMESHDS_Mesh == NULL )
4101 return aResult._retn();
4104 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4106 return aResult._retn();
4110 aResult[0] = aNode->X();
4111 aResult[1] = aNode->Y();
4112 aResult[2] = aNode->Z();
4113 return aResult._retn();
4117 //=============================================================================
4119 * For given node returns list of IDs of inverse elements
4120 * If there is not node for given ID - returns empty list
4122 //=============================================================================
4124 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4127 _preMeshInfo->FullLoadFromFile();
4129 SMESH::long_array_var aResult = new SMESH::long_array();
4130 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4131 if ( aSMESHDS_Mesh == NULL )
4132 return aResult._retn();
4135 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4137 return aResult._retn();
4139 // find inverse elements
4140 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4141 aResult->length( aNode->NbInverseElements() );
4142 for( int i = 0; eIt->more(); ++i )
4144 const SMDS_MeshElement* elem = eIt->next();
4145 aResult[ i ] = elem->GetID();
4147 return aResult._retn();
4150 //=============================================================================
4152 * \brief Return position of a node on shape
4154 //=============================================================================
4156 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4159 _preMeshInfo->FullLoadFromFile();
4161 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4162 aNodePosition->shapeID = 0;
4163 aNodePosition->shapeType = GEOM::SHAPE;
4165 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4166 if ( !mesh ) return aNodePosition;
4168 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4170 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4172 aNodePosition->shapeID = aNode->getshapeId();
4173 switch ( pos->GetTypeOfPosition() ) {
4175 aNodePosition->shapeType = GEOM::EDGE;
4176 aNodePosition->params.length(1);
4177 aNodePosition->params[0] =
4178 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
4181 aNodePosition->shapeType = GEOM::FACE;
4182 aNodePosition->params.length(2);
4183 aNodePosition->params[0] =
4184 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
4185 aNodePosition->params[1] =
4186 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
4188 case SMDS_TOP_VERTEX:
4189 aNodePosition->shapeType = GEOM::VERTEX;
4191 case SMDS_TOP_3DSPACE:
4192 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4193 aNodePosition->shapeType = GEOM::SOLID;
4194 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4195 aNodePosition->shapeType = GEOM::SHELL;
4201 return aNodePosition;
4204 //=============================================================================
4206 * \brief Return position of an element on shape
4208 //=============================================================================
4210 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4213 _preMeshInfo->FullLoadFromFile();
4215 SMESH::ElementPosition anElementPosition;
4216 anElementPosition.shapeID = 0;
4217 anElementPosition.shapeType = GEOM::SHAPE;
4219 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4220 if ( !mesh ) return anElementPosition;
4222 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4224 anElementPosition.shapeID = anElem->getshapeId();
4225 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4226 if ( !aSp.IsNull() ) {
4227 switch ( aSp.ShapeType() ) {
4229 anElementPosition.shapeType = GEOM::EDGE;
4232 anElementPosition.shapeType = GEOM::FACE;
4235 anElementPosition.shapeType = GEOM::VERTEX;
4238 anElementPosition.shapeType = GEOM::SOLID;
4241 anElementPosition.shapeType = GEOM::SHELL;
4247 return anElementPosition;
4250 //=============================================================================
4252 * If given element is node returns IDs of shape from position
4253 * If there is not node for given ID - returns -1
4255 //=============================================================================
4257 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4260 _preMeshInfo->FullLoadFromFile();
4262 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4263 if ( aSMESHDS_Mesh == NULL )
4267 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4269 return aNode->getshapeId();
4276 //=============================================================================
4278 * For given element returns ID of result shape after
4279 * ::FindShape() from SMESH_MeshEditor
4280 * If there is not element for given ID - returns -1
4282 //=============================================================================
4284 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4287 _preMeshInfo->FullLoadFromFile();
4289 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4290 if ( aSMESHDS_Mesh == NULL )
4293 // try to find element
4294 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4298 ::SMESH_MeshEditor aMeshEditor(_impl);
4299 int index = aMeshEditor.FindShape( elem );
4307 //=============================================================================
4309 * Returns number of nodes for given element
4310 * If there is not element for given ID - returns -1
4312 //=============================================================================
4314 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4317 _preMeshInfo->FullLoadFromFile();
4319 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4320 if ( aSMESHDS_Mesh == NULL ) return -1;
4321 // try to find element
4322 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4323 if(!elem) return -1;
4324 return elem->NbNodes();
4328 //=============================================================================
4330 * Returns ID of node by given index for given element
4331 * If there is not element for given ID - returns -1
4332 * If there is not node for given index - returns -2
4334 //=============================================================================
4336 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4339 _preMeshInfo->FullLoadFromFile();
4341 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4342 if ( aSMESHDS_Mesh == NULL ) return -1;
4343 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4344 if(!elem) return -1;
4345 if( index>=elem->NbNodes() || index<0 ) return -1;
4346 return elem->GetNode(index)->GetID();
4349 //=============================================================================
4351 * Returns IDs of nodes of given element
4353 //=============================================================================
4355 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4358 _preMeshInfo->FullLoadFromFile();
4360 SMESH::long_array_var aResult = new SMESH::long_array();
4361 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4363 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
4365 aResult->length( elem->NbNodes() );
4366 for ( int i = 0; i < elem->NbNodes(); ++i )
4367 aResult[ i ] = elem->GetNode( i )->GetID();
4370 return aResult._retn();
4373 //=============================================================================
4375 * Returns true if given node is medium node
4376 * in given quadratic element
4378 //=============================================================================
4380 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4383 _preMeshInfo->FullLoadFromFile();
4385 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4386 if ( aSMESHDS_Mesh == NULL ) return false;
4388 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4389 if(!aNode) return false;
4390 // try to find element
4391 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
4392 if(!elem) return false;
4394 return elem->IsMediumNode(aNode);
4398 //=============================================================================
4400 * Returns true if given node is medium node
4401 * in one of quadratic elements
4403 //=============================================================================
4405 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4406 SMESH::ElementType theElemType)
4409 _preMeshInfo->FullLoadFromFile();
4411 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4412 if ( aSMESHDS_Mesh == NULL ) return false;
4415 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4416 if(!aNode) return false;
4418 SMESH_MesherHelper aHelper( *(_impl) );
4420 SMDSAbs_ElementType aType;
4421 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4422 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4423 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4424 else aType = SMDSAbs_All;
4426 return aHelper.IsMedium(aNode,aType);
4430 //=============================================================================
4432 * Returns number of edges for given element
4434 //=============================================================================
4436 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4439 _preMeshInfo->FullLoadFromFile();
4441 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4442 if ( aSMESHDS_Mesh == NULL ) return -1;
4443 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4444 if(!elem) return -1;
4445 return elem->NbEdges();
4449 //=============================================================================
4451 * Returns number of faces for given element
4453 //=============================================================================
4455 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4458 _preMeshInfo->FullLoadFromFile();
4460 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4461 if ( aSMESHDS_Mesh == NULL ) return -1;
4462 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4463 if(!elem) return -1;
4464 return elem->NbFaces();
4467 //=======================================================================
4468 //function : GetElemFaceNodes
4469 //purpose : Returns nodes of given face (counted from zero) for given element.
4470 //=======================================================================
4472 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4473 CORBA::Short faceIndex)
4476 _preMeshInfo->FullLoadFromFile();
4478 SMESH::long_array_var aResult = new SMESH::long_array();
4479 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4481 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4483 SMDS_VolumeTool vtool( elem );
4484 if ( faceIndex < vtool.NbFaces() )
4486 aResult->length( vtool.NbFaceNodes( faceIndex ));
4487 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4488 for ( int i = 0; i < aResult->length(); ++i )
4489 aResult[ i ] = nn[ i ]->GetID();
4493 return aResult._retn();
4496 //=======================================================================
4497 //function : GetElemFaceNodes
4498 //purpose : Returns three components of normal of given mesh face.
4499 //=======================================================================
4501 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4502 CORBA::Boolean normalized)
4505 _preMeshInfo->FullLoadFromFile();
4507 SMESH::double_array_var aResult = new SMESH::double_array();
4509 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4512 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4514 aResult->length( 3 );
4515 aResult[ 0 ] = normal.X();
4516 aResult[ 1 ] = normal.Y();
4517 aResult[ 2 ] = normal.Z();
4520 return aResult._retn();
4523 //=======================================================================
4524 //function : FindElementByNodes
4525 //purpose : Returns an element based on all given nodes.
4526 //=======================================================================
4528 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4531 _preMeshInfo->FullLoadFromFile();
4533 CORBA::Long elemID(0);
4534 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4536 vector< const SMDS_MeshNode * > nn( nodes.length() );
4537 for ( int i = 0; i < nodes.length(); ++i )
4538 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4541 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4542 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4543 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4544 _impl->NbVolumes( ORDER_QUADRATIC )))
4545 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4547 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4552 //=============================================================================
4554 * Returns true if given element is polygon
4556 //=============================================================================
4558 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4561 _preMeshInfo->FullLoadFromFile();
4563 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4564 if ( aSMESHDS_Mesh == NULL ) return false;
4565 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4566 if(!elem) return false;
4567 return elem->IsPoly();
4571 //=============================================================================
4573 * Returns true if given element is quadratic
4575 //=============================================================================
4577 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4580 _preMeshInfo->FullLoadFromFile();
4582 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4583 if ( aSMESHDS_Mesh == NULL ) return false;
4584 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4585 if(!elem) return false;
4586 return elem->IsQuadratic();
4589 //=============================================================================
4591 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4593 //=============================================================================
4595 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4598 _preMeshInfo->FullLoadFromFile();
4600 if ( const SMDS_BallElement* ball =
4601 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4602 return ball->GetDiameter();
4607 //=============================================================================
4609 * Returns bary center for given element
4611 //=============================================================================
4613 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4616 _preMeshInfo->FullLoadFromFile();
4618 SMESH::double_array_var aResult = new SMESH::double_array();
4619 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4620 if ( aSMESHDS_Mesh == NULL )
4621 return aResult._retn();
4623 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4625 return aResult._retn();
4627 if(elem->GetType()==SMDSAbs_Volume) {
4628 SMDS_VolumeTool aTool;
4629 if(aTool.Set(elem)) {
4631 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4636 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4638 double x=0., y=0., z=0.;
4639 for(; anIt->more(); ) {
4641 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4655 return aResult._retn();
4658 //================================================================================
4660 * \brief Create a group of elements preventing computation of a sub-shape
4662 //================================================================================
4664 SMESH::ListOfGroups*
4665 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4666 const char* theGroupName )
4667 throw ( SALOME::SALOME_Exception )
4669 Unexpect aCatch(SALOME_SalomeException);
4671 if ( !theGroupName || strlen( theGroupName) == 0 )
4672 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4674 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4676 // submesh by subshape id
4677 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4678 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4681 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4682 if ( error && !error->myBadElements.empty())
4684 // sort bad elements by type
4685 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4686 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4687 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4688 for ( ; elemIt != elemEnd; ++elemIt )
4690 const SMDS_MeshElement* elem = *elemIt;
4691 if ( !elem ) continue;
4693 if ( elem->GetID() < 1 )
4695 // elem is a temporary element, make a real element
4696 vector< const SMDS_MeshNode* > nodes;
4697 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4698 while ( nIt->more() && elem )
4700 nodes.push_back( nIt->next() );
4701 if ( nodes.back()->GetID() < 1 )
4702 elem = 0; // a temporary element on temporary nodes
4706 ::SMESH_MeshEditor editor( _impl );
4707 elem = editor.AddElement( nodes, elem->GetType(), elem->IsPoly() );
4711 elemsByType[ elem->GetType() ].push_back( elem );
4714 // how many groups to create?
4716 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4717 nbTypes += int( !elemsByType[ i ].empty() );
4718 groups->length( nbTypes );
4721 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4723 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4724 if ( elems.empty() ) continue;
4726 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4727 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4729 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
4730 SMESH::SMESH_Mesh_var mesh = _this();
4731 SALOMEDS::SObject_wrap aSO =
4732 _gen_i->PublishGroup( study, mesh, groups[ iG ],
4733 GEOM::GEOM_Object::_nil(), theGroupName);
4734 aSO->_is_nil(); // avoid "unused variable" warning
4736 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4737 if ( !grp_i ) continue;
4739 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4740 for ( size_t iE = 0; iE < elems.size(); ++iE )
4741 grpDS->SMDSGroup().Add( elems[ iE ]);
4746 return groups._retn();
4749 //=============================================================================
4751 * Create and publish group servants if any groups were imported or created anyhow
4753 //=============================================================================
4755 void SMESH_Mesh_i::CreateGroupServants()
4757 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4758 SMESH::SMESH_Mesh_var aMesh = _this();
4761 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4762 while ( groupIt->more() )
4764 ::SMESH_Group* group = groupIt->next();
4765 int anId = group->GetGroupDS()->GetID();
4767 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4768 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4770 addedIDs.insert( anId );
4772 SMESH_GroupBase_i* aGroupImpl;
4774 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4775 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4777 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4778 shape = groupOnGeom->GetShape();
4781 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4784 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
4785 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4786 aGroupImpl->Register();
4788 // register CORBA object for persistence
4789 int nextId = _gen_i->RegisterObject( groupVar );
4790 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4791 else { nextId = 0; } // avoid "unused variable" warning in release mode
4793 // publishing the groups in the study
4794 if ( !aStudy->_is_nil() ) {
4795 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4796 _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName());
4799 if ( !addedIDs.empty() )
4802 set<int>::iterator id = addedIDs.begin();
4803 for ( ; id != addedIDs.end(); ++id )
4805 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4806 int i = std::distance( _mapGroups.begin(), it );
4807 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
4812 //=============================================================================
4814 * \brief Return groups cantained in _mapGroups by their IDs
4816 //=============================================================================
4818 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4820 int nbGroups = groupIDs.size();
4821 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4822 aList->length( nbGroups );
4824 list<int>::const_iterator ids = groupIDs.begin();
4825 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4827 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4828 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4829 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4831 aList->length( nbGroups );
4832 return aList._retn();
4835 //=============================================================================
4837 * \brief Return information about imported file
4839 //=============================================================================
4841 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
4843 SMESH::MedFileInfo_var res( _medFileInfo );
4844 if ( !res.operator->() ) {
4845 res = new SMESH::MedFileInfo;
4847 res->fileSize = res->major = res->minor = res->release = -1;
4852 //=============================================================================
4854 * \brief Pass names of mesh groups from study to mesh DS
4856 //=============================================================================
4858 void SMESH_Mesh_i::checkGroupNames()
4860 int nbGrp = NbGroups();
4864 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4865 if ( aStudy->_is_nil() )
4866 return; // nothing to do
4868 SMESH::ListOfGroups* grpList = 0;
4869 // avoid dump of "GetGroups"
4871 // store python dump into a local variable inside local scope
4872 SMESH::TPythonDump pDump; // do not delete this line of code
4873 grpList = GetGroups();
4876 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
4877 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
4880 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
4881 if ( aGrpSO->_is_nil() )
4883 // correct name of the mesh group if necessary
4884 const char* guiName = aGrpSO->GetName();
4885 if ( strcmp(guiName, aGrp->GetName()) )
4886 aGrp->SetName( guiName );
4890 //=============================================================================
4892 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
4894 //=============================================================================
4895 void SMESH_Mesh_i::SetParameters(const char* theParameters)
4897 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
4901 //=============================================================================
4903 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
4905 //=============================================================================
4907 char* SMESH_Mesh_i::GetParameters()
4909 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
4912 //=============================================================================
4914 * \brief Returns list of notebook variables used for last Mesh operation
4916 //=============================================================================
4917 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
4919 SMESH::string_array_var aResult = new SMESH::string_array();
4920 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4922 CORBA::String_var aParameters = GetParameters();
4923 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
4924 if ( !aStudy->_is_nil()) {
4925 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
4926 if(aSections->length() > 0) {
4927 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
4928 aResult->length(aVars.length());
4929 for(int i = 0;i < aVars.length();i++)
4930 aResult[i] = CORBA::string_dup( aVars[i]);
4934 return aResult._retn();
4937 //=======================================================================
4938 //function : GetTypes
4939 //purpose : Returns types of elements it contains
4940 //=======================================================================
4942 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
4945 return _preMeshInfo->GetTypes();
4947 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
4951 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
4952 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
4953 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
4954 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
4955 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
4956 types->length( nbTypes );
4958 return types._retn();
4961 //=======================================================================
4962 //function : GetMesh
4963 //purpose : Returns self
4964 //=======================================================================
4966 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
4968 return SMESH::SMESH_Mesh::_duplicate( _this() );
4971 //=======================================================================
4972 //function : IsMeshInfoCorrect
4973 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
4974 // * happen if mesh data is not yet fully loaded from the file of study.
4975 //=======================================================================
4977 bool SMESH_Mesh_i::IsMeshInfoCorrect()
4979 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
4982 //=============================================================================
4984 * \brief Returns number of mesh elements per each \a EntityType
4986 //=============================================================================
4988 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
4991 return _preMeshInfo->GetMeshInfo();
4993 SMESH::long_array_var aRes = new SMESH::long_array();
4994 aRes->length(SMESH::Entity_Last);
4995 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4997 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4999 return aRes._retn();
5000 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5001 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5002 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5003 return aRes._retn();
5006 //=============================================================================
5008 * \brief Returns number of mesh elements per each \a ElementType
5010 //=============================================================================
5012 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5014 SMESH::long_array_var aRes = new SMESH::long_array();
5015 aRes->length(SMESH::NB_ELEMENT_TYPES);
5016 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5019 const SMDS_MeshInfo* meshInfo = 0;
5021 meshInfo = _preMeshInfo;
5022 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5023 meshInfo = & meshDS->GetMeshInfo();
5026 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5027 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5029 return aRes._retn();
5032 //=============================================================================
5034 * Collect statistic of mesh elements given by iterator
5036 //=============================================================================
5038 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5039 SMESH::long_array& theInfo)
5041 if (!theItr) return;
5042 while (theItr->more())
5043 theInfo[ theItr->next()->GetEntityType() ]++;
5046 //=============================================================================
5047 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5048 * SMESH::ElementType type) */
5050 using namespace SMESH::Controls;
5051 //-----------------------------------------------------------------------------
5052 struct PredicateIterator : public SMDS_ElemIterator
5054 SMDS_ElemIteratorPtr _elemIter;
5055 PredicatePtr _predicate;
5056 const SMDS_MeshElement* _elem;
5058 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5059 PredicatePtr predicate):
5060 _elemIter(iterator), _predicate(predicate)
5068 virtual const SMDS_MeshElement* next()
5070 const SMDS_MeshElement* res = _elem;
5072 while ( _elemIter->more() && !_elem )
5074 _elem = _elemIter->next();
5075 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5082 //-----------------------------------------------------------------------------
5083 struct IDSourceIterator : public SMDS_ElemIterator
5085 const CORBA::Long* _idPtr;
5086 const CORBA::Long* _idEndPtr;
5087 SMESH::long_array_var _idArray;
5088 const SMDS_Mesh* _mesh;
5089 const SMDSAbs_ElementType _type;
5090 const SMDS_MeshElement* _elem;
5092 IDSourceIterator( const SMDS_Mesh* mesh,
5093 const CORBA::Long* ids,
5095 SMDSAbs_ElementType type):
5096 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5098 if ( _idPtr && nbIds && _mesh )
5101 IDSourceIterator( const SMDS_Mesh* mesh,
5102 SMESH::long_array* idArray,
5103 SMDSAbs_ElementType type):
5104 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5106 if ( idArray && _mesh )
5108 _idPtr = &_idArray[0];
5109 _idEndPtr = _idPtr + _idArray->length();
5117 virtual const SMDS_MeshElement* next()
5119 const SMDS_MeshElement* res = _elem;
5121 while ( _idPtr < _idEndPtr && !_elem )
5123 if ( _type == SMDSAbs_Node )
5125 _elem = _mesh->FindNode( *_idPtr++ );
5127 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5128 _elem->GetType() != _type )
5136 //-----------------------------------------------------------------------------
5138 struct NodeOfElemIterator : public SMDS_ElemIterator
5140 TColStd_MapOfInteger _checkedNodeIDs;
5141 SMDS_ElemIteratorPtr _elemIter;
5142 SMDS_ElemIteratorPtr _nodeIter;
5143 const SMDS_MeshElement* _node;
5145 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5147 if ( _elemIter && _elemIter->more() )
5149 _nodeIter = _elemIter->next()->nodesIterator();
5157 virtual const SMDS_MeshElement* next()
5159 const SMDS_MeshElement* res = _node;
5161 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
5163 if ( _nodeIter->more() )
5165 _node = _nodeIter->next();
5166 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5171 _nodeIter = _elemIter->next()->nodesIterator();
5179 //=============================================================================
5181 * Return iterator on elements of given type in given object
5183 //=============================================================================
5185 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5186 SMESH::ElementType theType)
5188 SMDS_ElemIteratorPtr elemIt;
5189 bool typeOK = false;
5190 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5192 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5193 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5194 if ( !mesh_i ) return elemIt;
5195 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5197 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5199 elemIt = meshDS->elementsIterator( elemType );
5202 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5204 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5207 elemIt = sm->GetElements();
5208 if ( elemType != SMDSAbs_Node )
5210 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5211 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5215 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5217 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5218 if ( groupDS && ( groupDS->GetType() == elemType || elemType == SMDSAbs_Node ))
5220 elemIt = groupDS->GetElements();
5221 typeOK = ( groupDS->GetType() == elemType );
5224 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5226 if ( filter_i->GetElementType() == theType || elemType == SMDSAbs_Node )
5228 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5229 if ( pred_i && pred_i->GetPredicate() )
5231 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5232 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5233 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5234 typeOK = ( filterType == elemType );
5240 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5241 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5242 if ( isNodes && elemType != SMDSAbs_Node )
5244 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5247 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5248 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5252 SMESH::long_array_var ids = theObject->GetIDs();
5253 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5255 typeOK = ( isNodes == ( elemType == SMDSAbs_Node ));
5258 if ( elemIt && elemIt->more() && !typeOK )
5260 if ( elemType == SMDSAbs_Node )
5262 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5266 elemIt = SMDS_ElemIteratorPtr();
5272 //=============================================================================
5273 namespace // Finding concurrent hypotheses
5274 //=============================================================================
5278 * \brief mapping of mesh dimension into shape type
5280 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5282 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5284 case 0: aType = TopAbs_VERTEX; break;
5285 case 1: aType = TopAbs_EDGE; break;
5286 case 2: aType = TopAbs_FACE; break;
5288 default:aType = TopAbs_SOLID; break;
5293 //-----------------------------------------------------------------------------
5295 * \brief Internal structure used to find concurent submeshes
5297 * It represents a pair < submesh, concurent dimension >, where
5298 * 'concurrent dimension' is dimension of shape where the submesh can concurent
5299 * with another submesh. In other words, it is dimension of a hypothesis assigned
5306 int _dim; //!< a dimension the algo can build (concurrent dimension)
5307 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5308 TopTools_MapOfShape _shapeMap;
5309 SMESH_subMesh* _subMesh;
5310 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5312 //-----------------------------------------------------------------------------
5313 // Return the algorithm
5314 const SMESH_Algo* GetAlgo() const
5315 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5317 //-----------------------------------------------------------------------------
5319 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5321 const TopoDS_Shape& theShape)
5323 _subMesh = (SMESH_subMesh*)theSubMesh;
5324 SetShape( theDim, theShape );
5327 //-----------------------------------------------------------------------------
5329 void SetShape(const int theDim,
5330 const TopoDS_Shape& theShape)
5333 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5334 if (_dim >= _ownDim)
5335 _shapeMap.Add( theShape );
5337 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5338 for( ; anExp.More(); anExp.Next() )
5339 _shapeMap.Add( anExp.Current() );
5343 //-----------------------------------------------------------------------------
5344 //! Check sharing of sub-shapes
5345 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5346 const TopTools_MapOfShape& theToFind,
5347 const TopAbs_ShapeEnum theType)
5349 bool isShared = false;
5350 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5351 for (; !isShared && anItr.More(); anItr.Next() )
5353 const TopoDS_Shape aSubSh = anItr.Key();
5354 // check for case when concurrent dimensions are same
5355 isShared = theToFind.Contains( aSubSh );
5356 // check for sub-shape with concurrent dimension
5357 TopExp_Explorer anExp( aSubSh, theType );
5358 for ( ; !isShared && anExp.More(); anExp.Next() )
5359 isShared = theToFind.Contains( anExp.Current() );
5364 //-----------------------------------------------------------------------------
5365 //! check algorithms
5366 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5367 const SMESHDS_Hypothesis* theA2)
5369 if ( !theA1 || !theA2 ||
5370 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5371 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5372 return false; // one of the hypothesis is not algorithm
5373 // check algorithm names (should be equal)
5374 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5378 //-----------------------------------------------------------------------------
5379 //! Check if sub-shape hypotheses are concurrent
5380 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5382 if ( _subMesh == theOther->_subMesh )
5383 return false; // same sub-shape - should not be
5385 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5386 // any of the two submeshes is not on COMPOUND shape )
5387 // -> no concurrency
5388 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5389 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5390 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5391 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5392 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5395 // bool checkSubShape = ( _dim >= theOther->_dim )
5396 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5397 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5398 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5399 if ( !checkSubShape )
5402 // check algorithms to be same
5403 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5404 return true; // different algorithms -> concurrency !
5406 // check hypothesises for concurrence (skip first as algorithm)
5408 // pointers should be same, because it is referened from mesh hypothesis partition
5409 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5410 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5411 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5412 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5414 // the submeshes are concurrent if their algorithms has different parameters
5415 return nbSame != theOther->_hypotheses.size() - 1;
5418 // Return true if algorithm of this SMESH_DimHyp is used if no
5419 // sub-mesh order is imposed by the user
5420 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5422 // NeedDiscreteBoundary() algo has a higher priority
5423 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5424 theOther->GetAlgo()->NeedDiscreteBoundary() )
5425 return !this->GetAlgo()->NeedDiscreteBoundary();
5427 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5430 }; // end of SMESH_DimHyp
5431 //-----------------------------------------------------------------------------
5433 typedef list<const SMESH_DimHyp*> TDimHypList;
5435 //-----------------------------------------------------------------------------
5437 void addDimHypInstance(const int theDim,
5438 const TopoDS_Shape& theShape,
5439 const SMESH_Algo* theAlgo,
5440 const SMESH_subMesh* theSubMesh,
5441 const list <const SMESHDS_Hypothesis*>& theHypList,
5442 TDimHypList* theDimHypListArr )
5444 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5445 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5446 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5447 dimHyp->_hypotheses.push_front(theAlgo);
5448 listOfdimHyp.push_back( dimHyp );
5451 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5452 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5453 theHypList.begin(), theHypList.end() );
5456 //-----------------------------------------------------------------------------
5457 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5458 TDimHypList& theListOfConcurr)
5460 if ( theListOfConcurr.empty() )
5462 theListOfConcurr.push_back( theDimHyp );
5466 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5467 while ( hypIt != theListOfConcurr.end() &&
5468 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5470 theListOfConcurr.insert( hypIt, theDimHyp );
5474 //-----------------------------------------------------------------------------
5475 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5476 const TDimHypList& theListOfDimHyp,
5477 TDimHypList& theListOfConcurrHyp,
5478 set<int>& theSetOfConcurrId )
5480 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5481 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5483 const SMESH_DimHyp* curDimHyp = *rIt;
5484 if ( curDimHyp == theDimHyp )
5485 break; // meet own dimHyp pointer in same dimension
5487 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5488 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5490 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5495 //-----------------------------------------------------------------------------
5496 void unionLists(TListOfInt& theListOfId,
5497 TListOfListOfInt& theListOfListOfId,
5500 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5501 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5503 continue; //skip already treated lists
5504 // check if other list has any same submesh object
5505 TListOfInt& otherListOfId = *it;
5506 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5507 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5510 // union two lists (from source into target)
5511 TListOfInt::iterator it2 = otherListOfId.begin();
5512 for ( ; it2 != otherListOfId.end(); it2++ ) {
5513 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5514 theListOfId.push_back(*it2);
5516 // clear source list
5517 otherListOfId.clear();
5520 //-----------------------------------------------------------------------------
5522 //! free memory allocated for dimension-hypothesis objects
5523 void removeDimHyps( TDimHypList* theArrOfList )
5525 for (int i = 0; i < 4; i++ ) {
5526 TDimHypList& listOfdimHyp = theArrOfList[i];
5527 TDimHypList::const_iterator it = listOfdimHyp.begin();
5528 for ( ; it != listOfdimHyp.end(); it++ )
5533 //-----------------------------------------------------------------------------
5535 * \brief find common submeshes with given submesh
5536 * \param theSubMeshList list of already collected submesh to check
5537 * \param theSubMesh given submesh to intersect with other
5538 * \param theCommonSubMeshes collected common submeshes
5540 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5541 const SMESH_subMesh* theSubMesh,
5542 set<const SMESH_subMesh*>& theCommon )
5546 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5547 for ( ; it != theSubMeshList.end(); it++ )
5548 theSubMesh->FindIntersection( *it, theCommon );
5549 theSubMeshList.push_back( theSubMesh );
5550 //theCommon.insert( theSubMesh );
5553 //-----------------------------------------------------------------------------
5554 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5556 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5557 for ( ; listsIt != smLists.end(); ++listsIt )
5559 const TListOfInt& smIDs = *listsIt;
5560 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5568 //=============================================================================
5570 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5572 //=============================================================================
5574 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5576 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5577 if ( isSubMeshInList( submeshID, anOrder ))
5580 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5581 return isSubMeshInList( submeshID, allConurrent );
5584 //=============================================================================
5586 * \brief Return submesh objects list in meshing order
5588 //=============================================================================
5590 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5592 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5594 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5596 return aResult._retn();
5598 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5599 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5600 anOrder.splice( anOrder.end(), allConurrent );
5603 TListOfListOfInt::iterator listIt = anOrder.begin();
5604 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5605 unionLists( *listIt, anOrder, listIndx + 1 );
5607 // convert submesh ids into interface instances
5608 // and dump command into python
5609 convertMeshOrder( anOrder, aResult, false );
5611 return aResult._retn();
5614 //=============================================================================
5616 * \brief Finds concurrent sub-meshes
5618 //=============================================================================
5620 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5622 TListOfListOfInt anOrder;
5623 ::SMESH_Mesh& mesh = GetImpl();
5625 // collect submeshes and detect concurrent algorithms and hypothesises
5626 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5628 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5629 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5630 ::SMESH_subMesh* sm = (*i_sm).second;
5632 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5634 // list of assigned hypothesises
5635 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5636 // Find out dimensions where the submesh can be concurrent.
5637 // We define the dimensions by algo of each of hypotheses in hypList
5638 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5639 for( ; hypIt != hypList.end(); hypIt++ ) {
5640 SMESH_Algo* anAlgo = 0;
5641 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5642 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5643 // hyp it-self is algo
5644 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5646 // try to find algorithm with help of sub-shapes
5647 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5648 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5649 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5652 continue; // no algorithm assigned to a current submesh
5654 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5655 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5657 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5658 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5659 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5661 } // end iterations on submesh
5663 // iterate on created dimension-hypotheses and check for concurrents
5664 for ( int i = 0; i < 4; i++ ) {
5665 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5666 // check for concurrents in own and other dimensions (step-by-step)
5667 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5668 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5669 const SMESH_DimHyp* dimHyp = *dhIt;
5670 TDimHypList listOfConcurr;
5671 set<int> setOfConcurrIds;
5672 // looking for concurrents and collect into own list
5673 for ( int j = i; j < 4; j++ )
5674 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5675 // check if any concurrents found
5676 if ( listOfConcurr.size() > 0 ) {
5677 // add own submesh to list of concurrent
5678 addInOrderOfPriority( dimHyp, listOfConcurr );
5679 list<int> listOfConcurrIds;
5680 TDimHypList::iterator hypIt = listOfConcurr.begin();
5681 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5682 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5683 anOrder.push_back( listOfConcurrIds );
5688 removeDimHyps(dimHypListArr);
5690 // now, minimise the number of concurrent groups
5691 // Here we assume that lists of submeshes can have same submesh
5692 // in case of multi-dimension algorithms, as result
5693 // list with common submesh has to be united into one list
5695 TListOfListOfInt::iterator listIt = anOrder.begin();
5696 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5697 unionLists( *listIt, anOrder, listIndx + 1 );
5703 //=============================================================================
5705 * \brief Set submesh object order
5706 * \param theSubMeshArray submesh array order
5708 //=============================================================================
5710 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5713 _preMeshInfo->ForgetOrLoad();
5716 ::SMESH_Mesh& mesh = GetImpl();
5718 TPythonDump aPythonDump; // prevent dump of called methods
5719 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5721 TListOfListOfInt subMeshOrder;
5722 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5724 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5725 TListOfInt subMeshIds;
5726 aPythonDump << "[ ";
5727 // Collect subMeshes which should be clear
5728 // do it list-by-list, because modification of submesh order
5729 // take effect between concurrent submeshes only
5730 set<const SMESH_subMesh*> subMeshToClear;
5731 list<const SMESH_subMesh*> subMeshList;
5732 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5734 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5736 aPythonDump << ", ";
5737 aPythonDump << subMesh;
5738 subMeshIds.push_back( subMesh->GetId() );
5739 // detect common parts of submeshes
5740 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5741 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5743 aPythonDump << " ]";
5744 subMeshOrder.push_back( subMeshIds );
5746 // clear collected submeshes
5747 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
5748 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
5749 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
5750 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
5752 aPythonDump << " ])";
5754 mesh.SetMeshOrder( subMeshOrder );
5760 //=============================================================================
5762 * \brief Convert submesh ids into submesh interfaces
5764 //=============================================================================
5766 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
5767 SMESH::submesh_array_array& theResOrder,
5768 const bool theIsDump)
5770 int nbSet = theIdsOrder.size();
5771 TPythonDump aPythonDump; // prevent dump of called methods
5773 aPythonDump << "[ ";
5774 theResOrder.length(nbSet);
5775 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
5777 for( ; it != theIdsOrder.end(); it++ ) {
5778 // translate submesh identificators into submesh objects
5779 // takeing into account real number of concurrent lists
5780 const TListOfInt& aSubOrder = (*it);
5781 if (!aSubOrder.size())
5784 aPythonDump << "[ ";
5785 // convert shape indeces into interfaces
5786 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
5787 aResSubSet->length(aSubOrder.size());
5788 TListOfInt::const_iterator subIt = aSubOrder.begin();
5790 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
5791 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
5793 SMESH::SMESH_subMesh_var subMesh =
5794 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
5797 aPythonDump << ", ";
5798 aPythonDump << subMesh;
5800 aResSubSet[ j++ ] = subMesh;
5803 aPythonDump << " ]";
5805 theResOrder[ listIndx++ ] = aResSubSet;
5807 // correct number of lists
5808 theResOrder.length( listIndx );
5811 // finilise python dump
5812 aPythonDump << " ]";
5813 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
5817 //================================================================================
5819 // Implementation of SMESH_MeshPartDS
5821 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
5822 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
5824 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
5825 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
5827 _meshDS = mesh_i->GetImpl().GetMeshDS();
5829 SetPersistentId( _meshDS->GetPersistentId() );
5831 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
5833 // <meshPart> is the whole mesh
5834 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
5836 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
5837 myGroupSet = _meshDS->GetGroups();
5842 SMESH::long_array_var anIDs = meshPart->GetIDs();
5843 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
5844 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
5846 for (int i=0; i < anIDs->length(); i++)
5847 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
5848 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5853 for (int i=0; i < anIDs->length(); i++)
5854 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
5855 if ( _elements[ e->GetType() ].insert( e ).second )
5858 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5859 while ( nIt->more() )
5861 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5862 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5869 _meshDS = 0; // to enforce iteration on _elements and _nodes
5872 // -------------------------------------------------------------------------------------
5873 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
5874 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
5877 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
5878 for ( ; partIt != meshPart.end(); ++partIt )
5879 if ( const SMDS_MeshElement * e = *partIt )
5880 if ( _elements[ e->GetType() ].insert( e ).second )
5883 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5884 while ( nIt->more() )
5886 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5887 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5893 // -------------------------------------------------------------------------------------
5894 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
5896 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
5898 typedef SMDS_SetIterator
5899 <const SMDS_MeshElement*,
5900 TIDSortedElemSet::const_iterator,
5901 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5902 SMDS_MeshElement::GeomFilter
5905 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
5907 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5908 _elements[type].end(),
5909 SMDS_MeshElement::GeomFilter( geomType )));
5911 // -------------------------------------------------------------------------------------
5912 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
5914 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
5916 typedef SMDS_SetIterator
5917 <const SMDS_MeshElement*,
5918 TIDSortedElemSet::const_iterator,
5919 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5920 SMDS_MeshElement::EntityFilter
5923 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
5925 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5926 _elements[type].end(),
5927 SMDS_MeshElement::EntityFilter( entity )));
5929 // -------------------------------------------------------------------------------------
5930 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
5932 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5933 if ( type == SMDSAbs_All && !_meshDS )
5935 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
5937 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5938 if ( !_elements[i].empty() && i != SMDSAbs_Node )
5940 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
5942 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
5943 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
5945 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
5946 ( new TIter( _elements[type].begin(), _elements[type].end() ));
5948 // -------------------------------------------------------------------------------------
5949 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
5950 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
5952 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
5953 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
5954 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
5956 // -------------------------------------------------------------------------------------
5957 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
5958 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
5959 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
5960 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
5961 #undef _GET_ITER_DEFINE
5963 // END Implementation of SMESH_MeshPartDS
5965 //================================================================================