Merge branch 'master' into V9_3_BR

This commit is contained in:
vsr 2019-04-08 19:23:20 +03:00
commit 474a24023d
20 changed files with 480 additions and 213 deletions

View File

@ -116,7 +116,7 @@ If the parent mesh is already computed, then you can define the **Geometry** by
.. image:: ../images/choose_geom_selection_way.png .. image:: ../images/choose_geom_selection_way.png
:align: center :align: center
**Direct geometry selection** enables selecting the sub-shape in the Objec Browser. **Direct geometry selection** enables selecting the sub-shape in the Object Browser.
**Find geometry by mesh element selection** activates the following dialog. **Find geometry by mesh element selection** activates the following dialog.
.. image:: ../images/find_geom_by_mesh_elem.png .. image:: ../images/find_geom_by_mesh_elem.png

View File

@ -143,7 +143,7 @@ Extrusion of 2d elements along a closed path
.. |add| image:: ../images/add.png .. |add| image:: ../images/add.png
.. |rem| image:: ../images/remove.png .. |rem| image:: ../images/remove.png
* The elements can also be rotated around the path with rotaion center at the **Base point** to get the resulting mesh in a helical fashion. You can set the values of angles at the right, add them to **Rotation angles** list at the left by pressing the *"Add"* button |add| and remove them from the list by pressing the *"Remove"* button |rem|. * The elements can also be rotated around the path with rotation center at the **Base point** to get the resulting mesh in a helical fashion. You can set the values of angles at the right, add them to **Rotation angles** list at the left by pressing the *"Add"* button |add| and remove them from the list by pressing the *"Remove"* button |rem|.
**Linear variation of angles** option allows defining the angle of gradual rotation for the whole path. At each step the elements will be rotated by *( angle / nb. of steps )*. **Linear variation of angles** option allows defining the angle of gradual rotation for the whole path. At each step the elements will be rotated by *( angle / nb. of steps )*.

View File

@ -296,7 +296,7 @@ module SMESH
* \param invalidEntries - return study entries of objects whose * \param invalidEntries - return study entries of objects whose
* counterparts are not found in the newGeometry, followed by entries * counterparts are not found in the newGeometry, followed by entries
* of mesh sub-objects that are invalid because they depend on a not found * of mesh sub-objects that are invalid because they depend on a not found
* preceeding sub-shape * preceding sub-shape
*/ */
boolean CopyMeshWithGeom( in SMESH_Mesh sourceMesh, boolean CopyMeshWithGeom( in SMESH_Mesh sourceMesh,
in GEOM::GEOM_Object newGeometry, in GEOM::GEOM_Object newGeometry,
@ -500,9 +500,9 @@ module SMESH
* Return indices of elements, which are located inside the sphere * Return indices of elements, which are located inside the sphere
* \param theSource - mesh, sub-mesh or group * \param theSource - mesh, sub-mesh or group
* \param theElemType - mesh element type * \param theElemType - mesh element type
* \param theX - x cooridate of the center of the sphere * \param theX - x coordinate of the center of the sphere
* \param theY - y cooridate of the center of the sphere * \param theY - y coordinate of the center of the sphere
* \param theZ - y cooridate of the center of the sphere * \param theZ - y coordinate of the center of the sphere
* \param theR - radius of the sphere * \param theR - radius of the sphere
*/ */
long_array GetInsideSphere( in SMESH_IDSource theSource, long_array GetInsideSphere( in SMESH_IDSource theSource,
@ -516,12 +516,12 @@ module SMESH
* Return indices of elements, which are located inside the box * Return indices of elements, which are located inside the box
* \param theSource - mesh, sub-mesh or group * \param theSource - mesh, sub-mesh or group
* \param theElemType - mesh element type * \param theElemType - mesh element type
* \param theX1 - x cooridate of the first opposite point * \param theX1 - x coordinate of the first opposite point
* \param theY1 - y cooridate of the first opposite point * \param theY1 - y coordinate of the first opposite point
* \param theZ1 - y cooridate of the first opposite point * \param theZ1 - y coordinate of the first opposite point
* \param theX2 - x cooridate of the second opposite point * \param theX2 - x coordinate of the second opposite point
* \param theY2 - y cooridate of the second opposite point * \param theY2 - y coordinate of the second opposite point
* \param theZ2 - y cooridate of the second opposite point * \param theZ2 - y coordinate of the second opposite point
*/ */
long_array GetInsideBox( in SMESH_IDSource theSource, long_array GetInsideBox( in SMESH_IDSource theSource,
in ElementType theElemType, in ElementType theElemType,
@ -535,12 +535,12 @@ module SMESH
* Return indices of elements, which are located inside the box * Return indices of elements, which are located inside the box
* \param theSource - mesh, sub-mesh or group * \param theSource - mesh, sub-mesh or group
* \param theElemType - mesh element type * \param theElemType - mesh element type
* \param theX - x cooridate of the cented of the bottom face * \param theX - x coordinate of the cented of the bottom face
* \param theY - y cooridate of the cented of the bottom face * \param theY - y coordinate of the cented of the bottom face
* \param theZ - y cooridate of the cented of the bottom face * \param theZ - y coordinate of the cented of the bottom face
* \param theDX - x cooridate of the cented of the base vector * \param theDX - x coordinate of the cented of the base vector
* \param theDY - y cooridate of the cented of the base vector * \param theDY - y coordinate of the cented of the base vector
* \param theDZ - z cooridate of the cented of the base vector * \param theDZ - z coordinate of the cented of the base vector
* \param theH - height of the cylinder * \param theH - height of the cylinder
* \param theR - radius of the cylinder * \param theR - radius of the cylinder
*/ */

View File

@ -193,7 +193,7 @@ namespace MED
TInt myNbElem; //<! Number of corresponding mesh entities TInt myNbElem; //<! Number of corresponding mesh entities
TInt GetNbElem() const { return myNbElem; } //! Get number of mesh elements TInt GetNbElem() const { return myNbElem; } //! Get number of mesh elements
//! Defines sequence MED Family indexes for corresponding mesh entites //! Defines sequence MED Family indexes for corresponding mesh entities
PElemNum myFamNum; PElemNum myFamNum;
//! Get number of a MED FAMILY by order number of the mesh element //! Get number of a MED FAMILY by order number of the mesh element
TInt GetFamNum(TInt theId) const; TInt GetFamNum(TInt theId) const;
@ -587,7 +587,7 @@ namespace MED
size_t size_t
GetSize() const; GetSize() const;
//! Returns MED interpetation of the value size //! Returns MED interpretation of the value size
size_t size_t
GetNbVal() const; GetNbVal() const;

View File

@ -239,6 +239,9 @@ int SMDS_ElementFactory::FromVtkToSmds( vtkIdType vtkID )
void SMDS_ElementFactory::Free( const SMDS_MeshElement* e ) void SMDS_ElementFactory::Free( const SMDS_MeshElement* e )
{ {
if ( e != FindElement( e->GetID() ))
SALOME_Exception("SMDS_ElementFactory::Free(): element of other mesh");
if ( !myVtkIDs.empty() ) if ( !myVtkIDs.empty() )
{ {
size_t id = e->GetID() - 1; size_t id = e->GetID() - 1;

View File

@ -147,6 +147,7 @@ namespace // Iterator
size_t myNbToFind, myNbFound, myTotalNb; size_t myNbToFind, myNbFound, myTotalNb;
vector< const SMDS_MeshElement*>& myFoundElems; vector< const SMDS_MeshElement*>& myFoundElems;
bool & myFoundElemsOK; bool & myFoundElemsOK;
bool myFoundElemsChecked;
TIterator( const SMESH_PredicatePtr& filter, TIterator( const SMESH_PredicatePtr& filter,
SMDS_ElemIteratorPtr& elems, SMDS_ElemIteratorPtr& elems,
@ -161,14 +162,15 @@ namespace // Iterator
myNbFound( 0 ), myNbFound( 0 ),
myTotalNb( totalNb ), myTotalNb( totalNb ),
myFoundElems( foundElems ), myFoundElems( foundElems ),
myFoundElemsOK( foundElemsOK ) myFoundElemsOK( foundElemsOK ),
myFoundElemsChecked( false )
{ {
myFoundElemsOK = false; myFoundElemsOK = false;
next(); next();
} }
~TIterator() ~TIterator()
{ {
if ( !myFoundElemsOK ) if ( !myFoundElemsChecked && !myFoundElemsOK )
clearVector( myFoundElems ); clearVector( myFoundElems );
} }
virtual bool more() virtual bool more()
@ -225,6 +227,8 @@ namespace // Iterator
} }
if ( !myFoundElemsOK ) if ( !myFoundElemsOK )
clearVector( myFoundElems ); clearVector( myFoundElems );
myFoundElemsChecked = true; // in destructor: not to clearVector() which may already die
} }
}; };

View File

@ -356,7 +356,7 @@ QString SMESHGUI_CopyMeshDlg::getErrorMsg( SMESH::string_array_var theInvalidEnt
// theInvalidEntries - SObject's that hold geometry objects whose // theInvalidEntries - SObject's that hold geometry objects whose
// counterparts are not found in the newGeometry, followed by SObject's // counterparts are not found in the newGeometry, followed by SObject's
// holding mesh sub-objects that are invalid because they depend on a not found // holding mesh sub-objects that are invalid because they depend on a not found
// preceeding sub-shape // preceding sub-shape
QString msg = tr("SUBSHAPES_NOT_FOUND_MSG") + "\n"; QString msg = tr("SUBSHAPES_NOT_FOUND_MSG") + "\n";

View File

@ -1402,7 +1402,7 @@ void SMESHGUI_FilterTable::SetCriterion (const int theRow,
theCriterion.Type != SMESH::FT_OverConstrainedVolume && theCriterion.Type != SMESH::FT_OverConstrainedVolume &&
theCriterion.Type != SMESH::FT_LinearOrQuadratic) theCriterion.Type != SMESH::FT_LinearOrQuadratic)
{ {
// Numberic criterion // Numeric criterion
aTable->item( theRow, 2 )->setText(QString("%1").arg(theCriterion.Threshold, 0, 'g', 15)); aTable->item( theRow, 2 )->setText(QString("%1").arg(theCriterion.Threshold, 0, 'g', 15));
} }
else else

View File

@ -81,7 +81,7 @@ public:
/*! /*!
\brief Constructor. \brief Constructor.
\param parent Parent widget. \param parent Parent widget.
\param name Field name. Defauls to null string. \param name Field name. Defaults to null string.
*/ */
Field::Field( QWidget* parent, const QString& name ): QLabel( parent ) Field::Field( QWidget* parent, const QString& name ): QLabel( parent )
{ {
@ -382,7 +382,7 @@ namespace
\brief Format connectivity data to string representation. \brief Format connectivity data to string representation.
\param connectivity Connectivity map. \param connectivity Connectivity map.
\param type Element type or face index if negative \param type Element type or face index if negative
\return Stringifed representation of the connectivity. \return Stringified representation of the connectivity.
*/ */
QString formatConnectivity( SMESH::Connectivity connectivity, int type ) QString formatConnectivity( SMESH::Connectivity connectivity, int type )
{ {
@ -1036,7 +1036,7 @@ void SMESHGUI_BaseInfo::setFieldsVisible( int startRow, int lastRow, bool on )
} }
/*! /*!
\brief Write information from panel to ouput stream. \brief Write information from panel to output stream.
\param out Text stream output. \param out Text stream output.
*/ */
void SMESHGUI_BaseInfo::saveInfo( QTextStream& out ) void SMESHGUI_BaseInfo::saveInfo( QTextStream& out )
@ -1999,7 +1999,7 @@ void SMESHGUI_ElemInfo::updateControls()
} }
/*! /*!
\brief Write information from panel to ouput stream. \brief Write information from panel to output stream.
\param out Text stream output. \param out Text stream output.
*/ */
void SMESHGUI_ElemInfo::saveInfo( QTextStream &out ) void SMESHGUI_ElemInfo::saveInfo( QTextStream &out )
@ -2864,7 +2864,7 @@ void SMESHGUI_AddInfo::showNextSubMeshes()
} }
/*! /*!
\brief Write information from panel to ouput stream. \brief Write information from panel to output stream.
\param out Text stream output. \param out Text stream output.
*/ */
void SMESHGUI_AddInfo::saveInfo( QTextStream &out ) void SMESHGUI_AddInfo::saveInfo( QTextStream &out )
@ -2926,7 +2926,7 @@ public:
}; };
/*! /*!
\brief Contructor. \brief Constructor.
\param parent Parent widget. \param parent Parent widget.
\internal \internal
*/ */

View File

@ -101,7 +101,7 @@ SMESH::SelectionProxy::SelectionProxy( const SelectionProxy& other )
void SMESH::SelectionProxy::init() void SMESH::SelectionProxy::init()
{ {
if ( myIO.IsNull() ) if ( myIO.IsNull() )
myIO = new SALOME_InteractiveObject(); // create dummy IO to avoid crashes when accesing it myIO = new SALOME_InteractiveObject(); // create dummy IO to avoid crashes when accessing it
if ( !CORBA::is_nil( myObject ) ) if ( !CORBA::is_nil( myObject ) )
{ {
@ -1376,7 +1376,7 @@ void SMESH::MedInfo::setVersion( uint major, uint minor, uint release )
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/*! /*!
\brief Contructor. Creates invalid position. \brief Constructor. Creates invalid position.
*/ */
SMESH::Position::Position(): SMESH::Position::Position():
myShapeId(-1), myShapeType(-1), myU(0), myV(0), myHasU(false), myHasV(false) myShapeId(-1), myShapeType(-1), myU(0), myV(0), myHasU(false), myHasV(false)

View File

@ -759,10 +759,7 @@ namespace SMESH_MeshAlgos
const double theSign, const double theSign,
const bool theOptimize ); const bool theOptimize );
//! Cut a face by planes, whose normals point to parts to keep void IntersectNewEdges( const CutFace& theCFace );
bool CutByPlanes(const SMDS_MeshElement* face,
const std::vector< gp_Ax1 > & planes,
std::vector< SMESH_NodeXYZ > & newConnectivity );
private: private:
@ -815,7 +812,6 @@ namespace SMESH_MeshAlgos
bool & isCollinear ); bool & isCollinear );
bool intersectEdgeEdge( int iE1, int iE2, IntPoint2D& intPoint ); bool intersectEdgeEdge( int iE1, int iE2, IntPoint2D& intPoint );
bool isPointInTriangle( const gp_XYZ& p, const std::vector< SMESH_NodeXYZ >& nodes ); bool isPointInTriangle( const gp_XYZ& p, const std::vector< SMESH_NodeXYZ >& nodes );
void intersectNewEdges( const CutFace& theCFace );
const SMDS_MeshNode* createNode( const gp_XYZ& p ); const SMDS_MeshNode* createNode( const gp_XYZ& p );
}; };
@ -1662,7 +1658,7 @@ namespace SMESH_MeshAlgos
*/ */
//================================================================================ //================================================================================
void Intersector::Algo::intersectNewEdges( const CutFace& cf ) void Intersector::Algo::IntersectNewEdges( const CutFace& cf )
{ {
IntPoint2D intPoint; IntPoint2D intPoint;
@ -1859,7 +1855,7 @@ namespace SMESH_MeshAlgos
} }
} }
if ( cf.myLinks.size() >= limit ) if ( cf.myLinks.size() >= limit )
throw SALOME_Exception( "Infinite loop in Intersector::Algo::intersectNewEdges()" ); throw SALOME_Exception( "Infinite loop in Intersector::Algo::IntersectNewEdges()" );
} }
++i1; // each internal edge encounters twice ++i1; // each internal edge encounters twice
} }
@ -1913,7 +1909,7 @@ namespace SMESH_MeshAlgos
{ {
const CutFace& cf = *cutFacesIt; const CutFace& cf = *cutFacesIt;
cf.ReplaceNodes( myRemove2KeepNodes ); cf.ReplaceNodes( myRemove2KeepNodes );
intersectNewEdges( cf ); IntersectNewEdges( cf );
} }
// make new faces // make new faces
@ -1948,7 +1944,7 @@ namespace SMESH_MeshAlgos
// avoid loops that are not connected to boundary edges of cf.myInitFace // avoid loops that are not connected to boundary edges of cf.myInitFace
if ( cf.RemoveInternalLoops( loopSet )) if ( cf.RemoveInternalLoops( loopSet ))
{ {
intersectNewEdges( cf ); IntersectNewEdges( cf );
cf.MakeLoops( loopSet, normal ); cf.MakeLoops( loopSet, normal );
} }
// erase loops that are cut off by face intersections // erase loops that are cut off by face intersections
@ -2228,6 +2224,10 @@ namespace SMESH_MeshAlgos
theNewFaceConnectivity.push_back( facePoints ); theNewFaceConnectivity.push_back( facePoints );
break; break;
} }
// intersect cut lines
algo.IntersectNewEdges( cf );
// form loops of new faces // form loops of new faces
EdgeLoopSet loopSet; EdgeLoopSet loopSet;
cf.MakeLoops( loopSet, normals[ faceToCut->GetID() ]); cf.MakeLoops( loopSet, normals[ faceToCut->GetID() ]);
@ -2392,6 +2392,7 @@ namespace
// myLinks[ i ].myFace = cutterFace; // myLinks[ i ].myFace = cutterFace;
// else // else
myLinks[ i ].ReplaceCoplanar( newEdge ); myLinks[ i ].ReplaceCoplanar( newEdge );
if ( myLinks[i].IsInternal() && i+1 < myLinks.size() )
myLinks[ i+1 ].ReplaceCoplanar( newEdge ); myLinks[ i+1 ].ReplaceCoplanar( newEdge );
return; return;
} }

View File

@ -42,8 +42,6 @@
#include <Utils_SALOME_Exception.hxx> #include <Utils_SALOME_Exception.hxx>
#include <boost/container/flat_set.hpp>
namespace namespace
{ {
typedef SMESH_MeshAlgos::Edge TEdge; typedef SMESH_MeshAlgos::Edge TEdge;
@ -55,19 +53,50 @@ namespace
SMESH_NodeXYZ myNode; // point and a node SMESH_NodeXYZ myNode; // point and a node
int myEdgeIndex; // face edge index int myEdgeIndex; // face edge index
bool myIsOutPln[2]; // isOut of two planes bool myIsOutPln[2]; // isOut of two planes
double SquareDistance( const IntPoint& p ) const { return ( myNode-p.myNode ).SquareModulus(); }
};
//================================================================================
//! cut of a face
struct Cut
{
IntPoint myIntPnt1, myIntPnt2;
const SMDS_MeshElement* myFace;
const IntPoint& operator[]( size_t i ) const { return i ? myIntPnt2 : myIntPnt1; }
double SquareDistance( const gp_Pnt& p, gp_XYZ & pClosest ) const
{
gp_Vec edge( myIntPnt1.myNode, myIntPnt2.myNode );
gp_Vec n1p ( myIntPnt1.myNode, p );
double u = ( edge * n1p ) / edge.SquareMagnitude(); // param [0,1] on the edge
if ( u <= 0. )
{
pClosest = myIntPnt1.myNode;
return n1p.SquareMagnitude();
}
if ( u >= 1. )
{
pClosest = myIntPnt2.myNode;
return p.SquareDistance( myIntPnt2.myNode );
}
pClosest = myIntPnt1.myNode + u * edge.XYZ(); // projection of the point on the edge
return p.SquareDistance( pClosest );
}
}; };
//================================================================================ //================================================================================
//! poly-line segment //! poly-line segment
struct Segment struct Segment
{ {
typedef boost::container::flat_set< const SMDS_MeshNode* > TNodeSet; typedef std::vector< Cut > TCutList;
//typedef std::list< TEdge > TEdgeList;
const SMDS_MeshElement* myEdge; const SMDS_MeshElement* myEdge;
TNodeSet myEndNodes; // ends of cut edges TCutList myCuts;
//TEdgeList myCutEdges[2]; std::vector< const IntPoint* > myFreeEnds; // ends of cut edges
Segment( const SMDS_MeshElement* e = 0 ): myEdge(e) { myCuts.reserve( 4 ); }
// return its axis // return its axis
gp_Ax1 Ax1( bool reversed = false ) const gp_Ax1 Ax1( bool reversed = false ) const
@ -76,67 +105,100 @@ namespace
SMESH_NodeXYZ n2 = myEdge->GetNode( !reversed ); SMESH_NodeXYZ n2 = myEdge->GetNode( !reversed );
return gp_Ax1( n1, gp_Dir( n2 - n1 )); return gp_Ax1( n1, gp_Dir( n2 - n1 ));
} }
// return a node // return a node
const SMDS_MeshNode* Node(int i) const const SMDS_MeshNode* Node(int i) const
{ {
return myEdge->GetNode( i % 2 ); return myEdge->GetNode( i % 2 );
} }
// store an intersection edge forming the slot border // store an intersection edge forming the slot border
void AddEdge( TEdge& e, double tol ) void AddCutEdge( const IntPoint& p1,
const IntPoint& p2,
const SMDS_MeshElement* myFace )
{ {
const SMDS_MeshNode** nodes = & e._node1; myCuts.push_back( Cut({ p1, p2, myFace }));
for ( int i = 0; i < 2; ++i ) }
// return number of not shared IntPoint's
int NbFreeEnds( double tol )
{ {
std::pair< TNodeSet::iterator, bool > nItAdded = myEndNodes.insert( nodes[ i ]); if ( myCuts.empty() )
if ( !nItAdded.second ) return 0;
myEndNodes.erase( nItAdded.first ); if ( myFreeEnds.empty() )
{
int nbShared = 0;
std::vector< bool > isSharedPnt( myCuts.size() * 2, false );
for ( size_t iC1 = 0; iC1 < myCuts.size() - 1; ++iC1 )
for ( size_t iP1 = 0; iP1 < 2; ++iP1 )
{
size_t i1 = iC1 * 2 + iP1;
if ( isSharedPnt[ i1 ])
continue;
for ( size_t iC2 = iC1 + 1; iC2 < myCuts.size(); ++iC2 )
for ( size_t iP2 = 0; iP2 < 2; ++iP2 )
{
size_t i2 = iC2 * 2 + iP2;
if ( isSharedPnt[ i2 ])
continue;
if ( myCuts[ iC1 ][ iP1 ].SquareDistance( myCuts[ iC2 ][ iP2 ]) < tol * tol )
{
nbShared += 2;
isSharedPnt[ i1 ] = isSharedPnt[ i2 ] = true;
} }
} }
// { -- PREV version }
// int i = myCutEdges[0].empty() ? 0 : 1; myFreeEnds.reserve( isSharedPnt.size() - nbShared );
// std::insert_iterator< TEdgeList > where = inserter( myCutEdges[i], myCutEdges[i].begin() ); for ( size_t i = 0; i < isSharedPnt.size(); ++i )
if ( !isSharedPnt[ i ] )
// //double minDist = 1e100; {
// SMESH_NodeXYZ nNew[2] = { e._node1, e._node2 }; int iP = i % 2;
// int iNewMin = 0, iCurMin = 1; int iC = i / 2;
// for ( i = 0; i < 2; ++i ) myFreeEnds.push_back( & myCuts[ iC ][ iP ]);
// { }
// if ( myCutEdges[i].empty() ) }
// continue; return myFreeEnds.size();
// SMESH_NodeXYZ nCur[2] = { myCutEdges[i].front()._node1, }
// myCutEdges[i].back()._node2 };
// for ( int iN = 0; iN < 2; ++iN )
// for ( int iC = 0; iC < 2; ++iC )
// {
// if (( nCur[iC].Node() && nCur[iC] == nNew[iN] ) ||
// ( nCur[iC] - nNew[iN] ).SquareModulus() < tol * tol )
// {
// where = inserter( myCutEdges[i], iC ? myCutEdges[i].end() : myCutEdges[i].begin() );
// iNewMin = iN;
// iCurMin = iC;
// //minDist = dist;
// iN = 2;
// break;
// }
// }
// }
// if ( iNewMin == iCurMin )
// std::swap( e._node1, e._node2 );
// where = e;
// }
Segment( const SMDS_MeshElement* e = 0 ): myEdge(e) { myEndNodes.reserve( 4 ); }
}; };
typedef ObjectPoolIterator<Segment> TSegmentIterator; typedef ObjectPoolIterator<Segment> TSegmentIterator;
//================================================================================
//! Segments and plane separating domains of segments, at common node
struct NodeData
{
std::vector< Segment* > mySegments;
gp_Ax1 myPlane; // oriented OK for mySegments[0]
void AddSegment( Segment* seg, const SMDS_MeshNode* n )
{
mySegments.reserve(2);
mySegments.push_back( seg );
if ( mySegments.size() == 1 )
{
myPlane = mySegments[0]->Ax1( mySegments[0]->myEdge->GetNodeIndex( n ));
}
else
{
gp_Ax1 axis2 = mySegments[1]->Ax1( mySegments[1]->myEdge->GetNodeIndex( n ));
myPlane.SetDirection( myPlane.Direction().XYZ() - axis2.Direction().XYZ() );
}
}
gp_Ax1 Plane( const Segment* seg )
{
return ( seg == mySegments[0] ) ? myPlane : myPlane.Reversed();
}
};
typedef NCollection_DataMap< const SMDS_MeshNode*, NodeData, SMESH_Hasher > TSegmentsOfNode;
//================================================================================ //================================================================================
/*! /*!
* \brief Intersect a face edge given by its nodes with a cylinder. * \brief Intersect a face edge given by its nodes with a cylinder.
*/ */
//================================================================================ //================================================================================
void intersectEdge( const gp_Cylinder& cyl, bool intersectEdge( const gp_Cylinder& cyl,
const SMESH_NodeXYZ& n1, const SMESH_NodeXYZ& n1,
const SMESH_NodeXYZ& n2, const SMESH_NodeXYZ& n2,
const double tol, const double tol,
@ -149,7 +211,7 @@ namespace
intersection.IsParallel() || intersection.IsParallel() ||
intersection.IsInQuadric() || intersection.IsInQuadric() ||
intersection.NbPoints() == 0 ) intersection.NbPoints() == 0 )
return; return false;
gp_Vec edge( n1, n2 ); gp_Vec edge( n1, n2 );
@ -196,7 +258,7 @@ namespace
std::swap( intPoints[ i ], intPoints[ i - 1 ]); std::swap( intPoints[ i ], intPoints[ i - 1 ]);
} }
return; return intPoints.size() - oldNbPnts > 0;
} }
//================================================================================ //================================================================================
@ -218,11 +280,11 @@ namespace
*/ */
//================================================================================ //================================================================================
bool isOut( const gp_Pnt& p, const gp_Ax1* planeNormal, bool* isOutPtr ) bool isOut( const gp_Pnt& p, const gp_Ax1* planeNormal, bool* isOutPtr, int nbPln = 2 )
{ {
isOutPtr[0] = isOutPtr[1] = false; isOutPtr[0] = isOutPtr[1] = false;
for ( int i = 0; i < 2; ++i ) for ( int i = 0; i < nbPln; ++i )
{ {
isOutPtr[i] = ( signedDist( p, planeNormal[i] ) <= 0. ); isOutPtr[i] = ( signedDist( p, planeNormal[i] ) <= 0. );
} }
@ -317,6 +379,131 @@ namespace
if ( !theWorkGroups.empty() ) if ( !theWorkGroups.empty() )
theFaceID2Groups.Bind( theFace->GetID(), theWorkGroups ); theFaceID2Groups.Bind( theFace->GetID(), theWorkGroups );
} }
//================================================================================
/*!
* \brief Check distance between a point and an edge defined by a couple of nodes
*/
//================================================================================
bool isOnEdge( const SMDS_MeshNode* n1,
const SMDS_MeshNode* n2,
const gp_Pnt& p,
const double tol )
{
SMDS_LinearEdge edge( n1, n2 );
return ( SMESH_MeshAlgos::GetDistance( &edge, p ) < tol );
}
//================================================================================
/*!
* \return Index of intersection point detected on a triangle cut by planes
* \param [in] i - index of a cut triangle side
* \param [in] n1 - 1st point of a cut triangle side
* \param [in] n2 - 2nd point of a cut triangle side
* \param [in] face - a not cut triangle
* \param [in] intPoint - the intersection point
* \param [in] faceNodes - nodes of not cut triangle
* \param [in] tol - tolerance
*/
//================================================================================
int edgeIndex( const int i,
const SMESH_NodeXYZ& n1,
const SMESH_NodeXYZ& n2,
const SMDS_MeshElement* face,
const IntPoint& intPoint,
const std::vector< const SMDS_MeshNode* >& faceNodes,
const double tol )
{
if ( n1.Node() && n2.Node() )
return face->GetNodeIndex( n1.Node() );
// project intPoint to sides of face
for ( size_t i = 1; i < faceNodes.size(); ++i )
if ( isOnEdge( faceNodes[ i-1 ], faceNodes[ i ], intPoint.myNode, tol ))
return i - 1;
return -(i+1);
}
//================================================================================
/*!
* \brief Find a neighboring segment and its next node
* \param [in] curSegment - a current segment
* \param [in,out] curNode - a current node to update
* \param [in] segmentsOfNode - map of segments of nodes
* \return Segment* - the found segment
*/
//================================================================================
Segment* nextSegment( const Segment* curSegment,
const SMDS_MeshNode* & curNode,
const TSegmentsOfNode& segmentsOfNode )
{
Segment* neighborSeg = 0;
const NodeData& noData = segmentsOfNode( curNode );
for ( size_t iS = 0; iS < noData.mySegments.size() && !neighborSeg; ++iS )
if ( noData.mySegments[ iS ] != curSegment )
neighborSeg = noData.mySegments[ iS ];
if ( neighborSeg )
{
int iN = ( neighborSeg->Node(0) == curNode );
curNode = neighborSeg->Node( iN );
}
return neighborSeg;
}
//================================================================================
/*!
* \brief Tries to find a segment to which a given point is too close
* \param [in] p - the point
* \param [in] minDist - minimal allowed distance from segment
* \param [in] curSegment - start segment
* \param [in] curNode - start node
* \param [in] segmentsOfNode - map of segments of nodes
* \return bool - true if a too close segment found
*/
//================================================================================
const Segment* findTooCloseSegment( const IntPoint& p,
const double minDist,
const double tol,
const Segment* curSegment,
const SMDS_MeshNode* curNode,
const TSegmentsOfNode& segmentsOfNode )
{
double prevDist = Precision::Infinite();
while ( curSegment )
{
double dist = SMESH_MeshAlgos::GetDistance( curSegment->myEdge, p.myNode );
if ( dist < minDist )
{
// check if dist is less than distance of curSegment to its cuts
// double minCutDist = prevDist;
// bool coincide = false;
// for ( size_t iC = 0; iC < curSegment->myCuts.size(); ++iC )
// {
// if (( coincide = ( curSegment->myCuts[iC].SquareDistance( p.myNode ) < tol * tol )))
// break;
// for ( size_t iP = 0; iP < 2; ++iP )
// {
// double cutDist = SMESH_MeshAlgos::GetDistance( curSegment->myEdge,
// curSegment->myCuts[iC][iP].myNode );
// minCutDist = std::min( minCutDist, cutDist );
// }
// }
// if ( !coincide && minCutDist > dist )
return curSegment;
}
if ( dist > prevDist )
break;
prevDist = dist;
curSegment = nextSegment( curSegment, curNode, segmentsOfNode );
}
return 0;
}
} }
//================================================================================ //================================================================================
@ -338,10 +525,10 @@ SMESH_MeshAlgos::MakeSlot( SMDS_ElemIteratorPtr theSegmentIt,
if ( !theSegmentIt || !theSegmentIt->more() || !theMesh || theWidth == 0.) if ( !theSegmentIt || !theSegmentIt->more() || !theMesh || theWidth == 0.)
return bndEdges; return bndEdges;
// ----------------------------------------------------------------------------------
// put the input segments to a data map in order to be able finding neighboring ones // put the input segments to a data map in order to be able finding neighboring ones
// ----------------------------------------------------------------------------------
typedef std::vector< Segment* > TSegmentVec;
typedef NCollection_DataMap< const SMDS_MeshNode*, TSegmentVec, SMESH_Hasher > TSegmentsOfNode;
TSegmentsOfNode segmentsOfNode; TSegmentsOfNode segmentsOfNode;
ObjectPool< Segment > segmentPool; ObjectPool< Segment > segmentPool;
@ -357,15 +544,16 @@ SMESH_MeshAlgos::MakeSlot( SMDS_ElemIteratorPtr theSegmentIt,
for ( SMDS_NodeIteratorPtr nIt = edge->nodeIterator(); nIt->more(); ) for ( SMDS_NodeIteratorPtr nIt = edge->nodeIterator(); nIt->more(); )
{ {
const SMDS_MeshNode* n = nIt->next(); const SMDS_MeshNode* n = nIt->next();
TSegmentVec* segVec = segmentsOfNode.ChangeSeek( n ); NodeData* noData = segmentsOfNode.ChangeSeek( n );
if ( !segVec ) if ( !noData )
segVec = segmentsOfNode.Bound( n, TSegmentVec() ); noData = segmentsOfNode.Bound( n, NodeData() );
segVec->reserve(2); noData->AddSegment( segment, n );
segVec->push_back( segment );
} }
} }
// ---------------------------------
// Cut the mesh around the segments // Cut the mesh around the segments
// ---------------------------------
const double tol = Precision::Confusion(); const double tol = Precision::Confusion();
std::vector< gp_XYZ > faceNormals; std::vector< gp_XYZ > faceNormals;
@ -398,21 +586,8 @@ SMESH_MeshAlgos::MakeSlot( SMDS_ElemIteratorPtr theSegmentIt,
// get normals of planes separating domains of neighboring segments // get normals of planes separating domains of neighboring segments
for ( int i = 0; i < 2; ++i ) // loop on 2 segment ends for ( int i = 0; i < 2; ++i ) // loop on 2 segment ends
{ {
planeNormal[i] = segment->Ax1(i);
const SMDS_MeshNode* n = segment->Node( i ); const SMDS_MeshNode* n = segment->Node( i );
const TSegmentVec& segVec = segmentsOfNode( n ); planeNormal[i] = segmentsOfNode( n ).Plane( segment );
for ( size_t iS = 0; iS < segVec.size(); ++iS )
{
if ( segVec[iS] == segment )
continue;
gp_Ax1 axis2 = segVec[iS]->Ax1();
if ( n != segVec[iS]->Node( 1 ))
axis2.Reverse(); // along a wire
planeNormal[i].SetDirection( planeNormal[i].Direction().XYZ() + axis2.Direction().XYZ() );
}
} }
// we explore faces around a segment starting from face edges; // we explore faces around a segment starting from face edges;
@ -455,9 +630,10 @@ SMESH_MeshAlgos::MakeSlot( SMDS_ElemIteratorPtr theSegmentIt,
int nbNodes = face->NbCornerNodes(); int nbNodes = face->NbCornerNodes();
if ( nbNodes != 3 ) if ( nbNodes != 3 )
throw SALOME_Exception( "MakeSlot() accepts triangles only" ); throw SALOME_Exception( "MakeSlot() accepts triangles only" );
facePoints.assign( face->begin_nodes(), face->end_nodes() ); faceNodes.assign( face->begin_nodes(), face->end_nodes() );
facePoints.resize( nbNodes + 1 ); faceNodes.resize( nbNodes + 1 );
facePoints[ nbNodes ] = facePoints[ 0 ]; faceNodes[ nbNodes ] = faceNodes[ 0 ];
facePoints.assign( faceNodes.begin(), faceNodes.end() );
// check if cylinder axis || face // check if cylinder axis || face
const gp_XYZ& faceNorm = computeNormal( face, faceNormals ); const gp_XYZ& faceNorm = computeNormal( face, faceNormals );
@ -489,22 +665,18 @@ SMESH_MeshAlgos::MakeSlot( SMDS_ElemIteratorPtr theSegmentIt,
intPoints[ iP ].myEdgeIndex = i; intPoints[ iP ].myEdgeIndex = i;
else else
for ( ; iP < intPoints.size(); ++iP ) for ( ; iP < intPoints.size(); ++iP )
if ( n1.Node() && n2.Node() ) intPoints[ iP ].myEdgeIndex = edgeIndex( i, n1, n2, face,
intPoints[ iP ].myEdgeIndex = face->GetNodeIndex( n1.Node() ); intPoints[ iP ], faceNodes, tol );
else
intPoints[ iP ].myEdgeIndex = -(i+1);
nbFarPoints += ( segLine.SquareDistance( n1 ) > radius2 ); nbFarPoints += ( segLine.SquareDistance( n1 ) > radius2 );
} }
// feed startEdges // feed startEdges
if ( nbFarPoints < nbPoints || !intPoints.empty() ) if ( nbFarPoints < nbPoints || !intPoints.empty() )
for ( int i = 0; i < nbPoints; ++i ) for ( size_t i = 1; i < faceNodes.size(); ++i )
{
const SMESH_NodeXYZ& n1 = facePoints[i];
const SMESH_NodeXYZ& n2 = facePoints[i+1];
if ( n1.Node() && n2.Node() )
{ {
const SMESH_NodeXYZ& n1 = faceNodes[i];
const SMESH_NodeXYZ& n2 = faceNodes[i-1];
isOut( n1, planeNormal, p[0].myIsOutPln ); isOut( n1, planeNormal, p[0].myIsOutPln );
isOut( n2, planeNormal, p[1].myIsOutPln ); isOut( n2, planeNormal, p[1].myIsOutPln );
if ( !isSegmentOut( p[0].myIsOutPln, p[1].myIsOutPln )) if ( !isSegmentOut( p[0].myIsOutPln, p[1].myIsOutPln ))
@ -512,7 +684,6 @@ SMESH_MeshAlgos::MakeSlot( SMDS_ElemIteratorPtr theSegmentIt,
startEdges.push_back( NLink( n1.Node(), n2.Node() )); startEdges.push_back( NLink( n1.Node(), n2.Node() ));
} }
} }
}
if ( intPoints.size() < 2 ) if ( intPoints.size() < 2 )
continue; continue;
@ -570,20 +741,12 @@ SMESH_MeshAlgos::MakeSlot( SMDS_ElemIteratorPtr theSegmentIt,
cutOff( intPoints[iE-1], intPoints[iE], cutOff( intPoints[iE-1], intPoints[iE],
planeNormal[ intPoints[iE-1].myIsOutPln[1] ], tol ); planeNormal[ intPoints[iE-1].myIsOutPln[1] ], tol );
edegDir = intPoints[iE].myNode - intPoints[iE-1].myNode; gp_XYZ edegDirNew = intPoints[iE].myNode - intPoints[iE-1].myNode;
if ( edegDir.SquareModulus() < tol * tol ) if ( edegDir * edegDirNew < 0 ||
edegDir.SquareModulus() < tol * tol )
continue; // fully cut off continue; // fully cut off
// face cut segment->AddCutEdge( intPoints[iE], intPoints[iE-1], face );
meshIntersector.Cut( face,
intPoints[iE-1].myNode, intPoints[iE-1].myEdgeIndex,
intPoints[iE ].myNode, intPoints[iE ].myEdgeIndex );
Edge e = { intPoints[iE].myNode.Node(), intPoints[iE-1].myNode.Node(), 0 };
segment->AddEdge( e, tol );
bndEdges.push_back( e );
findGroups( face, theGroupsToUpdate, faceID2Groups, groupVec );
} }
} // loop on faces sharing an edge } // loop on faces sharing an edge
@ -595,63 +758,151 @@ SMESH_MeshAlgos::MakeSlot( SMDS_ElemIteratorPtr theSegmentIt,
} // loop on all input segments } // loop on all input segments
// ----------------------------------------------------------
// If a plane fully cuts off edges of one side of a segment,
// it also may cut edges of adjacent segments
// ----------------------------------------------------------
for ( TSegmentIterator segIt( segmentPool ); segIt.more(); ) // loop on all segments
{
Segment* segment = const_cast< Segment* >( segIt.next() );
if ( segment->NbFreeEnds( tol ) >= 4 )
continue;
for ( int iE = 0; iE < 2; ++iE ) // loop on 2 segment ends
{
const SMDS_MeshNode* n1 = segment->Node( iE );
const SMDS_MeshNode* n2 = segment->Node( 1 - iE );
planeNormal[0] = segmentsOfNode( n1 ).Plane( segment );
bool isNeighborCut;
Segment* neighborSeg = segment;
do // check segments connected to the segment via n2
{
neighborSeg = nextSegment( neighborSeg, n2, segmentsOfNode );
if ( !neighborSeg )
break;
isNeighborCut = false;
for ( size_t iC = 0; iC < neighborSeg->myCuts.size(); ++iC ) // check cut edges
{
IntPoint* intPnt = &( neighborSeg->myCuts[iC].myIntPnt1 );
isOut( intPnt[0].myNode, planeNormal, intPnt[0].myIsOutPln, 1 );
isOut( intPnt[1].myNode, planeNormal, intPnt[1].myIsOutPln, 1 );
const Segment * closeSeg[2] = { 0, 0 };
if ( intPnt[0].myIsOutPln[0] )
closeSeg[0] = findTooCloseSegment( intPnt[0], 0.5 * theWidth - tol, tol,
segment, n1, segmentsOfNode );
if ( intPnt[1].myIsOutPln[0] )
closeSeg[1] = findTooCloseSegment( intPnt[1], 0.5 * theWidth - tol, tol,
segment, n1, segmentsOfNode );
int nbCut = bool( closeSeg[0] ) + bool( closeSeg[1] );
if ( nbCut == 0 )
continue;
isNeighborCut = true;
if ( nbCut == 2 ) // remove a cut
{
if ( iC < neighborSeg->myCuts.size() - 1 )
neighborSeg->myCuts[iC] = neighborSeg->myCuts.back();
neighborSeg->myCuts.pop_back();
}
else // shorten cuts of 1) neighborSeg and 2) closeSeg
{
// 1)
int iP = bool( closeSeg[1] );
gp_Lin segLine( closeSeg[iP]->Ax1() );
gp_Ax3 cylAxis( segLine.Location(), segLine.Direction() );
gp_Cylinder cyl( cylAxis, 0.5 * theWidth );
intPoints.clear();
if ( intersectEdge( cyl, intPnt[iP].myNode, intPnt[1-iP].myNode, tol, intPoints ) &&
intPoints[0].SquareDistance( intPnt[iP] ) > tol * tol )
intPnt[iP].myNode = intPoints[0].myNode;
// 2)
double minCutDist = theWidth;
gp_XYZ projection, closestProj;
int iCut;
for ( size_t iC = 0; iC < closeSeg[iP]->myCuts.size(); ++iC )
{
double cutDist = closeSeg[iP]->myCuts[iC].SquareDistance( intPnt[iP].myNode,
projection );
if ( cutDist < minCutDist )
{
closestProj = projection;
minCutDist = cutDist;
iCut = iC;
}
if ( minCutDist < tol * tol )
break;
}
double d1 = SMESH_MeshAlgos::GetDistance( neighborSeg->myEdge,
closeSeg[iP]->myCuts[iCut][0].myNode );
double d2 = SMESH_MeshAlgos::GetDistance( neighborSeg->myEdge,
closeSeg[iP]->myCuts[iCut][1].myNode );
int iP2 = ( d2 < d1 );
IntPoint& ip = const_cast< IntPoint& >( closeSeg[iP]->myCuts[iCut][iP2] );
ip = intPnt[iP];
}
// update myFreeEnds
neighborSeg->myFreeEnds.clear();
neighborSeg->NbFreeEnds( tol );
}
}
while ( isNeighborCut );
}
}
// -----------------------
// Cut faces by cut edges
// -----------------------
for ( TSegmentIterator segIt( segmentPool ); segIt.more(); ) // loop on all segments
{
Segment* segment = const_cast< Segment* >( segIt.next() );
for ( size_t iC = 0; iC < segment->myCuts.size(); ++iC )
{
Cut & cut = segment->myCuts[ iC ];
computeNormal( cut.myFace, faceNormals );
meshIntersector.Cut( cut.myFace,
cut.myIntPnt1.myNode, cut.myIntPnt1.myEdgeIndex,
cut.myIntPnt2.myNode, cut.myIntPnt2.myEdgeIndex );
Edge e = { cut.myIntPnt1.myNode.Node(), cut.myIntPnt2.myNode.Node(), 0 };
bndEdges.push_back( e );
findGroups( cut.myFace, theGroupsToUpdate, faceID2Groups, groupVec );
}
}
// -----------------------------------------
// Make cut at the end of group of segments // Make cut at the end of group of segments
// -----------------------------------------
std::vector<const SMDS_MeshElement*> polySegments; std::vector<const SMDS_MeshElement*> polySegments;
for ( TSegmentsOfNode::Iterator nSegsIt( segmentsOfNode ); nSegsIt.More(); nSegsIt.Next() ) for ( TSegmentsOfNode::Iterator nSegsIt( segmentsOfNode ); nSegsIt.More(); nSegsIt.Next() )
{ {
const TSegmentVec& segVec = nSegsIt.Value(); const NodeData& noData = nSegsIt.Value();
if ( segVec.size() != 1 ) if ( noData.mySegments.size() != 1 )
continue; continue;
const Segment* segment = segVec[0]; const Segment* segment = noData.mySegments[0];
const SMDS_MeshNode* segNode = nSegsIt.Key();
// find two end nodes of cut edges to make a cut between // find two IntPoint's of cut edges to make a cut between
if ( segment->myEndNodes.size() != 4 ) if ( segment->myFreeEnds.size() != 4 )
throw SALOME_Exception( "MakeSlot(): too short end edge?" ); throw SALOME_Exception( "MakeSlot(): too short end edge?" );
std::multimap< double, const IntPoint* > dist2IntPntMap;
for ( size_t iE = 0; iE < segment->myFreeEnds.size(); ++iE )
{
const SMESH_NodeXYZ& n = segment->myFreeEnds[ iE ]->myNode;
double d = Abs( signedDist( n, noData.myPlane ));
dist2IntPntMap.insert( std::make_pair( d, segment->myFreeEnds[ iE ]));
}
std::multimap< double, const IntPoint* >::iterator d2ip = dist2IntPntMap.begin();
SMESH_MeshAlgos::PolySegment linkNodes; SMESH_MeshAlgos::PolySegment linkNodes;
gp_Ax1 planeNorm = segment->Ax1( segNode != segment->Node(0) ); linkNodes.myXYZ[0] = d2ip->second->myNode;
double minDist[2] = { 1e100, 1e100 }; linkNodes.myXYZ[1] = (++d2ip)->second->myNode;
Segment::TNodeSet::const_iterator nIt = segment->myEndNodes.begin(); linkNodes.myVector = noData.myPlane.Direction() ^ (linkNodes.myXYZ[0] - linkNodes.myXYZ[1]);
for ( ; nIt != segment->myEndNodes.end(); ++nIt )
{
SMESH_NodeXYZ n = *nIt;
double d = Abs( signedDist( n, planeNorm ));
double diff1 = minDist[0] - d, diff2 = minDist[1] - d;
int i;
if ( diff1 > 0 && diff2 > 0 )
{
i = ( diff1 < diff2 );
}
else if ( diff1 > 0 )
{
i = 0;
}
else if ( diff2 > 0 )
{
i = 1;
}
else
{
continue;
}
linkNodes.myXYZ[ i ] = n;
minDist [ i ] = d;
}
// for ( int iSide = 0; iSide < 2; ++iSide )
// {
// if ( segment->myCutEdges[ iSide ].empty() )
// throw SALOME_Exception( "MakeSlot(): too short end edge?" );
// SMESH_NodeXYZ n1 = segment->myCutEdges[ iSide ].front()._node1;
// SMESH_NodeXYZ n2 = segment->myCutEdges[ iSide ].back ()._node2;
// double d1 = Abs( signedDist( n1, planeNorm ));
// double d2 = Abs( signedDist( n2, planeNorm ));
// linkNodes.myXYZ [ iSide ] = ( d1 < d2 ) ? n1 : n2;
// linkNodes.myNode1[ iSide ] = linkNodes.myNode2[ iSide ] = 0;
// }
linkNodes.myVector = planeNorm.Direction() ^ (linkNodes.myXYZ[0] - linkNodes.myXYZ[1]);
linkNodes.myNode1[ 0 ] = linkNodes.myNode2[ 0 ] = 0; linkNodes.myNode1[ 0 ] = linkNodes.myNode2[ 0 ] = 0;
linkNodes.myNode1[ 1 ] = linkNodes.myNode2[ 1 ] = 0; linkNodes.myNode1[ 1 ] = linkNodes.myNode2[ 1 ] = 0;
@ -682,8 +933,7 @@ SMESH_MeshAlgos::MakeSlot( SMDS_ElemIteratorPtr theSegmentIt,
intPoints[iP].myEdgeIndex = -1; intPoints[iP].myEdgeIndex = -1;
for ( int iN = 0; iN < nbNodes && intPoints[iP].myEdgeIndex < 0; ++iN ) for ( int iN = 0; iN < nbNodes && intPoints[iP].myEdgeIndex < 0; ++iN )
{ {
SMDS_LinearEdge edge( faceNodes[iN], faceNodes[iN+1] ); if ( isOnEdge( faceNodes[iN], faceNodes[iN+1], intPoints[iP].myNode, tol ))
if ( SMESH_MeshAlgos::GetDistance( &edge, intPoints[iP].myNode) < tol )
intPoints[iP].myEdgeIndex = iN; intPoints[iP].myEdgeIndex = iN;
} }
} }

View File

@ -3453,7 +3453,7 @@ namespace // utils for CopyMeshWithGeom()
* \param [out] invalidEntries - return study entries of objects whose * \param [out] invalidEntries - return study entries of objects whose
* counterparts are not found in the newGeometry, followed by entries * counterparts are not found in the newGeometry, followed by entries
* of mesh sub-objects that are invalid because they depend on a not found * of mesh sub-objects that are invalid because they depend on a not found
* preceeding sub-shape * preceding sub-shape
* \return CORBA::Boolean - is a success * \return CORBA::Boolean - is a success
*/ */
//================================================================================ //================================================================================

View File

@ -1104,6 +1104,10 @@ void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
if ( !aGroup ) if ( !aGroup )
return; return;
if ( aGroup->GetMeshServant() != this )
THROW_SALOME_CORBA_EXCEPTION( "RemoveGroup(): group does not belong to this mesh",
SALOME::BAD_PARAM );
SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup ); SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
if ( !aGroupSO->_is_nil() ) if ( !aGroupSO->_is_nil() )
{ {
@ -1138,6 +1142,11 @@ void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup
if ( theGroup->_is_nil() ) if ( theGroup->_is_nil() )
return; return;
SMESH_GroupBase_i* groupImpl = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup );
if ( !groupImpl || groupImpl->GetMeshServant() != this )
THROW_SALOME_CORBA_EXCEPTION( "RemoveGroupWithContents(): group does not belong to this mesh",
SALOME::BAD_PARAM);
vector<int> nodeIds; // to remove nodes becoming free vector<int> nodeIds; // to remove nodes becoming free
bool isNodal = ( theGroup->GetType() == SMESH::NODE ); bool isNodal = ( theGroup->GetType() == SMESH::NODE );
if ( !isNodal && !theGroup->IsEmpty() ) if ( !isNodal && !theGroup->IsEmpty() )

View File

@ -603,7 +603,7 @@ SMESH_Invalid_subMesh_i::SMESH_Invalid_subMesh_i( PortableServer::POA_ptr thePOA
//======================================================================= //=======================================================================
//function : GetSubShape //function : GetSubShape
//purpose : return geomtry which is not a sub-shape of the main shape //purpose : return geometry which is not a sub-shape of the main shape
//======================================================================= //=======================================================================
GEOM::GEOM_Object_ptr SMESH_Invalid_subMesh_i::GetSubShape() GEOM::GEOM_Object_ptr SMESH_Invalid_subMesh_i::GetSubShape()

View File

@ -34,7 +34,7 @@ import SMESH, SALOMEDS
from salome.smesh import smeshBuilder from salome.smesh import smeshBuilder
smesh = smeshBuilder.New() smesh = smeshBuilder.New()
# ---- define a boxe # ---- define a box
box = geompy.MakeBox(0., 0., 0., 100., 200., 300.) box = geompy.MakeBox(0., 0., 0., 100., 200., 300.)
@ -52,7 +52,7 @@ print("number of Edges in box : ", len(subEdgeList))
### ---------------------------- SMESH -------------------------------------- ### ---------------------------- SMESH --------------------------------------
# ---- init a Mesh with the boxe # ---- init a Mesh with the box
mesh = smesh.Mesh(box, "MeshBox") mesh = smesh.Mesh(box, "MeshBox")
@ -90,7 +90,7 @@ print(hypVolume.GetId())
print(hypVolume.GetMaxElementVolume()) print(hypVolume.GetMaxElementVolume())
smesh.SetName(hypVolume, "MaxElementVolume_" + str(maxElementVolume)) smesh.SetName(hypVolume, "MaxElementVolume_" + str(maxElementVolume))
print("-------------------------- compute the mesh of the boxe") print("-------------------------- compute the mesh of the box")
ret = mesh.Compute() ret = mesh.Compute()
print(ret) print(ret)
if ret != 0: if ret != 0:

View File

@ -812,7 +812,7 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
Parameters: Parameters:
sourceMesh: the mesh to copy definition of. sourceMesh: the mesh to copy definition of.
newGeom: the new geomtry. newGeom: the new geometry.
meshName: an optional name of the new mesh. If omitted, the mesh name is kept. meshName: an optional name of the new mesh. If omitted, the mesh name is kept.
toCopyGroups: to create groups in the new mesh. toCopyGroups: to create groups in the new mesh.
toReuseHypotheses: to reuse hypotheses of the *sourceMesh*. toReuseHypotheses: to reuse hypotheses of the *sourceMesh*.
@ -823,7 +823,7 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
*invalidEntries* are study entries of objects whose *invalidEntries* are study entries of objects whose
counterparts are not found in the *newGeom*, followed by entries counterparts are not found in the *newGeom*, followed by entries
of mesh sub-objects that are invalid because they depend on a not found of mesh sub-objects that are invalid because they depend on a not found
preceeding sub-shape preceding sub-shape
""" """
if isinstance( sourceMesh, Mesh ): if isinstance( sourceMesh, Mesh ):
sourceMesh = sourceMesh.GetMesh() sourceMesh = sourceMesh.GetMesh()
@ -6419,7 +6419,7 @@ class Mesh(metaclass = MeshMeta):
holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes) holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
if not isinstance( holeNodes, SMESH.FreeBorder ): if not isinstance( holeNodes, SMESH.FreeBorder ):
raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes) raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
self.editor.FillHole( holeNodes, groupName ) return self.editor.FillHole( holeNodes, groupName )
def FindCoincidentFreeBorders (self, tolerance=0.): def FindCoincidentFreeBorders (self, tolerance=0.):
""" """

View File

@ -3989,10 +3989,10 @@ bool StdMeshers_PrismAsBlock::GetLayersTransformation(vector<gp_Trsf> &
//================================================================================ //================================================================================
/*! /*!
* \brief Check curve orientation of a bootom edge * \brief Check curve orientation of a bottom edge
* \param meshDS - mesh DS * \param meshDS - mesh DS
* \param columnsMap - node columns map of side face * \param columnsMap - node columns map of side face
* \param bottomEdge - the bootom edge * \param bottomEdge - the bottom edge
* \param sideFaceID - side face in-block ID * \param sideFaceID - side face in-block ID
* \retval bool - true if orientation coincide with in-block forward orientation * \retval bool - true if orientation coincide with in-block forward orientation
*/ */

View File

@ -245,10 +245,10 @@ class STDMESHERS_EXPORT StdMeshers_PrismAsBlock: public SMESH_Block
{ return myShapeIDMap.FindIndex( shape ); } { return myShapeIDMap.FindIndex( shape ); }
/*! /*!
* \brief Check curve orientation of a bootom edge * \brief Check curve orientation of a bottom edge
* \param meshDS - mesh DS * \param meshDS - mesh DS
* \param columnsMap - node columns map of side face * \param columnsMap - node columns map of side face
* \param bottomEdge - the bootom edge * \param bottomEdge - the bottom edge
* \param sideFaceID - side face in-block ID * \param sideFaceID - side face in-block ID
* \retval bool - true if orientation coincide with in-block forward orientation * \retval bool - true if orientation coincide with in-block forward orientation
*/ */

View File

@ -1591,7 +1591,7 @@ namespace VISCOUS_3D
//================================================================================ //================================================================================
/*! /*!
* \brief Computes mimimal distance of face in-FACE nodes from an EDGE * \brief Computes minimal distance of face in-FACE nodes from an EDGE
* \param [in] face - the mesh face to treat * \param [in] face - the mesh face to treat
* \param [in] nodeOnEdge - a node on the EDGE * \param [in] nodeOnEdge - a node on the EDGE
* \param [out] faceSize - the computed distance * \param [out] faceSize - the computed distance
@ -4091,7 +4091,7 @@ gp_XYZ _OffsetPlane::GetCommonPoint(bool& isFound,
//================================================================================ //================================================================================
/*! /*!
* \brief Find 2 neigbor nodes of a node on EDGE * \brief Find 2 neighbor nodes of a node on EDGE
*/ */
//================================================================================ //================================================================================
@ -4136,7 +4136,7 @@ bool _ViscousBuilder::findNeiborsOnEdge(const _LayerEdge* edge,
//================================================================================ //================================================================================
/*! /*!
* \brief Set _curvature and _2neibors->_plnNorm by 2 neigbor nodes residing the same EDGE * \brief Set _curvature and _2neibors->_plnNorm by 2 neighbor nodes residing the same EDGE
*/ */
//================================================================================ //================================================================================