1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_Mesh_i.cxx
23 // Author : Paul RASCLE, EDF
26 #include "SMESH_Mesh_i.hxx"
28 #include "DriverMED_R_SMESHDS_Mesh.h"
29 #include "DriverMED_W_Field.h"
30 #include "DriverMED_W_SMESHDS_Mesh.h"
31 #include "MED_Factory.hxx"
32 #include "SMDS_LinearEdge.hxx"
33 #include "SMDS_EdgePosition.hxx"
34 #include "SMDS_ElemIterator.hxx"
35 #include "SMDS_FacePosition.hxx"
36 #include "SMDS_IteratorOnIterators.hxx"
37 #include "SMDS_MeshGroup.hxx"
38 #include "SMDS_SetIterator.hxx"
39 #include "SMDS_StdIterator.hxx"
40 #include "SMDS_VolumeTool.hxx"
41 #include "SMESHDS_Command.hxx"
42 #include "SMESHDS_CommandType.hxx"
43 #include "SMESHDS_Group.hxx"
44 #include "SMESHDS_GroupOnGeom.hxx"
45 #include "SMESH_Controls.hxx"
46 #include "SMESH_File.hxx"
47 #include "SMESH_Filter_i.hxx"
48 #include "SMESH_Gen_i.hxx"
49 #include "SMESH_Group.hxx"
50 #include "SMESH_Group_i.hxx"
51 #include "SMESH_Mesh.hxx"
52 #include "SMESH_MeshAlgos.hxx"
53 #include "SMESH_MeshEditor.hxx"
54 #include "SMESH_MeshEditor_i.hxx"
55 #include "SMESH_MeshPartDS.hxx"
56 #include "SMESH_MesherHelper.hxx"
57 #include "SMESH_PreMeshInfo.hxx"
58 #include "SMESH_PythonDump.hxx"
59 #include "SMESH_subMesh_i.hxx"
61 #include <SALOMEDS_Attributes_wrap.hxx>
62 #include <SALOMEDS_wrap.hxx>
63 #include <Utils_ExceptHandlers.hxx>
64 #include <utilities.h>
66 #include <GEOMImpl_Types.hxx>
67 #include <GEOM_wrap.hxx>
70 #include <BRep_Builder.hxx>
71 #include <Standard_ErrorHandler.hxx>
72 #include <TColStd_MapOfInteger.hxx>
74 #include <TopExp_Explorer.hxx>
75 #include <TopTools_MapIteratorOfMapOfShape.hxx>
76 #include <TopTools_MapOfShape.hxx>
77 #include <TopoDS_Compound.hxx>
84 #include <vtkUnstructuredGridWriter.h>
86 // to pass CORBA exception through SMESH_TRY
87 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
89 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
92 static int MYDEBUG = 0;
94 static int MYDEBUG = 0;
98 using SMESH::TPythonDump;
101 int SMESH_Mesh_i::_idGenerator = 0;
103 //=============================================================================
107 //=============================================================================
109 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
111 : SALOME::GenericObj_i( thePOA )
115 _id = _idGenerator++;
117 _previewEditor = NULL;
122 //=============================================================================
126 //=============================================================================
128 SMESH_Mesh_i::~SMESH_Mesh_i()
131 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
132 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
133 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
135 aGroup->UnRegister();
136 SMESH::SMESH_GroupBase_var( itGr->second );
141 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
142 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
143 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
145 aSubMesh->UnRegister();
146 SMESH::SMESH_subMesh_var( itSM->second );
148 _mapSubMeshIor.clear();
150 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
151 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
152 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
153 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
154 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
155 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
158 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
162 // clear cached shapes if no more meshes remain; (the cache is blame,
163 // together with publishing, of spent time increasing in issue 22874)
164 if ( _impl->NbMeshes() == 1 )
165 _gen_i->GetShapeReader()->ClearClientBuffer();
167 delete _editor; _editor = NULL;
168 delete _previewEditor; _previewEditor = NULL;
169 delete _impl; _impl = NULL;
170 delete _preMeshInfo; _preMeshInfo = NULL;
173 //=============================================================================
177 * Associates <this> mesh with <theShape> and puts a reference
178 * to <theShape> into the current study;
179 * the previous shape is substituted by the new one.
181 //=============================================================================
183 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
184 throw (SALOME::SALOME_Exception)
186 Unexpect aCatch(SALOME_SalomeException);
188 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
190 catch(SALOME_Exception & S_ex) {
191 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
193 // to track changes of GEOM groups
194 SMESH::SMESH_Mesh_var mesh = _this();
195 addGeomGroupData( theShapeObject, mesh );
196 if ( !CORBA::is_nil( theShapeObject ))
197 _mainShapeTick = theShapeObject->GetTick();
200 //================================================================================
202 * \brief return true if mesh has a shape to build a shape on
204 //================================================================================
206 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
207 throw (SALOME::SALOME_Exception)
209 Unexpect aCatch(SALOME_SalomeException);
212 res = _impl->HasShapeToMesh();
214 catch(SALOME_Exception & S_ex) {
215 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
220 //=======================================================================
221 //function : GetShapeToMesh
223 //=======================================================================
225 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
226 throw (SALOME::SALOME_Exception)
228 Unexpect aCatch(SALOME_SalomeException);
229 GEOM::GEOM_Object_var aShapeObj;
231 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
234 aShapeObj = _gen_i->ShapeToGeomObject( S );
235 if ( aShapeObj->_is_nil() )
237 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
238 // find GEOM_Object by entry (IPAL52735)
239 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
240 for ( ; data != _geomGroupData.end(); ++data )
241 if ( data->_smeshObject->_is_equivalent( _this() ))
243 SALOMEDS::SObject_wrap so = SMESH_Gen_i::getStudyServant()->FindObjectID( data->_groupEntry.c_str() );
244 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
245 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
251 catch(SALOME_Exception & S_ex) {
252 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
254 return aShapeObj._retn();
257 //================================================================================
259 * \brief Return false if the mesh is not yet fully loaded from the study file
261 //================================================================================
263 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
265 Unexpect aCatch(SALOME_SalomeException);
266 return !_preMeshInfo;
269 //================================================================================
271 * \brief Load full mesh data from the study file
273 //================================================================================
275 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
277 Unexpect aCatch(SALOME_SalomeException);
279 _preMeshInfo->FullLoadFromFile();
282 //================================================================================
284 * \brief Remove all nodes and elements
286 //================================================================================
288 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
290 Unexpect aCatch(SALOME_SalomeException);
292 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
296 //CheckGeomGroupModif(); // issue 20145
298 catch(SALOME_Exception & S_ex) {
299 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
302 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
304 SMESH::SMESH_Mesh_var mesh = _this();
305 _gen_i->UpdateIcons( mesh );
308 //================================================================================
310 * \brief Remove all nodes and elements for indicated shape
312 //================================================================================
314 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
315 throw (SALOME::SALOME_Exception)
317 Unexpect aCatch(SALOME_SalomeException);
319 _preMeshInfo->FullLoadFromFile();
322 _impl->ClearSubMesh( ShapeID );
324 catch(SALOME_Exception & S_ex) {
325 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
327 _impl->GetMeshDS()->Modified();
329 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
332 //=============================================================================
334 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
336 //=============================================================================
338 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
340 SMESH::DriverMED_ReadStatus res;
343 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
344 res = SMESH::DRS_OK; break;
345 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
346 res = SMESH::DRS_EMPTY; break;
347 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
348 res = SMESH::DRS_WARN_RENUMBER; break;
349 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
350 res = SMESH::DRS_WARN_SKIP_ELEM; break;
351 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
352 res = SMESH::DRS_WARN_DESCENDING; break;
353 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
355 res = SMESH::DRS_FAIL; break;
360 //=============================================================================
362 * Convert ::SMESH_ComputeError to SMESH::ComputeError
364 //=============================================================================
366 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
368 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
369 errVar->subShapeID = -1;
370 errVar->hasBadMesh = false;
372 if ( !errorPtr || errorPtr->IsOK() )
374 errVar->code = SMESH::COMPERR_OK;
378 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
379 errVar->comment = errorPtr->myComment.c_str();
381 return errVar._retn();
384 //=============================================================================
388 * Imports mesh data from MED file
390 //=============================================================================
392 SMESH::DriverMED_ReadStatus
393 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
394 throw ( SALOME::SALOME_Exception )
396 Unexpect aCatch(SALOME_SalomeException);
399 status = _impl->MEDToMesh( theFileName, theMeshName );
401 catch( SALOME_Exception& S_ex ) {
402 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
405 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
408 CreateGroupServants();
410 int major, minor, release;
411 major = minor = release = 0;
412 MED::GetMEDVersion(theFileName, major, minor, release);
413 _medFileInfo = new SMESH::MedFileInfo();
414 _medFileInfo->fileName = theFileName;
415 _medFileInfo->fileSize = 0;
416 _medFileInfo->major = major;
417 _medFileInfo->minor = minor;
418 _medFileInfo->release = release;
419 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
421 return ConvertDriverMEDReadStatus(status);
424 //================================================================================
426 * \brief Imports mesh data from the CGNS file
428 //================================================================================
430 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
431 const int theMeshIndex,
432 std::string& theMeshName )
433 throw ( SALOME::SALOME_Exception )
435 Unexpect aCatch(SALOME_SalomeException);
438 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
440 catch( SALOME_Exception& S_ex ) {
441 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
444 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
447 CreateGroupServants();
449 _medFileInfo = new SMESH::MedFileInfo();
450 _medFileInfo->fileName = theFileName;
451 _medFileInfo->major = 0;
452 _medFileInfo->minor = 0;
453 _medFileInfo->release = 0;
454 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
456 return ConvertDriverMEDReadStatus(status);
459 //================================================================================
461 * \brief Return string representation of a MED file version comprising nbDigits
463 //================================================================================
465 char* SMESH_Mesh_i::GetVersionString(CORBA::Long minor, CORBA::Short nbDigits)
467 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(minor,
469 return CORBA::string_dup( ver.c_str() );
472 //================================================================================
474 * Return the list of med versions compatibles for write/append,
475 * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32)
477 //================================================================================
478 SMESH::long_array* SMESH_Mesh_i::GetMEDVersionsCompatibleForAppend()
480 SMESH::long_array_var aResult = new SMESH::long_array();
481 std::vector<int> mvok = MED::GetMEDVersionsAppendCompatible();
482 long nbver = mvok.size();
483 aResult->length( nbver );
484 for ( int i = 0; i < nbver; i++ )
485 aResult[i] = mvok[i];
486 return aResult._retn();
489 //=============================================================================
493 * Imports mesh data from MED file
495 //=============================================================================
497 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
498 throw ( SALOME::SALOME_Exception )
502 // Read mesh with name = <theMeshName> into SMESH_Mesh
503 _impl->UNVToMesh( theFileName );
505 CreateGroupServants();
507 _medFileInfo = new SMESH::MedFileInfo();
508 _medFileInfo->fileName = theFileName;
509 _medFileInfo->major = 0;
510 _medFileInfo->minor = 0;
511 _medFileInfo->release = 0;
512 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
514 SMESH_CATCH( SMESH::throwCorbaException );
519 //=============================================================================
523 * Imports mesh data from STL file
525 //=============================================================================
526 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
527 throw ( SALOME::SALOME_Exception )
531 // Read mesh with name = <theMeshName> into SMESH_Mesh
532 std::string name = _impl->STLToMesh( theFileName );
535 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
536 _gen_i->SetName( meshSO, name.c_str() );
538 _medFileInfo = new SMESH::MedFileInfo();
539 _medFileInfo->fileName = theFileName;
540 _medFileInfo->major = 0;
541 _medFileInfo->minor = 0;
542 _medFileInfo->release = 0;
543 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
545 SMESH_CATCH( SMESH::throwCorbaException );
550 //================================================================================
552 * \brief Function used in SMESH_CATCH by ImportGMFFile()
554 //================================================================================
558 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
560 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
564 //================================================================================
566 * \brief Imports data from a GMF file and returns an error description
568 //================================================================================
570 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
571 bool theMakeRequiredGroups )
572 throw (SALOME::SALOME_Exception)
574 SMESH_ComputeErrorPtr error;
577 #define SMESH_CAUGHT error =
580 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
582 _medFileInfo = new SMESH::MedFileInfo();
583 _medFileInfo->fileName = theFileName;
584 _medFileInfo->major = 0;
585 _medFileInfo->minor = 0;
586 _medFileInfo->release = 0;
587 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
589 SMESH_CATCH( exceptionToComputeError );
593 CreateGroupServants();
595 return ConvertComputeError( error );
598 //=============================================================================
602 //=============================================================================
604 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
606 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
607 (SMESH_Hypothesis::Hypothesis_Status theStatus)
610 RETURNCASE( HYP_OK );
611 RETURNCASE( HYP_MISSING );
612 RETURNCASE( HYP_CONCURRENT );
613 RETURNCASE( HYP_BAD_PARAMETER );
614 RETURNCASE( HYP_HIDDEN_ALGO );
615 RETURNCASE( HYP_HIDING_ALGO );
616 RETURNCASE( HYP_UNKNOWN_FATAL );
617 RETURNCASE( HYP_INCOMPATIBLE );
618 RETURNCASE( HYP_NOTCONFORM );
619 RETURNCASE( HYP_ALREADY_EXIST );
620 RETURNCASE( HYP_BAD_DIM );
621 RETURNCASE( HYP_BAD_SUBSHAPE );
622 RETURNCASE( HYP_BAD_GEOMETRY );
623 RETURNCASE( HYP_NEED_SHAPE );
624 RETURNCASE( HYP_INCOMPAT_HYPS );
627 return SMESH::HYP_UNKNOWN_FATAL;
630 //=============================================================================
634 * calls internal addHypothesis() and then adds a reference to <anHyp> under
635 * the SObject actually having a reference to <aSubShape>.
636 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
638 //=============================================================================
640 SMESH::Hypothesis_Status
641 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
642 SMESH::SMESH_Hypothesis_ptr anHyp,
643 CORBA::String_out anErrorText)
644 throw(SALOME::SALOME_Exception)
646 Unexpect aCatch(SALOME_SalomeException);
648 _preMeshInfo->ForgetOrLoad();
651 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
652 anErrorText = error.c_str();
654 SMESH::SMESH_Mesh_var mesh( _this() );
655 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
657 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
658 _gen_i->UpdateIcons( mesh );
660 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
662 // Update Python script
663 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
664 << aSubShape << ", " << anHyp << " )";
666 return ConvertHypothesisStatus(status);
669 //=============================================================================
673 //=============================================================================
675 SMESH_Hypothesis::Hypothesis_Status
676 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
677 SMESH::SMESH_Hypothesis_ptr anHyp,
678 std::string* anErrorText)
680 if(MYDEBUG) MESSAGE("addHypothesis");
682 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
683 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
685 if (CORBA::is_nil( anHyp ))
686 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
688 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
691 TopoDS_Shape myLocSubShape;
692 //use PseudoShape in case if mesh has no shape
694 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
696 myLocSubShape = _impl->GetShapeToMesh();
698 const int hypId = anHyp->GetId();
700 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
701 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
703 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
705 // assure there is a corresponding submesh
706 if ( !_impl->IsMainShape( myLocSubShape )) {
707 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
708 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
709 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
712 else if ( anErrorText )
714 *anErrorText = error;
717 catch(SALOME_Exception & S_ex)
719 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
724 //=============================================================================
728 //=============================================================================
730 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
731 SMESH::SMESH_Hypothesis_ptr anHyp)
732 throw(SALOME::SALOME_Exception)
734 Unexpect aCatch(SALOME_SalomeException);
736 _preMeshInfo->ForgetOrLoad();
738 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
739 SMESH::SMESH_Mesh_var mesh = _this();
741 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
743 _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
744 _gen_i->UpdateIcons( mesh );
746 // Update Python script
747 if(_impl->HasShapeToMesh())
748 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
749 << aSubShape << ", " << anHyp << " )";
751 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
754 return ConvertHypothesisStatus(status);
757 //=============================================================================
761 //=============================================================================
763 SMESH_Hypothesis::Hypothesis_Status
764 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
765 SMESH::SMESH_Hypothesis_ptr anHyp)
767 if(MYDEBUG) MESSAGE("removeHypothesis()");
769 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
770 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
772 if (CORBA::is_nil( anHyp ))
773 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
775 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
778 TopoDS_Shape myLocSubShape;
779 //use PseudoShape in case if mesh has no shape
780 if( _impl->HasShapeToMesh() )
781 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
783 myLocSubShape = _impl->GetShapeToMesh();
785 const int hypId = anHyp->GetId();
786 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
787 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
789 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
793 catch(SALOME_Exception & S_ex)
795 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
800 //=============================================================================
804 //=============================================================================
806 SMESH::ListOfHypothesis *
807 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
808 throw(SALOME::SALOME_Exception)
810 Unexpect aCatch(SALOME_SalomeException);
811 if (MYDEBUG) MESSAGE("GetHypothesisList");
812 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
813 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
815 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
818 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
819 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
820 myLocSubShape = _impl->GetShapeToMesh();
821 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
822 int i = 0, n = aLocalList.size();
825 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
826 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
827 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
829 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
830 if ( id_hypptr != _mapHypo.end() )
831 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
835 catch(SALOME_Exception & S_ex) {
836 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
839 return aList._retn();
842 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
844 Unexpect aCatch(SALOME_SalomeException);
845 if (MYDEBUG) MESSAGE("GetSubMeshes");
847 SMESH::submesh_array_var aList = new SMESH::submesh_array();
850 TPythonDump aPythonDump;
851 if ( !_mapSubMeshIor.empty() )
855 aList->length( _mapSubMeshIor.size() );
857 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
858 for ( ; it != _mapSubMeshIor.end(); it++ ) {
859 if ( CORBA::is_nil( it->second )) continue;
860 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
862 if (i > 1) aPythonDump << ", ";
863 aPythonDump << it->second;
867 catch(SALOME_Exception & S_ex) {
868 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
871 // Update Python script
872 if ( !_mapSubMeshIor.empty() )
873 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
875 return aList._retn();
878 //=============================================================================
882 //=============================================================================
884 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
885 const char* theName )
886 throw(SALOME::SALOME_Exception)
888 Unexpect aCatch(SALOME_SalomeException);
889 if (CORBA::is_nil(aSubShape))
890 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
892 SMESH::SMESH_subMesh_var subMesh;
893 SMESH::SMESH_Mesh_var aMesh = _this();
895 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
897 //Get or Create the SMESH_subMesh object implementation
899 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
901 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
903 TopoDS_Iterator it( myLocSubShape );
905 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
907 subMesh = getSubMesh( subMeshId );
909 // create a new subMesh object servant if there is none for the shape
910 if ( subMesh->_is_nil() )
911 subMesh = createSubMesh( aSubShape );
912 if ( _gen_i->CanPublishInStudy( subMesh ))
914 SALOMEDS::SObject_wrap aSO =
915 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
916 if ( !aSO->_is_nil()) {
917 // Update Python script
918 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
919 << aSubShape << ", '" << theName << "' )";
923 catch(SALOME_Exception & S_ex) {
924 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
926 return subMesh._retn();
929 //=============================================================================
933 //=============================================================================
935 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
936 throw (SALOME::SALOME_Exception)
940 if ( theSubMesh->_is_nil() )
943 GEOM::GEOM_Object_var aSubShape;
944 // Remove submesh's SObject
945 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
946 if ( !anSO->_is_nil() ) {
947 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
948 SALOMEDS::SObject_wrap anObj, aRef;
949 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
950 anObj->ReferencedObject( aRef.inout() ))
952 CORBA::Object_var obj = aRef->GetObject();
953 aSubShape = GEOM::GEOM_Object::_narrow( obj );
955 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
956 // aSubShape = theSubMesh->GetSubShape();
958 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
959 builder->RemoveObjectWithChildren( anSO );
961 // Update Python script
962 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
965 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
967 _preMeshInfo->ForgetOrLoad();
969 SMESH_CATCH( SMESH::throwCorbaException );
972 //=============================================================================
976 //=============================================================================
978 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
979 const char* theName )
980 throw(SALOME::SALOME_Exception)
982 Unexpect aCatch(SALOME_SalomeException);
984 _preMeshInfo->FullLoadFromFile();
986 SMESH::SMESH_Group_var aNewGroup =
987 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
989 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
991 SMESH::SMESH_Mesh_var mesh = _this();
992 SALOMEDS::SObject_wrap aSO =
993 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
994 if ( !aSO->_is_nil())
995 // Update Python script
996 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
997 << theElemType << ", '" << theName << "' )";
999 return aNewGroup._retn();
1002 //=============================================================================
1006 //=============================================================================
1007 SMESH::SMESH_GroupOnGeom_ptr
1008 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
1009 const char* theName,
1010 GEOM::GEOM_Object_ptr theGeomObj)
1011 throw(SALOME::SALOME_Exception)
1013 Unexpect aCatch(SALOME_SalomeException);
1015 _preMeshInfo->FullLoadFromFile();
1017 SMESH::SMESH_GroupOnGeom_var aNewGroup;
1019 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
1020 if ( !aShape.IsNull() )
1023 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, /*id=*/-1, aShape ));
1025 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1027 SMESH::SMESH_Mesh_var mesh = _this();
1028 SALOMEDS::SObject_wrap aSO =
1029 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
1030 if ( !aSO->_is_nil())
1031 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
1032 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
1036 return aNewGroup._retn();
1039 //================================================================================
1041 * \brief Creates a group whose contents is defined by filter
1042 * \param theElemType - group type
1043 * \param theName - group name
1044 * \param theFilter - the filter
1045 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1047 //================================================================================
1049 SMESH::SMESH_GroupOnFilter_ptr
1050 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1051 const char* theName,
1052 SMESH::Filter_ptr theFilter )
1053 throw (SALOME::SALOME_Exception)
1055 Unexpect aCatch(SALOME_SalomeException);
1057 _preMeshInfo->FullLoadFromFile();
1059 if ( CORBA::is_nil( theFilter ))
1060 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1062 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1064 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1066 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1067 ( createGroup( theElemType, theName, /*id=*/-1, TopoDS_Shape(), predicate ));
1070 if ( !aNewGroup->_is_nil() )
1071 aNewGroup->SetFilter( theFilter );
1073 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1075 SMESH::SMESH_Mesh_var mesh = _this();
1076 SALOMEDS::SObject_wrap aSO =
1077 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1079 if ( !aSO->_is_nil())
1080 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1081 << theElemType << ", '" << theName << "', " << theFilter << " )";
1083 return aNewGroup._retn();
1086 //=============================================================================
1090 //=============================================================================
1092 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1093 throw (SALOME::SALOME_Exception)
1095 if ( theGroup->_is_nil() )
1100 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1104 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1105 if ( !aGroupSO->_is_nil() )
1107 // Update Python script
1108 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1110 // Remove group's SObject
1111 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1112 builder->RemoveObjectWithChildren( aGroupSO );
1114 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1116 // Remove the group from SMESH data structures
1117 removeGroup( aGroup->GetLocalID() );
1119 SMESH_CATCH( SMESH::throwCorbaException );
1122 //=============================================================================
1124 * Remove group with its contents
1126 //=============================================================================
1128 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1129 throw (SALOME::SALOME_Exception)
1133 _preMeshInfo->FullLoadFromFile();
1135 if ( theGroup->_is_nil() )
1138 vector<int> nodeIds; // to remove nodes becoming free
1139 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1140 if ( !isNodal && !theGroup->IsEmpty() )
1142 CORBA::Long elemID = theGroup->GetID( 1 );
1143 int nbElemNodes = GetElemNbNodes( elemID );
1144 if ( nbElemNodes > 0 )
1145 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1148 // Retrieve contents
1149 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1150 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1151 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1152 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1153 elems.assign( elemBeg, elemEnd );
1155 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1158 RemoveGroup( theGroup );
1161 for ( size_t i = 0; i < elems.size(); ++i )
1163 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1167 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1168 nodeIds.push_back( nIt->next()->GetID() );
1170 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1174 _impl->GetMeshDS()->RemoveElement( elems[i] );
1178 // Remove free nodes
1179 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1180 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1181 if ( n->NbInverseElements() == 0 )
1182 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1184 // Update Python script (theGroup must be alive for this)
1185 pyDump << SMESH::SMESH_Mesh_var(_this())
1186 << ".RemoveGroupWithContents( " << theGroup << " )";
1188 SMESH_CATCH( SMESH::throwCorbaException );
1191 //================================================================================
1193 * \brief Get the list of groups existing in the mesh
1194 * \retval SMESH::ListOfGroups * - list of groups
1196 //================================================================================
1198 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1200 Unexpect aCatch(SALOME_SalomeException);
1201 if (MYDEBUG) MESSAGE("GetGroups");
1203 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1206 TPythonDump aPythonDump;
1207 if ( !_mapGroups.empty() )
1209 aPythonDump << "[ ";
1211 aList->length( _mapGroups.size() );
1213 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1214 for ( ; it != _mapGroups.end(); it++ ) {
1215 if ( CORBA::is_nil( it->second )) continue;
1216 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1218 if (i > 1) aPythonDump << ", ";
1219 aPythonDump << it->second;
1223 catch(SALOME_Exception & S_ex) {
1224 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1226 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1228 return aList._retn();
1231 //=============================================================================
1233 * Get number of groups existing in the mesh
1235 //=============================================================================
1237 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1239 Unexpect aCatch(SALOME_SalomeException);
1240 return _mapGroups.size();
1243 //=============================================================================
1245 * New group including all mesh elements present in initial groups is created.
1247 //=============================================================================
1249 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1250 SMESH::SMESH_GroupBase_ptr theGroup2,
1251 const char* theName )
1252 throw (SALOME::SALOME_Exception)
1254 SMESH::SMESH_Group_var aResGrp;
1258 _preMeshInfo->FullLoadFromFile();
1260 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1261 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1263 if ( theGroup1->GetType() != theGroup2->GetType() )
1264 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1269 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1270 if ( aResGrp->_is_nil() )
1271 return SMESH::SMESH_Group::_nil();
1273 aResGrp->AddFrom( theGroup1 );
1274 aResGrp->AddFrom( theGroup2 );
1276 // Update Python script
1277 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1278 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1280 SMESH_CATCH( SMESH::throwCorbaException );
1282 return aResGrp._retn();
1285 //=============================================================================
1287 * \brief New group including all mesh elements present in initial groups is created.
1288 * \param theGroups list of groups
1289 * \param theName name of group to be created
1290 * \return pointer to the new group
1292 //=============================================================================
1294 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1295 const char* theName )
1296 throw (SALOME::SALOME_Exception)
1298 SMESH::SMESH_Group_var aResGrp;
1301 _preMeshInfo->FullLoadFromFile();
1304 return SMESH::SMESH_Group::_nil();
1309 SMESH::ElementType aType = SMESH::ALL;
1310 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1312 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1313 if ( CORBA::is_nil( aGrp ) )
1315 if ( aType == SMESH::ALL )
1316 aType = aGrp->GetType();
1317 else if ( aType != aGrp->GetType() )
1318 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1321 if ( aType == SMESH::ALL )
1322 return SMESH::SMESH_Group::_nil();
1327 aResGrp = CreateGroup( aType, theName );
1328 if ( aResGrp->_is_nil() )
1329 return SMESH::SMESH_Group::_nil();
1331 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1332 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1334 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1335 if ( !CORBA::is_nil( aGrp ) )
1337 aResGrp->AddFrom( aGrp );
1338 if ( g > 0 ) pyDump << ", ";
1342 pyDump << " ], '" << theName << "' )";
1344 SMESH_CATCH( SMESH::throwCorbaException );
1346 return aResGrp._retn();
1349 //=============================================================================
1351 * New group is created. All mesh elements that are
1352 * present in both initial groups are added to the new one.
1354 //=============================================================================
1356 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1357 SMESH::SMESH_GroupBase_ptr theGroup2,
1358 const char* theName )
1359 throw (SALOME::SALOME_Exception)
1361 SMESH::SMESH_Group_var aResGrp;
1366 _preMeshInfo->FullLoadFromFile();
1368 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1369 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1371 if ( theGroup1->GetType() != theGroup2->GetType() )
1372 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1376 // Create Intersection
1377 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1378 if ( aResGrp->_is_nil() )
1379 return aResGrp._retn();
1381 SMESHDS_GroupBase* groupDS1 = 0;
1382 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1383 groupDS1 = grp_i->GetGroupDS();
1385 SMESHDS_GroupBase* groupDS2 = 0;
1386 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1387 groupDS2 = grp_i->GetGroupDS();
1389 SMESHDS_Group* resGroupDS = 0;
1390 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1391 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1393 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1395 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1396 while ( elemIt1->more() )
1398 const SMDS_MeshElement* e = elemIt1->next();
1399 if ( groupDS2->Contains( e ))
1400 resGroupDS->SMDSGroup().Add( e );
1403 // Update Python script
1404 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1405 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1407 SMESH_CATCH( SMESH::throwCorbaException );
1409 return aResGrp._retn();
1412 //=============================================================================
1414 \brief Intersect list of groups. New group is created. All mesh elements that
1415 are present in all initial groups simultaneously are added to the new one.
1416 \param theGroups list of groups
1417 \param theName name of group to be created
1418 \return pointer on the group
1420 //=============================================================================
1421 SMESH::SMESH_Group_ptr
1422 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1423 const char* theName )
1424 throw (SALOME::SALOME_Exception)
1426 SMESH::SMESH_Group_var aResGrp;
1431 _preMeshInfo->FullLoadFromFile();
1434 return SMESH::SMESH_Group::_nil();
1436 // check types and get SMESHDS_GroupBase's
1437 SMESH::ElementType aType = SMESH::ALL;
1438 vector< SMESHDS_GroupBase* > groupVec;
1439 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1441 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1442 if ( CORBA::is_nil( aGrp ) )
1444 if ( aType == SMESH::ALL )
1445 aType = aGrp->GetType();
1446 else if ( aType != aGrp->GetType() )
1447 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1450 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1451 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1453 if ( grpDS->IsEmpty() )
1458 groupVec.push_back( grpDS );
1461 if ( aType == SMESH::ALL ) // all groups are nil
1462 return SMESH::SMESH_Group::_nil();
1467 aResGrp = CreateGroup( aType, theName );
1469 SMESHDS_Group* resGroupDS = 0;
1470 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1471 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1472 if ( !resGroupDS || groupVec.empty() )
1473 return aResGrp._retn();
1476 size_t i, nb = groupVec.size();
1477 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1478 while ( elemIt1->more() )
1480 const SMDS_MeshElement* e = elemIt1->next();
1482 for ( i = 1; ( i < nb && inAll ); ++i )
1483 inAll = groupVec[i]->Contains( e );
1486 resGroupDS->SMDSGroup().Add( e );
1489 // Update Python script
1490 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1491 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1493 SMESH_CATCH( SMESH::throwCorbaException );
1495 return aResGrp._retn();
1498 //=============================================================================
1500 * New group is created. All mesh elements that are present in
1501 * a main group but is not present in a tool group are added to the new one
1503 //=============================================================================
1505 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1506 SMESH::SMESH_GroupBase_ptr theGroup2,
1507 const char* theName )
1508 throw (SALOME::SALOME_Exception)
1510 SMESH::SMESH_Group_var aResGrp;
1515 _preMeshInfo->FullLoadFromFile();
1517 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1518 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1520 if ( theGroup1->GetType() != theGroup2->GetType() )
1521 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1525 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1526 if ( aResGrp->_is_nil() )
1527 return aResGrp._retn();
1529 SMESHDS_GroupBase* groupDS1 = 0;
1530 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1531 groupDS1 = grp_i->GetGroupDS();
1533 SMESHDS_GroupBase* groupDS2 = 0;
1534 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1535 groupDS2 = grp_i->GetGroupDS();
1537 SMESHDS_Group* resGroupDS = 0;
1538 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1539 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1541 if ( groupDS1 && groupDS2 && resGroupDS )
1543 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1544 while ( elemIt1->more() )
1546 const SMDS_MeshElement* e = elemIt1->next();
1547 if ( !groupDS2->Contains( e ))
1548 resGroupDS->SMDSGroup().Add( e );
1551 // Update Python script
1552 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1553 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1555 SMESH_CATCH( SMESH::throwCorbaException );
1557 return aResGrp._retn();
1560 //=============================================================================
1562 \brief Cut lists of groups. New group is created. All mesh elements that are
1563 present in main groups but do not present in tool groups are added to the new one
1564 \param theMainGroups list of main groups
1565 \param theToolGroups list of tool groups
1566 \param theName name of group to be created
1567 \return pointer on the group
1569 //=============================================================================
1570 SMESH::SMESH_Group_ptr
1571 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1572 const SMESH::ListOfGroups& theToolGroups,
1573 const char* theName )
1574 throw (SALOME::SALOME_Exception)
1576 SMESH::SMESH_Group_var aResGrp;
1581 _preMeshInfo->FullLoadFromFile();
1584 return SMESH::SMESH_Group::_nil();
1586 // check types and get SMESHDS_GroupBase's
1587 SMESH::ElementType aType = SMESH::ALL;
1588 vector< SMESHDS_GroupBase* > toolGroupVec;
1589 vector< SMDS_ElemIteratorPtr > mainIterVec;
1591 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1593 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1594 if ( CORBA::is_nil( aGrp ) )
1596 if ( aType == SMESH::ALL )
1597 aType = aGrp->GetType();
1598 else if ( aType != aGrp->GetType() )
1599 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1601 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1602 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1603 if ( !grpDS->IsEmpty() )
1604 mainIterVec.push_back( grpDS->GetElements() );
1606 if ( aType == SMESH::ALL ) // all main groups are nil
1607 return SMESH::SMESH_Group::_nil();
1608 if ( mainIterVec.empty() ) // all main groups are empty
1609 return aResGrp._retn();
1611 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1613 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1614 if ( CORBA::is_nil( aGrp ) )
1616 if ( aType != aGrp->GetType() )
1617 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1619 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1620 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1621 toolGroupVec.push_back( grpDS );
1627 aResGrp = CreateGroup( aType, theName );
1629 SMESHDS_Group* resGroupDS = 0;
1630 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1631 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1633 return aResGrp._retn();
1636 size_t i, nb = toolGroupVec.size();
1637 SMDS_ElemIteratorPtr mainElemIt
1638 ( new SMDS_IteratorOnIterators
1639 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1640 while ( mainElemIt->more() )
1642 const SMDS_MeshElement* e = mainElemIt->next();
1644 for ( i = 0; ( i < nb && !isIn ); ++i )
1645 isIn = toolGroupVec[i]->Contains( e );
1648 resGroupDS->SMDSGroup().Add( e );
1651 // Update Python script
1652 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1653 << ".CutListOfGroups( " << theMainGroups << ", "
1654 << theToolGroups << ", '" << theName << "' )";
1656 SMESH_CATCH( SMESH::throwCorbaException );
1658 return aResGrp._retn();
1661 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1663 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1664 bool & toStopChecking )
1666 toStopChecking = ( nbCommon < nbChecked );
1667 return nbCommon == nbNodes;
1669 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1670 bool & toStopChecking )
1672 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1673 return nbCommon == nbCorners;
1675 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1676 bool & toStopChecking )
1678 return nbCommon > 0;
1680 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1681 bool & toStopChecking )
1683 return nbCommon >= (nbNodes+1) / 2;
1687 //=============================================================================
1689 * Create a group of entities basing on nodes of other groups.
1690 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1691 * \param [in] anElemType - a type of elements to include to the new group.
1692 * \param [in] theName - a name of the new group.
1693 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1694 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1695 * new group provided that it is based on nodes of an element of \a aListOfGroups
1696 * \return SMESH_Group - the created group
1698 // IMP 19939, bug 22010, IMP 22635
1699 //=============================================================================
1701 SMESH::SMESH_Group_ptr
1702 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1703 SMESH::ElementType theElemType,
1704 const char* theName,
1705 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1706 CORBA::Boolean theUnderlyingOnly)
1707 throw (SALOME::SALOME_Exception)
1709 SMESH::SMESH_Group_var aResGrp;
1713 _preMeshInfo->FullLoadFromFile();
1715 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1717 if ( !theName || !aMeshDS )
1718 return SMESH::SMESH_Group::_nil();
1720 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1722 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1723 SMESH_Comment nbCoNoStr( "SMESH.");
1724 switch ( theNbCommonNodes ) {
1725 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1726 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1727 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1728 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1729 default: return aResGrp._retn();
1731 int nbChecked, nbCommon, nbNodes, nbCorners;
1737 aResGrp = CreateGroup( theElemType, theName );
1738 if ( aResGrp->_is_nil() )
1739 return SMESH::SMESH_Group::_nil();
1741 SMESHDS_GroupBase* groupBaseDS =
1742 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1743 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1745 vector<bool> isNodeInGroups;
1747 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1749 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1750 if ( CORBA::is_nil( aGrp ) )
1752 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1753 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1756 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1757 if ( !elIt ) continue;
1759 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1761 while ( elIt->more() ) {
1762 const SMDS_MeshElement* el = elIt->next();
1763 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1764 while ( nIt->more() )
1765 resGroupCore.Add( nIt->next() );
1768 // get elements of theElemType based on nodes of every element of group
1769 else if ( theUnderlyingOnly )
1771 while ( elIt->more() )
1773 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1774 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1775 TIDSortedElemSet checkedElems;
1776 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1777 while ( nIt->more() )
1779 const SMDS_MeshNode* n = nIt->next();
1780 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1781 // check nodes of elements of theElemType around el
1782 while ( elOfTypeIt->more() )
1784 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1785 if ( !checkedElems.insert( elOfType ).second ) continue;
1786 nbNodes = elOfType->NbNodes();
1787 nbCorners = elOfType->NbCornerNodes();
1789 bool toStopChecking = false;
1790 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1791 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1792 if ( elNodes.count( nIt2->next() ) &&
1793 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1795 resGroupCore.Add( elOfType );
1802 // get all nodes of elements of groups
1805 while ( elIt->more() )
1807 const SMDS_MeshElement* el = elIt->next(); // an element of group
1808 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1809 while ( nIt->more() )
1811 const SMDS_MeshNode* n = nIt->next();
1812 if ( n->GetID() >= (int) isNodeInGroups.size() )
1813 isNodeInGroups.resize( n->GetID() + 1, false );
1814 isNodeInGroups[ n->GetID() ] = true;
1820 // Get elements of theElemType based on a certain number of nodes of elements of groups
1821 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1823 const SMDS_MeshNode* n;
1824 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1825 const int isNodeInGroupsSize = isNodeInGroups.size();
1826 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1828 if ( !isNodeInGroups[ iN ] ||
1829 !( n = aMeshDS->FindNode( iN )))
1832 // check nodes of elements of theElemType around n
1833 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1834 while ( elOfTypeIt->more() )
1836 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1837 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1842 nbNodes = elOfType->NbNodes();
1843 nbCorners = elOfType->NbCornerNodes();
1845 bool toStopChecking = false;
1846 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1847 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1849 const int nID = nIt->next()->GetID();
1850 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1851 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1853 resGroupCore.Add( elOfType );
1861 // Update Python script
1862 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1863 << ".CreateDimGroup( "
1864 << theGroups << ", " << theElemType << ", '" << theName << "', "
1865 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1867 SMESH_CATCH( SMESH::throwCorbaException );
1869 return aResGrp._retn();
1872 //================================================================================
1874 * \brief Distribute all faces of the mesh between groups using sharp edges and optionally
1875 * existing 1D elements as group boundaries.
1876 * \param [in] theSharpAngle - edge is considered sharp if an angle between normals of
1877 * adjacent faces is more than \a sharpAngle in degrees.
1878 * \param [in] theCreateEdges - to create 1D elements for detected sharp edges.
1879 * \param [in] theUseExistingEdges - to use existing edges as group boundaries
1880 * \return ListOfGroups - the created groups
1882 //================================================================================
1884 SMESH::ListOfGroups*
1885 SMESH_Mesh_i::FaceGroupsSeparatedByEdges( CORBA::Double theSharpAngle,
1886 CORBA::Boolean theCreateEdges,
1887 CORBA::Boolean theUseExistingEdges )
1888 throw (SALOME::SALOME_Exception)
1890 if ( theSharpAngle < 0 || theSharpAngle > 180 )
1891 THROW_SALOME_CORBA_EXCEPTION("Invalid sharp angle, it must be between 0 and 180 degrees",
1894 SMESH::ListOfGroups_var resultGroups = new SMESH::ListOfGroups;
1900 _preMeshInfo->FullLoadFromFile();
1902 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1904 std::vector< SMESH_MeshAlgos::Edge > edges =
1905 SMESH_MeshAlgos::FindSharpEdges( meshDS, theSharpAngle, theUseExistingEdges );
1907 if ( theCreateEdges )
1909 std::vector<const SMDS_MeshNode *> nodes(2);
1910 for ( size_t i = 0; i < edges.size(); ++i )
1912 nodes[0] = edges[i]._node1;
1913 nodes[1] = edges[i]._node2;
1914 if ( meshDS->FindElement( nodes, SMDSAbs_Edge ))
1916 if ( edges[i]._medium )
1917 meshDS->AddEdge( edges[i]._node1, edges[i]._node2, edges[i]._medium );
1919 meshDS->AddEdge( edges[i]._node1, edges[i]._node2 );
1923 std::vector< std::vector< const SMDS_MeshElement* > > faceGroups =
1924 SMESH_MeshAlgos::SeparateFacesByEdges( meshDS, edges );
1926 SMESH::SMESH_MeshEditor_var editor = GetMeshEditor(); // create _editor
1928 resultGroups->length( faceGroups.size() );
1929 for ( size_t iG = 0; iG < faceGroups.size(); ++iG )
1931 SMESH::SMESH_Group_var group = CreateGroup( SMESH::FACE,
1932 _editor->GenerateGroupName("Group").c_str());
1933 resultGroups[iG] = SMESH::SMESH_Group::_duplicate( group );
1935 SMESHDS_GroupBase* groupBaseDS =
1936 SMESH::DownCast<SMESH_GroupBase_i*>( group )->GetGroupDS();
1937 SMDS_MeshGroup& groupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1939 std::vector< const SMDS_MeshElement* >& faces = faceGroups[ iG ];
1940 for ( size_t i = 0; i < faces.size(); ++i )
1941 groupCore.Add( faces[i] );
1944 pyDump << resultGroups << " = " << SMESH::SMESH_Mesh_var(_this())
1945 << ".FaceGroupsSeparatedByEdges( "
1946 << TVar( theSharpAngle ) << ", "
1947 << theCreateEdges << ", "
1948 << theUseExistingEdges << " )";
1950 SMESH_CATCH( SMESH::throwCorbaException );
1951 return resultGroups._retn();
1955 //================================================================================
1957 * \brief Remember GEOM group data
1959 //================================================================================
1961 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1962 CORBA::Object_ptr theSmeshObj)
1964 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1967 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
1968 if ( groupSO->_is_nil() )
1971 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1972 GEOM::GEOM_IGroupOperations_wrap groupOp =
1973 geomGen->GetIGroupOperations();
1974 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1977 _geomGroupData.push_back( TGeomGroupData() );
1978 TGeomGroupData & groupData = _geomGroupData.back();
1980 CORBA::String_var entry = groupSO->GetID();
1981 groupData._groupEntry = entry.in();
1983 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1984 groupData._indices.insert( ids[i] );
1986 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1987 // shape index in SMESHDS
1988 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1989 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1992 //================================================================================
1994 * Remove GEOM group data relating to removed smesh object
1996 //================================================================================
1998 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
2000 list<TGeomGroupData>::iterator
2001 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2002 for ( ; data != dataEnd; ++data ) {
2003 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
2004 _geomGroupData.erase( data );
2010 //================================================================================
2012 * \brief Return new group contents if it has been changed and update group data
2014 //================================================================================
2016 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
2018 TopoDS_Shape newShape;
2021 SALOMEDS::SObject_wrap groupSO = SMESH_Gen_i::getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
2022 if ( !groupSO->_is_nil() )
2024 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
2025 if ( CORBA::is_nil( groupObj )) return newShape;
2026 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
2028 // get indices of group items
2029 set<int> curIndices;
2030 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
2031 GEOM::GEOM_IGroupOperations_wrap groupOp =
2032 geomGen->GetIGroupOperations();
2033 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
2034 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2035 curIndices.insert( ids[i] );
2037 if ( groupData._indices == curIndices )
2038 return newShape; // group not changed
2041 groupData._indices = curIndices;
2043 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2044 if ( !geomClient ) return newShape;
2045 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
2046 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
2047 newShape = _gen_i->GeomObjectToShape( geomGroup );
2050 if ( newShape.IsNull() ) {
2051 // geom group becomes empty - return empty compound
2052 TopoDS_Compound compound;
2053 BRep_Builder().MakeCompound(compound);
2054 newShape = compound;
2061 //-----------------------------------------------------------------------------
2063 * \brief Storage of shape and index used in CheckGeomGroupModif()
2065 struct TIndexedShape
2068 TopoDS_Shape _shape;
2069 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
2071 //-----------------------------------------------------------------------------
2073 * \brief Data to re-create a group on geometry
2075 struct TGroupOnGeomData
2079 SMDSAbs_ElementType _type;
2081 Quantity_Color _color;
2085 //=============================================================================
2087 * \brief Update data if geometry changes
2091 //=============================================================================
2093 void SMESH_Mesh_i::CheckGeomModif()
2095 if ( !_impl->HasShapeToMesh() ) return;
2097 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
2098 //if ( mainGO->_is_nil() ) return;
2100 // Update after group modification
2102 if ( mainGO->_is_nil() || /* shape was removed from GEOM_Client by newGroupShape()
2103 called by other mesh (IPAL52735) */
2104 mainGO->GetType() == GEOM_GROUP ||
2105 mainGO->GetTick() == _mainShapeTick )
2107 CheckGeomGroupModif();
2111 // Update after shape transformation like Translate
2113 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2114 if ( !geomClient ) return;
2115 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
2116 if ( geomGen->_is_nil() ) return;
2118 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2119 geomClient->RemoveShapeFromBuffer( ior.in() );
2121 // Update data taking into account that
2122 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2125 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2126 if ( newShape.IsNull() )
2129 _mainShapeTick = mainGO->GetTick();
2131 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2133 // store data of groups on geometry
2134 vector< TGroupOnGeomData > groupsData;
2135 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2136 groupsData.reserve( groups.size() );
2137 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2138 for ( ; g != groups.end(); ++g )
2139 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2141 TGroupOnGeomData data;
2142 data._oldID = group->GetID();
2143 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
2144 data._type = group->GetType();
2145 data._name = group->GetStoreName();
2146 data._color = group->GetColor();
2147 groupsData.push_back( data );
2149 // store assigned hypotheses
2150 vector< pair< int, THypList > > ids2Hyps;
2151 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2152 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2154 const TopoDS_Shape& s = s2hyps.Key();
2155 const THypList& hyps = s2hyps.ChangeValue();
2156 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2159 // change shape to mesh
2160 int oldNbSubShapes = meshDS->MaxShapeIndex();
2161 _impl->ShapeToMesh( TopoDS_Shape() );
2162 _impl->ShapeToMesh( newShape );
2164 // re-add shapes of geom groups
2165 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2166 for ( ; data != _geomGroupData.end(); ++data )
2168 TopoDS_Shape newShape = newGroupShape( *data );
2169 if ( !newShape.IsNull() )
2171 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2173 TopoDS_Compound compound;
2174 BRep_Builder().MakeCompound( compound );
2175 BRep_Builder().Add( compound, newShape );
2176 newShape = compound;
2178 _impl->GetSubMesh( newShape );
2181 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2182 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2183 SALOME::INTERNAL_ERROR );
2185 // re-assign hypotheses
2186 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2188 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2189 const THypList& hyps = ids2Hyps[i].second;
2190 THypList::const_iterator h = hyps.begin();
2191 for ( ; h != hyps.end(); ++h )
2192 _impl->AddHypothesis( s, (*h)->GetID() );
2196 for ( size_t i = 0; i < groupsData.size(); ++i )
2198 const TGroupOnGeomData& data = groupsData[i];
2200 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2201 if ( i2g == _mapGroups.end() ) continue;
2203 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2204 if ( !gr_i ) continue;
2207 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
2208 meshDS->IndexToShape( data._shapeID ));
2211 _mapGroups.erase( i2g );
2215 g->GetGroupDS()->SetColor( data._color );
2216 gr_i->changeLocalId( id );
2217 _mapGroups[ id ] = i2g->second;
2218 if ( data._oldID != id )
2219 _mapGroups.erase( i2g );
2223 // update _mapSubMesh
2224 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2225 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2226 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2230 //=============================================================================
2232 * \brief Update objects depending on changed geom groups
2234 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2235 * issue 0020210: Update of a smesh group after modification of the associated geom group
2237 //=============================================================================
2239 void SMESH_Mesh_i::CheckGeomGroupModif()
2241 if ( !_impl->HasShapeToMesh() ) return;
2243 CORBA::Long nbEntities = NbNodes() + NbElements();
2245 // Check if group contents changed
2247 typedef map< string, TopoDS_Shape > TEntry2Geom;
2248 TEntry2Geom newGroupContents;
2250 list<TGeomGroupData>::iterator
2251 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2252 for ( ; data != dataEnd; ++data )
2254 pair< TEntry2Geom::iterator, bool > it_new =
2255 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2256 bool processedGroup = !it_new.second;
2257 TopoDS_Shape& newShape = it_new.first->second;
2258 if ( !processedGroup )
2259 newShape = newGroupShape( *data );
2260 if ( newShape.IsNull() )
2261 continue; // no changes
2264 _preMeshInfo->ForgetOrLoad();
2266 if ( processedGroup ) { // update group indices
2267 list<TGeomGroupData>::iterator data2 = data;
2268 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2269 data->_indices = data2->_indices;
2272 // Update SMESH objects according to new GEOM group contents
2274 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2275 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2277 int oldID = submesh->GetId();
2278 if ( !_mapSubMeshIor.count( oldID ))
2280 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2282 // update hypotheses
2283 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2284 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2285 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2287 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2288 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2290 // care of submeshes
2291 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2292 int newID = newSubmesh->GetId();
2293 if ( newID != oldID ) {
2294 _mapSubMesh [ newID ] = newSubmesh;
2295 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2296 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2297 _mapSubMesh. erase(oldID);
2298 _mapSubMesh_i. erase(oldID);
2299 _mapSubMeshIor.erase(oldID);
2300 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2305 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2306 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2307 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2309 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2311 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2312 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2313 ds->SetShape( newShape );
2318 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2319 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2321 // Remove groups and submeshes basing on removed sub-shapes
2323 TopTools_MapOfShape newShapeMap;
2324 TopoDS_Iterator shapeIt( newShape );
2325 for ( ; shapeIt.More(); shapeIt.Next() )
2326 newShapeMap.Add( shapeIt.Value() );
2328 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2329 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2331 if ( newShapeMap.Contains( shapeIt.Value() ))
2333 TopTools_IndexedMapOfShape oldShapeMap;
2334 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2335 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2337 const TopoDS_Shape& oldShape = oldShapeMap(i);
2338 int oldInd = meshDS->ShapeToIndex( oldShape );
2340 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2341 if ( i_smIor != _mapSubMeshIor.end() ) {
2342 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2345 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2346 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2348 // check if a group bases on oldInd shape
2349 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2350 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2351 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2352 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2354 RemoveGroup( i_grp->second ); // several groups can base on same shape
2355 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2360 // Reassign hypotheses and update groups after setting the new shape to mesh
2362 // collect anassigned hypotheses
2363 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2364 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2365 TShapeHypList assignedHyps;
2366 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2368 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2369 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2370 if ( !hyps.empty() ) {
2371 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2372 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2373 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2376 // collect shapes supporting groups
2377 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2378 TShapeTypeList groupData;
2379 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2380 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2381 for ( ; grIt != groups.end(); ++grIt )
2383 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2385 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2387 // set new shape to mesh -> DS of sub-meshes and geom groups are deleted
2389 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2390 _impl->ShapeToMesh( newShape );
2392 // reassign hypotheses
2393 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2394 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2396 TIndexedShape& geom = indS_hyps->first;
2397 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2398 int oldID = geom._index;
2399 int newID = meshDS->ShapeToIndex( geom._shape );
2400 if ( oldID == 1 ) { // main shape
2402 geom._shape = newShape;
2406 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2407 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2408 // care of sub-meshes
2409 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2410 if ( newID != oldID ) {
2411 _mapSubMesh [ newID ] = newSubmesh;
2412 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2413 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2414 _mapSubMesh. erase(oldID);
2415 _mapSubMesh_i. erase(oldID);
2416 _mapSubMeshIor.erase(oldID);
2417 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2421 TShapeTypeList::iterator geomType = groupData.begin();
2422 for ( ; geomType != groupData.end(); ++geomType )
2424 const TIndexedShape& geom = geomType->first;
2425 int oldID = geom._index;
2426 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2429 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2430 CORBA::String_var name = groupSO->GetName();
2432 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
2433 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
2434 /*id=*/-1, geom._shape ))
2435 group_i->changeLocalId( group->GetID() );
2438 break; // everything has been updated
2441 } // loop on group data
2445 CORBA::Long newNbEntities = NbNodes() + NbElements();
2446 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2447 if ( newNbEntities != nbEntities )
2449 // Add all SObjects with icons to soToUpdateIcons
2450 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2452 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2453 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2454 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2456 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2457 i_gr != _mapGroups.end(); ++i_gr ) // groups
2458 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2461 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2462 for ( ; so != soToUpdateIcons.end(); ++so )
2463 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2466 //=============================================================================
2468 * \brief Create standalone group from a group on geometry or filter
2470 //=============================================================================
2472 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2473 throw (SALOME::SALOME_Exception)
2475 SMESH::SMESH_Group_var aGroup;
2480 _preMeshInfo->FullLoadFromFile();
2482 if ( theGroup->_is_nil() )
2483 return aGroup._retn();
2485 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2487 return aGroup._retn();
2489 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2491 const int anId = aGroupToRem->GetLocalID();
2492 if ( !_impl->ConvertToStandalone( anId ) )
2493 return aGroup._retn();
2494 removeGeomGroupData( theGroup );
2496 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2498 // remove old instance of group from own map
2499 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2500 _mapGroups.erase( anId );
2502 SALOMEDS::StudyBuilder_var builder;
2503 SALOMEDS::SObject_wrap aGroupSO;
2504 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2505 if ( !aStudy->_is_nil() ) {
2506 builder = aStudy->NewBuilder();
2507 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2508 if ( !aGroupSO->_is_nil() )
2510 // remove reference to geometry
2511 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2512 for ( ; chItr->More(); chItr->Next() )
2513 // Remove group's child SObject
2514 builder->RemoveObject( chItr->Value() );
2516 // Update Python script
2517 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2518 << ".ConvertToStandalone( " << aGroupSO << " )";
2520 // change icon of Group on Filter
2523 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2524 const int isEmpty = ( elemTypes->length() == 0 );
2527 SALOMEDS::GenericAttribute_wrap anAttr =
2528 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2529 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2530 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2536 // remember new group in own map
2537 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2538 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2540 // register CORBA object for persistence
2541 _gen_i->RegisterObject( aGroup );
2543 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2544 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2545 //aGroup->Register();
2546 aGroupToRem->UnRegister();
2548 SMESH_CATCH( SMESH::throwCorbaException );
2550 return aGroup._retn();
2553 //=============================================================================
2557 //=============================================================================
2559 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2561 if(MYDEBUG) MESSAGE( "createSubMesh" );
2562 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2563 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2566 SMESH_subMesh_i * subMeshServant;
2569 subMeshId = mySubMesh->GetId();
2570 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2572 else // "invalid sub-mesh"
2574 // The invalid sub-mesh is created for the case where a valid sub-shape not found
2575 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
2576 if ( _mapSubMesh.empty() )
2579 subMeshId = _mapSubMesh.begin()->first - 1;
2580 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
2583 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2585 _mapSubMesh [subMeshId] = mySubMesh;
2586 _mapSubMesh_i [subMeshId] = subMeshServant;
2587 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2589 subMeshServant->Register();
2591 // register CORBA object for persistence
2592 int nextId = _gen_i->RegisterObject( subMesh );
2593 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2594 else { nextId = 0; } // avoid "unused variable" warning
2596 // to track changes of GEOM groups
2597 if ( subMeshId > 0 )
2598 addGeomGroupData( theSubShapeObject, subMesh );
2600 return subMesh._retn();
2603 //=======================================================================
2604 //function : getSubMesh
2606 //=======================================================================
2608 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2610 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2611 if ( it == _mapSubMeshIor.end() )
2612 return SMESH::SMESH_subMesh::_nil();
2614 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2617 //=============================================================================
2621 //=============================================================================
2623 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2624 GEOM::GEOM_Object_ptr theSubShapeObject )
2626 bool isHypChanged = false;
2627 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2628 return isHypChanged;
2630 const int subMeshId = theSubMesh->GetId();
2632 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2634 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end() &&
2635 _mapSubMesh[ subMeshId ])
2637 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2640 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2641 isHypChanged = !hyps.empty();
2642 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2643 for ( ; hyp != hyps.end(); ++hyp )
2644 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2651 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2652 isHypChanged = ( aHypList->length() > 0 );
2653 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2654 removeHypothesis( theSubShapeObject, aHypList[i] );
2657 catch( const SALOME::SALOME_Exception& ) {
2658 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2660 removeGeomGroupData( theSubShapeObject );
2664 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2665 if ( id_smi != _mapSubMesh_i.end() )
2666 id_smi->second->UnRegister();
2668 // remove a CORBA object
2669 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2670 if ( id_smptr != _mapSubMeshIor.end() )
2671 SMESH::SMESH_subMesh_var( id_smptr->second );
2673 _mapSubMesh.erase(subMeshId);
2674 _mapSubMesh_i.erase(subMeshId);
2675 _mapSubMeshIor.erase(subMeshId);
2677 return isHypChanged;
2680 //=============================================================================
2684 //=============================================================================
2686 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2687 const char* theName,
2689 const TopoDS_Shape& theShape,
2690 const SMESH_PredicatePtr& thePredicate )
2692 std::string newName;
2693 if ( !theName || !theName[0] )
2695 std::set< std::string > presentNames;
2696 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2697 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2699 CORBA::String_var name = i_gr->second->GetName();
2700 presentNames.insert( name.in() );
2703 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2704 } while ( !presentNames.insert( newName ).second );
2705 theName = newName.c_str();
2707 SMESH::SMESH_GroupBase_var aGroup;
2708 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
2709 theID, theShape, thePredicate ))
2711 int anId = g->GetID();
2712 SMESH_GroupBase_i* aGroupImpl;
2713 if ( !theShape.IsNull() )
2714 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2715 else if ( thePredicate )
2716 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2718 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2720 aGroup = aGroupImpl->_this();
2721 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2722 aGroupImpl->Register();
2724 // register CORBA object for persistence
2725 int nextId = _gen_i->RegisterObject( aGroup );
2726 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2727 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
2729 // to track changes of GEOM groups
2730 if ( !theShape.IsNull() ) {
2731 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2732 addGeomGroupData( geom, aGroup );
2735 return aGroup._retn();
2738 //=============================================================================
2740 * SMESH_Mesh_i::removeGroup
2742 * Should be called by ~SMESH_Group_i()
2744 //=============================================================================
2746 void SMESH_Mesh_i::removeGroup( const int theId )
2748 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2749 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2750 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2751 _mapGroups.erase( theId );
2752 removeGeomGroupData( group );
2753 if ( !_impl->RemoveGroup( theId ))
2755 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2756 RemoveGroup( group );
2758 group->UnRegister();
2762 //=============================================================================
2766 //=============================================================================
2768 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2769 throw(SALOME::SALOME_Exception)
2771 SMESH::log_array_var aLog;
2775 _preMeshInfo->FullLoadFromFile();
2777 list < SMESHDS_Command * >logDS = _impl->GetLog();
2778 aLog = new SMESH::log_array;
2780 int lg = logDS.size();
2783 list < SMESHDS_Command * >::iterator its = logDS.begin();
2784 while(its != logDS.end()){
2785 SMESHDS_Command *com = *its;
2786 int comType = com->GetType();
2788 int lgcom = com->GetNumber();
2790 const list < int >&intList = com->GetIndexes();
2791 int inum = intList.size();
2793 list < int >::const_iterator ii = intList.begin();
2794 const list < double >&coordList = com->GetCoords();
2795 int rnum = coordList.size();
2797 list < double >::const_iterator ir = coordList.begin();
2798 aLog[indexLog].commandType = comType;
2799 aLog[indexLog].number = lgcom;
2800 aLog[indexLog].coords.length(rnum);
2801 aLog[indexLog].indexes.length(inum);
2802 for(int i = 0; i < rnum; i++){
2803 aLog[indexLog].coords[i] = *ir;
2804 //MESSAGE(" "<<i<<" "<<ir.Value());
2807 for(int i = 0; i < inum; i++){
2808 aLog[indexLog].indexes[i] = *ii;
2809 //MESSAGE(" "<<i<<" "<<ii.Value());
2818 SMESH_CATCH( SMESH::throwCorbaException );
2820 return aLog._retn();
2824 //=============================================================================
2828 //=============================================================================
2830 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2834 SMESH_CATCH( SMESH::throwCorbaException );
2837 //=============================================================================
2841 //=============================================================================
2843 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2848 //=============================================================================
2851 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2852 // issue 0020918: groups removal is caused by hyp modification
2853 // issue 0021208: to forget not loaded mesh data at hyp modification
2854 struct TCallUp_i : public SMESH_Mesh::TCallUp
2856 SMESH_Mesh_i* _mesh;
2857 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2858 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2859 virtual void HypothesisModified (int theHypID) { _mesh->onHypothesisModified( theHypID ); }
2860 virtual void Load () { _mesh->Load(); }
2864 //================================================================================
2866 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2868 //================================================================================
2870 void SMESH_Mesh_i::onHypothesisModified(int theHypID)
2873 _preMeshInfo->ForgetOrLoad();
2875 SMESH::SMESH_Mesh_var mesh = _this();
2876 _gen_i->UpdateIcons( mesh );
2878 // mark a hypothesis as valid after edition
2879 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
2880 SALOMEDS::SObject_wrap hypRoot;
2881 if ( !smeshComp->_is_nil() &&
2882 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
2884 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
2885 for ( ; anIter->More(); anIter->Next() )
2887 SALOMEDS::SObject_wrap hypSO = anIter->Value();
2888 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
2889 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
2890 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
2891 _gen_i->HighLightInvalid( hyp, false );
2896 //=============================================================================
2900 //=============================================================================
2902 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2904 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2907 _impl->SetCallUp( new TCallUp_i(this));
2910 //=============================================================================
2914 //=============================================================================
2916 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2918 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2922 //=============================================================================
2924 * Return mesh editor
2926 //=============================================================================
2928 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2929 throw (SALOME::SALOME_Exception)
2931 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2935 _preMeshInfo->FullLoadFromFile();
2937 // Create MeshEditor
2939 _editor = new SMESH_MeshEditor_i( this, false );
2940 aMeshEdVar = _editor->_this();
2942 // Update Python script
2943 TPythonDump() << _editor << " = "
2944 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2946 SMESH_CATCH( SMESH::throwCorbaException );
2948 return aMeshEdVar._retn();
2951 //=============================================================================
2953 * Return mesh edition previewer
2955 //=============================================================================
2957 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2958 throw (SALOME::SALOME_Exception)
2960 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2964 _preMeshInfo->FullLoadFromFile();
2966 if ( !_previewEditor )
2967 _previewEditor = new SMESH_MeshEditor_i( this, true );
2968 aMeshEdVar = _previewEditor->_this();
2970 SMESH_CATCH( SMESH::throwCorbaException );
2972 return aMeshEdVar._retn();
2975 //================================================================================
2977 * \brief Return true if the mesh has been edited since a last total re-compute
2978 * and those modifications may prevent successful partial re-compute
2980 //================================================================================
2982 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2984 Unexpect aCatch(SALOME_SalomeException);
2985 return _impl->HasModificationsToDiscard();
2988 //================================================================================
2990 * \brief Returns a random unique color
2992 //================================================================================
2994 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2996 const int MAX_ATTEMPTS = 100;
2998 double tolerance = 0.5;
2999 SALOMEDS::Color col;
3003 // generate random color
3004 double red = (double)rand() / RAND_MAX;
3005 double green = (double)rand() / RAND_MAX;
3006 double blue = (double)rand() / RAND_MAX;
3007 // check existence in the list of the existing colors
3008 bool matched = false;
3009 std::list<SALOMEDS::Color>::const_iterator it;
3010 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3011 SALOMEDS::Color color = *it;
3012 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3013 matched = tol < tolerance;
3015 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3016 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3024 //=============================================================================
3026 * Sets auto-color mode. If it is on, groups get unique random colors
3028 //=============================================================================
3030 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
3032 Unexpect aCatch(SALOME_SalomeException);
3033 _impl->SetAutoColor(theAutoColor);
3035 TPythonDump pyDump; // not to dump group->SetColor() from below code
3036 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3038 std::list<SALOMEDS::Color> aReservedColors;
3039 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3040 for ( ; it != _mapGroups.end(); it++ ) {
3041 if ( CORBA::is_nil( it->second )) continue;
3042 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3043 it->second->SetColor( aColor );
3044 aReservedColors.push_back( aColor );
3048 //=============================================================================
3050 * Returns true if auto-color mode is on
3052 //=============================================================================
3054 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
3056 Unexpect aCatch(SALOME_SalomeException);
3057 return _impl->GetAutoColor();
3060 //=============================================================================
3062 * Checks if there are groups with equal names
3064 //=============================================================================
3066 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3068 return _impl->HasDuplicatedGroupNamesMED();
3071 //================================================================================
3073 * \brief Care of a file before exporting mesh into it
3075 //================================================================================
3077 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3079 SMESH_File aFile( file );
3081 if (aFile.exists()) {
3082 // existing filesystem node
3083 if ( !aFile.isDirectory() ) {
3084 if ( aFile.openForWriting() ) {
3085 if ( overwrite && ! aFile.remove()) {
3086 msg << "Can't replace " << aFile.getName();
3089 msg << "Can't write into " << aFile.getName();
3092 msg << "Location " << aFile.getName() << " is not a file";
3096 // nonexisting file; check if it can be created
3097 if ( !aFile.openForWriting() ) {
3098 msg << "You cannot create the file "
3100 << ". Check the directory existence and access rights";
3108 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3112 //================================================================================
3114 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
3115 * \param file - file name
3116 * \param overwrite - to erase the file or not
3117 * \retval string - mesh name
3119 //================================================================================
3121 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3122 CORBA::Boolean overwrite)
3125 PrepareForWriting(file, overwrite);
3126 string aMeshName = "Mesh";
3127 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3128 if ( !aStudy->_is_nil() ) {
3129 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3130 if ( !aMeshSO->_is_nil() ) {
3131 CORBA::String_var name = aMeshSO->GetName();
3133 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3134 if ( !aStudy->GetProperties()->IsLocked() )
3136 SALOMEDS::GenericAttribute_wrap anAttr;
3137 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3138 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3139 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3140 ASSERT(!aFileName->_is_nil());
3141 aFileName->SetValue(file);
3142 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3143 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3144 ASSERT(!aFileType->_is_nil());
3145 aFileType->SetValue("FICHIERMED");
3149 // Update Python script
3150 // set name of mesh before export
3151 TPythonDump() << _gen_i << ".SetName("
3152 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3154 // check names of groups
3160 //================================================================================
3162 * \brief Export to MED file
3164 //================================================================================
3166 void SMESH_Mesh_i::ExportMED(const char* file,
3167 CORBA::Boolean auto_groups,
3168 CORBA::Long version,
3169 CORBA::Boolean overwrite,
3170 CORBA::Boolean autoDimension)
3171 throw(SALOME::SALOME_Exception)
3173 //MESSAGE("MED minor version: "<< minor);
3176 _preMeshInfo->FullLoadFromFile();
3178 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3179 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3181 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3183 << "auto_groups=" <<auto_groups << ", "
3184 << "minor=" << version << ", "
3185 << "overwrite=" << overwrite << ", "
3186 << "meshPart=None, "
3187 << "autoDimension=" << autoDimension << " )";
3189 SMESH_CATCH( SMESH::throwCorbaException );
3192 //================================================================================
3194 * \brief Export a mesh to a SAUV file
3196 //================================================================================
3198 void SMESH_Mesh_i::ExportSAUV (const char* file,
3199 CORBA::Boolean auto_groups)
3200 throw(SALOME::SALOME_Exception)
3202 Unexpect aCatch(SALOME_SalomeException);
3204 _preMeshInfo->FullLoadFromFile();
3206 string aMeshName = prepareMeshNameAndGroups(file, true);
3207 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3208 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3209 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3213 //================================================================================
3215 * \brief Export a mesh to a DAT file
3217 //================================================================================
3219 void SMESH_Mesh_i::ExportDAT (const char *file)
3220 throw(SALOME::SALOME_Exception)
3222 Unexpect aCatch(SALOME_SalomeException);
3224 _preMeshInfo->FullLoadFromFile();
3226 // Update Python script
3227 // check names of groups
3229 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3232 PrepareForWriting(file);
3233 _impl->ExportDAT(file);
3236 //================================================================================
3238 * \brief Export a mesh to an UNV file
3240 //================================================================================
3242 void SMESH_Mesh_i::ExportUNV (const char *file)
3243 throw(SALOME::SALOME_Exception)
3245 Unexpect aCatch(SALOME_SalomeException);
3247 _preMeshInfo->FullLoadFromFile();
3249 // Update Python script
3250 // check names of groups
3252 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3255 PrepareForWriting(file);
3256 _impl->ExportUNV(file);
3259 //================================================================================
3261 * \brief Export a mesh to an STL file
3263 //================================================================================
3265 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3266 throw(SALOME::SALOME_Exception)
3268 Unexpect aCatch(SALOME_SalomeException);
3270 _preMeshInfo->FullLoadFromFile();
3272 // Update Python script
3273 // check names of groups
3275 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3276 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3278 CORBA::String_var name;
3279 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3280 if ( !so->_is_nil() )
3281 name = so->GetName();
3284 PrepareForWriting( file );
3285 _impl->ExportSTL( file, isascii, name.in() );
3288 //================================================================================
3290 * \brief Export a part of mesh to a med file
3292 //================================================================================
3294 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3296 CORBA::Boolean auto_groups,
3297 CORBA::Long version,
3298 CORBA::Boolean overwrite,
3299 CORBA::Boolean autoDimension,
3300 const GEOM::ListOfFields& fields,
3301 const char* geomAssocFields,
3302 CORBA::Double ZTolerance)
3303 throw (SALOME::SALOME_Exception)
3305 MESSAGE("MED version: "<< version);
3308 _preMeshInfo->FullLoadFromFile();
3311 bool have0dField = false;
3312 if ( fields.length() > 0 )
3314 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3315 if ( shapeToMesh->_is_nil() )
3316 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3318 for ( size_t i = 0; i < fields.length(); ++i )
3320 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3321 THROW_SALOME_CORBA_EXCEPTION
3322 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3323 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3324 if ( fieldShape->_is_nil() )
3325 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3326 if ( !fieldShape->IsSame( shapeToMesh ) )
3327 THROW_SALOME_CORBA_EXCEPTION
3328 ( "Field defined not on shape", SALOME::BAD_PARAM);
3329 if ( fields[i]->GetDimension() == 0 )
3332 if ( geomAssocFields )
3333 for ( int i = 0; geomAssocFields[i]; ++i )
3334 switch ( geomAssocFields[i] ) {
3335 case 'v':case 'e':case 'f':case 's': break;
3336 case 'V':case 'E':case 'F':case 'S': break;
3337 default: THROW_SALOME_CORBA_EXCEPTION
3338 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3342 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3346 string aMeshName = "Mesh";
3347 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3348 if ( CORBA::is_nil( meshPart ) ||
3349 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3351 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3352 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3353 0, autoDimension, /*addODOnVertices=*/have0dField,
3355 meshDS = _impl->GetMeshDS();
3360 _preMeshInfo->FullLoadFromFile();
3362 PrepareForWriting(file, overwrite);
3364 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3365 if ( !SO->_is_nil() ) {
3366 CORBA::String_var name = SO->GetName();
3370 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3371 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3372 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3373 meshDS = tmpDSDeleter._obj = partDS;
3378 if ( _impl->HasShapeToMesh() )
3380 DriverMED_W_Field fieldWriter;
3381 fieldWriter.SetFile( file );
3382 fieldWriter.SetMeshName( aMeshName );
3383 fieldWriter.AddODOnVertices( have0dField );
3385 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3389 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3390 goList->length( fields.length() );
3391 for ( size_t i = 0; i < fields.length(); ++i )
3393 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3396 TPythonDump() << _this() << ".ExportPartToMED( "
3397 << meshPart << ", r'"
3399 << auto_groups << ", "
3401 << overwrite << ", "
3402 << autoDimension << ", "
3404 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
3405 << TVar( ZTolerance )
3408 SMESH_CATCH( SMESH::throwCorbaException );
3411 //================================================================================
3413 * Write GEOM fields to MED file
3415 //================================================================================
3417 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3418 SMESHDS_Mesh* meshDS,
3419 const GEOM::ListOfFields& fields,
3420 const char* geomAssocFields)
3422 #define METH "SMESH_Mesh_i::exportMEDFields() "
3424 if (( fields.length() < 1 ) &&
3425 ( !geomAssocFields || !geomAssocFields[0] ))
3428 std::vector< std::vector< double > > dblVals;
3429 std::vector< std::vector< int > > intVals;
3430 std::vector< int > subIdsByDim[ 4 ];
3431 const double noneDblValue = 0.;
3432 const double noneIntValue = 0;
3434 for ( size_t iF = 0; iF < fields.length(); ++iF )
3438 int dim = fields[ iF ]->GetDimension();
3439 SMDSAbs_ElementType elemType;
3440 TopAbs_ShapeEnum shapeType;
3442 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3443 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3444 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3445 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3447 continue; // skip fields on whole shape
3449 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3450 if ( dataType == GEOM::FDT_String )
3452 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3453 if ( stepIDs->length() < 1 )
3455 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3456 if ( comps->length() < 1 )
3458 CORBA::String_var name = fields[ iF ]->GetName();
3460 if ( !fieldWriter.Set( meshDS,
3464 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3467 for ( size_t iC = 0; iC < comps->length(); ++iC )
3468 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3470 dblVals.resize( comps->length() );
3471 intVals.resize( comps->length() );
3473 // find sub-shape IDs
3475 std::vector< int >& subIds = subIdsByDim[ dim ];
3476 if ( subIds.empty() )
3477 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3478 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3479 subIds.push_back( id );
3483 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3487 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3489 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3490 if ( step->_is_nil() )
3493 CORBA::Long stamp = step->GetStamp();
3494 CORBA::Long id = step->GetID();
3495 fieldWriter.SetDtIt( int( stamp ), int( id ));
3497 // fill dblVals or intVals
3498 for ( size_t iC = 0; iC < comps->length(); ++iC )
3499 if ( dataType == GEOM::FDT_Double )
3501 dblVals[ iC ].clear();
3502 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3506 intVals[ iC ].clear();
3507 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3511 case GEOM::FDT_Double:
3513 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3514 if ( dblStep->_is_nil() ) continue;
3515 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3516 if ( vv->length() != subIds.size() * comps->length() )
3517 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3518 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3519 for ( size_t iC = 0; iC < comps->length(); ++iC )
3520 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3525 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3526 if ( intStep->_is_nil() ) continue;
3527 GEOM::ListOfLong_var vv = intStep->GetValues();
3528 if ( vv->length() != subIds.size() * comps->length() )
3529 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3530 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3531 for ( size_t iC = 0; iC < comps->length(); ++iC )
3532 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3535 case GEOM::FDT_Bool:
3537 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3538 if ( boolStep->_is_nil() ) continue;
3539 GEOM::short_array_var vv = boolStep->GetValues();
3540 if ( vv->length() != subIds.size() * comps->length() )
3541 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3542 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3543 for ( size_t iC = 0; iC < comps->length(); ++iC )
3544 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3550 // pass values to fieldWriter
3551 elemIt = fieldWriter.GetOrderedElems();
3552 if ( dataType == GEOM::FDT_Double )
3553 while ( elemIt->more() )
3555 const SMDS_MeshElement* e = elemIt->next();
3556 const int shapeID = e->getshapeId();
3557 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3558 for ( size_t iC = 0; iC < comps->length(); ++iC )
3559 fieldWriter.AddValue( noneDblValue );
3561 for ( size_t iC = 0; iC < comps->length(); ++iC )
3562 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3565 while ( elemIt->more() )
3567 const SMDS_MeshElement* e = elemIt->next();
3568 const int shapeID = e->getshapeId();
3569 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3570 for ( size_t iC = 0; iC < comps->length(); ++iC )
3571 fieldWriter.AddValue( (double) noneIntValue );
3573 for ( size_t iC = 0; iC < comps->length(); ++iC )
3574 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3578 fieldWriter.Perform();
3579 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3580 if ( res && res->IsKO() )
3582 if ( res->myComment.empty() )
3583 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3585 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3591 if ( !geomAssocFields || !geomAssocFields[0] )
3594 // write geomAssocFields
3596 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3597 shapeDim[ TopAbs_COMPOUND ] = 3;
3598 shapeDim[ TopAbs_COMPSOLID ] = 3;
3599 shapeDim[ TopAbs_SOLID ] = 3;
3600 shapeDim[ TopAbs_SHELL ] = 2;
3601 shapeDim[ TopAbs_FACE ] = 2;
3602 shapeDim[ TopAbs_WIRE ] = 1;
3603 shapeDim[ TopAbs_EDGE ] = 1;
3604 shapeDim[ TopAbs_VERTEX ] = 0;
3605 shapeDim[ TopAbs_SHAPE ] = 3;
3607 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3609 std::vector< std::string > compNames;
3610 switch ( geomAssocFields[ iF ]) {
3612 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3613 compNames.push_back( "dim" );
3616 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3619 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3622 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3626 compNames.push_back( "id" );
3627 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3628 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3630 fieldWriter.SetDtIt( -1, -1 );
3632 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3636 if ( compNames.size() == 2 ) // _vertices_
3637 while ( elemIt->more() )
3639 const SMDS_MeshElement* e = elemIt->next();
3640 const int shapeID = e->getshapeId();
3643 fieldWriter.AddValue( (double) -1 );
3644 fieldWriter.AddValue( (double) -1 );
3648 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3649 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3650 fieldWriter.AddValue( (double) shapeID );
3654 while ( elemIt->more() )
3656 const SMDS_MeshElement* e = elemIt->next();
3657 const int shapeID = e->getshapeId();
3659 fieldWriter.AddValue( (double) -1 );
3661 fieldWriter.AddValue( (double) shapeID );
3665 fieldWriter.Perform();
3666 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3667 if ( res && res->IsKO() )
3669 if ( res->myComment.empty() )
3670 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3672 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3675 } // loop on geomAssocFields
3680 //================================================================================
3682 * \brief Export a part of mesh to a DAT file
3684 //================================================================================
3686 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3688 throw (SALOME::SALOME_Exception)
3690 Unexpect aCatch(SALOME_SalomeException);
3692 _preMeshInfo->FullLoadFromFile();
3694 PrepareForWriting(file);
3696 SMESH_MeshPartDS partDS( meshPart );
3697 _impl->ExportDAT(file,&partDS);
3699 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3700 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3702 //================================================================================
3704 * \brief Export a part of mesh to an UNV file