mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-01-18 14:10:34 +05:00
0021543: EDF 1978 SMESH: Viscous layer for 2D meshes
debug on a complex sketch
This commit is contained in:
parent
f0bf265fc0
commit
fb0d4ffa39
@ -53,6 +53,8 @@
|
||||
#include <Bnd_B3d.hxx>
|
||||
#include <ElCLib.hxx>
|
||||
#include <GCPnts_AbscissaPoint.hxx>
|
||||
#include <Geom2dAdaptor_Curve.hxx>
|
||||
#include <Geom2dInt_GInter.hxx>
|
||||
#include <Geom2d_Circle.hxx>
|
||||
#include <Geom2d_Line.hxx>
|
||||
#include <Geom2d_TrimmedCurve.hxx>
|
||||
@ -61,6 +63,7 @@
|
||||
#include <Geom_Curve.hxx>
|
||||
#include <Geom_Line.hxx>
|
||||
#include <Geom_TrimmedCurve.hxx>
|
||||
#include <IntRes2d_IntersectionPoint.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <Standard_ErrorHandler.hxx>
|
||||
#include <TColStd_Array1OfReal.hxx>
|
||||
@ -258,9 +261,16 @@ namespace VISCOUS_2D
|
||||
typedef vector< _LayerEdge >::iterator TEdgeIterator;
|
||||
|
||||
bool IsCommonEdgeShared( const _PolyLine& other );
|
||||
size_t FirstLEdge() const { return _leftLine->_advancable ? 1 : 0; }
|
||||
bool IsAdjacent( const _Segment& seg ) const
|
||||
size_t FirstLEdge() const
|
||||
{
|
||||
return ( _leftLine->_advancable && _lEdges.size() > 2 ) ? 1 : 0;
|
||||
}
|
||||
bool IsAdjacent( const _Segment& seg, const _LayerEdge* LE=0 ) const
|
||||
{
|
||||
if ( LE && seg._indexInLine < _lEdges.size() &&
|
||||
( seg._uv[0] == & LE->_uvIn ||
|
||||
seg._uv[1] == & LE->_uvIn ))
|
||||
return true;
|
||||
return ( & seg == &_leftLine->_segments.back() ||
|
||||
& seg == &_rightLine->_segments[0] );
|
||||
}
|
||||
@ -421,6 +431,7 @@ StdMeshers_ViscousLayers2D::Compute(SMESH_Mesh& theMesh,
|
||||
theMesh.GetSubMesh( theFace )->GetComputeError() = error;
|
||||
else if ( !pm )
|
||||
pm.reset( new SMESH_ProxyMesh( theMesh ));
|
||||
//pm.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -710,8 +721,8 @@ bool _ViscousBuilder2D::makePolyLines()
|
||||
L._segTree.reset( new _SegmentTree( L._segments ));
|
||||
}
|
||||
|
||||
// Evaluate possible _thickness if required layers thickness seems too high
|
||||
// -------------------------------------------------------------------------
|
||||
// Evaluate max possible _thickness if required layers thickness seems too high
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
_thickness = _hyp->GetTotalThickness();
|
||||
_SegmentTree::box_type faceBndBox2D;
|
||||
@ -726,9 +737,12 @@ bool _ViscousBuilder2D::makePolyLines()
|
||||
for ( size_t iL1 = 0; iL1 < _polyLineVec.size(); ++iL1 )
|
||||
{
|
||||
_PolyLine& L1 = _polyLineVec[ iL1 ];
|
||||
const _SegmentTree::box_type* boxL1 = L1._segTree->getBox();
|
||||
for ( size_t iL2 = iL1+1; iL2 < _polyLineVec.size(); ++iL2 )
|
||||
{
|
||||
_PolyLine& L2 = _polyLineVec[ iL2 ];
|
||||
if ( boxL1->IsOut( *L2._segTree->getBox() ))
|
||||
continue;
|
||||
for ( size_t iLE = 1; iLE < L1._lEdges.size(); ++iLE )
|
||||
{
|
||||
foundSegs.clear();
|
||||
@ -790,16 +804,16 @@ bool _ViscousBuilder2D::makePolyLines()
|
||||
{
|
||||
lineBoxes[ iPoLine ] = *_polyLineVec[ iPoLine ]._segTree->getBox();
|
||||
if ( _polyLineVec[ iPoLine ]._advancable )
|
||||
lineBoxes[ iPoLine ].Enlarge( maxLen2dTo3dRatio * _thickness );
|
||||
lineBoxes[ iPoLine ].Enlarge( maxLen2dTo3dRatio * _thickness * 2 );
|
||||
}
|
||||
// _reachableLines
|
||||
for ( iPoLine = 0; iPoLine < _polyLineVec.size(); ++iPoLine )
|
||||
{
|
||||
_PolyLine& L1 = _polyLineVec[ iPoLine ];
|
||||
for ( size_t i = 0; i < _polyLineVec.size(); ++i )
|
||||
for ( size_t iL2 = 0; iL2 < _polyLineVec.size(); ++iL2 )
|
||||
{
|
||||
_PolyLine& L2 = _polyLineVec[ i ];
|
||||
if ( iPoLine == i || lineBoxes[ iPoLine ].IsOut( lineBoxes[ i ]))
|
||||
_PolyLine& L2 = _polyLineVec[ iL2 ];
|
||||
if ( iPoLine == iL2 || lineBoxes[ iPoLine ].IsOut( lineBoxes[ iL2 ]))
|
||||
continue;
|
||||
if ( !L1._advancable && ( L1._leftLine == &L2 || L1._rightLine == &L2 ))
|
||||
continue;
|
||||
@ -808,10 +822,8 @@ bool _ViscousBuilder2D::makePolyLines()
|
||||
for ( size_t iLE = 1; iLE < L1._lEdges.size(); iLE += iDelta )
|
||||
{
|
||||
_LayerEdge& LE = L1._lEdges[iLE];
|
||||
if ( !lineBoxes[ i ].IsOut ( LE._uvOut,
|
||||
LE._uvOut + LE._normal2D * _thickness * LE._len2dTo3dRatio )
|
||||
&&
|
||||
!L1.IsAdjacent( L2._segments[0] ))
|
||||
if ( !lineBoxes[ iL2 ].IsOut ( LE._uvOut,
|
||||
LE._uvOut + LE._normal2D *_thickness * LE._len2dTo3dRatio ))
|
||||
{
|
||||
L1._reachableLines.push_back( & L2 );
|
||||
break;
|
||||
@ -849,14 +861,17 @@ void _ViscousBuilder2D::adjustCommonEdge( _PolyLine& LL, _PolyLine& LR )
|
||||
gp_XY normL = EL._normal2D;
|
||||
gp_XY normR = ER._normal2D;
|
||||
gp_XY tangL ( normL.Y(), -normL.X() );
|
||||
//gp_XY tangR ( normR.Y(), -normR.X() );
|
||||
|
||||
gp_XY normCommon = ( normL + normR ).Normalized(); // average normal at VERTEX
|
||||
|
||||
// set common direction to a VERTEX _LayerEdge shared by two _PolyLine's
|
||||
gp_XY normCommon = ( normL * int( LL._advancable ) +
|
||||
normR * int( LR._advancable )).Normalized();
|
||||
EL._normal2D = normCommon;
|
||||
EL._ray.SetLocation ( EL._uvOut );
|
||||
EL._ray.SetDirection( EL._normal2D );
|
||||
|
||||
if ( nbAdvancableL == 1 ) {
|
||||
EL._isBlocked = true;
|
||||
EL._length2D = 0;
|
||||
}
|
||||
// update _LayerEdge::_len2dTo3dRatio according to a new direction
|
||||
const vector<UVPtStruct>& points = LL._wire->GetUVPtStruct();
|
||||
setLenRatio( EL, SMESH_TNodeXYZ( points[ LL._lastPntInd ].node ));
|
||||
@ -865,48 +880,85 @@ void _ViscousBuilder2D::adjustCommonEdge( _PolyLine& LL, _PolyLine& LR )
|
||||
|
||||
const double dotNormTang = normR * tangL;
|
||||
const bool largeAngle = Abs( dotNormTang ) > 0.2;
|
||||
if ( largeAngle )
|
||||
if ( largeAngle ) // not 180 degrees
|
||||
{
|
||||
// recompute _len2dTo3dRatio to take into account angle between EDGEs
|
||||
gp_Vec2d oldNorm( LL._advancable ? normL : normR );
|
||||
double fact = 1. / Max( 0.3, Cos( oldNorm.Angle( normCommon )));
|
||||
EL._len2dTo3dRatio *= fact;
|
||||
double angleFactor = 1. / Max( 0.3, Cos( oldNorm.Angle( normCommon )));
|
||||
EL._len2dTo3dRatio *= angleFactor;
|
||||
ER._len2dTo3dRatio = EL._len2dTo3dRatio;
|
||||
|
||||
gp_XY normAvg = ( normL + normR ).Normalized(); // average normal at VERTEX
|
||||
|
||||
if ( dotNormTang < 0. ) // ---------------------------- CONVEX ANGLE
|
||||
{
|
||||
// Remove _LayerEdge's intersecting the normCommon
|
||||
// Remove _LayerEdge's intersecting the normAvg to avoid collisions
|
||||
// during inflate().
|
||||
//
|
||||
// find max length of the VERTEX based _LayerEdge whose direction is normAvg
|
||||
double maxLen2D = _thickness * EL._len2dTo3dRatio;
|
||||
const gp_XY& pCommOut = ER._uvOut;
|
||||
gp_XY pCommIn( pCommOut + normCommon * _thickness * EL._len2dTo3dRatio );
|
||||
gp_XY pCommIn = pCommOut + normAvg * maxLen2D;
|
||||
_Segment segCommon( pCommOut, pCommIn );
|
||||
_SegmentIntersection intersection;
|
||||
vector< const _Segment* > foundSegs;
|
||||
for ( size_t iL1 = 0; iL1 < _polyLineVec.size(); ++iL1 )
|
||||
{
|
||||
_PolyLine& L1 = _polyLineVec[ iL1 ];
|
||||
const _SegmentTree::box_type* boxL1 = L1._segTree->getBox();
|
||||
if ( boxL1->IsOut ( pCommOut, pCommIn ))
|
||||
continue;
|
||||
for ( size_t iLE = 1; iLE < L1._lEdges.size(); ++iLE )
|
||||
{
|
||||
foundSegs.clear();
|
||||
L1._segTree->GetSegmentsNear( segCommon, foundSegs );
|
||||
for ( size_t i = 0; i < foundSegs.size(); ++i )
|
||||
if ( intersection.Compute( *foundSegs[i], segCommon ) &&
|
||||
intersection._param2 > 1e-10 )
|
||||
{
|
||||
double len2D = intersection._param2 * maxLen2D / ( 2 + L1._advancable );
|
||||
if ( len2D < maxLen2D ) {
|
||||
maxLen2D = len2D;
|
||||
pCommIn = pCommOut + normAvg * maxLen2D; // here length of segCommon changes
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove _LayerEdge's intersecting segCommon
|
||||
for ( int isR = 0; isR < 2; ++isR ) // loop on [ LL, LR ]
|
||||
{
|
||||
_PolyLine& L = isR ? LR : LL;
|
||||
_PolyLine::TEdgeIterator eIt = isR ? L._lEdges.begin()+1 : L._lEdges.end()-2;
|
||||
int dIt = isR ? +1 : -1;
|
||||
// at least 2 _LayerEdge's should remain in a _PolyLine (if _advancable)
|
||||
if ( L._lEdges.size() < 3 ) continue;
|
||||
if ( nbAdvancableL == 1 && L._advancable && normL * normR > -0.01 )
|
||||
continue; // obtuse internal angle
|
||||
// at least 3 _LayerEdge's should remain in a _PolyLine
|
||||
if ( L._lEdges.size() < 4 ) continue;
|
||||
size_t iLE = 1;
|
||||
_SegmentIntersection lastIntersection;
|
||||
for ( ; iLE < L._lEdges.size(); ++iLE, eIt += dIt )
|
||||
{
|
||||
gp_XY uvIn = eIt->_uvOut + eIt->_normal2D * _thickness * eIt->_len2dTo3dRatio;
|
||||
_Segment segOfEdge( eIt->_uvOut, uvIn );
|
||||
if ( !intersection.Compute( segCommon, segOfEdge ))
|
||||
break;
|
||||
lastIntersection._param1 = intersection._param1;
|
||||
lastIntersection._param2 = intersection._param2;
|
||||
}
|
||||
if ( iLE >= L._lEdges.size () - 1 )
|
||||
{
|
||||
// all _LayerEdge's intersect the segCommon, limit inflation
|
||||
// of remaining 2 _LayerEdge's
|
||||
vector< _LayerEdge > newEdgeVec( 2 );
|
||||
vector< _LayerEdge > newEdgeVec( Min( 3, L._lEdges.size() ));
|
||||
newEdgeVec.front() = L._lEdges.front();
|
||||
newEdgeVec.back() = L._lEdges.back();
|
||||
if ( newEdgeVec.size() == 3 )
|
||||
newEdgeVec[1] = L._lEdges[ L._lEdges.size() / 2 ];
|
||||
L._lEdges.swap( newEdgeVec );
|
||||
if ( !isR ) std::swap( intersection._param1 , intersection._param2 );
|
||||
L._lEdges.front()._len2dTo3dRatio *= intersection._param1;
|
||||
L._lEdges.back ()._len2dTo3dRatio *= intersection._param2;
|
||||
if ( !isR ) std::swap( lastIntersection._param1 , lastIntersection._param2 );
|
||||
L._lEdges.front()._len2dTo3dRatio *= lastIntersection._param1; // ??
|
||||
L._lEdges.back ()._len2dTo3dRatio *= lastIntersection._param2;
|
||||
}
|
||||
else if ( iLE != 1 )
|
||||
{
|
||||
@ -924,7 +976,11 @@ void _ViscousBuilder2D::adjustCommonEdge( _PolyLine& LL, _PolyLine& LR )
|
||||
{
|
||||
// make that the _LayerEdge at VERTEX is not shared by LL and LR
|
||||
_LayerEdge& notSharedEdge = LL._advancable ? LR._lEdges[0] : LL._lEdges.back();
|
||||
_LayerEdge& sharedEdge = LR._advancable ? LR._lEdges[0] : LL._lEdges.back();
|
||||
|
||||
notSharedEdge._normal2D.SetCoord( 0.,0. );
|
||||
sharedEdge._normal2D = normAvg;
|
||||
sharedEdge._isBlocked = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -973,7 +1029,7 @@ bool _ViscousBuilder2D::inflate()
|
||||
foundSegs.clear();
|
||||
L2._segTree->GetSegmentsNear( L1._lEdges[iLE]._ray, foundSegs );
|
||||
for ( size_t i = 0; i < foundSegs.size(); ++i )
|
||||
if ( ! L1.IsAdjacent( *foundSegs[i] ) &&
|
||||
if ( ! L1.IsAdjacent( *foundSegs[i], & L1._lEdges[iLE] ) &&
|
||||
intersection.Compute( *foundSegs[i], L1._lEdges[iLE]._ray ))
|
||||
{
|
||||
double distToL2 = intersection._param2 / L1._lEdges[iLE]._len2dTo3dRatio;
|
||||
@ -1049,6 +1105,7 @@ bool _ViscousBuilder2D::fixCollisions()
|
||||
_SegmentIntersection intersection;
|
||||
|
||||
list< pair< _LayerEdge*, double > > edgeLenLimitList;
|
||||
list< _LayerEdge* > blockedEdgesList;
|
||||
|
||||
for ( size_t iL1 = 0; iL1 < _polyLineVec.size(); ++iL1 )
|
||||
{
|
||||
@ -1057,16 +1114,15 @@ bool _ViscousBuilder2D::fixCollisions()
|
||||
for ( size_t iL2 = 0; iL2 < L1._reachableLines.size(); ++iL2 )
|
||||
{
|
||||
_PolyLine& L2 = * L1._reachableLines[ iL2 ];
|
||||
//for ( size_t iLE = L1.FirstLEdge(); iLE < L1._lEdges.size(); ++iLE )
|
||||
for ( size_t iLE = 1; iLE < L1._lEdges.size()-1; ++iLE )
|
||||
for ( size_t iLE = L1.FirstLEdge(); iLE < L1._lEdges.size(); ++iLE )
|
||||
{
|
||||
_LayerEdge& LE1 = L1._lEdges[iLE];
|
||||
if ( LE1._isBlocked ) continue;
|
||||
//if ( LE1._isBlocked ) continue;
|
||||
foundSegs.clear();
|
||||
L2._segTree->GetSegmentsNear( LE1._ray, foundSegs );
|
||||
for ( size_t i = 0; i < foundSegs.size(); ++i )
|
||||
{
|
||||
if ( ! L1.IsAdjacent( *foundSegs[i] ) &&
|
||||
if ( ! L1.IsAdjacent( *foundSegs[i], &LE1 ) &&
|
||||
intersection.Compute( *foundSegs[i], LE1._ray ))
|
||||
{
|
||||
const double dist2DToL2 = intersection._param2;
|
||||
@ -1075,11 +1131,12 @@ bool _ViscousBuilder2D::fixCollisions()
|
||||
{
|
||||
if ( newLen2D < LE1._length2D )
|
||||
{
|
||||
blockedEdgesList.push_back( &LE1 );
|
||||
if ( L1._advancable )
|
||||
{
|
||||
edgeLenLimitList.push_back( make_pair( &LE1, newLen2D ));
|
||||
L2._lEdges[ foundSegs[i]->_indexInLine ]._isBlocked = true;
|
||||
L2._lEdges[ foundSegs[i]->_indexInLine + 1 ]._isBlocked = true;
|
||||
blockedEdgesList.push_back( &L2._lEdges[ foundSegs[i]->_indexInLine ]);
|
||||
blockedEdgesList.push_back( &L2._lEdges[ foundSegs[i]->_indexInLine + 1 ]);
|
||||
}
|
||||
else // here dist2DToL2 < 0 and LE1._length2D == 0
|
||||
{
|
||||
@ -1091,21 +1148,9 @@ bool _ViscousBuilder2D::fixCollisions()
|
||||
|
||||
edgeLenLimitList.push_back( make_pair( &LE2[0], newLen2D ));
|
||||
edgeLenLimitList.push_back( make_pair( &LE2[1], newLen2D ));
|
||||
LE2[0]._isBlocked = true;
|
||||
LE2[1]._isBlocked = true;
|
||||
}
|
||||
}
|
||||
LE1._isBlocked = true; // !! after SetNewLength()
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// double step2D = newLen2D - LE1._length2D;
|
||||
// double step = step2D / LE1._len2dTo3dRatio;
|
||||
// if ( step > maxStep )
|
||||
// maxStep = step;
|
||||
// if ( step < minStep )
|
||||
// minStep = step;
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1118,8 +1163,15 @@ bool _ViscousBuilder2D::fixCollisions()
|
||||
{
|
||||
_LayerEdge* LE = edge2Len->first;
|
||||
LE->SetNewLength( edge2Len->second / LE->_len2dTo3dRatio );
|
||||
LE->_isBlocked = true;
|
||||
}
|
||||
|
||||
// block inflation of _LayerEdge's
|
||||
list< _LayerEdge* >::iterator edge = blockedEdgesList.begin();
|
||||
for ( ; edge != blockedEdgesList.end(); ++edge )
|
||||
(*edge)->_isBlocked = true;
|
||||
|
||||
// find a not blocked _LayerEdge
|
||||
for ( size_t iL = 0; iL < _polyLineVec.size(); ++iL )
|
||||
{
|
||||
_PolyLine& L = _polyLineVec[ iL ];
|
||||
@ -1150,7 +1202,8 @@ bool _ViscousBuilder2D::shrink()
|
||||
_PolyLine& L = _polyLineVec[ iL1 ]; // line with no layers
|
||||
if ( L._advancable )
|
||||
continue;
|
||||
if ( !L._rightLine->_advancable && !L._leftLine->_advancable )
|
||||
const int nbAdvancable = ( L._rightLine->_advancable + L._leftLine->_advancable );
|
||||
if ( nbAdvancable == 0 )
|
||||
continue;
|
||||
|
||||
const TopoDS_Edge& E = L._wire->Edge ( L._edgeInd );
|
||||
@ -1275,47 +1328,62 @@ bool _ViscousBuilder2D::shrink()
|
||||
double u0 = isR ? ul : uf; // init value of the param to move
|
||||
int iPEnd = isR ? nodeDataVec.size() - 1 : 0;
|
||||
|
||||
_LayerEdge& nearLE = isR ? L._lEdges.back() : L._lEdges.front();
|
||||
_LayerEdge& farLE = isR ? L._lEdges.front() : L._lEdges.back();
|
||||
|
||||
// try to find length of advancement along L by intersecting L with
|
||||
// an adjacent _Segment of L2
|
||||
|
||||
double & length2D = ( isR ? L._lEdges.back() : L._lEdges.front() )._length2D;
|
||||
double & length2D = nearLE._length2D;
|
||||
sign = ( isR ^ edgeReversed ) ? -1. : 1.;
|
||||
pcurve->D1( u, uv, tangent );
|
||||
|
||||
if ( L2->_advancable )
|
||||
{
|
||||
gp_Ax2d edgeRay( uv, tangent * sign );
|
||||
const _Segment& seg2( isR ? L2->_segments.front() : L2->_segments.back() );
|
||||
// make an elongated seg2
|
||||
gp_XY seg2Vec( seg2.p2() - seg2.p1() );
|
||||
gp_XY longSeg2p1 = seg2.p1() - 1000 * seg2Vec;
|
||||
gp_XY longSeg2p2 = seg2.p2() + 1000 * seg2Vec;
|
||||
_Segment longSeg2( longSeg2p1, longSeg2p2 );
|
||||
if ( intersection.Compute( longSeg2, edgeRay )) { // convex VERTEX
|
||||
int iFSeg2 = isR ? 0 : L2->_segments.size() - 1;
|
||||
int iLSeg2 = isR ? 1 : L2->_segments.size() - 2;
|
||||
gp_XY uvLSeg2In = L2->_lEdges[ iLSeg2 ]._uvIn;
|
||||
gp_XY uvLSeg2Out = L2->_lEdges[ iLSeg2 ]._uvOut;
|
||||
gp_XY uvFSeg2Out = L2->_lEdges[ iFSeg2 ]._uvOut;
|
||||
Handle(Geom2d_Line) seg2Line = new Geom2d_Line( uvLSeg2In, uvFSeg2Out - uvLSeg2Out );
|
||||
|
||||
length2D = intersection._param2; /* |L seg2
|
||||
* | o---o---
|
||||
* | / |
|
||||
* |/ | L2
|
||||
* x------x--- */
|
||||
Geom2dAdaptor_Curve edgeCurve( pcurve, Min( uf, ul ), Max( uf, ul ));
|
||||
Geom2dAdaptor_Curve seg2Curve( seg2Line );
|
||||
Geom2dInt_GInter curveInt( edgeCurve, seg2Curve, 1e-7, 1e-7 );
|
||||
double maxDist2d = 2 * L2->_lEdges[ iLSeg2 ]._length2D;
|
||||
if ( curveInt.IsDone() &&
|
||||
!curveInt.IsEmpty() &&
|
||||
curveInt.Point( 1 ).Value().Distance( uvFSeg2Out ) <= maxDist2d )
|
||||
{ /* convex VERTEX */
|
||||
u = curveInt.Point( 1 ).ParamOnFirst(); /* |L seg2
|
||||
* | o---o---
|
||||
* | / |
|
||||
* |/ | L2
|
||||
* x------x--- */
|
||||
}
|
||||
else { /* concave VERTEX */ /* o-----o---
|
||||
* \ |
|
||||
* \ | L2
|
||||
* x--x---
|
||||
* /
|
||||
* L / */
|
||||
length2D = ( isR ? L2->_lEdges.front() : L2->_lEdges.back() )._length2D;
|
||||
else { /* concave VERTEX */ /* o-----o---
|
||||
* \ |
|
||||
* \ | L2
|
||||
* x--x---
|
||||
* /
|
||||
* L / */
|
||||
length2D = sign * L2->_lEdges[ iFSeg2 ]._length2D;
|
||||
}
|
||||
}
|
||||
else // L2 is advancable but in the face adjacent by L
|
||||
{
|
||||
length2D = ( isR ? L._lEdges.front() : L._lEdges.back() )._length2D;
|
||||
length2D = farLE._length2D;
|
||||
if ( length2D == 0 )
|
||||
length2D = ( isR ? L._leftLine->_lEdges.back() : L._rightLine->_lEdges.front() )._length2D;
|
||||
}
|
||||
// move u to the internal boundary of layers
|
||||
u += length2D * sign;
|
||||
if ( length2D > 0 ) {
|
||||
// move u to the internal boundary of layers
|
||||
double maxLen3D = Min( _thickness, edgeLen / ( 1 + nbAdvancable ));
|
||||
double maxLen2D = maxLen3D * nearLE._len2dTo3dRatio;
|
||||
if ( length2D > maxLen2D )
|
||||
length2D = maxLen2D;
|
||||
u += length2D * sign;
|
||||
}
|
||||
nodeDataVec[ iPEnd ].param = u;
|
||||
|
||||
gp_Pnt2d newUV = pcurve->Value( u );
|
||||
@ -1510,7 +1578,7 @@ bool _ViscousBuilder2D::refine()
|
||||
|
||||
//if ( L._leftLine->_advancable ) L._lEdges[0] = L._leftLine->_lEdges.back();
|
||||
|
||||
// calculate intermediate UV on _LayerEdge's ( _LayerEdge::_uvRefined )
|
||||
// replace an inactive _LayerEdge with an active one of a neighbour _PolyLine
|
||||
size_t iLE = 0, nbLE = L._lEdges.size();
|
||||
if ( /*!L._leftLine->_advancable &&*/ L.IsCommonEdgeShared( *L._leftLine ))
|
||||
{
|
||||
@ -1522,6 +1590,34 @@ bool _ViscousBuilder2D::refine()
|
||||
L._lEdges.back() = L._rightLine->_lEdges[0];
|
||||
--nbLE;
|
||||
}
|
||||
|
||||
// remove intersecting _LayerEdge's
|
||||
_SegmentIntersection intersection;
|
||||
for ( int isR = 0; ( isR < 2 && L._lEdges.size() > 2 ); ++isR )
|
||||
{
|
||||
int nbRemove = 0, deltaIt = isR ? -1 : +1;
|
||||
_PolyLine::TEdgeIterator eIt = isR ? L._lEdges.end()-1 : L._lEdges.begin();
|
||||
// HEURISTICS !!! elongate the first _LayerEdge
|
||||
gp_XY newIn = eIt->_uvOut + eIt->_normal2D * eIt->_length2D/* * 2*/;
|
||||
_Segment seg1( eIt->_uvOut, newIn );
|
||||
for ( eIt += deltaIt; nbRemove < L._lEdges.size()-2; eIt += deltaIt )
|
||||
{
|
||||
_Segment seg2( eIt->_uvOut, eIt->_uvIn );
|
||||
if ( !intersection.Compute( seg1, seg2 ))
|
||||
break;
|
||||
++nbRemove;
|
||||
}
|
||||
if ( nbRemove > 0 ) {
|
||||
if ( isR )
|
||||
L._lEdges.erase( L._lEdges.end()-nbRemove-1,
|
||||
L._lEdges.end()-nbRemove );
|
||||
else
|
||||
L._lEdges.erase( L._lEdges.begin()+2,
|
||||
L._lEdges.begin()+2+nbRemove );
|
||||
}
|
||||
}
|
||||
|
||||
// calculate intermediate UV on _LayerEdge's ( _LayerEdge::_uvRefined )
|
||||
for ( ; iLE < nbLE; ++iLE )
|
||||
{
|
||||
_LayerEdge& LE = L._lEdges[iLE];
|
||||
|
Loading…
Reference in New Issue
Block a user