0020974: Extra edges appear in the result of a partition and can't be removed

3D soomthing replaced by a real fix: take into account face orientation
This commit is contained in:
eap 2011-05-18 12:27:16 +00:00
parent fae1b077cf
commit 25145129e9

View File

@ -42,12 +42,11 @@
#include "SMDS_FacePosition.hxx" #include "SMDS_FacePosition.hxx"
#include <BRep_Tool.hxx> #include <BRep_Tool.hxx>
#include <GeomAPI_ProjectPointOnSurf.hxx>
#include <Geom_Surface.hxx> #include <Geom_Surface.hxx>
#include <NCollection_DefineArray2.hxx> #include <NCollection_DefineArray2.hxx>
#include <Precision.hxx> #include <Precision.hxx>
#include <TColStd_SequenceOfInteger.hxx>
#include <TColStd_SequenceOfReal.hxx> #include <TColStd_SequenceOfReal.hxx>
#include <TColStd_SequenceOfInteger.hxx>
#include <TColgp_SequenceOfXY.hxx> #include <TColgp_SequenceOfXY.hxx>
#include <TopExp.hxx> #include <TopExp.hxx>
#include <TopExp_Explorer.hxx> #include <TopExp_Explorer.hxx>
@ -3790,7 +3789,7 @@ namespace // data for smoothing
TSmoothNode* _n2; TSmoothNode* _n2;
TTriangle( TSmoothNode* n1=0, TSmoothNode* n2=0 ): _n1(n1), _n2(n2) {} TTriangle( TSmoothNode* n1=0, TSmoothNode* n2=0 ): _n1(n1), _n2(n2) {}
inline bool IsForward( gp_UV uv ); inline bool IsForward( gp_UV uv ) const;
}; };
// -------------------------------------------------------------------------------- // --------------------------------------------------------------------------------
/*! /*!
@ -3798,12 +3797,11 @@ namespace // data for smoothing
*/ */
struct TSmoothNode struct TSmoothNode
{ {
gp_XY _uv; gp_XY _uv;
gp_XYZ _xyz;
vector< TTriangle > _triangles; // if empty, then node is not movable vector< TTriangle > _triangles; // if empty, then node is not movable
}; };
// -------------------------------------------------------------------------------- // --------------------------------------------------------------------------------
inline bool TTriangle::IsForward( gp_UV uv ) inline bool TTriangle::IsForward( gp_UV uv ) const
{ {
gp_Vec2d v1( uv, _n1->_uv ), v2( uv, _n2->_uv ); gp_Vec2d v1( uv, _n1->_uv ), v2( uv, _n2->_uv );
double d = v1 ^ v2; double d = v1 ^ v2;
@ -3882,7 +3880,6 @@ void StdMeshers_Quadrangle_2D::Smooth (FaceQuadStruct* quad)
const SMDS_MeshNode* node = nIt->next(); const SMDS_MeshNode* node = nIt->next();
TSmoothNode & sNode = smooNoMap[ node ]; TSmoothNode & sNode = smooNoMap[ node ];
sNode._uv = myHelper->GetNodeUV( geomFace, node ); sNode._uv = myHelper->GetNodeUV( geomFace, node );
sNode._xyz = SMESH_TNodeXYZ( node );
// set sNode._triangles // set sNode._triangles
SMDS_ElemIteratorPtr fIt = node->GetInverseElementIterator( SMDSAbs_Face ); SMDS_ElemIteratorPtr fIt = node->GetInverseElementIterator( SMDSAbs_Face );
@ -3907,81 +3904,57 @@ void StdMeshers_Quadrangle_2D::Smooth (FaceQuadStruct* quad)
{ {
TSmoothNode & sNode = smooNoMap[ uvVec[j].node ]; TSmoothNode & sNode = smooNoMap[ uvVec[j].node ];
sNode._uv.SetCoord( uvVec[j].u, uvVec[j].v ); sNode._uv.SetCoord( uvVec[j].u, uvVec[j].v );
sNode._xyz = SMESH_TNodeXYZ( uvVec[j].node );
} }
} }
// Smoothing // define refernce orientation in 2D
TNo2SmooNoMap::iterator n2sn = smooNoMap.begin();
for ( ; n2sn != smooNoMap.end(); ++n2sn )
if ( !n2sn->second._triangles.empty() )
break;
if ( n2sn == smooNoMap.end() ) return;
const TSmoothNode & sampleNode = n2sn->second;
const bool refForward = ( sampleNode._triangles[0].IsForward( sampleNode._uv ));
Handle(Geom_Surface) surface = BRep_Tool::Surface( geomFace ); // Smoothing
GeomAPI_ProjectPointOnSurf surfProjection( gp_Pnt(0,0,0), surface );
for ( int iLoop = 0; iLoop < 5; ++iLoop ) for ( int iLoop = 0; iLoop < 5; ++iLoop )
{ {
TNo2SmooNoMap::iterator n2sn = smooNoMap.begin(); for ( n2sn = smooNoMap.begin(); n2sn != smooNoMap.end(); ++n2sn )
for ( ; n2sn != smooNoMap.end(); ++n2sn )
{ {
TSmoothNode& sNode = n2sn->second; TSmoothNode& sNode = n2sn->second;
if ( sNode._triangles.empty() ) if ( sNode._triangles.empty() )
continue; // not movable node continue; // not movable node
// compute a new XYZ as avarage of surrounding XYZs // compute a new UV
gp_XYZ newXYZ(0,0,0); gp_XY newUV (0,0);
for ( unsigned i = 0; i < sNode._triangles.size(); ++i ) for ( unsigned i = 0; i < sNode._triangles.size(); ++i )
newXYZ += sNode._triangles[i]._n1->_xyz; newUV += sNode._triangles[i]._n1->_uv;
newXYZ /= sNode._triangles.size(); newUV /= sNode._triangles.size();
// check validity of the newUV
bool isValid = true;
for ( unsigned i = 0; i < sNode._triangles.size() && isValid; ++i )
isValid = ( sNode._triangles[i].IsForward( newUV ) == refForward );
// compute a new UV by the new XYZ
gp_XY newUV;
surfProjection.Perform( newXYZ );
bool isValid = ( surfProjection.IsDone() && surfProjection.NbPoints() > 0 );
if ( isValid ) if ( isValid )
{ sNode._uv = newUV;
double u,v;
surfProjection.LowerDistanceParameters( u,v );
newUV.SetCoord( u,v );
// check validity of the newUV
for ( unsigned i = 0; i < sNode._triangles.size() && isValid; ++i )
isValid = sNode._triangles[i].IsForward( newUV );
}
if ( !isValid ) // smoothing in 3D fails, try in 2D
{
// compute the new UV as avarage of surrounding UVs
newUV.SetCoord (0.0, 0.0);
for ( unsigned i = 0; i < sNode._triangles.size(); ++i )
newUV += sNode._triangles[i]._n1->_uv;
newUV /= sNode._triangles.size();
// check validity of the newUV
isValid = true;
for ( unsigned i = 0; i < sNode._triangles.size() && isValid; ++i )
isValid = sNode._triangles[i].IsForward( newUV );
if ( isValid )
newXYZ = surface->Value( newUV.X(), newUV.Y() ).XYZ();
}
if ( isValid ) // store new node position
{
sNode._uv = newUV;
sNode._xyz = newXYZ;
}
} }
} }
// Set new XYZ to the smoothed nodes // Set new XYZ to the smoothed nodes
TNo2SmooNoMap::iterator n2sn = smooNoMap.begin(); Handle(Geom_Surface) surface = BRep_Tool::Surface( geomFace );
for ( ; n2sn != smooNoMap.end(); ++n2sn )
for ( n2sn = smooNoMap.begin(); n2sn != smooNoMap.end(); ++n2sn )
{ {
TSmoothNode& sNode = n2sn->second; TSmoothNode& sNode = n2sn->second;
if ( sNode._triangles.empty() ) if ( sNode._triangles.empty() )
continue; // not movable node continue; // not movable node
SMDS_MeshNode* node = const_cast< SMDS_MeshNode*>( n2sn->first ); SMDS_MeshNode* node = const_cast< SMDS_MeshNode*>( n2sn->first );
meshDS->MoveNode( node, sNode._xyz.X(), sNode._xyz.Y(), sNode._xyz.Z() ); gp_Pnt xyz = surface->Value( sNode._uv.X(), sNode._uv.Y() );
meshDS->MoveNode( node, xyz.X(), xyz.Y(), xyz.Z() );
// store the new UV // store the new UV
node->SetPosition( SMDS_PositionPtr( new SMDS_FacePosition( sNode._uv.X(), sNode._uv.Y() ))); node->SetPosition( SMDS_PositionPtr( new SMDS_FacePosition( sNode._uv.X(), sNode._uv.Y() )));