mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-01-15 06:00:34 +05:00
Fix regression SALOME_TESTS/Grids/smesh/3D_mesh_Projection_00/A1
StdMeshers_Projection_2D.cxx + fix failure of IPAL52648: Incorrect vicous layer elements
This commit is contained in:
parent
81bd7bc865
commit
1a28a08237
@ -42,7 +42,7 @@
|
|||||||
//#include <stdlib.h>
|
//#include <stdlib.h>
|
||||||
|
|
||||||
#ifdef _DEBUG_
|
#ifdef _DEBUG_
|
||||||
static int MYDEBUG = 1;
|
static int MYDEBUG = 0;
|
||||||
//#define _DEXCEPT_
|
//#define _DEXCEPT_
|
||||||
#else
|
#else
|
||||||
static int MYDEBUG = 0;
|
static int MYDEBUG = 0;
|
||||||
|
@ -1161,7 +1161,7 @@ namespace {
|
|||||||
SMESH_Mesh* srcMesh,
|
SMESH_Mesh* srcMesh,
|
||||||
TAssocTool::TShapeShapeMap & assocMap)
|
TAssocTool::TShapeShapeMap & assocMap)
|
||||||
{
|
{
|
||||||
if ( !tgtHelper.HasRealSeam() )
|
if ( !tgtHelper.HasRealSeam() || srcFace.ShapeType() != TopAbs_FACE )
|
||||||
return; // no seam edge
|
return; // no seam edge
|
||||||
list< TopoDS_Edge > tgtEdges, srcEdges;
|
list< TopoDS_Edge > tgtEdges, srcEdges;
|
||||||
list< int > tgtNbEW, srcNbEW;
|
list< int > tgtNbEW, srcNbEW;
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
#include <BRepAdaptor_Curve.hxx>
|
#include <BRepAdaptor_Curve.hxx>
|
||||||
#include <BRepAdaptor_Curve2d.hxx>
|
#include <BRepAdaptor_Curve2d.hxx>
|
||||||
#include <BRepAdaptor_Surface.hxx>
|
#include <BRepAdaptor_Surface.hxx>
|
||||||
|
//#include <BRepLProp_CLProps.hxx>
|
||||||
#include <BRepLProp_SLProps.hxx>
|
#include <BRepLProp_SLProps.hxx>
|
||||||
#include <BRepOffsetAPI_MakeOffsetShape.hxx>
|
#include <BRepOffsetAPI_MakeOffsetShape.hxx>
|
||||||
#include <BRep_Tool.hxx>
|
#include <BRep_Tool.hxx>
|
||||||
@ -1000,6 +1001,7 @@ namespace VISCOUS_3D
|
|||||||
{
|
{
|
||||||
gp_XYZ _xyz; // coord of a point inflated from EDGE w/o smooth
|
gp_XYZ _xyz; // coord of a point inflated from EDGE w/o smooth
|
||||||
double _len; // length reached at previous inflation step
|
double _len; // length reached at previous inflation step
|
||||||
|
double _param; // on EDGE
|
||||||
_2NearEdges _2edges; // 2 neighbor _LayerEdge's
|
_2NearEdges _2edges; // 2 neighbor _LayerEdge's
|
||||||
double Distance( const OffPnt& p ) const { return ( _xyz - p._xyz ).Modulus(); }
|
double Distance( const OffPnt& p ) const { return ( _xyz - p._xyz ).Modulus(); }
|
||||||
};
|
};
|
||||||
@ -1009,6 +1011,7 @@ namespace VISCOUS_3D
|
|||||||
_LayerEdge _leOnV[2]; // _LayerEdge's holding normal to the EDGE at VERTEXes
|
_LayerEdge _leOnV[2]; // _LayerEdge's holding normal to the EDGE at VERTEXes
|
||||||
size_t _iSeg[2]; // index of segment where extreme tgt node is projected
|
size_t _iSeg[2]; // index of segment where extreme tgt node is projected
|
||||||
_EdgesOnShape& _eos;
|
_EdgesOnShape& _eos;
|
||||||
|
double _curveLen; // length of the EDGE
|
||||||
|
|
||||||
static Handle(Geom_Curve) CurveForSmooth( const TopoDS_Edge& E,
|
static Handle(Geom_Curve) CurveForSmooth( const TopoDS_Edge& E,
|
||||||
_EdgesOnShape& eos,
|
_EdgesOnShape& eos,
|
||||||
@ -3880,11 +3883,11 @@ gp_XYZ _OffsetPlane::GetCommonPoint(bool& isFound) const
|
|||||||
if ( NbLines() == 2 )
|
if ( NbLines() == 2 )
|
||||||
{
|
{
|
||||||
gp_Vec lPerp0 = _lines[0].Direction().XYZ() ^ _plane.Axis().Direction().XYZ();
|
gp_Vec lPerp0 = _lines[0].Direction().XYZ() ^ _plane.Axis().Direction().XYZ();
|
||||||
gp_Vec l0l1 = _lines[1].Location().XYZ() - _lines[0].Location().XYZ();
|
|
||||||
double dot01 = lPerp0 * _lines[1].Direction().XYZ();
|
double dot01 = lPerp0 * _lines[1].Direction().XYZ();
|
||||||
if ( Abs( dot01 ) > std::numeric_limits<double>::min() )
|
if ( Abs( dot01 ) > std::numeric_limits<double>::min() )
|
||||||
{
|
{
|
||||||
double u1 = - ( lPerp0 * l0l1 ) / dot01;
|
gp_Vec l0l1 = _lines[1].Location().XYZ() - _lines[0].Location().XYZ();
|
||||||
|
double u1 = - ( lPerp0 * l0l1 ) / dot01;
|
||||||
p = ( _lines[1].Location().XYZ() + _lines[1].Direction().XYZ() * u1 );
|
p = ( _lines[1].Location().XYZ() + _lines[1].Direction().XYZ() * u1 );
|
||||||
isFound = true;
|
isFound = true;
|
||||||
}
|
}
|
||||||
@ -4417,7 +4420,7 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data,
|
|||||||
|
|
||||||
bool moved, improved;
|
bool moved, improved;
|
||||||
double vol;
|
double vol;
|
||||||
vector< _LayerEdge* > movedEdges, badSmooEdges;
|
vector< _LayerEdge* > movedEdges, badEdges;
|
||||||
vector< _EdgesOnShape* > eosC1; // C1 continues shapes
|
vector< _EdgesOnShape* > eosC1; // C1 continues shapes
|
||||||
vector< bool > isConcaveFace;
|
vector< bool > isConcaveFace;
|
||||||
|
|
||||||
@ -4520,13 +4523,13 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data,
|
|||||||
makeOffsetSurface( *eosC1[ iEOS ], helper );
|
makeOffsetSurface( *eosC1[ iEOS ], helper );
|
||||||
}
|
}
|
||||||
|
|
||||||
int step = 0, stepLimit = 5, badNb = 0;
|
int step = 0, stepLimit = 5, nbBad = 0;
|
||||||
while (( ++step <= stepLimit ) || improved )
|
while (( ++step <= stepLimit ) || improved )
|
||||||
{
|
{
|
||||||
dumpFunction(SMESH_Comment("smooth")<<data._index<<"_Fa"<<sInd
|
dumpFunction(SMESH_Comment("smooth")<<data._index<<"_Fa"<<sInd
|
||||||
<<"_InfStep"<<infStep<<"_"<<step); // debug
|
<<"_InfStep"<<infStep<<"_"<<step); // debug
|
||||||
int oldBadNb = badNb;
|
int oldBadNb = nbBad;
|
||||||
badSmooEdges.clear();
|
badEdges.clear();
|
||||||
|
|
||||||
#ifdef INCREMENTAL_SMOOTH
|
#ifdef INCREMENTAL_SMOOTH
|
||||||
bool findBest = false; // ( step == stepLimit );
|
bool findBest = false; // ( step == stepLimit );
|
||||||
@ -4534,7 +4537,7 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data,
|
|||||||
{
|
{
|
||||||
movedEdges[i]->Unset( _LayerEdge::SMOOTHED );
|
movedEdges[i]->Unset( _LayerEdge::SMOOTHED );
|
||||||
if ( movedEdges[i]->Smooth( step, findBest, movedEdges ) > 0 )
|
if ( movedEdges[i]->Smooth( step, findBest, movedEdges ) > 0 )
|
||||||
badSmooEdges.push_back( movedEdges[i] );
|
badEdges.push_back( movedEdges[i] );
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
bool findBest = ( step == stepLimit || isConcaveFace[ iEOS ]);
|
bool findBest = ( step == stepLimit || isConcaveFace[ iEOS ]);
|
||||||
@ -4545,18 +4548,18 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data,
|
|||||||
{
|
{
|
||||||
edges[i]->Unset( _LayerEdge::SMOOTHED );
|
edges[i]->Unset( _LayerEdge::SMOOTHED );
|
||||||
if ( edges[i]->Smooth( step, findBest, false ) > 0 )
|
if ( edges[i]->Smooth( step, findBest, false ) > 0 )
|
||||||
badSmooEdges.push_back( eos._edges[i] );
|
badEdges.push_back( eos._edges[i] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
badNb = badSmooEdges.size();
|
nbBad = badEdges.size();
|
||||||
|
|
||||||
if ( badNb > 0 )
|
if ( nbBad > 0 )
|
||||||
debugMsg(SMESH_Comment("badNb = ") << badNb );
|
debugMsg(SMESH_Comment("nbBad = ") << nbBad );
|
||||||
|
|
||||||
if ( !badSmooEdges.empty() && step >= stepLimit / 2 )
|
if ( !badEdges.empty() && step >= stepLimit / 2 )
|
||||||
{
|
{
|
||||||
if ( badSmooEdges[0]->Is( _LayerEdge::ON_CONCAVE_FACE ))
|
if ( badEdges[0]->Is( _LayerEdge::ON_CONCAVE_FACE ))
|
||||||
stepLimit = 9;
|
stepLimit = 9;
|
||||||
|
|
||||||
// resolve hard smoothing situation around concave VERTEXes
|
// resolve hard smoothing situation around concave VERTEXes
|
||||||
@ -4565,26 +4568,26 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data,
|
|||||||
vector< _EdgesOnShape* > & eosCoVe = eosC1[ iEOS ]->_eosConcaVer;
|
vector< _EdgesOnShape* > & eosCoVe = eosC1[ iEOS ]->_eosConcaVer;
|
||||||
for ( size_t i = 0; i < eosCoVe.size(); ++i )
|
for ( size_t i = 0; i < eosCoVe.size(); ++i )
|
||||||
eosCoVe[i]->_edges[0]->MoveNearConcaVer( eosCoVe[i], eosC1[ iEOS ],
|
eosCoVe[i]->_edges[0]->MoveNearConcaVer( eosCoVe[i], eosC1[ iEOS ],
|
||||||
step, badSmooEdges );
|
step, badEdges );
|
||||||
}
|
}
|
||||||
// look for the best smooth of _LayerEdge's neighboring badSmooEdges
|
// look for the best smooth of _LayerEdge's neighboring badEdges
|
||||||
badNb = 0;
|
nbBad = 0;
|
||||||
for ( size_t i = 0; i < badSmooEdges.size(); ++i )
|
for ( size_t i = 0; i < badEdges.size(); ++i )
|
||||||
{
|
{
|
||||||
_LayerEdge* ledge = badSmooEdges[i];
|
_LayerEdge* ledge = badEdges[i];
|
||||||
for ( size_t iN = 0; iN < ledge->_neibors.size(); ++iN )
|
for ( size_t iN = 0; iN < ledge->_neibors.size(); ++iN )
|
||||||
{
|
{
|
||||||
ledge->_neibors[iN]->Unset( _LayerEdge::SMOOTHED );
|
ledge->_neibors[iN]->Unset( _LayerEdge::SMOOTHED );
|
||||||
badNb += ledge->_neibors[iN]->Smooth( step, true, /*findBest=*/true );
|
nbBad += ledge->_neibors[iN]->Smooth( step, true, /*findBest=*/true );
|
||||||
}
|
}
|
||||||
ledge->Unset( _LayerEdge::SMOOTHED );
|
ledge->Unset( _LayerEdge::SMOOTHED );
|
||||||
badNb += ledge->Smooth( step, true, /*findBest=*/true );
|
nbBad += ledge->Smooth( step, true, /*findBest=*/true );
|
||||||
}
|
}
|
||||||
debugMsg(SMESH_Comment("badNb = ") << badNb );
|
debugMsg(SMESH_Comment("nbBad = ") << nbBad );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( badNb == oldBadNb &&
|
if ( nbBad == oldBadNb &&
|
||||||
badNb > 0 &&
|
nbBad > 0 &&
|
||||||
step < stepLimit ) // smooth w/o chech of validity
|
step < stepLimit ) // smooth w/o chech of validity
|
||||||
{
|
{
|
||||||
dumpFunctionEnd();
|
dumpFunctionEnd();
|
||||||
@ -4598,11 +4601,11 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data,
|
|||||||
stepLimit++;
|
stepLimit++;
|
||||||
}
|
}
|
||||||
|
|
||||||
improved = ( badNb < oldBadNb );
|
improved = ( nbBad < oldBadNb );
|
||||||
|
|
||||||
dumpFunctionEnd();
|
dumpFunctionEnd();
|
||||||
|
|
||||||
if (( step % 3 == 1 ) || ( badNb > 0 && step >= stepLimit / 2 ))
|
if (( step % 3 == 1 ) || ( nbBad > 0 && step >= stepLimit / 2 ))
|
||||||
for ( size_t iEOS = 0; iEOS < eosC1.size(); ++iEOS )
|
for ( size_t iEOS = 0; iEOS < eosC1.size(); ++iEOS )
|
||||||
{
|
{
|
||||||
putOnOffsetSurface( *eosC1[ iEOS ], infStep, step, /*moveAll=*/step == 1 );
|
putOnOffsetSurface( *eosC1[ iEOS ], infStep, step, /*moveAll=*/step == 1 );
|
||||||
@ -4613,13 +4616,13 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data,
|
|||||||
// project -- to prevent intersections or fix bad simplices
|
// project -- to prevent intersections or fix bad simplices
|
||||||
for ( size_t iEOS = 0; iEOS < eosC1.size(); ++iEOS )
|
for ( size_t iEOS = 0; iEOS < eosC1.size(); ++iEOS )
|
||||||
{
|
{
|
||||||
if ( ! eosC1[ iEOS ]->_eosConcaVer.empty() || badNb > 0 )
|
if ( ! eosC1[ iEOS ]->_eosConcaVer.empty() || nbBad > 0 )
|
||||||
putOnOffsetSurface( *eosC1[ iEOS ], infStep );
|
putOnOffsetSurface( *eosC1[ iEOS ], infStep );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !badSmooEdges.empty() )
|
if ( !badEdges.empty() )
|
||||||
{
|
{
|
||||||
badSmooEdges.clear();
|
badEdges.clear();
|
||||||
for ( size_t iEOS = 0; iEOS < eosC1.size(); ++iEOS )
|
for ( size_t iEOS = 0; iEOS < eosC1.size(); ++iEOS )
|
||||||
{
|
{
|
||||||
for ( size_t i = 0; i < eosC1[ iEOS ]->_edges.size(); ++i )
|
for ( size_t i = 0; i < eosC1[ iEOS ]->_edges.size(); ++i )
|
||||||
@ -4627,8 +4630,8 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data,
|
|||||||
if ( !eosC1[ iEOS ]->_sWOL.IsNull() ) continue;
|
if ( !eosC1[ iEOS ]->_sWOL.IsNull() ) continue;
|
||||||
|
|
||||||
_LayerEdge* edge = eosC1[ iEOS ]->_edges[i];
|
_LayerEdge* edge = eosC1[ iEOS ]->_edges[i];
|
||||||
edge->CheckNeiborsOnBoundary( & badSmooEdges );
|
edge->CheckNeiborsOnBoundary( & badEdges );
|
||||||
if ( badNb > 0 )
|
if ( nbBad > 0 )
|
||||||
{
|
{
|
||||||
SMESH_TNodeXYZ tgtXYZ = edge->_nodes.back();
|
SMESH_TNodeXYZ tgtXYZ = edge->_nodes.back();
|
||||||
const gp_XYZ& prevXYZ = edge->PrevCheckPos();
|
const gp_XYZ& prevXYZ = edge->PrevCheckPos();
|
||||||
@ -4639,7 +4642,7 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data,
|
|||||||
<< " "<< tgtXYZ._node->GetID()
|
<< " "<< tgtXYZ._node->GetID()
|
||||||
<< " "<< edge->_simplices[j]._nPrev->GetID()
|
<< " "<< edge->_simplices[j]._nPrev->GetID()
|
||||||
<< " "<< edge->_simplices[j]._nNext->GetID() << " )" );
|
<< " "<< edge->_simplices[j]._nNext->GetID() << " )" );
|
||||||
badSmooEdges.push_back( edge );
|
badEdges.push_back( edge );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4647,9 +4650,9 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// try to fix bad simplices by removing the last inflation step of some _LayerEdge's
|
// try to fix bad simplices by removing the last inflation step of some _LayerEdge's
|
||||||
badNb = invalidateBadSmooth( data, helper, badSmooEdges, eosC1, infStep );
|
nbBad = invalidateBadSmooth( data, helper, badEdges, eosC1, infStep );
|
||||||
|
|
||||||
if ( badNb > 0 )
|
if ( nbBad > 0 )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4667,7 +4670,7 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data,
|
|||||||
!eos._sWOL.IsNull() )
|
!eos._sWOL.IsNull() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
badSmooEdges.clear();
|
badEdges.clear();
|
||||||
for ( size_t i = 0; i < eos._edges.size(); ++i )
|
for ( size_t i = 0; i < eos._edges.size(); ++i )
|
||||||
{
|
{
|
||||||
_LayerEdge* edge = eos._edges[i];
|
_LayerEdge* edge = eos._edges[i];
|
||||||
@ -4682,15 +4685,15 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data,
|
|||||||
<< " "<< tgtXYZ._node->GetID()
|
<< " "<< tgtXYZ._node->GetID()
|
||||||
<< " "<< edge->_simplices[j]._nPrev->GetID()
|
<< " "<< edge->_simplices[j]._nPrev->GetID()
|
||||||
<< " "<< edge->_simplices[j]._nNext->GetID() << " )" );
|
<< " "<< edge->_simplices[j]._nNext->GetID() << " )" );
|
||||||
badSmooEdges.push_back( edge );
|
badEdges.push_back( edge );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to fix bad simplices by removing the last inflation step of some _LayerEdge's
|
// try to fix bad simplices by removing the last inflation step of some _LayerEdge's
|
||||||
eosC1[0] = &eos;
|
eosC1[0] = &eos;
|
||||||
int badNb = invalidateBadSmooth( data, helper, badSmooEdges, eosC1, infStep );
|
int nbBad = invalidateBadSmooth( data, helper, badEdges, eosC1, infStep );
|
||||||
if ( badNb > 0 )
|
if ( nbBad > 0 )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4723,7 +4726,41 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data,
|
|||||||
eos._edges[i]->Is( _LayerEdge::MULTI_NORMAL ))
|
eos._edges[i]->Is( _LayerEdge::MULTI_NORMAL ))
|
||||||
continue;
|
continue;
|
||||||
if ( eos._edges[i]->FindIntersection( *searcher, dist, data._epsilon, eos, &intFace ))
|
if ( eos._edges[i]->FindIntersection( *searcher, dist, data._epsilon, eos, &intFace ))
|
||||||
return false;
|
{
|
||||||
|
// Collision; try to deflate _LayerEdge's causing it
|
||||||
|
badEdges.clear();
|
||||||
|
badEdges.push_back( eos._edges[i] );
|
||||||
|
eosC1[0] = & eos;
|
||||||
|
int nbBad = invalidateBadSmooth( data, helper, badEdges, eosC1, infStep );
|
||||||
|
if ( nbBad > 0 )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
badEdges.clear();
|
||||||
|
if ( _EdgesOnShape* eof = data.GetShapeEdges( intFace->getshapeId() ))
|
||||||
|
{
|
||||||
|
if ( const _TmpMeshFace* f = dynamic_cast< const _TmpMeshFace*>( intFace ))
|
||||||
|
{
|
||||||
|
const SMDS_MeshElement* srcFace =
|
||||||
|
eof->_subMesh->GetSubMeshDS()->GetElement( f->getIdInShape() );
|
||||||
|
SMDS_ElemIteratorPtr nIt = srcFace->nodesIterator();
|
||||||
|
while ( nIt->more() )
|
||||||
|
{
|
||||||
|
const SMDS_MeshNode* srcNode = static_cast<const SMDS_MeshNode*>( nIt->next() );
|
||||||
|
TNode2Edge::iterator n2e = data._n2eMap.find( srcNode );
|
||||||
|
if ( n2e != data._n2eMap.end() )
|
||||||
|
badEdges.push_back( n2e->second );
|
||||||
|
}
|
||||||
|
eosC1[0] = eof;
|
||||||
|
nbBad = invalidateBadSmooth( data, helper, badEdges, eosC1, infStep );
|
||||||
|
if ( nbBad > 0 )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( eos._edges[i]->FindIntersection( *searcher, dist, data._epsilon, eos, &intFace ))
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if ( !intFace )
|
if ( !intFace )
|
||||||
{
|
{
|
||||||
SMESH_Comment msg("Invalid? normal at node "); msg << eos._edges[i]->_nodes[0]->GetID();
|
SMESH_Comment msg("Invalid? normal at node "); msg << eos._edges[i]->_nodes[0]->GetID();
|
||||||
@ -4849,7 +4886,7 @@ int _ViscousBuilder::invalidateBadSmooth( _SolidData& data,
|
|||||||
|
|
||||||
dumpFunction(SMESH_Comment("invalidateBadSmooth")<<"_S"<<eosC1[0]->_shapeID<<"_InfStep"<<infStep);
|
dumpFunction(SMESH_Comment("invalidateBadSmooth")<<"_S"<<eosC1[0]->_shapeID<<"_InfStep"<<infStep);
|
||||||
|
|
||||||
data.UnmarkEdges();
|
//data.UnmarkEdges();
|
||||||
|
|
||||||
double vol;
|
double vol;
|
||||||
//size_t iniNbBad = badSmooEdges.size();
|
//size_t iniNbBad = badSmooEdges.size();
|
||||||
@ -4862,7 +4899,7 @@ int _ViscousBuilder::invalidateBadSmooth( _SolidData& data,
|
|||||||
_EdgesOnShape* eos = data.GetShapeEdges( edge );
|
_EdgesOnShape* eos = data.GetShapeEdges( edge );
|
||||||
edge->InvalidateStep( edge->NbSteps(), *eos, /*restoreLength=*/true );
|
edge->InvalidateStep( edge->NbSteps(), *eos, /*restoreLength=*/true );
|
||||||
edge->Block( data );
|
edge->Block( data );
|
||||||
edge->Set( _LayerEdge::MARKED );
|
//edge->Set( _LayerEdge::MARKED );
|
||||||
|
|
||||||
// look for _LayerEdge's of bad _simplices
|
// look for _LayerEdge's of bad _simplices
|
||||||
SMESH_TNodeXYZ tgtXYZ = edge->_nodes.back();
|
SMESH_TNodeXYZ tgtXYZ = edge->_nodes.back();
|
||||||
@ -4900,7 +4937,7 @@ int _ViscousBuilder::invalidateBadSmooth( _SolidData& data,
|
|||||||
|
|
||||||
// check result of invalidation
|
// check result of invalidation
|
||||||
|
|
||||||
int badNb = 0;
|
int nbBad = 0;
|
||||||
for ( size_t iEOS = 0; iEOS < eosC1.size(); ++iEOS )
|
for ( size_t iEOS = 0; iEOS < eosC1.size(); ++iEOS )
|
||||||
{
|
{
|
||||||
for ( size_t i = 0; i < eosC1[ iEOS ]->_edges.size(); ++i )
|
for ( size_t i = 0; i < eosC1[ iEOS ]->_edges.size(); ++i )
|
||||||
@ -4912,7 +4949,7 @@ int _ViscousBuilder::invalidateBadSmooth( _SolidData& data,
|
|||||||
for ( size_t j = 0; j < edge->_simplices.size(); ++j )
|
for ( size_t j = 0; j < edge->_simplices.size(); ++j )
|
||||||
if ( !edge->_simplices[j].IsForward( &prevXYZ, &tgtXYZ, vol ))
|
if ( !edge->_simplices[j].IsForward( &prevXYZ, &tgtXYZ, vol ))
|
||||||
{
|
{
|
||||||
++badNb;
|
++nbBad;
|
||||||
debugMsg("Bad simplex remains ( " << edge->_nodes[0]->GetID()
|
debugMsg("Bad simplex remains ( " << edge->_nodes[0]->GetID()
|
||||||
<< " "<< tgtXYZ._node->GetID()
|
<< " "<< tgtXYZ._node->GetID()
|
||||||
<< " "<< edge->_simplices[j]._nPrev->GetID()
|
<< " "<< edge->_simplices[j]._nPrev->GetID()
|
||||||
@ -4922,7 +4959,7 @@ int _ViscousBuilder::invalidateBadSmooth( _SolidData& data,
|
|||||||
}
|
}
|
||||||
dumpFunctionEnd();
|
dumpFunctionEnd();
|
||||||
|
|
||||||
return badNb;
|
return nbBad;
|
||||||
}
|
}
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
@ -5329,7 +5366,7 @@ bool _Smoother1D::smoothComplexEdge( _SolidData& data,
|
|||||||
if ( _offPoints.empty() )
|
if ( _offPoints.empty() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// move _offPoints to a new position
|
// move _offPoints to positions along normals of _LayerEdge's
|
||||||
|
|
||||||
_LayerEdge* e[2] = { getLEdgeOnV(0), getLEdgeOnV(1) };
|
_LayerEdge* e[2] = { getLEdgeOnV(0), getLEdgeOnV(1) };
|
||||||
if ( e[0]->Is( _LayerEdge::NORMAL_UPDATED )) setNormalOnV( 0, helper );
|
if ( e[0]->Is( _LayerEdge::NORMAL_UPDATED )) setNormalOnV( 0, helper );
|
||||||
@ -5377,7 +5414,8 @@ bool _Smoother1D::smoothComplexEdge( _SolidData& data,
|
|||||||
int i = _iSeg[ is2nd ];
|
int i = _iSeg[ is2nd ];
|
||||||
int di = is2nd ? -1 : +1;
|
int di = is2nd ? -1 : +1;
|
||||||
bool projected = false;
|
bool projected = false;
|
||||||
double uOnSeg, uOnSegDiff, uOnSegBestDiff = Precision::Infinite();
|
double uOnSeg, uOnSegDiff, uOnSegBestDiff = Precision::Infinite(), uOnSegPrevDiff;
|
||||||
|
int nbWorse = 0;
|
||||||
do {
|
do {
|
||||||
gp_Vec v0p( _offPoints[i]._xyz, pExtreme[ is2nd ] );
|
gp_Vec v0p( _offPoints[i]._xyz, pExtreme[ is2nd ] );
|
||||||
gp_Vec v01( _offPoints[i]._xyz, _offPoints[i+1]._xyz );
|
gp_Vec v01( _offPoints[i]._xyz, _offPoints[i+1]._xyz );
|
||||||
@ -5390,6 +5428,12 @@ bool _Smoother1D::smoothComplexEdge( _SolidData& data,
|
|||||||
pProj[ is2nd ] = _offPoints[i]._xyz + ( v01 * uOnSeg ).XYZ();
|
pProj[ is2nd ] = _offPoints[i]._xyz + ( v01 * uOnSeg ).XYZ();
|
||||||
uOnSegBestDiff = uOnSegDiff;
|
uOnSegBestDiff = uOnSegDiff;
|
||||||
}
|
}
|
||||||
|
else if ( uOnSegDiff > uOnSegPrevDiff )
|
||||||
|
{
|
||||||
|
if ( ++nbWorse > 3 ) // avoid projection to the middle of a closed EDGE
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
uOnSegPrevDiff = uOnSegDiff;
|
||||||
i += di;
|
i += di;
|
||||||
}
|
}
|
||||||
while ( !projected &&
|
while ( !projected &&
|
||||||
@ -5479,10 +5523,14 @@ bool _Smoother1D::smoothComplexEdge( _SolidData& data,
|
|||||||
|
|
||||||
void _Smoother1D::prepare(_SolidData& data)
|
void _Smoother1D::prepare(_SolidData& data)
|
||||||
{
|
{
|
||||||
// sort _LayerEdge's by position on the EDGE
|
|
||||||
const TopoDS_Edge& E = TopoDS::Edge( _eos._shape );
|
const TopoDS_Edge& E = TopoDS::Edge( _eos._shape );
|
||||||
|
_curveLen = SMESH_Algo::EdgeLength( E );
|
||||||
|
|
||||||
|
// sort _LayerEdge's by position on the EDGE
|
||||||
data.SortOnEdge( E, _eos._edges );
|
data.SortOnEdge( E, _eos._edges );
|
||||||
|
|
||||||
|
SMESH_MesherHelper& helper = data.GetHelper();
|
||||||
|
|
||||||
// compute normalized param of _eos._edges on EDGE
|
// compute normalized param of _eos._edges on EDGE
|
||||||
_leParams.resize( _eos._edges.size() + 1 );
|
_leParams.resize( _eos._edges.size() + 1 );
|
||||||
{
|
{
|
||||||
@ -5499,10 +5547,46 @@ void _Smoother1D::prepare(_SolidData& data)
|
|||||||
pPrev = p;
|
pPrev = p;
|
||||||
}
|
}
|
||||||
double fullLen = _leParams.back() + pPrev.Distance( SMESH_TNodeXYZ( getLEdgeOnV(1)->_nodes[0]));
|
double fullLen = _leParams.back() + pPrev.Distance( SMESH_TNodeXYZ( getLEdgeOnV(1)->_nodes[0]));
|
||||||
for ( size_t i = 0; i < _leParams.size(); ++i )
|
for ( size_t i = 0; i < _leParams.size()-1; ++i )
|
||||||
_leParams[i] = _leParams[i+1] / fullLen;
|
_leParams[i] = _leParams[i+1] / fullLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// find intersection of neighbor _LayerEdge's to limit _maxLen
|
||||||
|
// according to EDGE curvature (IPAL52648)
|
||||||
|
_LayerEdge* e0 = _eos._edges[0];
|
||||||
|
for ( size_t i = 1; i < _eos._edges.size(); ++i )
|
||||||
|
{
|
||||||
|
_LayerEdge* ei = _eos._edges[i];
|
||||||
|
gp_XYZ plnNorm = e0->_normal ^ ei->_normal;
|
||||||
|
gp_XYZ perp0 = e0->_normal ^ plnNorm;
|
||||||
|
double dot0i = perp0 * ei->_normal;
|
||||||
|
if ( Abs( dot0i ) > std::numeric_limits<double>::min() )
|
||||||
|
{
|
||||||
|
SMESH_TNodeXYZ srci( ei->_nodes[0] ), src0( e0->_nodes[0] );
|
||||||
|
double ui = ( perp0 * ( src0 - srci )) / dot0i;
|
||||||
|
if ( ui > 0 )
|
||||||
|
{
|
||||||
|
ei->_maxLen = Min( ei->_maxLen, 0.75 * ui / ei->_lenFactor );
|
||||||
|
if ( ei->_maxLen < ei->_len )
|
||||||
|
{
|
||||||
|
ei->InvalidateStep( ei->NbSteps(), _eos, /*restoreLength=*/true );
|
||||||
|
ei->SetNewLength( ei->_maxLen, _eos, helper );
|
||||||
|
ei->Block( data );
|
||||||
|
}
|
||||||
|
gp_Pnt pi = srci + ei->_normal * ui;
|
||||||
|
double u0 = pi.Distance( src0 );
|
||||||
|
e0->_maxLen = Min( e0->_maxLen, 0.75 * u0 / e0->_lenFactor );
|
||||||
|
if ( e0->_maxLen < e0->_len )
|
||||||
|
{
|
||||||
|
e0->InvalidateStep( e0->NbSteps(), _eos, /*restoreLength=*/true );
|
||||||
|
e0->SetNewLength( e0->_maxLen, _eos, helper );
|
||||||
|
e0->Block( data );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
e0 = ei;
|
||||||
|
}
|
||||||
|
|
||||||
if ( isAnalytic() )
|
if ( isAnalytic() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -8602,6 +8686,10 @@ void _LayerEdge::Block( _SolidData& data )
|
|||||||
minDist = Min( pSrc.SquareDistance( pTgtN ), minDist );
|
minDist = Min( pSrc.SquareDistance( pTgtN ), minDist );
|
||||||
minDist = Min( pTgt.SquareDistance( pSrcN ), minDist );
|
minDist = Min( pTgt.SquareDistance( pSrcN ), minDist );
|
||||||
double newMaxLen = edge->_maxLen + 0.5 * Sqrt( minDist );
|
double newMaxLen = edge->_maxLen + 0.5 * Sqrt( minDist );
|
||||||
|
if ( edge->_nodes[0]->getshapeId() == neibor->_nodes[0]->getshapeId() )
|
||||||
|
{
|
||||||
|
newMaxLen *= edge->_lenFactor / neibor->_lenFactor;
|
||||||
|
}
|
||||||
if ( neibor->_maxLen > newMaxLen )
|
if ( neibor->_maxLen > newMaxLen )
|
||||||
{
|
{
|
||||||
neibor->_maxLen = newMaxLen;
|
neibor->_maxLen = newMaxLen;
|
||||||
@ -9446,7 +9534,7 @@ bool _ViscousBuilder::shrink()
|
|||||||
// ==================
|
// ==================
|
||||||
|
|
||||||
bool shrinked = true;
|
bool shrinked = true;
|
||||||
int badNb, shriStep=0, smooStep=0;
|
int nbBad, shriStep=0, smooStep=0;
|
||||||
_SmoothNode::SmoothType smoothType
|
_SmoothNode::SmoothType smoothType
|
||||||
= isConcaveFace ? _SmoothNode::ANGULAR : _SmoothNode::LAPLACIAN;
|
= isConcaveFace ? _SmoothNode::ANGULAR : _SmoothNode::LAPLACIAN;
|
||||||
SMESH_Comment errMsg;
|
SMESH_Comment errMsg;
|
||||||
@ -9477,22 +9565,22 @@ bool _ViscousBuilder::shrink()
|
|||||||
// -----------------
|
// -----------------
|
||||||
int nbNoImpSteps = 0;
|
int nbNoImpSteps = 0;
|
||||||
bool moved = true;
|
bool moved = true;
|
||||||
badNb = 1;
|
nbBad = 1;
|
||||||
while (( nbNoImpSteps < 5 && badNb > 0) && moved)
|
while (( nbNoImpSteps < 5 && nbBad > 0) && moved)
|
||||||
{
|
{
|
||||||
dumpFunction(SMESH_Comment("shrinkFace")<<f2sd->first<<"_st"<<++smooStep); // debug
|
dumpFunction(SMESH_Comment("shrinkFace")<<f2sd->first<<"_st"<<++smooStep); // debug
|
||||||
|
|
||||||
int oldBadNb = badNb;
|
int oldBadNb = nbBad;
|
||||||
badNb = 0;
|
nbBad = 0;
|
||||||
moved = false;
|
moved = false;
|
||||||
// '% 5' minimizes NB FUNCTIONS on viscous_layers_00/B2 case
|
// '% 5' minimizes NB FUNCTIONS on viscous_layers_00/B2 case
|
||||||
_SmoothNode::SmoothType smooTy = ( smooStep % 5 ) ? smoothType : _SmoothNode::LAPLACIAN;
|
_SmoothNode::SmoothType smooTy = ( smooStep % 5 ) ? smoothType : _SmoothNode::LAPLACIAN;
|
||||||
for ( size_t i = 0; i < nodesToSmooth.size(); ++i )
|
for ( size_t i = 0; i < nodesToSmooth.size(); ++i )
|
||||||
{
|
{
|
||||||
moved |= nodesToSmooth[i].Smooth( badNb, surface, helper, refSign,
|
moved |= nodesToSmooth[i].Smooth( nbBad, surface, helper, refSign,
|
||||||
smooTy, /*set3D=*/isConcaveFace);
|
smooTy, /*set3D=*/isConcaveFace);
|
||||||
}
|
}
|
||||||
if ( badNb < oldBadNb )
|
if ( nbBad < oldBadNb )
|
||||||
nbNoImpSteps = 0;
|
nbNoImpSteps = 0;
|
||||||
else
|
else
|
||||||
nbNoImpSteps++;
|
nbNoImpSteps++;
|
||||||
@ -9501,7 +9589,7 @@ bool _ViscousBuilder::shrink()
|
|||||||
}
|
}
|
||||||
|
|
||||||
errMsg.clear();
|
errMsg.clear();
|
||||||
if ( badNb > 0 )
|
if ( nbBad > 0 )
|
||||||
errMsg << "Can't shrink 2D mesh on face " << f2sd->first;
|
errMsg << "Can't shrink 2D mesh on face " << f2sd->first;
|
||||||
if ( shriStep > 200 )
|
if ( shriStep > 200 )
|
||||||
errMsg << "Infinite loop at shrinking 2D mesh on face " << f2sd->first;
|
errMsg << "Infinite loop at shrinking 2D mesh on face " << f2sd->first;
|
||||||
@ -9548,7 +9636,7 @@ bool _ViscousBuilder::shrink()
|
|||||||
// dumpFunction(SMESH_Comment("shrinkFace")<<f2sd->first<<"_st"<<++smooStep); // debug
|
// dumpFunction(SMESH_Comment("shrinkFace")<<f2sd->first<<"_st"<<++smooStep); // debug
|
||||||
// for ( size_t i = 0; i < nodesToSmooth.size(); ++i )
|
// for ( size_t i = 0; i < nodesToSmooth.size(); ++i )
|
||||||
// {
|
// {
|
||||||
// nodesToSmooth[i].Smooth( badNb,surface,helper,refSign,
|
// nodesToSmooth[i].Smooth( nbBad,surface,helper,refSign,
|
||||||
// _SmoothNode::LAPLACIAN,/*set3D=*/false);
|
// _SmoothNode::LAPLACIAN,/*set3D=*/false);
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
@ -9735,7 +9823,7 @@ bool _ViscousBuilder::shrink()
|
|||||||
dumpFunction(SMESH_Comment("shrinkFace")<<f2sd->first<<"_st"<<++smooStep); // debug
|
dumpFunction(SMESH_Comment("shrinkFace")<<f2sd->first<<"_st"<<++smooStep); // debug
|
||||||
for ( size_t i = 0; i < nodesToSmooth.size(); ++i )
|
for ( size_t i = 0; i < nodesToSmooth.size(); ++i )
|
||||||
{
|
{
|
||||||
nodesToSmooth[i].Smooth( badNb,surface,helper,refSign,
|
nodesToSmooth[i].Smooth( nbBad,surface,helper,refSign,
|
||||||
smoothType,/*set3D=*/st==1 );
|
smoothType,/*set3D=*/st==1 );
|
||||||
}
|
}
|
||||||
dumpFunctionEnd();
|
dumpFunctionEnd();
|
||||||
@ -10148,7 +10236,7 @@ bool _LayerEdge::SetNewLength2d( Handle(Geom_Surface)& surface,
|
|||||||
*/
|
*/
|
||||||
//================================================================================
|
//================================================================================
|
||||||
|
|
||||||
bool _SmoothNode::Smooth(int& badNb,
|
bool _SmoothNode::Smooth(int& nbBad,
|
||||||
Handle(Geom_Surface)& surface,
|
Handle(Geom_Surface)& surface,
|
||||||
SMESH_MesherHelper& helper,
|
SMESH_MesherHelper& helper,
|
||||||
const double refSign,
|
const double refSign,
|
||||||
@ -10229,7 +10317,7 @@ bool _SmoothNode::Smooth(int& badNb,
|
|||||||
|
|
||||||
if ( nbOkAfter < nbOkBefore )
|
if ( nbOkAfter < nbOkBefore )
|
||||||
{
|
{
|
||||||
badNb += _simplices.size() - nbOkBefore;
|
nbBad += _simplices.size() - nbOkBefore;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10247,7 +10335,7 @@ bool _SmoothNode::Smooth(int& badNb,
|
|||||||
dumpMove( _node );
|
dumpMove( _node );
|
||||||
}
|
}
|
||||||
|
|
||||||
badNb += _simplices.size() - nbOkAfter;
|
nbBad += _simplices.size() - nbOkAfter;
|
||||||
return ( (tgtUV-newPos).SquareModulus() > 1e-10 );
|
return ( (tgtUV-newPos).SquareModulus() > 1e-10 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user