Add methods to select mesh elements from python.

This commit is contained in:
rnv 2015-07-22 18:13:50 +03:00
parent 24fe0efaab
commit 938ed6ac35
9 changed files with 630 additions and 0 deletions

View File

@ -439,6 +439,79 @@ module SMESH
in string theLibName,
in GEOM::GEOM_Object theShapeObject,
in boolean toCheckAll );
/*!
* Return indices of elements, which are located inside the sphere
* \param theSource - mesh, sub-mesh or group
* \param theElemType - mesh element type
* \param theX - x cooridate of the center of the sphere
* \param theY - y cooridate of the center of the sphere
* \param theZ - y cooridate of the center of the sphere
* \param theR - radius of the sphere
*/
long_array GetInsideSphere( in SMESH_IDSource theSource,
in ElementType theElemType,
in double theX,
in double theY,
in double theZ,
in double theR );
/*!
* Return indices of elements, which are located inside the box
* \param theSource - mesh, sub-mesh or group
* \param theElemType - mesh element type
* \param theX1 - x cooridate of the first opposite point
* \param theY1 - y cooridate of the first opposite point
* \param theZ1 - y cooridate of the first opposite point
* \param theX2 - x cooridate of the second opposite point
* \param theY2 - y cooridate of the second opposite point
* \param theZ2 - y cooridate of the second opposite point
*/
long_array GetInsideBox( in SMESH_IDSource theSource,
in ElementType theElemType,
in double theX1,
in double theY1,
in double theZ1,
in double theX2,
in double theY2,
in double theZ2);
/*!
* Return indices of elements, which are located inside the box
* \param theSource - mesh, sub-mesh or group
* \param theElemType - mesh element type
* \param theX - x cooridate of the cented of the bottom face
* \param theY - y cooridate of the cented of the bottom face
* \param theZ - y cooridate of the cented of the bottom face
* \param theDX - x cooridate of the cented of the base vector
* \param theDY - y cooridate of the cented of the base vector
* \param theDZ - z cooridate of the cented of the base vector
* \param theH - height of the cylinder
* \param theR - radius of the cylinder
*/
long_array GetInsideCylinder( in SMESH_IDSource theSource,
in ElementType theElemType,
in double theX,
in double theY,
in double theZ,
in double theDX,
in double theDY,
in double theDZ,
in double theH,
in double theR );
/*!
* Return indices of elements, which are located inside the geometry
* \param theSource - mesh, sub-mesh or group
* \param theElemType - mesh element type
* \param theGeom - geometrical object
* \param theTolerance - tolerance for selection.
*/
long_array GetInside( in SMESH_IDSource theSource,
in ElementType theElemType,
in GEOM::GEOM_Object theGeom,
in double theTolerance );
};
};

View File

@ -44,6 +44,10 @@
#include <BRep_Tool.hxx>
#include <TCollection_AsciiString.hxx>
#include <OSD.hxx>
#include <BRepPrimAPI_MakeSphere.hxx>
#include <BRepPrimAPI_MakeCylinder.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#ifdef WIN32
#include <windows.h>
@ -93,6 +97,7 @@
#include "SMESH_Mesh_i.hxx"
#include "SMESH_PreMeshInfo.hxx"
#include "SMESH_PythonDump.hxx"
#include "SMESH_ControlsDef.hxx"
#include "SMESH_TryCatch.hxx" // to include after OCC headers!
#include CORBA_SERVER_HEADER(SMESH_Group)
@ -5125,6 +5130,193 @@ CORBA::Boolean SMESH_Gen_i::IsApplicable ( const char* theAlgoType,
return true;
}
//=================================================================================
// function : GetInsideSphere
// purpose : Collect indices of elements, which are located inside the sphere
//=================================================================================
SMESH::long_array* SMESH_Gen_i::GetInsideSphere( SMESH::SMESH_IDSource_ptr meshPart,
SMESH::ElementType theElemType,
CORBA::Double theX,
CORBA::Double theY,
CORBA::Double theZ,
CORBA::Double theR) {
SMESH::long_array_var aResult = new SMESH::long_array();
if(meshPart->_is_nil())
return aResult._retn();
// 1. Create geometrical object
gp_Pnt aP( theX, theY, theZ );
TopoDS_Shape aShape = BRepPrimAPI_MakeSphere( aP, theR ).Shape();
std::vector<long> lst =_GetInside(meshPart, theElemType, aShape);
if( lst.size() > 0 ) {
aResult->length( lst.size() );
for ( long i = 0; i < lst.size(); i++ ) {
aResult[i] = lst[i];
}
}
return aResult._retn();
}
SMESH::long_array* SMESH_Gen_i::GetInsideBox( SMESH::SMESH_IDSource_ptr meshPart,
SMESH::ElementType theElemType,
CORBA::Double theX1,
CORBA::Double theY1,
CORBA::Double theZ1,
CORBA::Double theX2,
CORBA::Double theY2,
CORBA::Double theZ2) {
SMESH::long_array_var aResult = new SMESH::long_array();
if( meshPart->_is_nil() )
return aResult._retn();
TopoDS_Shape aShape = BRepPrimAPI_MakeBox( gp_Pnt( theX1, theY1, theZ1 ), gp_Pnt( theX2, theY2, theZ2 ) ).Shape();
std::vector<long> lst =_GetInside(meshPart, theElemType, aShape);
if( lst.size() > 0 ) {
aResult->length( lst.size() );
for ( long i = 0; i < lst.size(); i++ ) {
aResult[i] = lst[i];
}
}
return aResult._retn();
}
SMESH::long_array* SMESH_Gen_i::GetInsideCylinder( SMESH::SMESH_IDSource_ptr meshPart,
SMESH::ElementType theElemType,
CORBA::Double theX,
CORBA::Double theY,
CORBA::Double theZ,
CORBA::Double theDX,
CORBA::Double theDY,
CORBA::Double theDZ,
CORBA::Double theH,
CORBA::Double theR ){
SMESH::long_array_var aResult = new SMESH::long_array();
if( meshPart->_is_nil() )
return aResult._retn();
gp_Pnt aP( theX, theY, theZ );
gp_Vec aV( theDX, theDY, theDZ );
gp_Ax2 anAxes (aP, aV);
TopoDS_Shape aShape = BRepPrimAPI_MakeCylinder(anAxes, theR, Abs(theH)).Shape();
std::vector<long> lst =_GetInside(meshPart, theElemType, aShape);
if( lst.size() > 0 ) {
aResult->length( lst.size() );
for ( long i = 0; i < lst.size(); i++ ) {
aResult[i] = lst[i];
}
}
return aResult._retn();
}
SMESH::long_array* SMESH_Gen_i::GetInside( SMESH::SMESH_IDSource_ptr meshPart,
SMESH::ElementType theElemType,
GEOM::GEOM_Object_ptr theGeom,
CORBA::Double theTolerance ) {
SMESH::long_array_var aResult = new SMESH::long_array();
if( meshPart->_is_nil() || theGeom->_is_nil() )
return aResult._retn();
TopoDS_Shape aShape = GeomObjectToShape( theGeom );
std::vector<long> lst =_GetInside(meshPart, theElemType, aShape, &theTolerance);
if( lst.size() > 0 ) {
aResult->length( lst.size() );
for ( long i = 0; i < lst.size(); i++ ) {
aResult[i] = lst[i];
}
}
return aResult._retn();
}
std::vector<long> SMESH_Gen_i::_GetInside( SMESH::SMESH_IDSource_ptr meshPart,
SMESH::ElementType theElemType,
TopoDS_Shape& aShape,
double* theTolerance) {
std::vector<long> res;
SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
if ( mesh->_is_nil() )
return res;
SMESH_Mesh_i* anImpl = dynamic_cast<SMESH_Mesh_i*>( GetServant( mesh ).in() );
if ( !anImpl )
return res;
const SMDS_Mesh* meshDS = anImpl->GetImpl().GetMeshDS();
if ( !meshDS )
return res;
SMDSAbs_ElementType aType = SMDSAbs_ElementType(theElemType);
SMESH::Controls::ElementsOnShape* anElementsOnShape = new SMESH::Controls::ElementsOnShape();
anElementsOnShape->SetAllNodes( true );
anElementsOnShape->SetMesh( meshDS );
anElementsOnShape->SetShape( aShape, aType );
if(theTolerance)
anElementsOnShape->SetTolerance(*theTolerance);
SMESH::SMESH_Mesh_var msource = SMESH::SMESH_Mesh::_narrow(meshPart);
if ( !msource->_is_nil() ) { // Mesh case
SMDS_ElemIteratorPtr elemIt = meshDS->elementsIterator( aType );
if ( elemIt ) {
while ( elemIt->more() ) {
const SMDS_MeshElement* anElem = elemIt->next();
long anId = anElem->GetID();
if ( anElementsOnShape->IsSatisfy( anId ) )
res.push_back( anId );
}
}
}
SMESH::SMESH_Group_var gsource = SMESH::SMESH_Group::_narrow(meshPart);
if ( !gsource->_is_nil() ) {
if(theElemType == SMESH::NODE) {
SMESH::long_array_var nodes = gsource->GetNodeIDs();
for ( int i = 0; i < nodes->length(); ++i ) {
if ( const SMDS_MeshNode* node = meshDS->FindNode( nodes[i] ) ) {
long anId = node->GetID();
if ( anElementsOnShape->IsSatisfy( anId ) )
res.push_back( anId );
}
}
} else if (gsource->GetType() == theElemType || theElemType == SMESH::ALL ) {
SMESH::long_array_var elems = gsource->GetListOfID();
for ( int i = 0; i < elems->length(); ++i ) {
if ( const SMDS_MeshElement* elem = meshDS->FindElement( elems[i] ) ) {
long anId = elem->GetID();
if ( anElementsOnShape->IsSatisfy( anId ) )
res.push_back( anId );
}
}
}
}
SMESH::SMESH_subMesh_var smsource = SMESH::SMESH_subMesh::_narrow(meshPart);
if ( !smsource->_is_nil() ) {
SMESH::long_array_var elems = smsource->GetElementsByType( theElemType );
for ( int i = 0; i < elems->length(); ++i ) {
const SMDS_MeshElement* elem = ( theElemType == SMESH::NODE ) ? meshDS->FindNode( elems[i] ) : meshDS->FindElement( elems[i] );
if (elem) {
long anId = elem->GetID();
if ( anElementsOnShape->IsSatisfy( anId ) )
res.push_back( anId );
}
}
}
return res;
}
//=================================================================================
// function : importData
// purpose : imports mesh data file (the med one) into the SMESH internal data structure

View File

@ -602,11 +602,44 @@ public:
void Move( const SMESH::sobject_list& what,
SALOMEDS::SObject_ptr where,
CORBA::Long row );
CORBA::Boolean IsApplicable ( const char* theAlgoType,
const char* theLibName,
GEOM::GEOM_Object_ptr theShapeObject,
CORBA::Boolean toCheckAll);
SMESH::long_array* GetInsideSphere( SMESH::SMESH_IDSource_ptr meshPart,
SMESH::ElementType theElemType,
CORBA::Double theX,
CORBA::Double theY,
CORBA::Double theZ,
CORBA::Double theR);
SMESH::long_array* GetInsideBox( SMESH::SMESH_IDSource_ptr meshPart,
SMESH::ElementType theElemType,
CORBA::Double theX1,
CORBA::Double theY1,
CORBA::Double theZ1,
CORBA::Double theX2,
CORBA::Double theY2,
CORBA::Double theZ2);
SMESH::long_array* GetInsideCylinder( SMESH::SMESH_IDSource_ptr meshPart,
SMESH::ElementType theElemType,
CORBA::Double theX,
CORBA::Double theY,
CORBA::Double theZ,
CORBA::Double theDX,
CORBA::Double theDY,
CORBA::Double theDZ,
CORBA::Double theH,
CORBA::Double theR );
SMESH::long_array* GetInside( SMESH::SMESH_IDSource_ptr meshPart,
SMESH::ElementType theElemType,
GEOM::GEOM_Object_ptr theGeom,
CORBA::Double theTolerance );
private:
// Get hypothesis creator
GenericHypothesisCreator_i* getHypothesisCreator( const char* theHypName,
@ -630,6 +663,11 @@ private:
void setCurrentStudy( SALOMEDS::Study_ptr theStudy,
bool theStudyIsBeingClosed=false);
std::vector<long> _GetInside(SMESH::SMESH_IDSource_ptr meshPart,
SMESH::ElementType theElemType,
TopoDS_Shape& aShape,
double* theTolerance = NULL);
private:
static GEOM::GEOM_Gen_var myGeomGen;
static CORBA::ORB_var myOrb; // ORB reference

View File

@ -89,6 +89,7 @@ SET(_bin_SCRIPTS
PAL_MESH_043_2D.py
PAL_MESH_043_3D.py
SMESH_reg.py
smesh_selection.py
)
SET(smesh_SCRIPTS

View File

@ -0,0 +1,156 @@
# Copyright (C) 2015 CEA/DEN, EDF R&D, OPEN CASCADE
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
# File : smesh_selection.py
# Author : Roman NIKOLAEV, OPEN CASCADE ( roman.nikolaev@opencascade.com )
# Module : SMESH
import salome
salome.salome_init()
import libSMESH_Swig
sm_gui = libSMESH_Swig.SMESH_Swig()
import SMESH, SALOMEDS
from salome.smesh import smeshBuilder
smesh = smeshBuilder.New(salome.myStudy)
import GEOM
# swig -> idl
_converter = {
libSMESH_Swig.EdgeOfCell : None, # TODO: check how to process it
libSMESH_Swig.Node : SMESH.NODE,
libSMESH_Swig.Edge : SMESH.EDGE,
libSMESH_Swig.Face : SMESH.FACE,
libSMESH_Swig.Volume : SMESH.VOLUME,
libSMESH_Swig.Elem0D : SMESH.ELEM0D,
libSMESH_Swig.Ball : SMESH.BALL,
libSMESH_Swig.Cell : SMESH.ALL
}
# Converts swig to idl enumeration
def _swig2idl( type ):
if _converter.has_key( type ) :
return _converter[type]
return None
def _getEntry(mesh):
if isinstance( mesh, smeshBuilder.Mesh ) :
return salome.ObjectToID( mesh.GetMesh() )
else :
if isinstance( mesh, str ) :
return mesh
return None
def _getMesh(mesh):
if isinstance( mesh, smeshBuilder.Mesh ) :
return mesh.GetMesh()
else :
if isinstance( mesh, str ) :
return salome.IDToObject( mesh )
return None
def _getGeom(geom):
if isinstance( geom, GEOM._objref_GEOM_Object ) :
return geom
else :
if isinstance( geom, str ) :
return salome.IDToObject( geom )
return None
# Selects an elements lst on the mesh
def select( mesh, lst, append = False ) :
# Check mesh parameter
entry = _getEntry(mesh)
if entry is None:
print "Wrong 'mesh' parameter"
return
# Check lst parameter
tmp = []
if isinstance( lst, int ) :
tmp.append( lst )
else :
if isinstance( lst,list ) :
tmp = lst
else :
print "Wrong 'lst' parameter"
return
sm_gui.select( entry, tmp, append )
def _preProcess(mesh) :
m = _getMesh(mesh);
if m is None:
print "Wrong 'mesh' parameter"
return [None, None]
elemType = _swig2idl(sm_gui.getSelectionMode())
if elemType is None:
return [None, None]
return [m, elemType]
# Selects an elements on the mesh inside the sphere with radius r and center (x, y, z)
def selectInsideSphere( mesh, x, y, z, r, append = False ) :
[m, elemType] = _preProcess(mesh)
if m is None or elemType is None :
return
l = smesh.GetInsideSphere( m, elemType, x, y, z, r )
if len(l) > 0:
select(mesh, l, append)
# Selects an elements on the mesh inside the box
def selectInsideBox( mesh, x1, y1, z1, x2, y2, z2 , append = False ) :
[m, elemType] = _preProcess(mesh)
if m is None or elemType is None :
return
l = smesh.GetInsideBox( m, elemType, x1, y1, z1, x2, y2, z2 )
if len(l) > 0:
select(mesh, l, append)
# Selects an elements on the mesh inside the cylinder
def selectInsideCylinder( mesh, x, y, z, dx, dy, dz, h, r, append = False ) :
[m, elemType] = _preProcess(mesh)
if m is None or elemType is None :
return
l = smesh.GetInsideCylinder( m, elemType, x, y, z, dx, dy, dz, h, r )
if len(l) > 0:
select(mesh, l, append)
# Selects an elements on the mesh inside the geometrical object
def selectInside( mesh, geom, tolerance , append = False ):
[m, elemType] = _preProcess(mesh)
if m is None or elemType is None :
return
g = _getGeom(geom)
l = smesh.GetInside( m, elemType, g ,tolerance )
if len(l) > 0:
select(mesh, l, append)

View File

@ -35,6 +35,9 @@ INCLUDE_DIRECTORIES(
${Boost_INCLUDE_DIRS}
${CMAKE_CURRENT_SOURCE_DIR}
${PROJECT_SOURCE_DIR}/src/SMESHGUI
${PROJECT_SOURCE_DIR}/src/OBJECT
${PROJECT_SOURCE_DIR}/src/SMESHDS
${PROJECT_SOURCE_DIR}/src/SMDS
${PROJECT_BINARY_DIR}/idl
)

View File

@ -24,9 +24,12 @@
//
#include "libSMESH_Swig.h"
#include <SMESHGUI.h>
#include <SMESHGUI_Utils.h>
#include <SMESHGUI_Displayer.h>
#include <SMESHGUI_VTKUtils.h>
#include <SMESH_Actor.h>
// SALOME KERNEL includes
#include <Utils_ORB_INIT.hxx>
@ -40,12 +43,16 @@
#include <SUIT_ViewManager.h>
#include <SALOME_Prs.h>
#include <SUIT_ViewWindow.h>
#include <SVTK_ViewWindow.h>
#include <VTKViewer_ViewModel.h>
#include <SALOME_Event.h>
#include <SalomeApp_Application.h>
#include <LightApp_SelectionMgr.h>
#include <SVTK_RenderWindowInteractor.h>
// OCCT includes
#include <TopAbs.hxx>
#include <TColStd_MapOfInteger.hxx>
// Qt includes
#include <QApplication>
@ -730,3 +737,112 @@ void SMESH_Swig::SetMeshIcon(const char* theMeshEntry,
theIsComputed,
isEmpty));
}
/*!
\brief Helper class for selection event.
*/
class TSelectListEvent: public SALOME_Event
{
const char* myId;
std::vector<int> myIdsList;
bool myIsAppend;
public:
TSelectListEvent(const char* id, std::vector<int> ids, bool append) :
myId(id),
myIdsList(ids),
myIsAppend(append)
{}
virtual void Execute()
{
SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI();
if( !aSMESHGUI )
return;
LightApp_SelectionMgr* selMgr = SMESH::GetSelectionMgr( aSMESHGUI );
if( !selMgr )
return;
selMgr->clearFilters();
SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( aSMESHGUI );
if(!aViewWindow)
return;
SMESH_Actor* anActor = SMESH::FindActorByEntry( myId );
if (!anActor || !anActor->hasIO())
return;
Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
SALOME_ListIO aList;
aList.Append(anIO);
selMgr->setSelectedObjects(aList, false);
if ( aViewWindow->SelectionMode() == ActorSelection ) {
return;
}
TColStd_MapOfInteger aMap;
std::vector<int>::const_iterator anIter;
for (anIter = myIdsList.begin(); anIter != myIdsList.end(); ++anIter) {
aMap.Add(*anIter);
}
// Set new selection
SVTK_Selector* aSelector = aViewWindow->GetSelector();
aSelector->AddOrRemoveIndex(anIO, aMap, myIsAppend);
aViewWindow->highlight( anIO, true, true );
aViewWindow->GetInteractor()->onEmitSelectionChanged();
}
};
/*!
\brief Select the elements on the mesh, sub-mesh or group.
\param id object entry
\param ids list of the element ids
\param mode selection mode
*/
void SMESH_Swig::select( const char* id, std::vector<int> ids, bool append ) {
ProcessVoidEvent( new TSelectListEvent( id, ids, append ) );
}
/*!
\brief Select the elements on the mesh, sub-mesh or group.
\param id object entry
\param id id of the element
\param mode selection mode
*/
void SMESH_Swig::select( const char* id, int id1, bool append ) {
std::vector<int> ids;
ids.push_back( id1 );
ProcessVoidEvent( new TSelectListEvent( id, ids, append ) );
}
class TGetSelectionModeEvent : public SALOME_Event
{
public:
typedef int TResult;
TResult myResult;
TGetSelectionModeEvent() : myResult( -1 ) {}
virtual void Execute()
{
SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI();
if( !aSMESHGUI )
return;
SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( aSMESHGUI );
if(!aViewWindow)
return;
myResult = aViewWindow->SelectionMode();
}
};
/*!
\brief Get selection mode of the active VTK View window.
*/
int SMESH_Swig::getSelectionMode() {
return ProcessEvent( new TGetSelectionModeEvent() );
}

View File

@ -38,6 +38,26 @@
#include <SALOMEconfig.h>
#include CORBA_SERVER_HEADER(SALOMEDS)
//std includes
#include <vector>
#include <SVTK_Selection.h>
#include <SVTK_Selection.h>
enum
{
Node = NodeSelection,
Cell = CellSelection,
EdgeOfCell = EdgeOfCellSelection,
Edge = EdgeSelection,
Face = FaceSelection,
Volume = VolumeSelection,
Actor = ActorSelection,
Elem0D = Elem0DSelection,
Ball = BallSelection
};
class SMESH_SWIG_EXPORT SMESH_Swig
{
public:
@ -74,6 +94,11 @@ public:
*/
void SetMeshIcon( const char*, const bool, const bool );
// --------------------- for the test purposes -----------------------
int getSelectionMode();
void select( const char *id, std::vector<int> ids, bool append = false );
void select( const char *id, int id1, bool append = false );
private:
SALOMEDS::Study_var myStudy;
SALOMEDS::StudyBuilder_var myStudyBuilder;

View File

@ -47,6 +47,26 @@
}
%include "typemaps.i"
%include "std_vector.i"
namespace std {
%template(VectorInt) vector<int>;
};
/* Selection mode enumeration (corresponds to constants from the SALOME_Selection.h) */
enum
{
Node,
Cell,
EdgeOfCell,
Edge,
Face,
Volume,
Actor,
Elem0D,
Ball
};
class SMESH_Swig
{
@ -76,4 +96,10 @@ class SMESH_Swig
void CreateAndDisplayActor( const char* Mesh_Entry );
void EraseActor( const char* Mesh_Entry, const bool allViewers = false );
// --------------------- for the test purposes -----------------------
int getSelectionMode();
void select( const char *id, std::vector<int> ids, bool append = false );
void select( const char *id, int id1, bool append = false );
};