1 // Copyright (C) 2007-2011 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.
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_SMESHDS_Mesh.h"
30 #include "SMDS_EdgePosition.hxx"
31 #include "SMDS_ElemIterator.hxx"
32 #include "SMDS_FacePosition.hxx"
33 #include "SMDS_IteratorOnIterators.hxx"
34 #include "SMDS_SetIterator.hxx"
35 #include "SMDS_VolumeTool.hxx"
36 #include "SMESHDS_Command.hxx"
37 #include "SMESHDS_CommandType.hxx"
38 #include "SMESHDS_GroupOnGeom.hxx"
39 #include "SMESH_Filter_i.hxx"
40 #include "SMESH_Gen_i.hxx"
41 #include "SMESH_Group.hxx"
42 #include "SMESH_Group_i.hxx"
43 #include "SMESH_MEDMesh_i.hxx"
44 #include "SMESH_MeshEditor.hxx"
45 #include "SMESH_MeshEditor_i.hxx"
46 #include "SMESH_MesherHelper.hxx"
47 #include "SMESH_PythonDump.hxx"
48 #include "SMESH_subMesh_i.hxx"
51 #include <SALOME_NamingService.hxx>
52 #include <Utils_CorbaException.hxx>
53 #include <Utils_ExceptHandlers.hxx>
54 #include <Utils_SINGLETON.hxx>
55 #include <utilities.h>
56 #include <GEOMImpl_Types.hxx>
59 #include <BRep_Builder.hxx>
60 #include <OSD_Directory.hxx>
61 #include <OSD_File.hxx>
62 #include <OSD_Path.hxx>
63 #include <OSD_Protection.hxx>
64 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
65 #include <TColStd_MapOfInteger.hxx>
66 #include <TColStd_SequenceOfInteger.hxx>
67 #include <TCollection_AsciiString.hxx>
69 #include <TopExp_Explorer.hxx>
70 #include <TopoDS_Compound.hxx>
71 #include <TopTools_MapOfShape.hxx>
72 #include <TopTools_MapIteratorOfMapOfShape.hxx>
82 static int MYDEBUG = 0;
84 static int MYDEBUG = 0;
88 using SMESH::TPythonDump;
90 int SMESH_Mesh_i::myIdGenerator = 0;
92 //To disable automatic genericobj management, the following line should be commented.
93 //Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx
94 #define WITHGENERICOBJ
96 //=============================================================================
100 //=============================================================================
102 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
104 CORBA::Long studyId )
105 : SALOME::GenericObj_i( thePOA )
107 MESSAGE("SMESH_Mesh_i");
110 _id = myIdGenerator++;
114 //=============================================================================
118 //=============================================================================
120 SMESH_Mesh_i::~SMESH_Mesh_i()
122 MESSAGE("~SMESH_Mesh_i");
124 #ifdef WITHGENERICOBJ
126 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
127 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++) {
128 if ( CORBA::is_nil( itGr->second ))
130 SMESH_GroupBase_i* aGroup = dynamic_cast<SMESH_GroupBase_i*>(SMESH_Gen_i::GetServant(itGr->second).in());
132 // this method is called from destructor of group (PAL6331)
133 //_impl->RemoveGroup( aGroup->GetLocalID() );
134 aGroup->myMeshServant = 0;
135 aGroup->UnRegister();
141 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
142 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ ) {
143 if ( CORBA::is_nil( itSM->second ))
145 SMESH_subMesh_i* aSubMesh = dynamic_cast<SMESH_subMesh_i*>(SMESH_Gen_i::GetServant(itSM->second).in());
147 aSubMesh->UnRegister();
150 _mapSubMeshIor.clear();
152 // destroy hypotheses
153 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
154 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
155 if ( CORBA::is_nil( itH->second ))
157 SMESH_Hypothesis_i* aHypo = dynamic_cast<SMESH_Hypothesis_i*>(SMESH_Gen_i::GetServant(itH->second).in());
168 //=============================================================================
172 * Associates <this> mesh with <theShape> and puts a reference
173 * to <theShape> into the current study;
174 * the previous shape is substituted by the new one.
176 //=============================================================================
178 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
179 throw (SALOME::SALOME_Exception)
181 Unexpect aCatch(SALOME_SalomeException);
183 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
185 catch(SALOME_Exception & S_ex) {
186 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
188 // to track changes of GEOM groups
189 addGeomGroupData( theShapeObject, _this() );
192 //================================================================================
194 * \brief return true if mesh has a shape to build a shape on
196 //================================================================================
198 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
199 throw (SALOME::SALOME_Exception)
201 Unexpect aCatch(SALOME_SalomeException);
204 res = _impl->HasShapeToMesh();
206 catch(SALOME_Exception & S_ex) {
207 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
212 //=======================================================================
213 //function : GetShapeToMesh
215 //=======================================================================
217 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
218 throw (SALOME::SALOME_Exception)
220 Unexpect aCatch(SALOME_SalomeException);
221 GEOM::GEOM_Object_var aShapeObj;
223 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
225 aShapeObj = _gen_i->ShapeToGeomObject( S );
227 catch(SALOME_Exception & S_ex) {
228 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
230 return aShapeObj._retn();
233 //================================================================================
235 * \brief Remove all nodes and elements
237 //================================================================================
239 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
241 Unexpect aCatch(SALOME_SalomeException);
244 CheckGeomGroupModif(); // issue 20145
246 catch(SALOME_Exception & S_ex) {
247 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
249 TPythonDump() << _this() << ".Clear()";
252 //================================================================================
254 * \brief Remove all nodes and elements for indicated shape
256 //================================================================================
258 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
259 throw (SALOME::SALOME_Exception)
261 Unexpect aCatch(SALOME_SalomeException);
263 _impl->ClearSubMesh( ShapeID );
265 catch(SALOME_Exception & S_ex) {
266 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
270 //=============================================================================
274 //=============================================================================
276 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
278 SMESH::DriverMED_ReadStatus res;
281 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
282 res = SMESH::DRS_OK; break;
283 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
284 res = SMESH::DRS_EMPTY; break;
285 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
286 res = SMESH::DRS_WARN_RENUMBER; break;
287 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
288 res = SMESH::DRS_WARN_SKIP_ELEM; break;
289 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
291 res = SMESH::DRS_FAIL; break;
296 //=============================================================================
300 * Imports mesh data from MED file
302 //=============================================================================
304 SMESH::DriverMED_ReadStatus
305 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
306 throw ( SALOME::SALOME_Exception )
308 Unexpect aCatch(SALOME_SalomeException);
311 status = _impl->MEDToMesh( theFileName, theMeshName );
313 catch( SALOME_Exception& S_ex ) {
314 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
317 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
320 CreateGroupServants();
322 int major, minor, release;
323 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
324 major = minor = release = -1;
325 myFileInfo = new SALOME_MED::MedFileInfo();
326 myFileInfo->fileName = theFileName;
327 myFileInfo->fileSize = 0;
330 if ( ::_stati64( theFileName, &d ) != -1 )
333 if ( ::stat64( theFileName, &d ) != -1 )
335 myFileInfo->fileSize = d.st_size;
336 myFileInfo->major = major;
337 myFileInfo->minor = minor;
338 myFileInfo->release = release;
340 return ConvertDriverMEDReadStatus(status);
343 //================================================================================
345 * \brief Imports mesh data from the CGNS file
347 //================================================================================
349 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
350 const int theMeshIndex,
351 std::string& theMeshName )
352 throw ( SALOME::SALOME_Exception )
354 Unexpect aCatch(SALOME_SalomeException);
357 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
359 catch( SALOME_Exception& S_ex ) {
360 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
363 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
366 CreateGroupServants();
368 return ConvertDriverMEDReadStatus(status);
371 //================================================================================
373 * \brief Return string representation of a MED file version comprising nbDigits
375 //================================================================================
377 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
379 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
381 return CORBA::string_dup( ver.c_str() );
384 //=============================================================================
388 * Imports mesh data from MED file
390 //=============================================================================
392 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
393 throw ( SALOME::SALOME_Exception )
395 // Read mesh with name = <theMeshName> into SMESH_Mesh
396 _impl->UNVToMesh( theFileName );
398 CreateGroupServants();
403 //=============================================================================
407 * Imports mesh data from STL file
409 //=============================================================================
410 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
411 throw ( SALOME::SALOME_Exception )
413 // Read mesh with name = <theMeshName> into SMESH_Mesh
414 _impl->STLToMesh( theFileName );
419 //=============================================================================
423 * Imports mesh data from MED file
425 //=============================================================================
427 // int SMESH_Mesh_i::importMEDFile( const char* theFileName, const char* theMeshName )
429 // // Read mesh with name = <theMeshName> and all its groups into SMESH_Mesh
430 // int status = _impl->MEDToMesh( theFileName, theMeshName );
431 // CreateGroupServants();
436 //=============================================================================
440 //=============================================================================
442 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
444 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
445 (SMESH_Hypothesis::Hypothesis_Status theStatus)
448 RETURNCASE( HYP_OK );
449 RETURNCASE( HYP_MISSING );
450 RETURNCASE( HYP_CONCURENT );
451 RETURNCASE( HYP_BAD_PARAMETER );
452 RETURNCASE( HYP_HIDDEN_ALGO );
453 RETURNCASE( HYP_HIDING_ALGO );
454 RETURNCASE( HYP_UNKNOWN_FATAL );
455 RETURNCASE( HYP_INCOMPATIBLE );
456 RETURNCASE( HYP_NOTCONFORM );
457 RETURNCASE( HYP_ALREADY_EXIST );
458 RETURNCASE( HYP_BAD_DIM );
459 RETURNCASE( HYP_BAD_SUBSHAPE );
460 RETURNCASE( HYP_BAD_GEOMETRY );
461 RETURNCASE( HYP_NEED_SHAPE );
464 return SMESH::HYP_UNKNOWN_FATAL;
467 //=============================================================================
471 * calls internal addHypothesis() and then adds a reference to <anHyp> under
472 * the SObject actually having a reference to <aSubShape>.
473 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
475 //=============================================================================
477 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
478 SMESH::SMESH_Hypothesis_ptr anHyp)
479 throw(SALOME::SALOME_Exception)
481 Unexpect aCatch(SALOME_SalomeException);
482 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
484 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
485 _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(),
486 aSubShapeObject, anHyp );
488 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
490 // Update Python script
491 if(_impl->HasShapeToMesh()) {
492 TPythonDump() << "status = " << _this() << ".AddHypothesis( "
493 << aSubShapeObject << ", " << anHyp << " )";
496 TPythonDump() << "status = " << _this() << ".AddHypothesis( "<< anHyp << " )";
499 return ConvertHypothesisStatus(status);
502 //=============================================================================
506 //=============================================================================
508 SMESH_Hypothesis::Hypothesis_Status
509 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
510 SMESH::SMESH_Hypothesis_ptr anHyp)
512 if(MYDEBUG) MESSAGE("addHypothesis");
514 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
515 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
518 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
519 if (CORBA::is_nil(myHyp))
520 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
523 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
526 TopoDS_Shape myLocSubShape;
527 //use PseudoShape in case if mesh has no shape
529 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
531 myLocSubShape = _impl->GetShapeToMesh();
533 int hypId = myHyp->GetId();
534 status = _impl->AddHypothesis(myLocSubShape, hypId);
535 if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
536 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp );
537 #ifdef WITHGENERICOBJ
538 _mapHypo[hypId]->Register();
540 // assure there is a corresponding submesh
541 if ( !_impl->IsMainShape( myLocSubShape )) {
542 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
543 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
544 createSubMesh( aSubShapeObject );
548 catch(SALOME_Exception & S_ex)
550 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
555 //=============================================================================
559 //=============================================================================
561 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
562 SMESH::SMESH_Hypothesis_ptr anHyp)
563 throw(SALOME::SALOME_Exception)
565 Unexpect aCatch(SALOME_SalomeException);
566 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
568 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
569 _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(),
570 aSubShapeObject, anHyp );
572 // Update Python script
573 // Update Python script
574 if(_impl->HasShapeToMesh()) {
575 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
576 << aSubShapeObject << ", " << anHyp << " )";
579 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
583 return ConvertHypothesisStatus(status);
586 //=============================================================================
590 //=============================================================================
592 SMESH_Hypothesis::Hypothesis_Status
593 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
594 SMESH::SMESH_Hypothesis_ptr anHyp)
596 if(MYDEBUG) MESSAGE("removeHypothesis()");
597 // **** proposer liste de subShape (selection multiple)
599 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
600 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", SALOME::BAD_PARAM);
602 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
603 if (CORBA::is_nil(myHyp))
604 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
606 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
609 TopoDS_Shape myLocSubShape;
610 //use PseudoShape in case if mesh has no shape
612 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
614 myLocSubShape = _impl->GetShapeToMesh();
616 int hypId = myHyp->GetId();
617 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
618 // if ( !SMESH_Hypothesis::IsStatusFatal(status) ) EAP: hyp can be used on many subshapes
619 // _mapHypo.erase( hypId );
621 catch(SALOME_Exception & S_ex)
623 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
628 //=============================================================================
632 //=============================================================================
634 SMESH::ListOfHypothesis *
635 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
636 throw(SALOME::SALOME_Exception)
638 Unexpect aCatch(SALOME_SalomeException);
639 if (MYDEBUG) MESSAGE("GetHypothesisList");
640 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
641 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", SALOME::BAD_PARAM);
643 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
646 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
647 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
648 myLocSubShape = _impl->GetShapeToMesh();
649 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
650 int i = 0, n = aLocalList.size();
653 for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
654 SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
655 if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
656 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
661 catch(SALOME_Exception & S_ex) {
662 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
665 return aList._retn();
668 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
670 Unexpect aCatch(SALOME_SalomeException);
671 if (MYDEBUG) MESSAGE("GetSubMeshes");
673 SMESH::submesh_array_var aList = new SMESH::submesh_array();
676 TPythonDump aPythonDump;
677 if ( !_mapSubMeshIor.empty() )
681 aList->length( _mapSubMeshIor.size() );
683 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
684 for ( ; it != _mapSubMeshIor.end(); it++ ) {
685 if ( CORBA::is_nil( it->second )) continue;
686 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
688 if (i > 1) aPythonDump << ", ";
689 aPythonDump << it->second;
693 catch(SALOME_Exception & S_ex) {
694 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
697 // Update Python script
698 if ( !_mapSubMeshIor.empty() )
699 aPythonDump << " ] = " << _this() << ".GetSubMeshes()";
701 return aList._retn();
704 //=============================================================================
708 //=============================================================================
709 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
710 const char* theName )
711 throw(SALOME::SALOME_Exception)
713 Unexpect aCatch(SALOME_SalomeException);
714 MESSAGE("SMESH_Mesh_i::GetSubMesh");
715 if (CORBA::is_nil(aSubShapeObject))
716 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
719 SMESH::SMESH_subMesh_var subMesh;
720 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(_this());
722 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
724 //Get or Create the SMESH_subMesh object implementation
726 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
728 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
730 TopoDS_Iterator it( myLocSubShape );
732 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
734 subMesh = getSubMesh( subMeshId );
736 // create a new subMesh object servant if there is none for the shape
737 if ( subMesh->_is_nil() )
738 subMesh = createSubMesh( aSubShapeObject );
739 if ( _gen_i->CanPublishInStudy( subMesh )) {
740 SALOMEDS::SObject_var aSO =
741 _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
742 subMesh, aSubShapeObject, theName );
743 if ( !aSO->_is_nil()) {
744 // Update Python script
745 TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( "
746 << aSubShapeObject << ", '" << theName << "' )";
750 catch(SALOME_Exception & S_ex) {
751 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
753 return subMesh._retn();
756 //=============================================================================
760 //=============================================================================
762 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
763 throw (SALOME::SALOME_Exception)
765 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
766 if ( theSubMesh->_is_nil() )
769 GEOM::GEOM_Object_var aSubShapeObject;
770 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
771 if ( !aStudy->_is_nil() ) {
772 // Remove submesh's SObject
773 SALOMEDS::SObject_var anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
774 if ( !anSO->_is_nil() ) {
775 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
776 SALOMEDS::SObject_var anObj, aRef;
777 if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) )
778 aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
780 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
781 // aSubShapeObject = theSubMesh->GetSubShape();
783 aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
785 // Update Python script
786 TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )";
790 removeSubMesh( theSubMesh, aSubShapeObject.in() );
793 //=============================================================================
797 //=============================================================================
799 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
800 const char* theName )
801 throw(SALOME::SALOME_Exception)
803 Unexpect aCatch(SALOME_SalomeException);
804 SMESH::SMESH_Group_var aNewGroup =
805 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
807 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
808 SALOMEDS::SObject_var aSO =
809 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
810 aNewGroup, GEOM::GEOM_Object::_nil(), theName);
811 if ( !aSO->_is_nil()) {
812 // Update Python script
813 TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
814 << theElemType << ", '" << theName << "' )";
817 return aNewGroup._retn();
821 //=============================================================================
825 //=============================================================================
826 SMESH::SMESH_GroupOnGeom_ptr
827 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
829 GEOM::GEOM_Object_ptr theGeomObj)
830 throw(SALOME::SALOME_Exception)
832 Unexpect aCatch(SALOME_SalomeException);
833 SMESH::SMESH_GroupOnGeom_var aNewGroup;
835 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
836 if ( !aShape.IsNull() )
838 aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
839 ( createGroup( theElemType, theName, aShape ));
841 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
842 SALOMEDS::SObject_var aSO =
843 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
844 aNewGroup, theGeomObj, theName);
845 if ( !aSO->_is_nil()) {
846 // Update Python script
847 TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
848 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
853 return aNewGroup._retn();
856 //================================================================================
858 * \brief Creates a group whose contents is defined by filter
859 * \param theElemType - group type
860 * \param theName - group name
861 * \param theFilter - the filter
862 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
864 //================================================================================
866 SMESH::SMESH_GroupOnFilter_ptr
867 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
869 SMESH::Filter_ptr theFilter )
870 throw (SALOME::SALOME_Exception)
872 Unexpect aCatch(SALOME_SalomeException);
874 if ( CORBA::is_nil( theFilter ))
875 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
877 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
879 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
881 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
882 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
885 if ( !aNewGroup->_is_nil() )
886 aNewGroup->SetFilter( theFilter );
888 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
890 SALOMEDS::SObject_var aSO =
891 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), aNewGroup,
892 GEOM::GEOM_Object::_nil(), theName);
893 if ( !aSO->_is_nil()) {
894 // Update Python script
895 pd << aSO << " = " << _this() << ".CreateGroupFromFilter("
896 << theElemType << ", '" << theName << "', " << theFilter << " )";
900 return aNewGroup._retn();
903 //=============================================================================
907 //=============================================================================
909 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
910 throw (SALOME::SALOME_Exception)
912 if ( theGroup->_is_nil() )
915 SMESH_GroupBase_i* aGroup =
916 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
920 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
921 if ( !aStudy->_is_nil() ) {
922 SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
924 if ( !aGroupSO->_is_nil() ) {
925 // Update Python script
926 TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
928 // Remove group's SObject
929 aStudy->NewBuilder()->RemoveObjectWithChildren( aGroupSO );
933 // Remove the group from SMESH data structures
934 removeGroup( aGroup->GetLocalID() );
937 //=============================================================================
938 /*! RemoveGroupWithContents
939 * Remove group with its contents
941 //=============================================================================
942 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
943 throw (SALOME::SALOME_Exception)
945 if ( theGroup->_is_nil() )
948 SMESH_GroupBase_i* aGroup =
949 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
953 SMESH::long_array_var anIds = aGroup->GetListOfID();
954 SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
956 TPythonDump pyDump; // Supress dump from RemoveNodes/Elements() and RemoveGroup()
959 if ( aGroup->GetType() == SMESH::NODE )
960 aMeshEditor->RemoveNodes( anIds );
962 aMeshEditor->RemoveElements( anIds );
965 RemoveGroup( theGroup );
967 // Update Python script
968 pyDump << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
971 //================================================================================
973 * \brief Get the list of groups existing in the mesh
974 * \retval SMESH::ListOfGroups * - list of groups
976 //================================================================================
978 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
980 Unexpect aCatch(SALOME_SalomeException);
981 if (MYDEBUG) MESSAGE("GetGroups");
983 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
986 TPythonDump aPythonDump;
987 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
991 aList->length( _mapGroups.size() );
993 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
994 for ( ; it != _mapGroups.end(); it++ ) {
995 if ( CORBA::is_nil( it->second )) continue;
996 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
998 if (i > 1) aPythonDump << ", ";
999 aPythonDump << it->second;
1003 catch(SALOME_Exception & S_ex) {
1004 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1007 // Update Python script
1008 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
1009 aPythonDump << " ] = " << _this() << ".GetGroups()";
1011 return aList._retn();
1014 //=============================================================================
1016 * Get number of groups existing in the mesh
1018 //=============================================================================
1020 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1022 Unexpect aCatch(SALOME_SalomeException);
1023 return _mapGroups.size();
1026 //=============================================================================
1028 * New group is created. All mesh elements that are
1029 * present in initial groups are added to the new one
1031 //=============================================================================
1032 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1033 SMESH::SMESH_GroupBase_ptr theGroup2,
1034 const char* theName )
1035 throw (SALOME::SALOME_Exception)
1039 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1040 theGroup1->GetType() != theGroup2->GetType() )
1041 return SMESH::SMESH_Group::_nil();
1044 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1045 if ( aResGrp->_is_nil() )
1046 return SMESH::SMESH_Group::_nil();
1048 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1049 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1051 TColStd_MapOfInteger aResMap;
1053 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1054 aResMap.Add( anIds1[ i1 ] );
1056 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1057 aResMap.Add( anIds2[ i2 ] );
1059 SMESH::long_array_var aResIds = new SMESH::long_array;
1060 aResIds->length( aResMap.Extent() );
1063 TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
1064 for( ; anIter.More(); anIter.Next() )
1065 aResIds[ resI++ ] = anIter.Key();
1067 aResGrp->Add( aResIds );
1069 // Clear python lines, created by CreateGroup() and Add()
1070 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1071 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1072 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1074 // Update Python script
1075 TPythonDump() << aResGrp << " = " << _this() << ".UnionGroups( "
1076 << theGroup1 << ", " << theGroup2 << ", '"
1077 << theName << "' )";
1079 return aResGrp._retn();
1083 return SMESH::SMESH_Group::_nil();
1087 //=============================================================================
1089 \brief Union list of groups. New group is created. All mesh elements that are
1090 present in initial groups are added to the new one.
1091 \param theGroups list of groups
1092 \param theName name of group to be created
1093 \return pointer on the group
1095 //=============================================================================
1096 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1097 const char* theName )
1098 throw (SALOME::SALOME_Exception)
1101 return SMESH::SMESH_Group::_nil();
1105 vector< int > anIds;
1106 SMESH::ElementType aType = SMESH::ALL;
1107 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1109 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1110 if ( CORBA::is_nil( aGrp ) )
1114 SMESH::ElementType aCurrType = aGrp->GetType();
1115 if ( aType == SMESH::ALL )
1119 if ( aType != aCurrType )
1120 return SMESH::SMESH_Group::_nil();
1124 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1125 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1127 int aCurrId = aCurrIds[ i ];
1128 anIds.push_back( aCurrId );
1133 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1134 if ( aResGrp->_is_nil() )
1135 return SMESH::SMESH_Group::_nil();
1137 // Create array of identifiers
1138 SMESH::long_array_var aResIds = new SMESH::long_array;
1139 aResIds->length( anIds.size() );
1141 //NCollection_Map< int >::Iterator anIter( anIds );
1142 for ( int i = 0; i<anIds.size(); i++ )
1144 aResIds[ i ] = anIds[i];
1146 aResGrp->Add( aResIds );
1148 // Clear python lines, created by CreateGroup() and Add()
1149 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1150 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1151 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1153 // Update Python script
1155 TPythonDump() << aResGrp << " = " << _this() << ".UnionListOfGroups( "
1156 << &theGroups << ", '" << theName << "' )";
1158 return aResGrp._retn();
1162 return SMESH::SMESH_Group::_nil();
1166 //=============================================================================
1168 * New group is created. All mesh elements that are
1169 * present in both initial groups are added to the new one.
1171 //=============================================================================
1172 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1173 SMESH::SMESH_GroupBase_ptr theGroup2,
1174 const char* theName )
1175 throw (SALOME::SALOME_Exception)
1177 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1178 theGroup1->GetType() != theGroup2->GetType() )
1179 return SMESH::SMESH_Group::_nil();
1181 // Create Intersection
1182 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1183 if ( aResGrp->_is_nil() )
1186 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1187 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1189 TColStd_MapOfInteger aMap1;
1191 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1192 aMap1.Add( anIds1[ i1 ] );
1194 TColStd_SequenceOfInteger aSeq;
1196 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1197 if ( aMap1.Contains( anIds2[ i2 ] ) )
1198 aSeq.Append( anIds2[ i2 ] );
1200 SMESH::long_array_var aResIds = new SMESH::long_array;
1201 aResIds->length( aSeq.Length() );
1203 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1204 aResIds[ resI ] = aSeq( resI + 1 );
1206 aResGrp->Add( aResIds );
1208 // Clear python lines, created by CreateGroup() and Add()
1209 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1210 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1211 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1213 // Update Python script
1214 TPythonDump() << aResGrp << " = " << _this() << ".IntersectGroups( "
1215 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1217 return aResGrp._retn();
1220 //=============================================================================
1222 \brief Intersect list of groups. New group is created. All mesh elements that
1223 are present in all initial groups simultaneously are added to the new one.
1224 \param theGroups list of groups
1225 \param theName name of group to be created
1226 \return pointer on the group
1228 //=============================================================================
1229 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectListOfGroups(
1230 const SMESH::ListOfGroups& theGroups, const char* theName )
1231 throw (SALOME::SALOME_Exception)
1234 return SMESH::SMESH_Group::_nil();
1238 NCollection_DataMap< int, int > anIdToCount;
1239 SMESH::ElementType aType = SMESH::ALL;
1240 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1242 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1243 if ( CORBA::is_nil( aGrp ) )
1247 SMESH::ElementType aCurrType = aGrp->GetType();
1248 if ( aType == SMESH::ALL )
1252 if ( aType != aCurrType )
1253 return SMESH::SMESH_Group::_nil();
1256 // calculates number of occurance ids in groups
1257 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1258 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1260 int aCurrId = aCurrIds[ i ];
1261 if ( !anIdToCount.IsBound( aCurrId ) )
1262 anIdToCount.Bind( aCurrId, 1 );
1264 anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
1268 // create map of ids
1269 int nbGrp = theGroups.length();
1270 vector< int > anIds;
1271 NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
1272 for ( ; anIter.More(); anIter.Next() )
1274 int aCurrId = anIter.Key();
1275 int aCurrNb = anIter.Value();
1276 if ( aCurrNb == nbGrp )
1277 anIds.push_back( aCurrId );
1281 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1282 if ( aResGrp->_is_nil() )
1283 return SMESH::SMESH_Group::_nil();
1285 // Create array of identifiers
1286 SMESH::long_array_var aResIds = new SMESH::long_array;
1287 aResIds->length( anIds.size() );
1289 //NCollection_Map< int >::Iterator aListIter( anIds );
1290 for ( int i = 0; i<anIds.size(); i++ )
1292 aResIds[ i ] = anIds[i];
1294 aResGrp->Add( aResIds );
1296 // Clear python lines, created by CreateGroup() and Add()
1297 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1298 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1299 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1301 // Update Python script
1303 TPythonDump() << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
1304 << &theGroups << ", '" << theName << "' )";
1306 return aResGrp._retn();
1310 return SMESH::SMESH_Group::_nil();
1314 //=============================================================================
1316 * New group is created. All mesh elements that are present in
1317 * main group but do not present in tool group are added to the new one
1319 //=============================================================================
1320 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1321 SMESH::SMESH_GroupBase_ptr theGroup2,
1322 const char* theName )
1323 throw (SALOME::SALOME_Exception)
1325 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1326 theGroup1->GetType() != theGroup2->GetType() )
1327 return SMESH::SMESH_Group::_nil();
1330 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1331 if ( aResGrp->_is_nil() )
1334 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1335 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1337 TColStd_MapOfInteger aMap2;
1339 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1340 aMap2.Add( anIds2[ i2 ] );
1342 TColStd_SequenceOfInteger aSeq;
1343 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1344 if ( !aMap2.Contains( anIds1[ i1 ] ) )
1345 aSeq.Append( anIds1[ i1 ] );
1347 SMESH::long_array_var aResIds = new SMESH::long_array;
1348 aResIds->length( aSeq.Length() );
1350 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1351 aResIds[ resI ] = aSeq( resI + 1 );
1353 aResGrp->Add( aResIds );
1355 // Clear python lines, created by CreateGroup() and Add()
1356 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1357 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1358 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1360 // Update Python script
1361 TPythonDump() << aResGrp << " = " << _this() << ".CutGroups( "
1362 << theGroup1 << ", " << theGroup2 << ", '"
1363 << theName << "' )";
1365 return aResGrp._retn();
1368 //=============================================================================
1370 \brief Cut lists of groups. New group is created. All mesh elements that are
1371 present in main groups but do not present in tool groups are added to the new one
1372 \param theMainGroups list of main groups
1373 \param theToolGroups list of tool groups
1374 \param theName name of group to be created
1375 \return pointer on the group
1377 //=============================================================================
1378 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups(
1379 const SMESH::ListOfGroups& theMainGroups,
1380 const SMESH::ListOfGroups& theToolGroups,
1381 const char* theName )
1382 throw (SALOME::SALOME_Exception)
1385 return SMESH::SMESH_Group::_nil();
1389 set< int > aToolIds;
1390 SMESH::ElementType aType = SMESH::ALL;
1392 // iterate through tool groups
1393 for ( g = 0, n = theToolGroups.length(); g < n; g++ )
1395 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1396 if ( CORBA::is_nil( aGrp ) )
1400 SMESH::ElementType aCurrType = aGrp->GetType();
1401 if ( aType == SMESH::ALL )
1405 if ( aType != aCurrType )
1406 return SMESH::SMESH_Group::_nil();
1410 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1411 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1413 int aCurrId = aCurrIds[ i ];
1414 aToolIds.insert( aCurrId );
1418 vector< int > anIds; // result
1420 // Iterate through main group
1421 for ( g = 0, n = theMainGroups.length(); g < n; g++ )
1423 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1424 if ( CORBA::is_nil( aGrp ) )
1428 SMESH::ElementType aCurrType = aGrp->GetType();
1429 if ( aType == SMESH::ALL )
1433 if ( aType != aCurrType )
1434 return SMESH::SMESH_Group::_nil();
1438 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1439 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1441 int aCurrId = aCurrIds[ i ];
1442 if ( !aToolIds.count( aCurrId ) )
1443 anIds.push_back( aCurrId );
1448 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1449 if ( aResGrp->_is_nil() )
1450 return SMESH::SMESH_Group::_nil();
1452 // Create array of identifiers
1453 SMESH::long_array_var aResIds = new SMESH::long_array;
1454 aResIds->length( anIds.size() );
1456 for (int i=0; i<anIds.size(); i++ )
1458 aResIds[ i ] = anIds[i];
1460 aResGrp->Add( aResIds );
1462 // Clear python lines, created by CreateGroup() and Add()
1463 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1464 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1465 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1467 // Update Python script
1469 TPythonDump() << aResGrp << " = " << _this() << ".CutListOfGroups( "
1470 << &theMainGroups << ", " << &theToolGroups << ", '"
1471 << theName << "' )";
1473 return aResGrp._retn();
1477 return SMESH::SMESH_Group::_nil();
1481 //=============================================================================
1483 \brief Create groups of entities from existing groups of superior dimensions
1485 1) extract all nodes from each group,
1486 2) combine all elements of specified dimension laying on these nodes.
1487 \param theGroups list of source groups
1488 \param theElemType dimension of elements
1489 \param theName name of new group
1490 \return pointer on new group
1492 //=============================================================================
1493 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
1494 const SMESH::ListOfGroups& theGroups,
1495 SMESH::ElementType theElemType,
1496 const char* theName )
1497 throw (SALOME::SALOME_Exception)
1499 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1501 if ( !theName || !aMeshDS )
1502 return SMESH::SMESH_Group::_nil();
1504 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1508 // Create map of nodes from all groups
1510 set< int > aNodeMap;
1512 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1514 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1515 if ( CORBA::is_nil( aGrp ) )
1518 SMESH::ElementType aType = aGrp->GetType();
1519 if ( aType == SMESH::ALL )
1521 else if ( aType == SMESH::NODE )
1523 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1524 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1526 int aCurrId = aCurrIds[ i ];
1527 const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
1529 aNodeMap.insert( aNode->GetID() );
1534 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1535 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1537 int aCurrId = aCurrIds[ i ];
1538 const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId );
1541 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1542 while( aNodeIter->more() )
1544 const SMDS_MeshNode* aNode =
1545 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1547 aNodeMap.insert( aNode->GetID() );
1553 // Get result identifiers
1555 vector< int > aResultIds;
1556 if ( theElemType == SMESH::NODE )
1558 //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1559 set<int>::iterator iter = aNodeMap.begin();
1560 for ( ; iter != aNodeMap.end(); iter++ )
1561 aResultIds.push_back( *iter);
1565 // Create list of elements of given dimension constructed on the nodes
1566 vector< int > anElemList;
1567 //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1568 //for ( ; aNodeIter.More(); aNodeIter.Next() )
1569 set<int>::iterator iter = aNodeMap.begin();
1570 for ( ; iter != aNodeMap.end(); iter++ )
1572 const SMDS_MeshElement* aNode =
1573 dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( *iter ) );
1577 SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType );
1578 while( anElemIter->more() )
1580 const SMDS_MeshElement* anElem =
1581 dynamic_cast<const SMDS_MeshElement*>( anElemIter->next() );
1582 if ( anElem && anElem->GetType() == anElemType )
1583 anElemList.push_back( anElem->GetID() );
1587 // check whether all nodes of elements are present in nodes map
1588 //NCollection_Map< int >::Iterator anIter( anElemList );
1589 //for ( ; anIter.More(); anIter.Next() )
1590 for (int i=0; i< anElemList.size(); i++)
1592 const SMDS_MeshElement* anElem = aMeshDS->FindElement( anElemList[i] );
1597 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1598 while( aNodeIter->more() )
1600 const SMDS_MeshNode* aNode =
1601 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1602 if ( !aNode || !aNodeMap.count( aNode->GetID() ) )
1609 aResultIds.push_back( anElem->GetID() );
1615 SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName );
1616 if ( aResGrp->_is_nil() )
1617 return SMESH::SMESH_Group::_nil();
1619 // Create array of identifiers
1620 SMESH::long_array_var aResIds = new SMESH::long_array;
1621 aResIds->length( aResultIds.size() );
1623 //NCollection_Map< int >::Iterator aResIter( aResultIds );
1624 //for ( int i = 0; aResIter.More(); aResIter.Next(), i++ )
1625 for (int i=0; i< aResultIds.size(); i++)
1626 aResIds[ i ] = aResultIds[i];
1627 aResGrp->Add( aResIds );
1629 // Remove strings corresponding to group creation
1630 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1631 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1632 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1634 // Update Python script
1636 TPythonDump() << aResGrp << " = " << _this() << ".CreateDimGroup( "
1637 << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1639 return aResGrp._retn();
1643 return SMESH::SMESH_Group::_nil();
1647 //================================================================================
1649 * \brief Remember GEOM group data
1651 //================================================================================
1653 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1654 CORBA::Object_ptr theSmeshObj)
1656 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1659 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1660 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1661 if ( groupSO->_is_nil() )
1664 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1665 GEOM::GEOM_IGroupOperations_var groupOp =
1666 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1667 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1670 _geomGroupData.push_back( TGeomGroupData() );
1671 TGeomGroupData & groupData = _geomGroupData.back();
1673 CORBA::String_var entry = groupSO->GetID();
1674 groupData._groupEntry = entry.in();
1676 for ( int i = 0; i < ids->length(); ++i )
1677 groupData._indices.insert( ids[i] );
1679 groupData._smeshObject = theSmeshObj;
1682 //================================================================================
1684 * Remove GEOM group data relating to removed smesh object
1686 //================================================================================
1688 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1690 list<TGeomGroupData>::iterator
1691 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1692 for ( ; data != dataEnd; ++data ) {
1693 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1694 _geomGroupData.erase( data );
1700 //================================================================================
1702 * \brief Return new group contents if it has been changed and update group data
1704 //================================================================================
1706 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1708 TopoDS_Shape newShape;
1711 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1712 if ( study->_is_nil() ) return newShape; // means "not changed"
1713 SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1714 if ( !groupSO->_is_nil() )
1716 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1717 if ( CORBA::is_nil( groupObj )) return newShape;
1718 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1720 // get indices of group items
1721 set<int> curIndices;
1722 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1723 GEOM::GEOM_IGroupOperations_var groupOp =
1724 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1725 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1726 for ( int i = 0; i < ids->length(); ++i )
1727 curIndices.insert( ids[i] );
1729 if ( groupData._indices == curIndices )
1730 return newShape; // group not changed
1733 groupData._indices = curIndices;
1735 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1736 if ( !geomClient ) return newShape;
1737 TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1738 geomClient->RemoveShapeFromBuffer( groupIOR );
1739 newShape = _gen_i->GeomObjectToShape( geomGroup );
1742 if ( newShape.IsNull() ) {
1743 // geom group becomes empty - return empty compound
1744 TopoDS_Compound compound;
1745 BRep_Builder().MakeCompound(compound);
1746 newShape = compound;
1752 //=============================================================================
1754 * \brief Storage of shape and index used in CheckGeomGroupModif()
1756 //=============================================================================
1757 struct TIndexedShape {
1759 TopoDS_Shape _shape;
1760 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1763 //=============================================================================
1765 * \brief Update objects depending on changed geom groups
1767 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1768 * issue 0020210: Update of a smesh group after modification of the associated geom group
1770 //=============================================================================
1772 void SMESH_Mesh_i::CheckGeomGroupModif()
1774 if ( !_impl->HasShapeToMesh() ) return;
1776 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1777 if ( study->_is_nil() ) return;
1779 CORBA::Long nbEntities = NbNodes() + NbElements();
1781 // Check if group contents changed
1783 typedef map< string, TopoDS_Shape > TEntry2Geom;
1784 TEntry2Geom newGroupContents;
1786 list<TGeomGroupData>::iterator
1787 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1788 for ( ; data != dataEnd; ++data )
1790 pair< TEntry2Geom::iterator, bool > it_new =
1791 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1792 bool processedGroup = !it_new.second;
1793 TopoDS_Shape& newShape = it_new.first->second;
1794 if ( !processedGroup )
1795 newShape = newGroupShape( *data );
1796 if ( newShape.IsNull() )
1797 continue; // no changes
1799 if ( processedGroup ) { // update group indices
1800 list<TGeomGroupData>::iterator data2 = data;
1801 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1802 data->_indices = data2->_indices;
1805 // Update SMESH objects according to new GEOM group contents
1807 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1808 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1810 int oldID = submesh->GetId();
1811 if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1813 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1815 // update hypotheses
1816 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1817 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1818 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1820 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1821 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1823 // care of submeshes
1824 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1825 int newID = newSubmesh->GetId();
1826 if ( newID != oldID ) {
1827 _mapSubMesh [ newID ] = newSubmesh;
1828 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1829 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1830 _mapSubMesh. erase(oldID);
1831 _mapSubMesh_i. erase(oldID);
1832 _mapSubMeshIor.erase(oldID);
1833 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1838 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1839 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1840 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1842 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1844 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1845 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1846 ds->SetShape( newShape );
1851 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1852 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1854 // Remove groups and submeshes basing on removed sub-shapes
1856 TopTools_MapOfShape newShapeMap;
1857 TopoDS_Iterator shapeIt( newShape );
1858 for ( ; shapeIt.More(); shapeIt.Next() )
1859 newShapeMap.Add( shapeIt.Value() );
1861 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1862 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1864 if ( newShapeMap.Contains( shapeIt.Value() ))
1866 TopTools_IndexedMapOfShape oldShapeMap;
1867 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1868 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1870 const TopoDS_Shape& oldShape = oldShapeMap(i);
1871 int oldInd = meshDS->ShapeToIndex( oldShape );
1873 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1874 if ( i_smIor != _mapSubMeshIor.end() ) {
1875 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1878 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1879 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1881 // check if a group bases on oldInd shape
1882 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1883 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1884 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1885 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1887 RemoveGroup( i_grp->second ); // several groups can base on same shape
1888 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1893 // Reassign hypotheses and update groups after setting the new shape to mesh
1895 // collect anassigned hypotheses
1896 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1897 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1898 TShapeHypList assignedHyps;
1899 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1901 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1902 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1903 if ( !hyps.empty() ) {
1904 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1905 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1906 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1909 // collect shapes supporting groups
1910 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1911 TShapeTypeList groupData;
1912 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1913 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1914 for ( ; grIt != groups.end(); ++grIt )
1916 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1918 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1920 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1921 _impl->ShapeToMesh( newShape );
1923 // reassign hypotheses
1924 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1925 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1927 TIndexedShape& geom = indS_hyps->first;
1928 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1929 int oldID = geom._index;
1930 int newID = meshDS->ShapeToIndex( geom._shape );
1933 if ( oldID == 1 ) { // main shape
1935 geom._shape = newShape;
1937 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1938 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
1939 // care of submeshes
1940 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
1941 if ( newID != oldID ) {
1942 _mapSubMesh [ newID ] = newSubmesh;
1943 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1944 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1945 _mapSubMesh. erase(oldID);
1946 _mapSubMesh_i. erase(oldID);
1947 _mapSubMeshIor.erase(oldID);
1948 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1952 TShapeTypeList::iterator geomType = groupData.begin();
1953 for ( ; geomType != groupData.end(); ++geomType )
1955 const TIndexedShape& geom = geomType->first;
1956 int oldID = geom._index;
1957 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
1960 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
1961 CORBA::String_var name = groupSO->GetName();
1963 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
1965 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
1966 group_i->changeLocalId( newID );
1969 break; // everything has been updated
1972 } // loop on group data
1976 CORBA::Long newNbEntities = NbNodes() + NbElements();
1977 list< SALOMEDS::SObject_var > soToUpdateIcons;
1978 if ( newNbEntities != nbEntities )
1980 // Add all SObjects with icons
1981 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
1983 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
1984 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
1985 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
1987 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
1988 i_gr != _mapGroups.end(); ++i_gr ) // groups
1989 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
1992 list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin();
1993 for ( ; so != soToUpdateIcons.end(); ++so )
1994 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
1997 //=============================================================================
1999 * \brief Create standalone group from a group on geometry or filter
2001 //=============================================================================
2003 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2005 SMESH::SMESH_Group_var aGroup;
2006 if ( theGroup->_is_nil() )
2007 return aGroup._retn();
2009 Unexpect aCatch(SALOME_SalomeException);
2011 SMESH_GroupBase_i* aGroupToRem =
2012 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
2014 return aGroup._retn();
2016 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2018 int anId = aGroupToRem->GetLocalID();
2019 if ( !_impl->ConvertToStandalone( anId ) )
2020 return aGroup._retn();
2021 removeGeomGroupData( theGroup );
2023 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2025 // remove old instance of group from own map
2026 _mapGroups.erase( anId );
2028 SALOMEDS::StudyBuilder_var builder;
2029 SALOMEDS::SObject_var aGroupSO;
2030 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2031 if ( !aStudy->_is_nil() ) {
2032 builder = aStudy->NewBuilder();
2033 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2034 if ( !aGroupSO->_is_nil() ) {
2036 // remove reference to geometry
2037 SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO);
2038 for ( ; chItr->More(); chItr->Next() )
2039 // Remove group's child SObject
2040 builder->RemoveObject( chItr->Value() );
2042 // Update Python script
2043 TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
2044 << aGroupSO << " )";
2046 // change icon of Group on Filter
2049 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2050 const int isEmpty = ( elemTypes->length() == 0 );
2053 SALOMEDS::GenericAttribute_var anAttr =
2054 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2055 SALOMEDS::AttributePixMap_var pm = SALOMEDS::AttributePixMap::_narrow( anAttr );
2056 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2062 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2063 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2064 aGroupImpl->Register();
2065 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2067 // remember new group in own map
2068 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2069 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2071 // register CORBA object for persistence
2072 /*int nextId =*/ _gen_i->RegisterObject( aGroup );
2074 builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) );
2076 return aGroup._retn();
2079 //=============================================================================
2083 //=============================================================================
2085 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2087 if(MYDEBUG) MESSAGE( "createSubMesh" );
2088 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2090 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2091 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
2092 SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2093 SMESH::SMESH_subMesh_var subMesh
2094 = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
2096 _mapSubMesh[subMeshId] = mySubMesh;
2097 _mapSubMesh_i[subMeshId] = subMeshServant;
2098 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
2100 // register CORBA object for persistence
2101 int nextId = _gen_i->RegisterObject( subMesh );
2102 if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
2104 // to track changes of GEOM groups
2105 addGeomGroupData( theSubShapeObject, subMesh );
2107 return subMesh._retn();
2110 //=======================================================================
2111 //function : getSubMesh
2113 //=======================================================================
2115 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2117 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2118 if ( it == _mapSubMeshIor.end() )
2119 return SMESH::SMESH_subMesh::_nil();
2121 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2125 //=============================================================================
2129 //=============================================================================
2131 void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2132 GEOM::GEOM_Object_ptr theSubShapeObject )
2134 MESSAGE("SMESH_Mesh_i::removeSubMesh()");
2135 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2138 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2140 CORBA::Long shapeId = theSubMesh->GetId();
2141 if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
2143 TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
2146 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2147 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2148 for ( ; hyp != hyps.end(); ++hyp )
2149 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2156 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2157 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2158 removeHypothesis( theSubShapeObject, aHypList[i] );
2161 catch( const SALOME::SALOME_Exception& ) {
2162 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2164 removeGeomGroupData( theSubShapeObject );
2166 int subMeshId = theSubMesh->GetId();
2168 _mapSubMesh.erase(subMeshId);
2169 _mapSubMesh_i.erase(subMeshId);
2170 _mapSubMeshIor.erase(subMeshId);
2171 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeSubMesh() completed");
2174 //=============================================================================
2178 //=============================================================================
2180 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2181 const char* theName,
2182 const TopoDS_Shape& theShape,
2183 const SMESH_PredicatePtr& thePredicate )
2185 std::string newName;
2186 if ( !theName || strlen( theName ) == 0 )
2188 std::set< std::string > presentNames;
2189 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2190 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2191 presentNames.insert( i_gr->second->GetName() );
2193 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2194 } while ( !presentNames.insert( newName ).second );
2195 theName = newName.c_str();
2198 SMESH::SMESH_GroupBase_var aGroup;
2199 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2201 SMESH_GroupBase_i* aGroupImpl;
2202 if ( !theShape.IsNull() )
2203 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2204 else if ( thePredicate )
2205 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2207 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2209 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2210 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2211 aGroupImpl->Register();
2212 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2214 aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2215 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2217 // register CORBA object for persistence
2218 int nextId = _gen_i->RegisterObject( aGroup );
2219 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2221 // to track changes of GEOM groups
2222 if ( !theShape.IsNull() ) {
2223 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2224 addGeomGroupData( geom, aGroup );
2227 return aGroup._retn();
2230 //=============================================================================
2232 * SMESH_Mesh_i::removeGroup
2234 * Should be called by ~SMESH_Group_i()
2236 //=============================================================================
2238 void SMESH_Mesh_i::removeGroup( const int theId )
2240 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2241 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2242 SMESH::SMESH_GroupBase_ptr group = _mapGroups[theId];
2243 _mapGroups.erase( theId );
2244 removeGeomGroupData( group );
2245 if (! _impl->RemoveGroup( theId ))
2247 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2248 RemoveGroup( group );
2253 //=============================================================================
2257 //=============================================================================
2259 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2260 throw(SALOME::SALOME_Exception)
2262 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetLog");
2264 SMESH::log_array_var aLog;
2266 list < SMESHDS_Command * >logDS = _impl->GetLog();
2267 aLog = new SMESH::log_array;
2269 int lg = logDS.size();
2272 list < SMESHDS_Command * >::iterator its = logDS.begin();
2273 while(its != logDS.end()){
2274 SMESHDS_Command *com = *its;
2275 int comType = com->GetType();
2277 int lgcom = com->GetNumber();
2279 const list < int >&intList = com->GetIndexes();
2280 int inum = intList.size();
2282 list < int >::const_iterator ii = intList.begin();
2283 const list < double >&coordList = com->GetCoords();
2284 int rnum = coordList.size();
2286 list < double >::const_iterator ir = coordList.begin();
2287 aLog[indexLog].commandType = comType;
2288 aLog[indexLog].number = lgcom;
2289 aLog[indexLog].coords.length(rnum);
2290 aLog[indexLog].indexes.length(inum);
2291 for(int i = 0; i < rnum; i++){
2292 aLog[indexLog].coords[i] = *ir;
2293 //MESSAGE(" "<<i<<" "<<ir.Value());
2296 for(int i = 0; i < inum; i++){
2297 aLog[indexLog].indexes[i] = *ii;
2298 //MESSAGE(" "<<i<<" "<<ii.Value());
2307 catch(SALOME_Exception & S_ex){
2308 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
2310 return aLog._retn();
2314 //=============================================================================
2318 //=============================================================================
2320 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2322 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
2326 //=============================================================================
2330 //=============================================================================
2332 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2334 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
2338 //=============================================================================
2342 //=============================================================================
2344 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2349 //=============================================================================
2352 //!< implementation of struct used to call SMESH_Mesh_i::removeGroup() from
2353 // SMESH_Mesh::RemoveGroup() (issue 0020918)
2354 struct TRmGroupCallUp_i : public SMESH_Mesh::TRmGroupCallUp
2356 SMESH_Mesh_i* _mesh;
2357 TRmGroupCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2358 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2362 //=============================================================================
2366 //=============================================================================
2368 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2370 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2373 _impl->SetRemoveGroupCallUp( new TRmGroupCallUp_i(this));
2376 //=============================================================================
2380 //=============================================================================
2382 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2384 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2388 //=============================================================================
2390 * Return mesh editor
2392 //=============================================================================
2394 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2396 // Create MeshEditor
2397 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
2398 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2400 // Update Python script
2401 TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
2403 return aMesh._retn();
2406 //=============================================================================
2408 * Return mesh edition previewer
2410 //=============================================================================
2412 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2414 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
2415 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2416 return aMesh._retn();
2419 //================================================================================
2421 * \brief Return true if the mesh has been edited since a last total re-compute
2422 * and those modifications may prevent successful partial re-compute
2424 //================================================================================
2426 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2428 Unexpect aCatch(SALOME_SalomeException);
2429 return _impl->HasModificationsToDiscard();
2432 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2434 const int MAX_ATTEMPTS = 100;
2436 double tolerance = 0.5;
2437 SALOMEDS::Color col;
2441 // generate random color
2442 double red = (double)rand() / RAND_MAX;
2443 double green = (double)rand() / RAND_MAX;
2444 double blue = (double)rand() / RAND_MAX;
2445 // check existence in the list of the existing colors
2446 bool matched = false;
2447 std::list<SALOMEDS::Color>::const_iterator it;
2448 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2449 SALOMEDS::Color color = *it;
2450 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2451 matched = tol < tolerance;
2453 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2454 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2462 //=============================================================================
2466 //=============================================================================
2467 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2469 Unexpect aCatch(SALOME_SalomeException);
2470 _impl->SetAutoColor(theAutoColor);
2472 TPythonDump pyDump; // not to dump group->SetColor() from below code
2473 pyDump<<_this()<<".SetAutoColor( "<<theAutoColor<<" )";
2475 std::list<SALOMEDS::Color> aReservedColors;
2476 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2477 for ( ; it != _mapGroups.end(); it++ ) {
2478 if ( CORBA::is_nil( it->second )) continue;
2479 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2480 it->second->SetColor( aColor );
2481 aReservedColors.push_back( aColor );
2485 //=============================================================================
2489 //=============================================================================
2490 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2492 Unexpect aCatch(SALOME_SalomeException);
2493 return _impl->GetAutoColor();
2497 //=============================================================================
2499 * Export in different formats
2501 //=============================================================================
2503 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2505 return _impl->HasDuplicatedGroupNamesMED();
2508 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2510 TCollection_AsciiString aFullName ((char*)file);
2511 OSD_Path aPath (aFullName);
2512 OSD_File aFile (aPath);
2513 if (aFile.Exists()) {
2514 // existing filesystem node
2515 if (aFile.KindOfFile() == OSD_FILE) {
2516 if (aFile.IsWriteable()) {
2521 if (aFile.Failed()) {
2522 TCollection_AsciiString msg ("File ");
2523 msg += aFullName + " cannot be replaced.";
2524 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2527 TCollection_AsciiString msg ("File ");
2528 msg += aFullName + " cannot be overwritten.";
2529 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2532 TCollection_AsciiString msg ("Location ");
2533 msg += aFullName + " is not a file.";
2534 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2537 // nonexisting file; check if it can be created
2539 aFile.Build(OSD_WriteOnly, OSD_Protection());
2540 if (aFile.Failed()) {
2541 TCollection_AsciiString msg ("You cannot create the file ");
2542 msg += aFullName + ". Check the directory existance and access rights.";
2543 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2551 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2552 CORBA::Boolean auto_groups,
2553 SMESH::MED_VERSION theVersion,
2554 CORBA::Boolean overwrite)
2555 throw(SALOME::SALOME_Exception)
2557 Unexpect aCatch(SALOME_SalomeException);
2560 PrepareForWriting(file, overwrite);
2561 string aMeshName = "Mesh";
2562 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2563 if ( !aStudy->_is_nil() ) {
2564 SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2565 if ( !aMeshSO->_is_nil() ) {
2566 CORBA::String_var name = aMeshSO->GetName();
2568 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2569 if ( !aStudy->GetProperties()->IsLocked() )
2571 SALOMEDS::GenericAttribute_var anAttr;
2572 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2573 SALOMEDS::AttributeExternalFileDef_var aFileName;
2574 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2575 aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
2576 ASSERT(!aFileName->_is_nil());
2577 aFileName->SetValue(file);
2578 SALOMEDS::AttributeFileType_var aFileType;
2579 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2580 aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
2581 ASSERT(!aFileType->_is_nil());
2582 aFileType->SetValue("FICHIERMED");
2586 // Update Python script
2587 // set name of mesh before export
2588 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName.c_str() << "')";
2590 // check names of groups
2593 TPythonDump() << _this() << ".ExportToMEDX( r'"
2594 << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )";
2596 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion );
2599 //================================================================================
2601 * \brief Export a mesh to a med file
2603 //================================================================================
2605 void SMESH_Mesh_i::ExportToMED (const char* file,
2606 CORBA::Boolean auto_groups,
2607 SMESH::MED_VERSION theVersion)
2608 throw(SALOME::SALOME_Exception)
2610 ExportToMEDX(file,auto_groups,theVersion,true);
2613 //================================================================================
2615 * \brief Export a mesh to a med file
2617 //================================================================================
2619 void SMESH_Mesh_i::ExportMED (const char* file,
2620 CORBA::Boolean auto_groups)
2621 throw(SALOME::SALOME_Exception)
2623 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
2626 //================================================================================
2628 * \brief Export a mesh to a DAT file
2630 //================================================================================
2632 void SMESH_Mesh_i::ExportDAT (const char *file)
2633 throw(SALOME::SALOME_Exception)
2635 Unexpect aCatch(SALOME_SalomeException);
2637 // Update Python script
2638 // check names of groups
2640 TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )";
2643 PrepareForWriting(file);
2644 _impl->ExportDAT(file);
2647 //================================================================================
2649 * \brief Export a mesh to an UNV file
2651 //================================================================================
2653 void SMESH_Mesh_i::ExportUNV (const char *file)
2654 throw(SALOME::SALOME_Exception)
2656 Unexpect aCatch(SALOME_SalomeException);
2658 // Update Python script
2659 // check names of groups
2661 TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )";
2664 PrepareForWriting(file);
2665 _impl->ExportUNV(file);
2668 //================================================================================
2670 * \brief Export a mesh to an STL file
2672 //================================================================================
2674 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2675 throw(SALOME::SALOME_Exception)
2677 Unexpect aCatch(SALOME_SalomeException);
2679 // Update Python script
2680 // check names of groups
2682 TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )";
2685 PrepareForWriting(file);
2686 _impl->ExportSTL(file, isascii);
2689 //=============================================================================
2691 * \brief Class providing SMESHDS_Mesh API to SMESH_IDSource.
2692 * It is used to export a part of mesh as a whole mesh.
2694 class SMESH_MeshPartDS : public SMESHDS_Mesh
2697 SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart);
2699 virtual SMDS_NodeIteratorPtr nodesIterator (bool idInceasingOrder=false) const;
2700 virtual SMDS_0DElementIteratorPtr elements0dIterator(bool idInceasingOrder=false) const;
2701 virtual SMDS_EdgeIteratorPtr edgesIterator (bool idInceasingOrder=false) const;
2702 virtual SMDS_FaceIteratorPtr facesIterator (bool idInceasingOrder=false) const;
2703 virtual SMDS_VolumeIteratorPtr volumesIterator (bool idInceasingOrder=false) const;
2705 virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type=SMDSAbs_All) const;
2708 TIDSortedElemSet _elements[ SMDSAbs_NbElementTypes ];
2709 SMESHDS_Mesh* _meshDS;
2711 * \brief Class used to access to protected data of SMDS_MeshInfo
2713 struct TMeshInfo : public SMDS_MeshInfo
2715 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
2719 //================================================================================
2721 * \brief Export a part of mesh to a med file
2723 //================================================================================
2725 void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart,
2727 CORBA::Boolean auto_groups,
2728 ::SMESH::MED_VERSION version,
2729 ::CORBA::Boolean overwrite)
2730 throw (SALOME::SALOME_Exception)
2732 Unexpect aCatch(SALOME_SalomeException);
2734 PrepareForWriting(file, overwrite);
2736 string aMeshName = "Mesh";
2737 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2738 if ( !aStudy->_is_nil() ) {
2739 SALOMEDS::SObject_var SO = _gen_i->ObjectToSObject( aStudy, meshPart );
2740 if ( !SO->_is_nil() ) {
2741 CORBA::String_var name = SO->GetName();
2745 SMESH_MeshPartDS partDS( meshPart );
2746 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, &partDS );
2748 TPythonDump() << _this() << ".ExportPartToMED( " << meshPart << ", r'" << file << "', "
2749 << auto_groups << ", " << version << ", " << overwrite << " )";
2752 //================================================================================
2754 * \brief Export a part of mesh to a DAT file
2756 //================================================================================
2758 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
2760 throw (SALOME::SALOME_Exception)
2762 Unexpect aCatch(SALOME_SalomeException);
2764 PrepareForWriting(file);
2766 SMESH_MeshPartDS partDS( meshPart );
2767 _impl->ExportDAT(file,&partDS);
2769 TPythonDump() << _this() << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
2771 //================================================================================
2773 * \brief Export a part of mesh to an UNV file
2775 //================================================================================
2777 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
2779 throw (SALOME::SALOME_Exception)
2781 Unexpect aCatch(SALOME_SalomeException);
2783 PrepareForWriting(file);
2785 SMESH_MeshPartDS partDS( meshPart );
2786 _impl->ExportUNV(file, &partDS);
2788 TPythonDump() << _this() << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
2790 //================================================================================
2792 * \brief Export a part of mesh to an STL file
2794 //================================================================================
2796 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
2798 ::CORBA::Boolean isascii)
2799 throw (SALOME::SALOME_Exception)
2801 Unexpect aCatch(SALOME_SalomeException);
2803 PrepareForWriting(file);
2805 SMESH_MeshPartDS partDS( meshPart );
2806 _impl->ExportSTL(file, isascii, &partDS);
2808 TPythonDump() << _this() << ".ExportPartToSTL( "
2809 << meshPart<< ", r'" << file << "', " << isascii << ")";
2812 //================================================================================
2814 * \brief Export a part of mesh to an STL file
2816 //================================================================================
2818 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
2820 CORBA::Boolean overwrite)
2821 throw (SALOME::SALOME_Exception)
2824 Unexpect aCatch(SALOME_SalomeException);
2826 PrepareForWriting(file,overwrite);
2828 SMESH_MeshPartDS partDS( meshPart );
2829 _impl->ExportCGNS(file, &partDS);
2831 TPythonDump() << _this() << ".ExportCGNS( "
2832 << meshPart<< ", r'" << file << "', " << overwrite << ")";
2834 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
2838 //=============================================================================
2842 //=============================================================================
2844 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
2846 Unexpect aCatch(SALOME_SalomeException);
2847 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
2848 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
2849 return aMesh._retn();
2852 //=============================================================================
2856 //=============================================================================
2857 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
2859 Unexpect aCatch(SALOME_SalomeException);
2860 return _impl->NbNodes();
2863 //=============================================================================
2867 //=============================================================================
2868 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
2870 Unexpect aCatch(SALOME_SalomeException);
2871 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes();
2874 //=============================================================================
2878 //=============================================================================
2879 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
2881 Unexpect aCatch(SALOME_SalomeException);
2882 return _impl->Nb0DElements();
2885 //=============================================================================
2889 //=============================================================================
2890 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
2892 Unexpect aCatch(SALOME_SalomeException);
2893 return _impl->NbEdges();
2896 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
2897 throw(SALOME::SALOME_Exception)
2899 Unexpect aCatch(SALOME_SalomeException);
2900 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
2903 //=============================================================================
2907 //=============================================================================
2908 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
2910 Unexpect aCatch(SALOME_SalomeException);
2911 return _impl->NbFaces();
2914 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
2916 Unexpect aCatch(SALOME_SalomeException);
2917 return _impl->NbTriangles();
2920 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
2922 Unexpect aCatch(SALOME_SalomeException);
2923 return _impl->NbQuadrangles();
2926 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
2928 Unexpect aCatch(SALOME_SalomeException);
2929 return _impl->NbPolygons();
2932 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
2933 throw(SALOME::SALOME_Exception)
2935 Unexpect aCatch(SALOME_SalomeException);
2936 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
2939 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
2940 throw(SALOME::SALOME_Exception)
2942 Unexpect aCatch(SALOME_SalomeException);
2943 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
2946 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
2947 throw(SALOME::SALOME_Exception)
2949 Unexpect aCatch(SALOME_SalomeException);
2950 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
2953 //=============================================================================
2957 //=============================================================================
2958 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
2960 Unexpect aCatch(SALOME_SalomeException);
2961 return _impl->NbVolumes();
2964 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
2966 Unexpect aCatch(SALOME_SalomeException);
2967 return _impl->NbTetras();
2970 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
2972 Unexpect aCatch(SALOME_SalomeException);
2973 return _impl->NbHexas();
2976 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
2978 Unexpect aCatch(SALOME_SalomeException);
2979 return _impl->NbPyramids();
2982 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
2984 Unexpect aCatch(SALOME_SalomeException);
2985 return _impl->NbPrisms();
2988 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
2990 Unexpect aCatch(SALOME_SalomeException);
2991 return _impl->NbPolyhedrons();
2994 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
2995 throw(SALOME::SALOME_Exception)
2997 Unexpect aCatch(SALOME_SalomeException);
2998 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3001 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3002 throw(SALOME::SALOME_Exception)
3004 Unexpect aCatch(SALOME_SalomeException);
3005 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3008 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3009 throw(SALOME::SALOME_Exception)
3011 Unexpect aCatch(SALOME_SalomeException);
3012 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3015 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3016 throw(SALOME::SALOME_Exception)
3018 Unexpect aCatch(SALOME_SalomeException);
3019 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3022 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3023 throw(SALOME::SALOME_Exception)
3025 Unexpect aCatch(SALOME_SalomeException);
3026 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3029 //=============================================================================
3033 //=============================================================================
3034 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3036 Unexpect aCatch(SALOME_SalomeException);
3037 return _mapSubMesh_i.size();
3040 //=============================================================================
3044 //=============================================================================
3045 char* SMESH_Mesh_i::Dump()
3049 return CORBA::string_dup( os.str().c_str() );
3052 //=============================================================================
3056 //=============================================================================
3057 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3059 // SMESH::long_array_var aResult = new SMESH::long_array();
3060 // SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3061 // int aMinId = aSMESHDS_Mesh->MinElementID();
3062 // int aMaxId = aSMESHDS_Mesh->MaxElementID();
3064 // aResult->length(aMaxId - aMinId + 1);
3066 // for (int i = 0, id = aMinId; id <= aMaxId; id++ )
3067 // aResult[i++] = id;
3069 // return aResult._retn();
3071 return GetElementsId();
3074 //=============================================================================
3078 //=============================================================================
3080 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3081 throw (SALOME::SALOME_Exception)
3083 Unexpect aCatch(SALOME_SalomeException);
3084 MESSAGE("SMESH_Mesh_i::GetElementsId");
3085 SMESH::long_array_var aResult = new SMESH::long_array();
3086 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3088 if ( aSMESHDS_Mesh == NULL )
3089 return aResult._retn();
3091 long nbElements = NbElements();
3092 aResult->length( nbElements );
3093 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3094 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3095 aResult[i] = anIt->next()->GetID();
3097 return aResult._retn();
3101 //=============================================================================
3105 //=============================================================================
3107 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3108 throw (SALOME::SALOME_Exception)
3110 Unexpect aCatch(SALOME_SalomeException);
3111 MESSAGE("SMESH_subMesh_i::GetElementsByType");
3112 SMESH::long_array_var aResult = new SMESH::long_array();
3113 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3115 if ( aSMESHDS_Mesh == NULL )
3116 return aResult._retn();
3118 long nbElements = NbElements();
3120 // No sense in returning ids of elements along with ids of nodes:
3121 // when theElemType == SMESH::ALL, return node ids only if
3122 // there are no elements
3123 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3124 return GetNodesId();
3126 aResult->length( nbElements );
3130 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3131 while ( i < nbElements && anIt->more() ) {
3132 const SMDS_MeshElement* anElem = anIt->next();
3133 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
3134 aResult[i++] = anElem->GetID();
3137 aResult->length( i );
3139 return aResult._retn();
3142 //=============================================================================
3146 //=============================================================================
3148 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3149 throw (SALOME::SALOME_Exception)
3151 Unexpect aCatch(SALOME_SalomeException);
3152 MESSAGE("SMESH_subMesh_i::GetNodesId");
3153 SMESH::long_array_var aResult = new SMESH::long_array();
3154 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3156 if ( aSMESHDS_Mesh == NULL )
3157 return aResult._retn();
3159 long nbNodes = NbNodes();
3160 aResult->length( nbNodes );
3161 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3162 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3163 aResult[i] = anIt->next()->GetID();
3165 return aResult._retn();
3168 //=============================================================================
3172 //=============================================================================
3174 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3175 throw (SALOME::SALOME_Exception)
3177 return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
3180 //=============================================================================
3184 //=============================================================================
3186 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3187 throw (SALOME::SALOME_Exception)
3189 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3191 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3193 return ( SMESH::EntityType ) e->GetEntityType();
3196 //=============================================================================
3198 * Returns ID of elements for given submesh
3200 //=============================================================================
3201 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3202 throw (SALOME::SALOME_Exception)
3204 SMESH::long_array_var aResult = new SMESH::long_array();
3206 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3207 if(!SM) return aResult._retn();
3209 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3210 if(!SDSM) return aResult._retn();
3212 aResult->length(SDSM->NbElements());
3214 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3216 while ( eIt->more() ) {
3217 aResult[i++] = eIt->next()->GetID();
3220 return aResult._retn();
3224 //=============================================================================
3226 * Returns ID of nodes for given submesh
3227 * If param all==true - returns all nodes, else -
3228 * returns only nodes on shapes.
3230 //=============================================================================
3231 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all)
3232 throw (SALOME::SALOME_Exception)
3234 SMESH::long_array_var aResult = new SMESH::long_array();
3236 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3237 if(!SM) return aResult._retn();
3239 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3240 if(!SDSM) return aResult._retn();
3243 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
3244 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
3245 while ( nIt->more() ) {
3246 const SMDS_MeshNode* elem = nIt->next();
3247 theElems.insert( elem->GetID() );
3250 else { // all nodes of submesh elements
3251 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3252 while ( eIt->more() ) {
3253 const SMDS_MeshElement* anElem = eIt->next();
3254 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
3255 while ( nIt->more() ) {
3256 const SMDS_MeshElement* elem = nIt->next();
3257 theElems.insert( elem->GetID() );
3262 aResult->length(theElems.size());
3263 set<int>::iterator itElem;
3265 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
3266 aResult[i++] = *itElem;
3268 return aResult._retn();
3272 //=============================================================================
3274 * Returns type of elements for given submesh
3276 //=============================================================================
3277 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
3278 throw (SALOME::SALOME_Exception)
3280 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3281 if(!SM) return SMESH::ALL;
3283 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3284 if(!SDSM) return SMESH::ALL;
3286 if(SDSM->NbElements()==0)
3287 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
3289 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3290 const SMDS_MeshElement* anElem = eIt->next();
3291 return ( SMESH::ElementType ) anElem->GetType();
3295 //=============================================================================
3299 //=============================================================================
3301 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
3303 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
3305 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
3310 //=============================================================================
3312 * Get XYZ coordinates of node as list of double
3313 * If there is not node for given ID - returns empty list
3315 //=============================================================================
3317 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
3319 SMESH::double_array_var aResult = new SMESH::double_array();
3320 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3321 if ( aSMESHDS_Mesh == NULL )
3322 return aResult._retn();
3325 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3327 return aResult._retn();
3331 aResult[0] = aNode->X();
3332 aResult[1] = aNode->Y();
3333 aResult[2] = aNode->Z();
3334 return aResult._retn();
3338 //=============================================================================
3340 * For given node returns list of IDs of inverse elements
3341 * If there is not node for given ID - returns empty list
3343 //=============================================================================
3345 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
3347 SMESH::long_array_var aResult = new SMESH::long_array();
3348 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3349 if ( aSMESHDS_Mesh == NULL )
3350 return aResult._retn();
3353 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3355 return aResult._retn();
3357 // find inverse elements
3358 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
3359 TColStd_SequenceOfInteger IDs;
3360 while(eIt->more()) {
3361 const SMDS_MeshElement* elem = eIt->next();
3362 IDs.Append(elem->GetID());
3364 if(IDs.Length()>0) {
3365 aResult->length(IDs.Length());
3367 for(; i<=IDs.Length(); i++) {
3368 aResult[i-1] = IDs.Value(i);
3371 return aResult._retn();
3374 //=============================================================================
3376 * \brief Return position of a node on shape
3378 //=============================================================================
3380 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
3382 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
3383 aNodePosition->shapeID = 0;
3384 aNodePosition->shapeType = GEOM::SHAPE;
3386 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3387 if ( !mesh ) return aNodePosition;
3389 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
3391 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
3393 aNodePosition->shapeID = aNode->getshapeId();
3394 switch ( pos->GetTypeOfPosition() ) {
3396 aNodePosition->shapeType = GEOM::EDGE;
3397 aNodePosition->params.length(1);
3398 aNodePosition->params[0] =
3399 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
3402 aNodePosition->shapeType = GEOM::FACE;
3403 aNodePosition->params.length(2);
3404 aNodePosition->params[0] =
3405 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
3406 aNodePosition->params[1] =
3407 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
3409 case SMDS_TOP_VERTEX:
3410 aNodePosition->shapeType = GEOM::VERTEX;
3412 case SMDS_TOP_3DSPACE:
3413 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3414 aNodePosition->shapeType = GEOM::SOLID;
3415 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3416 aNodePosition->shapeType = GEOM::SHELL;
3422 return aNodePosition;
3425 //=============================================================================
3427 * If given element is node returns IDs of shape from position
3428 * If there is not node for given ID - returns -1
3430 //=============================================================================
3432 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3434 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3435 if ( aSMESHDS_Mesh == NULL )
3439 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3441 return aNode->getshapeId();
3448 //=============================================================================
3450 * For given element returns ID of result shape after
3451 * ::FindShape() from SMESH_MeshEditor
3452 * If there is not element for given ID - returns -1
3454 //=============================================================================
3456 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3458 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3459 if ( aSMESHDS_Mesh == NULL )
3462 // try to find element
3463 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3467 //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
3468 ::SMESH_MeshEditor aMeshEditor(_impl);
3469 int index = aMeshEditor.FindShape( elem );
3477 //=============================================================================
3479 * Returns number of nodes for given element
3480 * If there is not element for given ID - returns -1
3482 //=============================================================================
3484 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3486 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3487 if ( aSMESHDS_Mesh == NULL ) return -1;
3488 // try to find element
3489 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3490 if(!elem) return -1;
3491 return elem->NbNodes();
3495 //=============================================================================
3497 * Returns ID of node by given index for given element
3498 * If there is not element for given ID - returns -1
3499 * If there is not node for given index - returns -2
3501 //=============================================================================
3503 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3505 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3506 if ( aSMESHDS_Mesh == NULL ) return -1;
3507 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3508 if(!elem) return -1;
3509 if( index>=elem->NbNodes() || index<0 ) return -1;
3510 return elem->GetNode(index)->GetID();
3513 //=============================================================================
3515 * Returns IDs of nodes of given element
3517 //=============================================================================
3519 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3521 SMESH::long_array_var aResult = new SMESH::long_array();
3522 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3524 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3526 aResult->length( elem->NbNodes() );
3527 for ( int i = 0; i < elem->NbNodes(); ++i )
3528 aResult[ i ] = elem->GetNode( i )->GetID();
3531 return aResult._retn();
3534 //=============================================================================
3536 * Returns true if given node is medium node
3537 * in given quadratic element
3539 //=============================================================================
3541 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3543 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3544 if ( aSMESHDS_Mesh == NULL ) return false;
3546 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3547 if(!aNode) return false;
3548 // try to find element
3549 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3550 if(!elem) return false;
3552 return elem->IsMediumNode(aNode);
3556 //=============================================================================
3558 * Returns true if given node is medium node
3559 * in one of quadratic elements
3561 //=============================================================================
3563 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3564 SMESH::ElementType theElemType)
3566 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3567 if ( aSMESHDS_Mesh == NULL ) return false;
3570 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3571 if(!aNode) return false;
3573 SMESH_MesherHelper aHelper( *(_impl) );
3575 SMDSAbs_ElementType aType;
3576 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3577 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3578 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3579 else aType = SMDSAbs_All;
3581 return aHelper.IsMedium(aNode,aType);
3585 //=============================================================================
3587 * Returns number of edges for given element
3589 //=============================================================================
3591 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3593 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3594 if ( aSMESHDS_Mesh == NULL ) return -1;
3595 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3596 if(!elem) return -1;
3597 return elem->NbEdges();
3601 //=============================================================================
3603 * Returns number of faces for given element
3605 //=============================================================================
3607 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3609 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3610 if ( aSMESHDS_Mesh == NULL ) return -1;
3611 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3612 if(!elem) return -1;
3613 return elem->NbFaces();
3616 //=======================================================================
3617 //function : GetElemFaceNodes
3618 //purpose : Returns nodes of given face (counted from zero) for given element.
3619 //=======================================================================
3621 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
3622 CORBA::Short faceIndex)
3624 SMESH::long_array_var aResult = new SMESH::long_array();
3625 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3627 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
3629 SMDS_VolumeTool vtool( elem );
3630 if ( faceIndex < vtool.NbFaces() )
3632 aResult->length( vtool.NbFaceNodes( faceIndex ));
3633 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
3634 for ( int i = 0; i < aResult->length(); ++i )
3635 aResult[ i ] = nn[ i ]->GetID();
3639 return aResult._retn();
3642 //=======================================================================
3643 //function : FindElementByNodes
3644 //purpose : Returns an element based on all given nodes.
3645 //=======================================================================
3647 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
3649 CORBA::Long elemID(0);
3650 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
3652 vector< const SMDS_MeshNode * > nn( nodes.length() );
3653 for ( int i = 0; i < nodes.length(); ++i )
3654 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
3657 const SMDS_MeshElement* elem = mesh->FindElement( nn );
3658 if ( !elem && ( _impl->NbEdges( ORDER_QUADRATIC ) ||
3659 _impl->NbFaces( ORDER_QUADRATIC ) ||
3660 _impl->NbVolumes( ORDER_QUADRATIC )))
3661 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
3663 if ( elem ) elemID = CORBA::Long( elem->GetID() );
3668 //=============================================================================
3670 * Returns true if given element is polygon
3672 //=============================================================================
3674 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
3676 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3677 if ( aSMESHDS_Mesh == NULL ) return false;
3678 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3679 if(!elem) return false;
3680 return elem->IsPoly();
3684 //=============================================================================
3686 * Returns true if given element is quadratic
3688 //=============================================================================
3690 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
3692 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3693 if ( aSMESHDS_Mesh == NULL ) return false;
3694 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3695 if(!elem) return false;
3696 return elem->IsQuadratic();
3700 //=============================================================================
3702 * Returns bary center for given element
3704 //=============================================================================
3706 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
3708 SMESH::double_array_var aResult = new SMESH::double_array();
3709 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3710 if ( aSMESHDS_Mesh == NULL )
3711 return aResult._retn();
3713 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3715 return aResult._retn();
3717 if(elem->GetType()==SMDSAbs_Volume) {
3718 SMDS_VolumeTool aTool;
3719 if(aTool.Set(elem)) {
3721 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
3726 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
3728 double x=0., y=0., z=0.;
3729 for(; anIt->more(); ) {
3731 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
3745 return aResult._retn();
3749 //=============================================================================
3751 * Create and publish group servants if any groups were imported or created anyhow
3753 //=============================================================================
3755 void SMESH_Mesh_i::CreateGroupServants()
3757 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3760 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
3761 while ( groupIt->more() )
3763 ::SMESH_Group* group = groupIt->next();
3764 int anId = group->GetGroupDS()->GetID();
3766 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
3767 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3769 addedIDs.insert( anId );
3771 SMESH_GroupBase_i* aGroupImpl;
3773 if ( SMESHDS_GroupOnGeom* groupOnGeom =
3774 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
3776 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3777 shape = groupOnGeom->GetShape();
3780 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3783 // To ensure correct mapping of servant and correct reference counting in GenericObj_i
3784 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
3785 aGroupImpl->Register();
3787 SMESH::SMESH_GroupBase_var groupVar =
3788 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
3789 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
3791 // register CORBA object for persistence
3792 int nextId = _gen_i->RegisterObject( groupVar );
3793 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
3795 // publishing the groups in the study
3796 if ( !aStudy->_is_nil() ) {
3797 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
3798 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
3801 if ( !addedIDs.empty() )
3804 set<int>::iterator id = addedIDs.begin();
3805 for ( ; id != addedIDs.end(); ++id )
3807 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
3808 int i = std::distance( _mapGroups.begin(), it );
3809 TPythonDump() << it->second << " = " << _this() << ".GetGroups()[ "<< i << " ]";
3814 //=============================================================================
3816 * \brief Return groups cantained in _mapGroups by their IDs
3818 //=============================================================================
3820 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
3822 int nbGroups = groupIDs.size();
3823 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
3824 aList->length( nbGroups );
3826 list<int>::const_iterator ids = groupIDs.begin();
3827 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
3829 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
3830 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3831 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
3833 aList->length( nbGroups );
3834 return aList._retn();
3837 //=============================================================================
3839 * \brief Return information about imported file
3841 //=============================================================================
3843 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
3845 SALOME_MED::MedFileInfo_var res( myFileInfo );
3846 if ( !res.operator->() ) {
3847 res = new SALOME_MED::MedFileInfo;
3849 res->fileSize = res->major = res->minor = res->release = -1;
3854 //=============================================================================
3856 * \brief Check and correct names of mesh groups
3858 //=============================================================================
3860 void SMESH_Mesh_i::checkGroupNames()
3862 int nbGrp = NbGroups();
3866 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3867 if ( aStudy->_is_nil() )
3868 return; // nothing to do
3870 SMESH::ListOfGroups* grpList = 0;
3871 // avoid dump of "GetGroups"
3873 // store python dump into a local variable inside local scope
3874 SMESH::TPythonDump pDump; // do not delete this line of code
3875 grpList = GetGroups();
3878 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
3879 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
3882 SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
3883 if ( aGrpSO->_is_nil() )
3885 // correct name of the mesh group if necessary
3886 const char* guiName = aGrpSO->GetName();
3887 if ( strcmp(guiName, aGrp->GetName()) )
3888 aGrp->SetName( guiName );
3892 //=============================================================================
3894 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
3896 //=============================================================================
3897 void SMESH_Mesh_i::SetParameters(const char* theParameters)
3899 SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
3900 CORBA::string_dup(theParameters));
3903 //=============================================================================
3905 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
3907 //=============================================================================
3908 char* SMESH_Mesh_i::GetParameters()
3910 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3911 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
3914 //=============================================================================
3916 * \brief Returns list of notebook variables used for last Mesh operation
3918 //=============================================================================
3919 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
3921 SMESH::string_array_var aResult = new SMESH::string_array();
3922 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3924 char *aParameters = GetParameters();
3925 SALOMEDS::Study_ptr aStudy = gen->GetCurrentStudy();
3926 if(!aStudy->_is_nil()) {
3927 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
3928 if(aSections->length() > 0) {
3929 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
3930 aResult->length(aVars.length());
3931 for(int i = 0;i < aVars.length();i++)
3932 aResult[i] = CORBA::string_dup( aVars[i]);
3936 return aResult._retn();
3939 //=======================================================================
3940 //function : GetTypes
3941 //purpose : Returns types of elements it contains
3942 //=======================================================================
3944 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
3946 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
3950 if (_impl->NbEdges())
3951 types[nbTypes++] = SMESH::EDGE;
3952 if (_impl->NbFaces())
3953 types[nbTypes++] = SMESH::FACE;
3954 if (_impl->NbVolumes())
3955 types[nbTypes++] = SMESH::VOLUME;
3956 if (_impl->Nb0DElements())
3957 types[nbTypes++] = SMESH::ELEM0D;
3958 types->length( nbTypes );
3960 return types._retn();
3963 //=======================================================================
3964 //function : GetMesh
3965 //purpose : Returns self
3966 //=======================================================================
3968 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
3970 return SMESH::SMESH_Mesh::_duplicate( _this() );
3973 //=============================================================================
3975 * \brief Returns statistic of mesh elements
3977 //=============================================================================
3978 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
3980 SMESH::long_array_var aRes = new SMESH::long_array();
3981 aRes->length(SMESH::Entity_Last);
3982 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3984 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3986 return aRes._retn();
3987 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
3988 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3989 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
3990 return aRes._retn();
3993 //=============================================================================
3995 * \brief Collect statistic of mesh elements given by iterator
3997 //=============================================================================
3998 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
3999 SMESH::long_array& theInfo)
4001 if (!theItr) return;
4002 while (theItr->more())
4003 theInfo[ theItr->next()->GetEntityType() ]++;
4006 //=============================================================================
4008 * \brief mapping of mesh dimension into shape type
4010 //=============================================================================
4011 static TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
4013 TopAbs_ShapeEnum aType = TopAbs_SOLID;
4015 case 0: aType = TopAbs_VERTEX; break;
4016 case 1: aType = TopAbs_EDGE; break;
4017 case 2: aType = TopAbs_FACE; break;
4019 default:aType = TopAbs_SOLID; break;
4024 //=============================================================================
4026 * \brief Internal structure used to find concurent submeshes
4028 * It represents a pair < submesh, concurent dimension >, where
4029 * 'concurrent dimension' is dimension of shape where the submesh can concurent
4030 * with another submesh. In other words, it is dimension of a hypothesis assigned
4033 //=============================================================================
4039 int _dim; //!< a dimension the algo can build (concurrent dimension)
4040 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
4041 TopTools_MapOfShape _shapeMap;
4042 SMESH_subMesh* _subMesh;
4043 list<const SMESHDS_Hypothesis*> _hypothesises; //!< algo is first, then its parameters
4046 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
4048 const TopoDS_Shape& theShape)
4050 _subMesh = (SMESH_subMesh*)theSubMesh;
4051 SetShape( theDim, theShape );
4055 void SetShape(const int theDim,
4056 const TopoDS_Shape& theShape)
4059 _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
4060 if (_dim >= _ownDim)
4061 _shapeMap.Add( theShape );
4063 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
4064 for( ; anExp.More(); anExp.Next() )
4065 _shapeMap.Add( anExp.Current() );
4069 //! Check sharing of sub shapes
4070 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
4071 const TopTools_MapOfShape& theToFind,
4072 const TopAbs_ShapeEnum theType)
4074 bool isShared = false;
4075 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
4076 for (; !isShared && anItr.More(); anItr.Next() ) {
4077 const TopoDS_Shape aSubSh = anItr.Key();
4078 // check for case when concurrent dimensions are same
4079 isShared = theToFind.Contains( aSubSh );
4080 // check for subshape with concurrent dimension
4081 TopExp_Explorer anExp( aSubSh, theType );
4082 for ( ; !isShared && anExp.More(); anExp.Next() )
4083 isShared = theToFind.Contains( anExp.Current() );
4088 //! check algorithms
4089 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
4090 const SMESHDS_Hypothesis* theA2)
4092 if ( theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
4093 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
4094 return false; // one of the hypothesis is not algorithm
4095 // check algorithm names (should be equal)
4096 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
4100 //! Check if subshape hypotheses are concurrent
4101 bool IsConcurrent(const SMESH_DimHyp* theOther) const
4103 if ( _subMesh == theOther->_subMesh )
4104 return false; // same subshape - should not be
4106 // if ( <own dim of either of submeshes> == <concurrent dim> &&
4107 // any of the two submeshes is not on COMPOUND shape )
4108 // -> no concurrency
4109 bool meIsCompound = (_subMesh->GetSubMeshDS() && _subMesh->GetSubMeshDS()->IsComplexSubmesh());
4110 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() && theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
4111 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
4114 // bool checkSubShape = ( _dim >= theOther->_dim )
4115 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
4116 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
4117 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
4118 if ( !checkSubShape )
4121 // check algorithms to be same
4122 if (!checkAlgo( _hypothesises.front(), theOther->_hypothesises.front() ))
4123 return true; // different algorithms
4125 // check hypothesises for concurrence (skip first as algorithm)
4127 // pointers should be same, becase it is referenes from mesh hypothesis partition
4128 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypothesises.begin();
4129 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypothesises.end();
4130 for ( hypIt++ /*skip first as algo*/; hypIt != _hypothesises.end(); hypIt++ )
4131 if ( find( theOther->_hypothesises.begin(), otheEndIt, *hypIt ) != otheEndIt )
4133 // the submeshes are concurrent if their algorithms has different parameters
4134 return nbSame != theOther->_hypothesises.size() - 1;
4137 }; // end of SMESH_DimHyp
4139 typedef list<SMESH_DimHyp*> TDimHypList;
4141 static void addDimHypInstance(const int theDim,
4142 const TopoDS_Shape& theShape,
4143 const SMESH_Algo* theAlgo,
4144 const SMESH_subMesh* theSubMesh,
4145 const list <const SMESHDS_Hypothesis*>& theHypList,
4146 TDimHypList* theDimHypListArr )
4148 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
4149 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
4150 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
4151 listOfdimHyp.push_back( dimHyp );
4154 SMESH_DimHyp* dimHyp = listOfdimHyp.back();
4155 dimHyp->_hypothesises.push_front(theAlgo);
4156 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = theHypList.begin();
4157 for( ; hypIt != theHypList.end(); hypIt++ )
4158 dimHyp->_hypothesises.push_back( *hypIt );
4161 static void findConcurrents(const SMESH_DimHyp* theDimHyp,
4162 const TDimHypList& theListOfDimHyp,
4163 TListOfInt& theListOfConcurr )
4165 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
4166 for ( ; rIt != theListOfDimHyp.rend(); rIt++ ) {
4167 const SMESH_DimHyp* curDimHyp = *rIt;
4168 if ( curDimHyp == theDimHyp )
4169 break; // meet own dimHyp pointer in same dimension
4170 else if ( theDimHyp->IsConcurrent( curDimHyp ) )
4171 if ( find( theListOfConcurr.begin(),
4172 theListOfConcurr.end(),
4173 curDimHyp->_subMesh->GetId() ) == theListOfConcurr.end() )
4174 theListOfConcurr.push_back( curDimHyp->_subMesh->GetId() );
4178 static void unionLists(TListOfInt& theListOfId,
4179 TListOfListOfInt& theListOfListOfId,
4182 TListOfListOfInt::iterator it = theListOfListOfId.begin();
4183 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
4185 continue; //skip already treated lists
4186 // check if other list has any same submesh object
4187 TListOfInt& otherListOfId = *it;
4188 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
4189 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
4192 // union two lists (from source into target)
4193 TListOfInt::iterator it2 = otherListOfId.begin();
4194 for ( ; it2 != otherListOfId.end(); it2++ ) {
4195 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
4196 theListOfId.push_back(*it2);
4198 // clear source list
4199 otherListOfId.clear();
4203 //! free memory allocated for dimension-hypothesis objects
4204 static void removeDimHyps( TDimHypList* theArrOfList )
4206 for (int i = 0; i < 4; i++ ) {
4207 TDimHypList& listOfdimHyp = theArrOfList[i];
4208 TDimHypList::const_iterator it = listOfdimHyp.begin();
4209 for ( ; it != listOfdimHyp.end(); it++ )
4214 //=============================================================================
4216 * \brief Return submesh objects list in meshing order
4218 //=============================================================================
4220 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
4222 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
4224 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4226 return aResult._retn();
4228 ::SMESH_Mesh& mesh = GetImpl();
4229 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
4230 if ( !anOrder.size() ) {
4232 // collect submeshes detecting concurrent algorithms and hypothesises
4233 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
4235 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
4236 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
4237 ::SMESH_subMesh* sm = (*i_sm).second;
4239 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
4241 // list of assigned hypothesises
4242 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
4243 // Find out dimensions where the submesh can be concurrent.
4244 // We define the dimensions by algo of each of hypotheses in hypList
4245 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
4246 for( ; hypIt != hypList.end(); hypIt++ ) {
4247 SMESH_Algo* anAlgo = 0;
4248 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
4249 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
4250 // hyp it-self is algo
4251 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
4253 // try to find algorithm with help of subshapes
4254 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
4255 for ( ; !anAlgo && anExp.More(); anExp.Next() )
4256 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
4259 continue; // no assigned algorithm to current submesh
4261 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
4262 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDescretBoundary())
4264 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
4265 for ( int j = anAlgo->NeedDescretBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
4266 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
4268 } // end iterations on submesh
4270 // iterate on created dimension-hypotheses and check for concurrents
4271 for ( int i = 0; i < 4; i++ ) {
4272 const list<SMESH_DimHyp*>& listOfDimHyp = dimHypListArr[i];
4273 // check for concurrents in own and other dimensions (step-by-step)
4274 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
4275 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
4276 const SMESH_DimHyp* dimHyp = *dhIt;
4277 TListOfInt listOfConcurr;
4278 // looking for concurrents and collect into own list
4279 for ( int j = i; j < 4; j++ )
4280 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr );
4281 // check if any concurrents found
4282 if ( listOfConcurr.size() > 0 ) {
4283 // add own submesh to list of concurrent
4284 listOfConcurr.push_front( dimHyp->_subMesh->GetId() );
4285 anOrder.push_back( listOfConcurr );
4290 removeDimHyps(dimHypListArr);
4292 // now, minimise the number of concurrent groups
4293 // Here we assume that lists of submhes can has same submesh
4294 // in case of multi-dimension algorithms, as result
4295 // list with common submesh have to be union into one list
4297 TListOfListOfInt::iterator listIt = anOrder.begin();
4298 for(; listIt != anOrder.end(); listIt++, listIndx++ )
4299 unionLists( *listIt, anOrder, listIndx + 1 );
4301 // convert submesh ids into interface instances
4302 // and dump command into python
4303 convertMeshOrder( anOrder, aResult, true );
4305 return aResult._retn();
4308 //=============================================================================
4310 * \brief find common submeshes with given submesh
4311 * \param theSubMeshList list of already collected submesh to check
4312 * \param theSubMesh given submesh to intersect with other
4313 * \param theCommonSubMeshes collected common submeshes
4315 //=============================================================================
4317 static void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
4318 const SMESH_subMesh* theSubMesh,
4319 set<const SMESH_subMesh*>& theCommon )
4323 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
4324 for ( ; it != theSubMeshList.end(); it++ )
4325 theSubMesh->FindIntersection( *it, theCommon );
4326 theSubMeshList.push_back( theSubMesh );
4327 //theCommon.insert( theSubMesh );
4330 //=============================================================================
4332 * \brief Set submesh object order
4333 * \param theSubMeshArray submesh array order
4335 //=============================================================================
4337 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
4340 ::SMESH_Mesh& mesh = GetImpl();
4342 TPythonDump aPythonDump; // prevent dump of called methods
4343 aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
4345 TListOfListOfInt subMeshOrder;
4346 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
4348 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
4349 TListOfInt subMeshIds;
4350 aPythonDump << "[ ";
4351 // Collect subMeshes which should be clear
4352 // do it list-by-list, because modification of submesh order
4353 // take effect between concurrent submeshes only
4354 set<const SMESH_subMesh*> subMeshToClear;
4355 list<const SMESH_subMesh*> subMeshList;
4356 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
4358 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
4360 aPythonDump << ", ";
4361 aPythonDump << subMesh;
4362 subMeshIds.push_back( subMesh->GetId() );
4363 // detect common parts of submeshes
4364 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
4365 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
4367 aPythonDump << " ]";
4368 subMeshOrder.push_back( subMeshIds );
4370 // clear collected submeshes
4371 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
4372 for ( ; clrIt != subMeshToClear.end(); clrIt++ ) {
4373 SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt;
4375 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
4376 // ClearSubMesh( *clrIt );
4379 aPythonDump << " ])";
4381 mesh.SetMeshOrder( subMeshOrder );
4387 //=============================================================================
4389 * \brief Convert submesh ids into submesh interfaces
4391 //=============================================================================
4393 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
4394 SMESH::submesh_array_array& theResOrder,
4395 const bool theIsDump)
4397 int nbSet = theIdsOrder.size();
4398 TPythonDump aPythonDump; // prevent dump of called methods
4400 aPythonDump << "[ ";
4401 theResOrder.length(nbSet);
4402 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
4404 for( ; it != theIdsOrder.end(); it++ ) {
4405 // translate submesh identificators into submesh objects
4406 // takeing into account real number of concurrent lists
4407 const TListOfInt& aSubOrder = (*it);
4408 if (!aSubOrder.size())
4411 aPythonDump << "[ ";
4412 // convert shape indeces into interfaces
4413 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
4414 aResSubSet->length(aSubOrder.size());
4415 TListOfInt::const_iterator subIt = aSubOrder.begin();
4416 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
4417 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
4419 SMESH::SMESH_subMesh_var subMesh =
4420 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
4423 aPythonDump << ", ";
4424 aPythonDump << subMesh;
4426 aResSubSet[ j++ ] = subMesh;
4429 aPythonDump << " ]";
4430 theResOrder[ listIndx++ ] = aResSubSet;
4432 // correct number of lists
4433 theResOrder.length( listIndx );
4436 // finilise python dump
4437 aPythonDump << " ]";
4438 aPythonDump << " = " << _this() << ".GetMeshOrder()";
4442 //================================================================================
4444 // Implementation of SMESH_MeshPartDS
4446 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
4447 SMESHDS_Mesh( /*theMeshID=*/-1, /*theIsEmbeddedMode=*/true)
4449 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
4450 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4452 _meshDS = mesh_i->GetImpl().GetMeshDS();
4454 SetPersistentId( _meshDS->GetPersistentId() );
4456 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
4458 // <meshPart> is the whole mesh
4459 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
4461 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
4462 myGroupSet = _meshDS->GetGroups();
4467 SMESH::long_array_var anIDs = meshPart->GetIDs();
4468 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
4469 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
4471 for (int i=0; i < anIDs->length(); i++)
4472 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
4473 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4478 for (int i=0; i < anIDs->length(); i++)
4479 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
4480 if ( _elements[ e->GetType() ].insert( e ).second )
4483 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
4484 while ( nIt->more() )
4486 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
4487 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4494 _meshDS = 0; // to enforce iteration on _elements and _nodes
4497 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
4499 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
4500 if ( type == SMDSAbs_All && !_meshDS )
4502 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
4504 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4505 if ( !_elements[i].empty() && i != SMDSAbs_Node )
4507 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
4509 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
4510 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
4512 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
4513 ( new TIter( _elements[type].begin(), _elements[type].end() ));
4515 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
4516 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
4518 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
4519 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
4520 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
4522 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
4523 _GET_ITER_DEFINE( SMDS_0DElementIteratorPtr, elements0dIterator, SMDS_Mesh0DElement, SMDSAbs_0DElement)
4524 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
4525 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
4526 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
4527 #undef _GET_ITER_DEFINE
4529 // END Implementation of SMESH_MeshPartDS
4531 //================================================================================