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 int anId = aGroupToRem->GetLocalID();
1953 if ( !_impl->ConvertToStandalone( anId ) )
1954 return aGroup._retn();
1955 removeGeomGroupData( theGroup );
1957 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
1959 // remove old instance of group from own map
1960 _mapGroups.erase( anId );
1962 SALOMEDS::StudyBuilder_var builder;
1963 SALOMEDS::SObject_var aGroupSO;
1964 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1965 if ( !aStudy->_is_nil() ) {
1966 builder = aStudy->NewBuilder();
1967 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1968 if ( !aGroupSO->_is_nil() ) {
1970 // remove reference to geometry
1971 SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO);
1972 for ( ; chItr->More(); chItr->Next() )
1973 // Remove group's child SObject
1974 builder->RemoveObject( chItr->Value() );
1976 // Update Python script
1977 TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
1978 << aGroupSO << " )";
1982 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1983 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
1984 aGroupImpl->Register();
1985 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1987 // remember new group in own map
1988 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
1989 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
1991 // register CORBA object for persistence
1992 /*int nextId =*/ _gen_i->RegisterObject( aGroup );
1994 builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) );
1996 return aGroup._retn();
1999 //=============================================================================
2003 //=============================================================================
2005 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2007 if(MYDEBUG) MESSAGE( "createSubMesh" );
2008 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2010 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2011 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
2012 SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2013 SMESH::SMESH_subMesh_var subMesh
2014 = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
2016 _mapSubMesh[subMeshId] = mySubMesh;
2017 _mapSubMesh_i[subMeshId] = subMeshServant;
2018 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
2020 // register CORBA object for persistence
2021 int nextId = _gen_i->RegisterObject( subMesh );
2022 if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
2024 // to track changes of GEOM groups
2025 addGeomGroupData( theSubShapeObject, subMesh );
2027 return subMesh._retn();
2030 //=======================================================================
2031 //function : getSubMesh
2033 //=======================================================================
2035 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2037 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2038 if ( it == _mapSubMeshIor.end() )
2039 return SMESH::SMESH_subMesh::_nil();
2041 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2045 //=============================================================================
2049 //=============================================================================
2051 void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2052 GEOM::GEOM_Object_ptr theSubShapeObject )
2054 MESSAGE("SMESH_Mesh_i::removeSubMesh()");
2055 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2058 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2060 CORBA::Long shapeId = theSubMesh->GetId();
2061 if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
2063 TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
2066 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2067 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2068 for ( ; hyp != hyps.end(); ++hyp )
2069 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2076 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2077 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2078 removeHypothesis( theSubShapeObject, aHypList[i] );
2081 catch( const SALOME::SALOME_Exception& ) {
2082 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2084 removeGeomGroupData( theSubShapeObject );
2086 int subMeshId = theSubMesh->GetId();
2088 _mapSubMesh.erase(subMeshId);
2089 _mapSubMesh_i.erase(subMeshId);
2090 _mapSubMeshIor.erase(subMeshId);
2091 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeSubMesh() completed");
2094 //=============================================================================
2098 //=============================================================================
2100 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2101 const char* theName,
2102 const TopoDS_Shape& theShape,
2103 const SMESH_PredicatePtr& thePredicate )
2105 std::string newName;
2106 if ( !theName || strlen( theName ) == 0 )
2108 std::set< std::string > presentNames;
2109 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2110 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2111 presentNames.insert( i_gr->second->GetName() );
2113 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2114 } while ( !presentNames.insert( newName ).second );
2115 theName = newName.c_str();
2118 SMESH::SMESH_GroupBase_var aGroup;
2119 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2121 SMESH_GroupBase_i* aGroupImpl;
2122 if ( !theShape.IsNull() )
2123 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2124 else if ( thePredicate )
2125 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2127 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2129 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2130 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2131 aGroupImpl->Register();
2132 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2134 aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2135 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2137 // register CORBA object for persistence
2138 int nextId = _gen_i->RegisterObject( aGroup );
2139 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2141 // to track changes of GEOM groups
2142 if ( !theShape.IsNull() ) {
2143 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2144 addGeomGroupData( geom, aGroup );
2147 return aGroup._retn();
2150 //=============================================================================
2152 * SMESH_Mesh_i::removeGroup
2154 * Should be called by ~SMESH_Group_i()
2156 //=============================================================================
2158 void SMESH_Mesh_i::removeGroup( const int theId )
2160 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2161 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2162 SMESH::SMESH_GroupBase_ptr group = _mapGroups[theId];
2163 _mapGroups.erase( theId );
2164 removeGeomGroupData( group );
2165 if (! _impl->RemoveGroup( theId ))
2167 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2168 RemoveGroup( group );
2173 //=============================================================================
2177 //=============================================================================
2179 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2180 throw(SALOME::SALOME_Exception)
2182 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetLog");
2184 SMESH::log_array_var aLog;
2186 list < SMESHDS_Command * >logDS = _impl->GetLog();
2187 aLog = new SMESH::log_array;
2189 int lg = logDS.size();
2192 list < SMESHDS_Command * >::iterator its = logDS.begin();
2193 while(its != logDS.end()){
2194 SMESHDS_Command *com = *its;
2195 int comType = com->GetType();
2197 int lgcom = com->GetNumber();
2199 const list < int >&intList = com->GetIndexes();
2200 int inum = intList.size();
2202 list < int >::const_iterator ii = intList.begin();
2203 const list < double >&coordList = com->GetCoords();
2204 int rnum = coordList.size();
2206 list < double >::const_iterator ir = coordList.begin();
2207 aLog[indexLog].commandType = comType;
2208 aLog[indexLog].number = lgcom;
2209 aLog[indexLog].coords.length(rnum);
2210 aLog[indexLog].indexes.length(inum);
2211 for(int i = 0; i < rnum; i++){
2212 aLog[indexLog].coords[i] = *ir;
2213 //MESSAGE(" "<<i<<" "<<ir.Value());
2216 for(int i = 0; i < inum; i++){
2217 aLog[indexLog].indexes[i] = *ii;
2218 //MESSAGE(" "<<i<<" "<<ii.Value());
2227 catch(SALOME_Exception & S_ex){
2228 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
2230 return aLog._retn();
2234 //=============================================================================
2238 //=============================================================================
2240 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2242 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
2246 //=============================================================================
2250 //=============================================================================
2252 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2254 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
2258 //=============================================================================
2262 //=============================================================================
2264 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2269 //=============================================================================
2272 //!< implementation of struct used to call SMESH_Mesh_i::removeGroup() from
2273 // SMESH_Mesh::RemoveGroup() (issue 0020918)
2274 struct TRmGroupCallUp_i : public SMESH_Mesh::TRmGroupCallUp
2276 SMESH_Mesh_i* _mesh;
2277 TRmGroupCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2278 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2282 //=============================================================================
2286 //=============================================================================
2288 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2290 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2293 _impl->SetRemoveGroupCallUp( new TRmGroupCallUp_i(this));
2296 //=============================================================================
2300 //=============================================================================
2302 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2304 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2308 //=============================================================================
2310 * Return mesh editor
2312 //=============================================================================
2314 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2316 // Create MeshEditor
2317 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
2318 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2320 // Update Python script
2321 TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
2323 return aMesh._retn();
2326 //=============================================================================
2328 * Return mesh edition previewer
2330 //=============================================================================
2332 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2334 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
2335 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2336 return aMesh._retn();
2339 //================================================================================
2341 * \brief Return true if the mesh has been edited since a last total re-compute
2342 * and those modifications may prevent successful partial re-compute
2344 //================================================================================
2346 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2348 Unexpect aCatch(SALOME_SalomeException);
2349 return _impl->HasModificationsToDiscard();
2352 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2354 const int MAX_ATTEMPTS = 100;
2356 double tolerance = 0.5;
2357 SALOMEDS::Color col;
2361 // generate random color
2362 double red = (double)rand() / RAND_MAX;
2363 double green = (double)rand() / RAND_MAX;
2364 double blue = (double)rand() / RAND_MAX;
2365 // check existence in the list of the existing colors
2366 bool matched = false;
2367 std::list<SALOMEDS::Color>::const_iterator it;
2368 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2369 SALOMEDS::Color color = *it;
2370 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2371 matched = tol < tolerance;
2373 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2374 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2382 //=============================================================================
2386 //=============================================================================
2387 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2389 Unexpect aCatch(SALOME_SalomeException);
2390 _impl->SetAutoColor(theAutoColor);
2392 TPythonDump pyDump; // not to dump group->SetColor() from below code
2393 pyDump<<_this()<<".SetAutoColor( "<<theAutoColor<<" )";
2395 std::list<SALOMEDS::Color> aReservedColors;
2396 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2397 for ( ; it != _mapGroups.end(); it++ ) {
2398 if ( CORBA::is_nil( it->second )) continue;
2399 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2400 it->second->SetColor( aColor );
2401 aReservedColors.push_back( aColor );
2405 //=============================================================================
2409 //=============================================================================
2410 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2412 Unexpect aCatch(SALOME_SalomeException);
2413 return _impl->GetAutoColor();
2417 //=============================================================================
2419 * Export in different formats
2421 //=============================================================================
2423 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2425 return _impl->HasDuplicatedGroupNamesMED();
2428 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2430 TCollection_AsciiString aFullName ((char*)file);
2431 OSD_Path aPath (aFullName);
2432 OSD_File aFile (aPath);
2433 if (aFile.Exists()) {
2434 // existing filesystem node
2435 if (aFile.KindOfFile() == OSD_FILE) {
2436 if (aFile.IsWriteable()) {
2441 if (aFile.Failed()) {
2442 TCollection_AsciiString msg ("File ");
2443 msg += aFullName + " cannot be replaced.";
2444 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2447 TCollection_AsciiString msg ("File ");
2448 msg += aFullName + " cannot be overwritten.";
2449 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2452 TCollection_AsciiString msg ("Location ");
2453 msg += aFullName + " is not a file.";
2454 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2457 // nonexisting file; check if it can be created
2459 aFile.Build(OSD_WriteOnly, OSD_Protection());
2460 if (aFile.Failed()) {
2461 TCollection_AsciiString msg ("You cannot create the file ");
2462 msg += aFullName + ". Check the directory existance and access rights.";
2463 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2471 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2472 CORBA::Boolean auto_groups,
2473 SMESH::MED_VERSION theVersion,
2474 CORBA::Boolean overwrite)
2475 throw(SALOME::SALOME_Exception)
2477 Unexpect aCatch(SALOME_SalomeException);
2480 PrepareForWriting(file, overwrite);
2481 string aMeshName = "Mesh";
2482 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2483 if ( !aStudy->_is_nil() ) {
2484 SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2485 if ( !aMeshSO->_is_nil() ) {
2486 CORBA::String_var name = aMeshSO->GetName();
2488 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2489 if ( !aStudy->GetProperties()->IsLocked() )
2491 SALOMEDS::GenericAttribute_var anAttr;
2492 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2493 SALOMEDS::AttributeExternalFileDef_var aFileName;
2494 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2495 aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
2496 ASSERT(!aFileName->_is_nil());
2497 aFileName->SetValue(file);
2498 SALOMEDS::AttributeFileType_var aFileType;
2499 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2500 aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
2501 ASSERT(!aFileType->_is_nil());
2502 aFileType->SetValue("FICHIERMED");
2506 // Update Python script
2507 // set name of mesh before export
2508 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName.c_str() << "')";
2510 // check names of groups
2513 TPythonDump() << _this() << ".ExportToMEDX( r'"
2514 << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )";
2516 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion );
2519 //================================================================================
2521 * \brief Export a mesh to a med file
2523 //================================================================================
2525 void SMESH_Mesh_i::ExportToMED (const char* file,
2526 CORBA::Boolean auto_groups,
2527 SMESH::MED_VERSION theVersion)
2528 throw(SALOME::SALOME_Exception)
2530 ExportToMEDX(file,auto_groups,theVersion,true);
2533 //================================================================================
2535 * \brief Export a mesh to a med file
2537 //================================================================================
2539 void SMESH_Mesh_i::ExportMED (const char* file,
2540 CORBA::Boolean auto_groups)
2541 throw(SALOME::SALOME_Exception)
2543 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
2546 //================================================================================
2548 * \brief Export a mesh to a DAT file
2550 //================================================================================
2552 void SMESH_Mesh_i::ExportDAT (const char *file)
2553 throw(SALOME::SALOME_Exception)
2555 Unexpect aCatch(SALOME_SalomeException);
2557 // Update Python script
2558 // check names of groups
2560 TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )";
2563 PrepareForWriting(file);
2564 _impl->ExportDAT(file);
2567 //================================================================================
2569 * \brief Export a mesh to an UNV file
2571 //================================================================================
2573 void SMESH_Mesh_i::ExportUNV (const char *file)
2574 throw(SALOME::SALOME_Exception)
2576 Unexpect aCatch(SALOME_SalomeException);
2578 // Update Python script
2579 // check names of groups
2581 TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )";
2584 PrepareForWriting(file);
2585 _impl->ExportUNV(file);
2588 //================================================================================
2590 * \brief Export a mesh to an STL file
2592 //================================================================================
2594 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2595 throw(SALOME::SALOME_Exception)
2597 Unexpect aCatch(SALOME_SalomeException);
2599 // Update Python script
2600 // check names of groups
2602 TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )";
2605 PrepareForWriting(file);
2606 _impl->ExportSTL(file, isascii);
2609 //=============================================================================
2611 * \brief Class providing SMESHDS_Mesh API to SMESH_IDSource.
2612 * It is used to export a part of mesh as a whole mesh.
2614 class SMESH_MeshPartDS : public SMESHDS_Mesh
2617 SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart);
2619 virtual SMDS_NodeIteratorPtr nodesIterator (bool idInceasingOrder=false) const;
2620 virtual SMDS_0DElementIteratorPtr elements0dIterator(bool idInceasingOrder=false) const;
2621 virtual SMDS_EdgeIteratorPtr edgesIterator (bool idInceasingOrder=false) const;
2622 virtual SMDS_FaceIteratorPtr facesIterator (bool idInceasingOrder=false) const;
2623 virtual SMDS_VolumeIteratorPtr volumesIterator (bool idInceasingOrder=false) const;
2625 virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type=SMDSAbs_All) const;
2628 TIDSortedElemSet _elements[ SMDSAbs_NbElementTypes ];
2629 SMESHDS_Mesh* _meshDS;
2631 * \brief Class used to access to protected data of SMDS_MeshInfo
2633 struct TMeshInfo : public SMDS_MeshInfo
2635 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
2639 //================================================================================
2641 * \brief Export a part of mesh to a med file
2643 //================================================================================
2645 void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart,
2647 CORBA::Boolean auto_groups,
2648 ::SMESH::MED_VERSION version,
2649 ::CORBA::Boolean overwrite)
2650 throw (SALOME::SALOME_Exception)
2652 Unexpect aCatch(SALOME_SalomeException);
2654 PrepareForWriting(file, overwrite);
2656 string aMeshName = "Mesh";
2657 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2658 if ( !aStudy->_is_nil() ) {
2659 SALOMEDS::SObject_var SO = _gen_i->ObjectToSObject( aStudy, meshPart );
2660 if ( !SO->_is_nil() ) {
2661 CORBA::String_var name = SO->GetName();
2665 SMESH_MeshPartDS partDS( meshPart );
2666 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, &partDS );
2668 TPythonDump() << _this() << ".ExportPartToMED( " << meshPart << ", r'" << file << "', "
2669 << auto_groups << ", " << version << ", " << overwrite << " )";
2672 //================================================================================
2674 * \brief Export a part of mesh to a DAT file
2676 //================================================================================
2678 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
2680 throw (SALOME::SALOME_Exception)
2682 Unexpect aCatch(SALOME_SalomeException);
2684 PrepareForWriting(file);
2686 SMESH_MeshPartDS partDS( meshPart );
2687 _impl->ExportDAT(file,&partDS);
2689 TPythonDump() << _this() << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
2691 //================================================================================
2693 * \brief Export a part of mesh to an UNV file
2695 //================================================================================
2697 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
2699 throw (SALOME::SALOME_Exception)
2701 Unexpect aCatch(SALOME_SalomeException);
2703 PrepareForWriting(file);
2705 SMESH_MeshPartDS partDS( meshPart );
2706 _impl->ExportUNV(file, &partDS);
2708 TPythonDump() << _this() << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
2710 //================================================================================
2712 * \brief Export a part of mesh to an STL file
2714 //================================================================================
2716 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
2718 ::CORBA::Boolean isascii)
2719 throw (SALOME::SALOME_Exception)
2721 Unexpect aCatch(SALOME_SalomeException);
2723 PrepareForWriting(file);
2725 SMESH_MeshPartDS partDS( meshPart );
2726 _impl->ExportSTL(file, isascii, &partDS);
2728 TPythonDump() << _this() << ".ExportPartToSTL( "
2729 << meshPart<< ", r'" << file << "', " << isascii << ")";
2732 //=============================================================================
2736 //=============================================================================
2738 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
2740 Unexpect aCatch(SALOME_SalomeException);
2741 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
2742 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
2743 return aMesh._retn();
2746 //=============================================================================
2750 //=============================================================================
2751 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
2753 Unexpect aCatch(SALOME_SalomeException);
2754 return _impl->NbNodes();
2757 //=============================================================================
2761 //=============================================================================
2762 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
2764 Unexpect aCatch(SALOME_SalomeException);
2765 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes();
2768 //=============================================================================
2772 //=============================================================================
2773 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
2775 Unexpect aCatch(SALOME_SalomeException);
2776 return _impl->Nb0DElements();
2779 //=============================================================================
2783 //=============================================================================
2784 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
2786 Unexpect aCatch(SALOME_SalomeException);
2787 return _impl->NbEdges();
2790 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
2791 throw(SALOME::SALOME_Exception)
2793 Unexpect aCatch(SALOME_SalomeException);
2794 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
2797 //=============================================================================
2801 //=============================================================================
2802 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
2804 Unexpect aCatch(SALOME_SalomeException);
2805 return _impl->NbFaces();
2808 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
2810 Unexpect aCatch(SALOME_SalomeException);
2811 return _impl->NbTriangles();
2814 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
2816 Unexpect aCatch(SALOME_SalomeException);
2817 return _impl->NbQuadrangles();
2820 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
2822 Unexpect aCatch(SALOME_SalomeException);
2823 return _impl->NbPolygons();
2826 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
2827 throw(SALOME::SALOME_Exception)
2829 Unexpect aCatch(SALOME_SalomeException);
2830 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
2833 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
2834 throw(SALOME::SALOME_Exception)
2836 Unexpect aCatch(SALOME_SalomeException);
2837 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
2840 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
2841 throw(SALOME::SALOME_Exception)
2843 Unexpect aCatch(SALOME_SalomeException);
2844 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
2847 //=============================================================================
2851 //=============================================================================
2852 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
2854 Unexpect aCatch(SALOME_SalomeException);
2855 return _impl->NbVolumes();
2858 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
2860 Unexpect aCatch(SALOME_SalomeException);
2861 return _impl->NbTetras();
2864 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
2866 Unexpect aCatch(SALOME_SalomeException);
2867 return _impl->NbHexas();
2870 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
2872 Unexpect aCatch(SALOME_SalomeException);
2873 return _impl->NbPyramids();
2876 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
2878 Unexpect aCatch(SALOME_SalomeException);
2879 return _impl->NbPrisms();
2882 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
2884 Unexpect aCatch(SALOME_SalomeException);
2885 return _impl->NbPolyhedrons();
2888 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
2889 throw(SALOME::SALOME_Exception)
2891 Unexpect aCatch(SALOME_SalomeException);
2892 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
2895 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
2896 throw(SALOME::SALOME_Exception)
2898 Unexpect aCatch(SALOME_SalomeException);
2899 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
2902 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
2903 throw(SALOME::SALOME_Exception)
2905 Unexpect aCatch(SALOME_SalomeException);
2906 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
2909 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
2910 throw(SALOME::SALOME_Exception)
2912 Unexpect aCatch(SALOME_SalomeException);
2913 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
2916 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
2917 throw(SALOME::SALOME_Exception)
2919 Unexpect aCatch(SALOME_SalomeException);
2920 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
2923 //=============================================================================
2927 //=============================================================================
2928 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
2930 Unexpect aCatch(SALOME_SalomeException);
2931 return _mapSubMesh_i.size();
2934 //=============================================================================
2938 //=============================================================================
2939 char* SMESH_Mesh_i::Dump()
2943 return CORBA::string_dup( os.str().c_str() );
2946 //=============================================================================
2950 //=============================================================================
2951 SMESH::long_array* SMESH_Mesh_i::GetIDs()
2953 // SMESH::long_array_var aResult = new SMESH::long_array();
2954 // SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2955 // int aMinId = aSMESHDS_Mesh->MinElementID();
2956 // int aMaxId = aSMESHDS_Mesh->MaxElementID();
2958 // aResult->length(aMaxId - aMinId + 1);
2960 // for (int i = 0, id = aMinId; id <= aMaxId; id++ )
2961 // aResult[i++] = id;
2963 // return aResult._retn();
2965 return GetElementsId();
2968 //=============================================================================
2972 //=============================================================================
2974 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
2975 throw (SALOME::SALOME_Exception)
2977 Unexpect aCatch(SALOME_SalomeException);
2978 MESSAGE("SMESH_Mesh_i::GetElementsId");
2979 SMESH::long_array_var aResult = new SMESH::long_array();
2980 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2982 if ( aSMESHDS_Mesh == NULL )
2983 return aResult._retn();
2985 long nbElements = NbElements();
2986 aResult->length( nbElements );
2987 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2988 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
2989 aResult[i] = anIt->next()->GetID();
2991 return aResult._retn();
2995 //=============================================================================
2999 //=============================================================================
3001 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3002 throw (SALOME::SALOME_Exception)
3004 Unexpect aCatch(SALOME_SalomeException);
3005 MESSAGE("SMESH_subMesh_i::GetElementsByType");
3006 SMESH::long_array_var aResult = new SMESH::long_array();
3007 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3009 if ( aSMESHDS_Mesh == NULL )
3010 return aResult._retn();
3012 long nbElements = NbElements();
3014 // No sense in returning ids of elements along with ids of nodes:
3015 // when theElemType == SMESH::ALL, return node ids only if
3016 // there are no elements
3017 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3018 return GetNodesId();
3020 aResult->length( nbElements );
3024 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3025 while ( i < nbElements && anIt->more() ) {
3026 const SMDS_MeshElement* anElem = anIt->next();
3027 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
3028 aResult[i++] = anElem->GetID();
3031 aResult->length( i );
3033 return aResult._retn();
3036 //=============================================================================
3040 //=============================================================================
3042 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3043 throw (SALOME::SALOME_Exception)
3045 Unexpect aCatch(SALOME_SalomeException);
3046 MESSAGE("SMESH_subMesh_i::GetNodesId");
3047 SMESH::long_array_var aResult = new SMESH::long_array();
3048 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3050 if ( aSMESHDS_Mesh == NULL )
3051 return aResult._retn();
3053 long nbNodes = NbNodes();
3054 aResult->length( nbNodes );
3055 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3056 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3057 aResult[i] = anIt->next()->GetID();
3059 return aResult._retn();
3062 //=============================================================================
3066 //=============================================================================
3068 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3069 throw (SALOME::SALOME_Exception)
3071 return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
3074 //=============================================================================
3078 //=============================================================================
3080 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3081 throw (SALOME::SALOME_Exception)
3083 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3085 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3087 return ( SMESH::EntityType ) e->GetEntityType();
3090 //=============================================================================
3092 * Returns ID of elements for given submesh
3094 //=============================================================================
3095 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3096 throw (SALOME::SALOME_Exception)
3098 SMESH::long_array_var aResult = new SMESH::long_array();
3100 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3101 if(!SM) return aResult._retn();
3103 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3104 if(!SDSM) return aResult._retn();
3106 aResult->length(SDSM->NbElements());
3108 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3110 while ( eIt->more() ) {
3111 aResult[i++] = eIt->next()->GetID();
3114 return aResult._retn();
3118 //=============================================================================
3120 * Returns ID of nodes for given submesh
3121 * If param all==true - returns all nodes, else -
3122 * returns only nodes on shapes.
3124 //=============================================================================
3125 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all)
3126 throw (SALOME::SALOME_Exception)
3128 SMESH::long_array_var aResult = new SMESH::long_array();
3130 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3131 if(!SM) return aResult._retn();
3133 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3134 if(!SDSM) return aResult._retn();
3137 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
3138 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
3139 while ( nIt->more() ) {
3140 const SMDS_MeshNode* elem = nIt->next();
3141 theElems.insert( elem->GetID() );
3144 else { // all nodes of submesh elements
3145 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3146 while ( eIt->more() ) {
3147 const SMDS_MeshElement* anElem = eIt->next();
3148 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
3149 while ( nIt->more() ) {
3150 const SMDS_MeshElement* elem = nIt->next();
3151 theElems.insert( elem->GetID() );
3156 aResult->length(theElems.size());
3157 set<int>::iterator itElem;
3159 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
3160 aResult[i++] = *itElem;
3162 return aResult._retn();
3166 //=============================================================================
3168 * Returns type of elements for given submesh
3170 //=============================================================================
3171 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
3172 throw (SALOME::SALOME_Exception)
3174 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3175 if(!SM) return SMESH::ALL;
3177 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3178 if(!SDSM) return SMESH::ALL;
3180 if(SDSM->NbElements()==0)
3181 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
3183 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3184 const SMDS_MeshElement* anElem = eIt->next();
3185 return ( SMESH::ElementType ) anElem->GetType();
3189 //=============================================================================
3193 //=============================================================================
3195 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
3197 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
3199 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
3204 //=============================================================================
3206 * Get XYZ coordinates of node as list of double
3207 * If there is not node for given ID - returns empty list
3209 //=============================================================================
3211 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
3213 SMESH::double_array_var aResult = new SMESH::double_array();
3214 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3215 if ( aSMESHDS_Mesh == NULL )
3216 return aResult._retn();
3219 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3221 return aResult._retn();
3225 aResult[0] = aNode->X();
3226 aResult[1] = aNode->Y();
3227 aResult[2] = aNode->Z();
3228 return aResult._retn();
3232 //=============================================================================
3234 * For given node returns list of IDs of inverse elements
3235 * If there is not node for given ID - returns empty list
3237 //=============================================================================
3239 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
3241 SMESH::long_array_var aResult = new SMESH::long_array();
3242 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3243 if ( aSMESHDS_Mesh == NULL )
3244 return aResult._retn();
3247 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3249 return aResult._retn();
3251 // find inverse elements
3252 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
3253 TColStd_SequenceOfInteger IDs;
3254 while(eIt->more()) {
3255 const SMDS_MeshElement* elem = eIt->next();
3256 IDs.Append(elem->GetID());
3258 if(IDs.Length()>0) {
3259 aResult->length(IDs.Length());
3261 for(; i<=IDs.Length(); i++) {
3262 aResult[i-1] = IDs.Value(i);
3265 return aResult._retn();
3268 //=============================================================================
3270 * \brief Return position of a node on shape
3272 //=============================================================================
3274 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
3276 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
3277 aNodePosition->shapeID = 0;
3278 aNodePosition->shapeType = GEOM::SHAPE;
3280 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3281 if ( !mesh ) return aNodePosition;
3283 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
3285 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
3287 aNodePosition->shapeID = aNode->getshapeId();
3288 switch ( pos->GetTypeOfPosition() ) {
3290 aNodePosition->shapeType = GEOM::EDGE;
3291 aNodePosition->params.length(1);
3292 aNodePosition->params[0] =
3293 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
3296 aNodePosition->shapeType = GEOM::FACE;
3297 aNodePosition->params.length(2);
3298 aNodePosition->params[0] =
3299 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
3300 aNodePosition->params[1] =
3301 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
3303 case SMDS_TOP_VERTEX:
3304 aNodePosition->shapeType = GEOM::VERTEX;
3306 case SMDS_TOP_3DSPACE:
3307 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3308 aNodePosition->shapeType = GEOM::SOLID;
3309 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3310 aNodePosition->shapeType = GEOM::SHELL;
3316 return aNodePosition;
3319 //=============================================================================
3321 * If given element is node returns IDs of shape from position
3322 * If there is not node for given ID - returns -1
3324 //=============================================================================
3326 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3328 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3329 if ( aSMESHDS_Mesh == NULL )
3333 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3335 return aNode->getshapeId();
3342 //=============================================================================
3344 * For given element returns ID of result shape after
3345 * ::FindShape() from SMESH_MeshEditor
3346 * If there is not element for given ID - returns -1
3348 //=============================================================================
3350 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3352 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3353 if ( aSMESHDS_Mesh == NULL )
3356 // try to find element
3357 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3361 //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
3362 ::SMESH_MeshEditor aMeshEditor(_impl);
3363 int index = aMeshEditor.FindShape( elem );
3371 //=============================================================================
3373 * Returns number of nodes for given element
3374 * If there is not element for given ID - returns -1
3376 //=============================================================================
3378 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3380 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3381 if ( aSMESHDS_Mesh == NULL ) return -1;
3382 // try to find element
3383 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3384 if(!elem) return -1;
3385 return elem->NbNodes();
3389 //=============================================================================
3391 * Returns ID of node by given index for given element
3392 * If there is not element for given ID - returns -1
3393 * If there is not node for given index - returns -2
3395 //=============================================================================
3397 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3399 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3400 if ( aSMESHDS_Mesh == NULL ) return -1;
3401 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3402 if(!elem) return -1;
3403 if( index>=elem->NbNodes() || index<0 ) return -1;
3404 return elem->GetNode(index)->GetID();
3407 //=============================================================================
3409 * Returns IDs of nodes of given element
3411 //=============================================================================
3413 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3415 SMESH::long_array_var aResult = new SMESH::long_array();
3416 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3418 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3420 aResult->length( elem->NbNodes() );
3421 for ( int i = 0; i < elem->NbNodes(); ++i )
3422 aResult[ i ] = elem->GetNode( i )->GetID();
3425 return aResult._retn();
3428 //=============================================================================
3430 * Returns true if given node is medium node
3431 * in given quadratic element
3433 //=============================================================================
3435 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3437 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3438 if ( aSMESHDS_Mesh == NULL ) return false;
3440 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3441 if(!aNode) return false;
3442 // try to find element
3443 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3444 if(!elem) return false;
3446 return elem->IsMediumNode(aNode);
3450 //=============================================================================
3452 * Returns true if given node is medium node
3453 * in one of quadratic elements
3455 //=============================================================================
3457 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3458 SMESH::ElementType theElemType)
3460 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3461 if ( aSMESHDS_Mesh == NULL ) return false;
3464 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3465 if(!aNode) return false;
3467 SMESH_MesherHelper aHelper( *(_impl) );
3469 SMDSAbs_ElementType aType;
3470 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3471 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3472 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3473 else aType = SMDSAbs_All;
3475 return aHelper.IsMedium(aNode,aType);
3479 //=============================================================================
3481 * Returns number of edges for given element
3483 //=============================================================================
3485 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3487 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3488 if ( aSMESHDS_Mesh == NULL ) return -1;
3489 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3490 if(!elem) return -1;
3491 return elem->NbEdges();
3495 //=============================================================================
3497 * Returns number of faces for given element
3499 //=============================================================================
3501 CORBA::Long SMESH_Mesh_i::ElemNbFaces(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->NbFaces();
3510 //=======================================================================
3511 //function : GetElemFaceNodes
3512 //purpose : Returns nodes of given face (counted from zero) for given element.
3513 //=======================================================================
3515 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
3516 CORBA::Short faceIndex)
3518 SMESH::long_array_var aResult = new SMESH::long_array();
3519 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3521 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
3523 SMDS_VolumeTool vtool( elem );
3524 if ( faceIndex < vtool.NbFaces() )
3526 aResult->length( vtool.NbFaceNodes( faceIndex ));
3527 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
3528 for ( int i = 0; i < aResult->length(); ++i )
3529 aResult[ i ] = nn[ i ]->GetID();
3533 return aResult._retn();
3536 //=======================================================================
3537 //function : FindElementByNodes
3538 //purpose : Returns an element based on all given nodes.
3539 //=======================================================================
3541 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
3543 CORBA::Long elemID(0);
3544 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
3546 vector< const SMDS_MeshNode * > nn( nodes.length() );
3547 for ( int i = 0; i < nodes.length(); ++i )
3548 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
3551 const SMDS_MeshElement* elem = mesh->FindElement( nn );
3552 if ( !elem && ( _impl->NbEdges( ORDER_QUADRATIC ) ||
3553 _impl->NbFaces( ORDER_QUADRATIC ) ||
3554 _impl->NbVolumes( ORDER_QUADRATIC )))
3555 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
3557 if ( elem ) elemID = CORBA::Long( elem->GetID() );
3562 //=============================================================================
3564 * Returns true if given element is polygon
3566 //=============================================================================
3568 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
3570 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3571 if ( aSMESHDS_Mesh == NULL ) return false;
3572 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3573 if(!elem) return false;
3574 return elem->IsPoly();
3578 //=============================================================================
3580 * Returns true if given element is quadratic
3582 //=============================================================================
3584 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(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->IsQuadratic();
3594 //=============================================================================
3596 * Returns bary center for given element
3598 //=============================================================================
3600 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
3602 SMESH::double_array_var aResult = new SMESH::double_array();
3603 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3604 if ( aSMESHDS_Mesh == NULL )
3605 return aResult._retn();
3607 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3609 return aResult._retn();
3611 if(elem->GetType()==SMDSAbs_Volume) {
3612 SMDS_VolumeTool aTool;
3613 if(aTool.Set(elem)) {
3615 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
3620 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
3622 double x=0., y=0., z=0.;
3623 for(; anIt->more(); ) {
3625 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
3639 return aResult._retn();
3643 //=============================================================================
3645 * Create and publish group servants if any groups were imported or created anyhow
3647 //=============================================================================
3649 void SMESH_Mesh_i::CreateGroupServants()
3651 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3654 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
3655 while ( groupIt->more() )
3657 ::SMESH_Group* group = groupIt->next();
3658 int anId = group->GetGroupDS()->GetID();
3660 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
3661 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3663 addedIDs.insert( anId );
3665 SMESH_GroupBase_i* aGroupImpl;
3667 if ( SMESHDS_GroupOnGeom* groupOnGeom =
3668 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
3670 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3671 shape = groupOnGeom->GetShape();
3674 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3677 // To ensure correct mapping of servant and correct reference counting in GenericObj_i
3678 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
3679 aGroupImpl->Register();
3681 SMESH::SMESH_GroupBase_var groupVar =
3682 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
3683 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
3685 // register CORBA object for persistence
3686 int nextId = _gen_i->RegisterObject( groupVar );
3687 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
3689 // publishing the groups in the study
3690 if ( !aStudy->_is_nil() ) {
3691 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
3692 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
3695 if ( !addedIDs.empty() )
3698 set<int>::iterator id = addedIDs.begin();
3699 for ( ; id != addedIDs.end(); ++id )
3701 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
3702 int i = std::distance( _mapGroups.begin(), it );
3703 TPythonDump() << it->second << " = " << _this() << ".GetGroups()[ "<< i << " ]";
3708 //=============================================================================
3710 * \brief Return groups cantained in _mapGroups by their IDs
3712 //=============================================================================
3714 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
3716 int nbGroups = groupIDs.size();
3717 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
3718 aList->length( nbGroups );
3720 list<int>::const_iterator ids = groupIDs.begin();
3721 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
3723 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
3724 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3725 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
3727 aList->length( nbGroups );
3728 return aList._retn();
3731 //=============================================================================
3733 * \brief Return information about imported file
3735 //=============================================================================
3737 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
3739 SALOME_MED::MedFileInfo_var res( myFileInfo );
3740 if ( !res.operator->() ) {
3741 res = new SALOME_MED::MedFileInfo;
3743 res->fileSize = res->major = res->minor = res->release = -1;
3748 //=============================================================================
3750 * \brief Check and correct names of mesh groups
3752 //=============================================================================
3754 void SMESH_Mesh_i::checkGroupNames()
3756 int nbGrp = NbGroups();
3760 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3761 if ( aStudy->_is_nil() )
3762 return; // nothing to do
3764 SMESH::ListOfGroups* grpList = 0;
3765 // avoid dump of "GetGroups"
3767 // store python dump into a local variable inside local scope
3768 SMESH::TPythonDump pDump; // do not delete this line of code
3769 grpList = GetGroups();
3772 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
3773 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
3776 SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
3777 if ( aGrpSO->_is_nil() )
3779 // correct name of the mesh group if necessary
3780 const char* guiName = aGrpSO->GetName();
3781 if ( strcmp(guiName, aGrp->GetName()) )
3782 aGrp->SetName( guiName );
3786 //=============================================================================
3788 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
3790 //=============================================================================
3791 void SMESH_Mesh_i::SetParameters(const char* theParameters)
3793 SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
3794 CORBA::string_dup(theParameters));
3797 //=============================================================================
3799 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
3801 //=============================================================================
3802 char* SMESH_Mesh_i::GetParameters()
3804 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3805 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
3808 //=============================================================================
3810 * \brief Returns list of notebook variables used for last Mesh operation
3812 //=============================================================================
3813 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
3815 SMESH::string_array_var aResult = new SMESH::string_array();
3816 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3818 char *aParameters = GetParameters();
3819 SALOMEDS::Study_ptr aStudy = gen->GetCurrentStudy();
3820 if(!aStudy->_is_nil()) {
3821 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
3822 if(aSections->length() > 0) {
3823 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
3824 aResult->length(aVars.length());
3825 for(int i = 0;i < aVars.length();i++)
3826 aResult[i] = CORBA::string_dup( aVars[i]);
3830 return aResult._retn();
3833 //=======================================================================
3834 //function : GetTypes
3835 //purpose : Returns types of elements it contains
3836 //=======================================================================
3838 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
3840 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
3844 if (_impl->NbEdges())
3845 types[nbTypes++] = SMESH::EDGE;
3846 if (_impl->NbFaces())
3847 types[nbTypes++] = SMESH::FACE;
3848 if (_impl->NbVolumes())
3849 types[nbTypes++] = SMESH::VOLUME;
3850 if (_impl->Nb0DElements())
3851 types[nbTypes++] = SMESH::ELEM0D;
3852 types->length( nbTypes );
3854 return types._retn();
3857 //=======================================================================
3858 //function : GetMesh
3859 //purpose : Returns self
3860 //=======================================================================
3862 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
3864 return SMESH::SMESH_Mesh::_duplicate( _this() );
3867 //=============================================================================
3869 * \brief Returns statistic of mesh elements
3871 //=============================================================================
3872 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
3874 SMESH::long_array_var aRes = new SMESH::long_array();
3875 aRes->length(SMESH::Entity_Last);
3876 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3878 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3880 return aRes._retn();
3881 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
3882 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3883 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
3884 return aRes._retn();
3887 //=============================================================================
3889 * \brief Collect statistic of mesh elements given by iterator
3891 //=============================================================================
3892 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
3893 SMESH::long_array& theInfo)
3895 if (!theItr) return;
3896 while (theItr->more())
3897 theInfo[ theItr->next()->GetEntityType() ]++;
3900 //=============================================================================
3902 * \brief mapping of mesh dimension into shape type
3904 //=============================================================================
3905 static TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
3907 TopAbs_ShapeEnum aType = TopAbs_SOLID;
3909 case 0: aType = TopAbs_VERTEX; break;
3910 case 1: aType = TopAbs_EDGE; break;
3911 case 2: aType = TopAbs_FACE; break;
3913 default:aType = TopAbs_SOLID; break;
3918 //=============================================================================
3920 * \brief Internal structure used to find concurent submeshes
3922 * It represents a pair < submesh, concurent dimension >, where
3923 * 'concurrent dimension' is dimension of shape where the submesh can concurent
3924 * with another submesh. In other words, it is dimension of a hypothesis assigned
3927 //=============================================================================
3933 int _dim; //!< a dimension the algo can build (concurrent dimension)
3934 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
3935 TopTools_MapOfShape _shapeMap;
3936 SMESH_subMesh* _subMesh;
3937 list<const SMESHDS_Hypothesis*> _hypothesises; //!< algo is first, then its parameters
3940 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
3942 const TopoDS_Shape& theShape)
3944 _subMesh = (SMESH_subMesh*)theSubMesh;
3945 SetShape( theDim, theShape );
3949 void SetShape(const int theDim,
3950 const TopoDS_Shape& theShape)
3953 _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
3954 if (_dim >= _ownDim)
3955 _shapeMap.Add( theShape );
3957 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
3958 for( ; anExp.More(); anExp.Next() )
3959 _shapeMap.Add( anExp.Current() );
3963 //! Check sharing of sub shapes
3964 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
3965 const TopTools_MapOfShape& theToFind,
3966 const TopAbs_ShapeEnum theType)
3968 bool isShared = false;
3969 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
3970 for (; !isShared && anItr.More(); anItr.Next() ) {
3971 const TopoDS_Shape aSubSh = anItr.Key();
3972 // check for case when concurrent dimensions are same
3973 isShared = theToFind.Contains( aSubSh );
3974 // check for subshape with concurrent dimension
3975 TopExp_Explorer anExp( aSubSh, theType );
3976 for ( ; !isShared && anExp.More(); anExp.Next() )
3977 isShared = theToFind.Contains( anExp.Current() );
3982 //! check algorithms
3983 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
3984 const SMESHDS_Hypothesis* theA2)
3986 if ( theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
3987 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
3988 return false; // one of the hypothesis is not algorithm
3989 // check algorithm names (should be equal)
3990 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
3994 //! Check if subshape hypotheses are concurrent
3995 bool IsConcurrent(const SMESH_DimHyp* theOther) const
3997 if ( _subMesh == theOther->_subMesh )
3998 return false; // same subshape - should not be
4000 // if ( <own dim of either of submeshes> == <concurrent dim> &&
4001 // any of the two submeshes is not on COMPOUND shape )
4002 // -> no concurrency
4003 bool meIsCompound = (_subMesh->GetSubMeshDS() && _subMesh->GetSubMeshDS()->IsComplexSubmesh());
4004 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() && theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
4005 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
4008 // bool checkSubShape = ( _dim >= theOther->_dim )
4009 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
4010 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
4011 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
4012 if ( !checkSubShape )
4015 // check algorithms to be same
4016 if (!checkAlgo( _hypothesises.front(), theOther->_hypothesises.front() ))
4017 return true; // different algorithms
4019 // check hypothesises for concurrence (skip first as algorithm)
4021 // pointers should be same, becase it is referenes from mesh hypothesis partition
4022 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypothesises.begin();
4023 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypothesises.end();
4024 for ( hypIt++ /*skip first as algo*/; hypIt != _hypothesises.end(); hypIt++ )
4025 if ( find( theOther->_hypothesises.begin(), otheEndIt, *hypIt ) != otheEndIt )
4027 // the submeshes are concurrent if their algorithms has different parameters
4028 return nbSame != theOther->_hypothesises.size() - 1;
4031 }; // end of SMESH_DimHyp
4033 typedef list<SMESH_DimHyp*> TDimHypList;
4035 static void addDimHypInstance(const int theDim,
4036 const TopoDS_Shape& theShape,
4037 const SMESH_Algo* theAlgo,
4038 const SMESH_subMesh* theSubMesh,
4039 const list <const SMESHDS_Hypothesis*>& theHypList,
4040 TDimHypList* theDimHypListArr )
4042 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
4043 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
4044 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
4045 listOfdimHyp.push_back( dimHyp );
4048 SMESH_DimHyp* dimHyp = listOfdimHyp.back();
4049 dimHyp->_hypothesises.push_front(theAlgo);
4050 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = theHypList.begin();
4051 for( ; hypIt != theHypList.end(); hypIt++ )
4052 dimHyp->_hypothesises.push_back( *hypIt );
4055 static void findConcurrents(const SMESH_DimHyp* theDimHyp,
4056 const TDimHypList& theListOfDimHyp,
4057 TListOfInt& theListOfConcurr )
4059 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
4060 for ( ; rIt != theListOfDimHyp.rend(); rIt++ ) {
4061 const SMESH_DimHyp* curDimHyp = *rIt;
4062 if ( curDimHyp == theDimHyp )
4063 break; // meet own dimHyp pointer in same dimension
4064 else if ( theDimHyp->IsConcurrent( curDimHyp ) )
4065 if ( find( theListOfConcurr.begin(),
4066 theListOfConcurr.end(),
4067 curDimHyp->_subMesh->GetId() ) == theListOfConcurr.end() )
4068 theListOfConcurr.push_back( curDimHyp->_subMesh->GetId() );
4072 static void unionLists(TListOfInt& theListOfId,
4073 TListOfListOfInt& theListOfListOfId,
4076 TListOfListOfInt::iterator it = theListOfListOfId.begin();
4077 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
4079 continue; //skip already treated lists
4080 // check if other list has any same submesh object
4081 TListOfInt& otherListOfId = *it;
4082 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
4083 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
4086 // union two lists (from source into target)
4087 TListOfInt::iterator it2 = otherListOfId.begin();
4088 for ( ; it2 != otherListOfId.end(); it2++ ) {
4089 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
4090 theListOfId.push_back(*it2);
4092 // clear source list
4093 otherListOfId.clear();
4097 //! free memory allocated for dimension-hypothesis objects
4098 static void removeDimHyps( TDimHypList* theArrOfList )
4100 for (int i = 0; i < 4; i++ ) {
4101 TDimHypList& listOfdimHyp = theArrOfList[i];
4102 TDimHypList::const_iterator it = listOfdimHyp.begin();
4103 for ( ; it != listOfdimHyp.end(); it++ )
4108 //=============================================================================
4110 * \brief Return submesh objects list in meshing order
4112 //=============================================================================
4114 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
4116 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
4118 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4120 return aResult._retn();
4122 ::SMESH_Mesh& mesh = GetImpl();
4123 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
4124 if ( !anOrder.size() ) {
4126 // collect submeshes detecting concurrent algorithms and hypothesises
4127 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
4129 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
4130 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
4131 ::SMESH_subMesh* sm = (*i_sm).second;
4133 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
4135 // list of assigned hypothesises
4136 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
4137 // Find out dimensions where the submesh can be concurrent.
4138 // We define the dimensions by algo of each of hypotheses in hypList
4139 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
4140 for( ; hypIt != hypList.end(); hypIt++ ) {
4141 SMESH_Algo* anAlgo = 0;
4142 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
4143 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
4144 // hyp it-self is algo
4145 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
4147 // try to find algorithm with help of subshapes
4148 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
4149 for ( ; !anAlgo && anExp.More(); anExp.Next() )
4150 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
4153 continue; // no assigned algorithm to current submesh
4155 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
4156 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDescretBoundary())
4158 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
4159 for ( int j = anAlgo->NeedDescretBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
4160 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
4162 } // end iterations on submesh
4164 // iterate on created dimension-hypotheses and check for concurrents
4165 for ( int i = 0; i < 4; i++ ) {
4166 const list<SMESH_DimHyp*>& listOfDimHyp = dimHypListArr[i];
4167 // check for concurrents in own and other dimensions (step-by-step)
4168 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
4169 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
4170 const SMESH_DimHyp* dimHyp = *dhIt;
4171 TListOfInt listOfConcurr;
4172 // looking for concurrents and collect into own list
4173 for ( int j = i; j < 4; j++ )
4174 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr );
4175 // check if any concurrents found
4176 if ( listOfConcurr.size() > 0 ) {
4177 // add own submesh to list of concurrent
4178 listOfConcurr.push_front( dimHyp->_subMesh->GetId() );
4179 anOrder.push_back( listOfConcurr );
4184 removeDimHyps(dimHypListArr);
4186 // now, minimise the number of concurrent groups
4187 // Here we assume that lists of submhes can has same submesh
4188 // in case of multi-dimension algorithms, as result
4189 // list with common submesh have to be union into one list
4191 TListOfListOfInt::iterator listIt = anOrder.begin();
4192 for(; listIt != anOrder.end(); listIt++, listIndx++ )
4193 unionLists( *listIt, anOrder, listIndx + 1 );
4195 // convert submesh ids into interface instances
4196 // and dump command into python
4197 convertMeshOrder( anOrder, aResult, true );
4199 return aResult._retn();
4202 //=============================================================================
4204 * \brief find common submeshes with given submesh
4205 * \param theSubMeshList list of already collected submesh to check
4206 * \param theSubMesh given submesh to intersect with other
4207 * \param theCommonSubMeshes collected common submeshes
4209 //=============================================================================
4211 static void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
4212 const SMESH_subMesh* theSubMesh,
4213 set<const SMESH_subMesh*>& theCommon )
4217 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
4218 for ( ; it != theSubMeshList.end(); it++ )
4219 theSubMesh->FindIntersection( *it, theCommon );
4220 theSubMeshList.push_back( theSubMesh );
4221 //theCommon.insert( theSubMesh );
4224 //=============================================================================
4226 * \brief Set submesh object order
4227 * \param theSubMeshArray submesh array order
4229 //=============================================================================
4231 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
4234 ::SMESH_Mesh& mesh = GetImpl();
4236 TPythonDump aPythonDump; // prevent dump of called methods
4237 aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
4239 TListOfListOfInt subMeshOrder;
4240 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
4242 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
4243 TListOfInt subMeshIds;
4244 aPythonDump << "[ ";
4245 // Collect subMeshes which should be clear
4246 // do it list-by-list, because modification of submesh order
4247 // take effect between concurrent submeshes only
4248 set<const SMESH_subMesh*> subMeshToClear;
4249 list<const SMESH_subMesh*> subMeshList;
4250 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
4252 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
4254 aPythonDump << ", ";
4255 aPythonDump << subMesh;
4256 subMeshIds.push_back( subMesh->GetId() );
4257 // detect common parts of submeshes
4258 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
4259 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
4261 aPythonDump << " ]";
4262 subMeshOrder.push_back( subMeshIds );
4264 // clear collected submeshes
4265 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
4266 for ( ; clrIt != subMeshToClear.end(); clrIt++ ) {
4267 SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt;
4269 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
4270 // ClearSubMesh( *clrIt );
4273 aPythonDump << " ])";
4275 mesh.SetMeshOrder( subMeshOrder );
4281 //=============================================================================
4283 * \brief Convert submesh ids into submesh interfaces
4285 //=============================================================================
4287 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
4288 SMESH::submesh_array_array& theResOrder,
4289 const bool theIsDump)
4291 int nbSet = theIdsOrder.size();
4292 TPythonDump aPythonDump; // prevent dump of called methods
4294 aPythonDump << "[ ";
4295 theResOrder.length(nbSet);
4296 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
4298 for( ; it != theIdsOrder.end(); it++ ) {
4299 // translate submesh identificators into submesh objects
4300 // takeing into account real number of concurrent lists
4301 const TListOfInt& aSubOrder = (*it);
4302 if (!aSubOrder.size())
4305 aPythonDump << "[ ";
4306 // convert shape indeces into interfaces
4307 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
4308 aResSubSet->length(aSubOrder.size());
4309 TListOfInt::const_iterator subIt = aSubOrder.begin();
4310 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
4311 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
4313 SMESH::SMESH_subMesh_var subMesh =
4314 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
4317 aPythonDump << ", ";
4318 aPythonDump << subMesh;
4320 aResSubSet[ j++ ] = subMesh;
4323 aPythonDump << " ]";
4324 theResOrder[ listIndx++ ] = aResSubSet;
4326 // correct number of lists
4327 theResOrder.length( listIndx );
4330 // finilise python dump
4331 aPythonDump << " ]";
4332 aPythonDump << " = " << _this() << ".GetMeshOrder()";
4336 //================================================================================
4338 // Implementation of SMESH_MeshPartDS
4340 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
4341 SMESHDS_Mesh( /*theMeshID=*/-1, /*theIsEmbeddedMode=*/true)
4343 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
4344 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4346 _meshDS = mesh_i->GetImpl().GetMeshDS();
4348 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
4350 // <meshPart> is the whole mesh
4351 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
4356 SMESH::long_array_var anIDs = meshPart->GetIDs();
4357 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
4358 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
4360 for (int i=0; i < anIDs->length(); i++)
4361 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
4362 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4367 for (int i=0; i < anIDs->length(); i++)
4368 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
4369 if ( _elements[ e->GetType() ].insert( e ).second )
4372 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
4373 while ( nIt->more() )
4375 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
4376 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4383 _meshDS = 0; // to enforce iteration on _elements and _nodes
4386 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
4388 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
4389 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
4390 ( new TIter( _elements[type].begin(), _elements[type].end() ));
4392 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
4393 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
4395 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
4396 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
4397 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
4399 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
4400 _GET_ITER_DEFINE( SMDS_0DElementIteratorPtr, elements0dIterator, SMDS_Mesh0DElement, SMDSAbs_0DElement)
4401 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
4402 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
4403 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
4404 #undef _GET_ITER_DEFINE
4406 // END Implementation of SMESH_MeshPartDS
4408 //================================================================================