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 "SMESH_Filter_i.hxx"
29 #include "SMESH_Gen_i.hxx"
30 #include "SMESH_Group_i.hxx"
31 #include "SMESH_MEDMesh_i.hxx"
32 #include "SMESH_MeshEditor_i.hxx"
33 #include "SMESH_PythonDump.hxx"
34 #include "SMESH_subMesh_i.hxx"
36 #include "DriverMED_R_SMESHDS_Mesh.h"
37 #include "DriverMED_W_SMESHDS_Mesh.h"
38 #include "SMDS_EdgePosition.hxx"
39 #include "SMDS_ElemIterator.hxx"
40 #include "SMDS_FacePosition.hxx"
41 #include "SMDS_SetIterator.hxx"
42 #include "SMDS_VolumeTool.hxx"
43 #include "SMESHDS_Command.hxx"
44 #include "SMESHDS_CommandType.hxx"
45 #include "SMESHDS_GroupOnGeom.hxx"
46 #include "SMESH_Group.hxx"
47 #include "SMESH_MeshEditor.hxx"
48 #include "SMESH_MesherHelper.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 Return string representation of a MED file version comprising nbDigits
347 //================================================================================
349 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
351 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
353 return CORBA::string_dup( ver.c_str() );
356 //=============================================================================
360 * Imports mesh data from MED file
362 //=============================================================================
364 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
365 throw ( SALOME::SALOME_Exception )
367 // Read mesh with name = <theMeshName> into SMESH_Mesh
368 _impl->UNVToMesh( theFileName );
370 CreateGroupServants();
375 //=============================================================================
379 * Imports mesh data from STL file
381 //=============================================================================
382 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
383 throw ( SALOME::SALOME_Exception )
385 // Read mesh with name = <theMeshName> into SMESH_Mesh
386 _impl->STLToMesh( theFileName );
391 //=============================================================================
395 * Imports mesh data from MED file
397 //=============================================================================
399 // int SMESH_Mesh_i::importMEDFile( const char* theFileName, const char* theMeshName )
401 // // Read mesh with name = <theMeshName> and all its groups into SMESH_Mesh
402 // int status = _impl->MEDToMesh( theFileName, theMeshName );
403 // CreateGroupServants();
408 //=============================================================================
412 //=============================================================================
414 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
416 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
417 (SMESH_Hypothesis::Hypothesis_Status theStatus)
420 RETURNCASE( HYP_OK );
421 RETURNCASE( HYP_MISSING );
422 RETURNCASE( HYP_CONCURENT );
423 RETURNCASE( HYP_BAD_PARAMETER );
424 RETURNCASE( HYP_HIDDEN_ALGO );
425 RETURNCASE( HYP_HIDING_ALGO );
426 RETURNCASE( HYP_UNKNOWN_FATAL );
427 RETURNCASE( HYP_INCOMPATIBLE );
428 RETURNCASE( HYP_NOTCONFORM );
429 RETURNCASE( HYP_ALREADY_EXIST );
430 RETURNCASE( HYP_BAD_DIM );
431 RETURNCASE( HYP_BAD_SUBSHAPE );
432 RETURNCASE( HYP_BAD_GEOMETRY );
433 RETURNCASE( HYP_NEED_SHAPE );
436 return SMESH::HYP_UNKNOWN_FATAL;
439 //=============================================================================
443 * calls internal addHypothesis() and then adds a reference to <anHyp> under
444 * the SObject actually having a reference to <aSubShape>.
445 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
447 //=============================================================================
449 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
450 SMESH::SMESH_Hypothesis_ptr anHyp)
451 throw(SALOME::SALOME_Exception)
453 Unexpect aCatch(SALOME_SalomeException);
454 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
456 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
457 _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(),
458 aSubShapeObject, anHyp );
460 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
462 // Update Python script
463 if(_impl->HasShapeToMesh()) {
464 TPythonDump() << "status = " << _this() << ".AddHypothesis( "
465 << aSubShapeObject << ", " << anHyp << " )";
468 TPythonDump() << "status = " << _this() << ".AddHypothesis( "<< anHyp << " )";
471 return ConvertHypothesisStatus(status);
474 //=============================================================================
478 //=============================================================================
480 SMESH_Hypothesis::Hypothesis_Status
481 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
482 SMESH::SMESH_Hypothesis_ptr anHyp)
484 if(MYDEBUG) MESSAGE("addHypothesis");
486 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
487 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
490 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
491 if (CORBA::is_nil(myHyp))
492 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
495 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
498 TopoDS_Shape myLocSubShape;
499 //use PseudoShape in case if mesh has no shape
501 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
503 myLocSubShape = _impl->GetShapeToMesh();
505 int hypId = myHyp->GetId();
506 status = _impl->AddHypothesis(myLocSubShape, hypId);
507 if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
508 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp );
509 #ifdef WITHGENERICOBJ
510 _mapHypo[hypId]->Register();
512 // assure there is a corresponding submesh
513 if ( !_impl->IsMainShape( myLocSubShape )) {
514 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
515 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
516 createSubMesh( aSubShapeObject );
520 catch(SALOME_Exception & S_ex)
522 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
527 //=============================================================================
531 //=============================================================================
533 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
534 SMESH::SMESH_Hypothesis_ptr anHyp)
535 throw(SALOME::SALOME_Exception)
537 Unexpect aCatch(SALOME_SalomeException);
538 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
540 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
541 _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(),
542 aSubShapeObject, anHyp );
544 // Update Python script
545 // Update Python script
546 if(_impl->HasShapeToMesh()) {
547 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
548 << aSubShapeObject << ", " << anHyp << " )";
551 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
555 return ConvertHypothesisStatus(status);
558 //=============================================================================
562 //=============================================================================
564 SMESH_Hypothesis::Hypothesis_Status
565 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
566 SMESH::SMESH_Hypothesis_ptr anHyp)
568 if(MYDEBUG) MESSAGE("removeHypothesis()");
569 // **** proposer liste de subShape (selection multiple)
571 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
572 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", SALOME::BAD_PARAM);
574 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
575 if (CORBA::is_nil(myHyp))
576 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
578 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
581 TopoDS_Shape myLocSubShape;
582 //use PseudoShape in case if mesh has no shape
584 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
586 myLocSubShape = _impl->GetShapeToMesh();
588 int hypId = myHyp->GetId();
589 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
590 // if ( !SMESH_Hypothesis::IsStatusFatal(status) ) EAP: hyp can be used on many subshapes
591 // _mapHypo.erase( hypId );
593 catch(SALOME_Exception & S_ex)
595 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
600 //=============================================================================
604 //=============================================================================
606 SMESH::ListOfHypothesis *
607 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
608 throw(SALOME::SALOME_Exception)
610 Unexpect aCatch(SALOME_SalomeException);
611 if (MYDEBUG) MESSAGE("GetHypothesisList");
612 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
613 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", SALOME::BAD_PARAM);
615 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
618 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
619 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
620 myLocSubShape = _impl->GetShapeToMesh();
621 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
622 int i = 0, n = aLocalList.size();
625 for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
626 SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
627 if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
628 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
633 catch(SALOME_Exception & S_ex) {
634 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
637 return aList._retn();
640 //=============================================================================
644 //=============================================================================
645 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
646 const char* theName )
647 throw(SALOME::SALOME_Exception)
649 Unexpect aCatch(SALOME_SalomeException);
650 MESSAGE("SMESH_Mesh_i::GetSubMesh");
651 if (CORBA::is_nil(aSubShapeObject))
652 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
655 SMESH::SMESH_subMesh_var subMesh;
656 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(_this());
658 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
660 //Get or Create the SMESH_subMesh object implementation
662 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
664 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
666 TopoDS_Iterator it( myLocSubShape );
668 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
670 subMesh = getSubMesh( subMeshId );
672 // create a new subMesh object servant if there is none for the shape
673 if ( subMesh->_is_nil() )
674 subMesh = createSubMesh( aSubShapeObject );
675 if ( _gen_i->CanPublishInStudy( subMesh )) {
676 SALOMEDS::SObject_var aSO =
677 _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
678 subMesh, aSubShapeObject, theName );
679 if ( !aSO->_is_nil()) {
680 // Update Python script
681 TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( "
682 << aSubShapeObject << ", '" << theName << "' )";
686 catch(SALOME_Exception & S_ex) {
687 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
689 return subMesh._retn();
692 //=============================================================================
696 //=============================================================================
698 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
699 throw (SALOME::SALOME_Exception)
701 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
702 if ( theSubMesh->_is_nil() )
705 GEOM::GEOM_Object_var aSubShapeObject;
706 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
707 if ( !aStudy->_is_nil() ) {
708 // Remove submesh's SObject
709 SALOMEDS::SObject_var anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
710 if ( !anSO->_is_nil() ) {
711 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
712 SALOMEDS::SObject_var anObj, aRef;
713 if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) )
714 aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
716 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
717 // aSubShapeObject = theSubMesh->GetSubShape();
719 aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
721 // Update Python script
722 TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )";
726 removeSubMesh( theSubMesh, aSubShapeObject.in() );
729 //=============================================================================
733 //=============================================================================
735 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
736 const char* theName )
737 throw(SALOME::SALOME_Exception)
739 Unexpect aCatch(SALOME_SalomeException);
740 SMESH::SMESH_Group_var aNewGroup =
741 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
743 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
744 SALOMEDS::SObject_var aSO =
745 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
746 aNewGroup, GEOM::GEOM_Object::_nil(), theName);
747 if ( !aSO->_is_nil()) {
748 // Update Python script
749 TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
750 << theElemType << ", '" << theName << "' )";
753 return aNewGroup._retn();
757 //=============================================================================
761 //=============================================================================
762 SMESH::SMESH_GroupOnGeom_ptr
763 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
765 GEOM::GEOM_Object_ptr theGeomObj)
766 throw(SALOME::SALOME_Exception)
768 Unexpect aCatch(SALOME_SalomeException);
769 SMESH::SMESH_GroupOnGeom_var aNewGroup;
771 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
772 if ( !aShape.IsNull() )
774 aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
775 ( createGroup( theElemType, theName, aShape ));
777 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
778 SALOMEDS::SObject_var aSO =
779 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
780 aNewGroup, theGeomObj, theName);
781 if ( !aSO->_is_nil()) {
782 // Update Python script
783 TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
784 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
789 return aNewGroup._retn();
792 //================================================================================
794 * \brief Creates a group whose contents is defined by filter
795 * \param theElemType - group type
796 * \param theName - group name
797 * \param theFilter - the filter
798 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
800 //================================================================================
802 SMESH::SMESH_GroupOnFilter_ptr
803 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
805 SMESH::Filter_ptr theFilter )
806 throw (SALOME::SALOME_Exception)
808 Unexpect aCatch(SALOME_SalomeException);
810 if ( CORBA::is_nil( theFilter ))
811 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
813 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
815 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
817 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
818 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
821 if ( !aNewGroup->_is_nil() )
822 aNewGroup->SetFilter( theFilter );
824 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
826 SALOMEDS::SObject_var aSO =
827 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), aNewGroup,
828 GEOM::GEOM_Object::_nil(), theName);
829 if ( !aSO->_is_nil()) {
830 // Update Python script
831 pd << aSO << " = " << _this() << ".CreateGroupFromFilter("
832 << theElemType << ", '" << theName << "', " << theFilter << " )";
836 return aNewGroup._retn();
839 //=============================================================================
843 //=============================================================================
845 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
846 throw (SALOME::SALOME_Exception)
848 if ( theGroup->_is_nil() )
851 SMESH_GroupBase_i* aGroup =
852 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
856 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
857 if ( !aStudy->_is_nil() ) {
858 SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
860 if ( !aGroupSO->_is_nil() ) {
861 // Update Python script
862 TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
864 // Remove group's SObject
865 aStudy->NewBuilder()->RemoveObjectWithChildren( aGroupSO );
869 // Remove the group from SMESH data structures
870 removeGroup( aGroup->GetLocalID() );
873 //=============================================================================
874 /*! RemoveGroupWithContents
875 * Remove group with its contents
877 //=============================================================================
878 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
879 throw (SALOME::SALOME_Exception)
881 if ( theGroup->_is_nil() )
884 SMESH_GroupBase_i* aGroup =
885 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
889 SMESH::long_array_var anIds = aGroup->GetListOfID();
890 SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
892 TPythonDump pyDump; // Supress dump from RemoveNodes/Elements() and RemoveGroup()
895 if ( aGroup->GetType() == SMESH::NODE )
896 aMeshEditor->RemoveNodes( anIds );
898 aMeshEditor->RemoveElements( anIds );
901 RemoveGroup( theGroup );
903 // Update Python script
904 pyDump << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
907 //================================================================================
909 * \brief Get the list of groups existing in the mesh
910 * \retval SMESH::ListOfGroups * - list of groups
912 //================================================================================
914 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
916 Unexpect aCatch(SALOME_SalomeException);
917 if (MYDEBUG) MESSAGE("GetGroups");
919 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
922 TPythonDump aPythonDump;
923 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
927 aList->length( _mapGroups.size() );
929 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
930 for ( ; it != _mapGroups.end(); it++ ) {
931 if ( CORBA::is_nil( it->second )) continue;
932 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
934 if (i > 1) aPythonDump << ", ";
935 aPythonDump << it->second;
939 catch(SALOME_Exception & S_ex) {
940 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
943 // Update Python script
944 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
945 aPythonDump << " ] = " << _this() << ".GetGroups()";
947 return aList._retn();
950 //=============================================================================
952 * Get number of groups existing in the mesh
954 //=============================================================================
956 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
958 Unexpect aCatch(SALOME_SalomeException);
959 return _mapGroups.size();
962 //=============================================================================
964 * New group is created. All mesh elements that are
965 * present in initial groups are added to the new one
967 //=============================================================================
968 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
969 SMESH::SMESH_GroupBase_ptr theGroup2,
970 const char* theName )
971 throw (SALOME::SALOME_Exception)
975 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
976 theGroup1->GetType() != theGroup2->GetType() )
977 return SMESH::SMESH_Group::_nil();
980 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
981 if ( aResGrp->_is_nil() )
982 return SMESH::SMESH_Group::_nil();
984 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
985 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
987 TColStd_MapOfInteger aResMap;
989 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
990 aResMap.Add( anIds1[ i1 ] );
992 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
993 aResMap.Add( anIds2[ i2 ] );
995 SMESH::long_array_var aResIds = new SMESH::long_array;
996 aResIds->length( aResMap.Extent() );
999 TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
1000 for( ; anIter.More(); anIter.Next() )
1001 aResIds[ resI++ ] = anIter.Key();
1003 aResGrp->Add( aResIds );
1005 // Clear python lines, created by CreateGroup() and Add()
1006 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1007 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1008 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1010 // Update Python script
1011 TPythonDump() << aResGrp << " = " << _this() << ".UnionGroups( "
1012 << theGroup1 << ", " << theGroup2 << ", '"
1013 << theName << "' )";
1015 return aResGrp._retn();
1019 return SMESH::SMESH_Group::_nil();
1023 //=============================================================================
1025 \brief Union list of groups. New group is created. All mesh elements that are
1026 present in initial groups are added to the new one.
1027 \param theGroups list of groups
1028 \param theName name of group to be created
1029 \return pointer on the group
1031 //=============================================================================
1032 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1033 const char* theName )
1034 throw (SALOME::SALOME_Exception)
1037 return SMESH::SMESH_Group::_nil();
1041 vector< int > anIds;
1042 SMESH::ElementType aType = SMESH::ALL;
1043 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1045 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1046 if ( CORBA::is_nil( aGrp ) )
1050 SMESH::ElementType aCurrType = aGrp->GetType();
1051 if ( aType == SMESH::ALL )
1055 if ( aType != aCurrType )
1056 return SMESH::SMESH_Group::_nil();
1060 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1061 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1063 int aCurrId = aCurrIds[ i ];
1064 anIds.push_back( aCurrId );
1069 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1070 if ( aResGrp->_is_nil() )
1071 return SMESH::SMESH_Group::_nil();
1073 // Create array of identifiers
1074 SMESH::long_array_var aResIds = new SMESH::long_array;
1075 aResIds->length( anIds.size() );
1077 //NCollection_Map< int >::Iterator anIter( anIds );
1078 for ( int i = 0; i<anIds.size(); i++ )
1080 aResIds[ i ] = anIds[i];
1082 aResGrp->Add( aResIds );
1084 // Clear python lines, created by CreateGroup() and Add()
1085 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1086 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1087 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1089 // Update Python script
1091 TPythonDump() << aResGrp << " = " << _this() << ".UnionListOfGroups( "
1092 << &theGroups << ", '" << theName << "' )";
1094 return aResGrp._retn();
1098 return SMESH::SMESH_Group::_nil();
1102 //=============================================================================
1104 * New group is created. All mesh elements that are
1105 * present in both initial groups are added to the new one.
1107 //=============================================================================
1108 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1109 SMESH::SMESH_GroupBase_ptr theGroup2,
1110 const char* theName )
1111 throw (SALOME::SALOME_Exception)
1113 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1114 theGroup1->GetType() != theGroup2->GetType() )
1115 return SMESH::SMESH_Group::_nil();
1117 // Create Intersection
1118 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1119 if ( aResGrp->_is_nil() )
1122 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1123 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1125 TColStd_MapOfInteger aMap1;
1127 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1128 aMap1.Add( anIds1[ i1 ] );
1130 TColStd_SequenceOfInteger aSeq;
1132 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1133 if ( aMap1.Contains( anIds2[ i2 ] ) )
1134 aSeq.Append( anIds2[ i2 ] );
1136 SMESH::long_array_var aResIds = new SMESH::long_array;
1137 aResIds->length( aSeq.Length() );
1139 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1140 aResIds[ resI ] = aSeq( resI + 1 );
1142 aResGrp->Add( aResIds );
1144 // Clear python lines, created by CreateGroup() and Add()
1145 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1146 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1147 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1149 // Update Python script
1150 TPythonDump() << aResGrp << " = " << _this() << ".IntersectGroups( "
1151 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1153 return aResGrp._retn();
1156 //=============================================================================
1158 \brief Intersect list of groups. New group is created. All mesh elements that
1159 are present in all initial groups simultaneously are added to the new one.
1160 \param theGroups list of groups
1161 \param theName name of group to be created
1162 \return pointer on the group
1164 //=============================================================================
1165 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectListOfGroups(
1166 const SMESH::ListOfGroups& theGroups, const char* theName )
1167 throw (SALOME::SALOME_Exception)
1170 return SMESH::SMESH_Group::_nil();
1174 NCollection_DataMap< int, int > anIdToCount;
1175 SMESH::ElementType aType = SMESH::ALL;
1176 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1178 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1179 if ( CORBA::is_nil( aGrp ) )
1183 SMESH::ElementType aCurrType = aGrp->GetType();
1184 if ( aType == SMESH::ALL )
1188 if ( aType != aCurrType )
1189 return SMESH::SMESH_Group::_nil();
1192 // calculates number of occurance ids in groups
1193 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1194 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1196 int aCurrId = aCurrIds[ i ];
1197 if ( !anIdToCount.IsBound( aCurrId ) )
1198 anIdToCount.Bind( aCurrId, 1 );
1200 anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
1204 // create map of ids
1205 int nbGrp = theGroups.length();
1206 vector< int > anIds;
1207 NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
1208 for ( ; anIter.More(); anIter.Next() )
1210 int aCurrId = anIter.Key();
1211 int aCurrNb = anIter.Value();
1212 if ( aCurrNb == nbGrp )
1213 anIds.push_back( aCurrId );
1217 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1218 if ( aResGrp->_is_nil() )
1219 return SMESH::SMESH_Group::_nil();
1221 // Create array of identifiers
1222 SMESH::long_array_var aResIds = new SMESH::long_array;
1223 aResIds->length( anIds.size() );
1225 //NCollection_Map< int >::Iterator aListIter( anIds );
1226 for ( int i = 0; i<anIds.size(); i++ )
1228 aResIds[ i ] = anIds[i];
1230 aResGrp->Add( aResIds );
1232 // Clear python lines, created by CreateGroup() and Add()
1233 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1234 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1235 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1237 // Update Python script
1239 TPythonDump() << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
1240 << &theGroups << ", '" << theName << "' )";
1242 return aResGrp._retn();
1246 return SMESH::SMESH_Group::_nil();
1250 //=============================================================================
1252 * New group is created. All mesh elements that are present in
1253 * main group but do not present in tool group are added to the new one
1255 //=============================================================================
1256 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1257 SMESH::SMESH_GroupBase_ptr theGroup2,
1258 const char* theName )
1259 throw (SALOME::SALOME_Exception)
1261 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1262 theGroup1->GetType() != theGroup2->GetType() )
1263 return SMESH::SMESH_Group::_nil();
1266 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1267 if ( aResGrp->_is_nil() )
1270 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1271 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1273 TColStd_MapOfInteger aMap2;
1275 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1276 aMap2.Add( anIds2[ i2 ] );
1278 TColStd_SequenceOfInteger aSeq;
1279 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1280 if ( !aMap2.Contains( anIds1[ i1 ] ) )
1281 aSeq.Append( anIds1[ i1 ] );
1283 SMESH::long_array_var aResIds = new SMESH::long_array;
1284 aResIds->length( aSeq.Length() );
1286 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1287 aResIds[ resI ] = aSeq( resI + 1 );
1289 aResGrp->Add( aResIds );
1291 // Clear python lines, created by CreateGroup() and Add()
1292 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1293 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1294 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1296 // Update Python script
1297 TPythonDump() << aResGrp << " = " << _this() << ".CutGroups( "
1298 << theGroup1 << ", " << theGroup2 << ", '"
1299 << theName << "' )";
1301 return aResGrp._retn();
1304 //=============================================================================
1306 \brief Cut lists of groups. New group is created. All mesh elements that are
1307 present in main groups but do not present in tool groups are added to the new one
1308 \param theMainGroups list of main groups
1309 \param theToolGroups list of tool groups
1310 \param theName name of group to be created
1311 \return pointer on the group
1313 //=============================================================================
1314 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups(
1315 const SMESH::ListOfGroups& theMainGroups,
1316 const SMESH::ListOfGroups& theToolGroups,
1317 const char* theName )
1318 throw (SALOME::SALOME_Exception)
1321 return SMESH::SMESH_Group::_nil();
1325 set< int > aToolIds;
1326 SMESH::ElementType aType = SMESH::ALL;
1328 // iterate through tool groups
1329 for ( g = 0, n = theToolGroups.length(); g < n; g++ )
1331 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1332 if ( CORBA::is_nil( aGrp ) )
1336 SMESH::ElementType aCurrType = aGrp->GetType();
1337 if ( aType == SMESH::ALL )
1341 if ( aType != aCurrType )
1342 return SMESH::SMESH_Group::_nil();
1346 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1347 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1349 int aCurrId = aCurrIds[ i ];
1350 aToolIds.insert( aCurrId );
1354 vector< int > anIds; // result
1356 // Iterate through main group
1357 for ( g = 0, n = theMainGroups.length(); g < n; g++ )
1359 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1360 if ( CORBA::is_nil( aGrp ) )
1364 SMESH::ElementType aCurrType = aGrp->GetType();
1365 if ( aType == SMESH::ALL )
1369 if ( aType != aCurrType )
1370 return SMESH::SMESH_Group::_nil();
1374 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1375 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1377 int aCurrId = aCurrIds[ i ];
1378 if ( !aToolIds.count( aCurrId ) )
1379 anIds.push_back( aCurrId );
1384 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1385 if ( aResGrp->_is_nil() )
1386 return SMESH::SMESH_Group::_nil();
1388 // Create array of identifiers
1389 SMESH::long_array_var aResIds = new SMESH::long_array;
1390 aResIds->length( anIds.size() );
1392 for (int i=0; i<anIds.size(); i++ )
1394 aResIds[ i ] = anIds[i];
1396 aResGrp->Add( aResIds );
1398 // Clear python lines, created by CreateGroup() and Add()
1399 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1400 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1401 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1403 // Update Python script
1405 TPythonDump() << aResGrp << " = " << _this() << ".CutListOfGroups( "
1406 << &theMainGroups << ", " << &theToolGroups << ", '"
1407 << theName << "' )";
1409 return aResGrp._retn();
1413 return SMESH::SMESH_Group::_nil();
1417 //=============================================================================
1419 \brief Create groups of entities from existing groups of superior dimensions
1421 1) extract all nodes from each group,
1422 2) combine all elements of specified dimension laying on these nodes.
1423 \param theGroups list of source groups
1424 \param theElemType dimension of elements
1425 \param theName name of new group
1426 \return pointer on new group
1428 //=============================================================================
1429 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
1430 const SMESH::ListOfGroups& theGroups,
1431 SMESH::ElementType theElemType,
1432 const char* theName )
1433 throw (SALOME::SALOME_Exception)
1435 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1437 if ( !theName || !aMeshDS )
1438 return SMESH::SMESH_Group::_nil();
1440 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1444 // Create map of nodes from all groups
1446 set< int > aNodeMap;
1448 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1450 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1451 if ( CORBA::is_nil( aGrp ) )
1454 SMESH::ElementType aType = aGrp->GetType();
1455 if ( aType == SMESH::ALL )
1457 else if ( aType == SMESH::NODE )
1459 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1460 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1462 int aCurrId = aCurrIds[ i ];
1463 const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
1465 aNodeMap.insert( aNode->GetID() );
1470 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1471 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1473 int aCurrId = aCurrIds[ i ];
1474 const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId );
1477 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1478 while( aNodeIter->more() )
1480 const SMDS_MeshNode* aNode =
1481 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1483 aNodeMap.insert( aNode->GetID() );
1489 // Get result identifiers
1491 vector< int > aResultIds;
1492 if ( theElemType == SMESH::NODE )
1494 //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1495 set<int>::iterator iter = aNodeMap.begin();
1496 for ( ; iter != aNodeMap.end(); iter++ )
1497 aResultIds.push_back( *iter);
1501 // Create list of elements of given dimension constructed on the nodes
1502 vector< int > anElemList;
1503 //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1504 //for ( ; aNodeIter.More(); aNodeIter.Next() )
1505 set<int>::iterator iter = aNodeMap.begin();
1506 for ( ; iter != aNodeMap.end(); iter++ )
1508 const SMDS_MeshElement* aNode =
1509 dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( *iter ) );
1513 SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType );
1514 while( anElemIter->more() )
1516 const SMDS_MeshElement* anElem =
1517 dynamic_cast<const SMDS_MeshElement*>( anElemIter->next() );
1518 if ( anElem && anElem->GetType() == anElemType )
1519 anElemList.push_back( anElem->GetID() );
1523 // check whether all nodes of elements are present in nodes map
1524 //NCollection_Map< int >::Iterator anIter( anElemList );
1525 //for ( ; anIter.More(); anIter.Next() )
1526 for (int i=0; i< anElemList.size(); i++)
1528 const SMDS_MeshElement* anElem = aMeshDS->FindElement( anElemList[i] );
1533 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1534 while( aNodeIter->more() )
1536 const SMDS_MeshNode* aNode =
1537 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1538 if ( !aNode || !aNodeMap.count( aNode->GetID() ) )
1545 aResultIds.push_back( anElem->GetID() );
1551 SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName );
1552 if ( aResGrp->_is_nil() )
1553 return SMESH::SMESH_Group::_nil();
1555 // Create array of identifiers
1556 SMESH::long_array_var aResIds = new SMESH::long_array;
1557 aResIds->length( aResultIds.size() );
1559 //NCollection_Map< int >::Iterator aResIter( aResultIds );
1560 //for ( int i = 0; aResIter.More(); aResIter.Next(), i++ )
1561 for (int i=0; i< aResultIds.size(); i++)
1562 aResIds[ i ] = aResultIds[i];
1563 aResGrp->Add( aResIds );
1565 // Remove strings corresponding to group creation
1566 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1567 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1568 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1570 // Update Python script
1572 TPythonDump() << aResGrp << " = " << _this() << ".CreateDimGroup( "
1573 << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1575 return aResGrp._retn();
1579 return SMESH::SMESH_Group::_nil();
1583 //================================================================================
1585 * \brief Remember GEOM group data
1587 //================================================================================
1589 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1590 CORBA::Object_ptr theSmeshObj)
1592 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1595 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1596 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1597 if ( groupSO->_is_nil() )
1600 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1601 GEOM::GEOM_IGroupOperations_var groupOp =
1602 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1603 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1606 _geomGroupData.push_back( TGeomGroupData() );
1607 TGeomGroupData & groupData = _geomGroupData.back();
1609 CORBA::String_var entry = groupSO->GetID();
1610 groupData._groupEntry = entry.in();
1612 for ( int i = 0; i < ids->length(); ++i )
1613 groupData._indices.insert( ids[i] );
1615 groupData._smeshObject = theSmeshObj;
1618 //================================================================================
1620 * Remove GEOM group data relating to removed smesh object
1622 //================================================================================
1624 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1626 list<TGeomGroupData>::iterator
1627 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1628 for ( ; data != dataEnd; ++data ) {
1629 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1630 _geomGroupData.erase( data );
1636 //================================================================================
1638 * \brief Return new group contents if it has been changed and update group data
1640 //================================================================================
1642 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1644 TopoDS_Shape newShape;
1647 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1648 if ( study->_is_nil() ) return newShape; // means "not changed"
1649 SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1650 if ( !groupSO->_is_nil() )
1652 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1653 if ( CORBA::is_nil( groupObj )) return newShape;
1654 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1656 // get indices of group items
1657 set<int> curIndices;
1658 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1659 GEOM::GEOM_IGroupOperations_var groupOp =
1660 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1661 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1662 for ( int i = 0; i < ids->length(); ++i )
1663 curIndices.insert( ids[i] );
1665 if ( groupData._indices == curIndices )
1666 return newShape; // group not changed
1669 groupData._indices = curIndices;
1671 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1672 if ( !geomClient ) return newShape;
1673 TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1674 geomClient->RemoveShapeFromBuffer( groupIOR );
1675 newShape = _gen_i->GeomObjectToShape( geomGroup );
1678 if ( newShape.IsNull() ) {
1679 // geom group becomes empty - return empty compound
1680 TopoDS_Compound compound;
1681 BRep_Builder().MakeCompound(compound);
1682 newShape = compound;
1688 //=============================================================================
1690 * \brief Storage of shape and index used in CheckGeomGroupModif()
1692 //=============================================================================
1693 struct TIndexedShape {
1695 TopoDS_Shape _shape;
1696 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1699 //=============================================================================
1701 * \brief Update objects depending on changed geom groups
1703 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1704 * issue 0020210: Update of a smesh group after modification of the associated geom group
1706 //=============================================================================
1708 void SMESH_Mesh_i::CheckGeomGroupModif()
1710 if ( !_impl->HasShapeToMesh() ) return;
1712 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1713 if ( study->_is_nil() ) return;
1715 CORBA::Long nbEntities = NbNodes() + NbElements();
1717 // Check if group contents changed
1719 typedef map< string, TopoDS_Shape > TEntry2Geom;
1720 TEntry2Geom newGroupContents;
1722 list<TGeomGroupData>::iterator
1723 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1724 for ( ; data != dataEnd; ++data )
1726 pair< TEntry2Geom::iterator, bool > it_new =
1727 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1728 bool processedGroup = !it_new.second;
1729 TopoDS_Shape& newShape = it_new.first->second;
1730 if ( !processedGroup )
1731 newShape = newGroupShape( *data );
1732 if ( newShape.IsNull() )
1733 continue; // no changes
1735 if ( processedGroup ) { // update group indices
1736 list<TGeomGroupData>::iterator data2 = data;
1737 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1738 data->_indices = data2->_indices;
1741 // Update SMESH objects according to new GEOM group contents
1743 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1744 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1746 int oldID = submesh->GetId();
1747 if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1749 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1751 // update hypotheses
1752 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1753 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1754 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1756 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1757 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1759 // care of submeshes
1760 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1761 int newID = newSubmesh->GetId();
1762 if ( newID != oldID ) {
1763 _mapSubMesh [ newID ] = newSubmesh;
1764 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1765 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1766 _mapSubMesh. erase(oldID);
1767 _mapSubMesh_i. erase(oldID);
1768 _mapSubMeshIor.erase(oldID);
1769 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1774 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1775 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1776 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1778 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1780 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1781 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1782 ds->SetShape( newShape );
1787 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1788 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1790 // Remove groups and submeshes basing on removed sub-shapes
1792 TopTools_MapOfShape newShapeMap;
1793 TopoDS_Iterator shapeIt( newShape );
1794 for ( ; shapeIt.More(); shapeIt.Next() )
1795 newShapeMap.Add( shapeIt.Value() );
1797 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1798 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1800 if ( newShapeMap.Contains( shapeIt.Value() ))
1802 TopTools_IndexedMapOfShape oldShapeMap;
1803 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1804 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1806 const TopoDS_Shape& oldShape = oldShapeMap(i);
1807 int oldInd = meshDS->ShapeToIndex( oldShape );
1809 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1810 if ( i_smIor != _mapSubMeshIor.end() ) {
1811 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1814 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1815 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1817 // check if a group bases on oldInd shape
1818 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1819 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1820 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1821 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1823 RemoveGroup( i_grp->second ); // several groups can base on same shape
1824 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1829 // Reassign hypotheses and update groups after setting the new shape to mesh
1831 // collect anassigned hypotheses
1832 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1833 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1834 TShapeHypList assignedHyps;
1835 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1837 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1838 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1839 if ( !hyps.empty() ) {
1840 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1841 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1842 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1845 // collect shapes supporting groups
1846 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1847 TShapeTypeList groupData;
1848 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1849 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1850 for ( ; grIt != groups.end(); ++grIt )
1852 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1854 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1856 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1857 _impl->ShapeToMesh( newShape );
1859 // reassign hypotheses
1860 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1861 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1863 TIndexedShape& geom = indS_hyps->first;
1864 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1865 int oldID = geom._index;
1866 int newID = meshDS->ShapeToIndex( geom._shape );
1869 if ( oldID == 1 ) { // main shape
1871 geom._shape = newShape;
1873 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1874 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
1875 // care of submeshes
1876 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
1877 if ( newID != oldID ) {
1878 _mapSubMesh [ newID ] = newSubmesh;
1879 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1880 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1881 _mapSubMesh. erase(oldID);
1882 _mapSubMesh_i. erase(oldID);
1883 _mapSubMeshIor.erase(oldID);
1884 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1888 TShapeTypeList::iterator geomType = groupData.begin();
1889 for ( ; geomType != groupData.end(); ++geomType )
1891 const TIndexedShape& geom = geomType->first;
1892 int oldID = geom._index;
1893 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
1896 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
1897 CORBA::String_var name = groupSO->GetName();
1899 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
1901 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
1902 group_i->changeLocalId( newID );
1905 break; // everything has been updated
1908 } // loop on group data
1912 CORBA::Long newNbEntities = NbNodes() + NbElements();
1913 list< SALOMEDS::SObject_var > soToUpdateIcons;
1914 if ( newNbEntities != nbEntities )
1916 // Add all SObjects with icons
1917 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
1919 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
1920 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
1921 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
1923 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
1924 i_gr != _mapGroups.end(); ++i_gr ) // groups
1925 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
1928 list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin();
1929 for ( ; so != soToUpdateIcons.end(); ++so )
1930 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
1933 //=============================================================================
1935 * \brief Create standalone group from a group on geometry or filter
1937 //=============================================================================
1939 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
1941 SMESH::SMESH_Group_var aGroup;
1942 if ( theGroup->_is_nil() )
1943 return aGroup._retn();
1945 Unexpect aCatch(SALOME_SalomeException);
1947 SMESH_GroupBase_i* aGroupToRem =
1948 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1950 return aGroup._retn();
1952 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
1954 int anId = aGroupToRem->GetLocalID();
1955 if ( !_impl->ConvertToStandalone( anId ) )
1956 return aGroup._retn();
1957 removeGeomGroupData( theGroup );
1959 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
1961 // remove old instance of group from own map
1962 _mapGroups.erase( anId );
1964 SALOMEDS::StudyBuilder_var builder;
1965 SALOMEDS::SObject_var aGroupSO;
1966 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1967 if ( !aStudy->_is_nil() ) {
1968 builder = aStudy->NewBuilder();
1969 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1970 if ( !aGroupSO->_is_nil() ) {
1972 // remove reference to geometry
1973 SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO);
1974 for ( ; chItr->More(); chItr->Next() )
1975 // Remove group's child SObject
1976 builder->RemoveObject( chItr->Value() );
1978 // Update Python script
1979 TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
1980 << aGroupSO << " )";
1982 // change icon of Group on Filter
1985 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
1986 const int isEmpty = ( elemTypes->length() == 0 );
1989 SALOMEDS::GenericAttribute_var anAttr =
1990 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
1991 SALOMEDS::AttributePixMap_var pm = SALOMEDS::AttributePixMap::_narrow( anAttr );
1992 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
1998 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1999 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2000 aGroupImpl->Register();
2001 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2003 // remember new group in own map
2004 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2005 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2007 // register CORBA object for persistence
2008 /*int nextId =*/ _gen_i->RegisterObject( aGroup );
2010 builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) );
2012 return aGroup._retn();
2015 //=============================================================================
2019 //=============================================================================
2021 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2023 if(MYDEBUG) MESSAGE( "createSubMesh" );
2024 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2026 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2027 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
2028 SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2029 SMESH::SMESH_subMesh_var subMesh
2030 = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
2032 _mapSubMesh[subMeshId] = mySubMesh;
2033 _mapSubMesh_i[subMeshId] = subMeshServant;
2034 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
2036 // register CORBA object for persistence
2037 int nextId = _gen_i->RegisterObject( subMesh );
2038 if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
2040 // to track changes of GEOM groups
2041 addGeomGroupData( theSubShapeObject, subMesh );
2043 return subMesh._retn();
2046 //=======================================================================
2047 //function : getSubMesh
2049 //=======================================================================
2051 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2053 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2054 if ( it == _mapSubMeshIor.end() )
2055 return SMESH::SMESH_subMesh::_nil();
2057 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2061 //=============================================================================
2065 //=============================================================================
2067 void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2068 GEOM::GEOM_Object_ptr theSubShapeObject )
2070 MESSAGE("SMESH_Mesh_i::removeSubMesh()");
2071 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2074 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2076 CORBA::Long shapeId = theSubMesh->GetId();
2077 if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
2079 TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
2082 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2083 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2084 for ( ; hyp != hyps.end(); ++hyp )
2085 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2092 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2093 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2094 removeHypothesis( theSubShapeObject, aHypList[i] );
2097 catch( const SALOME::SALOME_Exception& ) {
2098 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2100 removeGeomGroupData( theSubShapeObject );
2102 int subMeshId = theSubMesh->GetId();
2104 _mapSubMesh.erase(subMeshId);
2105 _mapSubMesh_i.erase(subMeshId);
2106 _mapSubMeshIor.erase(subMeshId);
2107 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeSubMesh() completed");
2110 //=============================================================================
2114 //=============================================================================
2116 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2117 const char* theName,
2118 const TopoDS_Shape& theShape,
2119 const SMESH_PredicatePtr& thePredicate )
2121 std::string newName;
2122 if ( !theName || strlen( theName ) == 0 )
2124 std::set< std::string > presentNames;
2125 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2126 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2127 presentNames.insert( i_gr->second->GetName() );
2129 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2130 } while ( !presentNames.insert( newName ).second );
2131 theName = newName.c_str();
2134 SMESH::SMESH_GroupBase_var aGroup;
2135 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2137 SMESH_GroupBase_i* aGroupImpl;
2138 if ( !theShape.IsNull() )
2139 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2140 else if ( thePredicate )
2141 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2143 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2145 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2146 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2147 aGroupImpl->Register();
2148 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2150 aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2151 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2153 // register CORBA object for persistence
2154 int nextId = _gen_i->RegisterObject( aGroup );
2155 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2157 // to track changes of GEOM groups
2158 if ( !theShape.IsNull() ) {
2159 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2160 addGeomGroupData( geom, aGroup );
2163 return aGroup._retn();
2166 //=============================================================================
2168 * SMESH_Mesh_i::removeGroup
2170 * Should be called by ~SMESH_Group_i()
2172 //=============================================================================
2174 void SMESH_Mesh_i::removeGroup( const int theId )
2176 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2177 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2178 SMESH::SMESH_GroupBase_ptr group = _mapGroups[theId];
2179 _mapGroups.erase( theId );
2180 removeGeomGroupData( group );
2181 if (! _impl->RemoveGroup( theId ))
2183 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2184 RemoveGroup( group );
2189 //=============================================================================
2193 //=============================================================================
2195 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2196 throw(SALOME::SALOME_Exception)
2198 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetLog");
2200 SMESH::log_array_var aLog;
2202 list < SMESHDS_Command * >logDS = _impl->GetLog();
2203 aLog = new SMESH::log_array;
2205 int lg = logDS.size();
2208 list < SMESHDS_Command * >::iterator its = logDS.begin();
2209 while(its != logDS.end()){
2210 SMESHDS_Command *com = *its;
2211 int comType = com->GetType();
2213 int lgcom = com->GetNumber();
2215 const list < int >&intList = com->GetIndexes();
2216 int inum = intList.size();
2218 list < int >::const_iterator ii = intList.begin();
2219 const list < double >&coordList = com->GetCoords();
2220 int rnum = coordList.size();
2222 list < double >::const_iterator ir = coordList.begin();
2223 aLog[indexLog].commandType = comType;
2224 aLog[indexLog].number = lgcom;
2225 aLog[indexLog].coords.length(rnum);
2226 aLog[indexLog].indexes.length(inum);
2227 for(int i = 0; i < rnum; i++){
2228 aLog[indexLog].coords[i] = *ir;
2229 //MESSAGE(" "<<i<<" "<<ir.Value());
2232 for(int i = 0; i < inum; i++){
2233 aLog[indexLog].indexes[i] = *ii;
2234 //MESSAGE(" "<<i<<" "<<ii.Value());
2243 catch(SALOME_Exception & S_ex){
2244 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
2246 return aLog._retn();
2250 //=============================================================================
2254 //=============================================================================
2256 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2258 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
2262 //=============================================================================
2266 //=============================================================================
2268 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2270 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
2274 //=============================================================================
2278 //=============================================================================
2280 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2285 //=============================================================================
2288 //!< implementation of struct used to call SMESH_Mesh_i::removeGroup() from
2289 // SMESH_Mesh::RemoveGroup() (issue 0020918)
2290 struct TRmGroupCallUp_i : public SMESH_Mesh::TRmGroupCallUp
2292 SMESH_Mesh_i* _mesh;
2293 TRmGroupCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2294 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2298 //=============================================================================
2302 //=============================================================================
2304 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2306 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2309 _impl->SetRemoveGroupCallUp( new TRmGroupCallUp_i(this));
2312 //=============================================================================
2316 //=============================================================================
2318 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2320 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2324 //=============================================================================
2326 * Return mesh editor
2328 //=============================================================================
2330 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2332 // Create MeshEditor
2333 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
2334 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2336 // Update Python script
2337 TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
2339 return aMesh._retn();
2342 //=============================================================================
2344 * Return mesh edition previewer
2346 //=============================================================================
2348 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2350 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
2351 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2352 return aMesh._retn();
2355 //================================================================================
2357 * \brief Return true if the mesh has been edited since a last total re-compute
2358 * and those modifications may prevent successful partial re-compute
2360 //================================================================================
2362 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2364 Unexpect aCatch(SALOME_SalomeException);
2365 return _impl->HasModificationsToDiscard();
2368 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2370 const int MAX_ATTEMPTS = 100;
2372 double tolerance = 0.5;
2373 SALOMEDS::Color col;
2377 // generate random color
2378 double red = (double)rand() / RAND_MAX;
2379 double green = (double)rand() / RAND_MAX;
2380 double blue = (double)rand() / RAND_MAX;
2381 // check existence in the list of the existing colors
2382 bool matched = false;
2383 std::list<SALOMEDS::Color>::const_iterator it;
2384 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2385 SALOMEDS::Color color = *it;
2386 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2387 matched = tol < tolerance;
2389 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2390 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2398 //=============================================================================
2402 //=============================================================================
2403 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2405 Unexpect aCatch(SALOME_SalomeException);
2406 _impl->SetAutoColor(theAutoColor);
2408 TPythonDump pyDump; // not to dump group->SetColor() from below code
2409 pyDump<<_this()<<".SetAutoColor( "<<theAutoColor<<" )";
2411 std::list<SALOMEDS::Color> aReservedColors;
2412 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2413 for ( ; it != _mapGroups.end(); it++ ) {
2414 if ( CORBA::is_nil( it->second )) continue;
2415 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2416 it->second->SetColor( aColor );
2417 aReservedColors.push_back( aColor );
2421 //=============================================================================
2425 //=============================================================================
2426 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2428 Unexpect aCatch(SALOME_SalomeException);
2429 return _impl->GetAutoColor();
2433 //=============================================================================
2435 * Export in different formats
2437 //=============================================================================
2439 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2441 return _impl->HasDuplicatedGroupNamesMED();
2444 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2446 TCollection_AsciiString aFullName ((char*)file);
2447 OSD_Path aPath (aFullName);
2448 OSD_File aFile (aPath);
2449 if (aFile.Exists()) {
2450 // existing filesystem node
2451 if (aFile.KindOfFile() == OSD_FILE) {
2452 if (aFile.IsWriteable()) {
2457 if (aFile.Failed()) {
2458 TCollection_AsciiString msg ("File ");
2459 msg += aFullName + " cannot be replaced.";
2460 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2463 TCollection_AsciiString msg ("File ");
2464 msg += aFullName + " cannot be overwritten.";
2465 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2468 TCollection_AsciiString msg ("Location ");
2469 msg += aFullName + " is not a file.";
2470 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2473 // nonexisting file; check if it can be created
2475 aFile.Build(OSD_WriteOnly, OSD_Protection());
2476 if (aFile.Failed()) {
2477 TCollection_AsciiString msg ("You cannot create the file ");
2478 msg += aFullName + ". Check the directory existance and access rights.";
2479 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2487 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2488 CORBA::Boolean auto_groups,
2489 SMESH::MED_VERSION theVersion,
2490 CORBA::Boolean overwrite)
2491 throw(SALOME::SALOME_Exception)
2493 Unexpect aCatch(SALOME_SalomeException);
2496 PrepareForWriting(file, overwrite);
2497 string aMeshName = "Mesh";
2498 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2499 if ( !aStudy->_is_nil() ) {
2500 SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2501 if ( !aMeshSO->_is_nil() ) {
2502 CORBA::String_var name = aMeshSO->GetName();
2504 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2505 if ( !aStudy->GetProperties()->IsLocked() )
2507 SALOMEDS::GenericAttribute_var anAttr;
2508 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2509 SALOMEDS::AttributeExternalFileDef_var aFileName;
2510 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2511 aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
2512 ASSERT(!aFileName->_is_nil());
2513 aFileName->SetValue(file);
2514 SALOMEDS::AttributeFileType_var aFileType;
2515 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2516 aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
2517 ASSERT(!aFileType->_is_nil());
2518 aFileType->SetValue("FICHIERMED");
2522 // Update Python script
2523 // set name of mesh before export
2524 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName.c_str() << "')";
2526 // check names of groups
2529 TPythonDump() << _this() << ".ExportToMEDX( r'"
2530 << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )";
2532 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion );
2535 //================================================================================
2537 * \brief Export a mesh to a med file
2539 //================================================================================
2541 void SMESH_Mesh_i::ExportToMED (const char* file,
2542 CORBA::Boolean auto_groups,
2543 SMESH::MED_VERSION theVersion)
2544 throw(SALOME::SALOME_Exception)
2546 ExportToMEDX(file,auto_groups,theVersion,true);
2549 //================================================================================
2551 * \brief Export a mesh to a med file
2553 //================================================================================
2555 void SMESH_Mesh_i::ExportMED (const char* file,
2556 CORBA::Boolean auto_groups)
2557 throw(SALOME::SALOME_Exception)
2559 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
2562 //================================================================================
2564 * \brief Export a mesh to a DAT file
2566 //================================================================================
2568 void SMESH_Mesh_i::ExportDAT (const char *file)
2569 throw(SALOME::SALOME_Exception)
2571 Unexpect aCatch(SALOME_SalomeException);
2573 // Update Python script
2574 // check names of groups
2576 TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )";
2579 PrepareForWriting(file);
2580 _impl->ExportDAT(file);
2583 //================================================================================
2585 * \brief Export a mesh to an UNV file
2587 //================================================================================
2589 void SMESH_Mesh_i::ExportUNV (const char *file)
2590 throw(SALOME::SALOME_Exception)
2592 Unexpect aCatch(SALOME_SalomeException);
2594 // Update Python script
2595 // check names of groups
2597 TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )";
2600 PrepareForWriting(file);
2601 _impl->ExportUNV(file);
2604 //================================================================================
2606 * \brief Export a mesh to an STL file
2608 //================================================================================
2610 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2611 throw(SALOME::SALOME_Exception)
2613 Unexpect aCatch(SALOME_SalomeException);
2615 // Update Python script
2616 // check names of groups
2618 TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )";
2621 PrepareForWriting(file);
2622 _impl->ExportSTL(file, isascii);
2625 //=============================================================================
2627 * \brief Class providing SMESHDS_Mesh API to SMESH_IDSource.
2628 * It is used to export a part of mesh as a whole mesh.
2630 class SMESH_MeshPartDS : public SMESHDS_Mesh
2633 SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart);
2635 virtual SMDS_NodeIteratorPtr nodesIterator (bool idInceasingOrder=false) const;
2636 virtual SMDS_0DElementIteratorPtr elements0dIterator(bool idInceasingOrder=false) const;
2637 virtual SMDS_EdgeIteratorPtr edgesIterator (bool idInceasingOrder=false) const;
2638 virtual SMDS_FaceIteratorPtr facesIterator (bool idInceasingOrder=false) const;
2639 virtual SMDS_VolumeIteratorPtr volumesIterator (bool idInceasingOrder=false) const;
2641 virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type=SMDSAbs_All) const;
2644 TIDSortedElemSet _elements[ SMDSAbs_NbElementTypes ];
2645 SMESHDS_Mesh* _meshDS;
2647 * \brief Class used to access to protected data of SMDS_MeshInfo
2649 struct TMeshInfo : public SMDS_MeshInfo
2651 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
2655 //================================================================================
2657 * \brief Export a part of mesh to a med file
2659 //================================================================================
2661 void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart,
2663 CORBA::Boolean auto_groups,
2664 ::SMESH::MED_VERSION version,
2665 ::CORBA::Boolean overwrite)
2666 throw (SALOME::SALOME_Exception)
2668 Unexpect aCatch(SALOME_SalomeException);
2670 PrepareForWriting(file, overwrite);
2672 string aMeshName = "Mesh";
2673 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2674 if ( !aStudy->_is_nil() ) {
2675 SALOMEDS::SObject_var SO = _gen_i->ObjectToSObject( aStudy, meshPart );
2676 if ( !SO->_is_nil() ) {
2677 CORBA::String_var name = SO->GetName();
2681 SMESH_MeshPartDS partDS( meshPart );
2682 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, &partDS );
2684 TPythonDump() << _this() << ".ExportPartToMED( " << meshPart << ", r'" << file << "', "
2685 << auto_groups << ", " << version << ", " << overwrite << " )";
2688 //================================================================================
2690 * \brief Export a part of mesh to a DAT file
2692 //================================================================================
2694 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
2696 throw (SALOME::SALOME_Exception)
2698 Unexpect aCatch(SALOME_SalomeException);
2700 PrepareForWriting(file);
2702 SMESH_MeshPartDS partDS( meshPart );
2703 _impl->ExportDAT(file,&partDS);
2705 TPythonDump() << _this() << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
2707 //================================================================================
2709 * \brief Export a part of mesh to an UNV file
2711 //================================================================================
2713 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
2715 throw (SALOME::SALOME_Exception)
2717 Unexpect aCatch(SALOME_SalomeException);
2719 PrepareForWriting(file);
2721 SMESH_MeshPartDS partDS( meshPart );
2722 _impl->ExportUNV(file, &partDS);
2724 TPythonDump() << _this() << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
2726 //================================================================================
2728 * \brief Export a part of mesh to an STL file
2730 //================================================================================
2732 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
2734 ::CORBA::Boolean isascii)
2735 throw (SALOME::SALOME_Exception)
2737 Unexpect aCatch(SALOME_SalomeException);
2739 PrepareForWriting(file);
2741 SMESH_MeshPartDS partDS( meshPart );
2742 _impl->ExportSTL(file, isascii, &partDS);
2744 TPythonDump() << _this() << ".ExportPartToSTL( "
2745 << meshPart<< ", r'" << file << "', " << isascii << ")";
2748 //=============================================================================
2752 //=============================================================================
2754 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
2756 Unexpect aCatch(SALOME_SalomeException);
2757 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
2758 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
2759 return aMesh._retn();
2762 //=============================================================================
2766 //=============================================================================
2767 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
2769 Unexpect aCatch(SALOME_SalomeException);
2770 return _impl->NbNodes();
2773 //=============================================================================
2777 //=============================================================================
2778 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
2780 Unexpect aCatch(SALOME_SalomeException);
2781 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes();
2784 //=============================================================================
2788 //=============================================================================
2789 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
2791 Unexpect aCatch(SALOME_SalomeException);
2792 return _impl->Nb0DElements();
2795 //=============================================================================
2799 //=============================================================================
2800 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
2802 Unexpect aCatch(SALOME_SalomeException);
2803 return _impl->NbEdges();
2806 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
2807 throw(SALOME::SALOME_Exception)
2809 Unexpect aCatch(SALOME_SalomeException);
2810 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
2813 //=============================================================================
2817 //=============================================================================
2818 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
2820 Unexpect aCatch(SALOME_SalomeException);
2821 return _impl->NbFaces();
2824 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
2826 Unexpect aCatch(SALOME_SalomeException);
2827 return _impl->NbTriangles();
2830 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
2832 Unexpect aCatch(SALOME_SalomeException);
2833 return _impl->NbQuadrangles();
2836 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
2838 Unexpect aCatch(SALOME_SalomeException);
2839 return _impl->NbPolygons();
2842 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
2843 throw(SALOME::SALOME_Exception)
2845 Unexpect aCatch(SALOME_SalomeException);
2846 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
2849 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
2850 throw(SALOME::SALOME_Exception)
2852 Unexpect aCatch(SALOME_SalomeException);
2853 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
2856 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
2857 throw(SALOME::SALOME_Exception)
2859 Unexpect aCatch(SALOME_SalomeException);
2860 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
2863 //=============================================================================
2867 //=============================================================================
2868 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
2870 Unexpect aCatch(SALOME_SalomeException);
2871 return _impl->NbVolumes();
2874 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
2876 Unexpect aCatch(SALOME_SalomeException);
2877 return _impl->NbTetras();
2880 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
2882 Unexpect aCatch(SALOME_SalomeException);
2883 return _impl->NbHexas();
2886 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
2888 Unexpect aCatch(SALOME_SalomeException);
2889 return _impl->NbPyramids();
2892 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
2894 Unexpect aCatch(SALOME_SalomeException);
2895 return _impl->NbPrisms();
2898 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
2900 Unexpect aCatch(SALOME_SalomeException);
2901 return _impl->NbPolyhedrons();
2904 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
2905 throw(SALOME::SALOME_Exception)
2907 Unexpect aCatch(SALOME_SalomeException);
2908 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
2911 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
2912 throw(SALOME::SALOME_Exception)
2914 Unexpect aCatch(SALOME_SalomeException);
2915 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
2918 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
2919 throw(SALOME::SALOME_Exception)
2921 Unexpect aCatch(SALOME_SalomeException);
2922 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
2925 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
2926 throw(SALOME::SALOME_Exception)
2928 Unexpect aCatch(SALOME_SalomeException);
2929 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
2932 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
2933 throw(SALOME::SALOME_Exception)
2935 Unexpect aCatch(SALOME_SalomeException);
2936 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
2939 //=============================================================================
2943 //=============================================================================
2944 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
2946 Unexpect aCatch(SALOME_SalomeException);
2947 return _mapSubMesh_i.size();
2950 //=============================================================================
2954 //=============================================================================
2955 char* SMESH_Mesh_i::Dump()
2959 return CORBA::string_dup( os.str().c_str() );
2962 //=============================================================================
2966 //=============================================================================
2967 SMESH::long_array* SMESH_Mesh_i::GetIDs()
2969 // SMESH::long_array_var aResult = new SMESH::long_array();
2970 // SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2971 // int aMinId = aSMESHDS_Mesh->MinElementID();
2972 // int aMaxId = aSMESHDS_Mesh->MaxElementID();
2974 // aResult->length(aMaxId - aMinId + 1);
2976 // for (int i = 0, id = aMinId; id <= aMaxId; id++ )
2977 // aResult[i++] = id;
2979 // return aResult._retn();
2981 return GetElementsId();
2984 //=============================================================================
2988 //=============================================================================
2990 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
2991 throw (SALOME::SALOME_Exception)
2993 Unexpect aCatch(SALOME_SalomeException);
2994 MESSAGE("SMESH_Mesh_i::GetElementsId");
2995 SMESH::long_array_var aResult = new SMESH::long_array();
2996 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2998 if ( aSMESHDS_Mesh == NULL )
2999 return aResult._retn();
3001 long nbElements = NbElements();
3002 aResult->length( nbElements );
3003 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3004 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3005 aResult[i] = anIt->next()->GetID();
3007 return aResult._retn();
3011 //=============================================================================
3015 //=============================================================================
3017 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3018 throw (SALOME::SALOME_Exception)
3020 Unexpect aCatch(SALOME_SalomeException);
3021 MESSAGE("SMESH_subMesh_i::GetElementsByType");
3022 SMESH::long_array_var aResult = new SMESH::long_array();
3023 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3025 if ( aSMESHDS_Mesh == NULL )
3026 return aResult._retn();
3028 long nbElements = NbElements();
3030 // No sense in returning ids of elements along with ids of nodes:
3031 // when theElemType == SMESH::ALL, return node ids only if
3032 // there are no elements
3033 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3034 return GetNodesId();
3036 aResult->length( nbElements );
3040 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3041 while ( i < nbElements && anIt->more() ) {
3042 const SMDS_MeshElement* anElem = anIt->next();
3043 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
3044 aResult[i++] = anElem->GetID();
3047 aResult->length( i );
3049 return aResult._retn();
3052 //=============================================================================
3056 //=============================================================================
3058 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3059 throw (SALOME::SALOME_Exception)
3061 Unexpect aCatch(SALOME_SalomeException);
3062 MESSAGE("SMESH_subMesh_i::GetNodesId");
3063 SMESH::long_array_var aResult = new SMESH::long_array();
3064 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3066 if ( aSMESHDS_Mesh == NULL )
3067 return aResult._retn();
3069 long nbNodes = NbNodes();
3070 aResult->length( nbNodes );
3071 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3072 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3073 aResult[i] = anIt->next()->GetID();
3075 return aResult._retn();
3078 //=============================================================================
3082 //=============================================================================
3084 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3085 throw (SALOME::SALOME_Exception)
3087 return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
3090 //=============================================================================
3094 //=============================================================================
3096 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3097 throw (SALOME::SALOME_Exception)
3099 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3101 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3103 return ( SMESH::EntityType ) e->GetEntityType();
3106 //=============================================================================
3108 * Returns ID of elements for given submesh
3110 //=============================================================================
3111 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3112 throw (SALOME::SALOME_Exception)
3114 SMESH::long_array_var aResult = new SMESH::long_array();
3116 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3117 if(!SM) return aResult._retn();
3119 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3120 if(!SDSM) return aResult._retn();
3122 aResult->length(SDSM->NbElements());
3124 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3126 while ( eIt->more() ) {
3127 aResult[i++] = eIt->next()->GetID();
3130 return aResult._retn();
3134 //=============================================================================
3136 * Returns ID of nodes for given submesh
3137 * If param all==true - returns all nodes, else -
3138 * returns only nodes on shapes.
3140 //=============================================================================
3141 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all)
3142 throw (SALOME::SALOME_Exception)
3144 SMESH::long_array_var aResult = new SMESH::long_array();
3146 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3147 if(!SM) return aResult._retn();
3149 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3150 if(!SDSM) return aResult._retn();
3153 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
3154 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
3155 while ( nIt->more() ) {
3156 const SMDS_MeshNode* elem = nIt->next();
3157 theElems.insert( elem->GetID() );
3160 else { // all nodes of submesh elements
3161 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3162 while ( eIt->more() ) {
3163 const SMDS_MeshElement* anElem = eIt->next();
3164 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
3165 while ( nIt->more() ) {
3166 const SMDS_MeshElement* elem = nIt->next();
3167 theElems.insert( elem->GetID() );
3172 aResult->length(theElems.size());
3173 set<int>::iterator itElem;
3175 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
3176 aResult[i++] = *itElem;
3178 return aResult._retn();
3182 //=============================================================================
3184 * Returns type of elements for given submesh
3186 //=============================================================================
3187 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
3188 throw (SALOME::SALOME_Exception)
3190 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3191 if(!SM) return SMESH::ALL;
3193 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3194 if(!SDSM) return SMESH::ALL;
3196 if(SDSM->NbElements()==0)
3197 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
3199 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3200 const SMDS_MeshElement* anElem = eIt->next();
3201 return ( SMESH::ElementType ) anElem->GetType();
3205 //=============================================================================
3209 //=============================================================================
3211 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
3213 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
3215 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
3220 //=============================================================================
3222 * Get XYZ coordinates of node as list of double
3223 * If there is not node for given ID - returns empty list
3225 //=============================================================================
3227 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
3229 SMESH::double_array_var aResult = new SMESH::double_array();
3230 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3231 if ( aSMESHDS_Mesh == NULL )
3232 return aResult._retn();
3235 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3237 return aResult._retn();
3241 aResult[0] = aNode->X();
3242 aResult[1] = aNode->Y();
3243 aResult[2] = aNode->Z();
3244 return aResult._retn();
3248 //=============================================================================
3250 * For given node returns list of IDs of inverse elements
3251 * If there is not node for given ID - returns empty list
3253 //=============================================================================
3255 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
3257 SMESH::long_array_var aResult = new SMESH::long_array();
3258 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3259 if ( aSMESHDS_Mesh == NULL )
3260 return aResult._retn();
3263 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3265 return aResult._retn();
3267 // find inverse elements
3268 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
3269 TColStd_SequenceOfInteger IDs;
3270 while(eIt->more()) {
3271 const SMDS_MeshElement* elem = eIt->next();
3272 IDs.Append(elem->GetID());
3274 if(IDs.Length()>0) {
3275 aResult->length(IDs.Length());
3277 for(; i<=IDs.Length(); i++) {
3278 aResult[i-1] = IDs.Value(i);
3281 return aResult._retn();
3284 //=============================================================================
3286 * \brief Return position of a node on shape
3288 //=============================================================================
3290 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
3292 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
3293 aNodePosition->shapeID = 0;
3294 aNodePosition->shapeType = GEOM::SHAPE;
3296 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3297 if ( !mesh ) return aNodePosition;
3299 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
3301 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
3303 aNodePosition->shapeID = aNode->getshapeId();
3304 switch ( pos->GetTypeOfPosition() ) {
3306 aNodePosition->shapeType = GEOM::EDGE;
3307 aNodePosition->params.length(1);
3308 aNodePosition->params[0] =
3309 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
3312 aNodePosition->shapeType = GEOM::FACE;
3313 aNodePosition->params.length(2);
3314 aNodePosition->params[0] =
3315 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
3316 aNodePosition->params[1] =
3317 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
3319 case SMDS_TOP_VERTEX:
3320 aNodePosition->shapeType = GEOM::VERTEX;
3322 case SMDS_TOP_3DSPACE:
3323 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3324 aNodePosition->shapeType = GEOM::SOLID;
3325 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3326 aNodePosition->shapeType = GEOM::SHELL;
3332 return aNodePosition;
3335 //=============================================================================
3337 * If given element is node returns IDs of shape from position
3338 * If there is not node for given ID - returns -1
3340 //=============================================================================
3342 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3344 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3345 if ( aSMESHDS_Mesh == NULL )
3349 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3351 return aNode->getshapeId();
3358 //=============================================================================
3360 * For given element returns ID of result shape after
3361 * ::FindShape() from SMESH_MeshEditor
3362 * If there is not element for given ID - returns -1
3364 //=============================================================================
3366 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3368 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3369 if ( aSMESHDS_Mesh == NULL )
3372 // try to find element
3373 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3377 //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
3378 ::SMESH_MeshEditor aMeshEditor(_impl);
3379 int index = aMeshEditor.FindShape( elem );
3387 //=============================================================================
3389 * Returns number of nodes for given element
3390 * If there is not element for given ID - returns -1
3392 //=============================================================================
3394 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3396 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3397 if ( aSMESHDS_Mesh == NULL ) return -1;
3398 // try to find element
3399 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3400 if(!elem) return -1;
3401 return elem->NbNodes();
3405 //=============================================================================
3407 * Returns ID of node by given index for given element
3408 * If there is not element for given ID - returns -1
3409 * If there is not node for given index - returns -2
3411 //=============================================================================
3413 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3415 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3416 if ( aSMESHDS_Mesh == NULL ) return -1;
3417 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3418 if(!elem) return -1;
3419 if( index>=elem->NbNodes() || index<0 ) return -1;
3420 return elem->GetNode(index)->GetID();
3423 //=============================================================================
3425 * Returns IDs of nodes of given element
3427 //=============================================================================
3429 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3431 SMESH::long_array_var aResult = new SMESH::long_array();
3432 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3434 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3436 aResult->length( elem->NbNodes() );
3437 for ( int i = 0; i < elem->NbNodes(); ++i )
3438 aResult[ i ] = elem->GetNode( i )->GetID();
3441 return aResult._retn();
3444 //=============================================================================
3446 * Returns true if given node is medium node
3447 * in given quadratic element
3449 //=============================================================================
3451 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3453 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3454 if ( aSMESHDS_Mesh == NULL ) return false;
3456 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3457 if(!aNode) return false;
3458 // try to find element
3459 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3460 if(!elem) return false;
3462 return elem->IsMediumNode(aNode);
3466 //=============================================================================
3468 * Returns true if given node is medium node
3469 * in one of quadratic elements
3471 //=============================================================================
3473 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3474 SMESH::ElementType theElemType)
3476 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3477 if ( aSMESHDS_Mesh == NULL ) return false;
3480 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3481 if(!aNode) return false;
3483 SMESH_MesherHelper aHelper( *(_impl) );
3485 SMDSAbs_ElementType aType;
3486 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3487 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3488 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3489 else aType = SMDSAbs_All;
3491 return aHelper.IsMedium(aNode,aType);
3495 //=============================================================================
3497 * Returns number of edges for given element
3499 //=============================================================================
3501 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3503 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3504 if ( aSMESHDS_Mesh == NULL ) return -1;
3505 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3506 if(!elem) return -1;
3507 return elem->NbEdges();
3511 //=============================================================================
3513 * Returns number of faces for given element
3515 //=============================================================================
3517 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3519 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3520 if ( aSMESHDS_Mesh == NULL ) return -1;
3521 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3522 if(!elem) return -1;
3523 return elem->NbFaces();
3526 //=======================================================================
3527 //function : GetElemFaceNodes
3528 //purpose : Returns nodes of given face (counted from zero) for given element.
3529 //=======================================================================
3531 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
3532 CORBA::Short faceIndex)
3534 SMESH::long_array_var aResult = new SMESH::long_array();
3535 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3537 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
3539 SMDS_VolumeTool vtool( elem );
3540 if ( faceIndex < vtool.NbFaces() )
3542 aResult->length( vtool.NbFaceNodes( faceIndex ));
3543 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
3544 for ( int i = 0; i < aResult->length(); ++i )
3545 aResult[ i ] = nn[ i ]->GetID();
3549 return aResult._retn();
3552 //=======================================================================
3553 //function : FindElementByNodes
3554 //purpose : Returns an element based on all given nodes.
3555 //=======================================================================
3557 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
3559 CORBA::Long elemID(0);
3560 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
3562 vector< const SMDS_MeshNode * > nn( nodes.length() );
3563 for ( int i = 0; i < nodes.length(); ++i )
3564 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
3567 const SMDS_MeshElement* elem = mesh->FindElement( nn );
3568 if ( !elem && ( _impl->NbEdges( ORDER_QUADRATIC ) ||
3569 _impl->NbFaces( ORDER_QUADRATIC ) ||
3570 _impl->NbVolumes( ORDER_QUADRATIC )))
3571 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
3573 if ( elem ) elemID = CORBA::Long( elem->GetID() );
3578 //=============================================================================
3580 * Returns true if given element is polygon
3582 //=============================================================================
3584 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
3586 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3587 if ( aSMESHDS_Mesh == NULL ) return false;
3588 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3589 if(!elem) return false;
3590 return elem->IsPoly();
3594 //=============================================================================
3596 * Returns true if given element is quadratic
3598 //=============================================================================
3600 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
3602 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3603 if ( aSMESHDS_Mesh == NULL ) return false;
3604 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3605 if(!elem) return false;
3606 return elem->IsQuadratic();
3610 //=============================================================================
3612 * Returns bary center for given element
3614 //=============================================================================
3616 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
3618 SMESH::double_array_var aResult = new SMESH::double_array();
3619 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3620 if ( aSMESHDS_Mesh == NULL )
3621 return aResult._retn();
3623 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3625 return aResult._retn();
3627 if(elem->GetType()==SMDSAbs_Volume) {
3628 SMDS_VolumeTool aTool;
3629 if(aTool.Set(elem)) {
3631 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
3636 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
3638 double x=0., y=0., z=0.;
3639 for(; anIt->more(); ) {
3641 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
3655 return aResult._retn();
3659 //=============================================================================
3661 * Create and publish group servants if any groups were imported or created anyhow
3663 //=============================================================================
3665 void SMESH_Mesh_i::CreateGroupServants()
3667 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3670 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
3671 while ( groupIt->more() )
3673 ::SMESH_Group* group = groupIt->next();
3674 int anId = group->GetGroupDS()->GetID();
3676 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
3677 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3679 addedIDs.insert( anId );
3681 SMESH_GroupBase_i* aGroupImpl;
3683 if ( SMESHDS_GroupOnGeom* groupOnGeom =
3684 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
3686 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3687 shape = groupOnGeom->GetShape();
3690 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3693 // To ensure correct mapping of servant and correct reference counting in GenericObj_i
3694 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
3695 aGroupImpl->Register();
3697 SMESH::SMESH_GroupBase_var groupVar =
3698 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
3699 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
3701 // register CORBA object for persistence
3702 int nextId = _gen_i->RegisterObject( groupVar );
3703 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
3705 // publishing the groups in the study
3706 if ( !aStudy->_is_nil() ) {
3707 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
3708 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
3711 if ( !addedIDs.empty() )
3714 set<int>::iterator id = addedIDs.begin();
3715 for ( ; id != addedIDs.end(); ++id )
3717 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
3718 int i = std::distance( _mapGroups.begin(), it );
3719 TPythonDump() << it->second << " = " << _this() << ".GetGroups()[ "<< i << " ]";
3724 //=============================================================================
3726 * \brief Return groups cantained in _mapGroups by their IDs
3728 //=============================================================================
3730 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
3732 int nbGroups = groupIDs.size();
3733 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
3734 aList->length( nbGroups );
3736 list<int>::const_iterator ids = groupIDs.begin();
3737 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
3739 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
3740 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3741 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
3743 aList->length( nbGroups );
3744 return aList._retn();
3747 //=============================================================================
3749 * \brief Return information about imported file
3751 //=============================================================================
3753 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
3755 SALOME_MED::MedFileInfo_var res( myFileInfo );
3756 if ( !res.operator->() ) {
3757 res = new SALOME_MED::MedFileInfo;
3759 res->fileSize = res->major = res->minor = res->release = -1;
3764 //=============================================================================
3766 * \brief Check and correct names of mesh groups
3768 //=============================================================================
3770 void SMESH_Mesh_i::checkGroupNames()
3772 int nbGrp = NbGroups();
3776 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3777 if ( aStudy->_is_nil() )
3778 return; // nothing to do
3780 SMESH::ListOfGroups* grpList = 0;
3781 // avoid dump of "GetGroups"
3783 // store python dump into a local variable inside local scope
3784 SMESH::TPythonDump pDump; // do not delete this line of code
3785 grpList = GetGroups();
3788 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
3789 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
3792 SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
3793 if ( aGrpSO->_is_nil() )
3795 // correct name of the mesh group if necessary
3796 const char* guiName = aGrpSO->GetName();
3797 if ( strcmp(guiName, aGrp->GetName()) )
3798 aGrp->SetName( guiName );
3802 //=============================================================================
3804 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
3806 //=============================================================================
3807 void SMESH_Mesh_i::SetParameters(const char* theParameters)
3809 SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
3810 CORBA::string_dup(theParameters));
3813 //=============================================================================
3815 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
3817 //=============================================================================
3818 char* SMESH_Mesh_i::GetParameters()
3820 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3821 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
3824 //=============================================================================
3826 * \brief Returns list of notebook variables used for last Mesh operation
3828 //=============================================================================
3829 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
3831 SMESH::string_array_var aResult = new SMESH::string_array();
3832 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3834 char *aParameters = GetParameters();
3835 SALOMEDS::Study_ptr aStudy = gen->GetCurrentStudy();
3836 if(!aStudy->_is_nil()) {
3837 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
3838 if(aSections->length() > 0) {
3839 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
3840 aResult->length(aVars.length());
3841 for(int i = 0;i < aVars.length();i++)
3842 aResult[i] = CORBA::string_dup( aVars[i]);
3846 return aResult._retn();
3849 //=======================================================================
3850 //function : GetTypes
3851 //purpose : Returns types of elements it contains
3852 //=======================================================================
3854 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
3856 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
3860 if (_impl->NbEdges())
3861 types[nbTypes++] = SMESH::EDGE;
3862 if (_impl->NbFaces())
3863 types[nbTypes++] = SMESH::FACE;
3864 if (_impl->NbVolumes())
3865 types[nbTypes++] = SMESH::VOLUME;
3866 if (_impl->Nb0DElements())
3867 types[nbTypes++] = SMESH::ELEM0D;
3868 types->length( nbTypes );
3870 return types._retn();
3873 //=======================================================================
3874 //function : GetMesh
3875 //purpose : Returns self
3876 //=======================================================================
3878 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
3880 return SMESH::SMESH_Mesh::_duplicate( _this() );
3883 //=============================================================================
3885 * \brief Returns statistic of mesh elements
3887 //=============================================================================
3888 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
3890 SMESH::long_array_var aRes = new SMESH::long_array();
3891 aRes->length(SMESH::Entity_Last);
3892 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3894 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3896 return aRes._retn();
3897 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
3898 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3899 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
3900 return aRes._retn();
3903 //=============================================================================
3905 * \brief Collect statistic of mesh elements given by iterator
3907 //=============================================================================
3908 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
3909 SMESH::long_array& theInfo)
3911 if (!theItr) return;
3912 while (theItr->more())
3913 theInfo[ theItr->next()->GetEntityType() ]++;
3916 //=============================================================================
3918 * \brief mapping of mesh dimension into shape type
3920 //=============================================================================
3921 static TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
3923 TopAbs_ShapeEnum aType = TopAbs_SOLID;
3925 case 0: aType = TopAbs_VERTEX; break;
3926 case 1: aType = TopAbs_EDGE; break;
3927 case 2: aType = TopAbs_FACE; break;
3929 default:aType = TopAbs_SOLID; break;
3934 //=============================================================================
3936 * \brief Internal structure used to find concurent submeshes
3938 * It represents a pair < submesh, concurent dimension >, where
3939 * 'concurrent dimension' is dimension of shape where the submesh can concurent
3940 * with another submesh. In other words, it is dimension of a hypothesis assigned
3943 //=============================================================================
3949 int _dim; //!< a dimension the algo can build (concurrent dimension)
3950 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
3951 TopTools_MapOfShape _shapeMap;
3952 SMESH_subMesh* _subMesh;
3953 list<const SMESHDS_Hypothesis*> _hypothesises; //!< algo is first, then its parameters
3956 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
3958 const TopoDS_Shape& theShape)
3960 _subMesh = (SMESH_subMesh*)theSubMesh;
3961 SetShape( theDim, theShape );
3965 void SetShape(const int theDim,
3966 const TopoDS_Shape& theShape)
3969 _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
3970 if (_dim >= _ownDim)
3971 _shapeMap.Add( theShape );
3973 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
3974 for( ; anExp.More(); anExp.Next() )
3975 _shapeMap.Add( anExp.Current() );
3979 //! Check sharing of sub shapes
3980 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
3981 const TopTools_MapOfShape& theToFind,
3982 const TopAbs_ShapeEnum theType)
3984 bool isShared = false;
3985 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
3986 for (; !isShared && anItr.More(); anItr.Next() ) {
3987 const TopoDS_Shape aSubSh = anItr.Key();
3988 // check for case when concurrent dimensions are same
3989 isShared = theToFind.Contains( aSubSh );
3990 // check for subshape with concurrent dimension
3991 TopExp_Explorer anExp( aSubSh, theType );
3992 for ( ; !isShared && anExp.More(); anExp.Next() )
3993 isShared = theToFind.Contains( anExp.Current() );
3998 //! check algorithms
3999 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
4000 const SMESHDS_Hypothesis* theA2)
4002 if ( theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
4003 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
4004 return false; // one of the hypothesis is not algorithm
4005 // check algorithm names (should be equal)
4006 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
4010 //! Check if subshape hypotheses are concurrent
4011 bool IsConcurrent(const SMESH_DimHyp* theOther) const
4013 if ( _subMesh == theOther->_subMesh )
4014 return false; // same subshape - should not be
4016 // if ( <own dim of either of submeshes> == <concurrent dim> &&
4017 // any of the two submeshes is not on COMPOUND shape )
4018 // -> no concurrency
4019 bool meIsCompound = (_subMesh->GetSubMeshDS() && _subMesh->GetSubMeshDS()->IsComplexSubmesh());
4020 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() && theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
4021 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
4024 // bool checkSubShape = ( _dim >= theOther->_dim )
4025 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
4026 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
4027 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
4028 if ( !checkSubShape )
4031 // check algorithms to be same
4032 if (!checkAlgo( _hypothesises.front(), theOther->_hypothesises.front() ))
4033 return true; // different algorithms
4035 // check hypothesises for concurrence (skip first as algorithm)
4037 // pointers should be same, becase it is referenes from mesh hypothesis partition
4038 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypothesises.begin();
4039 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypothesises.end();
4040 for ( hypIt++ /*skip first as algo*/; hypIt != _hypothesises.end(); hypIt++ )
4041 if ( find( theOther->_hypothesises.begin(), otheEndIt, *hypIt ) != otheEndIt )
4043 // the submeshes are concurrent if their algorithms has different parameters
4044 return nbSame != theOther->_hypothesises.size() - 1;
4047 }; // end of SMESH_DimHyp
4049 typedef list<SMESH_DimHyp*> TDimHypList;
4051 static void addDimHypInstance(const int theDim,
4052 const TopoDS_Shape& theShape,
4053 const SMESH_Algo* theAlgo,
4054 const SMESH_subMesh* theSubMesh,
4055 const list <const SMESHDS_Hypothesis*>& theHypList,
4056 TDimHypList* theDimHypListArr )
4058 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
4059 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
4060 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
4061 listOfdimHyp.push_back( dimHyp );
4064 SMESH_DimHyp* dimHyp = listOfdimHyp.back();
4065 dimHyp->_hypothesises.push_front(theAlgo);
4066 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = theHypList.begin();
4067 for( ; hypIt != theHypList.end(); hypIt++ )
4068 dimHyp->_hypothesises.push_back( *hypIt );
4071 static void findConcurrents(const SMESH_DimHyp* theDimHyp,
4072 const TDimHypList& theListOfDimHyp,
4073 TListOfInt& theListOfConcurr )
4075 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
4076 for ( ; rIt != theListOfDimHyp.rend(); rIt++ ) {
4077 const SMESH_DimHyp* curDimHyp = *rIt;
4078 if ( curDimHyp == theDimHyp )
4079 break; // meet own dimHyp pointer in same dimension
4080 else if ( theDimHyp->IsConcurrent( curDimHyp ) )
4081 if ( find( theListOfConcurr.begin(),
4082 theListOfConcurr.end(),
4083 curDimHyp->_subMesh->GetId() ) == theListOfConcurr.end() )
4084 theListOfConcurr.push_back( curDimHyp->_subMesh->GetId() );
4088 static void unionLists(TListOfInt& theListOfId,
4089 TListOfListOfInt& theListOfListOfId,
4092 TListOfListOfInt::iterator it = theListOfListOfId.begin();
4093 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
4095 continue; //skip already treated lists
4096 // check if other list has any same submesh object
4097 TListOfInt& otherListOfId = *it;
4098 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
4099 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
4102 // union two lists (from source into target)
4103 TListOfInt::iterator it2 = otherListOfId.begin();
4104 for ( ; it2 != otherListOfId.end(); it2++ ) {
4105 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
4106 theListOfId.push_back(*it2);
4108 // clear source list
4109 otherListOfId.clear();
4113 //! free memory allocated for dimension-hypothesis objects
4114 static void removeDimHyps( TDimHypList* theArrOfList )
4116 for (int i = 0; i < 4; i++ ) {
4117 TDimHypList& listOfdimHyp = theArrOfList[i];
4118 TDimHypList::const_iterator it = listOfdimHyp.begin();
4119 for ( ; it != listOfdimHyp.end(); it++ )
4124 //=============================================================================
4126 * \brief Return submesh objects list in meshing order
4128 //=============================================================================
4130 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
4132 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
4134 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4136 return aResult._retn();
4138 ::SMESH_Mesh& mesh = GetImpl();
4139 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
4140 if ( !anOrder.size() ) {
4142 // collect submeshes detecting concurrent algorithms and hypothesises
4143 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
4145 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
4146 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
4147 ::SMESH_subMesh* sm = (*i_sm).second;
4149 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
4151 // list of assigned hypothesises
4152 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
4153 // Find out dimensions where the submesh can be concurrent.
4154 // We define the dimensions by algo of each of hypotheses in hypList
4155 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
4156 for( ; hypIt != hypList.end(); hypIt++ ) {
4157 SMESH_Algo* anAlgo = 0;
4158 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
4159 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
4160 // hyp it-self is algo
4161 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
4163 // try to find algorithm with help of subshapes
4164 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
4165 for ( ; !anAlgo && anExp.More(); anExp.Next() )
4166 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
4169 continue; // no assigned algorithm to current submesh
4171 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
4172 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDescretBoundary())
4174 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
4175 for ( int j = anAlgo->NeedDescretBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
4176 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
4178 } // end iterations on submesh
4180 // iterate on created dimension-hypotheses and check for concurrents
4181 for ( int i = 0; i < 4; i++ ) {
4182 const list<SMESH_DimHyp*>& listOfDimHyp = dimHypListArr[i];
4183 // check for concurrents in own and other dimensions (step-by-step)
4184 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
4185 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
4186 const SMESH_DimHyp* dimHyp = *dhIt;
4187 TListOfInt listOfConcurr;
4188 // looking for concurrents and collect into own list
4189 for ( int j = i; j < 4; j++ )
4190 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr );
4191 // check if any concurrents found
4192 if ( listOfConcurr.size() > 0 ) {
4193 // add own submesh to list of concurrent
4194 listOfConcurr.push_front( dimHyp->_subMesh->GetId() );
4195 anOrder.push_back( listOfConcurr );
4200 removeDimHyps(dimHypListArr);
4202 // now, minimise the number of concurrent groups
4203 // Here we assume that lists of submhes can has same submesh
4204 // in case of multi-dimension algorithms, as result
4205 // list with common submesh have to be union into one list
4207 TListOfListOfInt::iterator listIt = anOrder.begin();
4208 for(; listIt != anOrder.end(); listIt++, listIndx++ )
4209 unionLists( *listIt, anOrder, listIndx + 1 );
4211 // convert submesh ids into interface instances
4212 // and dump command into python
4213 convertMeshOrder( anOrder, aResult, true );
4215 return aResult._retn();
4218 //=============================================================================
4220 * \brief find common submeshes with given submesh
4221 * \param theSubMeshList list of already collected submesh to check
4222 * \param theSubMesh given submesh to intersect with other
4223 * \param theCommonSubMeshes collected common submeshes
4225 //=============================================================================
4227 static void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
4228 const SMESH_subMesh* theSubMesh,
4229 set<const SMESH_subMesh*>& theCommon )
4233 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
4234 for ( ; it != theSubMeshList.end(); it++ )
4235 theSubMesh->FindIntersection( *it, theCommon );
4236 theSubMeshList.push_back( theSubMesh );
4237 //theCommon.insert( theSubMesh );
4240 //=============================================================================
4242 * \brief Set submesh object order
4243 * \param theSubMeshArray submesh array order
4245 //=============================================================================
4247 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
4250 ::SMESH_Mesh& mesh = GetImpl();
4252 TPythonDump aPythonDump; // prevent dump of called methods
4253 aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
4255 TListOfListOfInt subMeshOrder;
4256 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
4258 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
4259 TListOfInt subMeshIds;
4260 aPythonDump << "[ ";
4261 // Collect subMeshes which should be clear
4262 // do it list-by-list, because modification of submesh order
4263 // take effect between concurrent submeshes only
4264 set<const SMESH_subMesh*> subMeshToClear;
4265 list<const SMESH_subMesh*> subMeshList;
4266 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
4268 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
4270 aPythonDump << ", ";
4271 aPythonDump << subMesh;
4272 subMeshIds.push_back( subMesh->GetId() );
4273 // detect common parts of submeshes
4274 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
4275 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
4277 aPythonDump << " ]";
4278 subMeshOrder.push_back( subMeshIds );
4280 // clear collected submeshes
4281 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
4282 for ( ; clrIt != subMeshToClear.end(); clrIt++ ) {
4283 SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt;
4285 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
4286 // ClearSubMesh( *clrIt );
4289 aPythonDump << " ])";
4291 mesh.SetMeshOrder( subMeshOrder );
4297 //=============================================================================
4299 * \brief Convert submesh ids into submesh interfaces
4301 //=============================================================================
4303 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
4304 SMESH::submesh_array_array& theResOrder,
4305 const bool theIsDump)
4307 int nbSet = theIdsOrder.size();
4308 TPythonDump aPythonDump; // prevent dump of called methods
4310 aPythonDump << "[ ";
4311 theResOrder.length(nbSet);
4312 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
4314 for( ; it != theIdsOrder.end(); it++ ) {
4315 // translate submesh identificators into submesh objects
4316 // takeing into account real number of concurrent lists
4317 const TListOfInt& aSubOrder = (*it);
4318 if (!aSubOrder.size())
4321 aPythonDump << "[ ";
4322 // convert shape indeces into interfaces
4323 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
4324 aResSubSet->length(aSubOrder.size());
4325 TListOfInt::const_iterator subIt = aSubOrder.begin();
4326 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
4327 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
4329 SMESH::SMESH_subMesh_var subMesh =
4330 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
4333 aPythonDump << ", ";
4334 aPythonDump << subMesh;
4336 aResSubSet[ j++ ] = subMesh;
4339 aPythonDump << " ]";
4340 theResOrder[ listIndx++ ] = aResSubSet;
4342 // correct number of lists
4343 theResOrder.length( listIndx );
4346 // finilise python dump
4347 aPythonDump << " ]";
4348 aPythonDump << " = " << _this() << ".GetMeshOrder()";
4352 //================================================================================
4354 // Implementation of SMESH_MeshPartDS
4356 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
4357 SMESHDS_Mesh( /*theMeshID=*/-1, /*theIsEmbeddedMode=*/true)
4359 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
4360 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4362 _meshDS = mesh_i->GetImpl().GetMeshDS();
4364 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
4366 // <meshPart> is the whole mesh
4367 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
4372 SMESH::long_array_var anIDs = meshPart->GetIDs();
4373 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
4374 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
4376 for (int i=0; i < anIDs->length(); i++)
4377 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
4378 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4383 for (int i=0; i < anIDs->length(); i++)
4384 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
4385 if ( _elements[ e->GetType() ].insert( e ).second )
4388 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
4389 while ( nIt->more() )
4391 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
4392 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4399 _meshDS = 0; // to enforce iteration on _elements and _nodes
4402 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
4404 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
4405 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
4406 ( new TIter( _elements[type].begin(), _elements[type].end() ));
4408 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
4409 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
4411 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
4412 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
4413 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
4415 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
4416 _GET_ITER_DEFINE( SMDS_0DElementIteratorPtr, elements0dIterator, SMDS_Mesh0DElement, SMDSAbs_0DElement)
4417 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
4418 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
4419 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
4420 #undef _GET_ITER_DEFINE
4422 // END Implementation of SMESH_MeshPartDS
4424 //================================================================================