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 //=============================================================================
734 #define CASE2STRING(enum) case SMESH::enum: return "SMESH."#enum;
735 inline TCollection_AsciiString ElementTypeString (SMESH::ElementType theElemType)
737 switch (theElemType) {
742 CASE2STRING( VOLUME );
743 CASE2STRING( ELEM0D );
749 //=============================================================================
753 //=============================================================================
755 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
756 const char* theName )
757 throw(SALOME::SALOME_Exception)
759 Unexpect aCatch(SALOME_SalomeException);
760 SMESH::SMESH_Group_var aNewGroup =
761 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
763 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
764 SALOMEDS::SObject_var aSO =
765 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
766 aNewGroup, GEOM::GEOM_Object::_nil(), theName);
767 if ( !aSO->_is_nil()) {
768 // Update Python script
769 TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
770 << ElementTypeString(theElemType) << ", '" << theName << "' )";
773 return aNewGroup._retn();
777 //=============================================================================
781 //=============================================================================
782 SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
784 GEOM::GEOM_Object_ptr theGeomObj)
785 throw(SALOME::SALOME_Exception)
787 Unexpect aCatch(SALOME_SalomeException);
788 SMESH::SMESH_GroupOnGeom_var aNewGroup;
790 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
791 if ( !aShape.IsNull() )
793 aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
794 ( createGroup( theElemType, theName, aShape ));
796 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
797 SALOMEDS::SObject_var aSO =
798 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
799 aNewGroup, theGeomObj, theName);
800 if ( !aSO->_is_nil()) {
801 // Update Python script
802 TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
803 << ElementTypeString(theElemType) << ", '" << theName << "', "
804 << theGeomObj << " )";
809 return aNewGroup._retn();
812 //=============================================================================
816 //=============================================================================
818 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
819 throw (SALOME::SALOME_Exception)
821 if ( theGroup->_is_nil() )
824 SMESH_GroupBase_i* aGroup =
825 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
829 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
830 if ( !aStudy->_is_nil() ) {
831 SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
833 if ( !aGroupSO->_is_nil() ) {
834 // Update Python script
835 TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
837 // Remove group's SObject
838 aStudy->NewBuilder()->RemoveObjectWithChildren( aGroupSO );
842 // Remove the group from SMESH data structures
843 removeGroup( aGroup->GetLocalID() );
846 //=============================================================================
847 /*! RemoveGroupWithContents
848 * Remove group with its contents
850 //=============================================================================
851 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
852 throw (SALOME::SALOME_Exception)
854 if ( theGroup->_is_nil() )
857 SMESH_GroupBase_i* aGroup =
858 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
862 SMESH::long_array_var anIds = aGroup->GetListOfID();
863 SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
865 TPythonDump pyDump; // Supress dump from RemoveNodes/Elements() and RemoveGroup()
868 if ( aGroup->GetType() == SMESH::NODE )
869 aMeshEditor->RemoveNodes( anIds );
871 aMeshEditor->RemoveElements( anIds );
874 RemoveGroup( theGroup );
876 // Update Python script
877 pyDump << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
880 //================================================================================
882 * \brief Get the list of groups existing in the mesh
883 * \retval SMESH::ListOfGroups * - list of groups
885 //================================================================================
887 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
889 Unexpect aCatch(SALOME_SalomeException);
890 if (MYDEBUG) MESSAGE("GetGroups");
892 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
895 TPythonDump aPythonDump;
896 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
900 aList->length( _mapGroups.size() );
902 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
903 for ( ; it != _mapGroups.end(); it++ ) {
904 if ( CORBA::is_nil( it->second )) continue;
905 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
907 if (i > 1) aPythonDump << ", ";
908 aPythonDump << it->second;
912 catch(SALOME_Exception & S_ex) {
913 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
916 // Update Python script
917 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
918 aPythonDump << " ] = " << _this() << ".GetGroups()";
920 return aList._retn();
923 //=============================================================================
925 * Get number of groups existing in the mesh
927 //=============================================================================
929 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
931 Unexpect aCatch(SALOME_SalomeException);
932 return _mapGroups.size();
935 //=============================================================================
937 * New group is created. All mesh elements that are
938 * present in initial groups are added to the new one
940 //=============================================================================
941 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
942 SMESH::SMESH_GroupBase_ptr theGroup2,
943 const char* theName )
944 throw (SALOME::SALOME_Exception)
948 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
949 theGroup1->GetType() != theGroup2->GetType() )
950 return SMESH::SMESH_Group::_nil();
953 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
954 if ( aResGrp->_is_nil() )
955 return SMESH::SMESH_Group::_nil();
957 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
958 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
960 TColStd_MapOfInteger aResMap;
962 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
963 aResMap.Add( anIds1[ i1 ] );
965 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
966 aResMap.Add( anIds2[ i2 ] );
968 SMESH::long_array_var aResIds = new SMESH::long_array;
969 aResIds->length( aResMap.Extent() );
972 TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
973 for( ; anIter.More(); anIter.Next() )
974 aResIds[ resI++ ] = anIter.Key();
976 aResGrp->Add( aResIds );
978 // Clear python lines, created by CreateGroup() and Add()
979 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
980 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
981 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
983 // Update Python script
984 TPythonDump() << aResGrp << " = " << _this() << ".UnionGroups( "
985 << theGroup1 << ", " << theGroup2 << ", '"
988 return aResGrp._retn();
992 return SMESH::SMESH_Group::_nil();
996 //=============================================================================
998 \brief Union list of groups. New group is created. All mesh elements that are
999 present in initial groups are added to the new one.
1000 \param theGroups list of groups
1001 \param theName name of group to be created
1002 \return pointer on the group
1004 //=============================================================================
1005 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1006 const char* theName )
1007 throw (SALOME::SALOME_Exception)
1010 return SMESH::SMESH_Group::_nil();
1014 vector< int > anIds;
1015 SMESH::ElementType aType = SMESH::ALL;
1016 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1018 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1019 if ( CORBA::is_nil( aGrp ) )
1023 SMESH::ElementType aCurrType = aGrp->GetType();
1024 if ( aType == SMESH::ALL )
1028 if ( aType != aCurrType )
1029 return SMESH::SMESH_Group::_nil();
1033 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1034 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1036 int aCurrId = aCurrIds[ i ];
1037 anIds.push_back( aCurrId );
1042 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1043 if ( aResGrp->_is_nil() )
1044 return SMESH::SMESH_Group::_nil();
1046 // Create array of identifiers
1047 SMESH::long_array_var aResIds = new SMESH::long_array;
1048 aResIds->length( anIds.size() );
1050 //NCollection_Map< int >::Iterator anIter( anIds );
1051 for ( int i = 0; i<anIds.size(); i++ )
1053 aResIds[ i ] = anIds[i];
1055 aResGrp->Add( aResIds );
1057 // Clear python lines, created by CreateGroup() and Add()
1058 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1059 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1060 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1062 // Update Python script
1064 TPythonDump() << aResGrp << " = " << _this() << ".UnionListOfGroups( "
1065 << &theGroups << ", '" << theName << "' )";
1067 return aResGrp._retn();
1071 return SMESH::SMESH_Group::_nil();
1075 //=============================================================================
1077 * New group is created. All mesh elements that are
1078 * present in both initial groups are added to the new one.
1080 //=============================================================================
1081 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1082 SMESH::SMESH_GroupBase_ptr theGroup2,
1083 const char* theName )
1084 throw (SALOME::SALOME_Exception)
1086 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1087 theGroup1->GetType() != theGroup2->GetType() )
1088 return SMESH::SMESH_Group::_nil();
1090 // Create Intersection
1091 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1092 if ( aResGrp->_is_nil() )
1095 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1096 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1098 TColStd_MapOfInteger aMap1;
1100 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1101 aMap1.Add( anIds1[ i1 ] );
1103 TColStd_SequenceOfInteger aSeq;
1105 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1106 if ( aMap1.Contains( anIds2[ i2 ] ) )
1107 aSeq.Append( anIds2[ i2 ] );
1109 SMESH::long_array_var aResIds = new SMESH::long_array;
1110 aResIds->length( aSeq.Length() );
1112 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1113 aResIds[ resI ] = aSeq( resI + 1 );
1115 aResGrp->Add( aResIds );
1117 // Clear python lines, created by CreateGroup() and Add()
1118 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1119 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1120 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1122 // Update Python script
1123 TPythonDump() << aResGrp << " = " << _this() << ".IntersectGroups( "
1124 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1126 return aResGrp._retn();
1129 //=============================================================================
1131 \brief Intersect list of groups. New group is created. All mesh elements that
1132 are present in all initial groups simultaneously are added to the new one.
1133 \param theGroups list of groups
1134 \param theName name of group to be created
1135 \return pointer on the group
1137 //=============================================================================
1138 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectListOfGroups(
1139 const SMESH::ListOfGroups& theGroups, const char* theName )
1140 throw (SALOME::SALOME_Exception)
1143 return SMESH::SMESH_Group::_nil();
1147 NCollection_DataMap< int, int > anIdToCount;
1148 SMESH::ElementType aType = SMESH::ALL;
1149 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1151 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1152 if ( CORBA::is_nil( aGrp ) )
1156 SMESH::ElementType aCurrType = aGrp->GetType();
1157 if ( aType == SMESH::ALL )
1161 if ( aType != aCurrType )
1162 return SMESH::SMESH_Group::_nil();
1165 // calculates number of occurance ids in groups
1166 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1167 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1169 int aCurrId = aCurrIds[ i ];
1170 if ( !anIdToCount.IsBound( aCurrId ) )
1171 anIdToCount.Bind( aCurrId, 1 );
1173 anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
1177 // create map of ids
1178 int nbGrp = theGroups.length();
1179 vector< int > anIds;
1180 NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
1181 for ( ; anIter.More(); anIter.Next() )
1183 int aCurrId = anIter.Key();
1184 int aCurrNb = anIter.Value();
1185 if ( aCurrNb == nbGrp )
1186 anIds.push_back( aCurrId );
1190 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1191 if ( aResGrp->_is_nil() )
1192 return SMESH::SMESH_Group::_nil();
1194 // Create array of identifiers
1195 SMESH::long_array_var aResIds = new SMESH::long_array;
1196 aResIds->length( anIds.size() );
1198 //NCollection_Map< int >::Iterator aListIter( anIds );
1199 for ( int i = 0; i<anIds.size(); i++ )
1201 aResIds[ i ] = anIds[i];
1203 aResGrp->Add( aResIds );
1205 // Clear python lines, created by CreateGroup() and Add()
1206 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1207 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1208 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1210 // Update Python script
1212 TPythonDump() << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
1213 << &theGroups << ", '" << theName << "' )";
1215 return aResGrp._retn();
1219 return SMESH::SMESH_Group::_nil();
1223 //=============================================================================
1225 * New group is created. All mesh elements that are present in
1226 * main group but do not present in tool group are added to the new one
1228 //=============================================================================
1229 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1230 SMESH::SMESH_GroupBase_ptr theGroup2,
1231 const char* theName )
1232 throw (SALOME::SALOME_Exception)
1234 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1235 theGroup1->GetType() != theGroup2->GetType() )
1236 return SMESH::SMESH_Group::_nil();
1239 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1240 if ( aResGrp->_is_nil() )
1243 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1244 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1246 TColStd_MapOfInteger aMap2;
1248 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1249 aMap2.Add( anIds2[ i2 ] );
1251 TColStd_SequenceOfInteger aSeq;
1252 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1253 if ( !aMap2.Contains( anIds1[ i1 ] ) )
1254 aSeq.Append( anIds1[ i1 ] );
1256 SMESH::long_array_var aResIds = new SMESH::long_array;
1257 aResIds->length( aSeq.Length() );
1259 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1260 aResIds[ resI ] = aSeq( resI + 1 );
1262 aResGrp->Add( aResIds );
1264 // Clear python lines, created by CreateGroup() and Add()
1265 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1266 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1267 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1269 // Update Python script
1270 TPythonDump() << aResGrp << " = " << _this() << ".CutGroups( "
1271 << theGroup1 << ", " << theGroup2 << ", '"
1272 << theName << "' )";
1274 return aResGrp._retn();
1277 //=============================================================================
1279 \brief Cut lists of groups. New group is created. All mesh elements that are
1280 present in main groups but do not present in tool groups are added to the new one
1281 \param theMainGroups list of main groups
1282 \param theToolGroups list of tool groups
1283 \param theName name of group to be created
1284 \return pointer on the group
1286 //=============================================================================
1287 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups(
1288 const SMESH::ListOfGroups& theMainGroups,
1289 const SMESH::ListOfGroups& theToolGroups,
1290 const char* theName )
1291 throw (SALOME::SALOME_Exception)
1294 return SMESH::SMESH_Group::_nil();
1298 set< int > aToolIds;
1299 SMESH::ElementType aType = SMESH::ALL;
1301 // iterate through tool groups
1302 for ( g = 0, n = theToolGroups.length(); g < n; g++ )
1304 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1305 if ( CORBA::is_nil( aGrp ) )
1309 SMESH::ElementType aCurrType = aGrp->GetType();
1310 if ( aType == SMESH::ALL )
1314 if ( aType != aCurrType )
1315 return SMESH::SMESH_Group::_nil();
1319 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1320 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1322 int aCurrId = aCurrIds[ i ];
1323 aToolIds.insert( aCurrId );
1327 vector< int > anIds; // result
1329 // Iterate through main group
1330 for ( g = 0, n = theMainGroups.length(); g < n; g++ )
1332 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1333 if ( CORBA::is_nil( aGrp ) )
1337 SMESH::ElementType aCurrType = aGrp->GetType();
1338 if ( aType == SMESH::ALL )
1342 if ( aType != aCurrType )
1343 return SMESH::SMESH_Group::_nil();
1347 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1348 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1350 int aCurrId = aCurrIds[ i ];
1351 if ( !aToolIds.count( aCurrId ) )
1352 anIds.push_back( aCurrId );
1357 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1358 if ( aResGrp->_is_nil() )
1359 return SMESH::SMESH_Group::_nil();
1361 // Create array of identifiers
1362 SMESH::long_array_var aResIds = new SMESH::long_array;
1363 aResIds->length( anIds.size() );
1365 for (int i=0; i<anIds.size(); i++ )
1367 aResIds[ i ] = anIds[i];
1369 aResGrp->Add( aResIds );
1371 // Clear python lines, created by CreateGroup() and Add()
1372 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1373 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1374 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1376 // Update Python script
1378 TPythonDump() << aResGrp << " = " << _this() << ".CutListOfGroups( "
1379 << &theMainGroups << ", " << &theToolGroups << ", '"
1380 << theName << "' )";
1382 return aResGrp._retn();
1386 return SMESH::SMESH_Group::_nil();
1390 //=============================================================================
1392 \brief Create groups of entities from existing groups of superior dimensions
1394 1) extract all nodes from each group,
1395 2) combine all elements of specified dimension laying on these nodes.
1396 \param theGroups list of source groups
1397 \param theElemType dimension of elements
1398 \param theName name of new group
1399 \return pointer on new group
1401 //=============================================================================
1402 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
1403 const SMESH::ListOfGroups& theGroups,
1404 SMESH::ElementType theElemType,
1405 const char* theName )
1406 throw (SALOME::SALOME_Exception)
1408 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1410 if ( !theName || !aMeshDS )
1411 return SMESH::SMESH_Group::_nil();
1413 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1417 // Create map of nodes from all groups
1419 set< int > aNodeMap;
1421 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1423 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1424 if ( CORBA::is_nil( aGrp ) )
1427 SMESH::ElementType aType = aGrp->GetType();
1428 if ( aType == SMESH::ALL )
1430 else if ( aType == SMESH::NODE )
1432 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1433 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1435 int aCurrId = aCurrIds[ i ];
1436 const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
1438 aNodeMap.insert( aNode->GetID() );
1443 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1444 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1446 int aCurrId = aCurrIds[ i ];
1447 const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId );
1450 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1451 while( aNodeIter->more() )
1453 const SMDS_MeshNode* aNode =
1454 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1456 aNodeMap.insert( aNode->GetID() );
1462 // Get result identifiers
1464 vector< int > aResultIds;
1465 if ( theElemType == SMESH::NODE )
1467 //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1468 set<int>::iterator iter = aNodeMap.begin();
1469 for ( ; iter != aNodeMap.end(); iter++ )
1470 aResultIds.push_back( *iter);
1474 // Create list of elements of given dimension constructed on the nodes
1475 vector< int > anElemList;
1476 //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1477 //for ( ; aNodeIter.More(); aNodeIter.Next() )
1478 set<int>::iterator iter = aNodeMap.begin();
1479 for ( ; iter != aNodeMap.end(); iter++ )
1481 const SMDS_MeshElement* aNode =
1482 dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( *iter ) );
1486 SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType );
1487 while( anElemIter->more() )
1489 const SMDS_MeshElement* anElem =
1490 dynamic_cast<const SMDS_MeshElement*>( anElemIter->next() );
1491 if ( anElem && anElem->GetType() == anElemType )
1492 anElemList.push_back( anElem->GetID() );
1496 // check whether all nodes of elements are present in nodes map
1497 //NCollection_Map< int >::Iterator anIter( anElemList );
1498 //for ( ; anIter.More(); anIter.Next() )
1499 for (int i=0; i< anElemList.size(); i++)
1501 const SMDS_MeshElement* anElem = aMeshDS->FindElement( anElemList[i] );
1506 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1507 while( aNodeIter->more() )
1509 const SMDS_MeshNode* aNode =
1510 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1511 if ( !aNode || !aNodeMap.count( aNode->GetID() ) )
1518 aResultIds.push_back( anElem->GetID() );
1524 SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName );
1525 if ( aResGrp->_is_nil() )
1526 return SMESH::SMESH_Group::_nil();
1528 // Create array of identifiers
1529 SMESH::long_array_var aResIds = new SMESH::long_array;
1530 aResIds->length( aResultIds.size() );
1532 //NCollection_Map< int >::Iterator aResIter( aResultIds );
1533 //for ( int i = 0; aResIter.More(); aResIter.Next(), i++ )
1534 for (int i=0; i< aResultIds.size(); i++)
1535 aResIds[ i ] = aResultIds[i];
1536 aResGrp->Add( aResIds );
1538 // Remove strings corresponding to group creation
1539 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1540 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1541 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1543 // Update Python script
1545 TPythonDump() << aResGrp << " = " << _this() << ".CreateDimGroup( "
1546 << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1548 return aResGrp._retn();
1552 return SMESH::SMESH_Group::_nil();
1556 //================================================================================
1558 * \brief Remember GEOM group data
1560 //================================================================================
1562 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1563 CORBA::Object_ptr theSmeshObj)
1565 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1568 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1569 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1570 if ( groupSO->_is_nil() )
1573 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1574 GEOM::GEOM_IGroupOperations_var groupOp =
1575 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1576 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1579 _geomGroupData.push_back( TGeomGroupData() );
1580 TGeomGroupData & groupData = _geomGroupData.back();
1582 CORBA::String_var entry = groupSO->GetID();
1583 groupData._groupEntry = entry.in();
1585 for ( int i = 0; i < ids->length(); ++i )
1586 groupData._indices.insert( ids[i] );
1588 groupData._smeshObject = theSmeshObj;
1591 //================================================================================
1593 * Remove GEOM group data relating to removed smesh object
1595 //================================================================================
1597 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1599 list<TGeomGroupData>::iterator
1600 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1601 for ( ; data != dataEnd; ++data ) {
1602 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1603 _geomGroupData.erase( data );
1609 //================================================================================
1611 * \brief Return new group contents if it has been changed and update group data
1613 //================================================================================
1615 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1617 TopoDS_Shape newShape;
1620 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1621 if ( study->_is_nil() ) return newShape; // means "not changed"
1622 SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1623 if ( !groupSO->_is_nil() )
1625 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1626 if ( CORBA::is_nil( groupObj )) return newShape;
1627 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1629 // get indices of group items
1630 set<int> curIndices;
1631 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1632 GEOM::GEOM_IGroupOperations_var groupOp =
1633 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1634 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1635 for ( int i = 0; i < ids->length(); ++i )
1636 curIndices.insert( ids[i] );
1638 if ( groupData._indices == curIndices )
1639 return newShape; // group not changed
1642 groupData._indices = curIndices;
1644 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1645 if ( !geomClient ) return newShape;
1646 TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1647 geomClient->RemoveShapeFromBuffer( groupIOR );
1648 newShape = _gen_i->GeomObjectToShape( geomGroup );
1651 if ( newShape.IsNull() ) {
1652 // geom group becomes empty - return empty compound
1653 TopoDS_Compound compound;
1654 BRep_Builder().MakeCompound(compound);
1655 newShape = compound;
1661 //=============================================================================
1663 * \brief Storage of shape and index used in CheckGeomGroupModif()
1665 //=============================================================================
1666 struct TIndexedShape {
1668 TopoDS_Shape _shape;
1669 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1672 //=============================================================================
1674 * \brief Update objects depending on changed geom groups
1676 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1677 * issue 0020210: Update of a smesh group after modification of the associated geom group
1679 //=============================================================================
1681 void SMESH_Mesh_i::CheckGeomGroupModif()
1683 if ( !_impl->HasShapeToMesh() ) return;
1685 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1686 if ( study->_is_nil() ) return;
1688 CORBA::Long nbEntities = NbNodes() + NbElements();
1690 // Check if group contents changed
1692 typedef map< string, TopoDS_Shape > TEntry2Geom;
1693 TEntry2Geom newGroupContents;
1695 list<TGeomGroupData>::iterator
1696 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1697 for ( ; data != dataEnd; ++data )
1699 pair< TEntry2Geom::iterator, bool > it_new =
1700 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1701 bool processedGroup = !it_new.second;
1702 TopoDS_Shape& newShape = it_new.first->second;
1703 if ( !processedGroup )
1704 newShape = newGroupShape( *data );
1705 if ( newShape.IsNull() )
1706 continue; // no changes
1708 if ( processedGroup ) { // update group indices
1709 list<TGeomGroupData>::iterator data2 = data;
1710 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1711 data->_indices = data2->_indices;
1714 // Update SMESH objects according to new GEOM group contents
1716 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1717 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1719 int oldID = submesh->GetId();
1720 if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1722 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1724 // update hypotheses
1725 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1726 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1727 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1729 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1730 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1732 // care of submeshes
1733 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1734 int newID = newSubmesh->GetId();
1735 if ( newID != oldID ) {
1736 _mapSubMesh [ newID ] = newSubmesh;
1737 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1738 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1739 _mapSubMesh. erase(oldID);
1740 _mapSubMesh_i. erase(oldID);
1741 _mapSubMeshIor.erase(oldID);
1742 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1747 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1748 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1749 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1751 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1753 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1754 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1755 ds->SetShape( newShape );
1760 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1761 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1763 // Remove groups and submeshes basing on removed sub-shapes
1765 TopTools_MapOfShape newShapeMap;
1766 TopoDS_Iterator shapeIt( newShape );
1767 for ( ; shapeIt.More(); shapeIt.Next() )
1768 newShapeMap.Add( shapeIt.Value() );
1770 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1771 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1773 if ( newShapeMap.Contains( shapeIt.Value() ))
1775 TopTools_IndexedMapOfShape oldShapeMap;
1776 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1777 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1779 const TopoDS_Shape& oldShape = oldShapeMap(i);
1780 int oldInd = meshDS->ShapeToIndex( oldShape );
1782 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1783 if ( i_smIor != _mapSubMeshIor.end() ) {
1784 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1787 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1788 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1790 // check if a group bases on oldInd shape
1791 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1792 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1793 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1794 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1796 RemoveGroup( i_grp->second ); // several groups can base on same shape
1797 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1802 // Reassign hypotheses and update groups after setting the new shape to mesh
1804 // collect anassigned hypotheses
1805 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1806 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1807 TShapeHypList assignedHyps;
1808 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1810 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1811 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1812 if ( !hyps.empty() ) {
1813 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1814 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1815 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1818 // collect shapes supporting groups
1819 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1820 TShapeTypeList groupData;
1821 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1822 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1823 for ( ; grIt != groups.end(); ++grIt )
1825 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1827 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1829 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1830 _impl->ShapeToMesh( newShape );
1832 // reassign hypotheses
1833 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1834 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1836 TIndexedShape& geom = indS_hyps->first;
1837 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1838 int oldID = geom._index;
1839 int newID = meshDS->ShapeToIndex( geom._shape );
1842 if ( oldID == 1 ) { // main shape
1844 geom._shape = newShape;
1846 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1847 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
1848 // care of submeshes
1849 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
1850 if ( newID != oldID ) {
1851 _mapSubMesh [ newID ] = newSubmesh;
1852 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1853 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1854 _mapSubMesh. erase(oldID);
1855 _mapSubMesh_i. erase(oldID);
1856 _mapSubMeshIor.erase(oldID);
1857 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1861 TShapeTypeList::iterator geomType = groupData.begin();
1862 for ( ; geomType != groupData.end(); ++geomType )
1864 const TIndexedShape& geom = geomType->first;
1865 int oldID = geom._index;
1866 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
1869 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
1870 CORBA::String_var name = groupSO->GetName();
1872 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
1874 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
1875 group_i->changeLocalId( newID );
1878 break; // everything has been updated
1881 } // loop on group data
1885 CORBA::Long newNbEntities = NbNodes() + NbElements();
1886 list< SALOMEDS::SObject_var > soToUpdateIcons;
1887 if ( newNbEntities != nbEntities )
1889 // Add all SObjects with icons
1890 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
1892 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
1893 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
1894 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
1896 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
1897 i_gr != _mapGroups.end(); ++i_gr ) // groups
1898 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
1901 list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin();
1902 for ( ; so != soToUpdateIcons.end(); ++so )
1903 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
1906 //=============================================================================
1908 * \brief Create standalone group instead if group on geometry
1910 //=============================================================================
1912 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupOnGeom_ptr theGroup )
1914 SMESH::SMESH_Group_var aGroup;
1915 if ( theGroup->_is_nil() )
1916 return aGroup._retn();
1918 Unexpect aCatch(SALOME_SalomeException);
1920 SMESH_GroupBase_i* aGroupToRem =
1921 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1923 return aGroup._retn();
1925 int anId = aGroupToRem->GetLocalID();
1926 if ( !_impl->ConvertToStandalone( anId ) )
1927 return aGroup._retn();
1928 removeGeomGroupData( theGroup );
1930 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
1932 // remove old instance of group from own map
1933 _mapGroups.erase( anId );
1935 SALOMEDS::StudyBuilder_var builder;
1936 SALOMEDS::SObject_var aGroupSO;
1937 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1938 if ( !aStudy->_is_nil() ) {
1939 builder = aStudy->NewBuilder();
1940 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1941 if ( !aGroupSO->_is_nil() ) {
1943 // remove reference to geometry
1944 SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO);
1945 for ( ; chItr->More(); chItr->Next() )
1946 // Remove group's child SObject
1947 builder->RemoveObject( chItr->Value() );
1949 // Update Python script
1950 TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
1951 << aGroupSO << " )";
1955 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1956 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
1957 aGroupImpl->Register();
1958 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1960 // remember new group in own map
1961 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
1962 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
1964 // register CORBA object for persistence
1965 /*int nextId =*/ _gen_i->RegisterObject( aGroup );
1967 builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) );
1969 return aGroup._retn();
1972 //=============================================================================
1976 //=============================================================================
1978 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
1980 if(MYDEBUG) MESSAGE( "createSubMesh" );
1981 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
1983 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
1984 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
1985 SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
1986 SMESH::SMESH_subMesh_var subMesh
1987 = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
1989 _mapSubMesh[subMeshId] = mySubMesh;
1990 _mapSubMesh_i[subMeshId] = subMeshServant;
1991 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
1993 // register CORBA object for persistence
1994 int nextId = _gen_i->RegisterObject( subMesh );
1995 if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
1997 // to track changes of GEOM groups
1998 addGeomGroupData( theSubShapeObject, subMesh );
2000 return subMesh._retn();
2003 //=======================================================================
2004 //function : getSubMesh
2006 //=======================================================================
2008 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2010 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2011 if ( it == _mapSubMeshIor.end() )
2012 return SMESH::SMESH_subMesh::_nil();
2014 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2018 //=============================================================================
2022 //=============================================================================
2024 void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2025 GEOM::GEOM_Object_ptr theSubShapeObject )
2027 MESSAGE("SMESH_Mesh_i::removeSubMesh()");
2028 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2031 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2033 CORBA::Long shapeId = theSubMesh->GetId();
2034 if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
2036 TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
2039 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2040 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2041 for ( ; hyp != hyps.end(); ++hyp )
2042 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2049 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2050 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2051 removeHypothesis( theSubShapeObject, aHypList[i] );
2054 catch( const SALOME::SALOME_Exception& ) {
2055 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2057 removeGeomGroupData( theSubShapeObject );
2059 int subMeshId = theSubMesh->GetId();
2061 _mapSubMesh.erase(subMeshId);
2062 _mapSubMesh_i.erase(subMeshId);
2063 _mapSubMeshIor.erase(subMeshId);
2064 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeSubMesh() completed");
2067 //=============================================================================
2071 //=============================================================================
2073 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2074 const char* theName,
2075 const TopoDS_Shape& theShape )
2077 std::string newName;
2078 if ( !theName || strlen( theName ) == 0 )
2080 std::set< std::string > presentNames;
2081 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2082 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2083 presentNames.insert( i_gr->second->GetName() );
2085 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2086 } while ( !presentNames.insert( newName ).second );
2087 theName = newName.c_str();
2090 SMESH::SMESH_GroupBase_var aGroup;
2091 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape )) {
2092 SMESH_GroupBase_i* aGroupImpl;
2093 if ( !theShape.IsNull() )
2094 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2096 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2098 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2099 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2100 aGroupImpl->Register();
2101 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2103 aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2104 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2106 // register CORBA object for persistence
2107 int nextId = _gen_i->RegisterObject( aGroup );
2108 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2110 // to track changes of GEOM groups
2111 if ( !theShape.IsNull() ) {
2112 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2113 addGeomGroupData( geom, aGroup );
2116 return aGroup._retn();
2119 //=============================================================================
2121 * SMESH_Mesh_i::removeGroup
2123 * Should be called by ~SMESH_Group_i()
2125 //=============================================================================
2127 void SMESH_Mesh_i::removeGroup( const int theId )
2129 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2130 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2131 SMESH::SMESH_GroupBase_ptr group = _mapGroups[theId];
2132 _mapGroups.erase( theId );
2133 removeGeomGroupData( group );
2134 if (! _impl->RemoveGroup( theId ))
2136 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2137 RemoveGroup( group );
2142 //=============================================================================
2146 //=============================================================================
2148 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2149 throw(SALOME::SALOME_Exception)
2151 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetLog");
2153 SMESH::log_array_var aLog;
2155 list < SMESHDS_Command * >logDS = _impl->GetLog();
2156 aLog = new SMESH::log_array;
2158 int lg = logDS.size();
2161 list < SMESHDS_Command * >::iterator its = logDS.begin();
2162 while(its != logDS.end()){
2163 SMESHDS_Command *com = *its;
2164 int comType = com->GetType();
2166 int lgcom = com->GetNumber();
2168 const list < int >&intList = com->GetIndexes();
2169 int inum = intList.size();
2171 list < int >::const_iterator ii = intList.begin();
2172 const list < double >&coordList = com->GetCoords();
2173 int rnum = coordList.size();
2175 list < double >::const_iterator ir = coordList.begin();
2176 aLog[indexLog].commandType = comType;
2177 aLog[indexLog].number = lgcom;
2178 aLog[indexLog].coords.length(rnum);
2179 aLog[indexLog].indexes.length(inum);
2180 for(int i = 0; i < rnum; i++){
2181 aLog[indexLog].coords[i] = *ir;
2182 //MESSAGE(" "<<i<<" "<<ir.Value());
2185 for(int i = 0; i < inum; i++){
2186 aLog[indexLog].indexes[i] = *ii;
2187 //MESSAGE(" "<<i<<" "<<ii.Value());
2196 catch(SALOME_Exception & S_ex){
2197 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
2199 return aLog._retn();
2203 //=============================================================================
2207 //=============================================================================
2209 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2211 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
2215 //=============================================================================
2219 //=============================================================================
2221 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2223 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
2227 //=============================================================================
2231 //=============================================================================
2233 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2238 //=============================================================================
2241 //!< implementation of struct used to call SMESH_Mesh_i::removeGroup() from
2242 // SMESH_Mesh::RemoveGroup() (issue 0020918)
2243 struct TRmGroupCallUp_i : public SMESH_Mesh::TRmGroupCallUp
2245 SMESH_Mesh_i* _mesh;
2246 TRmGroupCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2247 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2251 //=============================================================================
2255 //=============================================================================
2257 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2259 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2262 _impl->SetRemoveGroupCallUp( new TRmGroupCallUp_i(this));
2265 //=============================================================================
2269 //=============================================================================
2271 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2273 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2277 //=============================================================================
2279 * Return mesh editor
2281 //=============================================================================
2283 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2285 // Create MeshEditor
2286 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
2287 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2289 // Update Python script
2290 TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
2292 return aMesh._retn();
2295 //=============================================================================
2297 * Return mesh edition previewer
2299 //=============================================================================
2301 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2303 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
2304 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2305 return aMesh._retn();
2308 //================================================================================
2310 * \brief Return true if the mesh has been edited since a last total re-compute
2311 * and those modifications may prevent successful partial re-compute
2313 //================================================================================
2315 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2317 Unexpect aCatch(SALOME_SalomeException);
2318 return _impl->HasModificationsToDiscard();
2321 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2323 const int MAX_ATTEMPTS = 100;
2325 double tolerance = 0.5;
2326 SALOMEDS::Color col;
2330 // generate random color
2331 double red = (double)rand() / RAND_MAX;
2332 double green = (double)rand() / RAND_MAX;
2333 double blue = (double)rand() / RAND_MAX;
2334 // check existence in the list of the existing colors
2335 bool matched = false;
2336 std::list<SALOMEDS::Color>::const_iterator it;
2337 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2338 SALOMEDS::Color color = *it;
2339 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2340 matched = tol < tolerance;
2342 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2343 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2351 //=============================================================================
2355 //=============================================================================
2356 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2358 Unexpect aCatch(SALOME_SalomeException);
2359 _impl->SetAutoColor(theAutoColor);
2361 TPythonDump pyDump; // not to dump group->SetColor() from below code
2362 pyDump<<_this()<<".SetAutoColor( "<<theAutoColor<<" )";
2364 std::list<SALOMEDS::Color> aReservedColors;
2365 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2366 for ( ; it != _mapGroups.end(); it++ ) {
2367 if ( CORBA::is_nil( it->second )) continue;
2368 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2369 it->second->SetColor( aColor );
2370 aReservedColors.push_back( aColor );
2374 //=============================================================================
2378 //=============================================================================
2379 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2381 Unexpect aCatch(SALOME_SalomeException);
2382 return _impl->GetAutoColor();
2386 //=============================================================================
2388 * Export in different formats
2390 //=============================================================================
2392 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2394 return _impl->HasDuplicatedGroupNamesMED();
2397 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2399 TCollection_AsciiString aFullName ((char*)file);
2400 OSD_Path aPath (aFullName);
2401 OSD_File aFile (aPath);
2402 if (aFile.Exists()) {
2403 // existing filesystem node
2404 if (aFile.KindOfFile() == OSD_FILE) {
2405 if (aFile.IsWriteable()) {
2410 if (aFile.Failed()) {
2411 TCollection_AsciiString msg ("File ");
2412 msg += aFullName + " cannot be replaced.";
2413 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2416 TCollection_AsciiString msg ("File ");
2417 msg += aFullName + " cannot be overwritten.";
2418 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2421 TCollection_AsciiString msg ("Location ");
2422 msg += aFullName + " is not a file.";
2423 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2426 // nonexisting file; check if it can be created
2428 aFile.Build(OSD_WriteOnly, OSD_Protection());
2429 if (aFile.Failed()) {
2430 TCollection_AsciiString msg ("You cannot create the file ");
2431 msg += aFullName + ". Check the directory existance and access rights.";
2432 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2440 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2441 CORBA::Boolean auto_groups,
2442 SMESH::MED_VERSION theVersion,
2443 CORBA::Boolean overwrite)
2444 throw(SALOME::SALOME_Exception)
2446 Unexpect aCatch(SALOME_SalomeException);
2449 PrepareForWriting(file, overwrite);
2450 string aMeshName = "Mesh";
2451 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2452 if ( !aStudy->_is_nil() ) {
2453 SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2454 if ( !aMeshSO->_is_nil() ) {
2455 CORBA::String_var name = aMeshSO->GetName();
2457 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2458 if ( !aStudy->GetProperties()->IsLocked() )
2460 SALOMEDS::GenericAttribute_var anAttr;
2461 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2462 SALOMEDS::AttributeExternalFileDef_var aFileName;
2463 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2464 aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
2465 ASSERT(!aFileName->_is_nil());
2466 aFileName->SetValue(file);
2467 SALOMEDS::AttributeFileType_var aFileType;
2468 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2469 aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
2470 ASSERT(!aFileType->_is_nil());
2471 aFileType->SetValue("FICHIERMED");
2475 // Update Python script
2476 // set name of mesh before export
2477 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName.c_str() << "')";
2479 // check names of groups
2482 TPythonDump() << _this() << ".ExportToMEDX( r'"
2483 << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )";
2485 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion );
2488 //================================================================================
2490 * \brief Export a mesh to a med file
2492 //================================================================================
2494 void SMESH_Mesh_i::ExportToMED (const char* file,
2495 CORBA::Boolean auto_groups,
2496 SMESH::MED_VERSION theVersion)
2497 throw(SALOME::SALOME_Exception)
2499 ExportToMEDX(file,auto_groups,theVersion,true);
2502 //================================================================================
2504 * \brief Export a mesh to a med file
2506 //================================================================================
2508 void SMESH_Mesh_i::ExportMED (const char* file,
2509 CORBA::Boolean auto_groups)
2510 throw(SALOME::SALOME_Exception)
2512 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
2515 //================================================================================
2517 * \brief Export a mesh to a DAT file
2519 //================================================================================
2521 void SMESH_Mesh_i::ExportDAT (const char *file)
2522 throw(SALOME::SALOME_Exception)
2524 Unexpect aCatch(SALOME_SalomeException);
2526 // Update Python script
2527 // check names of groups
2529 TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )";
2532 PrepareForWriting(file);
2533 _impl->ExportDAT(file);
2536 //================================================================================
2538 * \brief Export a mesh to an UNV file
2540 //================================================================================
2542 void SMESH_Mesh_i::ExportUNV (const char *file)
2543 throw(SALOME::SALOME_Exception)
2545 Unexpect aCatch(SALOME_SalomeException);
2547 // Update Python script
2548 // check names of groups
2550 TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )";
2553 PrepareForWriting(file);
2554 _impl->ExportUNV(file);
2557 //================================================================================
2559 * \brief Export a mesh to an STL file
2561 //================================================================================
2563 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2564 throw(SALOME::SALOME_Exception)
2566 Unexpect aCatch(SALOME_SalomeException);
2568 // Update Python script
2569 // check names of groups
2571 TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )";
2574 PrepareForWriting(file);
2575 _impl->ExportSTL(file, isascii);
2578 //=============================================================================
2580 * \brief Class providing SMESHDS_Mesh API to SMESH_IDSource.
2581 * It is used to export a part of mesh as a whole mesh.
2583 class SMESH_MeshPartDS : public SMESHDS_Mesh
2586 SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart);
2588 virtual SMDS_NodeIteratorPtr nodesIterator (bool idInceasingOrder=false) const;
2589 virtual SMDS_0DElementIteratorPtr elements0dIterator(bool idInceasingOrder=false) const;
2590 virtual SMDS_EdgeIteratorPtr edgesIterator (bool idInceasingOrder=false) const;
2591 virtual SMDS_FaceIteratorPtr facesIterator (bool idInceasingOrder=false) const;
2592 virtual SMDS_VolumeIteratorPtr volumesIterator (bool idInceasingOrder=false) const;
2594 virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type=SMDSAbs_All) const;
2597 TIDSortedElemSet _elements[ SMDSAbs_NbElementTypes ];
2598 SMESHDS_Mesh* _meshDS;
2600 * \brief Class used to access to protected data of SMDS_MeshInfo
2602 struct TMeshInfo : public SMDS_MeshInfo
2604 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
2608 //================================================================================
2610 * \brief Export a part of mesh to a med file
2612 //================================================================================
2614 void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart,
2616 CORBA::Boolean auto_groups,
2617 ::SMESH::MED_VERSION version,
2618 ::CORBA::Boolean overwrite)
2619 throw (SALOME::SALOME_Exception)
2621 Unexpect aCatch(SALOME_SalomeException);
2623 PrepareForWriting(file, overwrite);
2625 string aMeshName = "Mesh";
2626 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2627 if ( !aStudy->_is_nil() ) {
2628 SALOMEDS::SObject_var SO = _gen_i->ObjectToSObject( aStudy, meshPart );
2629 if ( !SO->_is_nil() ) {
2630 CORBA::String_var name = SO->GetName();
2634 SMESH_MeshPartDS partDS( meshPart );
2635 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, &partDS );
2637 TPythonDump() << _this() << ".ExportPartToMED( " << meshPart << ", r'" << file << "', "
2638 << auto_groups << ", " << version << ", " << overwrite << " )";
2641 //================================================================================
2643 * \brief Export a part of mesh to a DAT file
2645 //================================================================================
2647 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
2649 throw (SALOME::SALOME_Exception)
2651 Unexpect aCatch(SALOME_SalomeException);
2653 PrepareForWriting(file);
2655 SMESH_MeshPartDS partDS( meshPart );
2656 _impl->ExportDAT(file,&partDS);
2658 TPythonDump() << _this() << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
2660 //================================================================================
2662 * \brief Export a part of mesh to an UNV file
2664 //================================================================================
2666 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
2668 throw (SALOME::SALOME_Exception)
2670 Unexpect aCatch(SALOME_SalomeException);
2672 PrepareForWriting(file);
2674 SMESH_MeshPartDS partDS( meshPart );
2675 _impl->ExportUNV(file, &partDS);
2677 TPythonDump() << _this() << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
2679 //================================================================================
2681 * \brief Export a part of mesh to an STL file
2683 //================================================================================
2685 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
2687 ::CORBA::Boolean isascii)
2688 throw (SALOME::SALOME_Exception)
2690 Unexpect aCatch(SALOME_SalomeException);
2692 PrepareForWriting(file);
2694 SMESH_MeshPartDS partDS( meshPart );
2695 _impl->ExportSTL(file, isascii, &partDS);
2697 TPythonDump() << _this() << ".ExportPartToSTL( "
2698 << meshPart<< ", r'" << file << "', " << isascii << ")";
2701 //=============================================================================
2705 //=============================================================================
2707 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
2709 Unexpect aCatch(SALOME_SalomeException);
2710 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
2711 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
2712 return aMesh._retn();
2715 //=============================================================================
2719 //=============================================================================
2720 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
2722 Unexpect aCatch(SALOME_SalomeException);
2723 return _impl->NbNodes();
2726 //=============================================================================
2730 //=============================================================================
2731 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
2733 Unexpect aCatch(SALOME_SalomeException);
2734 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes();
2737 //=============================================================================
2741 //=============================================================================
2742 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
2744 Unexpect aCatch(SALOME_SalomeException);
2745 return _impl->Nb0DElements();
2748 //=============================================================================
2752 //=============================================================================
2753 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
2755 Unexpect aCatch(SALOME_SalomeException);
2756 return _impl->NbEdges();
2759 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
2760 throw(SALOME::SALOME_Exception)
2762 Unexpect aCatch(SALOME_SalomeException);
2763 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
2766 //=============================================================================
2770 //=============================================================================
2771 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
2773 Unexpect aCatch(SALOME_SalomeException);
2774 return _impl->NbFaces();
2777 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
2779 Unexpect aCatch(SALOME_SalomeException);
2780 return _impl->NbTriangles();
2783 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
2785 Unexpect aCatch(SALOME_SalomeException);
2786 return _impl->NbQuadrangles();
2789 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
2791 Unexpect aCatch(SALOME_SalomeException);
2792 return _impl->NbPolygons();
2795 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
2796 throw(SALOME::SALOME_Exception)
2798 Unexpect aCatch(SALOME_SalomeException);
2799 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
2802 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
2803 throw(SALOME::SALOME_Exception)
2805 Unexpect aCatch(SALOME_SalomeException);
2806 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
2809 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
2810 throw(SALOME::SALOME_Exception)
2812 Unexpect aCatch(SALOME_SalomeException);
2813 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
2816 //=============================================================================
2820 //=============================================================================
2821 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
2823 Unexpect aCatch(SALOME_SalomeException);
2824 return _impl->NbVolumes();
2827 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
2829 Unexpect aCatch(SALOME_SalomeException);
2830 return _impl->NbTetras();
2833 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
2835 Unexpect aCatch(SALOME_SalomeException);
2836 return _impl->NbHexas();
2839 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
2841 Unexpect aCatch(SALOME_SalomeException);
2842 return _impl->NbPyramids();
2845 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
2847 Unexpect aCatch(SALOME_SalomeException);
2848 return _impl->NbPrisms();
2851 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
2853 Unexpect aCatch(SALOME_SalomeException);
2854 return _impl->NbPolyhedrons();
2857 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
2858 throw(SALOME::SALOME_Exception)
2860 Unexpect aCatch(SALOME_SalomeException);
2861 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
2864 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
2865 throw(SALOME::SALOME_Exception)
2867 Unexpect aCatch(SALOME_SalomeException);
2868 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
2871 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
2872 throw(SALOME::SALOME_Exception)
2874 Unexpect aCatch(SALOME_SalomeException);
2875 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
2878 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
2879 throw(SALOME::SALOME_Exception)
2881 Unexpect aCatch(SALOME_SalomeException);
2882 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
2885 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
2886 throw(SALOME::SALOME_Exception)
2888 Unexpect aCatch(SALOME_SalomeException);
2889 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
2892 //=============================================================================
2896 //=============================================================================
2897 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
2899 Unexpect aCatch(SALOME_SalomeException);
2900 return _mapSubMesh_i.size();
2903 //=============================================================================
2907 //=============================================================================
2908 char* SMESH_Mesh_i::Dump()
2912 return CORBA::string_dup( os.str().c_str() );
2915 //=============================================================================
2919 //=============================================================================
2920 SMESH::long_array* SMESH_Mesh_i::GetIDs()
2922 // SMESH::long_array_var aResult = new SMESH::long_array();
2923 // SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2924 // int aMinId = aSMESHDS_Mesh->MinElementID();
2925 // int aMaxId = aSMESHDS_Mesh->MaxElementID();
2927 // aResult->length(aMaxId - aMinId + 1);
2929 // for (int i = 0, id = aMinId; id <= aMaxId; id++ )
2930 // aResult[i++] = id;
2932 // return aResult._retn();
2934 return GetElementsId();
2937 //=============================================================================
2941 //=============================================================================
2943 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
2944 throw (SALOME::SALOME_Exception)
2946 Unexpect aCatch(SALOME_SalomeException);
2947 MESSAGE("SMESH_Mesh_i::GetElementsId");
2948 SMESH::long_array_var aResult = new SMESH::long_array();
2949 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2951 if ( aSMESHDS_Mesh == NULL )
2952 return aResult._retn();
2954 long nbElements = NbElements();
2955 aResult->length( nbElements );
2956 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2957 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
2958 aResult[i] = anIt->next()->GetID();
2960 return aResult._retn();
2964 //=============================================================================
2968 //=============================================================================
2970 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
2971 throw (SALOME::SALOME_Exception)
2973 Unexpect aCatch(SALOME_SalomeException);
2974 MESSAGE("SMESH_subMesh_i::GetElementsByType");
2975 SMESH::long_array_var aResult = new SMESH::long_array();
2976 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2978 if ( aSMESHDS_Mesh == NULL )
2979 return aResult._retn();
2981 long nbElements = NbElements();
2983 // No sense in returning ids of elements along with ids of nodes:
2984 // when theElemType == SMESH::ALL, return node ids only if
2985 // there are no elements
2986 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
2987 return GetNodesId();
2989 aResult->length( nbElements );
2993 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2994 while ( i < nbElements && anIt->more() ) {
2995 const SMDS_MeshElement* anElem = anIt->next();
2996 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
2997 aResult[i++] = anElem->GetID();
3000 aResult->length( i );
3002 return aResult._retn();
3005 //=============================================================================
3009 //=============================================================================
3011 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3012 throw (SALOME::SALOME_Exception)
3014 Unexpect aCatch(SALOME_SalomeException);
3015 MESSAGE("SMESH_subMesh_i::GetNodesId");
3016 SMESH::long_array_var aResult = new SMESH::long_array();
3017 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3019 if ( aSMESHDS_Mesh == NULL )
3020 return aResult._retn();
3022 long nbNodes = NbNodes();
3023 aResult->length( nbNodes );
3024 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3025 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3026 aResult[i] = anIt->next()->GetID();
3028 return aResult._retn();
3031 //=============================================================================
3035 //=============================================================================
3037 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3038 throw (SALOME::SALOME_Exception)
3040 return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
3043 //=============================================================================
3047 //=============================================================================
3049 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3050 throw (SALOME::SALOME_Exception)
3052 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3054 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3056 return ( SMESH::EntityType ) e->GetEntityType();
3059 //=============================================================================
3061 * Returns ID of elements for given submesh
3063 //=============================================================================
3064 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3065 throw (SALOME::SALOME_Exception)
3067 SMESH::long_array_var aResult = new SMESH::long_array();
3069 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3070 if(!SM) return aResult._retn();
3072 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3073 if(!SDSM) return aResult._retn();
3075 aResult->length(SDSM->NbElements());
3077 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3079 while ( eIt->more() ) {
3080 aResult[i++] = eIt->next()->GetID();
3083 return aResult._retn();
3087 //=============================================================================
3089 * Returns ID of nodes for given submesh
3090 * If param all==true - returns all nodes, else -
3091 * returns only nodes on shapes.
3093 //=============================================================================
3094 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all)
3095 throw (SALOME::SALOME_Exception)
3097 SMESH::long_array_var aResult = new SMESH::long_array();
3099 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3100 if(!SM) return aResult._retn();
3102 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3103 if(!SDSM) return aResult._retn();
3106 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
3107 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
3108 while ( nIt->more() ) {
3109 const SMDS_MeshNode* elem = nIt->next();
3110 theElems.insert( elem->GetID() );
3113 else { // all nodes of submesh elements
3114 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3115 while ( eIt->more() ) {
3116 const SMDS_MeshElement* anElem = eIt->next();
3117 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
3118 while ( nIt->more() ) {
3119 const SMDS_MeshElement* elem = nIt->next();
3120 theElems.insert( elem->GetID() );
3125 aResult->length(theElems.size());
3126 set<int>::iterator itElem;
3128 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
3129 aResult[i++] = *itElem;
3131 return aResult._retn();
3135 //=============================================================================
3137 * Returns type of elements for given submesh
3139 //=============================================================================
3140 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
3141 throw (SALOME::SALOME_Exception)
3143 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3144 if(!SM) return SMESH::ALL;
3146 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3147 if(!SDSM) return SMESH::ALL;
3149 if(SDSM->NbElements()==0)
3150 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
3152 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3153 const SMDS_MeshElement* anElem = eIt->next();
3154 return ( SMESH::ElementType ) anElem->GetType();
3158 //=============================================================================
3162 //=============================================================================
3164 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
3166 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
3168 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
3173 //=============================================================================
3175 * Get XYZ coordinates of node as list of double
3176 * If there is not node for given ID - returns empty list
3178 //=============================================================================
3180 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
3182 SMESH::double_array_var aResult = new SMESH::double_array();
3183 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3184 if ( aSMESHDS_Mesh == NULL )
3185 return aResult._retn();
3188 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3190 return aResult._retn();
3194 aResult[0] = aNode->X();
3195 aResult[1] = aNode->Y();
3196 aResult[2] = aNode->Z();
3197 return aResult._retn();
3201 //=============================================================================
3203 * For given node returns list of IDs of inverse elements
3204 * If there is not node for given ID - returns empty list
3206 //=============================================================================
3208 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
3210 SMESH::long_array_var aResult = new SMESH::long_array();
3211 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3212 if ( aSMESHDS_Mesh == NULL )
3213 return aResult._retn();
3216 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3218 return aResult._retn();
3220 // find inverse elements
3221 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
3222 TColStd_SequenceOfInteger IDs;
3223 while(eIt->more()) {
3224 const SMDS_MeshElement* elem = eIt->next();
3225 IDs.Append(elem->GetID());
3227 if(IDs.Length()>0) {
3228 aResult->length(IDs.Length());
3230 for(; i<=IDs.Length(); i++) {
3231 aResult[i-1] = IDs.Value(i);
3234 return aResult._retn();
3237 //=============================================================================
3239 * \brief Return position of a node on shape
3241 //=============================================================================
3243 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
3245 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
3246 aNodePosition->shapeID = 0;
3247 aNodePosition->shapeType = GEOM::SHAPE;
3249 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3250 if ( !mesh ) return aNodePosition;
3252 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
3254 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
3256 aNodePosition->shapeID = aNode->getshapeId();
3257 switch ( pos->GetTypeOfPosition() ) {
3259 aNodePosition->shapeType = GEOM::EDGE;
3260 aNodePosition->params.length(1);
3261 aNodePosition->params[0] =
3262 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
3265 aNodePosition->shapeType = GEOM::FACE;
3266 aNodePosition->params.length(2);
3267 aNodePosition->params[0] =
3268 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
3269 aNodePosition->params[1] =
3270 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
3272 case SMDS_TOP_VERTEX:
3273 aNodePosition->shapeType = GEOM::VERTEX;
3275 case SMDS_TOP_3DSPACE:
3276 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3277 aNodePosition->shapeType = GEOM::SOLID;
3278 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3279 aNodePosition->shapeType = GEOM::SHELL;
3285 return aNodePosition;
3288 //=============================================================================
3290 * If given element is node returns IDs of shape from position
3291 * If there is not node for given ID - returns -1
3293 //=============================================================================
3295 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3297 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3298 if ( aSMESHDS_Mesh == NULL )
3302 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3304 return aNode->getshapeId();
3311 //=============================================================================
3313 * For given element returns ID of result shape after
3314 * ::FindShape() from SMESH_MeshEditor
3315 * If there is not element for given ID - returns -1
3317 //=============================================================================
3319 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3321 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3322 if ( aSMESHDS_Mesh == NULL )
3325 // try to find element
3326 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3330 //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
3331 ::SMESH_MeshEditor aMeshEditor(_impl);
3332 int index = aMeshEditor.FindShape( elem );
3340 //=============================================================================
3342 * Returns number of nodes for given element
3343 * If there is not element for given ID - returns -1
3345 //=============================================================================
3347 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3349 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3350 if ( aSMESHDS_Mesh == NULL ) return -1;
3351 // try to find element
3352 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3353 if(!elem) return -1;
3354 return elem->NbNodes();
3358 //=============================================================================
3360 * Returns ID of node by given index for given element
3361 * If there is not element for given ID - returns -1
3362 * If there is not node for given index - returns -2
3364 //=============================================================================
3366 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3368 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3369 if ( aSMESHDS_Mesh == NULL ) return -1;
3370 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3371 if(!elem) return -1;
3372 if( index>=elem->NbNodes() || index<0 ) return -1;
3373 return elem->GetNode(index)->GetID();
3376 //=============================================================================
3378 * Returns IDs of nodes of given element
3380 //=============================================================================
3382 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3384 SMESH::long_array_var aResult = new SMESH::long_array();
3385 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3387 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3389 aResult->length( elem->NbNodes() );
3390 for ( int i = 0; i < elem->NbNodes(); ++i )
3391 aResult[ i ] = elem->GetNode( i )->GetID();
3394 return aResult._retn();
3397 //=============================================================================
3399 * Returns true if given node is medium node
3400 * in given quadratic element
3402 //=============================================================================
3404 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3406 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3407 if ( aSMESHDS_Mesh == NULL ) return false;
3409 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3410 if(!aNode) return false;
3411 // try to find element
3412 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3413 if(!elem) return false;
3415 return elem->IsMediumNode(aNode);
3419 //=============================================================================
3421 * Returns true if given node is medium node
3422 * in one of quadratic elements
3424 //=============================================================================
3426 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3427 SMESH::ElementType theElemType)
3429 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3430 if ( aSMESHDS_Mesh == NULL ) return false;
3433 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3434 if(!aNode) return false;
3436 SMESH_MesherHelper aHelper( *(_impl) );
3438 SMDSAbs_ElementType aType;
3439 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3440 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3441 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3442 else aType = SMDSAbs_All;
3444 return aHelper.IsMedium(aNode,aType);
3448 //=============================================================================
3450 * Returns number of edges for given element
3452 //=============================================================================
3454 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3456 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3457 if ( aSMESHDS_Mesh == NULL ) return -1;
3458 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3459 if(!elem) return -1;
3460 return elem->NbEdges();
3464 //=============================================================================
3466 * Returns number of faces for given element
3468 //=============================================================================
3470 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3472 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3473 if ( aSMESHDS_Mesh == NULL ) return -1;
3474 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3475 if(!elem) return -1;
3476 return elem->NbFaces();
3479 //=======================================================================
3480 //function : GetElemFaceNodes
3481 //purpose : Returns nodes of given face (counted from zero) for given element.
3482 //=======================================================================
3484 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
3485 CORBA::Short faceIndex)
3487 SMESH::long_array_var aResult = new SMESH::long_array();
3488 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3490 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
3492 SMDS_VolumeTool vtool( elem );
3493 if ( faceIndex < vtool.NbFaces() )
3495 aResult->length( vtool.NbFaceNodes( faceIndex ));
3496 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
3497 for ( int i = 0; i < aResult->length(); ++i )
3498 aResult[ i ] = nn[ i ]->GetID();
3502 return aResult._retn();
3505 //=======================================================================
3506 //function : FindElementByNodes
3507 //purpose : Returns an element based on all given nodes.
3508 //=======================================================================
3510 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
3512 CORBA::Long elemID(0);
3513 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
3515 vector< const SMDS_MeshNode * > nn( nodes.length() );
3516 for ( int i = 0; i < nodes.length(); ++i )
3517 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
3520 const SMDS_MeshElement* elem = mesh->FindElement( nn );
3521 if ( !elem && ( _impl->NbEdges( ORDER_QUADRATIC ) ||
3522 _impl->NbFaces( ORDER_QUADRATIC ) ||
3523 _impl->NbVolumes( ORDER_QUADRATIC )))
3524 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
3526 if ( elem ) elemID = CORBA::Long( elem->GetID() );
3531 //=============================================================================
3533 * Returns true if given element is polygon
3535 //=============================================================================
3537 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
3539 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3540 if ( aSMESHDS_Mesh == NULL ) return false;
3541 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3542 if(!elem) return false;
3543 return elem->IsPoly();
3547 //=============================================================================
3549 * Returns true if given element is quadratic
3551 //=============================================================================
3553 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
3555 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3556 if ( aSMESHDS_Mesh == NULL ) return false;
3557 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3558 if(!elem) return false;
3559 return elem->IsQuadratic();
3563 //=============================================================================
3565 * Returns bary center for given element
3567 //=============================================================================
3569 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
3571 SMESH::double_array_var aResult = new SMESH::double_array();
3572 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3573 if ( aSMESHDS_Mesh == NULL )
3574 return aResult._retn();
3576 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3578 return aResult._retn();
3580 if(elem->GetType()==SMDSAbs_Volume) {
3581 SMDS_VolumeTool aTool;
3582 if(aTool.Set(elem)) {
3584 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
3589 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
3591 double x=0., y=0., z=0.;
3592 for(; anIt->more(); ) {
3594 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
3608 return aResult._retn();
3612 //=============================================================================
3614 * Create and publish group servants if any groups were imported or created anyhow
3616 //=============================================================================
3618 void SMESH_Mesh_i::CreateGroupServants()
3620 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3623 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
3624 while ( groupIt->more() )
3626 ::SMESH_Group* group = groupIt->next();
3627 int anId = group->GetGroupDS()->GetID();
3629 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
3630 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3632 addedIDs.insert( anId );
3634 SMESH_GroupBase_i* aGroupImpl;
3636 if ( SMESHDS_GroupOnGeom* groupOnGeom =
3637 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
3639 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3640 shape = groupOnGeom->GetShape();
3643 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3646 // To ensure correct mapping of servant and correct reference counting in GenericObj_i
3647 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
3648 aGroupImpl->Register();
3650 SMESH::SMESH_GroupBase_var groupVar =
3651 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
3652 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
3654 // register CORBA object for persistence
3655 int nextId = _gen_i->RegisterObject( groupVar );
3656 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
3658 // publishing the groups in the study
3659 if ( !aStudy->_is_nil() ) {
3660 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
3661 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
3664 if ( !addedIDs.empty() )
3667 set<int>::iterator id = addedIDs.begin();
3668 for ( ; id != addedIDs.end(); ++id )
3670 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
3671 int i = std::distance( _mapGroups.begin(), it );
3672 TPythonDump() << it->second << " = " << _this() << ".GetGroups()[ "<< i << " ]";
3677 //=============================================================================
3679 * \brief Return groups cantained in _mapGroups by their IDs
3681 //=============================================================================
3683 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
3685 int nbGroups = groupIDs.size();
3686 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
3687 aList->length( nbGroups );
3689 list<int>::const_iterator ids = groupIDs.begin();
3690 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
3692 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
3693 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3694 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
3696 aList->length( nbGroups );
3697 return aList._retn();
3700 //=============================================================================
3702 * \brief Return information about imported file
3704 //=============================================================================
3706 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
3708 SALOME_MED::MedFileInfo_var res( myFileInfo );
3709 if ( !res.operator->() ) {
3710 res = new SALOME_MED::MedFileInfo;
3712 res->fileSize = res->major = res->minor = res->release = -1;
3717 //=============================================================================
3719 * \brief Check and correct names of mesh groups
3721 //=============================================================================
3723 void SMESH_Mesh_i::checkGroupNames()
3725 int nbGrp = NbGroups();
3729 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3730 if ( aStudy->_is_nil() )
3731 return; // nothing to do
3733 SMESH::ListOfGroups* grpList = 0;
3734 // avoid dump of "GetGroups"
3736 // store python dump into a local variable inside local scope
3737 SMESH::TPythonDump pDump; // do not delete this line of code
3738 grpList = GetGroups();
3741 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
3742 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
3745 SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
3746 if ( aGrpSO->_is_nil() )
3748 // correct name of the mesh group if necessary
3749 const char* guiName = aGrpSO->GetName();
3750 if ( strcmp(guiName, aGrp->GetName()) )
3751 aGrp->SetName( guiName );
3755 //=============================================================================
3757 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
3759 //=============================================================================
3760 void SMESH_Mesh_i::SetParameters(const char* theParameters)
3762 SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
3763 CORBA::string_dup(theParameters));
3766 //=============================================================================
3768 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
3770 //=============================================================================
3771 char* SMESH_Mesh_i::GetParameters()
3773 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3774 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
3777 //=============================================================================
3779 * \brief Returns list of notebook variables used for last Mesh operation
3781 //=============================================================================
3782 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
3784 SMESH::string_array_var aResult = new SMESH::string_array();
3785 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3787 char *aParameters = GetParameters();
3788 SALOMEDS::Study_ptr aStudy = gen->GetCurrentStudy();
3789 if(!aStudy->_is_nil()) {
3790 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
3791 if(aSections->length() > 0) {
3792 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
3793 aResult->length(aVars.length());
3794 for(int i = 0;i < aVars.length();i++)
3795 aResult[i] = CORBA::string_dup( aVars[i]);
3799 return aResult._retn();
3802 //=======================================================================
3803 //function : GetTypes
3804 //purpose : Returns types of elements it contains
3805 //=======================================================================
3807 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
3809 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
3813 if (_impl->NbEdges())
3814 types[nbTypes++] = SMESH::EDGE;
3815 if (_impl->NbFaces())
3816 types[nbTypes++] = SMESH::FACE;
3817 if (_impl->NbVolumes())
3818 types[nbTypes++] = SMESH::VOLUME;
3819 if (_impl->Nb0DElements())
3820 types[nbTypes++] = SMESH::ELEM0D;
3821 types->length( nbTypes );
3823 return types._retn();
3826 //=======================================================================
3827 //function : GetMesh
3828 //purpose : Returns self
3829 //=======================================================================
3831 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
3833 return SMESH::SMESH_Mesh::_duplicate( _this() );
3836 //=============================================================================
3838 * \brief Returns statistic of mesh elements
3840 //=============================================================================
3841 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
3843 SMESH::long_array_var aRes = new SMESH::long_array();
3844 aRes->length(SMESH::Entity_Last);
3845 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3847 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3849 return aRes._retn();
3850 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
3851 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3852 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
3853 return aRes._retn();
3856 //=============================================================================
3858 * \brief Collect statistic of mesh elements given by iterator
3860 //=============================================================================
3861 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
3862 SMESH::long_array& theInfo)
3864 if (!theItr) return;
3865 while (theItr->more())
3866 theInfo[ theItr->next()->GetEntityType() ]++;
3869 //=============================================================================
3871 * \brief mapping of mesh dimension into shape type
3873 //=============================================================================
3874 static TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
3876 TopAbs_ShapeEnum aType = TopAbs_SOLID;
3878 case 0: aType = TopAbs_VERTEX; break;
3879 case 1: aType = TopAbs_EDGE; break;
3880 case 2: aType = TopAbs_FACE; break;
3882 default:aType = TopAbs_SOLID; break;
3887 //=============================================================================
3889 * \brief Internal structure used to find concurent submeshes
3891 * It represents a pair < submesh, concurent dimension >, where
3892 * 'concurrent dimension' is dimension of shape where the submesh can concurent
3893 * with another submesh. In other words, it is dimension of a hypothesis assigned
3896 //=============================================================================
3902 int _dim; //!< a dimension the algo can build (concurrent dimension)
3903 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
3904 TopTools_MapOfShape _shapeMap;
3905 SMESH_subMesh* _subMesh;
3906 list<const SMESHDS_Hypothesis*> _hypothesises; //!< algo is first, then its parameters
3909 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
3911 const TopoDS_Shape& theShape)
3913 _subMesh = (SMESH_subMesh*)theSubMesh;
3914 SetShape( theDim, theShape );
3918 void SetShape(const int theDim,
3919 const TopoDS_Shape& theShape)
3922 _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
3923 if (_dim >= _ownDim)
3924 _shapeMap.Add( theShape );
3926 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
3927 for( ; anExp.More(); anExp.Next() )
3928 _shapeMap.Add( anExp.Current() );
3932 //! Check sharing of sub shapes
3933 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
3934 const TopTools_MapOfShape& theToFind,
3935 const TopAbs_ShapeEnum theType)
3937 bool isShared = false;
3938 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
3939 for (; !isShared && anItr.More(); anItr.Next() ) {
3940 const TopoDS_Shape aSubSh = anItr.Key();
3941 // check for case when concurrent dimensions are same
3942 isShared = theToFind.Contains( aSubSh );
3943 // check for subshape with concurrent dimension
3944 TopExp_Explorer anExp( aSubSh, theType );
3945 for ( ; !isShared && anExp.More(); anExp.Next() )
3946 isShared = theToFind.Contains( anExp.Current() );
3951 //! check algorithms
3952 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
3953 const SMESHDS_Hypothesis* theA2)
3955 if ( theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
3956 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
3957 return false; // one of the hypothesis is not algorithm
3958 // check algorithm names (should be equal)
3959 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
3963 //! Check if subshape hypotheses are concurrent
3964 bool IsConcurrent(const SMESH_DimHyp* theOther) const
3966 if ( _subMesh == theOther->_subMesh )
3967 return false; // same subshape - should not be
3969 // if ( <own dim of either of submeshes> == <concurrent dim> &&
3970 // any of the two submeshes is not on COMPOUND shape )
3971 // -> no concurrency
3972 bool meIsCompound = (_subMesh->GetSubMeshDS() && _subMesh->GetSubMeshDS()->IsComplexSubmesh());
3973 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() && theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
3974 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
3977 // bool checkSubShape = ( _dim >= theOther->_dim )
3978 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
3979 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
3980 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
3981 if ( !checkSubShape )
3984 // check algorithms to be same
3985 if (!checkAlgo( _hypothesises.front(), theOther->_hypothesises.front() ))
3986 return true; // different algorithms
3988 // check hypothesises for concurrence (skip first as algorithm)
3990 // pointers should be same, becase it is referenes from mesh hypothesis partition
3991 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypothesises.begin();
3992 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypothesises.end();
3993 for ( hypIt++ /*skip first as algo*/; hypIt != _hypothesises.end(); hypIt++ )
3994 if ( find( theOther->_hypothesises.begin(), otheEndIt, *hypIt ) != otheEndIt )
3996 // the submeshes are concurrent if their algorithms has different parameters
3997 return nbSame != theOther->_hypothesises.size() - 1;
4000 }; // end of SMESH_DimHyp
4002 typedef list<SMESH_DimHyp*> TDimHypList;
4004 static void addDimHypInstance(const int theDim,
4005 const TopoDS_Shape& theShape,
4006 const SMESH_Algo* theAlgo,
4007 const SMESH_subMesh* theSubMesh,
4008 const list <const SMESHDS_Hypothesis*>& theHypList,
4009 TDimHypList* theDimHypListArr )
4011 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
4012 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
4013 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
4014 listOfdimHyp.push_back( dimHyp );
4017 SMESH_DimHyp* dimHyp = listOfdimHyp.back();
4018 dimHyp->_hypothesises.push_front(theAlgo);
4019 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = theHypList.begin();
4020 for( ; hypIt != theHypList.end(); hypIt++ )
4021 dimHyp->_hypothesises.push_back( *hypIt );
4024 static void findConcurrents(const SMESH_DimHyp* theDimHyp,
4025 const TDimHypList& theListOfDimHyp,
4026 TListOfInt& theListOfConcurr )
4028 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
4029 for ( ; rIt != theListOfDimHyp.rend(); rIt++ ) {
4030 const SMESH_DimHyp* curDimHyp = *rIt;
4031 if ( curDimHyp == theDimHyp )
4032 break; // meet own dimHyp pointer in same dimension
4033 else if ( theDimHyp->IsConcurrent( curDimHyp ) )
4034 if ( find( theListOfConcurr.begin(),
4035 theListOfConcurr.end(),
4036 curDimHyp->_subMesh->GetId() ) == theListOfConcurr.end() )
4037 theListOfConcurr.push_back( curDimHyp->_subMesh->GetId() );
4041 static void unionLists(TListOfInt& theListOfId,
4042 TListOfListOfInt& theListOfListOfId,
4045 TListOfListOfInt::iterator it = theListOfListOfId.begin();
4046 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
4048 continue; //skip already treated lists
4049 // check if other list has any same submesh object
4050 TListOfInt& otherListOfId = *it;
4051 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
4052 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
4055 // union two lists (from source into target)
4056 TListOfInt::iterator it2 = otherListOfId.begin();
4057 for ( ; it2 != otherListOfId.end(); it2++ ) {
4058 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
4059 theListOfId.push_back(*it2);
4061 // clear source list
4062 otherListOfId.clear();
4066 //! free memory allocated for dimension-hypothesis objects
4067 static void removeDimHyps( TDimHypList* theArrOfList )
4069 for (int i = 0; i < 4; i++ ) {
4070 TDimHypList& listOfdimHyp = theArrOfList[i];
4071 TDimHypList::const_iterator it = listOfdimHyp.begin();
4072 for ( ; it != listOfdimHyp.end(); it++ )
4077 //=============================================================================
4079 * \brief Return submesh objects list in meshing order
4081 //=============================================================================
4083 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
4085 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
4087 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4089 return aResult._retn();
4091 ::SMESH_Mesh& mesh = GetImpl();
4092 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
4093 if ( !anOrder.size() ) {
4095 // collect submeshes detecting concurrent algorithms and hypothesises
4096 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
4098 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
4099 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
4100 ::SMESH_subMesh* sm = (*i_sm).second;
4102 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
4104 // list of assigned hypothesises
4105 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
4106 // Find out dimensions where the submesh can be concurrent.
4107 // We define the dimensions by algo of each of hypotheses in hypList
4108 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
4109 for( ; hypIt != hypList.end(); hypIt++ ) {
4110 SMESH_Algo* anAlgo = 0;
4111 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
4112 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
4113 // hyp it-self is algo
4114 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
4116 // try to find algorithm with help of subshapes
4117 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
4118 for ( ; !anAlgo && anExp.More(); anExp.Next() )
4119 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
4122 continue; // no assigned algorithm to current submesh
4124 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
4125 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDescretBoundary())
4127 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
4128 for ( int j = anAlgo->NeedDescretBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
4129 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
4131 } // end iterations on submesh
4133 // iterate on created dimension-hypotheses and check for concurrents
4134 for ( int i = 0; i < 4; i++ ) {
4135 const list<SMESH_DimHyp*>& listOfDimHyp = dimHypListArr[i];
4136 // check for concurrents in own and other dimensions (step-by-step)
4137 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
4138 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
4139 const SMESH_DimHyp* dimHyp = *dhIt;
4140 TListOfInt listOfConcurr;
4141 // looking for concurrents and collect into own list
4142 for ( int j = i; j < 4; j++ )
4143 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr );
4144 // check if any concurrents found
4145 if ( listOfConcurr.size() > 0 ) {
4146 // add own submesh to list of concurrent
4147 listOfConcurr.push_front( dimHyp->_subMesh->GetId() );
4148 anOrder.push_back( listOfConcurr );
4153 removeDimHyps(dimHypListArr);
4155 // now, minimise the number of concurrent groups
4156 // Here we assume that lists of submhes can has same submesh
4157 // in case of multi-dimension algorithms, as result
4158 // list with common submesh have to be union into one list
4160 TListOfListOfInt::iterator listIt = anOrder.begin();
4161 for(; listIt != anOrder.end(); listIt++, listIndx++ )
4162 unionLists( *listIt, anOrder, listIndx + 1 );
4164 // convert submesh ids into interface instances
4165 // and dump command into python
4166 convertMeshOrder( anOrder, aResult, true );
4168 return aResult._retn();
4171 //=============================================================================
4173 * \brief find common submeshes with given submesh
4174 * \param theSubMeshList list of already collected submesh to check
4175 * \param theSubMesh given submesh to intersect with other
4176 * \param theCommonSubMeshes collected common submeshes
4178 //=============================================================================
4180 static void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
4181 const SMESH_subMesh* theSubMesh,
4182 set<const SMESH_subMesh*>& theCommon )
4186 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
4187 for ( ; it != theSubMeshList.end(); it++ )
4188 theSubMesh->FindIntersection( *it, theCommon );
4189 theSubMeshList.push_back( theSubMesh );
4190 //theCommon.insert( theSubMesh );
4193 //=============================================================================
4195 * \brief Set submesh object order
4196 * \param theSubMeshArray submesh array order
4198 //=============================================================================
4200 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
4203 ::SMESH_Mesh& mesh = GetImpl();
4205 TPythonDump aPythonDump; // prevent dump of called methods
4206 aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
4208 TListOfListOfInt subMeshOrder;
4209 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
4211 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
4212 TListOfInt subMeshIds;
4213 aPythonDump << "[ ";
4214 // Collect subMeshes which should be clear
4215 // do it list-by-list, because modification of submesh order
4216 // take effect between concurrent submeshes only
4217 set<const SMESH_subMesh*> subMeshToClear;
4218 list<const SMESH_subMesh*> subMeshList;
4219 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
4221 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
4223 aPythonDump << ", ";
4224 aPythonDump << subMesh;
4225 subMeshIds.push_back( subMesh->GetId() );
4226 // detect common parts of submeshes
4227 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
4228 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
4230 aPythonDump << " ]";
4231 subMeshOrder.push_back( subMeshIds );
4233 // clear collected submeshes
4234 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
4235 for ( ; clrIt != subMeshToClear.end(); clrIt++ ) {
4236 SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt;
4238 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
4239 // ClearSubMesh( *clrIt );
4242 aPythonDump << " ])";
4244 mesh.SetMeshOrder( subMeshOrder );
4250 //=============================================================================
4252 * \brief Convert submesh ids into submesh interfaces
4254 //=============================================================================
4256 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
4257 SMESH::submesh_array_array& theResOrder,
4258 const bool theIsDump)
4260 int nbSet = theIdsOrder.size();
4261 TPythonDump aPythonDump; // prevent dump of called methods
4263 aPythonDump << "[ ";
4264 theResOrder.length(nbSet);
4265 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
4267 for( ; it != theIdsOrder.end(); it++ ) {
4268 // translate submesh identificators into submesh objects
4269 // takeing into account real number of concurrent lists
4270 const TListOfInt& aSubOrder = (*it);
4271 if (!aSubOrder.size())
4274 aPythonDump << "[ ";
4275 // convert shape indeces into interfaces
4276 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
4277 aResSubSet->length(aSubOrder.size());
4278 TListOfInt::const_iterator subIt = aSubOrder.begin();
4279 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
4280 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
4282 SMESH::SMESH_subMesh_var subMesh =
4283 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
4286 aPythonDump << ", ";
4287 aPythonDump << subMesh;
4289 aResSubSet[ j++ ] = subMesh;
4292 aPythonDump << " ]";
4293 theResOrder[ listIndx++ ] = aResSubSet;
4295 // correct number of lists
4296 theResOrder.length( listIndx );
4299 // finilise python dump
4300 aPythonDump << " ]";
4301 aPythonDump << " = " << _this() << ".GetMeshOrder()";
4305 //================================================================================
4307 // Implementation of SMESH_MeshPartDS
4309 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
4310 SMESHDS_Mesh( /*theMeshID=*/-1, /*theIsEmbeddedMode=*/true)
4312 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
4313 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4315 _meshDS = mesh_i->GetImpl().GetMeshDS();
4317 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
4319 // <meshPart> is the whole mesh
4320 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
4325 SMESH::long_array_var anIDs = meshPart->GetIDs();
4326 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
4327 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
4329 for (int i=0; i < anIDs->length(); i++)
4330 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
4331 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4336 for (int i=0; i < anIDs->length(); i++)
4337 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
4338 if ( _elements[ e->GetType() ].insert( e ).second )
4341 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
4342 while ( nIt->more() )
4344 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
4345 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4352 _meshDS = 0; // to enforce iteration on _elements and _nodes
4355 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
4357 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
4358 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
4359 ( new TIter( _elements[type].begin(), _elements[type].end() ));
4361 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
4362 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
4364 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
4365 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
4366 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
4368 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
4369 _GET_ITER_DEFINE( SMDS_0DElementIteratorPtr, elements0dIterator, SMDS_Mesh0DElement, SMDSAbs_0DElement)
4370 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
4371 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
4372 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
4373 #undef _GET_ITER_DEFINE
4375 // END Implementation of SMESH_MeshPartDS
4377 //================================================================================