mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-03-15 22:21:28 +05:00
Merge imn/IMACS branch into imn/IMACS_8_3_0
This commit is contained in:
commit
220a3ac6f1
37
doc/salome/examples/ex_MakePolyLine.py
Normal file
37
doc/salome/examples/ex_MakePolyLine.py
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import salome
|
||||||
|
salome.salome_init()
|
||||||
|
|
||||||
|
### create geometry
|
||||||
|
|
||||||
|
from salome.geom import geomBuilder
|
||||||
|
geompy = geomBuilder.New(salome.myStudy)
|
||||||
|
|
||||||
|
Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)
|
||||||
|
geompy.addToStudy( Box_1, 'Box_1' )
|
||||||
|
|
||||||
|
### create a mesh
|
||||||
|
|
||||||
|
import SMESH
|
||||||
|
from salome.smesh import smeshBuilder
|
||||||
|
smesh = smeshBuilder.New(salome.myStudy)
|
||||||
|
|
||||||
|
Mesh_1 = smesh.Mesh( Box_1 )
|
||||||
|
Mesh_1.Segment().NumberOfSegments(15)
|
||||||
|
Mesh_1.Triangle()
|
||||||
|
Mesh_1.Compute()
|
||||||
|
|
||||||
|
# define arguments for MakePolyLine
|
||||||
|
|
||||||
|
segments = []
|
||||||
|
# between nodes 20 and 1, default plane
|
||||||
|
segments.append( SMESH.PolySegment( 20, 0, 1, 0, smesh.MakeDirStruct(0,0,0) ))
|
||||||
|
# between nodes 1 and 100, default plane
|
||||||
|
segments.append( SMESH.PolySegment( 1, 0, 200, 0, smesh.MakeDirStruct(0,0,0) ))
|
||||||
|
# between nodes 200 and edge (578, 577), plane includes vector (1,1,1)
|
||||||
|
segments.append( SMESH.PolySegment( 200, 0, 578, 577, smesh.MakeDirStruct(1,1,1) ))
|
||||||
|
|
||||||
|
Mesh_1.MakePolyLine( segments, "1D group")
|
||||||
|
|
||||||
|
|
||||||
|
if salome.sg.hasDesktop():
|
||||||
|
salome.sg.updateObjBrowser(True)
|
@ -57,6 +57,24 @@ module SMESH
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// structure used in MakePolyLine() to define a cutting plane
|
||||||
|
struct PolySegment
|
||||||
|
{
|
||||||
|
// point 1: if node1ID2 > 0, then the point is in the middle of a face edge defined
|
||||||
|
// by two nodes, else it is at node1ID1
|
||||||
|
long node1ID1;
|
||||||
|
long node1ID2;
|
||||||
|
|
||||||
|
// point 2: if node2ID2 > 0, then the point is in the middle of a face edge defined
|
||||||
|
// by two nodes, else it is at node2ID1
|
||||||
|
long node2ID1;
|
||||||
|
long node2ID2;
|
||||||
|
|
||||||
|
DirStruct vector; // vector on the plane; to use a default plane set vector = (0,0,0)
|
||||||
|
};
|
||||||
|
typedef sequence<PolySegment> ListOfPolySegments;
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* This interface makes modifications on the Mesh - removing elements and nodes etc.
|
* This interface makes modifications on the Mesh - removing elements and nodes etc.
|
||||||
*/
|
*/
|
||||||
@ -1186,6 +1204,27 @@ module SMESH
|
|||||||
in double_array theNodesCoords,
|
in double_array theNodesCoords,
|
||||||
out array_of_long_array GroupsOfNodes)
|
out array_of_long_array GroupsOfNodes)
|
||||||
raises (SALOME::SALOME_Exception);
|
raises (SALOME::SALOME_Exception);
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Create a polyline consisting of 1D mesh elements each lying on a 2D element of
|
||||||
|
* the initial mesh. Positions of new nodes are found by cutting the mesh by the
|
||||||
|
* plane passing through pairs of points specified by each PolySegment structure.
|
||||||
|
* If there are several paths connecting a pair of points, the shortest path is
|
||||||
|
* selected by the module. Position of the cutting plane is defined by the two
|
||||||
|
* points and an optional vector lying on the plane specified by a PolySegment.
|
||||||
|
* By default the vector is defined by Mesh module as following. A middle point
|
||||||
|
* of the two given points is computed. The middle point is projected to the mesh.
|
||||||
|
* The vector goes from the middle point to the projection point. In case of planar
|
||||||
|
* mesh, the vector is normal to the mesh.
|
||||||
|
* \param [inout] segments - PolySegment's defining positions of cutting planes.
|
||||||
|
* Return the used vector which goes from the middle point to its projection.
|
||||||
|
* \param [in] groupName - optional name of a group where created mesh segments will
|
||||||
|
* be added.
|
||||||
|
*/
|
||||||
|
void MakePolyLine(inout ListOfPolySegments segments,
|
||||||
|
in string groupName)
|
||||||
|
raises (SALOME::SALOME_Exception);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1430,6 +1430,10 @@ double* SMESH_ActorDef::GetNodeCoord(int theObjID)
|
|||||||
return myPickableActor->GetNodeCoord(theObjID);
|
return myPickableActor->GetNodeCoord(theObjID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SMESH_ActorDef::GetNodeVtkId(int theObjID)
|
||||||
|
{
|
||||||
|
return myPickableActor->GetNodeVtkId(theObjID);
|
||||||
|
}
|
||||||
|
|
||||||
int SMESH_ActorDef::GetElemObjId(int theVtkID)
|
int SMESH_ActorDef::GetElemObjId(int theVtkID)
|
||||||
{
|
{
|
||||||
|
@ -150,6 +150,7 @@ class SMESH_ActorDef : public SMESH_Actor
|
|||||||
|
|
||||||
virtual int GetNodeObjId(int theVtkID);
|
virtual int GetNodeObjId(int theVtkID);
|
||||||
virtual double* GetNodeCoord(int theObjID);
|
virtual double* GetNodeCoord(int theObjID);
|
||||||
|
virtual int GetNodeVtkId(int theObjID);
|
||||||
|
|
||||||
virtual int GetElemObjId(int theVtkID);
|
virtual int GetElemObjId(int theVtkID);
|
||||||
virtual vtkCell* GetElemCell(int theObjID);
|
virtual vtkCell* GetElemCell(int theObjID);
|
||||||
|
@ -860,6 +860,12 @@ SMESH_DeviceActor
|
|||||||
return aCoord;
|
return aCoord;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
SMESH_DeviceActor
|
||||||
|
::GetNodeVtkId(int theObjID)
|
||||||
|
{
|
||||||
|
return myVisualObj->GetNodeVTKId(theObjID);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
SMESH_DeviceActor
|
SMESH_DeviceActor
|
||||||
|
@ -70,6 +70,7 @@ class SMESHOBJECT_EXPORT SMESH_DeviceActor: public vtkLODActor{
|
|||||||
|
|
||||||
virtual int GetNodeObjId(int theVtkID);
|
virtual int GetNodeObjId(int theVtkID);
|
||||||
virtual double* GetNodeCoord(int theObjID);
|
virtual double* GetNodeCoord(int theObjID);
|
||||||
|
virtual int GetNodeVtkId(int theObjID);
|
||||||
|
|
||||||
virtual int GetElemObjId(int theVtkID);
|
virtual int GetElemObjId(int theVtkID);
|
||||||
virtual vtkCell* GetElemCell(int theObjID);
|
virtual vtkCell* GetElemCell(int theObjID);
|
||||||
|
@ -21,9 +21,10 @@
|
|||||||
#define _OBJECTPOOL_HXX_
|
#define _OBJECTPOOL_HXX_
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
//#include <stack>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "SMDS_Iterator.hxx"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
// assure deallocation of memory of a vector
|
// assure deallocation of memory of a vector
|
||||||
@ -33,19 +34,23 @@ namespace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class X> class ObjectPoolIterator;
|
||||||
|
|
||||||
template<class X> class ObjectPool
|
template<class X> class ObjectPool
|
||||||
{
|
{
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<X*> _chunkList;
|
std::vector<X*> _chunkList;
|
||||||
std::vector<bool> _freeList;
|
std::vector<bool> _freeList;
|
||||||
int _nextFree;
|
int _nextFree; // either the 1st hole or last added
|
||||||
int _maxAvail;
|
int _maxAvail; // nb allocated elements
|
||||||
int _chunkSize;
|
int _chunkSize;
|
||||||
int _maxOccupied;
|
int _maxOccupied; // max used ID
|
||||||
int _nbHoles;
|
int _nbHoles;
|
||||||
int _lastDelChunk;
|
int _lastDelChunk;
|
||||||
|
|
||||||
|
friend class ObjectPoolIterator<X>;
|
||||||
|
|
||||||
int getNextFree()
|
int getNextFree()
|
||||||
{
|
{
|
||||||
// Don't iterate on the _freeList if all the "holes"
|
// Don't iterate on the _freeList if all the "holes"
|
||||||
@ -76,16 +81,16 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ObjectPool(int nblk)
|
ObjectPool(int nblk = 1024)
|
||||||
{
|
{
|
||||||
_chunkSize = nblk;
|
_chunkSize = nblk;
|
||||||
_nextFree = 0;
|
_nextFree = 0;
|
||||||
_maxAvail = 0;
|
_maxAvail = 0;
|
||||||
_maxOccupied = 0;
|
_maxOccupied = -1;
|
||||||
_nbHoles = 0;
|
_nbHoles = 0;
|
||||||
|
_lastDelChunk = 0;
|
||||||
_chunkList.clear();
|
_chunkList.clear();
|
||||||
_freeList.clear();
|
_freeList.clear();
|
||||||
_lastDelChunk = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~ObjectPool()
|
virtual ~ObjectPool()
|
||||||
@ -105,16 +110,16 @@ public:
|
|||||||
_freeList.insert(_freeList.end(), _chunkSize, true);
|
_freeList.insert(_freeList.end(), _chunkSize, true);
|
||||||
_maxAvail += _chunkSize;
|
_maxAvail += _chunkSize;
|
||||||
_freeList[_nextFree] = false;
|
_freeList[_nextFree] = false;
|
||||||
obj = newChunk; // &newChunk[0];
|
obj = newChunk;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int chunkId = _nextFree / _chunkSize;
|
int chunkId = _nextFree / _chunkSize;
|
||||||
int rank = _nextFree - chunkId * _chunkSize;
|
int rank = _nextFree - chunkId * _chunkSize;
|
||||||
_freeList[_nextFree] = false;
|
_freeList[_nextFree] = false;
|
||||||
obj = _chunkList[chunkId] + rank; // &_chunkList[chunkId][rank];
|
obj = _chunkList[chunkId] + rank;
|
||||||
}
|
}
|
||||||
if (_nextFree < _maxOccupied)
|
if (_nextFree <= _maxOccupied)
|
||||||
{
|
{
|
||||||
_nbHoles-=1;
|
_nbHoles-=1;
|
||||||
}
|
}
|
||||||
@ -122,7 +127,6 @@ public:
|
|||||||
{
|
{
|
||||||
_maxOccupied = _nextFree;
|
_maxOccupied = _nextFree;
|
||||||
}
|
}
|
||||||
//obj->init();
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,10 +152,10 @@ public:
|
|||||||
if (toFree < _nextFree)
|
if (toFree < _nextFree)
|
||||||
_nextFree = toFree;
|
_nextFree = toFree;
|
||||||
if (toFree < _maxOccupied)
|
if (toFree < _maxOccupied)
|
||||||
_nbHoles += 1;
|
++_nbHoles;
|
||||||
|
else
|
||||||
|
--_maxOccupied;
|
||||||
_lastDelChunk = i;
|
_lastDelChunk = i;
|
||||||
//obj->clean();
|
|
||||||
//checkDelete(i); compactage non fait
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear()
|
void clear()
|
||||||
@ -167,6 +171,37 @@ public:
|
|||||||
clearVector( _freeList );
|
clearVector( _freeList );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// nb allocated elements
|
||||||
|
size_t size() const
|
||||||
|
{
|
||||||
|
return _freeList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
// nb used elements
|
||||||
|
size_t nbElements() const
|
||||||
|
{
|
||||||
|
return _maxOccupied + 1 - _nbHoles;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return an element w/o any check
|
||||||
|
const X* operator[]( size_t i ) const // i < size()
|
||||||
|
{
|
||||||
|
int chunkId = i / _chunkSize;
|
||||||
|
int rank = i - chunkId * _chunkSize;
|
||||||
|
return _chunkList[ chunkId ] + rank;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return only being used element
|
||||||
|
const X* at( size_t i ) const // i < size()
|
||||||
|
{
|
||||||
|
if ( i >= size() || _freeList[ i ] )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int chunkId = i / _chunkSize;
|
||||||
|
int rank = i - chunkId * _chunkSize;
|
||||||
|
return _chunkList[ chunkId ] + rank;
|
||||||
|
}
|
||||||
|
|
||||||
// void destroy(int toFree)
|
// void destroy(int toFree)
|
||||||
// {
|
// {
|
||||||
// // no control 0<= toFree < _freeList.size()
|
// // no control 0<= toFree < _freeList.size()
|
||||||
@ -177,4 +212,41 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<class X> class ObjectPoolIterator : public SMDS_Iterator<const X*>
|
||||||
|
{
|
||||||
|
const ObjectPool<X>& _pool;
|
||||||
|
int _i, _nbFound;
|
||||||
|
public:
|
||||||
|
|
||||||
|
ObjectPoolIterator( const ObjectPool<X>& pool ) : _pool( pool ), _i( 0 ), _nbFound( 0 )
|
||||||
|
{
|
||||||
|
if ( more() && _pool._freeList[ _i ] == true )
|
||||||
|
{
|
||||||
|
next();
|
||||||
|
--_nbFound;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool more()
|
||||||
|
{
|
||||||
|
return ( _i <= _pool._maxOccupied && _nbFound < (int)_pool.nbElements() );
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const X* next()
|
||||||
|
{
|
||||||
|
const X* x = 0;
|
||||||
|
if ( more() )
|
||||||
|
{
|
||||||
|
x = _pool[ _i ];
|
||||||
|
|
||||||
|
++_nbFound;
|
||||||
|
|
||||||
|
for ( ++_i; _i <= _pool._maxOccupied; ++_i )
|
||||||
|
if ( _pool._freeList[ _i ] == false )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -98,6 +98,9 @@
|
|||||||
|
|
||||||
#include <Standard_Failure.hxx>
|
#include <Standard_Failure.hxx>
|
||||||
#include <Standard_ErrorHandler.hxx>
|
#include <Standard_ErrorHandler.hxx>
|
||||||
|
#include <OSD_Parallel.hxx>
|
||||||
|
|
||||||
|
#include "SMESH_TryCatch.hxx" // include after OCCT headers!
|
||||||
|
|
||||||
#define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
|
#define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
|
||||||
|
|
||||||
@ -7482,8 +7485,8 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove bad elements, then equal nodes (order important)
|
// Remove bad elements, then equal nodes (order important)
|
||||||
Remove( rmElemIds, false );
|
Remove( rmElemIds, /*isNodes=*/false );
|
||||||
Remove( rmNodeIds, true );
|
Remove( rmNodeIds, /*isNodes=*/true );
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -7553,14 +7556,14 @@ bool SMESH_MeshEditor::applyMerge( const SMDS_MeshElement* elem,
|
|||||||
toRemove = true;
|
toRemove = true;
|
||||||
nbResElems = 0;
|
nbResElems = 0;
|
||||||
|
|
||||||
if ( elem->IsQuadratic() && newElemDefs[0].myType == SMDSAbs_Face && nbNodes > 6 )
|
if ( newElemDefs[0].myIsQuad && newElemDefs[0].myType == SMDSAbs_Face && nbNodes > 6 )
|
||||||
{
|
{
|
||||||
// if corner nodes stick, remove medium nodes between them from uniqueNodes
|
// if corner nodes stick, remove medium nodes between them from uniqueNodes
|
||||||
int nbCorners = nbNodes / 2;
|
int nbCorners = nbNodes / 2;
|
||||||
for ( int iCur = 0; iCur < nbCorners; ++iCur )
|
for ( int iCur = 0; iCur < nbCorners; ++iCur )
|
||||||
{
|
{
|
||||||
int iPrev = ( iCur + 1 ) % nbCorners;
|
int iNext = ( iCur + 1 ) % nbCorners;
|
||||||
if ( curNodes[ iCur ] == curNodes[ iPrev ] ) // corners stick
|
if ( curNodes[ iCur ] == curNodes[ iNext ] ) // corners stick
|
||||||
{
|
{
|
||||||
int iMedium = iCur + nbCorners;
|
int iMedium = iCur + nbCorners;
|
||||||
vector< const SMDS_MeshNode* >::iterator i =
|
vector< const SMDS_MeshNode* >::iterator i =
|
||||||
@ -7711,11 +7714,9 @@ bool SMESH_MeshEditor::applyMerge( const SMDS_MeshElement* elem,
|
|||||||
// | |
|
// | |
|
||||||
// +---+---+
|
// +---+---+
|
||||||
// 0 7 3
|
// 0 7 3
|
||||||
if (( nbUniqueNodes == 7 && nbRepl == 2 && iRepl[1] != 8 ) &&
|
if ( nbUniqueNodes == 7 &&
|
||||||
(( iRepl[0] == 1 && iRepl[1] == 4 && curNodes[1] == curNodes[0] ) ||
|
iRepl[0] < 4 &&
|
||||||
( iRepl[0] == 2 && iRepl[1] == 5 && curNodes[2] == curNodes[1] ) ||
|
( nbRepl == 1 || iRepl[1] != 8 ))
|
||||||
( iRepl[0] == 3 && iRepl[1] == 6 && curNodes[3] == curNodes[2] ) ||
|
|
||||||
( iRepl[0] == 3 && iRepl[1] == 7 && curNodes[3] == curNodes[0] )))
|
|
||||||
{
|
{
|
||||||
toRemove = false;
|
toRemove = false;
|
||||||
}
|
}
|
||||||
@ -12833,3 +12834,482 @@ void SMESH_MeshEditor::copyPosition( const SMDS_MeshNode* from,
|
|||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace // utils for MakePolyLine
|
||||||
|
{
|
||||||
|
//================================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Sequence of found points and a current point data
|
||||||
|
*/
|
||||||
|
struct Path
|
||||||
|
{
|
||||||
|
std::vector< gp_XYZ > myPoints;
|
||||||
|
double myLength;
|
||||||
|
|
||||||
|
int mySrcPntInd; //!< start point index
|
||||||
|
const SMDS_MeshElement* myFace;
|
||||||
|
SMESH_NodeXYZ myNode1;
|
||||||
|
SMESH_NodeXYZ myNode2;
|
||||||
|
int myNodeInd1;
|
||||||
|
int myNodeInd2;
|
||||||
|
double myDot1;
|
||||||
|
double myDot2;
|
||||||
|
TIDSortedElemSet myElemSet, myAvoidSet;
|
||||||
|
|
||||||
|
Path(): myLength(0.0), myFace(0) {}
|
||||||
|
|
||||||
|
bool SetCutAtCorner( const SMESH_NodeXYZ& cornerNode,
|
||||||
|
const SMDS_MeshElement* face,
|
||||||
|
const gp_XYZ& plnNorm,
|
||||||
|
const gp_XYZ& plnOrig );
|
||||||
|
|
||||||
|
void AddPoint( const gp_XYZ& p );
|
||||||
|
|
||||||
|
bool Extend( const gp_XYZ& plnNorm, const gp_XYZ& plnOrig );
|
||||||
|
|
||||||
|
bool ReachSamePoint( const Path& other );
|
||||||
|
|
||||||
|
static void Remove( std::vector< Path > & paths, size_t& i );
|
||||||
|
};
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Return true if this Path meats another
|
||||||
|
*/
|
||||||
|
//================================================================================
|
||||||
|
|
||||||
|
bool Path::ReachSamePoint( const Path& other )
|
||||||
|
{
|
||||||
|
return ( mySrcPntInd != other.mySrcPntInd &&
|
||||||
|
myFace == other.myFace );
|
||||||
|
}
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Remove a path from a vector
|
||||||
|
*/
|
||||||
|
//================================================================================
|
||||||
|
|
||||||
|
void Path::Remove( std::vector< Path > & paths, size_t& i )
|
||||||
|
{
|
||||||
|
if ( paths.size() > 1 )
|
||||||
|
{
|
||||||
|
size_t j = paths.size() - 1; // last item to be removed
|
||||||
|
if ( i < j )
|
||||||
|
{
|
||||||
|
paths[ i ].myPoints.swap( paths[ j ].myPoints );
|
||||||
|
paths[ i ].myLength = paths[ j ].myLength;
|
||||||
|
paths[ i ].mySrcPntInd = paths[ j ].mySrcPntInd;
|
||||||
|
paths[ i ].myFace = paths[ j ].myFace;
|
||||||
|
paths[ i ].myNode1 = paths[ j ].myNode1;
|
||||||
|
paths[ i ].myNode2 = paths[ j ].myNode2;
|
||||||
|
paths[ i ].myNodeInd1 = paths[ j ].myNodeInd1;
|
||||||
|
paths[ i ].myNodeInd2 = paths[ j ].myNodeInd2;
|
||||||
|
paths[ i ].myDot1 = paths[ j ].myDot1;
|
||||||
|
paths[ i ].myDot2 = paths[ j ].myDot2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
paths.pop_back();
|
||||||
|
if ( i > 0 )
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Store a point that is at a node of a face if the face is intersected by plane.
|
||||||
|
* Return false if the node is a sole intersection point of the face and the plane
|
||||||
|
*/
|
||||||
|
//================================================================================
|
||||||
|
|
||||||
|
bool Path::SetCutAtCorner( const SMESH_NodeXYZ& cornerNode,
|
||||||
|
const SMDS_MeshElement* face,
|
||||||
|
const gp_XYZ& plnNorm,
|
||||||
|
const gp_XYZ& plnOrig )
|
||||||
|
{
|
||||||
|
if ( face == myFace )
|
||||||
|
return false;
|
||||||
|
myNodeInd1 = face->GetNodeIndex( cornerNode._node );
|
||||||
|
myNodeInd2 = ( myNodeInd1 + 1 ) % face->NbCornerNodes();
|
||||||
|
int ind3 = ( myNodeInd1 + 2 ) % face->NbCornerNodes();
|
||||||
|
myNode1.Set( face->GetNode( ind3 ));
|
||||||
|
myNode2.Set( face->GetNode( myNodeInd2 ));
|
||||||
|
|
||||||
|
myDot1 = plnNorm * ( myNode1 - plnOrig );
|
||||||
|
myDot2 = plnNorm * ( myNode2 - plnOrig );
|
||||||
|
|
||||||
|
bool ok = ( myDot1 * myDot2 < 0 );
|
||||||
|
if ( !ok && myDot1 * myDot2 == 0 )
|
||||||
|
{
|
||||||
|
ok = ( myDot1 != myDot2 );
|
||||||
|
if ( ok && myFace )
|
||||||
|
ok = ( myFace->GetNodeIndex(( myDot1 == 0 ? myNode1 : myNode2 )._node ) < 0 );
|
||||||
|
}
|
||||||
|
if ( ok )
|
||||||
|
{
|
||||||
|
myFace = face;
|
||||||
|
myDot1 = 0;
|
||||||
|
AddPoint( cornerNode );
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Store a point and update myLength
|
||||||
|
*/
|
||||||
|
//================================================================================
|
||||||
|
|
||||||
|
void Path::AddPoint( const gp_XYZ& p )
|
||||||
|
{
|
||||||
|
if ( !myPoints.empty() )
|
||||||
|
myLength += ( p - myPoints.back() ).Modulus();
|
||||||
|
else
|
||||||
|
myLength = 0;
|
||||||
|
myPoints.push_back( p );
|
||||||
|
}
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Try to find the next point
|
||||||
|
* \param [in] plnNorm - cutting plane normal
|
||||||
|
* \param [in] plnOrig - cutting plane origin
|
||||||
|
*/
|
||||||
|
//================================================================================
|
||||||
|
|
||||||
|
bool Path::Extend( const gp_XYZ& plnNorm, const gp_XYZ& plnOrig )
|
||||||
|
{
|
||||||
|
int nodeInd3 = ( myNodeInd1 + 1 ) % myFace->NbCornerNodes();
|
||||||
|
if ( myNodeInd2 == nodeInd3 )
|
||||||
|
nodeInd3 = ( myNodeInd1 + 2 ) % myFace->NbCornerNodes();
|
||||||
|
|
||||||
|
SMESH_NodeXYZ node3 = myFace->GetNode( nodeInd3 );
|
||||||
|
double dot3 = plnNorm * ( node3 - plnOrig );
|
||||||
|
|
||||||
|
if ( dot3 * myDot1 < 0. )
|
||||||
|
{
|
||||||
|
myNode2 = node3;
|
||||||
|
myNodeInd2 = nodeInd3;
|
||||||
|
myDot2 = dot3;
|
||||||
|
}
|
||||||
|
else if ( dot3 * myDot2 < 0. )
|
||||||
|
{
|
||||||
|
myNode1 = node3;
|
||||||
|
myNodeInd1 = nodeInd3;
|
||||||
|
myDot1 = dot3;
|
||||||
|
}
|
||||||
|
else if ( dot3 == 0. )
|
||||||
|
{
|
||||||
|
SMDS_ElemIteratorPtr fIt = node3._node->GetInverseElementIterator(SMDSAbs_Face);
|
||||||
|
while ( fIt->more() )
|
||||||
|
if ( SetCutAtCorner( node3, fIt->next(), plnNorm, plnOrig ))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if ( myDot2 == 0. )
|
||||||
|
{
|
||||||
|
SMESH_NodeXYZ node2 = myNode2; // copy as myNode2 changes in SetCutAtCorner()
|
||||||
|
SMDS_ElemIteratorPtr fIt = node2._node->GetInverseElementIterator(SMDSAbs_Face);
|
||||||
|
while ( fIt->more() )
|
||||||
|
if ( SetCutAtCorner( node2, fIt->next(), plnNorm, plnOrig ))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
double r = Abs( myDot1 / ( myDot2 - myDot1 ));
|
||||||
|
AddPoint( myNode1 * ( 1 - r ) + myNode2 * r );
|
||||||
|
|
||||||
|
myAvoidSet.clear();
|
||||||
|
myAvoidSet.insert( myFace );
|
||||||
|
myFace = SMESH_MeshAlgos::FindFaceInSet( myNode1._node, myNode2._node,
|
||||||
|
myElemSet, myAvoidSet,
|
||||||
|
&myNodeInd1, &myNodeInd2 );
|
||||||
|
return myFace;
|
||||||
|
}
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Compute a path between two points of PolySegment
|
||||||
|
*/
|
||||||
|
struct PolyPathCompute
|
||||||
|
{
|
||||||
|
SMESH_MeshEditor::TListOfPolySegments& mySegments; //!< inout PolySegment's
|
||||||
|
std::vector< Path >& myPaths; //!< path of each of segments to compute
|
||||||
|
SMESH_Mesh* myMesh;
|
||||||
|
mutable std::vector< std::string > myErrors;
|
||||||
|
|
||||||
|
PolyPathCompute( SMESH_MeshEditor::TListOfPolySegments& theSegments,
|
||||||
|
std::vector< Path >& thePaths,
|
||||||
|
SMESH_Mesh* theMesh):
|
||||||
|
mySegments( theSegments ),
|
||||||
|
myPaths( thePaths ),
|
||||||
|
myMesh( theMesh ),
|
||||||
|
myErrors( theSegments.size() )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#undef SMESH_CAUGHT
|
||||||
|
#define SMESH_CAUGHT myErrors[i] =
|
||||||
|
void operator() ( const int i ) const
|
||||||
|
{
|
||||||
|
SMESH_TRY;
|
||||||
|
const_cast< PolyPathCompute* >( this )->Compute( i );
|
||||||
|
SMESH_CATCH( SMESH::returnError );
|
||||||
|
}
|
||||||
|
#undef SMESH_CAUGHT
|
||||||
|
//================================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Compute a path of a given segment
|
||||||
|
*/
|
||||||
|
//================================================================================
|
||||||
|
|
||||||
|
void Compute( const int iSeg )
|
||||||
|
{
|
||||||
|
SMESH_MeshEditor::PolySegment& polySeg = mySegments[ iSeg ];
|
||||||
|
|
||||||
|
// get a cutting plane
|
||||||
|
|
||||||
|
gp_XYZ p1 = SMESH_NodeXYZ( polySeg.myNode1[0] );
|
||||||
|
gp_XYZ p2 = SMESH_NodeXYZ( polySeg.myNode1[1] );
|
||||||
|
if ( polySeg.myNode2[0] ) p1 = 0.5 * ( p1 + SMESH_NodeXYZ( polySeg.myNode2[0] ));
|
||||||
|
if ( polySeg.myNode2[1] ) p2 = 0.5 * ( p2 + SMESH_NodeXYZ( polySeg.myNode2[1] ));
|
||||||
|
|
||||||
|
gp_XYZ plnNorm = ( p1 - p2 ) ^ polySeg.myVector.XYZ();
|
||||||
|
gp_XYZ plnOrig = p2;
|
||||||
|
|
||||||
|
// find paths connecting the 2 end points of polySeg
|
||||||
|
|
||||||
|
std::vector< Path > paths; paths.reserve(10);
|
||||||
|
|
||||||
|
// initialize paths
|
||||||
|
|
||||||
|
for ( int iP = 0; iP < 2; ++iP ) // loop on the polySeg end points
|
||||||
|
{
|
||||||
|
Path path;
|
||||||
|
path.mySrcPntInd = iP;
|
||||||
|
size_t nbPaths = paths.size();
|
||||||
|
|
||||||
|
if ( polySeg.myNode2[ iP ] && polySeg.myNode2[ iP ] != polySeg.myNode1[ iP ] )
|
||||||
|
{
|
||||||
|
while (( path.myFace = SMESH_MeshAlgos::FindFaceInSet( polySeg.myNode1[ iP ],
|
||||||
|
polySeg.myNode2[ iP ],
|
||||||
|
path.myElemSet,
|
||||||
|
path.myAvoidSet,
|
||||||
|
&path.myNodeInd1,
|
||||||
|
&path.myNodeInd2 )))
|
||||||
|
{
|
||||||
|
path.myNode1.Set( polySeg.myNode1[ iP ]);
|
||||||
|
path.myNode2.Set( polySeg.myNode2[ iP ]);
|
||||||
|
path.myDot1 = plnNorm * ( path.myNode1 - plnOrig );
|
||||||
|
path.myDot2 = plnNorm * ( path.myNode2 - plnOrig );
|
||||||
|
path.myPoints.clear();
|
||||||
|
path.AddPoint( 0.5 * ( path.myNode1 + path.myNode2 ));
|
||||||
|
path.myAvoidSet.insert( path.myFace );
|
||||||
|
paths.push_back( path );
|
||||||
|
}
|
||||||
|
if ( nbPaths == paths.size() )
|
||||||
|
throw SALOME_Exception ( SMESH_Comment("No face edge found by point ") << iP+1
|
||||||
|
<< " in a PolySegment " << iSeg );
|
||||||
|
}
|
||||||
|
else // an end point is at node
|
||||||
|
{
|
||||||
|
std::set<const SMDS_MeshNode* > nodes;
|
||||||
|
SMDS_ElemIteratorPtr fIt = polySeg.myNode1[ iP ]->GetInverseElementIterator(SMDSAbs_Face);
|
||||||
|
while ( fIt->more() )
|
||||||
|
{
|
||||||
|
path.myPoints.clear();
|
||||||
|
if ( path.SetCutAtCorner( polySeg.myNode1[ iP ], fIt->next(), plnNorm, plnOrig ))
|
||||||
|
{
|
||||||
|
if (( path.myDot1 * path.myDot2 != 0 ) ||
|
||||||
|
( nodes.insert( path.myDot1 == 0 ? path.myNode1._node : path.myNode2._node ).second ))
|
||||||
|
paths.push_back( path );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// look for a one-segment path
|
||||||
|
for ( size_t i = 0; i < nbPaths; ++i )
|
||||||
|
for ( size_t j = nbPaths; j < paths.size(); ++j )
|
||||||
|
if ( paths[i].myFace == paths[j].myFace )
|
||||||
|
{
|
||||||
|
myPaths[ iSeg ].myPoints.push_back( paths[i].myPoints[0] );
|
||||||
|
myPaths[ iSeg ].myPoints.push_back( paths[j].myPoints[0] );
|
||||||
|
paths.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// extend paths
|
||||||
|
|
||||||
|
myPaths[ iSeg ].myLength = 1e100;
|
||||||
|
|
||||||
|
while ( paths.size() >= 2 )
|
||||||
|
{
|
||||||
|
for ( size_t i = 0; i < paths.size(); ++i )
|
||||||
|
{
|
||||||
|
Path& path = paths[ i ];
|
||||||
|
if ( !path.Extend( plnNorm, plnOrig ) || // path reached a mesh boundary
|
||||||
|
path.myLength > myPaths[ iSeg ].myLength ) // path is longer than others
|
||||||
|
{
|
||||||
|
Path::Remove( paths, i );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// join paths that reach same point
|
||||||
|
for ( size_t j = 0; j < paths.size(); ++j )
|
||||||
|
{
|
||||||
|
if ( i != j && paths[i].ReachSamePoint( paths[j] ))
|
||||||
|
{
|
||||||
|
double distLast = ( paths[i].myPoints.back() - paths[j].myPoints.back() ).Modulus();
|
||||||
|
double fullLength = ( paths[i].myLength + paths[j].myLength + distLast );
|
||||||
|
if ( fullLength < myPaths[ iSeg ].myLength )
|
||||||
|
{
|
||||||
|
myPaths[ iSeg ].myLength = fullLength;
|
||||||
|
std::vector< gp_XYZ > & allPoints = myPaths[ iSeg ].myPoints;
|
||||||
|
allPoints.swap( paths[i].myPoints );
|
||||||
|
allPoints.insert( allPoints.end(),
|
||||||
|
paths[j].myPoints.rbegin(),
|
||||||
|
paths[j].myPoints.rend() );
|
||||||
|
}
|
||||||
|
Path::Remove( paths, i );
|
||||||
|
Path::Remove( paths, j );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( !paths.empty() && (int) paths[0].myPoints.size() > myMesh->NbFaces() )
|
||||||
|
throw SALOME_Exception(LOCALIZED( "Infinite loop in MakePolyLine()"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( myPaths[ iSeg ].myPoints.empty() )
|
||||||
|
throw SALOME_Exception( SMESH_Comment("Can't find a full path for PolySegment #") << iSeg );
|
||||||
|
|
||||||
|
} // PolyPathCompute::Compute()
|
||||||
|
|
||||||
|
}; // struct PolyPathCompute
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : MakePolyLine
|
||||||
|
//purpose : Create a polyline consisting of 1D mesh elements each lying on a 2D element of
|
||||||
|
// the initial mesh
|
||||||
|
//=======================================================================
|
||||||
|
|
||||||
|
void SMESH_MeshEditor::MakePolyLine( TListOfPolySegments& theSegments,
|
||||||
|
SMESHDS_Group* theGroup,
|
||||||
|
SMESH_ElementSearcher* theSearcher)
|
||||||
|
{
|
||||||
|
std::vector< Path > segPaths( theSegments.size() ); // path of each of segments
|
||||||
|
|
||||||
|
SMESH_ElementSearcher* searcher = theSearcher;
|
||||||
|
SMESHUtils::Deleter<SMESH_ElementSearcher> delSearcher;
|
||||||
|
if ( !searcher )
|
||||||
|
{
|
||||||
|
searcher = SMESH_MeshAlgos::GetElementSearcher( *GetMeshDS() );
|
||||||
|
delSearcher._obj = searcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get cutting planes
|
||||||
|
|
||||||
|
std::vector< bool > isVectorOK( theSegments.size(), true );
|
||||||
|
const double planarCoef = 0.333; // plane height in planar case
|
||||||
|
|
||||||
|
for ( size_t iSeg = 0; iSeg < theSegments.size(); ++iSeg )
|
||||||
|
{
|
||||||
|
PolySegment& polySeg = theSegments[ iSeg ];
|
||||||
|
|
||||||
|
gp_XYZ p1 = SMESH_NodeXYZ( polySeg.myNode1[0] );
|
||||||
|
gp_XYZ p2 = SMESH_NodeXYZ( polySeg.myNode1[1] );
|
||||||
|
if ( polySeg.myNode2[0] ) p1 = 0.5 * ( p1 + SMESH_NodeXYZ( polySeg.myNode2[0] ));
|
||||||
|
if ( polySeg.myNode2[1] ) p2 = 0.5 * ( p2 + SMESH_NodeXYZ( polySeg.myNode2[1] ));
|
||||||
|
|
||||||
|
gp_XYZ plnNorm = ( p1 - p2 ) ^ polySeg.myVector.XYZ();
|
||||||
|
|
||||||
|
isVectorOK[ iSeg ] = ( plnNorm.Modulus() > std::numeric_limits<double>::min() );
|
||||||
|
if ( !isVectorOK[ iSeg ])
|
||||||
|
{
|
||||||
|
gp_XYZ pMid = 0.5 * ( p1 + p2 );
|
||||||
|
const SMDS_MeshElement* face;
|
||||||
|
polySeg.myMidProjPoint = searcher->Project( pMid, SMDSAbs_Face, &face );
|
||||||
|
polySeg.myVector = polySeg.myMidProjPoint.XYZ() - pMid;
|
||||||
|
|
||||||
|
gp_XYZ faceNorm;
|
||||||
|
SMESH_MeshAlgos::FaceNormal( face, faceNorm );
|
||||||
|
|
||||||
|
if ( polySeg.myVector.Magnitude() < Precision::Confusion() ||
|
||||||
|
polySeg.myVector * faceNorm < Precision::Confusion() )
|
||||||
|
{
|
||||||
|
polySeg.myVector = faceNorm;
|
||||||
|
polySeg.myMidProjPoint = pMid + faceNorm * ( p1 - p2 ).Modulus() * planarCoef;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
polySeg.myVector = plnNorm ^ ( p1 - p2 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// assure that inverse elements are constructed, avoid their concurrent building in threads
|
||||||
|
GetMeshDS()->nodesIterator()->next()->NbInverseElements();
|
||||||
|
|
||||||
|
// find paths
|
||||||
|
|
||||||
|
PolyPathCompute algo( theSegments, segPaths, myMesh );
|
||||||
|
OSD_Parallel::For( 0, theSegments.size(), algo, theSegments.size() == 1 );
|
||||||
|
|
||||||
|
for ( size_t iSeg = 0; iSeg < theSegments.size(); ++iSeg )
|
||||||
|
if ( !algo.myErrors[ iSeg ].empty() )
|
||||||
|
throw SALOME_Exception( algo.myErrors[ iSeg ].c_str() );
|
||||||
|
|
||||||
|
// create an 1D mesh
|
||||||
|
|
||||||
|
const SMDS_MeshNode *n, *nPrev = 0;
|
||||||
|
SMESHDS_Mesh* mesh = GetMeshDS();
|
||||||
|
|
||||||
|
for ( size_t iSeg = 0; iSeg < theSegments.size(); ++iSeg )
|
||||||
|
{
|
||||||
|
const Path& path = segPaths[iSeg];
|
||||||
|
if ( path.myPoints.size() < 2 )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
double tol = path.myLength / path.myPoints.size() / 1000.;
|
||||||
|
if ( !nPrev || ( SMESH_NodeXYZ( nPrev ) - path.myPoints[0] ).SquareModulus() > tol*tol )
|
||||||
|
{
|
||||||
|
nPrev = mesh->AddNode( path.myPoints[0].X(), path.myPoints[0].Y(), path.myPoints[0].Z() );
|
||||||
|
myLastCreatedNodes.Append( nPrev );
|
||||||
|
}
|
||||||
|
for ( size_t iP = 1; iP < path.myPoints.size(); ++iP )
|
||||||
|
{
|
||||||
|
n = mesh->AddNode( path.myPoints[iP].X(), path.myPoints[iP].Y(), path.myPoints[iP].Z() );
|
||||||
|
myLastCreatedNodes.Append( n );
|
||||||
|
|
||||||
|
const SMDS_MeshElement* elem = mesh->AddEdge( nPrev, n );
|
||||||
|
myLastCreatedElems.Append( elem );
|
||||||
|
if ( theGroup )
|
||||||
|
theGroup->Add( elem );
|
||||||
|
|
||||||
|
nPrev = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return a vector
|
||||||
|
|
||||||
|
gp_XYZ pMid = 0.5 * ( path.myPoints[0] + path.myPoints.back() );
|
||||||
|
if ( isVectorOK[ iSeg ])
|
||||||
|
{
|
||||||
|
// find the most distance point of a path
|
||||||
|
double maxDist = 0;
|
||||||
|
for ( size_t iP = 1; iP < path.myPoints.size(); ++iP )
|
||||||
|
{
|
||||||
|
double dist = Abs( theSegments[iSeg].myVector * ( path.myPoints[iP] - path.myPoints[0] ));
|
||||||
|
if ( dist > maxDist )
|
||||||
|
{
|
||||||
|
maxDist = dist;
|
||||||
|
theSegments[iSeg].myMidProjPoint = path.myPoints[iP];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( maxDist < Precision::Confusion() ) // planar case
|
||||||
|
theSegments[iSeg].myMidProjPoint =
|
||||||
|
pMid + theSegments[iSeg].myVector.XYZ().Normalized() * path.myLength * planarCoef;
|
||||||
|
}
|
||||||
|
theSegments[iSeg].myVector = gp_Vec( pMid, theSegments[iSeg].myMidProjPoint );
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
@ -46,8 +46,10 @@
|
|||||||
class SMDS_MeshElement;
|
class SMDS_MeshElement;
|
||||||
class SMDS_MeshFace;
|
class SMDS_MeshFace;
|
||||||
class SMDS_MeshNode;
|
class SMDS_MeshNode;
|
||||||
|
class SMESHDS_Group;
|
||||||
class SMESHDS_Mesh;
|
class SMESHDS_Mesh;
|
||||||
class SMESHDS_SubMesh;
|
class SMESHDS_SubMesh;
|
||||||
|
class SMESH_ElementSearcher;
|
||||||
class SMESH_Group;
|
class SMESH_Group;
|
||||||
class SMESH_Mesh;
|
class SMESH_Mesh;
|
||||||
class SMESH_MesherHelper;
|
class SMESH_MesherHelper;
|
||||||
@ -707,6 +709,42 @@ public:
|
|||||||
bool toAddExistingBondary = false,
|
bool toAddExistingBondary = false,
|
||||||
bool aroundElements = false);
|
bool aroundElements = false);
|
||||||
|
|
||||||
|
|
||||||
|
// structure used in MakePolyLine() to define a cutting plane
|
||||||
|
struct PolySegment
|
||||||
|
{
|
||||||
|
// 2 points: if myNode2 != 0, then the point is the middle of a face edge defined
|
||||||
|
// by two nodes, else it is at myNode1
|
||||||
|
const SMDS_MeshNode* myNode1[2];
|
||||||
|
const SMDS_MeshNode* myNode2[2];
|
||||||
|
|
||||||
|
gp_Vec myVector; // vector on the plane; to use a default plane set vector = (0,0,0)
|
||||||
|
|
||||||
|
// point to return coordinates of a middle of the two points, projected to mesh
|
||||||
|
gp_Pnt myMidProjPoint;
|
||||||
|
};
|
||||||
|
typedef std::vector<PolySegment> TListOfPolySegments;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Create a polyline consisting of 1D mesh elements each lying on a 2D element of
|
||||||
|
* the initial mesh. Positions of new nodes are found by cutting the mesh by the
|
||||||
|
* plane passing through pairs of points specified by each PolySegment structure.
|
||||||
|
* If there are several paths connecting a pair of points, the shortest path is
|
||||||
|
* selected by the module. Position of the cutting plane is defined by the two
|
||||||
|
* points and an optional vector lying on the plane specified by a PolySegment.
|
||||||
|
* By default the vector is defined by Mesh module as following. A middle point
|
||||||
|
* of the two given points is computed. The middle point is projected to the mesh.
|
||||||
|
* The vector goes from the middle point to the projection point. In case of planar
|
||||||
|
* mesh, the vector is normal to the mesh.
|
||||||
|
* \param [inout] segments - PolySegment's defining positions of cutting planes.
|
||||||
|
* Return the used vector and position of the middle point.
|
||||||
|
* \param [in] group - an optional group where created mesh segments will
|
||||||
|
* be added.
|
||||||
|
*/
|
||||||
|
void MakePolyLine( TListOfPolySegments& segments,
|
||||||
|
SMESHDS_Group* group=0,
|
||||||
|
SMESH_ElementSearcher* searcher=0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -22,6 +22,9 @@
|
|||||||
|
|
||||||
// File : SMESHGUI_SingleEditDlg.cxx
|
// File : SMESHGUI_SingleEditDlg.cxx
|
||||||
// Author : Sergey LITONIN, Open CASCADE S.A.S.
|
// Author : Sergey LITONIN, Open CASCADE S.A.S.
|
||||||
|
|
||||||
|
#include <SVTK_Selector.h>
|
||||||
|
|
||||||
// SMESH includes
|
// SMESH includes
|
||||||
//
|
//
|
||||||
#include "SMESHGUI_SingleEditDlg.h"
|
#include "SMESHGUI_SingleEditDlg.h"
|
||||||
@ -42,7 +45,6 @@
|
|||||||
#include <SUIT_Desktop.h>
|
#include <SUIT_Desktop.h>
|
||||||
#include <SUIT_Session.h>
|
#include <SUIT_Session.h>
|
||||||
|
|
||||||
#include <SVTK_Selector.h>
|
|
||||||
#include <SVTK_ViewWindow.h>
|
#include <SVTK_ViewWindow.h>
|
||||||
#include <SALOME_ListIO.hxx>
|
#include <SALOME_ListIO.hxx>
|
||||||
|
|
||||||
@ -347,9 +349,9 @@ void SMESHGUI_SingleEditDlg::onTextChange (const QString& theNewText)
|
|||||||
aList.Append(anIO);
|
aList.Append(anIO);
|
||||||
mySelectionMgr->setSelectedObjects(aList,false);
|
mySelectionMgr->setSelectedObjects(aList,false);
|
||||||
|
|
||||||
TColStd_IndexedMapOfInteger selectedIndices;
|
SVTK_IndexedMapOfIds selectedIndices;
|
||||||
TColStd_MapOfInteger newIndices;
|
SVTK_ListOfInteger newIndices;
|
||||||
mySelector->GetIndex(anIO,selectedIndices);
|
mySelector->GetCompositeIndex(anIO,selectedIndices);
|
||||||
|
|
||||||
int id1, id2;
|
int id1, id2;
|
||||||
if ( !getNodeIds(myEdge->text(), id1, id2) )
|
if ( !getNodeIds(myEdge->text(), id1, id2) )
|
||||||
@ -367,25 +369,13 @@ void SMESHGUI_SingleEditDlg::onTextChange (const QString& theNewText)
|
|||||||
|
|
||||||
if ( findTriangles(aNode1,aNode2,tria1,tria2) )
|
if ( findTriangles(aNode1,aNode2,tria1,tria2) )
|
||||||
{
|
{
|
||||||
newIndices.Add(tria1->GetID());
|
newIndices.push_back( aNode1->GetID() );
|
||||||
|
newIndices.push_back( aNode2->GetID() );
|
||||||
const SMDS_MeshNode* a3Nodes[3];
|
|
||||||
SMDS_ElemIteratorPtr it;
|
|
||||||
int edgeInd = 2, i;
|
|
||||||
for (i = 0, it = tria1->nodesIterator(); it->more(); i++) {
|
|
||||||
a3Nodes[ i ] = static_cast<const SMDS_MeshNode*>(it->next());
|
|
||||||
if (i > 0 && ( (a3Nodes[ i ] == aNode1 && a3Nodes[ i - 1] == aNode2) ||
|
|
||||||
(a3Nodes[ i ] == aNode2 && a3Nodes[ i - 1] == aNode1) ) ) {
|
|
||||||
edgeInd = i - 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
newIndices.Add(-edgeInd-1);
|
|
||||||
|
|
||||||
myOkBtn->setEnabled(true);
|
myOkBtn->setEnabled(true);
|
||||||
myApplyBtn->setEnabled(true);
|
myApplyBtn->setEnabled(true);
|
||||||
}
|
}
|
||||||
mySelector->AddOrRemoveIndex(anIO,newIndices, false);
|
mySelector->AddOrRemoveCompositeIndex(anIO, newIndices, false);
|
||||||
SMESH::GetViewWindow(mySMESHGUI)->highlight( anIO, true, true );
|
SMESH::GetViewWindow(mySMESHGUI)->highlight( anIO, true, true );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -420,7 +410,17 @@ void SMESHGUI_SingleEditDlg::onSelectionDone()
|
|||||||
if(SMDS_Mesh* aMesh = aVisualObj->GetMesh())
|
if(SMDS_Mesh* aMesh = aVisualObj->GetMesh())
|
||||||
{
|
{
|
||||||
const SMDS_MeshElement* tria[2];
|
const SMDS_MeshElement* tria[2];
|
||||||
if( SMESH::GetEdgeNodes( mySelector, aVisualObj, anId1, anId2 ) >= 1 &&
|
|
||||||
|
bool valid = false;
|
||||||
|
SVTK_IndexedMapOfIds anIds;
|
||||||
|
mySelector->GetCompositeIndex(anIO,anIds);
|
||||||
|
if( anIds.Extent() == 1 && anIds(1).size() == 2 ) {
|
||||||
|
anId1 = anIds(1)[0];
|
||||||
|
anId2 = anIds(1)[1];
|
||||||
|
valid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( valid &&
|
||||||
findTriangles( aMesh->FindNode( anId1 ), aMesh->FindNode( anId2 ), tria[0],tria[1] ) )
|
findTriangles( aMesh->FindNode( anId1 ), aMesh->FindNode( anId2 ), tria[0],tria[1] ) )
|
||||||
{
|
{
|
||||||
QString aText = QString("%1-%2").arg(anId1).arg(anId2);
|
QString aText = QString("%1-%2").arg(anId1).arg(anId2);
|
||||||
@ -523,6 +523,7 @@ bool SMESHGUI_SingleEditDlg::onApply()
|
|||||||
// update actor
|
// update actor
|
||||||
if (aResult) {
|
if (aResult) {
|
||||||
mySelector->ClearIndex();
|
mySelector->ClearIndex();
|
||||||
|
mySelector->ClearCompositeIndex();
|
||||||
mySelectionMgr->setSelectedObjects(aList, false);
|
mySelectionMgr->setSelectedObjects(aList, false);
|
||||||
onSelectionDone();
|
onSelectionDone();
|
||||||
SMESH::UpdateView();
|
SMESH::UpdateView();
|
||||||
|
@ -35,6 +35,8 @@
|
|||||||
#include "SMDS_VolumeTool.hxx"
|
#include "SMDS_VolumeTool.hxx"
|
||||||
#include "SMESH_OctreeNode.hxx"
|
#include "SMESH_OctreeNode.hxx"
|
||||||
|
|
||||||
|
#include <Utils_SALOME_Exception.hxx>
|
||||||
|
|
||||||
#include <GC_MakeSegment.hxx>
|
#include <GC_MakeSegment.hxx>
|
||||||
#include <GeomAPI_ExtremaCurveCurve.hxx>
|
#include <GeomAPI_ExtremaCurveCurve.hxx>
|
||||||
#include <Geom_Line.hxx>
|
#include <Geom_Line.hxx>
|
||||||
@ -228,15 +230,16 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
|
|||||||
SMDSAbs_ElementType elemType,
|
SMDSAbs_ElementType elemType,
|
||||||
SMDS_ElemIteratorPtr theElemIt = SMDS_ElemIteratorPtr(),
|
SMDS_ElemIteratorPtr theElemIt = SMDS_ElemIteratorPtr(),
|
||||||
double tolerance = NodeRadius );
|
double tolerance = NodeRadius );
|
||||||
void getElementsNearPoint( const gp_Pnt& point, TIDSortedElemSet& foundElems );
|
void prepare(); // !!!call it before calling the following methods!!!
|
||||||
void getElementsNearLine ( const gp_Ax1& line, TIDSortedElemSet& foundElems);
|
void getElementsNearPoint( const gp_Pnt& point, vector<const SMDS_MeshElement*>& foundElems );
|
||||||
|
void getElementsNearLine ( const gp_Ax1& line, vector<const SMDS_MeshElement*>& foundElems);
|
||||||
void getElementsInSphere ( const gp_XYZ& center,
|
void getElementsInSphere ( const gp_XYZ& center,
|
||||||
const double radius, TIDSortedElemSet& foundElems);
|
const double radius,
|
||||||
size_t getSize() { return std::max( _size, _elements.size() ); }
|
vector<const SMDS_MeshElement*>& foundElems);
|
||||||
virtual ~ElementBndBoxTree();
|
ElementBndBoxTree* getLeafAtPoint( const gp_XYZ& point );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ElementBndBoxTree():_size(0) {}
|
ElementBndBoxTree() {}
|
||||||
SMESH_Octree* newChild() const { return new ElementBndBoxTree; }
|
SMESH_Octree* newChild() const { return new ElementBndBoxTree; }
|
||||||
void buildChildrenData();
|
void buildChildrenData();
|
||||||
Bnd_B3d* buildRootBox();
|
Bnd_B3d* buildRootBox();
|
||||||
@ -245,11 +248,25 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
|
|||||||
struct ElementBox : public Bnd_B3d
|
struct ElementBox : public Bnd_B3d
|
||||||
{
|
{
|
||||||
const SMDS_MeshElement* _element;
|
const SMDS_MeshElement* _element;
|
||||||
int _refCount; // an ElementBox can be included in several tree branches
|
bool _isMarked;
|
||||||
ElementBox(const SMDS_MeshElement* elem, double tolerance);
|
void init(const SMDS_MeshElement* elem, double tolerance);
|
||||||
};
|
};
|
||||||
vector< ElementBox* > _elements;
|
vector< ElementBox* > _elements;
|
||||||
size_t _size;
|
|
||||||
|
typedef ObjectPool< ElementBox > TElementBoxPool;
|
||||||
|
|
||||||
|
//!< allocator of ElementBox's and SMESH_TreeLimit
|
||||||
|
struct LimitAndPool : public SMESH_TreeLimit
|
||||||
|
{
|
||||||
|
TElementBoxPool _elBoPool;
|
||||||
|
std::vector< ElementBox* > _markedElems;
|
||||||
|
LimitAndPool():SMESH_TreeLimit( MaxLevel, /*minSize=*/0. ) {}
|
||||||
|
};
|
||||||
|
LimitAndPool* getLimitAndPool() const
|
||||||
|
{
|
||||||
|
SMESH_TreeLimit* limitAndPool = const_cast< SMESH_TreeLimit* >( myLimit );
|
||||||
|
return static_cast< LimitAndPool* >( limitAndPool );
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
@ -258,30 +275,25 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
|
|||||||
*/
|
*/
|
||||||
//================================================================================
|
//================================================================================
|
||||||
|
|
||||||
ElementBndBoxTree::ElementBndBoxTree(const SMDS_Mesh& mesh, SMDSAbs_ElementType elemType, SMDS_ElemIteratorPtr theElemIt, double tolerance)
|
ElementBndBoxTree::ElementBndBoxTree(const SMDS_Mesh& mesh,
|
||||||
:SMESH_Octree( new SMESH_TreeLimit( MaxLevel, /*minSize=*/0. ))
|
SMDSAbs_ElementType elemType,
|
||||||
|
SMDS_ElemIteratorPtr theElemIt,
|
||||||
|
double tolerance)
|
||||||
|
:SMESH_Octree( new LimitAndPool() )
|
||||||
{
|
{
|
||||||
int nbElems = mesh.GetMeshInfo().NbElements( elemType );
|
int nbElems = mesh.GetMeshInfo().NbElements( elemType );
|
||||||
_elements.reserve( nbElems );
|
_elements.reserve( nbElems );
|
||||||
|
|
||||||
|
TElementBoxPool& elBoPool = getLimitAndPool()->_elBoPool;
|
||||||
|
|
||||||
SMDS_ElemIteratorPtr elemIt = theElemIt ? theElemIt : mesh.elementsIterator( elemType );
|
SMDS_ElemIteratorPtr elemIt = theElemIt ? theElemIt : mesh.elementsIterator( elemType );
|
||||||
while ( elemIt->more() )
|
while ( elemIt->more() )
|
||||||
_elements.push_back( new ElementBox( elemIt->next(),tolerance ));
|
|
||||||
|
|
||||||
compute();
|
|
||||||
}
|
|
||||||
|
|
||||||
//================================================================================
|
|
||||||
/*!
|
|
||||||
* \brief Destructor
|
|
||||||
*/
|
|
||||||
//================================================================================
|
|
||||||
|
|
||||||
ElementBndBoxTree::~ElementBndBoxTree()
|
|
||||||
{
|
{
|
||||||
for ( size_t i = 0; i < _elements.size(); ++i )
|
ElementBox* eb = elBoPool.getNew();
|
||||||
if ( --_elements[i]->_refCount <= 0 )
|
eb->init( elemIt->next(), tolerance );
|
||||||
delete _elements[i];
|
_elements.push_back( eb );
|
||||||
|
}
|
||||||
|
compute();
|
||||||
}
|
}
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
@ -311,14 +323,10 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
|
|||||||
for (int j = 0; j < 8; j++)
|
for (int j = 0; j < 8; j++)
|
||||||
{
|
{
|
||||||
if ( !_elements[i]->IsOut( *myChildren[j]->getBox() ))
|
if ( !_elements[i]->IsOut( *myChildren[j]->getBox() ))
|
||||||
{
|
|
||||||
_elements[i]->_refCount++;
|
|
||||||
((ElementBndBoxTree*)myChildren[j])->_elements.push_back( _elements[i]);
|
((ElementBndBoxTree*)myChildren[j])->_elements.push_back( _elements[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_elements[i]->_refCount--;
|
//_size = _elements.size();
|
||||||
}
|
|
||||||
_size = _elements.size();
|
|
||||||
SMESHUtils::FreeVector( _elements ); // = _elements.clear() + free memory
|
SMESHUtils::FreeVector( _elements ); // = _elements.clear() + free memory
|
||||||
|
|
||||||
for (int j = 0; j < 8; j++)
|
for (int j = 0; j < 8; j++)
|
||||||
@ -327,11 +335,24 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
|
|||||||
if ((int) child->_elements.size() <= MaxNbElemsInLeaf )
|
if ((int) child->_elements.size() <= MaxNbElemsInLeaf )
|
||||||
child->myIsLeaf = true;
|
child->myIsLeaf = true;
|
||||||
|
|
||||||
if ( child->_elements.capacity() - child->_elements.size() > 1000 )
|
if ( child->isLeaf() && child->_elements.capacity() > child->_elements.size() )
|
||||||
SMESHUtils::CompactVector( child->_elements );
|
SMESHUtils::CompactVector( child->_elements );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Un-mark all elements
|
||||||
|
*/
|
||||||
|
//================================================================================
|
||||||
|
|
||||||
|
void ElementBndBoxTree::prepare()
|
||||||
|
{
|
||||||
|
// TElementBoxPool& elBoPool = getElementBoxPool();
|
||||||
|
// for ( size_t i = 0; i < elBoPool.nbElements(); ++i )
|
||||||
|
// const_cast< ElementBox* >( elBoPool[ i ])->_isMarked = false;
|
||||||
|
}
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
/*!
|
/*!
|
||||||
* \brief Return elements which can include the point
|
* \brief Return elements which can include the point
|
||||||
@ -339,21 +360,36 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
|
|||||||
//================================================================================
|
//================================================================================
|
||||||
|
|
||||||
void ElementBndBoxTree::getElementsNearPoint( const gp_Pnt& point,
|
void ElementBndBoxTree::getElementsNearPoint( const gp_Pnt& point,
|
||||||
TIDSortedElemSet& foundElems)
|
vector<const SMDS_MeshElement*>& foundElems)
|
||||||
{
|
{
|
||||||
if ( getBox()->IsOut( point.XYZ() ))
|
if ( getBox()->IsOut( point.XYZ() ))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( isLeaf() )
|
if ( isLeaf() )
|
||||||
{
|
{
|
||||||
|
LimitAndPool* pool = getLimitAndPool();
|
||||||
|
|
||||||
for ( size_t i = 0; i < _elements.size(); ++i )
|
for ( size_t i = 0; i < _elements.size(); ++i )
|
||||||
if ( !_elements[i]->IsOut( point.XYZ() ))
|
if ( !_elements[i]->IsOut( point.XYZ() ) &&
|
||||||
foundElems.insert( _elements[i]->_element );
|
!_elements[i]->_isMarked )
|
||||||
|
{
|
||||||
|
foundElems.push_back( _elements[i]->_element );
|
||||||
|
_elements[i]->_isMarked = true;
|
||||||
|
pool->_markedElems.push_back( _elements[i] );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
((ElementBndBoxTree*) myChildren[i])->getElementsNearPoint( point, foundElems );
|
((ElementBndBoxTree*) myChildren[i])->getElementsNearPoint( point, foundElems );
|
||||||
|
|
||||||
|
if ( level() == 0 )
|
||||||
|
{
|
||||||
|
LimitAndPool* pool = getLimitAndPool();
|
||||||
|
for ( size_t i = 0; i < pool->_markedElems.size(); ++i )
|
||||||
|
pool->_markedElems[i]->_isMarked = false;
|
||||||
|
pool->_markedElems.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,21 +400,36 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
|
|||||||
//================================================================================
|
//================================================================================
|
||||||
|
|
||||||
void ElementBndBoxTree::getElementsNearLine( const gp_Ax1& line,
|
void ElementBndBoxTree::getElementsNearLine( const gp_Ax1& line,
|
||||||
TIDSortedElemSet& foundElems)
|
vector<const SMDS_MeshElement*>& foundElems)
|
||||||
{
|
{
|
||||||
if ( getBox()->IsOut( line ))
|
if ( getBox()->IsOut( line ))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( isLeaf() )
|
if ( isLeaf() )
|
||||||
{
|
{
|
||||||
|
LimitAndPool* pool = getLimitAndPool();
|
||||||
|
|
||||||
for ( size_t i = 0; i < _elements.size(); ++i )
|
for ( size_t i = 0; i < _elements.size(); ++i )
|
||||||
if ( !_elements[i]->IsOut( line ))
|
if ( !_elements[i]->IsOut( line ) &&
|
||||||
foundElems.insert( _elements[i]->_element );
|
!_elements[i]->_isMarked )
|
||||||
|
{
|
||||||
|
foundElems.push_back( _elements[i]->_element );
|
||||||
|
_elements[i]->_isMarked = true;
|
||||||
|
pool->_markedElems.push_back( _elements[i] );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
((ElementBndBoxTree*) myChildren[i])->getElementsNearLine( line, foundElems );
|
((ElementBndBoxTree*) myChildren[i])->getElementsNearLine( line, foundElems );
|
||||||
|
|
||||||
|
if ( level() == 0 )
|
||||||
|
{
|
||||||
|
LimitAndPool* pool = getLimitAndPool();
|
||||||
|
for ( size_t i = 0; i < pool->_markedElems.size(); ++i )
|
||||||
|
pool->_markedElems[i]->_isMarked = false;
|
||||||
|
pool->_markedElems.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,23 +441,62 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
|
|||||||
|
|
||||||
void ElementBndBoxTree::getElementsInSphere ( const gp_XYZ& center,
|
void ElementBndBoxTree::getElementsInSphere ( const gp_XYZ& center,
|
||||||
const double radius,
|
const double radius,
|
||||||
TIDSortedElemSet& foundElems)
|
vector<const SMDS_MeshElement*>& foundElems)
|
||||||
{
|
{
|
||||||
if ( getBox()->IsOut( center, radius ))
|
if ( getBox()->IsOut( center, radius ))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( isLeaf() )
|
if ( isLeaf() )
|
||||||
{
|
{
|
||||||
|
LimitAndPool* pool = getLimitAndPool();
|
||||||
|
|
||||||
for ( size_t i = 0; i < _elements.size(); ++i )
|
for ( size_t i = 0; i < _elements.size(); ++i )
|
||||||
if ( !_elements[i]->IsOut( center, radius ))
|
if ( !_elements[i]->IsOut( center, radius ) &&
|
||||||
foundElems.insert( _elements[i]->_element );
|
!_elements[i]->_isMarked )
|
||||||
|
{
|
||||||
|
foundElems.push_back( _elements[i]->_element );
|
||||||
|
_elements[i]->_isMarked = true;
|
||||||
|
pool->_markedElems.push_back( _elements[i] );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
((ElementBndBoxTree*) myChildren[i])->getElementsInSphere( center, radius, foundElems );
|
((ElementBndBoxTree*) myChildren[i])->getElementsInSphere( center, radius, foundElems );
|
||||||
|
|
||||||
|
if ( level() == 0 )
|
||||||
|
{
|
||||||
|
LimitAndPool* pool = getLimitAndPool();
|
||||||
|
for ( size_t i = 0; i < pool->_markedElems.size(); ++i )
|
||||||
|
pool->_markedElems[i]->_isMarked = false;
|
||||||
|
pool->_markedElems.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Return a leaf including a point
|
||||||
|
*/
|
||||||
|
//================================================================================
|
||||||
|
|
||||||
|
ElementBndBoxTree* ElementBndBoxTree::getLeafAtPoint( const gp_XYZ& point )
|
||||||
|
{
|
||||||
|
if ( getBox()->IsOut( point ))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ( isLeaf() )
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
if ( ElementBndBoxTree* l = ((ElementBndBoxTree*) myChildren[i])->getLeafAtPoint( point ))
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
/*!
|
/*!
|
||||||
@ -414,13 +504,13 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
|
|||||||
*/
|
*/
|
||||||
//================================================================================
|
//================================================================================
|
||||||
|
|
||||||
ElementBndBoxTree::ElementBox::ElementBox(const SMDS_MeshElement* elem, double tolerance)
|
void ElementBndBoxTree::ElementBox::init(const SMDS_MeshElement* elem, double tolerance)
|
||||||
{
|
{
|
||||||
_element = elem;
|
_element = elem;
|
||||||
_refCount = 1;
|
_isMarked = false;
|
||||||
SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
|
SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
|
||||||
while ( nIt->more() )
|
while ( nIt->more() )
|
||||||
Add( SMESH_TNodeXYZ( nIt->next() ));
|
Add( SMESH_NodeXYZ( nIt->next() ));
|
||||||
Enlarge( tolerance );
|
Enlarge( tolerance );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,13 +566,16 @@ struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher
|
|||||||
virtual const SMDS_MeshElement* FindClosestTo( const gp_Pnt& point,
|
virtual const SMDS_MeshElement* FindClosestTo( const gp_Pnt& point,
|
||||||
SMDSAbs_ElementType type );
|
SMDSAbs_ElementType type );
|
||||||
|
|
||||||
void GetElementsNearLine( const gp_Ax1& line,
|
virtual void GetElementsNearLine( const gp_Ax1& line,
|
||||||
SMDSAbs_ElementType type,
|
SMDSAbs_ElementType type,
|
||||||
vector< const SMDS_MeshElement* >& foundElems);
|
vector< const SMDS_MeshElement* >& foundElems);
|
||||||
void GetElementsInSphere( const gp_XYZ& center,
|
virtual void GetElementsInSphere( const gp_XYZ& center,
|
||||||
const double radius,
|
const double radius,
|
||||||
SMDSAbs_ElementType type,
|
SMDSAbs_ElementType type,
|
||||||
vector< const SMDS_MeshElement* >& foundElems);
|
vector< const SMDS_MeshElement* >& foundElems);
|
||||||
|
virtual gp_XYZ Project(const gp_Pnt& point,
|
||||||
|
SMDSAbs_ElementType type,
|
||||||
|
const SMDS_MeshElement** closestElem);
|
||||||
double getTolerance();
|
double getTolerance();
|
||||||
bool getIntersParamOnLine(const gp_Lin& line, const SMDS_MeshElement* face,
|
bool getIntersParamOnLine(const gp_Lin& line, const SMDS_MeshElement* face,
|
||||||
const double tolerance, double & param);
|
const double tolerance, double & param);
|
||||||
@ -604,7 +697,7 @@ bool SMESH_ElementSearcherImpl::getIntersParamOnLine(const gp_Lin& lin
|
|||||||
anExtCC.Init( lineCurve, edge.Value() );
|
anExtCC.Init( lineCurve, edge.Value() );
|
||||||
if ( anExtCC.NbExtrema() > 0 && anExtCC.LowerDistance() <= tol)
|
if ( anExtCC.NbExtrema() > 0 && anExtCC.LowerDistance() <= tol)
|
||||||
{
|
{
|
||||||
Quantity_Parameter pl, pe;
|
Standard_Real pl, pe;
|
||||||
anExtCC.LowerDistanceParameters( pl, pe );
|
anExtCC.LowerDistanceParameters( pl, pe );
|
||||||
param += pl;
|
param += pl;
|
||||||
if ( ++nbInts == 2 )
|
if ( ++nbInts == 2 )
|
||||||
@ -771,9 +864,13 @@ FindElementsByPoint(const gp_Pnt& point,
|
|||||||
{
|
{
|
||||||
_ebbTree[_elementType] = new ElementBndBoxTree( *_mesh, type, _meshPartIt, tolerance );
|
_ebbTree[_elementType] = new ElementBndBoxTree( *_mesh, type, _meshPartIt, tolerance );
|
||||||
}
|
}
|
||||||
TIDSortedElemSet suspectElems;
|
else
|
||||||
|
{
|
||||||
|
_ebbTree[ type ]->prepare();
|
||||||
|
}
|
||||||
|
vector< const SMDS_MeshElement* > suspectElems;
|
||||||
_ebbTree[ type ]->getElementsNearPoint( point, suspectElems );
|
_ebbTree[ type ]->getElementsNearPoint( point, suspectElems );
|
||||||
TIDSortedElemSet::iterator elem = suspectElems.begin();
|
vector< const SMDS_MeshElement* >::iterator elem = suspectElems.begin();
|
||||||
for ( ; elem != suspectElems.end(); ++elem )
|
for ( ; elem != suspectElems.end(); ++elem )
|
||||||
if ( !SMESH_MeshAlgos::IsOut( *elem, point, tolerance ))
|
if ( !SMESH_MeshAlgos::IsOut( *elem, point, tolerance ))
|
||||||
foundElements.push_back( *elem );
|
foundElements.push_back( *elem );
|
||||||
@ -801,8 +898,10 @@ SMESH_ElementSearcherImpl::FindClosestTo( const gp_Pnt& point,
|
|||||||
ElementBndBoxTree*& ebbTree = _ebbTree[ type ];
|
ElementBndBoxTree*& ebbTree = _ebbTree[ type ];
|
||||||
if ( !ebbTree )
|
if ( !ebbTree )
|
||||||
ebbTree = new ElementBndBoxTree( *_mesh, type, _meshPartIt );
|
ebbTree = new ElementBndBoxTree( *_mesh, type, _meshPartIt );
|
||||||
|
else
|
||||||
|
ebbTree->prepare();
|
||||||
|
|
||||||
TIDSortedElemSet suspectElems;
|
vector<const SMDS_MeshElement*> suspectElems;
|
||||||
ebbTree->getElementsNearPoint( point, suspectElems );
|
ebbTree->getElementsNearPoint( point, suspectElems );
|
||||||
|
|
||||||
if ( suspectElems.empty() && ebbTree->maxSize() > 0 )
|
if ( suspectElems.empty() && ebbTree->maxSize() > 0 )
|
||||||
@ -816,13 +915,14 @@ SMESH_ElementSearcherImpl::FindClosestTo( const gp_Pnt& point,
|
|||||||
radius = ebbTree->maxSize() / pow( 2., getTreeHeight()) / 2;
|
radius = ebbTree->maxSize() / pow( 2., getTreeHeight()) / 2;
|
||||||
while ( suspectElems.empty() )
|
while ( suspectElems.empty() )
|
||||||
{
|
{
|
||||||
|
ebbTree->prepare();
|
||||||
ebbTree->getElementsInSphere( point.XYZ(), radius, suspectElems );
|
ebbTree->getElementsInSphere( point.XYZ(), radius, suspectElems );
|
||||||
radius *= 1.1;
|
radius *= 1.1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
double minDist = std::numeric_limits<double>::max();
|
double minDist = std::numeric_limits<double>::max();
|
||||||
multimap< double, const SMDS_MeshElement* > dist2face;
|
multimap< double, const SMDS_MeshElement* > dist2face;
|
||||||
TIDSortedElemSet::iterator elem = suspectElems.begin();
|
vector<const SMDS_MeshElement*>::iterator elem = suspectElems.begin();
|
||||||
for ( ; elem != suspectElems.end(); ++elem )
|
for ( ; elem != suspectElems.end(); ++elem )
|
||||||
{
|
{
|
||||||
double dist = SMESH_MeshAlgos::GetDistance( *elem, point );
|
double dist = SMESH_MeshAlgos::GetDistance( *elem, point );
|
||||||
@ -886,6 +986,8 @@ TopAbs_State SMESH_ElementSearcherImpl::GetPointState(const gp_Pnt& point)
|
|||||||
ElementBndBoxTree*& ebbTree = _ebbTree[ SMDSAbs_Face ];
|
ElementBndBoxTree*& ebbTree = _ebbTree[ SMDSAbs_Face ];
|
||||||
if ( !ebbTree )
|
if ( !ebbTree )
|
||||||
ebbTree = new ElementBndBoxTree( *_mesh, _elementType, _meshPartIt );
|
ebbTree = new ElementBndBoxTree( *_mesh, _elementType, _meshPartIt );
|
||||||
|
else
|
||||||
|
ebbTree->prepare();
|
||||||
|
|
||||||
// Algo: analyse transition of a line starting at the point through mesh boundary;
|
// Algo: analyse transition of a line starting at the point through mesh boundary;
|
||||||
// try three lines parallel to axis of the coordinate system and perform rough
|
// try three lines parallel to axis of the coordinate system and perform rough
|
||||||
@ -901,13 +1003,14 @@ TopAbs_State SMESH_ElementSearcherImpl::GetPointState(const gp_Pnt& point)
|
|||||||
gp_Ax1 lineAxis( point, axisDir[axis]);
|
gp_Ax1 lineAxis( point, axisDir[axis]);
|
||||||
gp_Lin line ( lineAxis );
|
gp_Lin line ( lineAxis );
|
||||||
|
|
||||||
TIDSortedElemSet suspectFaces; // faces possibly intersecting the line
|
vector<const SMDS_MeshElement*> suspectFaces; // faces possibly intersecting the line
|
||||||
|
if ( axis > 0 ) ebbTree->prepare();
|
||||||
ebbTree->getElementsNearLine( lineAxis, suspectFaces );
|
ebbTree->getElementsNearLine( lineAxis, suspectFaces );
|
||||||
|
|
||||||
// Intersect faces with the line
|
// Intersect faces with the line
|
||||||
|
|
||||||
map< double, TInters > & u2inters = paramOnLine2TInters[ axis ];
|
map< double, TInters > & u2inters = paramOnLine2TInters[ axis ];
|
||||||
TIDSortedElemSet::iterator face = suspectFaces.begin();
|
vector<const SMDS_MeshElement*>::iterator face = suspectFaces.begin();
|
||||||
for ( ; face != suspectFaces.end(); ++face )
|
for ( ; face != suspectFaces.end(); ++face )
|
||||||
{
|
{
|
||||||
// get face plane
|
// get face plane
|
||||||
@ -1114,10 +1217,10 @@ void SMESH_ElementSearcherImpl::GetElementsNearLine( const gp_Ax1&
|
|||||||
ElementBndBoxTree*& ebbTree = _ebbTree[ type ];
|
ElementBndBoxTree*& ebbTree = _ebbTree[ type ];
|
||||||
if ( !ebbTree )
|
if ( !ebbTree )
|
||||||
ebbTree = new ElementBndBoxTree( *_mesh, _elementType, _meshPartIt );
|
ebbTree = new ElementBndBoxTree( *_mesh, _elementType, _meshPartIt );
|
||||||
|
else
|
||||||
|
ebbTree->prepare();
|
||||||
|
|
||||||
TIDSortedElemSet suspectFaces; // elements possibly intersecting the line
|
ebbTree->getElementsNearLine( line, foundElems );
|
||||||
ebbTree->getElementsNearLine( line, suspectFaces );
|
|
||||||
foundElems.assign( suspectFaces.begin(), suspectFaces.end());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
@ -1135,10 +1238,59 @@ void SMESH_ElementSearcherImpl::GetElementsInSphere( const gp_XYZ&
|
|||||||
ElementBndBoxTree*& ebbTree = _ebbTree[ type ];
|
ElementBndBoxTree*& ebbTree = _ebbTree[ type ];
|
||||||
if ( !ebbTree )
|
if ( !ebbTree )
|
||||||
ebbTree = new ElementBndBoxTree( *_mesh, _elementType, _meshPartIt );
|
ebbTree = new ElementBndBoxTree( *_mesh, _elementType, _meshPartIt );
|
||||||
|
else
|
||||||
|
ebbTree->prepare();
|
||||||
|
|
||||||
TIDSortedElemSet suspectFaces; // elements possibly intersecting the line
|
ebbTree->getElementsInSphere( center, radius, foundElems );
|
||||||
ebbTree->getElementsInSphere( center, radius, suspectFaces );
|
}
|
||||||
foundElems.assign( suspectFaces.begin(), suspectFaces.end() );
|
|
||||||
|
//=======================================================================
|
||||||
|
/*
|
||||||
|
* \brief Return a projection of a given point to a mesh.
|
||||||
|
* Optionally return the closest element
|
||||||
|
*/
|
||||||
|
//=======================================================================
|
||||||
|
|
||||||
|
gp_XYZ SMESH_ElementSearcherImpl::Project(const gp_Pnt& point,
|
||||||
|
SMDSAbs_ElementType type,
|
||||||
|
const SMDS_MeshElement** closestElem)
|
||||||
|
{
|
||||||
|
_elementType = type;
|
||||||
|
if ( _mesh->GetMeshInfo().NbElements( _elementType ) == 0 )
|
||||||
|
throw SALOME_Exception( LOCALIZED( "No elements of given type in the mesh" ));
|
||||||
|
|
||||||
|
ElementBndBoxTree*& ebbTree = _ebbTree[ _elementType ];
|
||||||
|
if ( !ebbTree )
|
||||||
|
ebbTree = new ElementBndBoxTree( *_mesh, _elementType );
|
||||||
|
|
||||||
|
gp_XYZ p = point.XYZ();
|
||||||
|
ElementBndBoxTree* ebbLeaf = ebbTree->getLeafAtPoint( p );
|
||||||
|
const Bnd_B3d* box = ebbLeaf->getBox();
|
||||||
|
double radius = ( box->CornerMax() - box->CornerMin() ).Modulus();
|
||||||
|
|
||||||
|
vector< const SMDS_MeshElement* > elems;
|
||||||
|
ebbTree->getElementsInSphere( p, radius, elems );
|
||||||
|
while ( elems.empty() )
|
||||||
|
{
|
||||||
|
radius *= 1.5;
|
||||||
|
ebbTree->getElementsInSphere( p, radius, elems );
|
||||||
|
}
|
||||||
|
gp_XYZ proj, bestProj;
|
||||||
|
const SMDS_MeshElement* elem = 0;
|
||||||
|
double minDist = 2 * radius;
|
||||||
|
for ( size_t i = 0; i < elems.size(); ++i )
|
||||||
|
{
|
||||||
|
double d = SMESH_MeshAlgos::GetDistance( elems[i], p, &proj );
|
||||||
|
if ( d < minDist )
|
||||||
|
{
|
||||||
|
bestProj = proj;
|
||||||
|
elem = elems[i];
|
||||||
|
minDist = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( closestElem ) *closestElem = elem;
|
||||||
|
|
||||||
|
return bestProj;
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
@ -1388,17 +1540,19 @@ namespace
|
|||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
|
||||||
double SMESH_MeshAlgos::GetDistance( const SMDS_MeshElement* elem,
|
double SMESH_MeshAlgos::GetDistance( const SMDS_MeshElement* elem,
|
||||||
const gp_Pnt& point )
|
const gp_Pnt& point,
|
||||||
|
gp_XYZ* closestPnt )
|
||||||
{
|
{
|
||||||
switch ( elem->GetType() )
|
switch ( elem->GetType() )
|
||||||
{
|
{
|
||||||
case SMDSAbs_Volume:
|
case SMDSAbs_Volume:
|
||||||
return GetDistance( dynamic_cast<const SMDS_MeshVolume*>( elem ), point);
|
return GetDistance( dynamic_cast<const SMDS_MeshVolume*>( elem ), point, closestPnt );
|
||||||
case SMDSAbs_Face:
|
case SMDSAbs_Face:
|
||||||
return GetDistance( dynamic_cast<const SMDS_MeshFace*>( elem ), point);
|
return GetDistance( dynamic_cast<const SMDS_MeshFace*>( elem ), point, closestPnt );
|
||||||
case SMDSAbs_Edge:
|
case SMDSAbs_Edge:
|
||||||
return GetDistance( dynamic_cast<const SMDS_MeshEdge*>( elem ), point);
|
return GetDistance( dynamic_cast<const SMDS_MeshEdge*>( elem ), point, closestPnt );
|
||||||
case SMDSAbs_Node:
|
case SMDSAbs_Node:
|
||||||
|
if ( closestPnt ) *closestPnt = SMESH_TNodeXYZ( elem );
|
||||||
return point.Distance( SMESH_TNodeXYZ( elem ));
|
return point.Distance( SMESH_TNodeXYZ( elem ));
|
||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
@ -1414,9 +1568,10 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshElement* elem,
|
|||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
|
||||||
double SMESH_MeshAlgos::GetDistance( const SMDS_MeshFace* face,
|
double SMESH_MeshAlgos::GetDistance( const SMDS_MeshFace* face,
|
||||||
const gp_Pnt& point )
|
const gp_Pnt& point,
|
||||||
|
gp_XYZ* closestPnt )
|
||||||
{
|
{
|
||||||
double badDistance = -1;
|
const double badDistance = -1;
|
||||||
if ( !face ) return badDistance;
|
if ( !face ) return badDistance;
|
||||||
|
|
||||||
// coordinates of nodes (medium nodes, if any, ignored)
|
// coordinates of nodes (medium nodes, if any, ignored)
|
||||||
@ -1460,7 +1615,7 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshFace* face,
|
|||||||
trsf.Transforms( tmpPnt );
|
trsf.Transforms( tmpPnt );
|
||||||
gp_XY point2D( tmpPnt.X(), tmpPnt.Z() );
|
gp_XY point2D( tmpPnt.X(), tmpPnt.Z() );
|
||||||
|
|
||||||
// loop on segments of the face to analyze point position ralative to the face
|
// loop on edges of the face to analyze point position ralative to the face
|
||||||
set< PointPos > pntPosSet;
|
set< PointPos > pntPosSet;
|
||||||
for ( size_t i = 1; i < xy.size(); ++i )
|
for ( size_t i = 1; i < xy.size(); ++i )
|
||||||
{
|
{
|
||||||
@ -1470,31 +1625,40 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshFace* face,
|
|||||||
|
|
||||||
// compute distance
|
// compute distance
|
||||||
PointPos pos = *pntPosSet.begin();
|
PointPos pos = *pntPosSet.begin();
|
||||||
// cout << "Face " << face->GetID() << " DIST: ";
|
|
||||||
switch ( pos._name )
|
switch ( pos._name )
|
||||||
{
|
{
|
||||||
case POS_LEFT: {
|
case POS_LEFT:
|
||||||
// point is most close to a segment
|
{
|
||||||
gp_Vec p0p1( point, xyz[ pos._index ] );
|
// point is most close to an edge
|
||||||
gp_Vec p1p2( xyz[ pos._index ], xyz[ pos._index+1 ]); // segment vector
|
gp_Vec edge( xyz[ pos._index ], xyz[ pos._index+1 ]);
|
||||||
p1p2.Normalize();
|
gp_Vec n1p ( xyz[ pos._index ], point );
|
||||||
double projDist = p0p1 * p1p2; // distance projected to the segment
|
double u = ( edge * n1p ) / edge.SquareMagnitude(); // param [0,1] on the edge
|
||||||
gp_Vec projVec = p1p2 * projDist;
|
// projection of the point on the edge
|
||||||
gp_Vec distVec = p0p1 - projVec;
|
gp_XYZ proj = ( 1. - u ) * xyz[ pos._index ] + u * xyz[ pos._index+1 ];
|
||||||
// cout << distVec.Magnitude() << ", SEG " << face->GetNode(pos._index)->GetID()
|
if ( closestPnt ) *closestPnt = proj;
|
||||||
// << " - " << face->GetNodeWrap(pos._index+1)->GetID() << endl;
|
return point.Distance( proj );
|
||||||
return distVec.Magnitude();
|
|
||||||
}
|
}
|
||||||
case POS_RIGHT: {
|
case POS_RIGHT:
|
||||||
|
{
|
||||||
// point is inside the face
|
// point is inside the face
|
||||||
double distToFacePlane = tmpPnt.Y();
|
double distToFacePlane = Abs( tmpPnt.Y() );
|
||||||
// cout << distToFacePlane << ", INSIDE " << endl;
|
if ( closestPnt )
|
||||||
return Abs( distToFacePlane );
|
{
|
||||||
|
if ( distToFacePlane < std::numeric_limits<double>::min() ) {
|
||||||
|
*closestPnt = point.XYZ();
|
||||||
}
|
}
|
||||||
case POS_VERTEX: {
|
else {
|
||||||
|
tmpPnt.SetY( 0 );
|
||||||
|
trsf.Inverted().Transforms( tmpPnt );
|
||||||
|
*closestPnt = tmpPnt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return distToFacePlane;
|
||||||
|
}
|
||||||
|
case POS_VERTEX:
|
||||||
|
{
|
||||||
// point is most close to a node
|
// point is most close to a node
|
||||||
gp_Vec distVec( point, xyz[ pos._index ]);
|
gp_Vec distVec( point, xyz[ pos._index ]);
|
||||||
// cout << distVec.Magnitude() << " VERTEX " << face->GetNode(pos._index)->GetID() << endl;
|
|
||||||
return distVec.Magnitude();
|
return distVec.Magnitude();
|
||||||
}
|
}
|
||||||
default:;
|
default:;
|
||||||
@ -1508,7 +1672,9 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshFace* face,
|
|||||||
*/
|
*/
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
|
||||||
double SMESH_MeshAlgos::GetDistance( const SMDS_MeshEdge* seg, const gp_Pnt& point )
|
double SMESH_MeshAlgos::GetDistance( const SMDS_MeshEdge* seg,
|
||||||
|
const gp_Pnt& point,
|
||||||
|
gp_XYZ* closestPnt )
|
||||||
{
|
{
|
||||||
double dist = Precision::Infinite();
|
double dist = Precision::Infinite();
|
||||||
if ( !seg ) return dist;
|
if ( !seg ) return dist;
|
||||||
@ -1527,13 +1693,16 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshEdge* seg, const gp_Pnt& poi
|
|||||||
double u = ( edge * n1p ) / edge.SquareMagnitude(); // param [0,1] on the edge
|
double u = ( edge * n1p ) / edge.SquareMagnitude(); // param [0,1] on the edge
|
||||||
if ( u <= 0. ) {
|
if ( u <= 0. ) {
|
||||||
dist = Min( dist, n1p.SquareMagnitude() );
|
dist = Min( dist, n1p.SquareMagnitude() );
|
||||||
|
if ( closestPnt ) *closestPnt = xyz[i-1];
|
||||||
}
|
}
|
||||||
else if ( u >= 1. ) {
|
else if ( u >= 1. ) {
|
||||||
dist = Min( dist, point.SquareDistance( xyz[i] ));
|
dist = Min( dist, point.SquareDistance( xyz[i] ));
|
||||||
|
if ( closestPnt ) *closestPnt = xyz[i];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
gp_XYZ proj = ( 1. - u ) * xyz[i-1] + u * xyz[i]; // projection of the point on the edge
|
gp_XYZ proj = ( 1. - u ) * xyz[i-1] + u * xyz[i]; // projection of the point on the edge
|
||||||
dist = Min( dist, point.SquareDistance( proj ));
|
dist = Min( dist, point.SquareDistance( proj ));
|
||||||
|
if ( closestPnt ) *closestPnt = proj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Sqrt( dist );
|
return Sqrt( dist );
|
||||||
@ -1547,7 +1716,9 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshEdge* seg, const gp_Pnt& poi
|
|||||||
*/
|
*/
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
|
||||||
double SMESH_MeshAlgos::GetDistance( const SMDS_MeshVolume* volume, const gp_Pnt& point )
|
double SMESH_MeshAlgos::GetDistance( const SMDS_MeshVolume* volume,
|
||||||
|
const gp_Pnt& point,
|
||||||
|
gp_XYZ* closestPnt )
|
||||||
{
|
{
|
||||||
SMDS_VolumeTool vTool( volume );
|
SMDS_VolumeTool vTool( volume );
|
||||||
vTool.SetExternalNormal();
|
vTool.SetExternalNormal();
|
||||||
@ -1555,6 +1726,8 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshVolume* volume, const gp_Pnt
|
|||||||
|
|
||||||
double n[3], bc[3];
|
double n[3], bc[3];
|
||||||
double minDist = 1e100, dist;
|
double minDist = 1e100, dist;
|
||||||
|
gp_XYZ closeP = point.XYZ();
|
||||||
|
bool isOut = false;
|
||||||
for ( int iF = 0; iF < vTool.NbFaces(); ++iF )
|
for ( int iF = 0; iF < vTool.NbFaces(); ++iF )
|
||||||
{
|
{
|
||||||
// skip a facet with normal not "looking at" the point
|
// skip a facet with normal not "looking at" the point
|
||||||
@ -1571,25 +1744,36 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshVolume* volume, const gp_Pnt
|
|||||||
case 3:
|
case 3:
|
||||||
{
|
{
|
||||||
SMDS_FaceOfNodes tmpFace( nodes[0], nodes[ 1*iQ ], nodes[ 2*iQ ] );
|
SMDS_FaceOfNodes tmpFace( nodes[0], nodes[ 1*iQ ], nodes[ 2*iQ ] );
|
||||||
dist = GetDistance( &tmpFace, point );
|
dist = GetDistance( &tmpFace, point, closestPnt );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 4:
|
case 4:
|
||||||
{
|
{
|
||||||
SMDS_FaceOfNodes tmpFace( nodes[0], nodes[ 1*iQ ], nodes[ 2*iQ ], nodes[ 3*iQ ]);
|
SMDS_FaceOfNodes tmpFace( nodes[0], nodes[ 1*iQ ], nodes[ 2*iQ ], nodes[ 3*iQ ]);
|
||||||
dist = GetDistance( &tmpFace, point );
|
dist = GetDistance( &tmpFace, point, closestPnt );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
vector<const SMDS_MeshNode *> nvec( nodes, nodes + vTool.NbFaceNodes( iF ));
|
vector<const SMDS_MeshNode *> nvec( nodes, nodes + vTool.NbFaceNodes( iF ));
|
||||||
SMDS_PolygonalFaceOfNodes tmpFace( nvec );
|
SMDS_PolygonalFaceOfNodes tmpFace( nvec );
|
||||||
dist = GetDistance( &tmpFace, point );
|
dist = GetDistance( &tmpFace, point, closestPnt );
|
||||||
}
|
}
|
||||||
minDist = Min( minDist, dist );
|
if ( dist < minDist )
|
||||||
|
{
|
||||||
|
minDist = dist;
|
||||||
|
isOut = true;
|
||||||
|
if ( closestPnt ) closeP = *closestPnt;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if ( isOut )
|
||||||
|
{
|
||||||
|
if ( closestPnt ) *closestPnt = closeP;
|
||||||
return minDist;
|
return minDist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0; // point is inside the volume
|
||||||
|
}
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns barycentric coordinates of a point within a triangle.
|
* \brief Returns barycentric coordinates of a point within a triangle.
|
||||||
|
@ -100,6 +100,15 @@ struct SMESHUtils_EXPORT SMESH_ElementSearcher
|
|||||||
* \brief Find out if the given point is out of closed 2D mesh.
|
* \brief Find out if the given point is out of closed 2D mesh.
|
||||||
*/
|
*/
|
||||||
virtual TopAbs_State GetPointState(const gp_Pnt& point) = 0;
|
virtual TopAbs_State GetPointState(const gp_Pnt& point) = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Return a projection of a given point to a 2D mesh.
|
||||||
|
* Optionally return the closest face
|
||||||
|
*/
|
||||||
|
virtual gp_XYZ Project(const gp_Pnt& point,
|
||||||
|
SMDSAbs_ElementType type,
|
||||||
|
const SMDS_MeshElement** closestFace= 0) = 0;
|
||||||
|
|
||||||
virtual ~SMESH_ElementSearcher();
|
virtual ~SMESH_ElementSearcher();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -112,16 +121,16 @@ namespace SMESH_MeshAlgos
|
|||||||
bool IsOut( const SMDS_MeshElement* element, const gp_Pnt& point, double tol );
|
bool IsOut( const SMDS_MeshElement* element, const gp_Pnt& point, double tol );
|
||||||
|
|
||||||
SMESHUtils_EXPORT
|
SMESHUtils_EXPORT
|
||||||
double GetDistance( const SMDS_MeshElement* elem, const gp_Pnt& point );
|
double GetDistance( const SMDS_MeshElement* elem, const gp_Pnt& point, gp_XYZ* closestPnt = 0 );
|
||||||
|
|
||||||
SMESHUtils_EXPORT
|
SMESHUtils_EXPORT
|
||||||
double GetDistance( const SMDS_MeshEdge* edge, const gp_Pnt& point );
|
double GetDistance( const SMDS_MeshEdge* edge, const gp_Pnt& point, gp_XYZ* closestPnt = 0 );
|
||||||
|
|
||||||
SMESHUtils_EXPORT
|
SMESHUtils_EXPORT
|
||||||
double GetDistance( const SMDS_MeshFace* face, const gp_Pnt& point );
|
double GetDistance( const SMDS_MeshFace* face, const gp_Pnt& point, gp_XYZ* closestPnt = 0 );
|
||||||
|
|
||||||
SMESHUtils_EXPORT
|
SMESHUtils_EXPORT
|
||||||
double GetDistance( const SMDS_MeshVolume* volume, const gp_Pnt& point );
|
double GetDistance( const SMDS_MeshVolume* volume, const gp_Pnt& point, gp_XYZ* closestPnt = 0 );
|
||||||
|
|
||||||
SMESHUtils_EXPORT
|
SMESHUtils_EXPORT
|
||||||
void GetBarycentricCoords( const gp_XY& point,
|
void GetBarycentricCoords( const gp_XY& point,
|
||||||
|
@ -32,6 +32,12 @@ void SMESH::doNothing(const char* txt)
|
|||||||
{
|
{
|
||||||
MESSAGE( txt << " " << __FILE__ << ": " << __LINE__ );
|
MESSAGE( txt << " " << __FILE__ << ": " << __LINE__ );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* SMESH::returnError(const char* txt)
|
||||||
|
{
|
||||||
|
return txt;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
#include "SMESH_ComputeError.hxx"
|
#include "SMESH_ComputeError.hxx"
|
||||||
|
|
||||||
|
@ -104,6 +104,7 @@ namespace SMESH
|
|||||||
{
|
{
|
||||||
SMESHUtils_EXPORT void throwSalomeEx(const char* txt);
|
SMESHUtils_EXPORT void throwSalomeEx(const char* txt);
|
||||||
SMESHUtils_EXPORT void doNothing(const char* txt);
|
SMESHUtils_EXPORT void doNothing(const char* txt);
|
||||||
|
SMESHUtils_EXPORT const char* returnError(const char* txt);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -6831,3 +6831,130 @@ CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
|
|||||||
SMESH_CATCH( SMESH::throwCorbaException );
|
SMESH_CATCH( SMESH::throwCorbaException );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Create a polyline consisting of 1D mesh elements each lying on a 2D element of
|
||||||
|
* the initial mesh. Positions of new nodes are found by cutting the mesh by the
|
||||||
|
* plane passing through pairs of points specified by each PolySegment structure.
|
||||||
|
* If there are several paths connecting a pair of points, the shortest path is
|
||||||
|
* selected by the module. Position of the cutting plane is defined by the two
|
||||||
|
* points and an optional vector lying on the plane specified by a PolySegment.
|
||||||
|
* By default the vector is defined by Mesh module as following. A middle point
|
||||||
|
* of the two given points is computed. The middle point is projected to the mesh.
|
||||||
|
* The vector goes from the middle point to the projection point. In case of planar
|
||||||
|
* mesh, the vector is normal to the mesh.
|
||||||
|
* \param [inout] segments - PolySegment's defining positions of cutting planes.
|
||||||
|
* Return the used vector and position of the middle point.
|
||||||
|
* \param [in] groupName - optional name of a group where created mesh segments will
|
||||||
|
* be added.
|
||||||
|
*/
|
||||||
|
//================================================================================
|
||||||
|
|
||||||
|
void SMESH_MeshEditor_i::MakePolyLine(SMESH::ListOfPolySegments& theSegments,
|
||||||
|
const char* theGroupName)
|
||||||
|
throw (SALOME::SALOME_Exception)
|
||||||
|
{
|
||||||
|
if ( theSegments.length() == 0 )
|
||||||
|
THROW_SALOME_CORBA_EXCEPTION("No segments given", SALOME::BAD_PARAM );
|
||||||
|
if ( myMesh->NbFaces() == 0 )
|
||||||
|
THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM );
|
||||||
|
|
||||||
|
SMESH_TRY;
|
||||||
|
initData(/*deleteSearchers=*/false);
|
||||||
|
|
||||||
|
SMESHDS_Group* groupDS = 0;
|
||||||
|
SMESHDS_Mesh* meshDS = getMeshDS();
|
||||||
|
if ( myIsPreviewMode ) // copy faces to the tmp mesh
|
||||||
|
{
|
||||||
|
TPreviewMesh * tmpMesh = getPreviewMesh( SMDSAbs_Edge );
|
||||||
|
SMDS_ElemIteratorPtr faceIt = getMeshDS()->elementsIterator( SMDSAbs_Face );
|
||||||
|
while ( faceIt->more() )
|
||||||
|
tmpMesh->Copy( faceIt->next() );
|
||||||
|
meshDS = tmpMesh->GetMeshDS();
|
||||||
|
}
|
||||||
|
else if ( theGroupName[0] ) // find/create a group of segments
|
||||||
|
{
|
||||||
|
SMESH_Mesh::GroupIteratorPtr grpIt = myMesh->GetGroups();
|
||||||
|
while ( !groupDS && grpIt->more() )
|
||||||
|
{
|
||||||
|
SMESH_Group* group = grpIt->next();
|
||||||
|
if ( group->GetGroupDS()->GetType() == SMDSAbs_Edge &&
|
||||||
|
strcmp( group->GetName(), theGroupName ) == 0 )
|
||||||
|
{
|
||||||
|
groupDS = dynamic_cast< SMESHDS_Group* >( group->GetGroupDS() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( !groupDS )
|
||||||
|
{
|
||||||
|
SMESH::SMESH_Group_var groupVar = myMesh_i->CreateGroup( SMESH::EDGE, theGroupName );
|
||||||
|
|
||||||
|
if ( SMESH_Group_i* groupImpl = SMESH::DownCast<SMESH_Group_i*>( groupVar ))
|
||||||
|
groupDS = dynamic_cast< SMESHDS_Group* >( groupImpl->GetGroupDS() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert input polySegments
|
||||||
|
::SMESH_MeshEditor::TListOfPolySegments segments( theSegments.length() );
|
||||||
|
for ( CORBA::ULong i = 0; i < theSegments.length(); ++i )
|
||||||
|
{
|
||||||
|
SMESH::PolySegment& segIn = theSegments[ i ];
|
||||||
|
::SMESH_MeshEditor::PolySegment& segOut = segments[ i ];
|
||||||
|
segOut.myNode1[0] = meshDS->FindNode( segIn.node1ID1 );
|
||||||
|
segOut.myNode2[0] = meshDS->FindNode( segIn.node1ID2 );
|
||||||
|
segOut.myNode1[1] = meshDS->FindNode( segIn.node2ID1 );
|
||||||
|
segOut.myNode2[1] = meshDS->FindNode( segIn.node2ID2 );
|
||||||
|
segOut.myVector.SetCoord( segIn.vector.PS.x,
|
||||||
|
segIn.vector.PS.y,
|
||||||
|
segIn.vector.PS.z );
|
||||||
|
if ( !segOut.myNode1[0] )
|
||||||
|
THROW_SALOME_CORBA_EXCEPTION( SMESH_Comment( "Invalid node ID: ") << segIn.node1ID1,
|
||||||
|
SALOME::BAD_PARAM );
|
||||||
|
if ( !segOut.myNode1[1] )
|
||||||
|
THROW_SALOME_CORBA_EXCEPTION( SMESH_Comment( "Invalid node ID: ") << segIn.node2ID1,
|
||||||
|
SALOME::BAD_PARAM );
|
||||||
|
}
|
||||||
|
|
||||||
|
// get a static ElementSearcher
|
||||||
|
SMESH::SMESH_IDSource_var idSource = SMESH::SMESH_IDSource::_narrow( myMesh_i->_this() );
|
||||||
|
theSearchersDeleter.Set( myMesh, getPartIOR( idSource, SMESH::FACE ));
|
||||||
|
if ( !theElementSearcher )
|
||||||
|
theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
|
||||||
|
|
||||||
|
// compute
|
||||||
|
getEditor().MakePolyLine( segments, groupDS, theElementSearcher );
|
||||||
|
|
||||||
|
// return vectors
|
||||||
|
if ( myIsPreviewMode )
|
||||||
|
{
|
||||||
|
for ( CORBA::ULong i = 0; i < theSegments.length(); ++i )
|
||||||
|
{
|
||||||
|
SMESH::PolySegment& segOut = theSegments[ i ];
|
||||||
|
::SMESH_MeshEditor::PolySegment& segIn = segments[ i ];
|
||||||
|
segOut.vector.PS.x = segIn.myVector.X();
|
||||||
|
segOut.vector.PS.y = segIn.myVector.Y();
|
||||||
|
segOut.vector.PS.z = segIn.myVector.Z();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TPythonDump() << "_segments = []";
|
||||||
|
for ( CORBA::ULong i = 0; i < theSegments.length(); ++i )
|
||||||
|
{
|
||||||
|
SMESH::PolySegment& segIn = theSegments[ i ];
|
||||||
|
TPythonDump() << "_segments.append( SMESH.PolySegment( "
|
||||||
|
<< segIn.node1ID1 << ", "
|
||||||
|
<< segIn.node1ID2 << ", "
|
||||||
|
<< segIn.node2ID1 << ", "
|
||||||
|
<< segIn.node2ID2 << ", "
|
||||||
|
<< "smeshBuilder.MakeDirStruct( "
|
||||||
|
<< segIn.vector.PS.x << ", "
|
||||||
|
<< segIn.vector.PS.y << ", "
|
||||||
|
<< segIn.vector.PS.z << ")))";
|
||||||
|
}
|
||||||
|
TPythonDump() << this << ".MakePolyLine( _segments, '" << theGroupName << "')";
|
||||||
|
}
|
||||||
|
|
||||||
|
SMESH_CATCH( SMESH::throwCorbaException );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
@ -844,6 +844,27 @@ public:
|
|||||||
SMESH::SMESH_Group_out group)
|
SMESH::SMESH_Group_out group)
|
||||||
throw (SALOME::SALOME_Exception);
|
throw (SALOME::SALOME_Exception);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Create a polyline consisting of 1D mesh elements each lying on a 2D element of
|
||||||
|
* the initial mesh. Positions of new nodes are found by cutting the mesh by the
|
||||||
|
* plane passing through pairs of points specified by each PolySegment structure.
|
||||||
|
* If there are several paths connecting a pair of points, the shortest path is
|
||||||
|
* selected by the module. Position of the cutting plane is defined by the two
|
||||||
|
* points and an optional vector lying on the plane specified by a PolySegment.
|
||||||
|
* By default the vector is defined by Mesh module as following. A middle point
|
||||||
|
* of the two given points is computed. The middle point is projected to the mesh.
|
||||||
|
* The vector goes from the middle point to the projection point. In case of planar
|
||||||
|
* mesh, the vector is normal to the mesh.
|
||||||
|
* \param [inout] segments - PolySegment's defining positions of cutting planes.
|
||||||
|
* Return the used vector and position of the middle point.
|
||||||
|
* \param [in] groupName - optional name of a group where created mesh segments will
|
||||||
|
* be added.
|
||||||
|
*/
|
||||||
|
void MakePolyLine(SMESH::ListOfPolySegments& segments,
|
||||||
|
const char* groupName)
|
||||||
|
throw (SALOME::SALOME_Exception);
|
||||||
|
|
||||||
|
|
||||||
private: //!< private methods
|
private: //!< private methods
|
||||||
|
|
||||||
::SMESH_MeshEditor& getEditor();
|
::SMESH_MeshEditor& getEditor();
|
||||||
|
@ -1879,8 +1879,11 @@ class Mesh:
|
|||||||
# @param f is the file name
|
# @param f is the file name
|
||||||
# @param overwrite boolean parameter for overwriting/not overwriting the file
|
# @param overwrite boolean parameter for overwriting/not overwriting the file
|
||||||
# @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh
|
# @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh
|
||||||
|
# @param groupElemsByType if true all elements of same entity type are exported at ones,
|
||||||
|
# else elements are exported in order of their IDs which can cause creation
|
||||||
|
# of multiple cgns sections
|
||||||
# @ingroup l2_impexp
|
# @ingroup l2_impexp
|
||||||
def ExportCGNS(self, f, overwrite=1, meshPart=None):
|
def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
|
||||||
unRegister = genObjUnRegister()
|
unRegister = genObjUnRegister()
|
||||||
if isinstance( meshPart, list ):
|
if isinstance( meshPart, list ):
|
||||||
meshPart = self.GetIDSource( meshPart, SMESH.ALL )
|
meshPart = self.GetIDSource( meshPart, SMESH.ALL )
|
||||||
@ -1889,7 +1892,7 @@ class Mesh:
|
|||||||
meshPart = meshPart.mesh
|
meshPart = meshPart.mesh
|
||||||
elif not meshPart:
|
elif not meshPart:
|
||||||
meshPart = self.mesh
|
meshPart = self.mesh
|
||||||
self.mesh.ExportCGNS(meshPart, f, overwrite)
|
self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
|
||||||
|
|
||||||
## Export the mesh in a file in GMF format.
|
## Export the mesh in a file in GMF format.
|
||||||
# GMF files must have .mesh extension for the ASCII format and .meshb for
|
# GMF files must have .mesh extension for the ASCII format and .meshb for
|
||||||
@ -2010,6 +2013,8 @@ class Mesh:
|
|||||||
# @ingroup l2_grps_create
|
# @ingroup l2_grps_create
|
||||||
def MakeGroupByIds(self, groupName, elementType, elemIDs):
|
def MakeGroupByIds(self, groupName, elementType, elemIDs):
|
||||||
group = self.mesh.CreateGroup(elementType, groupName)
|
group = self.mesh.CreateGroup(elementType, groupName)
|
||||||
|
if isinstance( elemIDs, Mesh ):
|
||||||
|
elemIDs = elemIDs.GetMesh()
|
||||||
if hasattr( elemIDs, "GetIDs" ):
|
if hasattr( elemIDs, "GetIDs" ):
|
||||||
if hasattr( elemIDs, "SetMesh" ):
|
if hasattr( elemIDs, "SetMesh" ):
|
||||||
elemIDs.SetMesh( self.GetMesh() )
|
elemIDs.SetMesh( self.GetMesh() )
|
||||||
@ -2690,6 +2695,11 @@ class Mesh:
|
|||||||
def FindElementByNodes(self, nodes):
|
def FindElementByNodes(self, nodes):
|
||||||
return self.mesh.FindElementByNodes(nodes)
|
return self.mesh.FindElementByNodes(nodes)
|
||||||
|
|
||||||
|
## Return elements including all given nodes.
|
||||||
|
# @ingroup l1_meshinfo
|
||||||
|
def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
|
||||||
|
return self.mesh.GetElementsByNodes( nodes, elemType )
|
||||||
|
|
||||||
## Return true if the given element is a polygon
|
## Return true if the given element is a polygon
|
||||||
# @ingroup l1_meshinfo
|
# @ingroup l1_meshinfo
|
||||||
def IsPoly(self, id):
|
def IsPoly(self, id):
|
||||||
@ -3882,6 +3892,7 @@ class Mesh:
|
|||||||
# - a GEOM point
|
# - a GEOM point
|
||||||
# @return the list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
|
# @return the list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
|
||||||
# @ingroup l2_modif_extrurev
|
# @ingroup l2_modif_extrurev
|
||||||
|
# @ref tui_extrusion example
|
||||||
def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
|
def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
|
||||||
scaleFactors=[], linearVariation=False, basePoint=[] ):
|
scaleFactors=[], linearVariation=False, basePoint=[] ):
|
||||||
unRegister = genObjUnRegister()
|
unRegister = genObjUnRegister()
|
||||||
@ -3922,6 +3933,7 @@ class Mesh:
|
|||||||
# @param IsNodes is True if elements with given ids are nodes
|
# @param IsNodes is True if elements with given ids are nodes
|
||||||
# @return the list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
|
# @return the list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
|
||||||
# @ingroup l2_modif_extrurev
|
# @ingroup l2_modif_extrurev
|
||||||
|
# @ref tui_extrusion example
|
||||||
def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
|
def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
|
||||||
n,e,f = [],[],[]
|
n,e,f = [],[],[]
|
||||||
if IsNodes: n = IDsOfElements
|
if IsNodes: n = IDsOfElements
|
||||||
@ -3948,6 +3960,7 @@ class Mesh:
|
|||||||
# @return the list of created groups (SMESH_GroupBase) if \a MakeGroups=True,
|
# @return the list of created groups (SMESH_GroupBase) if \a MakeGroups=True,
|
||||||
# empty list otherwise.
|
# empty list otherwise.
|
||||||
# @ingroup l2_modif_extrurev
|
# @ingroup l2_modif_extrurev
|
||||||
|
# @ref tui_extrusion example
|
||||||
def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
|
def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
|
||||||
ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
|
ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
|
||||||
unRegister = genObjUnRegister()
|
unRegister = genObjUnRegister()
|
||||||
@ -3977,6 +3990,7 @@ class Mesh:
|
|||||||
# @param IsNodes is True if elements to extrude are nodes
|
# @param IsNodes is True if elements to extrude are nodes
|
||||||
# @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
|
# @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
|
||||||
# @ingroup l2_modif_extrurev
|
# @ingroup l2_modif_extrurev
|
||||||
|
# @ref tui_extrusion example
|
||||||
def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
|
def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
|
||||||
n,e,f = [],[],[]
|
n,e,f = [],[],[]
|
||||||
if IsNodes: n = theObject
|
if IsNodes: n = theObject
|
||||||
@ -3993,6 +4007,7 @@ class Mesh:
|
|||||||
# @param MakeGroups to generate new groups from existing ones
|
# @param MakeGroups to generate new groups from existing ones
|
||||||
# @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
|
# @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
|
||||||
# @ingroup l2_modif_extrurev
|
# @ingroup l2_modif_extrurev
|
||||||
|
# @ref tui_extrusion example
|
||||||
def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
|
def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
|
||||||
return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
|
return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
|
||||||
|
|
||||||
@ -4006,6 +4021,7 @@ class Mesh:
|
|||||||
# @param MakeGroups forces the generation of new groups from existing ones
|
# @param MakeGroups forces the generation of new groups from existing ones
|
||||||
# @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
|
# @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
|
||||||
# @ingroup l2_modif_extrurev
|
# @ingroup l2_modif_extrurev
|
||||||
|
# @ref tui_extrusion example
|
||||||
def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
|
def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
|
||||||
return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
|
return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
|
||||||
|
|
||||||
@ -4050,6 +4066,7 @@ class Mesh:
|
|||||||
# @param MakeGroups forces the generation of new groups from existing ones
|
# @param MakeGroups forces the generation of new groups from existing ones
|
||||||
# @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error
|
# @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error
|
||||||
# @ingroup l2_modif_extrurev
|
# @ingroup l2_modif_extrurev
|
||||||
|
# @ref tui_extrusion_along_path example
|
||||||
def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathMesh, PathShape=None,
|
def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathMesh, PathShape=None,
|
||||||
NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
|
NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
|
||||||
HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False):
|
HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False):
|
||||||
@ -4093,6 +4110,7 @@ class Mesh:
|
|||||||
# @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
|
# @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
|
||||||
# only SMESH::Extrusion_Error otherwise
|
# only SMESH::Extrusion_Error otherwise
|
||||||
# @ingroup l2_modif_extrurev
|
# @ingroup l2_modif_extrurev
|
||||||
|
# @ref tui_extrusion_along_path example
|
||||||
def ExtrusionAlongPathX(self, Base, Path, NodeStart,
|
def ExtrusionAlongPathX(self, Base, Path, NodeStart,
|
||||||
HasAngles=False, Angles=[], LinearVariation=False,
|
HasAngles=False, Angles=[], LinearVariation=False,
|
||||||
HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
|
HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
|
||||||
@ -4125,6 +4143,7 @@ class Mesh:
|
|||||||
# @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
|
# @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
|
||||||
# only SMESH::Extrusion_Error otherwise
|
# only SMESH::Extrusion_Error otherwise
|
||||||
# @ingroup l2_modif_extrurev
|
# @ingroup l2_modif_extrurev
|
||||||
|
# @ref tui_extrusion_along_path example
|
||||||
def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
|
def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
|
||||||
HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
|
HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
|
||||||
MakeGroups=False, LinearVariation=False):
|
MakeGroups=False, LinearVariation=False):
|
||||||
@ -4155,6 +4174,7 @@ class Mesh:
|
|||||||
# @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
|
# @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
|
||||||
# only SMESH::Extrusion_Error otherwise
|
# only SMESH::Extrusion_Error otherwise
|
||||||
# @ingroup l2_modif_extrurev
|
# @ingroup l2_modif_extrurev
|
||||||
|
# @ref tui_extrusion_along_path example
|
||||||
def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
|
def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
|
||||||
HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
|
HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
|
||||||
MakeGroups=False, LinearVariation=False):
|
MakeGroups=False, LinearVariation=False):
|
||||||
@ -4184,6 +4204,7 @@ class Mesh:
|
|||||||
# @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
|
# @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
|
||||||
# only SMESH::Extrusion_Error otherwise
|
# only SMESH::Extrusion_Error otherwise
|
||||||
# @ingroup l2_modif_extrurev
|
# @ingroup l2_modif_extrurev
|
||||||
|
# @ref tui_extrusion_along_path example
|
||||||
def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
|
def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
|
||||||
HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
|
HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
|
||||||
MakeGroups=False, LinearVariation=False):
|
MakeGroups=False, LinearVariation=False):
|
||||||
@ -4213,6 +4234,7 @@ class Mesh:
|
|||||||
# @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
|
# @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
|
||||||
# only SMESH::Extrusion_Error otherwise
|
# only SMESH::Extrusion_Error otherwise
|
||||||
# @ingroup l2_modif_extrurev
|
# @ingroup l2_modif_extrurev
|
||||||
|
# @ref tui_extrusion_along_path example
|
||||||
def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
|
def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
|
||||||
HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
|
HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
|
||||||
MakeGroups=False, LinearVariation=False):
|
MakeGroups=False, LinearVariation=False):
|
||||||
@ -4912,6 +4934,32 @@ class Mesh:
|
|||||||
def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
|
def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
|
||||||
return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
|
return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
|
||||||
|
|
||||||
|
## Create a polyline consisting of 1D mesh elements each lying on a 2D element of
|
||||||
|
# the initial mesh. Positions of new nodes are found by cutting the mesh by the
|
||||||
|
# plane passing through pairs of points specified by each PolySegment structure.
|
||||||
|
# If there are several paths connecting a pair of points, the shortest path is
|
||||||
|
# selected by the module. Position of the cutting plane is defined by the two
|
||||||
|
# points and an optional vector lying on the plane specified by a PolySegment.
|
||||||
|
# By default the vector is defined by Mesh module as following. A middle point
|
||||||
|
# of the two given points is computed. The middle point is projected to the mesh.
|
||||||
|
# The vector goes from the middle point to the projection point. In case of planar
|
||||||
|
# mesh, the vector is normal to the mesh.
|
||||||
|
# @param segments - PolySegment's defining positions of cutting planes.
|
||||||
|
# Return the used vector which goes from the middle point to its projection.
|
||||||
|
# @param groupName - optional name of a group where created mesh segments will
|
||||||
|
# be added.
|
||||||
|
# @ingroup l2_modif_duplicat
|
||||||
|
def MakePolyLine(self, segments, groupName='', isPreview=False ):
|
||||||
|
editor = self.editor
|
||||||
|
if isPreview:
|
||||||
|
editor = self.mesh.GetMeshEditPreviewer()
|
||||||
|
segmentsRes = editor.MakePolyLine( segments, groupName )
|
||||||
|
for i, seg in enumerate( segmentsRes ):
|
||||||
|
segments[i].vector = seg.vector
|
||||||
|
if isPreview:
|
||||||
|
return editor.GetPreviewData()
|
||||||
|
return None
|
||||||
|
|
||||||
def _getFunctor(self, funcType ):
|
def _getFunctor(self, funcType ):
|
||||||
fn = self.functors[ funcType._v ]
|
fn = self.functors[ funcType._v ]
|
||||||
if not fn:
|
if not fn:
|
||||||
@ -5177,10 +5225,11 @@ omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
|
|||||||
## Private class used to bind methods creating algorithms to the class Mesh
|
## Private class used to bind methods creating algorithms to the class Mesh
|
||||||
#
|
#
|
||||||
class algoCreator:
|
class algoCreator:
|
||||||
def __init__(self):
|
def __init__(self, method):
|
||||||
self.mesh = None
|
self.mesh = None
|
||||||
self.defaultAlgoType = ""
|
self.defaultAlgoType = ""
|
||||||
self.algoTypeToClass = {}
|
self.algoTypeToClass = {}
|
||||||
|
self.method = method
|
||||||
|
|
||||||
# Store a python class of algorithm
|
# Store a python class of algorithm
|
||||||
def add(self, algoClass):
|
def add(self, algoClass):
|
||||||
@ -5194,7 +5243,7 @@ class algoCreator:
|
|||||||
|
|
||||||
# Create a copy of self and assign mesh to the copy
|
# Create a copy of self and assign mesh to the copy
|
||||||
def copy(self, mesh):
|
def copy(self, mesh):
|
||||||
other = algoCreator()
|
other = algoCreator( self.method )
|
||||||
other.defaultAlgoType = self.defaultAlgoType
|
other.defaultAlgoType = self.defaultAlgoType
|
||||||
other.algoTypeToClass = self.algoTypeToClass
|
other.algoTypeToClass = self.algoTypeToClass
|
||||||
other.mesh = mesh
|
other.mesh = mesh
|
||||||
@ -5202,17 +5251,40 @@ class algoCreator:
|
|||||||
|
|
||||||
# Create an instance of algorithm
|
# Create an instance of algorithm
|
||||||
def __call__(self,algo="",geom=0,*args):
|
def __call__(self,algo="",geom=0,*args):
|
||||||
algoType = self.defaultAlgoType
|
algoType = ""
|
||||||
for arg in args + (algo,geom):
|
shape = 0
|
||||||
if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ):
|
if isinstance( algo, str ):
|
||||||
geom = arg
|
algoType = algo
|
||||||
if isinstance( arg, str ) and arg:
|
elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
|
||||||
|
not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
|
||||||
|
shape = algo
|
||||||
|
elif algo:
|
||||||
|
args += (algo,)
|
||||||
|
|
||||||
|
if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
|
||||||
|
shape = geom
|
||||||
|
elif not algoType and isinstance( geom, str ):
|
||||||
|
algoType = geom
|
||||||
|
elif geom:
|
||||||
|
args += (geom,)
|
||||||
|
for arg in args:
|
||||||
|
if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
|
||||||
|
shape = arg
|
||||||
|
elif isinstance( arg, str ) and not algoType:
|
||||||
algoType = arg
|
algoType = arg
|
||||||
|
else:
|
||||||
|
import traceback, sys
|
||||||
|
msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
|
||||||
|
sys.stderr.write( msg + '\n' )
|
||||||
|
tb = traceback.extract_stack(None,2)
|
||||||
|
traceback.print_list( [tb[0]] )
|
||||||
|
if not algoType:
|
||||||
|
algoType = self.defaultAlgoType
|
||||||
if not algoType and self.algoTypeToClass:
|
if not algoType and self.algoTypeToClass:
|
||||||
algoType = self.algoTypeToClass.keys()[0]
|
algoType = self.algoTypeToClass.keys()[0]
|
||||||
if self.algoTypeToClass.has_key( algoType ):
|
if self.algoTypeToClass.has_key( algoType ):
|
||||||
#print "Create algo",algoType
|
#print "Create algo",algoType
|
||||||
return self.algoTypeToClass[ algoType ]( self.mesh, geom )
|
return self.algoTypeToClass[ algoType ]( self.mesh, shape )
|
||||||
raise RuntimeError, "No class found for algo type %s" % algoType
|
raise RuntimeError, "No class found for algo type %s" % algoType
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -5294,7 +5366,7 @@ for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ):
|
|||||||
if type( algo ).__name__ == 'classobj' and hasattr( algo, "meshMethod" ):
|
if type( algo ).__name__ == 'classobj' and hasattr( algo, "meshMethod" ):
|
||||||
#print " meshMethod:" , str(algo.meshMethod)
|
#print " meshMethod:" , str(algo.meshMethod)
|
||||||
if not hasattr( Mesh, algo.meshMethod ):
|
if not hasattr( Mesh, algo.meshMethod ):
|
||||||
setattr( Mesh, algo.meshMethod, algoCreator() )
|
setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
|
||||||
pass
|
pass
|
||||||
getattr( Mesh, algo.meshMethod ).add( algo )
|
getattr( Mesh, algo.meshMethod ).add( algo )
|
||||||
pass
|
pass
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
//
|
//
|
||||||
#include "libSMESH_Swig.h"
|
#include "libSMESH_Swig.h"
|
||||||
|
|
||||||
|
#include <SVTK_Selector.h>
|
||||||
|
|
||||||
#include <SMESHGUI.h>
|
#include <SMESHGUI.h>
|
||||||
#include <SMESHGUI_Utils.h>
|
#include <SMESHGUI_Utils.h>
|
||||||
@ -49,6 +50,7 @@
|
|||||||
#include <SalomeApp_Application.h>
|
#include <SalomeApp_Application.h>
|
||||||
#include <LightApp_SelectionMgr.h>
|
#include <LightApp_SelectionMgr.h>
|
||||||
#include <SVTK_RenderWindowInteractor.h>
|
#include <SVTK_RenderWindowInteractor.h>
|
||||||
|
#include <VTKViewer_Algorithm.h>
|
||||||
|
|
||||||
// OCCT includes
|
// OCCT includes
|
||||||
#include <TopAbs.hxx>
|
#include <TopAbs.hxx>
|
||||||
@ -62,6 +64,10 @@
|
|||||||
#include CORBA_SERVER_HEADER(SMESH_Gen)
|
#include CORBA_SERVER_HEADER(SMESH_Gen)
|
||||||
#include CORBA_SERVER_HEADER(SMESH_Hypothesis)
|
#include CORBA_SERVER_HEADER(SMESH_Hypothesis)
|
||||||
|
|
||||||
|
// VTK includes
|
||||||
|
#include <vtkActorCollection.h>
|
||||||
|
#include <vtkRenderer.h>
|
||||||
|
|
||||||
static CORBA::ORB_var anORB;
|
static CORBA::ORB_var anORB;
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@ -815,6 +821,25 @@ void SMESH_Swig::EraseActor( const char* Mesh_Entry, const bool allViewers )
|
|||||||
ProcessVoidEvent(new TEvent(Mesh_Entry, allViewers));
|
ProcessVoidEvent(new TEvent(Mesh_Entry, allViewers));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SMESH_Swig::UpdateActor( const char* Mesh_Entry ) {
|
||||||
|
class TEvent: public SALOME_Event
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const char* _entry;
|
||||||
|
public:
|
||||||
|
TEvent( const char* Mesh_Entry ) {
|
||||||
|
_entry = Mesh_Entry;
|
||||||
|
}
|
||||||
|
virtual void Execute() {
|
||||||
|
Handle(SALOME_InteractiveObject) anIO = new SALOME_InteractiveObject
|
||||||
|
( _entry, "SMESH", "" );
|
||||||
|
SMESH::Update( anIO, true );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ProcessVoidEvent( new TEvent(Mesh_Entry) );
|
||||||
|
}
|
||||||
|
|
||||||
void SMESH_Swig::SetName(const char* theEntry,
|
void SMESH_Swig::SetName(const char* theEntry,
|
||||||
const char* theName)
|
const char* theName)
|
||||||
{
|
{
|
||||||
@ -892,17 +917,18 @@ public:
|
|||||||
{}
|
{}
|
||||||
virtual void Execute()
|
virtual void Execute()
|
||||||
{
|
{
|
||||||
SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI();
|
|
||||||
if( !aSMESHGUI )
|
|
||||||
return;
|
|
||||||
|
|
||||||
LightApp_SelectionMgr* selMgr = SMESH::GetSelectionMgr( aSMESHGUI );
|
LightApp_SelectionMgr* selMgr = 0;
|
||||||
|
SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
|
||||||
|
if( anApp )
|
||||||
|
selMgr = dynamic_cast<LightApp_SelectionMgr*>( anApp->selectionMgr() );
|
||||||
|
|
||||||
if( !selMgr )
|
if( !selMgr )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
selMgr->clearFilters();
|
selMgr->clearFilters();
|
||||||
|
|
||||||
SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( aSMESHGUI );
|
SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow();
|
||||||
if(!aViewWindow)
|
if(!aViewWindow)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -956,30 +982,225 @@ void SMESH_Swig::select( const char* id, int id1, bool append ) {
|
|||||||
ProcessVoidEvent( new TSelectListEvent( id, ids, append ) );
|
ProcessVoidEvent( new TSelectListEvent( id, ids, append ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Helper class for selection edges of cell event
|
||||||
|
*/
|
||||||
|
class TSelectListOfPairEvent: public SALOME_Event
|
||||||
|
{
|
||||||
|
const char* myId;
|
||||||
|
std::vector<std::pair<int, int> > myIdsList;
|
||||||
|
bool myIsAppend;
|
||||||
|
|
||||||
|
public:
|
||||||
|
TSelectListOfPairEvent(const char* id, std::vector<std::pair<int, int> > ids, bool append) :
|
||||||
|
myId(id),
|
||||||
|
myIdsList(ids),
|
||||||
|
myIsAppend(append)
|
||||||
|
{}
|
||||||
|
virtual void Execute()
|
||||||
|
{
|
||||||
|
|
||||||
|
LightApp_SelectionMgr* selMgr = 0;
|
||||||
|
SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
|
||||||
|
if( anApp )
|
||||||
|
selMgr = dynamic_cast<LightApp_SelectionMgr*>( anApp->selectionMgr() );
|
||||||
|
|
||||||
|
if( !selMgr )
|
||||||
|
return;
|
||||||
|
|
||||||
|
selMgr->clearFilters();
|
||||||
|
|
||||||
|
SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow();
|
||||||
|
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() != EdgeOfCellSelection ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SVTK_IndexedMapOfIds aMap;
|
||||||
|
std::vector<std::pair<int, int> >::const_iterator anIter;
|
||||||
|
for (anIter = myIdsList.begin(); anIter != myIdsList.end(); ++anIter) {
|
||||||
|
std::vector<int> aCompositeId;
|
||||||
|
aCompositeId.push_back((*anIter).first);
|
||||||
|
aCompositeId.push_back((*anIter).second);
|
||||||
|
aMap.Add(aCompositeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set new selection
|
||||||
|
SVTK_Selector* aSelector = aViewWindow->GetSelector();
|
||||||
|
aSelector->AddOrRemoveCompositeIndex(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<std::pair<int,int> > ids, bool append ) {
|
||||||
|
ProcessVoidEvent( new TSelectListOfPairEvent( id, ids, append ) );
|
||||||
|
}
|
||||||
|
|
||||||
class TGetSelectionModeEvent : public SALOME_Event
|
class TGetSelectionModeEvent : public SALOME_Event
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef int TResult;
|
typedef SelectionMode TResult;
|
||||||
TResult myResult;
|
TResult myResult;
|
||||||
TGetSelectionModeEvent() : myResult( -1 ) {}
|
TGetSelectionModeEvent() : myResult( Undefined ) {}
|
||||||
virtual void Execute()
|
virtual void Execute()
|
||||||
{
|
{
|
||||||
SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI();
|
SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( );
|
||||||
if( !aSMESHGUI )
|
|
||||||
return;
|
|
||||||
|
|
||||||
SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( aSMESHGUI );
|
|
||||||
if(!aViewWindow)
|
if(!aViewWindow)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
myResult = aViewWindow->SelectionMode();
|
myResult = (SelectionMode) aViewWindow->SelectionMode();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Get selection mode of the active VTK View window.
|
\brief Get selection mode of the active VTK View window.
|
||||||
*/
|
*/
|
||||||
int SMESH_Swig::getSelectionMode() {
|
SelectionMode SMESH_Swig::getSelectionMode() {
|
||||||
return ProcessEvent( new TGetSelectionModeEvent() );
|
return ProcessEvent( new TGetSelectionModeEvent() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Event to set selection mode
|
||||||
|
*/
|
||||||
|
class TSetSelectionModeEvent : public SALOME_Event
|
||||||
|
{
|
||||||
|
SelectionMode mySelectionMode;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TSetSelectionModeEvent(const SelectionMode selectionMode) :
|
||||||
|
mySelectionMode(selectionMode)
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual void Execute()
|
||||||
|
{
|
||||||
|
SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow();
|
||||||
|
if(!aViewWindow)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Selection_Mode prevMode = aViewWindow->SelectionMode();
|
||||||
|
bool changePointRepresentation = ( prevMode == NodeSelection && mySelectionMode != Node ) ||
|
||||||
|
(prevMode != NodeSelection && mySelectionMode == Node);
|
||||||
|
|
||||||
|
if( changePointRepresentation ) {
|
||||||
|
vtkRenderer *aRenderer = aViewWindow->getRenderer();
|
||||||
|
VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
|
||||||
|
vtkActorCollection *aCollection = aCopy.GetActors();
|
||||||
|
aCollection->InitTraversal();
|
||||||
|
while(vtkActor *anAct = aCollection->GetNextActor()){
|
||||||
|
if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
|
||||||
|
if(anActor->GetVisibility()){
|
||||||
|
anActor->SetPointRepresentation(mySelectionMode == Node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
aViewWindow->SetSelectionMode(mySelectionMode);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void SMESH_Swig::setSelectionMode(SelectionMode selectionMode){
|
||||||
|
ProcessVoidEvent( new TSetSelectionModeEvent( selectionMode ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
class TGetSelectedEvent : public SALOME_Event
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef std::vector<int> TResult;
|
||||||
|
TResult myResult;
|
||||||
|
const char* myId;
|
||||||
|
|
||||||
|
TGetSelectedEvent( const char* id) :
|
||||||
|
myResult( std::vector<int>() ),
|
||||||
|
myId(id)
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual void Execute()
|
||||||
|
{
|
||||||
|
SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow();
|
||||||
|
if( !aViewWindow )
|
||||||
|
return;
|
||||||
|
|
||||||
|
SVTK_Selector* aSelector = aViewWindow->GetSelector();
|
||||||
|
if( !aSelector )
|
||||||
|
return;
|
||||||
|
|
||||||
|
SMESH_Actor* anActor = SMESH::FindActorByEntry( myId );
|
||||||
|
|
||||||
|
if ( !anActor || !anActor->hasIO() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
TColStd_IndexedMapOfInteger aMapIndex;
|
||||||
|
aSelector->GetIndex(anActor->getIO(),aMapIndex);
|
||||||
|
|
||||||
|
for( int i = 1; i <= aMapIndex.Extent(); i++ )
|
||||||
|
myResult.push_back( aMapIndex( i ) );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<int> SMESH_Swig::getSelected( const char* Mesh_Entry ) {
|
||||||
|
return ProcessEvent( new TGetSelectedEvent(Mesh_Entry) );
|
||||||
|
}
|
||||||
|
|
||||||
|
class TGetSelectedPairEvent : public SALOME_Event
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef std::vector<std::pair<int, int> > TResult;
|
||||||
|
TResult myResult;
|
||||||
|
const char* myId;
|
||||||
|
|
||||||
|
TGetSelectedPairEvent( const char* id) :
|
||||||
|
myResult( std::vector<std::pair<int,int> >() ),
|
||||||
|
myId(id)
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual void Execute()
|
||||||
|
{
|
||||||
|
SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow();
|
||||||
|
if( !aViewWindow )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(aViewWindow->SelectionMode() != EdgeOfCellSelection )
|
||||||
|
return;
|
||||||
|
|
||||||
|
SVTK_Selector* aSelector = aViewWindow->GetSelector();
|
||||||
|
if( !aSelector )
|
||||||
|
return;
|
||||||
|
|
||||||
|
SMESH_Actor* anActor = SMESH::FindActorByEntry( myId );
|
||||||
|
|
||||||
|
if ( !anActor || !anActor->hasIO() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
SVTK_IndexedMapOfIds aMapIndex;
|
||||||
|
aSelector->GetCompositeIndex(anActor->getIO(),aMapIndex);
|
||||||
|
|
||||||
|
for( int i = 1; i <= aMapIndex.Extent(); i++ )
|
||||||
|
myResult.push_back( std::make_pair<int,int>( (int)aMapIndex( i )[0], (int)aMapIndex( i )[1]) );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<std::pair<int,int> > SMESH_Swig::getSelectedEdgeOfCell( const char* Mesh_Entry ) {
|
||||||
|
return ProcessEvent( new TGetSelectedPairEvent(Mesh_Entry) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -40,13 +40,15 @@
|
|||||||
|
|
||||||
//std includes
|
//std includes
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include <SVTK_Selection.h>
|
#include <SVTK_Selection.h>
|
||||||
|
|
||||||
#include <SVTK_Selection.h>
|
#include <SVTK_Selection.h>
|
||||||
|
|
||||||
enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
Undefined = -1,
|
||||||
Node = NodeSelection,
|
Node = NodeSelection,
|
||||||
Cell = CellSelection,
|
Cell = CellSelection,
|
||||||
EdgeOfCell = EdgeOfCellSelection,
|
EdgeOfCell = EdgeOfCellSelection,
|
||||||
@ -56,7 +58,7 @@ enum
|
|||||||
Actor = ActorSelection,
|
Actor = ActorSelection,
|
||||||
Elem0D = Elem0DSelection,
|
Elem0D = Elem0DSelection,
|
||||||
Ball = BallSelection
|
Ball = BallSelection
|
||||||
};
|
} SelectionMode;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -118,6 +120,8 @@ public:
|
|||||||
|
|
||||||
void EraseActor( const char*, const bool allViewers = false );
|
void EraseActor( const char*, const bool allViewers = false );
|
||||||
|
|
||||||
|
void UpdateActor( const char* Mesh_Entry );
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Set mesh icon according to compute status
|
* \brief Set mesh icon according to compute status
|
||||||
* \param Mesh_Entry - entry of a mesh
|
* \param Mesh_Entry - entry of a mesh
|
||||||
@ -128,10 +132,15 @@ public:
|
|||||||
actorAspect GetActorAspect(const char* Mesh_Entry, int viewId = 0 );
|
actorAspect GetActorAspect(const char* Mesh_Entry, int viewId = 0 );
|
||||||
void SetActorAspect( const actorAspect& actorPres, const char* Mesh_Entry, int viewId = 0 );
|
void SetActorAspect( const actorAspect& actorPres, const char* Mesh_Entry, int viewId = 0 );
|
||||||
|
|
||||||
|
void setSelectionMode( SelectionMode selectionMode );
|
||||||
|
std::vector<int> getSelected( const char* Mesh_Entry );
|
||||||
|
std::vector<std::pair<int, int> > getSelectedEdgeOfCell( const char* Mesh_Entry );
|
||||||
|
|
||||||
// --------------------- for the test purposes -----------------------
|
// --------------------- for the test purposes -----------------------
|
||||||
int getSelectionMode();
|
SelectionMode getSelectionMode();
|
||||||
void select( const char *id, std::vector<int> ids, bool append = false );
|
void select( const char *id, std::vector<int> ids, bool append = false );
|
||||||
void select( const char *id, int id1, bool append = false );
|
void select( const char *id, int id1, bool append = false );
|
||||||
|
void select( const char *id, std::vector<std::pair<int,int> >, bool apend = false );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SALOMEDS::Study_var myStudy;
|
SALOMEDS::Study_var myStudy;
|
||||||
|
@ -48,16 +48,21 @@
|
|||||||
|
|
||||||
%include "typemaps.i"
|
%include "typemaps.i"
|
||||||
%include "std_vector.i"
|
%include "std_vector.i"
|
||||||
|
%include "std_pair.i"
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
|
|
||||||
%template(VectorInt) vector<int>;
|
%template(VectorInt) vector<int>;
|
||||||
|
%template() std::pair<int,int>;
|
||||||
|
%template(PairVector) std::vector<std::pair<int,int> >;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Selection mode enumeration (corresponds to constants from the SALOME_Selection.h) */
|
/* Selection mode enumeration (corresponds to constants from the SALOME_Selection.h) */
|
||||||
enum
|
enum SelectionMode
|
||||||
{
|
{
|
||||||
Node,
|
Undefined = -1,
|
||||||
|
Node = 0,
|
||||||
Cell,
|
Cell,
|
||||||
EdgeOfCell,
|
EdgeOfCell,
|
||||||
Edge,
|
Edge,
|
||||||
@ -127,13 +132,19 @@ class SMESH_Swig
|
|||||||
|
|
||||||
void CreateAndDisplayActor( const char* Mesh_Entry );
|
void CreateAndDisplayActor( const char* Mesh_Entry );
|
||||||
void EraseActor( const char* Mesh_Entry, const bool allViewers = false );
|
void EraseActor( const char* Mesh_Entry, const bool allViewers = false );
|
||||||
|
void UpdateActor( const char* Mesh_Entry );
|
||||||
|
|
||||||
|
void setSelectionMode( SelectionMode selectionMode);
|
||||||
|
std::vector<int> getSelected( const char* Mesh_Entry );
|
||||||
|
std::vector<std::pair<int,int> > getSelectedEdgeOfCell( const char* Mesh_Entry );
|
||||||
|
|
||||||
actorAspect GetActorAspect(const char* Mesh_Entry, int viewId = 0 );
|
actorAspect GetActorAspect(const char* Mesh_Entry, int viewId = 0 );
|
||||||
void SetActorAspect( const actorAspect& actorPres, const char* Mesh_Entry, int viewId = 0 );
|
void SetActorAspect( const actorAspect& actorPres, const char* Mesh_Entry, int viewId = 0 );
|
||||||
|
|
||||||
// --------------------- for the test purposes -----------------------
|
// --------------------- for the test purposes -----------------------
|
||||||
int getSelectionMode();
|
SelectionMode getSelectionMode();
|
||||||
void select( const char *id, std::vector<int> ids, bool append = false );
|
void select( const char *id, std::vector<int> ids, bool append = false );
|
||||||
void select( const char *id, int id1, bool append = false );
|
void select( const char *id, int id1, bool append = false );
|
||||||
|
void select( const char *id, std::vector<std::pair<int,int> >, bool apend = false );
|
||||||
|
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user