GPUSPHGUI: add Offset transformation

This commit is contained in:
eap 2018-02-09 22:41:01 +03:00
parent 9655cb578d
commit 3a821b48ba
54 changed files with 1857 additions and 1149 deletions

View File

@ -688,6 +688,13 @@ module SMESH
in string MeshName)
raises (SALOME::SALOME_Exception);
SMESH_Mesh Offset(in SMESH_IDSource theObject,
in double Value,
in boolean CopyGroups,
in string MeshName,
out ListOfGroups Groups)
raises (SALOME::SALOME_Exception);
void FindCoincidentNodes (in double Tolerance,
out array_of_long_array GroupsOfNodes,
in boolean SeparateCornersAndMedium)
@ -874,7 +881,7 @@ module SMESH
* \param theElements - container of elements to duplicate.
* \param theGroupName - a name of group to contain the generated elements.
* If a group with such a name already exists, the new elements
* are added to the existng group, else a new group is created.
* are added to the existing group, else a new group is created.
* If \a theGroupName is empty, new elements are not added
* in any group.
* \return a group where the new elements are added. NULL if theGroupName == "".

View File

@ -229,6 +229,7 @@ SET(SMESH_RESOURCES_FILES
mesh_show.png
mesh_hide.png
mesh_deflection.png
mesh_offset.png
)
INSTALL(FILES ${SMESH_RESOURCES_FILES} DESTINATION ${SALOME_SMESH_INSTALL_RES_DATA})

View File

@ -31,18 +31,13 @@
#include "SMDS_FaceOfNodes.hxx"
#include "SMDS_IteratorOnIterators.hxx"
#include "SMDS_Mesh.hxx"
#include "SMDS_MeshElement.hxx"
#include "SMDS_MeshNode.hxx"
#include "SMDS_PolygonalFaceOfNodes.hxx"
#include "SMDS_SetIterator.hxx"
#include "SMDS_VolumeTool.hxx"
#include "SMESH_File.hxx"
#include "SMESH_MeshAlgos.hxx"
#include "SMESH_TypeDefs.hxx"
#include <Standard_ErrorHandler.hxx>
#include <Standard_Failure.hxx>
#include <gp_Ax2.hxx>
#include <limits>
@ -208,270 +203,6 @@ static gp_XYZ getNormale( const SMDS_MeshNode* n1,
return n;
}
namespace
{
/*!
* \brief Vertex of a polygon. Together with 2 neighbor Vertices represents a triangle
*/
struct PolyVertex
{
SMESH_TNodeXYZ _nxyz;
gp_XY _xy;
PolyVertex* _prev;
PolyVertex* _next;
void SetNodeAndNext( const SMDS_MeshNode* n, PolyVertex& v )
{
_nxyz.Set( n );
_next = &v;
v._prev = this;
}
PolyVertex* Delete()
{
_prev->_next = _next;
_next->_prev = _prev;
return _next;
}
void GetTriaNodes( const SMDS_MeshNode** nodes) const
{
nodes[0] = _prev->_nxyz._node;
nodes[1] = this->_nxyz._node;
nodes[2] = _next->_nxyz._node;
}
inline static double Area( const PolyVertex* v0, const PolyVertex* v1, const PolyVertex* v2 )
{
gp_XY vPrev = v0->_xy - v1->_xy;
gp_XY vNext = v2->_xy - v1->_xy;
return vNext ^ vPrev;
}
double TriaArea() const { return Area( _prev, this, _next ); }
bool IsInsideTria( const PolyVertex* v )
{
gp_XY p = _prev->_xy - v->_xy;
gp_XY t = this->_xy - v->_xy;
gp_XY n = _next->_xy - v->_xy;
const double tol = -1e-12;
return (( p ^ t ) >= tol &&
( t ^ n ) >= tol &&
( n ^ p ) >= tol );
// return ( Area( _prev, this, v ) > 0 &&
// Area( this, _next, v ) > 0 &&
// Area( _next, _prev, v ) > 0 );
}
};
//================================================================================
/*!
* \brief Triangulate a polygon. Assure correct orientation for concave polygons
*/
//================================================================================
bool triangulate( std::vector< const SMDS_MeshNode*>& nodes, const size_t nbNodes )
{
// connect nodes into a ring
std::vector< PolyVertex > pv( nbNodes );
for ( size_t i = 1; i < nbNodes; ++i )
pv[i-1].SetNodeAndNext( nodes[i-1], pv[i] );
pv[ nbNodes-1 ].SetNodeAndNext( nodes[ nbNodes-1 ], pv[0] );
// get a polygon normal
gp_XYZ normal(0,0,0), p0,v01,v02;
p0 = pv[0]._nxyz;
v01 = pv[1]._nxyz - p0;
for ( size_t i = 2; i < nbNodes; ++i )
{
v02 = pv[i]._nxyz - p0;
normal += v01 ^ v02;
v01 = v02;
}
// project nodes to the found plane
gp_Ax2 axes;
try {
axes = gp_Ax2( p0, normal, v01 );
}
catch ( Standard_Failure ) {
return false;
}
for ( size_t i = 0; i < nbNodes; ++i )
{
gp_XYZ p = pv[i]._nxyz - p0;
pv[i]._xy.SetX( axes.XDirection().XYZ() * p );
pv[i]._xy.SetY( axes.YDirection().XYZ() * p );
}
// in a loop, find triangles with positive area and having no vertices inside
int iN = 0, nbTria = nbNodes - 2;
nodes.reserve( nbTria * 3 );
const double minArea = 1e-6;
PolyVertex* v = &pv[0], *vi;
int nbVertices = nbNodes, nbBadTria = 0, isGoodTria;
while ( nbBadTria < nbVertices )
{
if (( isGoodTria = v->TriaArea() > minArea ))
{
for ( vi = v->_next->_next;
vi != v->_prev;
vi = vi->_next )
{
if ( v->IsInsideTria( vi ))
break;
}
isGoodTria = ( vi == v->_prev );
}
if ( isGoodTria )
{
v->GetTriaNodes( &nodes[ iN ] );
iN += 3;
v = v->Delete();
if ( --nbVertices == 3 )
{
// last triangle remains
v->GetTriaNodes( &nodes[ iN ] );
return true;
}
nbBadTria = 0;
}
else
{
v = v->_next;
++nbBadTria;
}
}
// the polygon is invalid; add triangles with positive area
nbBadTria = 0;
while ( nbBadTria < nbVertices )
{
isGoodTria = v->TriaArea() > minArea;
if ( isGoodTria )
{
v->GetTriaNodes( &nodes[ iN ] );
iN += 3;
v = v->Delete();
if ( --nbVertices == 3 )
{
// last triangle remains
v->GetTriaNodes( &nodes[ iN ] );
return true;
}
nbBadTria = 0;
}
else
{
v = v->_next;
++nbBadTria;
}
}
// add all the rest triangles
while ( nbVertices >= 3 )
{
v->GetTriaNodes( &nodes[ iN ] );
iN += 3;
v = v->Delete();
--nbVertices;
}
return true;
} // triangulate()
} // namespace
//================================================================================
/*!
* \brief Return nb triangles in a decomposed mesh face
* \retval int - number of triangles
*/
//================================================================================
static int getNbTriangles( const SMDS_MeshElement* face)
{
// WARNING: counting triangles must be coherent with getTriangles()
switch ( face->GetEntityType() )
{
case SMDSEntity_BiQuad_Triangle:
case SMDSEntity_BiQuad_Quadrangle:
return face->NbNodes() - 1;
// case SMDSEntity_Triangle:
// case SMDSEntity_Quad_Triangle:
// case SMDSEntity_Quadrangle:
// case SMDSEntity_Quad_Quadrangle:
// case SMDSEntity_Polygon:
// case SMDSEntity_Quad_Polygon:
default:
return face->NbNodes() - 2;
}
return 0;
}
//================================================================================
/*!
* \brief Decompose a mesh face into triangles
* \retval int - number of triangles
*/
//================================================================================
static int getTriangles( const SMDS_MeshElement* face,
std::vector< const SMDS_MeshNode*>& nodes)
{
// WARNING: decomposing into triangles must be coherent with getNbTriangles()
int nbTria, i = 0, nbNodes = face->NbNodes();
SMDS_NodeIteratorPtr nIt = face->interlacedNodesIterator();
nodes.resize( nbNodes * 3 );
nodes[ i++ ] = nIt->next();
nodes[ i++ ] = nIt->next();
const SMDSAbs_EntityType type = face->GetEntityType();
switch ( type )
{
case SMDSEntity_BiQuad_Triangle:
case SMDSEntity_BiQuad_Quadrangle:
nbTria = ( type == SMDSEntity_BiQuad_Triangle ) ? 6 : 8;
nodes[ i++ ] = face->GetNode( nbTria );
for ( i = 3; i < 3*(nbTria-1); i += 3 )
{
nodes[ i+0 ] = nodes[ i-2 ];
nodes[ i+1 ] = nIt->next();
nodes[ i+2 ] = nodes[ 2 ];
}
nodes[ i+0 ] = nodes[ i-2 ];
nodes[ i+1 ] = nodes[ 0 ];
nodes[ i+2 ] = nodes[ 2 ];
break;
case SMDSEntity_Triangle:
nbTria = 1;
nodes[ i++ ] = nIt->next();
break;
default:
// case SMDSEntity_Quad_Triangle:
// case SMDSEntity_Quadrangle:
// case SMDSEntity_Quad_Quadrangle:
// case SMDSEntity_Polygon:
// case SMDSEntity_Quad_Polygon:
nbTria = nbNodes - 2;
while ( nIt->more() )
nodes[ i++ ] = nIt->next();
if ( !triangulate( nodes, nbNodes ))
{
nIt = face->interlacedNodesIterator();
nodes[ 0 ] = nIt->next();
nodes[ 1 ] = nIt->next();
nodes[ 2 ] = nIt->next();
for ( i = 3; i < 3*nbTria; i += 3 )
{
nodes[ i+0 ] = nodes[ 0 ];
nodes[ i+1 ] = nodes[ i-1 ];
nodes[ i+2 ] = nIt->next();
}
}
break;
}
return nbTria;
}
// private methods
Driver_Mesh::Status DriverSTL_W_SMDS_Mesh::writeAscii() const
@ -492,11 +223,13 @@ Driver_Mesh::Status DriverSTL_W_SMDS_Mesh::writeAscii() const
char sval[128];
std::vector< const SMDS_MeshNode* > triaNodes;
SMESH_MeshAlgos::Triangulate triangulator;
SMDS_ElemIteratorPtr itFaces = getFaces();
while ( itFaces->more() )
{
const SMDS_MeshElement* aFace = itFaces->next();
int nbTria = getTriangles( aFace, triaNodes );
int nbTria = triangulator.GetTriangles( aFace, triaNodes );
for ( int iT = 0, iN = 0; iT < nbTria; ++iT )
{
@ -546,13 +279,15 @@ Driver_Mesh::Status DriverSTL_W_SMDS_Mesh::writeBinary() const
SMESH_File aFile( myFile );
aFile.openForWriting();
SMESH_MeshAlgos::Triangulate triangulator;
// we first count the number of triangles
int nbTri = myNbVolumeTrias;
{
SMDS_FaceIteratorPtr itFaces = myMesh->facesIterator();
while ( itFaces->more() ) {
const SMDS_MeshElement* aFace = itFaces->next();
nbTri += getNbTriangles( aFace );
nbTri += triangulator.GetNbTriangles( aFace );
}
}
std::string sval( LABEL_SIZE, ' ' );
@ -576,7 +311,7 @@ Driver_Mesh::Status DriverSTL_W_SMDS_Mesh::writeBinary() const
while ( itFaces->more() )
{
const SMDS_MeshElement* aFace = itFaces->next();
int nbTria = getTriangles( aFace, triaNodes );
int nbTria = triangulator.GetTriangles( aFace, triaNodes );
for ( int iT = 0, iN = 0; iT < nbTria; ++iT )
{

View File

@ -688,6 +688,7 @@ public:
virtual void Renumber (const bool isNodes, const int startID = 1, const int deltaID = 1);
// Renumber all nodes or elements.
virtual void compactMesh();
virtual void CompactMesh() { compactMesh(); }
const SMDS_MeshNode *FindNode(int idnode) const;
const SMDS_MeshNode *FindNodeVtk(int idnode) const;

View File

@ -67,7 +67,6 @@ class SMDS_EXPORT SMDS_PolygonalFaceOfNodes:public SMDS_MeshFace
protected:
virtual SMDS_ElemIteratorPtr elementsIterator (SMDSAbs_ElementType type) const;
private:
std::vector<const SMDS_MeshNode *> myNodes;
};

View File

@ -45,7 +45,7 @@ public:
// constructor to use as return from begin()
SMDS_StdIterator( PtrSMDSIterator pItr )
: _value( pItr->more() ? (VALUE)(pItr->next()) : 0 ), _piterator(pItr)
: _value( pItr->more() ? VALUE(pItr->next()) : VALUE(0) ), _piterator(pItr)
{}
// constructor to use as return from end()
SMDS_StdIterator(): _value( 0 )
@ -58,12 +58,12 @@ public:
// Step to the next one
_Self&
operator++()
{ _value = _piterator->more() ? VALUE( _piterator->next()) : 0; return *this; }
{ _value = _piterator->more() ? VALUE( _piterator->next()) : VALUE(0); return *this; }
// Step to the next one
_Self
operator++(int)
{ _Self res = *this; _value = _piterator->more() ? VALUE( _piterator->next()) : 0; return res; }
{ _Self res = *this; _value = _piterator->more() ? VALUE( _piterator->next()) : VALUE(0); return res; }
// Test of end
bool

File diff suppressed because it is too large Load Diff

View File

@ -465,6 +465,13 @@ public:
SMESH_Mesh* theTargetMesh=0);
// Move or copy theElements applying theTrsf to their nodes
PGroupIDs Offset( TIDSortedElemSet & theElements,
const double theValue,
SMESH_Mesh* theTgtMesh,
const bool theMakeGroups,
const bool theFixSelfIntersection);
// Make an offset mesh from a source 2D mesh
typedef std::list< std::list< const SMDS_MeshNode* > > TListOfListOfNodes;
void FindCoincidentNodes (TIDSortedNodeSet & theNodes,

View File

@ -4143,9 +4143,9 @@ namespace { // Structures used by FixQuadraticElements()
{
// code is valid for convex faces only
gp_XYZ gc(0,0,0);
for ( TIDSortedNodeSet::const_iterator n = begin(); n!=end(); ++n)
gc += XYZ( *n ) / size();
for (unsigned i = 0; i < _sides.size(); ++i )
for ( TIDSortedNodeSet::const_iterator n = begin(); n != end(); ++n )
gc += XYZ( *n ) / double( size() );
for ( size_t i = 0; i < _sides.size(); ++i )
{
if ( _sides[i] == bentLink ) continue;
gp_Vec linkNorm = _normal ^ gp_Vec( XYZ(_sides[i]->node1()), XYZ(_sides[i]->node2()));
@ -4161,12 +4161,12 @@ namespace { // Structures used by FixQuadraticElements()
return true;
}
return false;
}
//================================================================================
/*!
* \brief Find pairs of continues faces
* \brief Find pairs of continues faces
*/
//================================================================================

View File

@ -111,6 +111,7 @@ SET(_moc_HEADERS
SMESHGUI_RotationDlg.h
SMESHGUI_TranslationDlg.h
SMESHGUI_ScaleDlg.h
SMESHGUI_OffsetDlg.h
SMESHGUI_SymmetryDlg.h
SMESHGUI_SewingDlg.h
SMESHGUI_DuplicateNodesDlg.h
@ -206,6 +207,7 @@ SET(_other_SOURCES
SMESHGUI_RotationDlg.cxx
SMESHGUI_TranslationDlg.cxx
SMESHGUI_ScaleDlg.cxx
SMESHGUI_OffsetDlg.cxx
SMESHGUI_SymmetryDlg.cxx
SMESHGUI_SewingDlg.cxx
SMESHGUI_DuplicateNodesDlg.cxx

View File

@ -74,6 +74,7 @@
#include "SMESHGUI_RevolutionDlg.h"
#include "SMESHGUI_RotationDlg.h"
#include "SMESHGUI_ScaleDlg.h"
#include "SMESHGUI_OffsetDlg.h"
#include "SMESHGUI_Selection.h"
#include "SMESHGUI_SewingDlg.h"
#include "SMESHGUI_SingleEditDlg.h"
@ -3534,6 +3535,20 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
break;
}
case SMESHOp::OpOffset:
{
if(checkLock(aStudy)) break;
if ( vtkwnd ) {
EmitSignalDeactivateDialog();
( new SMESHGUI_OffsetDlg( this ) )->show();
}
else {
SUIT_MessageBox::warning(SMESHGUI::desktop(),
tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
}
break;
}
case SMESHOp::OpSewing:
{
if(checkLock(aStudy)) break;
@ -3984,6 +3999,7 @@ void SMESHGUI::initialize( CAM_Application* app )
createSMESHAction( SMESHOp::OpRotation, "ROT", "ICON_DLG_MESH_ROTATION" );
createSMESHAction( SMESHOp::OpSymmetry, "SYM", "ICON_SMESH_SYMMETRY_PLANE" );
createSMESHAction( SMESHOp::OpScale, "SCALE", "ICON_DLG_MESH_SCALE" );
createSMESHAction( SMESHOp::OpOffset, "OFFSET", "ICON_DLG_MESH_OFFSET" );
createSMESHAction( SMESHOp::OpSewing, "SEW", "ICON_SMESH_SEWING_FREEBORDERS" );
createSMESHAction( SMESHOp::OpMergeNodes, "MERGE", "ICON_SMESH_MERGE_NODES" );
createSMESHAction( SMESHOp::OpMergeElements, "MERGE_ELEMENTS", "ICON_DLG_MERGE_ELEMENTS" );
@ -4222,31 +4238,32 @@ void SMESHGUI::initialize( CAM_Application* app )
//createMenu( SMESHOp::OpRenumberingNodes, renumId, -1 );
//createMenu( SMESHOp::OpRenumberingElements, renumId, -1 );
createMenu( SMESHOp::OpMergeNodes, transfId, -1 );
createMenu( SMESHOp::OpMergeElements, transfId, -1 );
createMenu( SMESHOp::OpTranslation, transfId, -1 );
createMenu( SMESHOp::OpRotation, transfId, -1 );
createMenu( SMESHOp::OpSymmetry, transfId, -1 );
createMenu( SMESHOp::OpScale, transfId, -1 );
createMenu( SMESHOp::OpOffset, transfId, -1 );
createMenu( SMESHOp::OpSewing, transfId, -1 );
createMenu( SMESHOp::OpMergeNodes, transfId, -1 );
createMenu( SMESHOp::OpMergeElements, transfId, -1 );
createMenu( SMESHOp::OpDuplicateNodes, transfId, -1 );
createMenu( SMESHOp::OpConvertMeshToQuadratic, modifyId, -1 );
createMenu( SMESHOp::OpCreateBoundaryElements, modifyId, -1 );
createMenu( SMESHOp::OpExtrusion, modifyId, -1 );
createMenu( SMESHOp::OpExtrusionAlongAPath, modifyId, -1 );
createMenu( SMESHOp::OpRevolution, modifyId, -1 );
createMenu( SMESHOp::OpOrientation, modifyId, -1 );
createMenu( SMESHOp::OpReorientFaces, modifyId, -1 );
createMenu( SMESHOp::OpMoveNode, modifyId, -1 );
createMenu( SMESHOp::OpDiagonalInversion, modifyId, -1 );
createMenu( SMESHOp::OpUnionOfTwoTriangle, modifyId, -1 );
createMenu( SMESHOp::OpOrientation, modifyId, -1 );
createMenu( SMESHOp::OpReorientFaces, modifyId, -1 );
createMenu( SMESHOp::OpUnionOfTriangles, modifyId, -1 );
createMenu( SMESHOp::OpCuttingOfQuadrangles, modifyId, -1 );
createMenu( SMESHOp::OpSplitVolumes, modifyId, -1 );
createMenu( SMESHOp::OpSplitBiQuadratic, modifyId, -1 );
createMenu( SMESHOp::OpSmoothing, modifyId, -1 );
createMenu( SMESHOp::OpExtrusion, modifyId, -1 );
createMenu( SMESHOp::OpExtrusionAlongAPath , modifyId, -1 );
createMenu( SMESHOp::OpRevolution, modifyId, -1 );
createMenu( SMESHOp::OpPatternMapping, modifyId, -1 );
createMenu( SMESHOp::OpConvertMeshToQuadratic, modifyId, -1 );
createMenu( SMESHOp::OpCreateBoundaryElements, modifyId, -1 );
createMenu( SMESHOp::OpMinimumDistance, measureId, -1 );
createMenu( SMESHOp::OpBoundingBox, measureId, -1 );
@ -4366,31 +4383,32 @@ void SMESHGUI::initialize( CAM_Application* app )
//createTool( SMESHOp::OpRenumberingNodes, renumbTb );
//createTool( SMESHOp::OpRenumberingElements, renumbTb );
createTool( SMESHOp::OpMergeNodes, transformTb );
createTool( SMESHOp::OpMergeElements, transformTb );
createTool( SMESHOp::OpTranslation, transformTb );
createTool( SMESHOp::OpRotation, transformTb );
createTool( SMESHOp::OpSymmetry, transformTb );
createTool( SMESHOp::OpScale, transformTb );
createTool( SMESHOp::OpOffset, transformTb );
createTool( SMESHOp::OpSewing, transformTb );
createTool( SMESHOp::OpMergeNodes, transformTb );
createTool( SMESHOp::OpMergeElements, transformTb );
createTool( SMESHOp::OpDuplicateNodes, transformTb );
createTool( SMESHOp::OpConvertMeshToQuadratic, modifyTb );
createTool( SMESHOp::OpCreateBoundaryElements, modifyTb );
createTool( SMESHOp::OpExtrusion, modifyTb );
createTool( SMESHOp::OpExtrusionAlongAPath, modifyTb );
createTool( SMESHOp::OpRevolution, modifyTb );
createTool( SMESHOp::OpOrientation, modifyTb );
createTool( SMESHOp::OpReorientFaces, modifyTb );
createTool( SMESHOp::OpMoveNode, modifyTb );
createTool( SMESHOp::OpDiagonalInversion, modifyTb );
createTool( SMESHOp::OpUnionOfTwoTriangle, modifyTb );
createTool( SMESHOp::OpOrientation, modifyTb );
createTool( SMESHOp::OpReorientFaces, modifyTb );
createTool( SMESHOp::OpUnionOfTriangles, modifyTb );
createTool( SMESHOp::OpCuttingOfQuadrangles, modifyTb );
createTool( SMESHOp::OpSplitVolumes, modifyTb );
createTool( SMESHOp::OpSplitBiQuadratic, modifyTb );
createTool( SMESHOp::OpSmoothing, modifyTb );
createTool( SMESHOp::OpExtrusion, modifyTb );
createTool( SMESHOp::OpExtrusionAlongAPath, modifyTb );
createTool( SMESHOp::OpRevolution, modifyTb );
createTool( SMESHOp::OpPatternMapping, modifyTb );
createTool( SMESHOp::OpConvertMeshToQuadratic, modifyTb );
createTool( SMESHOp::OpCreateBoundaryElements, modifyTb );
createTool( SMESHOp::OpMinimumDistance, measuremTb );

View File

@ -40,7 +40,7 @@
#include <SMESH_FaceOrientationFilter.h>
#include <SMDS_Mesh.hxx>
// SALOME GUI inclues
// SALOME GUI includes
#include <SUIT_Desktop.h>
#include <SUIT_Session.h>
#include <SUIT_ResourceMgr.h>
@ -56,7 +56,7 @@
#include <Qtx.h>
// IDL incldues
// IDL includes
#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
// OCCT includes
@ -777,7 +777,7 @@ void SMESHGUI_AddMeshElementDlg::onTextChange (const QString& theNewText)
mySimulation->SetVisibility(false);
// hilight entered nodes
// highlight entered nodes
SMDS_Mesh* aMesh = 0;
if (myActor)
aMesh = myActor->GetObject()->GetMesh();

View File

@ -977,7 +977,7 @@ void SMESHGUI_AddQuadraticElementDlg::onTextChange (const QString& theNewText)
mySimulation->SetVisibility(false);
// hilight entered nodes
// highlight entered nodes
SMDS_Mesh* aMesh = 0;
if (myActor)
aMesh = myActor->GetObject()->GetMesh();

View File

@ -452,7 +452,7 @@ void SMESHGUI_CopyMeshDlg::onTextChange (const QString& theNewText)
buttonOk->setEnabled(false);
buttonApply->setEnabled(false);
// hilight entered elements
// highlight entered elements
SMDS_Mesh* aMesh = 0;
if (myActor)
aMesh = myActor->GetObject()->GetMesh();

View File

@ -717,7 +717,7 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::onTextChange(const QString& theNewText)
buttonOk->setEnabled( false );
buttonApply->setEnabled( false );
// check entered ids of faces and hilight them
// check entered ids of faces and highlight them
QStringList aListId;
if ( aMesh ) {
TColStd_MapOfInteger newIndices;

View File

@ -337,7 +337,7 @@ void SMESHGUI_3TypesSelector::onTextChange( const QString& theNewText )
myBusy = true;
// hilight entered elements/nodes
// highlight entered elements/nodes
myIDSource[ iType ]->length( 0 );

View File

@ -346,7 +346,7 @@ void SMESHGUI_FindElemByPointOp::onCloseView()
}
//================================================================================
/*!
* \brief hilight found selected elements
* \brief highlight found selected elements
*/
//================================================================================

View File

@ -2373,7 +2373,7 @@ void SMESHGUI_TreeElemInfo::saveInfo( QTextStream &out )
*/
/*!
\brief Contructor
\brief Constructor
*/
GrpComputor::GrpComputor( SMESH::SMESH_GroupBase_ptr grp,
QTreeWidgetItem* item,

View File

@ -1400,7 +1400,7 @@ void SMESHGUI_MeshPatternDlg::onTextChanged (const QString& theNewText)
activateSelection();
}
// hilight entered elements/nodes
// highlight entered elements/nodes
SMDS_Mesh* aMesh = 0;
SMESH_Actor* anActor = SMESH::FindActorByObject(myMesh);
if (anActor)

View File

@ -883,7 +883,7 @@ void SMESHGUI_MultiEditDlg::onListSelectionChanged()
if (myListBox->item(i)->isSelected())
{
int anId = myListBox->item(i)->text().toInt();
if (anObj->GetElemVTKId(anId) >= 0) // avoid exception in hilight
if (anObj->GetElemVTKId(anId) >= 0) // avoid exception in highlight
anIndexes.Add(anId);
}
}

View File

@ -0,0 +1,937 @@
// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// File : SMESHGUI_OffsetDlg.cxx
// SMESH includes
#include "SMESHGUI_OffsetDlg.h"
#include "SMESHGUI.h"
#include "SMESHGUI_SpinBox.h"
#include "SMESHGUI_Utils.h"
#include "SMESHGUI_VTKUtils.h"
#include "SMESHGUI_MeshUtils.h"
#include "SMESHGUI_IdValidator.h"
#include "SMESHGUI_FilterDlg.h"
#include "SMESHGUI_MeshEditPreview.h"
#include <SMESH_Actor.h>
#include <SMESH_TypeFilter.hxx>
#include <SMESH_LogicalFilter.hxx>
#include <SMDS_Mesh.hxx>
// SALOME GUI includes
#include <LightApp_Application.h>
#include <LightApp_SelectionMgr.h>
#include <SALOME_ListIO.hxx>
#include <SUIT_Desktop.h>
#include <SUIT_MessageBox.h>
#include <SUIT_OverrideCursor.h>
#include <SUIT_ResourceMgr.h>
#include <SUIT_Session.h>
#include <SVTK_ViewModel.h>
#include <SVTK_ViewWindow.h>
#include <SalomeApp_Tools.h>
// SALOME KERNEL includes
#include <SALOMEDSClient.hxx>
#include <SALOMEDSClient_SObject.hxx>
// OCCT includes
#include <TColStd_MapOfInteger.hxx>
// Qt includes
#include <QApplication>
#include <QButtonGroup>
#include <QGroupBox>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QRadioButton>
#include <QCheckBox>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QGridLayout>
#include <QSpinBox>
#include <QKeyEvent>
// IDL includes
#include <SALOMEconfig.h>
#include CORBA_SERVER_HEADER(SMESH_Group)
#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
enum { MOVE_ELEMS_BUTTON = 0, COPY_ELEMS_BUTTON, MAKE_MESH_BUTTON }; //!< action type
/*!
\class BusyLocker
\brief Simple 'busy state' flag locker.
\internal
*/
class BusyLocker
{
public:
//! Constructor. Sets passed boolean flag to \c true.
BusyLocker( bool& busy ) : myBusy( busy ) { myBusy = true; }
//! Destructor. Clear external boolean flag passed as parameter to the constructor to \c false.
~BusyLocker() { myBusy = false; }
private:
bool& myBusy; //! External 'busy state' boolean flag
};
#define SPACING 6
#define MARGIN 11
//=================================================================================
// class : SMESHGUI_OffsetDlg()
// purpose :
//=================================================================================
SMESHGUI_OffsetDlg::SMESHGUI_OffsetDlg( SMESHGUI* theModule ) :
SMESHGUI_MultiPreviewDlg( theModule ),
mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
myFilterDlg(0)
{
QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_DLG_MESH_OFFSET")));
QPixmap image1 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
setModal(false);
setAttribute(Qt::WA_DeleteOnClose, true);
setWindowTitle(tr("SMESH_OFFSET_TITLE"));
setSizeGripEnabled(true);
QVBoxLayout* dlgLayout = new QVBoxLayout(this);
dlgLayout->setSpacing(SPACING);
dlgLayout->setMargin(MARGIN);
/***************************************************************/
ConstructorsBox = new QGroupBox(tr("SMESH_OFFSET"), this);
QHBoxLayout* ConstructorsBoxLayout = new QHBoxLayout(ConstructorsBox);
ConstructorsBoxLayout->setSpacing(SPACING);
ConstructorsBoxLayout->setMargin(MARGIN);
QRadioButton* RadioButton1= new QRadioButton(ConstructorsBox);
RadioButton1->setIcon(image0);
ConstructorsBoxLayout->addWidget(RadioButton1);
/***************************************************************/
GroupArguments = new QGroupBox(tr("SMESH_ARGUMENTS"), this);
QGridLayout* GroupArgumentsLayout = new QGridLayout(GroupArguments);
GroupArgumentsLayout->setSpacing(SPACING);
GroupArgumentsLayout->setMargin(MARGIN);
myIdValidator = new SMESHGUI_IdValidator(this);
// Controls for elements selection
TextLabelElements = new QLabel(tr("SMESH_ID_ELEMENTS"), GroupArguments);
// SelectElementsButton = new QPushButton(GroupArguments);
// SelectElementsButton->setIcon(image1);
LineEditElements = new QLineEdit(GroupArguments);
LineEditElements->setValidator(myIdValidator);
LineEditElements->setMaxLength(-1);
myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters()));
// Control for the whole mesh selection
CheckBoxMesh = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments);
// offset
QLabel* TextLabel1 = new QLabel(tr("OFFSET_VALUE"), GroupArguments);
SpinBox = new SMESHGUI_SpinBox(GroupArguments);
// switch of action type
ActionBox = new QGroupBox(GroupArguments);
ActionGroup = new QButtonGroup(GroupArguments);
QVBoxLayout* ActionBoxLayout = new QVBoxLayout(ActionBox);
ActionBoxLayout->addSpacing(SPACING);
ActionBoxLayout->setMargin(MARGIN);
QRadioButton* aMoveElements = new QRadioButton(tr("SMESH_MOVE_ELEMENTS"), ActionBox);
QRadioButton* aCopyElements = new QRadioButton(tr("SMESH_COPY_ELEMENTS"), ActionBox);
QRadioButton* aCreateMesh = new QRadioButton(tr("SMESH_CREATE_MESH"), ActionBox);
ActionBoxLayout->addWidget(aMoveElements);
ActionBoxLayout->addWidget(aCopyElements);
ActionBoxLayout->addWidget(aCreateMesh);
ActionGroup->addButton(aMoveElements, MOVE_ELEMS_BUTTON);
ActionGroup->addButton(aCopyElements, COPY_ELEMS_BUTTON);
ActionGroup->addButton(aCreateMesh, MAKE_MESH_BUTTON);
// CheckBox for groups generation
MakeGroupsCheck = new QCheckBox(tr("SMESH_MAKE_GROUPS"), GroupArguments);
MakeGroupsCheck->setChecked(false);
// Name of a mesh to create
LineEditNewMesh = new QLineEdit(GroupArguments);
//Preview check box
myPreviewCheckBox = new QCheckBox(tr("PREVIEW"), GroupArguments);
// layout
GroupArgumentsLayout->addWidget(TextLabelElements, 0, 0);
//GroupArgumentsLayout->addWidget(SelectElementsButton, 0, 1);
GroupArgumentsLayout->addWidget(LineEditElements, 0, 2, 1, 5);
GroupArgumentsLayout->addWidget(myFilterBtn, 0, 7);
GroupArgumentsLayout->addWidget(CheckBoxMesh, 1, 0, 1, 8);
GroupArgumentsLayout->addWidget(TextLabel1, 2, 0);
GroupArgumentsLayout->addWidget(SpinBox, 2, 3);
GroupArgumentsLayout->addWidget(ActionBox, 3, 0, 3, 4);
GroupArgumentsLayout->addWidget(MakeGroupsCheck, 4, 5, 1, 4);
GroupArgumentsLayout->addWidget(LineEditNewMesh, 5, 5, 1, 4);
GroupArgumentsLayout->addWidget(myPreviewCheckBox, 6, 0);
/***************************************************************/
GroupButtons = new QGroupBox(this);
QHBoxLayout* GroupButtonsLayout = new QHBoxLayout(GroupButtons);
GroupButtonsLayout->setSpacing(SPACING);
GroupButtonsLayout->setMargin(MARGIN);
buttonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), GroupButtons);
buttonOk->setAutoDefault(true);
buttonOk->setDefault(true);
buttonApply = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons);
buttonApply->setAutoDefault(true);
buttonCancel = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons);
buttonCancel->setAutoDefault(true);
buttonHelp = new QPushButton(tr("SMESH_BUT_HELP"), GroupButtons);
buttonHelp->setAutoDefault(true);
GroupButtonsLayout->addWidget(buttonOk);
GroupButtonsLayout->addSpacing(10);
GroupButtonsLayout->addWidget(buttonApply);
GroupButtonsLayout->addSpacing(10);
GroupButtonsLayout->addStretch();
GroupButtonsLayout->addWidget(buttonCancel);
GroupButtonsLayout->addWidget(buttonHelp);
/***************************************************************/
dlgLayout->addWidget(ConstructorsBox);
dlgLayout->addWidget(GroupArguments);
dlgLayout->addWidget(GroupButtons);
/* Initialisations */
SpinBox->RangeStepAndValidator(COORD_MIN, COORD_MAX, 1.0, "length_precision");
RadioButton1->setChecked(true);
mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
mySMESHGUI->SetActiveDialogBox((QDialog*)this);
// Costruction of the logical filter
SMESH_TypeFilter* aMeshOrSubMeshFilter = new SMESH_TypeFilter (SMESH::MESHorSUBMESH);
SMESH_TypeFilter* aSmeshGroupFilter = new SMESH_TypeFilter (SMESH::GROUP);
QList<SUIT_SelectionFilter*> aListOfFilters;
if (aMeshOrSubMeshFilter) aListOfFilters.append(aMeshOrSubMeshFilter);
if (aSmeshGroupFilter) aListOfFilters.append(aSmeshGroupFilter);
myMeshOrSubMeshOrGroupFilter =
new SMESH_LogicalFilter(aListOfFilters, SMESH_LogicalFilter::LO_OR);
myHelpFileName = "Offset_page.html";
Init();
/* signals and slots connections */
connect(buttonOk, SIGNAL(clicked()), this, SLOT(ClickOnOk()));
connect(buttonCancel, SIGNAL(clicked()), this, SLOT(reject()));
connect(buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply()));
connect(buttonHelp, SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
//connect(SelectElementsButton, SIGNAL (clicked()), this, SLOT(SetEditCurrentArgument()));
connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
/* to close dialog if study change */
connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(reject()));
connect(mySMESHGUI, SIGNAL(SignalActivatedViewManager()), this, SLOT(onOpenView()));
connect(mySMESHGUI, SIGNAL(SignalCloseView()), this, SLOT(onCloseView()));
connect(LineEditElements, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
connect(CheckBoxMesh, SIGNAL(toggled(bool)), SLOT(onSelectMesh(bool)));
connect(ActionGroup, SIGNAL(buttonClicked(int)), SLOT(onActionClicked(int)));
connect(SpinBox, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
//To Connect preview check box
connectPreviewControl();
SelectionIntoArgument();
onActionClicked(MOVE_ELEMS_BUTTON);
}
//=================================================================================
// function : ~SMESHGUI_OffsetDlg()
// purpose : Destroys the object and frees any allocated resources
//=================================================================================
SMESHGUI_OffsetDlg::~SMESHGUI_OffsetDlg()
{
if ( myFilterDlg ) {
myFilterDlg->setParent( 0 );
delete myFilterDlg;
myFilterDlg = 0;
}
}
//=================================================================================
// function : Init()
// purpose :
//=================================================================================
void SMESHGUI_OffsetDlg::Init (bool ResetControls)
{
myBusy = false;
myObjects.clear();
myObjectsNames.clear();
myMeshes.clear();
LineEditElements->clear();
myElementsId = "";
myNbOkElements = 0;
buttonOk->setEnabled(false);
buttonApply->setEnabled(false);
myActor = 0;
if (ResetControls)
{
SpinBox->SetValue(1.0);
myPreviewCheckBox->setChecked(false);
onDisplaySimulation(false);
ActionGroup->button( MOVE_ELEMS_BUTTON )->setChecked(true);
CheckBoxMesh->setChecked(true);
onSelectMesh(true);
}
}
//=================================================================================
// function : ClickOnApply()
// purpose :
//=================================================================================
bool SMESHGUI_OffsetDlg::ClickOnApply()
{
if (mySMESHGUI->isActiveStudyLocked())
return false;
if( !isValid() )
return false;
SUIT_OverrideCursor aWaitCursor;
if (myNbOkElements)
{
QStringList aListElementsId = myElementsId.split(" ", QString::SkipEmptyParts);
SMESH::long_array_var anElementsId = new SMESH::long_array;
anElementsId->length(aListElementsId.count());
for (int i = 0; i < aListElementsId.count(); i++)
anElementsId[i] = aListElementsId[i].toInt();
double offsetValue = SpinBox->value();
QStringList aParameters;
aParameters << SpinBox->text();
int actionButton = ActionGroup->checkedId();
bool makeGroups = ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() );
SMESH::ListOfGroups_var groups;
SMESH::SMESH_Mesh_var mesh;
QStringList anEntryList;
try
{
switch ( actionButton ) {
case MOVE_ELEMS_BUTTON:
if ( CheckBoxMesh->isChecked() )
for ( int i = 0; i < myObjects.count(); i++ ) {
SMESH::SMESH_MeshEditor_var aMeshEditor = myMeshes[i]->GetMeshEditor();
myMeshes[i]->SetParameters( aParameters.join( ":" ).toLatin1().constData() );
mesh = aMeshEditor->Offset( myObjects[i], offsetValue, true, "", groups.out() );
}
else {
SMESH::SMESH_MeshEditor_var aMeshEditor = myMeshes[0]->GetMeshEditor();
SMESH::IDSource_wrap src = aMeshEditor->MakeIDSource(anElementsId, SMESH::FACE);
myMeshes[0]->SetParameters( aParameters.join( ":" ).toLatin1().constData() );
mesh = aMeshEditor->Offset( src, offsetValue, true, "", groups.out() );
}
break;
case COPY_ELEMS_BUTTON:
if ( CheckBoxMesh->isChecked() )
for ( int i = 0; i < myObjects.count(); i++ ) {
SMESH::SMESH_MeshEditor_var aMeshEditor = myMeshes[i]->GetMeshEditor();
myMeshes[i]->SetParameters(aParameters.join( ":" ).toLatin1().constData());
mesh = aMeshEditor->Offset( myObjects[i], offsetValue, makeGroups, "", groups.out() );
}
else {
SMESH::SMESH_MeshEditor_var aMeshEditor = myMeshes[0]->GetMeshEditor();
SMESH::IDSource_wrap src = aMeshEditor->MakeIDSource(anElementsId, SMESH::FACE );
myMeshes[0]->SetParameters(aParameters.join( ":" ).toLatin1().constData());
mesh = aMeshEditor->Offset( src, offsetValue, makeGroups, "", groups.out() );
}
break;
case MAKE_MESH_BUTTON: {
SMESH::SMESH_Mesh_var mesh;
if ( CheckBoxMesh->isChecked() ) {
for ( int i = 0; i < myObjects.count(); i++ ) {
QString aName =
SMESH::UniqueMeshName( LineEditNewMesh->text().replace( "*", myObjectsNames[i] ));
SMESH::SMESH_MeshEditor_var aMeshEditor = myMeshes[i]->GetMeshEditor();
myMeshes[i]->SetParameters(aParameters.join( ":" ).toLatin1().constData());
mesh = aMeshEditor->Offset( myObjects[i], offsetValue, makeGroups,
aName.toLatin1().data(), groups.out() );
if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( mesh ))
anEntryList.append( aSObject->GetID().c_str() );
}
}
else {
SMESH::SMESH_MeshEditor_var aMeshEditor = myMeshes[0]->GetMeshEditor();
myMeshes[0]->SetParameters(aParameters.join( ":" ).toLatin1().constData());
SMESH::IDSource_wrap src = aMeshEditor->MakeIDSource(anElementsId, SMESH::FACE );
mesh = aMeshEditor->Offset( src, offsetValue, makeGroups,
LineEditNewMesh->text().toLatin1().data(), groups.out() );
if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( mesh ) )
anEntryList.append( aSObject->GetID().c_str() );
}
break;
}
}
}
catch ( const SALOME::SALOME_Exception& S_ex ) {
SalomeApp_Tools::QtCatchCorbaException( S_ex );
}
catch (...) {
}
for ( int i = 0; i < myObjects.count(); i++ ) {
SMESH_Actor* actor = SMESH::FindActorByObject( myObjects[i] );
if ( actor ) SMESH::Update( actor->getIO(), true );
}
if ( makeGroups || actionButton == MAKE_MESH_BUTTON )
{
mySMESHGUI->updateObjBrowser(true); // new groups may appear
if( LightApp_Application* anApp =
dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
anApp->browseObjects( anEntryList, isApplyAndClose() );
}
if ( !isApplyAndClose() )
{
Init(false);
SelectionIntoArgument();
}
SMESHGUI::Modified();
}
return true;
}
//=================================================================================
// function : ClickOnOk()
// purpose :
//=================================================================================
void SMESHGUI_OffsetDlg::ClickOnOk()
{
setIsApplyAndClose( true );
if( ClickOnApply() )
reject();
}
//=================================================================================
// function : reject()
// purpose :
//=================================================================================
void SMESHGUI_OffsetDlg::reject()
{
disconnect(mySelectionMgr, 0, this, 0);
mySelectionMgr->clearFilters();
if (SMESH::GetCurrentVtkView()) {
SMESH::RemoveFilters(); // PAL6938 -- clean all mesh entity filters
SMESH::SetPointRepresentation(false);
}
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
aViewWindow->SetSelectionMode( ActorSelection );
mySMESHGUI->ResetState();
QDialog::reject();
}
//=================================================================================
// function : onOpenView()
// purpose :
//=================================================================================
void SMESHGUI_OffsetDlg::onOpenView()
{
if ( mySelector ) {
SMESH::SetPointRepresentation(false);
}
else {
mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
ActivateThisDialog();
}
}
//=================================================================================
// function : onCloseView()
// purpose :
//=================================================================================
void SMESHGUI_OffsetDlg::onCloseView()
{
DeactivateActiveDialog();
mySelector = 0;
}
//=================================================================================
// function : ClickOnHelp()
// purpose :
//=================================================================================
void SMESHGUI_OffsetDlg::ClickOnHelp()
{
LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
if (app)
app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
else {
QString platform;
#ifdef WIN32
platform = "winapplication";
#else
platform = "application";
#endif
SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
arg(app->resourceMgr()->stringValue("ExternalBrowser",
platform)).
arg(myHelpFileName));
}
}
//=======================================================================
// function : onTextChange()
// purpose :
//=======================================================================
void SMESHGUI_OffsetDlg::onTextChange (const QString& theNewText)
{
if (myBusy) return;
BusyLocker lock( myBusy );
myNbOkElements = 0;
buttonOk->setEnabled(false);
buttonApply->setEnabled(false);
// hilight entered elements
SMDS_Mesh* aMesh = 0;
if (myActor)
aMesh = myActor->GetObject()->GetMesh();
if (aMesh) {
Handle(SALOME_InteractiveObject) anIO = myActor->getIO();
TColStd_MapOfInteger newIndices;
QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
for (int i = 0; i < aListId.count(); i++)
{
if ( const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt()))
newIndices.Add( e->GetID() );
myNbOkElements++;
}
mySelector->AddOrRemoveIndex( anIO, newIndices, false );
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
aViewWindow->highlight( anIO, true, true );
myElementsId = theNewText;
}
if (myNbOkElements) {
buttonOk->setEnabled(true);
buttonApply->setEnabled(true);
}
}
//=================================================================================
// function : SelectionIntoArgument()
// purpose : Called when selection as changed or other case
//=================================================================================
void SMESHGUI_OffsetDlg::SelectionIntoArgument()
{
if (myBusy) return;
if (myFilterDlg && myFilterDlg->isVisible()) return; // filter dlg active
BusyLocker lock( myBusy );
// clear
myActor = 0;
QString aString = "";
onDisplaySimulation(false);
LineEditElements->setText(aString);
myNbOkElements = 0;
buttonOk->setEnabled(false);
buttonApply->setEnabled(false);
if (!GroupButtons->isEnabled()) // inactive
return;
// get selected mesh
SALOME_ListIO aList;
mySelectionMgr->selectedObjects(aList);
int nbSel = aList.Extent();
if (nbSel < 1)
return;
myElementsId = "";
myObjects.clear();
myObjectsNames.clear();
myMeshes.clear();
for ( SALOME_ListIteratorOfListIO it( aList ); it.More(); it.Next() )
{
Handle(SALOME_InteractiveObject) IO = it.Value();
SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO( IO );
if ( aMesh->_is_nil() || aMesh->NbFaces() == 0 )
return;
myActor = SMESH::FindActorByObject( aMesh );
if ( !myActor )
myActor = SMESH::FindActorByEntry( IO->getEntry() );
SMESH::SMESH_IDSource_var idSrc = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
if ( _PTR(SObject) obj = SMESH::FindSObject( idSrc ))
{
std::string name = obj->GetName();
if ( !name.empty() )
{
myObjects << idSrc;
myObjectsNames << name.c_str();
myMeshes << aMesh;
}
}
}
// MakeGroups is available if there are groups and "Copy"
int aNbGroups = 0;
for ( int i = 0; i < myMeshes.count(); i++ )
aNbGroups += myMeshes[i]->NbGroups();
if ( aNbGroups == 0 ) {
MakeGroupsCheck->setChecked(false);
MakeGroupsCheck->setEnabled(false);
}
else if ( ActionGroup->checkedId() != MOVE_ELEMS_BUTTON ) {
MakeGroupsCheck->setEnabled(true);
}
if (CheckBoxMesh->isChecked()) {
if (myMeshes.isEmpty())
return;
SMESH::GetNameOfSelectedIObjects( mySelectionMgr, aString );
}
else {
int aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, aList.First(), aString);
myElementsId = aString;
if (aNbUnits < 1)
return;
}
myNbOkElements = true;
LineEditElements->setText(aString);
LineEditElements->repaint();
LineEditElements->setEnabled(false); // to fully update lineedit IPAL 19809
LineEditElements->setEnabled(true);
setNewMeshName();
buttonOk->setEnabled(true);
buttonApply->setEnabled(true);
onDisplaySimulation(true);
}
//=================================================================================
// function : DeactivateActiveDialog()
// purpose :
//=================================================================================
void SMESHGUI_OffsetDlg::DeactivateActiveDialog()
{
if (ConstructorsBox->isEnabled())
{
ConstructorsBox->setEnabled(false);
GroupArguments->setEnabled(false);
GroupButtons->setEnabled(false);
mySMESHGUI->ResetState();
mySMESHGUI->SetActiveDialogBox(0);
}
}
//=================================================================================
// function : ActivateThisDialog()
// purpose :
//=================================================================================
void SMESHGUI_OffsetDlg::ActivateThisDialog()
{
/* Emit a signal to deactivate the active dialog */
mySMESHGUI->EmitSignalDeactivateDialog();
ConstructorsBox->setEnabled(true);
GroupArguments->setEnabled(true);
GroupButtons->setEnabled(true);
mySMESHGUI->SetActiveDialogBox((QDialog*)this);
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
aViewWindow->SetSelectionMode( CellSelection );
SelectionIntoArgument();
}
//=================================================================================
// function : enterEvent()
// purpose :
//=================================================================================
void SMESHGUI_OffsetDlg::enterEvent (QEvent*)
{
if (!ConstructorsBox->isEnabled()) {
SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
if ( aViewWindow && !mySelector) {
mySelector = aViewWindow->GetSelector();
}
ActivateThisDialog();
}
}
//=======================================================================
//function : onSelectMesh
//purpose :
//=======================================================================
void SMESHGUI_OffsetDlg::onSelectMesh (bool toSelectMesh)
{
if (toSelectMesh)
TextLabelElements->setText(tr("SMESH_NAME"));
else
TextLabelElements->setText(tr("SMESH_ID_ELEMENTS"));
myFilterBtn->setEnabled(!toSelectMesh);
mySelectionMgr->clearFilters();
SMESH::SetPointRepresentation(false);
if (toSelectMesh)
{
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
aViewWindow->SetSelectionMode( ActorSelection );
mySelectionMgr->installFilter( myMeshOrSubMeshOrGroupFilter );
LineEditElements->setReadOnly( true );
LineEditElements->setValidator( 0 );
}
else
{
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
aViewWindow->SetSelectionMode( FaceSelection );
LineEditElements->setReadOnly( false );
LineEditElements->setValidator( myIdValidator );
onTextChange(LineEditElements->text());
hidePreview();
}
SelectionIntoArgument();
}
//=======================================================================
//function : onActionClicked
//purpose : slot called when an action type changed
//=======================================================================
void SMESHGUI_OffsetDlg::onActionClicked(int button)
{
int aNbGroups = 0;
for ( int i = 0; i < myMeshes.count(); i++ )
aNbGroups += myMeshes[i]->NbGroups();
switch ( button ) {
case MOVE_ELEMS_BUTTON:
MakeGroupsCheck->setEnabled(false);
LineEditNewMesh->setEnabled(false);
break;
case COPY_ELEMS_BUTTON:
LineEditNewMesh->setEnabled(false);
MakeGroupsCheck->setText( tr("SMESH_MAKE_GROUPS"));
MakeGroupsCheck->setEnabled( myMeshes.isEmpty() || aNbGroups > 0 );
break;
case MAKE_MESH_BUTTON:
LineEditNewMesh->setEnabled(true);
MakeGroupsCheck->setText( tr("SMESH_COPY_GROUPS"));
MakeGroupsCheck->setEnabled( myMeshes.isEmpty() || aNbGroups > 0 );
break;
}
setNewMeshName();
//toDisplaySimulation();
}
//=======================================================================
//function : setNewMeshName
//purpose : update contents of LineEditNewMesh
//=======================================================================
void SMESHGUI_OffsetDlg::setNewMeshName()
{
LineEditNewMesh->setText("");
if ( LineEditNewMesh->isEnabled() && !myMeshes.isEmpty() ) {
QString name;
if ( CheckBoxMesh->isChecked() ) {
name = myObjects.count() > 1 ? "*" : LineEditElements->text();
}
else {
_PTR(SObject) meshSO = SMESH::FindSObject( myMeshes[0] );
name = meshSO->GetName().c_str();
}
if ( !name.isEmpty() )
LineEditNewMesh->setText( SMESH::UniqueMeshName( name, "Offset"));
}
}
//=================================================================================
// function : keyPressEvent()
// purpose :
//=================================================================================
void SMESHGUI_OffsetDlg::keyPressEvent( QKeyEvent* e )
{
QDialog::keyPressEvent( e );
if ( e->isAccepted() )
return;
if ( e->key() == Qt::Key_F1 ) {
e->accept();
ClickOnHelp();
}
}
//=================================================================================
// function : setFilters()
// purpose : SLOT. Called when "Filter" button pressed.
//=================================================================================
void SMESHGUI_OffsetDlg::setFilters()
{
if ( myMeshes.isEmpty() ) {
SUIT_MessageBox::critical(this, tr("SMESH_ERROR"), tr("NO_MESH_SELECTED"));
return;
}
if ( !myFilterDlg ) {
myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::ALL );
connect(myFilterDlg, SIGNAL(Accepted()), SLOT(onFilterAccepted()));
}
myFilterDlg->Init( SMESH::FACE );
myFilterDlg->SetSelection();
myFilterDlg->SetMesh( myMeshes[0] );
myFilterDlg->SetSourceWg( LineEditElements );
myFilterDlg->show();
}
//=======================================================================
// name : onFilterAccepted()
// Purpose : SLOT. Called when Filter dlg closed with OK button.
// Activate [Apply] if no Actor is available
//=======================================================================
void SMESHGUI_OffsetDlg::onFilterAccepted()
{
if ( myMeshes.length() > 0 && !buttonOk->isEnabled() )
{
myElementsId = LineEditElements->text();
QStringList aListElementsId = myElementsId.split(" ", QString::SkipEmptyParts);
myNbOkElements = aListElementsId.count();
buttonOk->setEnabled ( myNbOkElements );
buttonApply->setEnabled( myNbOkElements );
}
}
//=================================================================================
// function : isValid
// purpose :
//=================================================================================
bool SMESHGUI_OffsetDlg::isValid()
{
return true;
}
//=================================================================================
// function : onDisplaySimulation
// purpose : Show/Hide preview
//=================================================================================
void SMESHGUI_OffsetDlg::onDisplaySimulation( bool toDisplayPreview )
{
SUIT_OverrideCursor aWaitCursor;
if (myPreviewCheckBox->isChecked() && toDisplayPreview)
{
if ( myNbOkElements && isValid() )
{
double offsetValue = SpinBox->value();
SMESH::ListOfGroups_var groups;
SMESH::SMESH_Mesh_var mesh;
try
{
QList<SMESH::MeshPreviewStruct_var> aMeshPreviewStruct;
if ( CheckBoxMesh->isChecked())
for ( int i = 0; i < myObjects.count(); i++ )
{
SMESH::SMESH_MeshEditor_var aMeshEditor = myMeshes[i]->GetMeshEditPreviewer();
mesh = aMeshEditor->Offset( myObjects[i], offsetValue, false, "", groups.out() );
aMeshPreviewStruct << aMeshEditor->GetPreviewData();
}
else
{
SMESH::long_array_var anElementsId = new SMESH::long_array;
QStringList aListElementsId = myElementsId.split(" ", QString::SkipEmptyParts);
anElementsId->length(aListElementsId.count());
for (int i = 0; i < aListElementsId.count(); i++)
anElementsId[i] = aListElementsId[i].toInt();
SMESH::SMESH_MeshEditor_var aMeshEditor = myMeshes[0]->GetMeshEditPreviewer();
SMESH::IDSource_wrap src = aMeshEditor->MakeIDSource(anElementsId, SMESH::FACE);
mesh = aMeshEditor->Offset( src, offsetValue, false, "", groups.out() );
aMeshPreviewStruct << aMeshEditor->GetPreviewData();
}
setSimulationPreview(aMeshPreviewStruct);
} catch (...) {
hidePreview();
}
} else {
hidePreview();
}
} else {
hidePreview();
}
}

View File

@ -166,6 +166,7 @@ namespace SMESHOp {
OpMergeNodes = 4405, // MENU MODIFICATION - TRANSFORMATION - MERGE NODES
OpMergeElements = 4406, // MENU MODIFICATION - TRANSFORMATION - MERGE ELEMENTS
OpDuplicateNodes = 4407, // MENU MODIFICATION - TRANSFORMATION - DUPLICATE NODES OR/AND ELEMENTS
OpOffset = 4408, // MENU MODIFICATION - TRANSFORMATION - OFFSET
OpMoveNode = 4500, // MENU MODIFICATION - MOVE NODE
OpDiagonalInversion = 4501, // MENU MODIFICATION - DIAGONAL INVERSION
OpUnionOfTwoTriangle = 4502, // MENU MODIFICATION - UNION OF TWO TRIANGLE

View File

@ -345,7 +345,7 @@ void SMESHGUI_RemoveElementsDlg::onTextChange(const QString& theNewText)
myNbOkElements = 0;
// hilight entered elements
// highlight entered elements
if(myActor){
if(SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh()){
Handle(SALOME_InteractiveObject) anIO = myActor->getIO();

View File

@ -351,7 +351,7 @@ void SMESHGUI_RemoveNodesDlg::onTextChange(const QString& theNewText)
myNbOkNodes = 0;
// hilight entered nodes
// highlight entered nodes
if(myActor){
if(SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh()){
Handle(SALOME_InteractiveObject) anIO = myActor->getIO();

View File

@ -635,7 +635,7 @@ void SMESHGUI_RotationDlg::onTextChange (const QString& theNewText)
buttonOk->setEnabled(false);
buttonApply->setEnabled(false);
// hilight entered elements
// highlight entered elements
SMDS_Mesh* aMesh = 0;
if (myActor)
aMesh = myActor->GetObject()->GetMesh();

View File

@ -674,7 +674,7 @@ void SMESHGUI_ScaleDlg::onTextChange (const QString& theNewText)
buttonOk->setEnabled(false);
buttonApply->setEnabled(false);
// hilight entered elements
// highlight entered elements
SMDS_Mesh* aMesh = 0;
if (myActor)
aMesh = myActor->GetObject()->GetMesh();

View File

@ -250,11 +250,11 @@ void SMESHGUI_SelectionOp::setSelectionMode( const Selection_Mode mode )
// Purpose : Highlight object in 3d viewer
//=======================================================================
void SMESHGUI_SelectionOp::highlight( const Handle( SALOME_InteractiveObject )& obj,
const bool hilight, const bool immediately )
const bool highlight, const bool immediately )
{
SVTK_ViewWindow* wnd = viewWindow();
if( wnd )
wnd->highlight( obj, hilight, immediately );
wnd->highlight( obj, highlight, immediately );
}
//=======================================================================

View File

@ -104,7 +104,7 @@ protected:
//! Set selection mode in VTK viewer
void setSelectionMode( const Selection_Mode );
//! Hilight object in VTK viewer
//! Highlight object in VTK viewer
void highlight( const Handle( SALOME_InteractiveObject )&,
const bool, const bool = true );

View File

@ -1532,7 +1532,7 @@ void SMESHGUI_SewingDlg::onTextChange (const QString& theNewText)
else if (send == LineEdit6)
myOk6 = false;
// hilight entered elements/nodes
// highlight entered elements/nodes
SMDS_Mesh* aMesh = 0;
if (myActor)

View File

@ -341,7 +341,7 @@ void SMESHGUI_SingleEditDlg::onTextChange (const QString& theNewText)
myOkBtn->setEnabled(false);
myApplyBtn->setEnabled(false);
// hilight entered edge
// highlight entered edge
if(myActor){
if(SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh()){
Handle(SALOME_InteractiveObject) anIO = myActor->getIO();

View File

@ -518,7 +518,7 @@ void SMESHGUI_SmoothingDlg::onTextChange (const QString& theNewText)
buttonOk->setEnabled(false);
buttonApply->setEnabled(false);
// hilight entered elements/nodes
// highlight entered elements/nodes
SMDS_Mesh* aMesh = myActor ? myActor->GetObject()->GetMesh() : 0;
QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);

View File

@ -693,7 +693,7 @@ void SMESHGUI_SymmetryDlg::onTextChange (const QString& theNewText)
buttonOk->setEnabled(false);
buttonApply->setEnabled(false);
// hilight entered elements
// highlight entered elements
SMDS_Mesh* aMesh = 0;
if (myActor)
aMesh = myActor->GetObject()->GetMesh();

View File

@ -705,7 +705,7 @@ void SMESHGUI_TranslationDlg::onTextChange (const QString& theNewText)
buttonOk->setEnabled(false);
buttonApply->setEnabled(false);
// hilight entered elements
// highlight entered elements
SMDS_Mesh* aMesh = 0;
if (myActor)
aMesh = myActor->GetObject()->GetMesh();

View File

@ -455,6 +455,10 @@
<source>ICON_DLG_MESH_SCALE</source>
<translation>scale.png</translation>
</message>
<message>
<source>ICON_DLG_MESH_OFFSET</source>
<translation>mesh_offset.png</translation>
</message>
<message>
<source>ICON_DLG_SCALE_ALONG_AXES</source>
<translation>scale_along_axes.png</translation>

View File

@ -1092,6 +1092,10 @@
<source>MEN_SCALE</source>
<translation>Scale Transform</translation>
</message>
<message>
<source>MEN_OFFSET</source>
<translation>Offset</translation>
</message>
<message>
<source>MEN_DUPLICATE_NODES</source>
<translation>Duplicate Nodes or/and Elements</translation>
@ -1926,7 +1930,7 @@ add the exported data to its contents?</translation>
<translation>Hexahedrons</translation>
</message>
<message>
<source>SMESH_HILIGHT_COLOR</source>
<source>SMESH_HIGHLIGHT_COLOR</source>
<translation>Highlight Color</translation>
</message>
<message>
@ -3554,6 +3558,10 @@ Use Display Entity menu command to show them.
<source>STB_SCALE</source>
<translation>Scale Transform</translation>
</message>
<message>
<source>STB_OFFSET</source>
<translation>Offset</translation>
</message>
<message>
<source>STB_DUPLICATE_NODES</source>
<translation>Duplicate Nodes or/and Elements</translation>
@ -4234,6 +4242,10 @@ Use Display Entity menu command to show them.
<source>TOP_SCALE</source>
<translation>Scale Transform</translation>
</message>
<message>
<source>TOP_OFFSET</source>
<translation>Offset</translation>
</message>
<message>
<source>TOP_DUPLICATE_NODES</source>
<translation>Duplicate Nodes or/and Elements</translation>
@ -4509,6 +4521,21 @@ It can&apos;t be deleted </translation>
<translation>Export Fields</translation>
</message>
</context>
<context>
<name>SMESHGUI_OffsetDlg</name>
<message>
<source>SMESH_OFFSET_TITLE</source>
<translation>Offset</translation>
</message>
<message>
<source>SMESH_OFFSET</source>
<translation>Offset</translation>
</message>
<message>
<source>OFFSET_VALUE</source>
<translation>Offset Value</translation>
</message>
</context>
<context>
<name>SMESHGUI_AddMeshElementDlg</name>
<message>

View File

@ -1910,7 +1910,7 @@ les données exportées ?</translation>
<translation>Hexaèdres</translation>
</message>
<message>
<source>SMESH_HILIGHT_COLOR</source>
<source>SMESH_HIGHLIGHT_COLOR</source>
<translation>Couleur de sélection</translation>
</message>
<message>

View File

@ -1880,7 +1880,7 @@
<translation></translation>
</message>
<message>
<source>SMESH_HILIGHT_COLOR</source>
<source>SMESH_HIGHLIGHT_COLOR</source>
<translation></translation>
</message>
<message>

View File

@ -87,6 +87,8 @@ SET(SMESHUtils_SOURCES
SMESH_DeMerge.cxx
SMESH_Delaunay.cxx
SMESH_FillHole.cxx
SMESH_Triangulate.cxx
SMESH_Offset.cxx
)
# --- rules ---

View File

@ -56,7 +56,7 @@ namespace SMESH_MAT2d
//-------------------------------------------------------------------------------------
// type of Branch end point
enum BranchEndType { BE_UNDEF,
BE_ON_VERTEX, // branch ends at a convex VRTEX
BE_ON_VERTEX, // branch ends at a convex VERTEX
BE_BRANCH_POINT, // branch meats 2 or more other branches
BE_END // branch end equidistant from several adjacent segments
};

View File

@ -48,7 +48,7 @@
#include <limits>
#include <numeric>
using namespace std;
#include <boost/container/flat_set.hpp>
//=======================================================================
/*!
@ -110,21 +110,21 @@ struct SMESH_NodeSearcherImpl: public SMESH_NodeSearcher
*/
const SMDS_MeshNode* FindClosestTo( const gp_Pnt& thePnt )
{
map<double, const SMDS_MeshNode*> dist2Nodes;
std::map<double, const SMDS_MeshNode*> dist2Nodes;
myOctreeNode->NodesAround( thePnt.Coord(), dist2Nodes, myHalfLeafSize );
if ( !dist2Nodes.empty() )
return dist2Nodes.begin()->second;
list<const SMDS_MeshNode*> nodes;
std::list<const SMDS_MeshNode*> nodes;
//myOctreeNode->NodesAround( &tgtNode, &nodes, myHalfLeafSize );
double minSqDist = DBL_MAX;
if ( nodes.empty() ) // get all nodes of OctreeNode's closest to thePnt
{
// sort leafs by their distance from thePnt
typedef map< double, SMESH_OctreeNode* > TDistTreeMap;
typedef std::map< double, SMESH_OctreeNode* > TDistTreeMap;
TDistTreeMap treeMap;
list< SMESH_OctreeNode* > treeList;
list< SMESH_OctreeNode* >::iterator trIt;
std::list< SMESH_OctreeNode* > treeList;
std::list< SMESH_OctreeNode* >::iterator trIt;
treeList.push_back( myOctreeNode );
gp_XYZ pointNode( thePnt.X(), thePnt.Y(), thePnt.Z() );
@ -143,9 +143,10 @@ struct SMESH_NodeSearcherImpl: public SMESH_NodeSearcher
{
const Bnd_B3d& box = *tree->getBox();
double sqDist = thePnt.SquareDistance( 0.5 * ( box.CornerMin() + box.CornerMax() ));
pair<TDistTreeMap::iterator,bool> it_in = treeMap.insert( make_pair( sqDist, tree ));
std::pair<TDistTreeMap::iterator,bool> it_in =
treeMap.insert( std::make_pair( sqDist, tree ));
if ( !it_in.second ) // not unique distance to box center
treeMap.insert( it_in.first, make_pair( sqDist + 1e-13*treeMap.size(), tree ));
treeMap.insert( it_in.first, std::make_pair( sqDist + 1e-13*treeMap.size(), tree ));
}
}
// find distance after which there is no sense to check tree's
@ -168,7 +169,7 @@ struct SMESH_NodeSearcherImpl: public SMESH_NodeSearcher
// find closest among nodes
minSqDist = DBL_MAX;
const SMDS_MeshNode* closestNode = 0;
list<const SMDS_MeshNode*>::iterator nIt = nodes.begin();
std::list<const SMDS_MeshNode*>::iterator nIt = nodes.begin();
for ( ; nIt != nodes.end(); ++nIt ) {
double sqDist = thePnt.SquareDistance( SMESH_TNodeXYZ( *nIt ) );
if ( minSqDist > sqDist ) {
@ -226,15 +227,16 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
{
public:
typedef boost::container::flat_set< const SMDS_MeshElement* > TElemSeq;
ElementBndBoxTree(const SMDS_Mesh& mesh,
SMDSAbs_ElementType elemType,
SMDS_ElemIteratorPtr theElemIt = SMDS_ElemIteratorPtr(),
double tolerance = NodeRadius );
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,
const double radius,
vector<const SMDS_MeshElement*>& foundElems);
void getElementsNearPoint( const gp_Pnt& point, TElemSeq& foundElems );
void getElementsNearLine ( const gp_Ax1& line, TElemSeq& foundElems );
void getElementsInBox ( const Bnd_B3d& box, TElemSeq& foundElems );
void getElementsInSphere ( const gp_XYZ& center, const double radius, TElemSeq& foundElems );
ElementBndBoxTree* getLeafAtPoint( const gp_XYZ& point );
protected:
@ -247,10 +249,9 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
struct ElementBox : public Bnd_B3d
{
const SMDS_MeshElement* _element;
bool _isMarked;
void init(const SMDS_MeshElement* elem, double tolerance);
};
vector< ElementBox* > _elements;
std::vector< ElementBox* > _elements;
typedef ObjectPool< ElementBox > TElementBoxPool;
@ -258,7 +259,6 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
struct LimitAndPool : public SMESH_TreeLimit
{
TElementBoxPool _elBoPool;
std::vector< ElementBox* > _markedElems;
LimitAndPool():SMESH_TreeLimit( MaxLevel, /*minSize=*/0. ) {}
};
LimitAndPool* getLimitAndPool() const
@ -345,37 +345,21 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
*/
//================================================================================
void ElementBndBoxTree::getElementsNearPoint( const gp_Pnt& point,
vector<const SMDS_MeshElement*>& foundElems)
void ElementBndBoxTree::getElementsNearPoint( const gp_Pnt& point, TElemSeq& foundElems)
{
if ( getBox()->IsOut( point.XYZ() ))
return;
if ( isLeaf() )
{
LimitAndPool* pool = getLimitAndPool();
for ( size_t i = 0; i < _elements.size(); ++i )
if ( !_elements[i]->IsOut( point.XYZ() ) &&
!_elements[i]->_isMarked )
{
foundElems.push_back( _elements[i]->_element );
_elements[i]->_isMarked = true;
pool->_markedElems.push_back( _elements[i] );
}
if ( !_elements[i]->IsOut( point.XYZ() ))
foundElems.insert( _elements[i]->_element );
}
else
{
for (int i = 0; i < 8; i++)
((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();
}
}
}
@ -385,37 +369,21 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
*/
//================================================================================
void ElementBndBoxTree::getElementsNearLine( const gp_Ax1& line,
vector<const SMDS_MeshElement*>& foundElems)
void ElementBndBoxTree::getElementsNearLine( const gp_Ax1& line, TElemSeq& foundElems )
{
if ( getBox()->IsOut( line ))
return;
if ( isLeaf() )
{
LimitAndPool* pool = getLimitAndPool();
for ( size_t i = 0; i < _elements.size(); ++i )
if ( !_elements[i]->IsOut( line ) &&
!_elements[i]->_isMarked )
{
foundElems.push_back( _elements[i]->_element );
_elements[i]->_isMarked = true;
pool->_markedElems.push_back( _elements[i] );
}
if ( !_elements[i]->IsOut( line ) )
foundElems.insert( _elements[i]->_element );
}
else
{
for (int i = 0; i < 8; i++)
((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();
}
}
}
@ -425,38 +393,47 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
*/
//================================================================================
void ElementBndBoxTree::getElementsInSphere ( const gp_XYZ& center,
const double radius,
vector<const SMDS_MeshElement*>& foundElems)
void ElementBndBoxTree::getElementsInSphere ( const gp_XYZ& center,
const double radius,
TElemSeq& foundElems)
{
if ( getBox()->IsOut( center, radius ))
return;
if ( isLeaf() )
{
LimitAndPool* pool = getLimitAndPool();
for ( size_t i = 0; i < _elements.size(); ++i )
if ( !_elements[i]->IsOut( center, radius ) &&
!_elements[i]->_isMarked )
{
foundElems.push_back( _elements[i]->_element );
_elements[i]->_isMarked = true;
pool->_markedElems.push_back( _elements[i] );
}
if ( !_elements[i]->IsOut( center, radius ))
foundElems.insert( _elements[i]->_element );
}
else
{
for (int i = 0; i < 8; i++)
((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 elements from leaves intersecting the box
*/
//================================================================================
void ElementBndBoxTree::getElementsInBox( const Bnd_B3d& box, TElemSeq& foundElems )
{
if ( getBox()->IsOut( box ))
return;
if ( isLeaf() )
{
for ( size_t i = 0; i < _elements.size(); ++i )
if ( !_elements[i]->IsOut( box ))
foundElems.insert( _elements[i]->_element );
}
else
{
for (int i = 0; i < 8; i++)
((ElementBndBoxTree*) myChildren[i])->getElementsInBox( box, foundElems );
}
}
@ -493,7 +470,6 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
void ElementBndBoxTree::ElementBox::init(const SMDS_MeshElement* elem, double tolerance)
{
_element = elem;
_isMarked = false;
SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
while ( nIt->more() )
Add( SMESH_NodeXYZ( nIt->next() ));
@ -515,15 +491,15 @@ SMESH_ElementSearcher::~SMESH_ElementSearcher()
struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher
{
SMDS_Mesh* _mesh;
SMDS_ElemIteratorPtr _meshPartIt;
ElementBndBoxTree* _ebbTree [SMDSAbs_NbElementTypes];
int _ebbTreeHeight[SMDSAbs_NbElementTypes];
SMESH_NodeSearcherImpl* _nodeSearcher;
SMDSAbs_ElementType _elementType;
double _tolerance;
bool _outerFacesFound;
set<const SMDS_MeshElement*> _outerFaces; // empty means "no internal faces at all"
SMDS_Mesh* _mesh;
SMDS_ElemIteratorPtr _meshPartIt;
ElementBndBoxTree* _ebbTree [SMDSAbs_NbElementTypes];
int _ebbTreeHeight[SMDSAbs_NbElementTypes];
SMESH_NodeSearcherImpl* _nodeSearcher;
SMDSAbs_ElementType _elementType;
double _tolerance;
bool _outerFacesFound;
std::set<const SMDS_MeshElement*> _outerFaces; // empty means "no internal faces at all"
SMESH_ElementSearcherImpl( SMDS_Mesh& mesh,
double tol=-1,
@ -545,20 +521,23 @@ struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher
}
if ( _nodeSearcher ) delete _nodeSearcher; _nodeSearcher = 0;
}
virtual int FindElementsByPoint(const gp_Pnt& point,
SMDSAbs_ElementType type,
vector< const SMDS_MeshElement* >& foundElements);
virtual int FindElementsByPoint(const gp_Pnt& point,
SMDSAbs_ElementType type,
std::vector< const SMDS_MeshElement* >& foundElements);
virtual TopAbs_State GetPointState(const gp_Pnt& point);
virtual const SMDS_MeshElement* FindClosestTo( const gp_Pnt& point,
SMDSAbs_ElementType type );
virtual void GetElementsNearLine( const gp_Ax1& line,
SMDSAbs_ElementType type,
vector< const SMDS_MeshElement* >& foundElems);
virtual void GetElementsInSphere( const gp_XYZ& center,
const double radius,
SMDSAbs_ElementType type,
vector< const SMDS_MeshElement* >& foundElems);
virtual void GetElementsNearLine( const gp_Ax1& line,
SMDSAbs_ElementType type,
std::vector< const SMDS_MeshElement* >& foundElems);
virtual void GetElementsInSphere( const gp_XYZ& center,
const double radius,
SMDSAbs_ElementType type,
std::vector< const SMDS_MeshElement* >& foundElems);
virtual void GetElementsInBox( const Bnd_B3d& box,
SMDSAbs_ElementType type,
std::vector< const SMDS_MeshElement* >& foundElems);
virtual gp_XYZ Project(const gp_Pnt& point,
SMDSAbs_ElementType type,
const SMDS_MeshElement** closestElem);
@ -649,7 +628,7 @@ double SMESH_ElementSearcherImpl::getTolerance()
while ( nodeIt->more() )
{
double dist = n1.Distance( static_cast<const SMDS_MeshNode*>( nodeIt->next() ));
elemSize = max( dist, elemSize );
elemSize = std::max( dist, elemSize );
}
}
_tolerance = 1e-4 * elemSize;
@ -707,10 +686,10 @@ void SMESH_ElementSearcherImpl::findOuterBoundary(const SMDS_MeshElement* outerF
// and BTW find out if there are internal faces at all.
// checked links and links where outer boundary meets internal one
set< SMESH_TLink > visitedLinks, seamLinks;
std::set< SMESH_TLink > visitedLinks, seamLinks;
// links to treat with already visited faces sharing them
list < TFaceLink > startLinks;
std::list < TFaceLink > startLinks;
// load startLinks with the first outerFace
startLinks.push_back( TFaceLink( outerFace->GetNode(0), outerFace->GetNode(1), outerFace));
@ -752,8 +731,8 @@ void SMESH_ElementSearcherImpl::findOuterBoundary(const SMDS_MeshElement* outerF
// direction from the link inside outerFace
gp_Vec dirInOF = gp_Vec( ofNorm ) ^ n1n2;
// sort all other faces by angle with the dirInOF
map< double, const SMDS_MeshElement* > angle2Face;
set< const SMDS_MeshElement*, TIDCompare >::const_iterator face = faces.begin();
std::map< double, const SMDS_MeshElement* > angle2Face;
std::set< const SMDS_MeshElement*, TIDCompare >::const_iterator face = faces.begin();
for ( ; face != faces.end(); ++face )
{
if ( *face == outerFace ) continue;
@ -762,7 +741,7 @@ void SMESH_ElementSearcherImpl::findOuterBoundary(const SMDS_MeshElement* outerF
gp_Vec dirInF = gp_Vec( fNorm ) ^ n1n2;
double angle = dirInOF.AngleWithRef( dirInF, n1n2 );
if ( angle < 0 ) angle += 2. * M_PI;
angle2Face.insert( make_pair( angle, *face ));
angle2Face.insert( std::make_pair( angle, *face ));
}
if ( !angle2Face.empty() )
outerFace2 = angle2Face.begin()->second;
@ -807,9 +786,9 @@ void SMESH_ElementSearcherImpl::findOuterBoundary(const SMDS_MeshElement* outerF
//=======================================================================
int SMESH_ElementSearcherImpl::
FindElementsByPoint(const gp_Pnt& point,
SMDSAbs_ElementType type,
vector< const SMDS_MeshElement* >& foundElements)
FindElementsByPoint(const gp_Pnt& point,
SMDSAbs_ElementType type,
std::vector< const SMDS_MeshElement* >& foundElements)
{
foundElements.clear();
_elementType = type;
@ -850,9 +829,9 @@ FindElementsByPoint(const gp_Pnt& point,
{
_ebbTree[_elementType] = new ElementBndBoxTree( *_mesh, type, _meshPartIt, tolerance );
}
vector< const SMDS_MeshElement* > suspectElems;
ElementBndBoxTree::TElemSeq suspectElems;
_ebbTree[ type ]->getElementsNearPoint( point, suspectElems );
vector< const SMDS_MeshElement* >::iterator elem = suspectElems.begin();
ElementBndBoxTree::TElemSeq::iterator elem = suspectElems.begin();
for ( ; elem != suspectElems.end(); ++elem )
if ( !SMESH_MeshAlgos::IsOut( *elem, point, tolerance ))
foundElements.push_back( *elem );
@ -883,7 +862,7 @@ SMESH_ElementSearcherImpl::FindClosestTo( const gp_Pnt& point,
if ( !ebbTree )
ebbTree = new ElementBndBoxTree( *_mesh, type, _meshPartIt );
vector<const SMDS_MeshElement*> suspectElems;
ElementBndBoxTree::TElemSeq suspectElems;
ebbTree->getElementsNearPoint( point, suspectElems );
if ( suspectElems.empty() && ebbTree->maxSize() > 0 )
@ -902,20 +881,20 @@ SMESH_ElementSearcherImpl::FindClosestTo( const gp_Pnt& point,
}
}
double minDist = std::numeric_limits<double>::max();
multimap< double, const SMDS_MeshElement* > dist2face;
vector<const SMDS_MeshElement*>::iterator elem = suspectElems.begin();
std::multimap< double, const SMDS_MeshElement* > dist2face;
ElementBndBoxTree::TElemSeq::iterator elem = suspectElems.begin();
for ( ; elem != suspectElems.end(); ++elem )
{
double dist = SMESH_MeshAlgos::GetDistance( *elem, point );
if ( dist < minDist + 1e-10)
{
minDist = dist;
dist2face.insert( dist2face.begin(), make_pair( dist, *elem ));
dist2face.insert( dist2face.begin(), std::make_pair( dist, *elem ));
}
}
if ( !dist2face.empty() )
{
multimap< double, const SMDS_MeshElement* >::iterator d2f = dist2face.begin();
std::multimap< double, const SMDS_MeshElement* >::iterator d2f = dist2face.begin();
closestElem = d2f->second;
// if there are several elements at the same distance, select one
// with GC closest to the point
@ -974,21 +953,21 @@ TopAbs_State SMESH_ElementSearcherImpl::GetPointState(const gp_Pnt& point)
const int nbAxes = 3;
gp_Dir axisDir[ nbAxes ] = { gp::DX(), gp::DY(), gp::DZ() };
map< double, TInters > paramOnLine2TInters[ nbAxes ];
list< TInters > tangentInters[ nbAxes ]; // of faces whose plane includes the line
multimap< int, int > nbInt2Axis; // to find the simplest case
std::map< double, TInters > paramOnLine2TInters[ nbAxes ];
std::list< TInters > tangentInters[ nbAxes ]; // of faces whose plane includes the line
std::multimap< int, int > nbInt2Axis; // to find the simplest case
for ( int axis = 0; axis < nbAxes; ++axis )
{
gp_Ax1 lineAxis( point, axisDir[axis]);
gp_Lin line ( lineAxis );
vector<const SMDS_MeshElement*> suspectFaces; // faces possibly intersecting the line
ElementBndBoxTree::TElemSeq suspectFaces; // faces possibly intersecting the line
ebbTree->getElementsNearLine( lineAxis, suspectFaces );
// Intersect faces with the line
map< double, TInters > & u2inters = paramOnLine2TInters[ axis ];
vector<const SMDS_MeshElement*>::iterator face = suspectFaces.begin();
std::map< double, TInters > & u2inters = paramOnLine2TInters[ axis ];
ElementBndBoxTree::TElemSeq::iterator face = suspectFaces.begin();
for ( ; face != suspectFaces.end(); ++face )
{
// get face plane
@ -1009,7 +988,7 @@ TopAbs_State SMESH_ElementSearcherImpl::GetPointState(const gp_Pnt& point)
double tol = 1e-4 * Sqrt( fNorm.Modulus() );
gp_Pnt intersectionPoint = intersection.Point(1);
if ( !SMESH_MeshAlgos::IsOut( *face, intersectionPoint, tol ))
u2inters.insert(make_pair( intersection.ParamOnConic(1), TInters( *face, fNorm )));
u2inters.insert( std::make_pair( intersection.ParamOnConic(1), TInters( *face, fNorm )));
}
}
// Analyse intersections roughly
@ -1033,7 +1012,7 @@ TopAbs_State SMESH_ElementSearcherImpl::GetPointState(const gp_Pnt& point)
if ( nbIntBeforePoint == 1 || nbIntAfterPoint == 1 )
return TopAbs_IN;
nbInt2Axis.insert( make_pair( min( nbIntBeforePoint, nbIntAfterPoint ), axis ));
nbInt2Axis.insert( std::make_pair( std::min( nbIntBeforePoint, nbIntAfterPoint ), axis ));
if ( _outerFacesFound ) break; // pass to thorough analysis
@ -1047,29 +1026,29 @@ TopAbs_State SMESH_ElementSearcherImpl::GetPointState(const gp_Pnt& point)
for ( int hasPositionInfo = _outerFacesFound; hasPositionInfo < 2; ++hasPositionInfo )
{
multimap< int, int >::const_iterator nb_axis = nbInt2Axis.begin();
std::multimap< int, int >::const_iterator nb_axis = nbInt2Axis.begin();
for ( ; nb_axis != nbInt2Axis.end(); ++nb_axis )
{
int axis = nb_axis->second;
map< double, TInters > & u2inters = paramOnLine2TInters[ axis ];
std::map< double, TInters > & u2inters = paramOnLine2TInters[ axis ];
gp_Ax1 lineAxis( point, axisDir[axis]);
gp_Lin line ( lineAxis );
// add tangent intersections to u2inters
double param;
list< TInters >::const_iterator tgtInt = tangentInters[ axis ].begin();
std::list< TInters >::const_iterator tgtInt = tangentInters[ axis ].begin();
for ( ; tgtInt != tangentInters[ axis ].end(); ++tgtInt )
if ( getIntersParamOnLine( line, tgtInt->_face, tolerance, param ))
u2inters.insert(make_pair( param, *tgtInt ));
u2inters.insert( std::make_pair( param, *tgtInt ));
tangentInters[ axis ].clear();
// Count intersections before and after the point excluding touching ones.
// If hasPositionInfo we count intersections of outer boundary only
int nbIntBeforePoint = 0, nbIntAfterPoint = 0;
double f = numeric_limits<double>::max(), l = -numeric_limits<double>::max();
map< double, TInters >::iterator u_int1 = u2inters.begin(), u_int2 = u_int1;
double f = std::numeric_limits<double>::max(), l = -std::numeric_limits<double>::max();
std::map< double, TInters >::iterator u_int1 = u2inters.begin(), u_int2 = u_int1;
bool ok = ! u_int1->second._coincides;
while ( ok && u_int1 != u2inters.end() )
{
@ -1118,8 +1097,8 @@ TopAbs_State SMESH_ElementSearcherImpl::GetPointState(const gp_Pnt& point)
// decide if we skipped a touching intersection
if ( nbSamePnt + nbTgt > 0 )
{
double minDot = numeric_limits<double>::max(), maxDot = -numeric_limits<double>::max();
map< double, TInters >::iterator u_int = u_int1;
double minDot = std::numeric_limits<double>::max(), maxDot = -minDot;
std::map< double, TInters >::iterator u_int = u_int1;
for ( ; u_int != u_int2; ++u_int )
{
if ( u_int->second._coincides ) continue;
@ -1172,7 +1151,7 @@ TopAbs_State SMESH_ElementSearcherImpl::GetPointState(const gp_Pnt& point)
if ( !hasPositionInfo )
{
// gather info on faces position - is face in the outer boundary or not
map< double, TInters > & u2inters = paramOnLine2TInters[ 0 ];
std::map< double, TInters > & u2inters = paramOnLine2TInters[ 0 ];
findOuterBoundary( u2inters.begin()->second._face );
}
@ -1187,16 +1166,20 @@ TopAbs_State SMESH_ElementSearcherImpl::GetPointState(const gp_Pnt& point)
*/
//=======================================================================
void SMESH_ElementSearcherImpl::GetElementsNearLine( const gp_Ax1& line,
SMDSAbs_ElementType type,
vector< const SMDS_MeshElement* >& foundElems)
void SMESH_ElementSearcherImpl::
GetElementsNearLine( const gp_Ax1& line,
SMDSAbs_ElementType type,
std::vector< const SMDS_MeshElement* >& foundElems)
{
_elementType = type;
ElementBndBoxTree*& ebbTree = _ebbTree[ type ];
if ( !ebbTree )
ebbTree = new ElementBndBoxTree( *_mesh, _elementType, _meshPartIt );
ebbTree->getElementsNearLine( line, foundElems );
ElementBndBoxTree::TElemSeq elems;
ebbTree->getElementsNearLine( line, elems );
foundElems.insert( foundElems.end(), elems.begin(), elems.end() );
}
//=======================================================================
@ -1205,17 +1188,43 @@ void SMESH_ElementSearcherImpl::GetElementsNearLine( const gp_Ax1&
*/
//=======================================================================
void SMESH_ElementSearcherImpl::GetElementsInSphere( const gp_XYZ& center,
const double radius,
SMDSAbs_ElementType type,
vector< const SMDS_MeshElement* >& foundElems)
void SMESH_ElementSearcherImpl::
GetElementsInSphere( const gp_XYZ& center,
const double radius,
SMDSAbs_ElementType type,
std::vector< const SMDS_MeshElement* >& foundElems)
{
_elementType = type;
ElementBndBoxTree*& ebbTree = _ebbTree[ type ];
if ( !ebbTree )
ebbTree = new ElementBndBoxTree( *_mesh, _elementType, _meshPartIt );
ebbTree->getElementsInSphere( center, radius, foundElems );
ElementBndBoxTree::TElemSeq elems;
ebbTree->getElementsInSphere( center, radius, elems );
foundElems.insert( foundElems.end(), elems.begin(), elems.end() );
}
//=======================================================================
/*
* Return elements whose bounding box intersects a given bounding box
*/
//=======================================================================
void SMESH_ElementSearcherImpl::
GetElementsInBox( const Bnd_B3d& box,
SMDSAbs_ElementType type,
std::vector< const SMDS_MeshElement* >& foundElems)
{
_elementType = type;
ElementBndBoxTree*& ebbTree = _ebbTree[ type ];
if ( !ebbTree )
ebbTree = new ElementBndBoxTree( *_mesh, _elementType, _meshPartIt, getTolerance() );
ElementBndBoxTree::TElemSeq elems;
ebbTree->getElementsInBox( box, elems );
foundElems.insert( foundElems.end(), elems.begin(), elems.end() );
}
//=======================================================================
@ -1242,7 +1251,7 @@ gp_XYZ SMESH_ElementSearcherImpl::Project(const gp_Pnt& point,
const Bnd_B3d* box = ebbLeaf->getBox();
double radius = ( box->CornerMax() - box->CornerMin() ).Modulus();
vector< const SMDS_MeshElement* > elems;
ElementBndBoxTree::TElemSeq elems;
ebbTree->getElementsInSphere( p, radius, elems );
while ( elems.empty() )
{
@ -1252,13 +1261,14 @@ gp_XYZ SMESH_ElementSearcherImpl::Project(const gp_Pnt& point,
gp_XYZ proj, bestProj;
const SMDS_MeshElement* elem = 0;
double minDist = 2 * radius;
for ( size_t i = 0; i < elems.size(); ++i )
ElementBndBoxTree::TElemSeq::iterator e = elems.begin();
for ( ; e != elems.end(); ++e )
{
double d = SMESH_MeshAlgos::GetDistance( elems[i], p, &proj );
double d = SMESH_MeshAlgos::GetDistance( *e, p, &proj );
if ( d < minDist )
{
bestProj = proj;
elem = elems[i];
elem = *e;
minDist = d;
}
}
@ -1282,7 +1292,7 @@ bool SMESH_MeshAlgos::IsOut( const SMDS_MeshElement* element, const gp_Pnt& poin
// get ordered nodes
vector< SMESH_TNodeXYZ > xyz; xyz.reserve( element->NbNodes()+1 );
std::vector< SMESH_TNodeXYZ > xyz; xyz.reserve( element->NbNodes()+1 );
SMDS_ElemIteratorPtr nodeIt = element->interlacedNodesElemIterator();
for ( int i = 0; nodeIt->more(); ++i )
@ -1347,7 +1357,7 @@ bool SMESH_MeshAlgos::IsOut( const SMDS_MeshElement* element, const gp_Pnt& poin
if ( n2pSize * n2pSize > fNormSize * 100 ) return true; // point is very far
plnNorm /= n2pSize;
// for each node of the face, compute its signed distance to the cutting plane
vector<double> dist( nbNodes + 1);
std::vector<double> dist( nbNodes + 1);
for ( i = 0; i < nbNodes; ++i )
{
gp_Vec n2p( xyz[i], point );
@ -1550,7 +1560,7 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshFace* face,
// coordinates of nodes (medium nodes, if any, ignored)
typedef SMDS_StdIterator< SMESH_TNodeXYZ, SMDS_ElemIteratorPtr > TXyzIterator;
vector<gp_XYZ> xyz( TXyzIterator( face->nodesIterator()), TXyzIterator() );
std::vector<gp_XYZ> xyz( TXyzIterator( face->nodesIterator()), TXyzIterator() );
xyz.resize( face->NbCornerNodes()+1 );
// transformation to get xyz[0] lies on the origin, xyz[1] lies on the Z axis,
@ -1574,7 +1584,7 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshFace* face,
trsf.SetTransformation( tgtCS );
// move all the nodes to 2D
vector<gp_XY> xy( xyz.size() );
std::vector<gp_XY> xy( xyz.size() );
for ( size_t i = 0;i < xyz.size()-1; ++i )
{
gp_XYZ p3d = xyz[i];
@ -1590,7 +1600,7 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshFace* face,
gp_XY point2D( tmpPnt.X(), tmpPnt.Z() );
// loop on edges of the face to analyze point position ralative to the face
set< PointPos > pntPosSet;
std::set< PointPos > pntPosSet;
for ( size_t i = 1; i < xy.size(); ++i )
{
PointPos pos = getPointPosition( point2D, &xy[0], i-1 );
@ -1608,7 +1618,7 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshFace* face,
gp_Vec n1p ( xyz[ pos._index ], point );
double u = ( edge * n1p ) / edge.SquareMagnitude(); // param [0,1] on the edge
// projection of the point on the edge
gp_XYZ proj = ( 1. - u ) * xyz[ pos._index ] + u * xyz[ pos._index+1 ];
gp_XYZ proj = xyz[ pos._index ] + u * edge.XYZ();
if ( closestPnt ) *closestPnt = proj;
return point.Distance( proj );
}
@ -1655,7 +1665,7 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshEdge* seg,
int i = 0, nbNodes = seg->NbNodes();
vector< SMESH_TNodeXYZ > xyz( nbNodes );
std::vector< SMESH_TNodeXYZ > xyz( nbNodes );
SMDS_ElemIteratorPtr nodeIt = seg->interlacedNodesElemIterator();
while ( nodeIt->more() )
xyz[ i++ ].Set( nodeIt->next() );
@ -1734,7 +1744,7 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshVolume* volume,
break;
}
default:
vector<const SMDS_MeshNode *> nvec( nodes, nodes + vTool.NbFaceNodes( iF ));
std::vector<const SMDS_MeshNode *> nvec( nodes, nodes + vTool.NbFaceNodes( iF ));
SMDS_PolygonalFaceOfNodes tmpFace( nvec );
dist = GetDistance( &tmpFace, point, closestPnt );
}
@ -1839,7 +1849,7 @@ SMESH_MeshAlgos::FindFaceInSet(const SMDS_MeshNode* n1,
}
else if ( n2 == prevN && n1 == n )
{
face = elem; swap( i1, i2 );
face = elem; std::swap( i1, i2 );
}
prevN = n;
}
@ -1874,7 +1884,7 @@ bool SMESH_MeshAlgos::FaceNormal(const SMDS_MeshElement* F, gp_XYZ& normal, bool
normal += ( p[2] - p[1] ) ^ ( p[0] - p[1] );
}
double size2 = normal.SquareModulus();
bool ok = ( size2 > numeric_limits<double>::min() * numeric_limits<double>::min());
bool ok = ( size2 > std::numeric_limits<double>::min() * std::numeric_limits<double>::min());
if ( normalized && ok )
normal /= sqrt( size2 );
@ -1886,10 +1896,10 @@ bool SMESH_MeshAlgos::FaceNormal(const SMDS_MeshElement* F, gp_XYZ& normal, bool
//purpose : Return nodes common to two elements
//=======================================================================
vector< const SMDS_MeshNode*> SMESH_MeshAlgos::GetCommonNodes(const SMDS_MeshElement* e1,
const SMDS_MeshElement* e2)
std::vector< const SMDS_MeshNode*> SMESH_MeshAlgos::GetCommonNodes(const SMDS_MeshElement* e1,
const SMDS_MeshElement* e2)
{
vector< const SMDS_MeshNode*> common;
std::vector< const SMDS_MeshNode*> common;
for ( int i = 0 ; i < e1->NbNodes(); ++i )
if ( e2->GetNodeIndex( e1->GetNode( i )) >= 0 )
common.push_back( e1->GetNode( i ));

View File

@ -24,7 +24,7 @@
// Author : Edward AGAPOV (eap)
// This file holds some low level algorithms extracted from SMESH_MeshEditor
// to make them accessible from Controls package
// to make them accessible from Controls package, and more
#ifndef __SMESH_MeshAlgos_HXX__
@ -41,6 +41,7 @@
class gp_Pnt;
class gp_Ax1;
class Bnd_B3d;
class SMDS_MeshNode;
class SMDS_MeshElement;
class SMDS_Mesh;
@ -96,6 +97,12 @@ struct SMESHUtils_EXPORT SMESH_ElementSearcher
const double radius,
SMDSAbs_ElementType type,
std::vector< const SMDS_MeshElement* >& foundElems) = 0;
/*!
* \brief Return elements whose bounding box intersects a given bounding box
*/
virtual void GetElementsInBox( const Bnd_B3d& box,
SMDSAbs_ElementType type,
std::vector< const SMDS_MeshElement* >& foundElems) = 0;
/*!
* \brief Find out if the given point is out of closed 2D mesh.
*/
@ -114,6 +121,27 @@ struct SMESHUtils_EXPORT SMESH_ElementSearcher
namespace SMESH_MeshAlgos
{
/*!
* \brief Return SMESH_NodeSearcher. The caller is responsible for deleting it
*/
SMESHUtils_EXPORT
SMESH_NodeSearcher* GetNodeSearcher( SMDS_Mesh& mesh );
SMESHUtils_EXPORT
SMESH_NodeSearcher* GetNodeSearcher( SMDS_ElemIteratorPtr elemIt );
/*!
* \brief Return SMESH_ElementSearcher. The caller is responsible for deleting it
*/
SMESHUtils_EXPORT
SMESH_ElementSearcher* GetElementSearcher( SMDS_Mesh& mesh,
double tolerance=-1.);
SMESHUtils_EXPORT
SMESH_ElementSearcher* GetElementSearcher( SMDS_Mesh& mesh,
SMDS_ElemIteratorPtr elemIt,
double tolerance=-1. );
/*!
* \brief Return true if the point is IN or ON of the element
*/
@ -219,26 +247,6 @@ namespace SMESH_MeshAlgos
MarkElems( (*it)->nodesIterator(), isMarked );
}
/*!
* \brief Return SMESH_NodeSearcher. The caller is responsible for deleting it
*/
SMESHUtils_EXPORT
SMESH_NodeSearcher* GetNodeSearcher( SMDS_Mesh& mesh );
SMESHUtils_EXPORT
SMESH_NodeSearcher* GetNodeSearcher( SMDS_ElemIteratorPtr elemIt );
/*!
* \brief Return SMESH_ElementSearcher. The caller is responsible for deleting it
*/
SMESHUtils_EXPORT
SMESH_ElementSearcher* GetElementSearcher( SMDS_Mesh& mesh,
double tolerance=-1.);
SMESHUtils_EXPORT
SMESH_ElementSearcher* GetElementSearcher( SMDS_Mesh& mesh,
SMDS_ElemIteratorPtr elemIt,
double tolerance=-1. );
typedef std::vector<const SMDS_MeshNode*> TFreeBorder;
@ -262,18 +270,16 @@ namespace SMESH_MeshAlgos
* Returns TFreeBorder's coincident within the given tolerance.
* If the tolerance <= 0.0 then one tenth of an average size of elements adjacent
* to free borders being compared is used.
*
* (Implemented in ./SMESH_FreeBorders.cxx)
*/
SMESHUtils_EXPORT
void FindCoincidentFreeBorders(SMDS_Mesh& mesh,
double tolerance,
CoincidentFreeBorders & foundFreeBordes);
// Implemented in ./SMESH_FreeBorders.cxx
/*!
* Returns all or only closed TFreeBorder's.
* Optionally check if the mesh is manifold and if faces are correctly oriented.
*
* (Implemented in ./SMESH_FreeBorders.cxx)
*/
SMESHUtils_EXPORT
void FindFreeBorders(SMDS_Mesh& mesh,
@ -281,26 +287,84 @@ namespace SMESH_MeshAlgos
const bool closedOnly,
bool* isManifold = 0,
bool* isGoodOri = 0);
// Implemented in ./SMESH_FreeBorders.cxx
/*!
* Fill a hole defined by a TFreeBorder with 2D elements.
*
* (Implemented in ./SMESH_FillHole.cxx)
*/
SMESHUtils_EXPORT
void FillHole(const TFreeBorder & freeBorder,
SMDS_Mesh& mesh,
std::vector<const SMDS_MeshElement*>& newFaces);
// Implemented in ./SMESH_FillHole.cxx
/*!
* \brief Find nodes whose merge makes the element invalid
*
* (Implemented in SMESH_DeMerge.cxx)
*/
SMESHUtils_EXPORT
void DeMerge(const SMDS_MeshElement* elem,
std::vector< const SMDS_MeshNode* >& newNodes,
std::vector< const SMDS_MeshNode* >& noMergeNodes);
// Implemented in SMESH_DeMerge.cxx
typedef std::vector< std::pair< const SMDS_MeshElement*, const SMDS_MeshElement* > > TEPairVec;
typedef std::vector< std::pair< const SMDS_MeshNode*, const SMDS_MeshNode* > > TNPairVec;
/*!
* \brief Create an offset mesh of given faces
* \param [in] faceIt - the input faces
* \param [in] theFixIntersections - to fix self intersections of the offset mesh or not
* \param [out] new2OldFaces - history of faces
* \param [out] new2OldNodes - history of nodes
* \return SMDS_Mesh* - the new offset mesh, a caller should delete
*/
SMESHUtils_EXPORT
SMDS_Mesh* MakeOffset( SMDS_ElemIteratorPtr faceIt,
SMDS_Mesh& mesh,
const double offset,
const bool theFixIntersections,
TEPairVec& new2OldFaces,
TNPairVec& new2OldNodes );
// Implemented in ./SMESH_Offset.cxx
/*!
* \brief Divide a mesh face into triangles
*/
// Implemented in ./SMESH_Triangulate.cxx
class SMESHUtils_EXPORT Triangulate
{
public:
static int GetNbTriangles( const SMDS_MeshElement* face );
int GetTriangles( const SMDS_MeshElement* face,
std::vector< const SMDS_MeshNode*>& nodes);
private:
bool triangulate( std::vector< const SMDS_MeshNode*>& nodes, const size_t nbNodes );
/*!
* \brief Vertex of a polygon. Together with 2 neighbor Vertices represents a triangle
*/
struct PolyVertex
{
SMESH_NodeXYZ _nxyz;
gp_XY _xy;
PolyVertex* _prev;
PolyVertex* _next;
void SetNodeAndNext( const SMDS_MeshNode* n, PolyVertex& v );
void GetTriaNodes( const SMDS_MeshNode** nodes) const;
double TriaArea() const;
bool IsInsideTria( const PolyVertex* v );
PolyVertex* Delete();
};
std::vector< PolyVertex > _pv;
};
} // namespace SMESH_MeshAlgos

View File

@ -29,6 +29,7 @@
#include "SMESH_Utils.hxx"
#include "SMDS_SetIterator.hxx"
#include "SMDS_MeshNode.hxx"
#include <gp_XYZ.hxx>
@ -39,6 +40,8 @@
#include <set>
#include <cassert>
#include <boost/make_shared.hpp>
typedef std::map<const SMDS_MeshElement*,
std::list<const SMDS_MeshElement*>, TIDCompare > TElemOfElemListMap;
typedef std::map<const SMDS_MeshElement*,
@ -100,6 +103,14 @@ namespace SMESHUtils
private:
ArrayDeleter( const ArrayDeleter& );
};
template < class ELEM_SET >
SMDS_ElemIteratorPtr elemSetIterator( const ELEM_SET& elements )
{
typedef SMDS_SetIterator
< SMDS_pElement, typename ELEM_SET::const_iterator> TSetIterator;
return boost::make_shared< TSetIterator >( elements.begin(), elements.end() );
}
}
//=======================================================================
@ -127,6 +138,7 @@ struct SMESH_TLink: public NLink
return ( l1.node1() == l2.node1() && l1.node2() == l2.node2() );
}
};
typedef SMESH_TLink SMESH_Link;
//=======================================================================
/*!
@ -163,9 +175,13 @@ struct SMESH_TNodeXYZ : public gp_XYZ
}
return false;
}
const SMDS_MeshNode* Node() const { return _node; }
double Distance(const SMDS_MeshNode* n) const { return (SMESH_TNodeXYZ( n )-*this).Modulus(); }
double SquareDistance(const SMDS_MeshNode* n) const { return (SMESH_TNodeXYZ( n )-*this).SquareModulus(); }
bool operator==(const SMESH_TNodeXYZ& other) const { return _node == other._node; }
bool operator!=(const SMESH_TNodeXYZ& other) const { return _node != other._node; }
bool operator!() const { return !_node; }
const SMDS_MeshNode* operator->() const { return _node; }
};
typedef SMESH_TNodeXYZ SMESH_NodeXYZ;
@ -198,17 +214,12 @@ typedef std::vector< UVPtStruct > UVPtStructVec;
// --------------------------------------------------------------------------------
// class SMESH_SequenceOfElemPtr
#include <NCollection_DefineSequence.hxx>
class SMDS_MeshElement;
typedef const SMDS_MeshElement* SMDS_MeshElementPtr;
DEFINE_SEQUENCE (SMESH_SequenceOfElemPtr, SMESH_BaseCollectionElemPtr, SMDS_MeshElementPtr)
typedef std::vector< const SMDS_MeshElement* > SMESH_SequenceOfElemPtr;
// --------------------------------------------------------------------------------
// class SMESH_SequenceOfNode
#include <NCollection_DefineSequence.hxx>
typedef const SMDS_MeshNode* SMDS_MeshNodePtr;
DEFINE_SEQUENCE(SMESH_SequenceOfNode,

View File

@ -117,10 +117,7 @@ private:
// get next free object identifier
int getNextId()
{
int id = 1;
while( mapIdToIOR.IsBound( id ) )
id++;
return id;
return mapIdToIOR.Extent() + 1;
}
TInt2StringMap mapIdToIOR; // persistent-to-transient map

View File

@ -1021,7 +1021,7 @@ void SMESH_Gen_i::UpdateParameters(CORBA::Object_ptr theObject, const char* theP
myLastObj.clear();
myLastParameters.clear();
myLastParamIndex.clear(); /* vector holding indices of virables within the string
of all varibles used for theObject */
of all variables used for theObject */
int nbVars = 0;
int pos = 0, prevPos = 0, len = strlen( theParameters );
if ( len == 0 ) return;
@ -1050,7 +1050,7 @@ void SMESH_Gen_i::UpdateParameters(CORBA::Object_ptr theObject, const char* theP
return;
// store
// (1) variable names in the string of all varibles used for theObject and
// (1) variable names in the string of all variables used for theObject and
// (2) indices of found variables in myLastParamIndex.
// remember theObject

View File

@ -165,7 +165,10 @@ namespace MeshEditor_I {
}
void Remove( SMDSAbs_ElementType type )
{
SMDS_ElemIteratorPtr eIt = GetMeshDS()->elementsIterator( type );
Remove( GetMeshDS()->elementsIterator( type ));
}
void Remove( SMDS_ElemIteratorPtr eIt )
{
while ( eIt->more() )
GetMeshDS()->RemoveFreeElement( eIt->next(), /*sm=*/0, /*fromGroups=*/false );
}
@ -522,14 +525,14 @@ SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
SMESH_TRY;
const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() );
if ( myIsPreviewMode || hasBadElems ) { // --- MeshPreviewStruct filling ---
if ( myIsPreviewMode || hasBadElems )
{
list<int> aNodesConnectivity;
typedef map<int, int> TNodesMap;
TNodesMap nodesMap;
SMESHDS_Mesh* aMeshDS;
std::auto_ptr< SMESH_MeshPartDS > aMeshPartDS;
std::unique_ptr< SMESH_MeshPartDS > aMeshPartDS;
if ( hasBadElems ) {
aMeshPartDS.reset( new SMESH_MeshPartDS( getEditor().GetError()->myBadElements ));
aMeshDS = aMeshPartDS.get();
@ -615,9 +618,9 @@ SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array();
const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedNodes();
myLastCreatedNodes->length( aSeq.Length() );
for (int i = 1; i <= aSeq.Length(); i++)
myLastCreatedNodes[i-1] = aSeq.Value(i)->GetID();
myLastCreatedNodes->length( aSeq.size() );
for ( size_t i = 0; i < aSeq.size(); i++)
myLastCreatedNodes[i] = aSeq[i]->GetID();
return myLastCreatedNodes._retn();
SMESH_CATCH( SMESH::throwCorbaException );
@ -638,9 +641,9 @@ SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
SMESH::long_array_var myLastCreatedElems = new SMESH::long_array();
const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
myLastCreatedElems->length( aSeq.Length() );
for ( int i = 1; i <= aSeq.Length(); i++ )
myLastCreatedElems[i-1] = aSeq.Value(i)->GetID();
myLastCreatedElems->length( aSeq.size() );
for ( size_t i = 0; i < aSeq.size(); i++ )
myLastCreatedElems[i] = aSeq[i]->GetID();
return myLastCreatedElems._retn();
SMESH_CATCH( SMESH::throwCorbaException );
@ -4014,6 +4017,84 @@ SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
return mesh._retn();
}
//================================================================================
/*!
* \brief Make an offset mesh from a source 2D mesh
* \param [inout] theObject - source mesh. New elements are added to this mesh
* if \a theMeshName is empty.
* \param [in] theValue - offset value
* \param [in] theCopyGroups - to generate groups
* \param [in] theMeshName - optional name of a new mesh
* \param [out] theGroups - new groups
* \return SMESH::SMESH_Mesh_ptr - the modified mesh
*/
//================================================================================
SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::Offset( SMESH::SMESH_IDSource_ptr theObject,
CORBA::Double theValue,
CORBA::Boolean theCopyGroups,
const char* theMeshName,
SMESH::ListOfGroups_out theGroups)
throw (SALOME::SALOME_Exception)
{
SMESH_TRY;
initData();
SMESHDS_Mesh* aMeshDS = getMeshDS();
SMESH::SMESH_Mesh_var mesh_var;
::SMESH_MeshEditor::PGroupIDs groupIds;
TPythonDump pyDump;
TIDSortedElemSet elements, copyElements;
if ( idSourceToSet( theObject, aMeshDS, elements, SMDSAbs_Face,
/*emptyIfIsMesh=*/ !myIsPreviewMode ))
{
// mesh to modify
SMESH_Mesh* tgtMesh = 0;
if ( myIsPreviewMode )
{
TPreviewMesh * tmpMesh = getPreviewMesh();
tgtMesh = tmpMesh;
tmpMesh->Copy( elements, copyElements );
theCopyGroups = false;
}
else
{
mesh_var =
*theMeshName ? makeMesh( theMeshName ) : SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
tgtMesh = & mesh_i->GetImpl();
}
groupIds = getEditor().Offset( elements, theValue, tgtMesh, theCopyGroups, !myIsPreviewMode );
tgtMesh->GetMeshDS()->Modified();
}
if ( myIsPreviewMode )
{
getPreviewMesh()->Remove( SMESHUtils::elemSetIterator( copyElements ));
}
else
{
theGroups = theCopyGroups ? getGroups( groupIds.get() ) : new SMESH::ListOfGroups;
// result of Offset() is a tuple (mesh, groups)
if ( mesh_var->_is_nil() ) pyDump << myMesh_i->_this() << ", ";
else pyDump << mesh_var << ", ";
pyDump << theGroups << " = "
<< this << ".Offset( "
<< theValue << ", "
<< theCopyGroups << ", "
<< "'" << theMeshName<< "')";
}
return mesh_var._retn();
SMESH_CATCH( SMESH::throwCorbaException );
return SMESH::SMESH_Mesh::_nil();
}
//=======================================================================
//function : findCoincidentNodes
@ -4713,8 +4794,7 @@ void SMESH_MeshEditor_i::FillHole(const SMESH::FreeBorder& theHole)
getEditor().ClearLastCreated();
SMESH_SequenceOfElemPtr& aSeq =
const_cast<SMESH_SequenceOfElemPtr&>( getEditor().GetLastCreatedElems() );
for ( size_t i = 0; i < newFaces.size(); ++i )
aSeq.Append( newFaces[i] );
aSeq.swap( newFaces );
TPythonDump() << this << ".FillHole( SMESH.FreeBorder(" << theHole.nodeIDs << " ))";
}
@ -5529,7 +5609,7 @@ bool SMESH_MeshEditor_i::idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource,
* \param theElements - container of elements to duplicate.
* \param theGroupName - a name of group to contain the generated elements.
* If a group with such a name already exists, the new elements
* are added to the existng group, else a new group is created.
* are added to the existing group, else a new group is created.
* If \a theGroupName is empty, new elements are not added
* in any group.
* \return a group where the new elements are added. NULL if theGroupName == "".
@ -5554,11 +5634,11 @@ SMESH_MeshEditor_i::DoubleElements(SMESH::SMESH_IDSource_ptr theElements,
{
getEditor().DoubleElements( elems );
if ( strlen( theGroupName ) && !getEditor().GetLastCreatedElems().IsEmpty() )
if ( strlen( theGroupName ) && !getEditor().GetLastCreatedElems().empty() )
{
// group type
SMESH::ElementType type =
SMESH::ElementType( getEditor().GetLastCreatedElems().Value(1)->GetType() );
SMESH::ElementType( getEditor().GetLastCreatedElems()[0]->GetType() );
// find existing group
SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
for ( size_t i = 0; i < groups->length(); ++i )
@ -5578,8 +5658,8 @@ SMESH_MeshEditor_i::DoubleElements(SMESH::SMESH_IDSource_ptr theElements,
{
SMESHDS_Group* groupDS = static_cast< SMESHDS_Group* >( group_i->GetGroupDS() );
const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
for ( int i = 1; i <= aSeq.Length(); i++ )
groupDS->SMDSGroup().Add( aSeq(i) );
for ( size_t i = 0; i <= aSeq.size(); i++ )
groupDS->SMDSGroup().Add( aSeq[i] );
}
}
}
@ -6070,14 +6150,14 @@ SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
// Create group with newly created elements
CORBA::String_var elemGroupName = theElems->GetName();
std::string aNewName = generateGroupName( std::string(elemGroupName.in()) + "_double");
if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
if ( !getEditor().GetLastCreatedElems().empty() && theElemGroupNeeded )
{
SMESH::long_array_var anIds = GetLastCreatedElems();
SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
aNewElemGroup->Add(anIds);
}
if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
if ( !getEditor().GetLastCreatedNodes().empty() && theNodeGroupNeeded )
{
SMESH::long_array_var anIds = GetLastCreatedNodes();
aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
@ -6302,14 +6382,14 @@ SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems
// Create group with newly created elements
CORBA::String_var elemGroupName = theElems[0]->GetName();
std::string aNewName = generateGroupName( std::string(elemGroupName.in()) + "_double");
if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
if ( !getEditor().GetLastCreatedElems().empty() && theElemGroupNeeded )
{
SMESH::long_array_var anIds = GetLastCreatedElems();
SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
aNewElemGroup->Add(anIds);
}
if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
if ( !getEditor().GetLastCreatedNodes().empty() && theNodeGroupNeeded )
{
SMESH::long_array_var anIds = GetLastCreatedNodes();
aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());

View File

@ -472,11 +472,18 @@ public:
const SMESH::double_array& theScaleFact)
throw (SALOME::SALOME_Exception);
SMESH::SMESH_Mesh_ptr ScaleMakeMesh(SMESH::SMESH_IDSource_ptr Object,
const SMESH::PointStruct& Point,
SMESH::SMESH_Mesh_ptr ScaleMakeMesh(SMESH::SMESH_IDSource_ptr Object,
const SMESH::PointStruct& Point,
const SMESH::double_array& theScaleFact,
CORBA::Boolean CopyGroups,
const char* MeshName)
CORBA::Boolean CopyGroups,
const char* MeshName)
throw (SALOME::SALOME_Exception);
SMESH::SMESH_Mesh_ptr Offset( SMESH::SMESH_IDSource_ptr theObject,
CORBA::Double Value,
CORBA::Boolean CopyGroups,
const char* MeshName,
SMESH::ListOfGroups_out Groups)
throw (SALOME::SALOME_Exception);
void FindCoincidentNodes (CORBA::Double Tolerance,
@ -983,8 +990,6 @@ public:
// temporary IDSources
struct _IDSource;
// std::list< _IDSource* > myAuxIDSources;
// void deleteAuxIDSources();
};
#endif

View File

@ -90,7 +90,7 @@ namespace SMESH
// ===========================================================================================
/*!
* \brief Object used to make TPythonDump know that its held value can be a varible
* \brief Object used to make TPythonDump know that its held value can be a variable
*
* TPythonDump substitute TVar with names of notebook variables if any.
*/

View File

@ -4583,6 +4583,24 @@ class Mesh:
self.mesh.SetParameters(Parameters)
return Mesh( self.smeshpyD, self.geompyD, mesh )
## Create an offset mesh from the given 2D object
# @param theObject the source object (mesh, submesh, group or filter)
# @param theValue signed offset size
# @param MakeGroups forces the generation of new groups from existing ones
# @param NewMeshName the name of a mesh to create. If empty, offset elements are added
# to this mesh
# @return a tuple (mesh, list_of_groups)
# @ingroup l2_modif_trsf
def Offset(self, theObject, theValue, MakeGroups=False, NewMeshName=''):
if isinstance( theObject, Mesh ):
theObject = theObject.GetMesh()
theValue,Parameters,hasVars = ParseParameters(theValue)
mesh_groups = self.editor.Offset(theObject, theValue, MakeGroups, NewMeshName )
self.mesh.SetParameters(Parameters)
# if mesh_groups[0]:
# return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
return mesh_groups
## Find groups of adjacent nodes within Tolerance.
# @param Tolerance the value of tolerance
# @param SeparateCornerAndMediumNodes if @c True, in quadratic mesh puts
@ -4794,7 +4812,7 @@ class Mesh:
# a Mesh, elements of highest dimension are duplicated
# @param theGroupName - a name of group to contain the generated elements.
# If a group with such a name already exists, the new elements
# are added to the existng group, else a new group is created.
# are added to the existing group, else a new group is created.
# If \a theGroupName is empty, new elements are not added
# in any group.
# @return a group where the new elements are added. None if theGroupName == "".

View File

@ -2613,34 +2613,34 @@ namespace
{
enum { X = 1, Y = 2, Z = 4 }; // == 001, 010, 100
int nbFacets = 0;
int vertex = 0, egdeMask = 0;
int vertex = 0, edgeMask = 0;
if ( Abs( _grid->_coords[0][ _i ] - ip->_uvw[0] ) < _grid->_tol ) {
facets[ nbFacets++ ] = SMESH_Block::ID_F0yz;
egdeMask |= X;
edgeMask |= X;
}
else if ( Abs( _grid->_coords[0][ _i+1 ] - ip->_uvw[0] ) < _grid->_tol ) {
facets[ nbFacets++ ] = SMESH_Block::ID_F1yz;
vertex |= X;
egdeMask |= X;
edgeMask |= X;
}
if ( Abs( _grid->_coords[1][ _j ] - ip->_uvw[1] ) < _grid->_tol ) {
facets[ nbFacets++ ] = SMESH_Block::ID_Fx0z;
egdeMask |= Y;
edgeMask |= Y;
}
else if ( Abs( _grid->_coords[1][ _j+1 ] - ip->_uvw[1] ) < _grid->_tol ) {
facets[ nbFacets++ ] = SMESH_Block::ID_Fx1z;
vertex |= Y;
egdeMask |= Y;
edgeMask |= Y;
}
if ( Abs( _grid->_coords[2][ _k ] - ip->_uvw[2] ) < _grid->_tol ) {
facets[ nbFacets++ ] = SMESH_Block::ID_Fxy0;
egdeMask |= Z;
edgeMask |= Z;
}
else if ( Abs( _grid->_coords[2][ _k+1 ] - ip->_uvw[2] ) < _grid->_tol ) {
facets[ nbFacets++ ] = SMESH_Block::ID_Fxy1;
vertex |= Z;
egdeMask |= Z;
edgeMask |= Z;
}
switch ( nbFacets )
@ -2656,7 +2656,7 @@ namespace
{ SMESH_Block::ID_Ex00, 0, SMESH_Block::ID_Ex10, 0,
SMESH_Block::ID_Ex01, 0, SMESH_Block::ID_Ex11 }
};
switch ( egdeMask ) {
switch ( edgeMask ) {
case X | Y: sub = edge[ 0 ][ vertex ]; break;
case X | Z: sub = edge[ 1 ][ vertex ]; break;
default: sub = edge[ 2 ][ vertex ];

View File

@ -219,7 +219,7 @@ bool StdMeshersGUI_PropagationHelperWdg::buildChains()
// aPreviewActor holds a map od all sub-shapes of mainShape
SMESH_PreviewActorsCollection* previewActor = mySubSelectWdg->GetActorCollection();
if ( !previewActor ) return false;
const QList<int>& egdeIDs = previewActor->GetIndices();
const QList<int>& edgeIDs = previewActor->GetIndices();
// Make a 'map' of WIREs of EDGE with quadrilateral WIREs only
@ -277,11 +277,11 @@ bool StdMeshersGUI_PropagationHelperWdg::buildChains()
TColStd_MapOfInteger shapeEdges;
if ( !shape.IsSame( mainShape ))
for ( QList<TGeomID>::const_iterator ieIt = egdeIDs.begin(); ieIt != egdeIDs.end(); ++ieIt )
for ( QList<TGeomID>::const_iterator ieIt = edgeIDs.begin(); ieIt != edgeIDs.end(); ++ieIt )
shapeEdges.Add( *ieIt );
// loop on all EDGEs in mainShape
for ( QList<TGeomID>::const_iterator ieIt = egdeIDs.begin(); ieIt != egdeIDs.end(); ++ieIt )
for ( QList<TGeomID>::const_iterator ieIt = edgeIDs.begin(); ieIt != edgeIDs.end(); ++ieIt )
{
if ( chainedEdges.Contains( *ieIt ))
continue;
@ -329,7 +329,7 @@ bool StdMeshersGUI_PropagationHelperWdg::buildChains()
if ( ch.size() < 2 )
myChains.pop_back();
}
} // loop on egdeIDs
} // loop on edgeIDs
return !myChains.empty();
}

View File

@ -56,8 +56,8 @@ def PublishGroups ():
TempNames = []
for MacroObj in Config.ListObj :
if group in MacroObj.GroupNames :
Occurences = IndexMultiOcc(MacroObj.GroupNames, group)
for Occ in Occurences :
Occurrences = IndexMultiOcc(MacroObj.GroupNames, group)
for Occ in Occurrences :
TempGEOList += MacroObj.GetBorder(Occ)
GroupGEO.append(geompy.MakeCompound(TempGEOList))
geompy.addToStudyInFather(FinalCompound,GroupGEO[-1],'GR_'+group)

View File

@ -35,7 +35,7 @@ These two parameters allow the user to prescribe a Maximal/Minimal size for the
- **Mesh gradation**
This parameter P controls the element size variation : MeshGems-SurfOpt will avoid having two adjacent edges which sizes vary more than the given gradation. A size correction is applied to the size map : if two adjacent edges are respectively e1 and e2 long and e2 > Pxe1, then, the new size for the second edge will be set to P x e1.
**This procedure is deactived if P=-1**
**This procedure is deactivated if P=-1**

View File

@ -22,7 +22,7 @@ Simple case
Optimisation
------------
This is the main remeshing Option. SurfOpt always does quality improvement. It is done by point smooting and edge swapping. It can produce a regular mesh for finite element computation (initial mesh is a a geometrical mesh). In this case, the given surface trianglation is modified in accordance to a size map : an intrinsic size map is computed automatically. it is based on the surface proporties. SurfOpt is also able to produce a geometrical mesh (initial mesh is a a mesh for finite element computation). In both case, It can coarsen or enrich the mesh.
This is the main remeshing Option. SurfOpt always does quality improvement. It is done by point smoothing and edge swapping. It can produce a regular mesh for finite element computation (initial mesh is a a geometrical mesh). In this case, the given surface trianglation is modified in accordance to a size map : an intrinsic size map is computed automatically. it is based on the surface proporties. SurfOpt is also able to produce a geometrical mesh (initial mesh is a mesh for finite element computation). In both case, It can coarsen or enrich the mesh.
- **Quality improvement**

View File

@ -100,10 +100,10 @@ class PluginDialog(QDialog):
def setupJobManager(self):
'''
This function configures the jobmanager by transmiting the
This function configures the jobmanager by transmitting the
parameters required for a local execution and a remote
execution. The choice between "local" and "remote" is done at
the initialize step, by specifing the name of the resource to
the initialize step, by specifying the name of the resource to
be used.
'''
# We first