Pb: entangled prisms are created on a face shared by solids where
VL have different thickness due to different size of solids

Test SALOME_TESTS/Grids/smesh/viscous_layers_00/A5
This commit is contained in:
eap 2014-05-13 18:49:32 +04:00
parent 9d93189fdb
commit 050aa87698

View File

@ -326,7 +326,7 @@ namespace VISCOUS_3D
gp_XYZ _normal; // to solid surface gp_XYZ _normal; // to solid surface
vector<gp_XYZ> _pos; // points computed during inflation vector<gp_XYZ> _pos; // points computed during inflation
double _len; // length achived with the last step double _len; // length achived with the last inflation step
double _cosin; // of angle (_normal ^ surface) double _cosin; // of angle (_normal ^ surface)
double _lenFactor; // to compute _len taking _cosin into account double _lenFactor; // to compute _len taking _cosin into account
@ -365,7 +365,7 @@ namespace VISCOUS_3D
const double& epsilon) const; const double& epsilon) const;
gp_Ax1 LastSegment(double& segLen) const; gp_Ax1 LastSegment(double& segLen) const;
bool IsOnEdge() const { return _2neibors; } bool IsOnEdge() const { return _2neibors; }
void Copy( _LayerEdge& other, SMESH_MesherHelper& helper ); gp_XYZ Copy( _LayerEdge& other, SMESH_MesherHelper& helper );
void SetCosin( double cosin ); void SetCosin( double cosin );
}; };
struct _LayerEdgeCmp struct _LayerEdgeCmp
@ -397,6 +397,8 @@ namespace VISCOUS_3D
const SMDS_MeshNode* _stepSizeNodes[2]; const SMDS_MeshNode* _stepSizeNodes[2];
TNode2Edge _n2eMap; TNode2Edge _n2eMap;
// map to find _n2eMap of another _SolidData by a shrink shape shared by two _SolidData's
map< TGeomID, TNode2Edge* > _s2neMap;
// edges of _n2eMap. We keep same data in two containers because // edges of _n2eMap. We keep same data in two containers because
// iteration over the map is 5 time longer than over the vector // iteration over the map is 5 time longer than over the vector
vector< _LayerEdge* > _edges; vector< _LayerEdge* > _edges;
@ -1445,7 +1447,6 @@ bool _ViscousBuilder::makeLayer(_SolidData& data)
} }
// make a map to find new nodes on sub-shapes shared with other SOLID // make a map to find new nodes on sub-shapes shared with other SOLID
map< TGeomID, TNode2Edge* > s2neMap;
map< TGeomID, TNode2Edge* >::iterator s2ne; map< TGeomID, TNode2Edge* >::iterator s2ne;
map< TGeomID, TopoDS_Shape >::iterator s2s = data._shrinkShape2Shape.begin(); map< TGeomID, TopoDS_Shape >::iterator s2s = data._shrinkShape2Shape.begin();
for (; s2s != data._shrinkShape2Shape.end(); ++s2s ) for (; s2s != data._shrinkShape2Shape.end(); ++s2s )
@ -1458,7 +1459,7 @@ bool _ViscousBuilder::makeLayer(_SolidData& data)
if ( s2s2 != _sdVec[i]._shrinkShape2Shape.end() && if ( s2s2 != _sdVec[i]._shrinkShape2Shape.end() &&
*s2s == *s2s2 && !_sdVec[i]._n2eMap.empty() ) *s2s == *s2s2 && !_sdVec[i]._n2eMap.empty() )
{ {
s2neMap.insert( make_pair( shapeInd, &_sdVec[i]._n2eMap )); data._s2neMap.insert( make_pair( shapeInd, &_sdVec[i]._n2eMap ));
break; break;
} }
} }
@ -1510,21 +1511,23 @@ bool _ViscousBuilder::makeLayer(_SolidData& data)
const int shapeID = n->getshapeId(); const int shapeID = n->getshapeId();
edgesByGeom[ shapeID ].push_back( edge ); edgesByGeom[ shapeID ].push_back( edge );
SMESH_TNodeXYZ xyz( n );
// set edge data or find already refined _LayerEdge and get data from it // set edge data or find already refined _LayerEdge and get data from it
if ( n->GetPosition()->GetTypeOfPosition() != SMDS_TOP_FACE && if ( n->GetPosition()->GetTypeOfPosition() != SMDS_TOP_FACE &&
( s2ne = s2neMap.find( shapeID )) != s2neMap.end() && ( s2ne = data._s2neMap.find( shapeID )) != data._s2neMap.end() &&
( n2e2 = (*s2ne).second->find( n )) != s2ne->second->end()) ( n2e2 = (*s2ne).second->find( n )) != s2ne->second->end())
{ {
_LayerEdge* foundEdge = (*n2e2).second; _LayerEdge* foundEdge = (*n2e2).second;
edge->Copy( *foundEdge, helper ); gp_XYZ lastPos = edge->Copy( *foundEdge, helper );
// location of the last node is modified but we can restore foundEdge->_pos.push_back( lastPos );
// it by node position on _sWOL stored by the node // location of the last node is modified and we restore it by foundEdge->_pos.back()
const_cast< SMDS_MeshNode* > const_cast< SMDS_MeshNode* >
( edge->_nodes.back() )->setXYZ( n->X(), n->Y(), n->Z() ); ( edge->_nodes.back() )->setXYZ( xyz.X(), xyz.Y(), xyz.Z() );
} }
else else
{ {
edge->_nodes.push_back( helper.AddNode( n->X(), n->Y(), n->Z() )); edge->_nodes.push_back( helper.AddNode( xyz.X(), xyz.Y(), xyz.Z() ));
if ( !setEdgeData( *edge, subIds, helper, data )) if ( !setEdgeData( *edge, subIds, helper, data ))
return false; return false;
} }
@ -2266,7 +2269,7 @@ void _LayerEdge::SetDataByNeighbors( const SMDS_MeshNode* n1,
*/ */
//================================================================================ //================================================================================
void _LayerEdge::Copy( _LayerEdge& other, SMESH_MesherHelper& helper ) gp_XYZ _LayerEdge::Copy( _LayerEdge& other, SMESH_MesherHelper& helper )
{ {
_nodes = other._nodes; _nodes = other._nodes;
_normal = other._normal; _normal = other._normal;
@ -2278,16 +2281,25 @@ void _LayerEdge::Copy( _LayerEdge& other, SMESH_MesherHelper& helper )
_curvature = 0; std::swap( _curvature, other._curvature ); _curvature = 0; std::swap( _curvature, other._curvature );
_2neibors = 0; std::swap( _2neibors, other._2neibors ); _2neibors = 0; std::swap( _2neibors, other._2neibors );
gp_XYZ lastPos( 0,0,0 );
if ( _sWOL.ShapeType() == TopAbs_EDGE ) if ( _sWOL.ShapeType() == TopAbs_EDGE )
{ {
double u = helper.GetNodeU( TopoDS::Edge( _sWOL ), _nodes[0] ); double u = helper.GetNodeU( TopoDS::Edge( _sWOL ), _nodes[0] );
_pos.push_back( gp_XYZ( u, 0, 0)); _pos.push_back( gp_XYZ( u, 0, 0));
u = helper.GetNodeU( TopoDS::Edge( _sWOL ), _nodes.back() );
lastPos.SetX( u );
} }
else // TopAbs_FACE else // TopAbs_FACE
{ {
gp_XY uv = helper.GetNodeUV( TopoDS::Face( _sWOL ), _nodes[0]); gp_XY uv = helper.GetNodeUV( TopoDS::Face( _sWOL ), _nodes[0]);
_pos.push_back( gp_XYZ( uv.X(), uv.Y(), 0)); _pos.push_back( gp_XYZ( uv.X(), uv.Y(), 0));
uv = helper.GetNodeUV( TopoDS::Face( _sWOL ), _nodes.back() );
lastPos.SetX( uv.X() );
lastPos.SetY( uv.Y() );
} }
return lastPos;
} }
//================================================================================ //================================================================================
@ -3663,10 +3675,14 @@ bool _ViscousBuilder::refine(_SolidData& data)
Handle(Geom_Surface) surface; Handle(Geom_Surface) surface;
TopoDS_Edge geomEdge; TopoDS_Edge geomEdge;
TopoDS_Face geomFace; TopoDS_Face geomFace;
TopoDS_Shape prevSWOL;
TopLoc_Location loc; TopLoc_Location loc;
double f,l, u/*, distXYZ[4]*/; double f,l, u;
gp_XY uv; gp_XY uv;
bool isOnEdge; bool isOnEdge;
TGeomID prevBaseId = -1;
TNode2Edge* n2eMap = 0;
TNode2Edge::iterator n2e;
for ( size_t i = 0; i < data._edges.size(); ++i ) for ( size_t i = 0; i < data._edges.size(); ++i )
{ {
@ -3686,27 +3702,46 @@ bool _ViscousBuilder::refine(_SolidData& data)
edge._nodes[1] = 0; edge._nodes[1] = 0;
edge._nodes.back() = tgtNode; edge._nodes.back() = tgtNode;
} }
if ( !edge._sWOL.IsNull() ) // get data of a shrink shape
if ( !edge._sWOL.IsNull() && edge._sWOL != prevSWOL )
{ {
isOnEdge = ( edge._sWOL.ShapeType() == TopAbs_EDGE ); isOnEdge = ( edge._sWOL.ShapeType() == TopAbs_EDGE );
// restore position of the last node
// gp_Pnt p;
if ( isOnEdge ) if ( isOnEdge )
{ {
geomEdge = TopoDS::Edge( edge._sWOL ); geomEdge = TopoDS::Edge( edge._sWOL );
curve = BRep_Tool::Curve( geomEdge, loc, f,l); curve = BRep_Tool::Curve( geomEdge, loc, f,l);
// double u = helper.GetNodeU( tgtNode );
// p = curve->Value( u );
} }
else else
{ {
geomFace = TopoDS::Face( edge._sWOL ); geomFace = TopoDS::Face( edge._sWOL );
surface = BRep_Tool::Surface( geomFace, loc ); surface = BRep_Tool::Surface( geomFace, loc );
// gp_XY uv = helper.GetNodeUV( tgtNode );
// p = surface->Value( uv.X(), uv.Y() );
} }
// p.Transform( loc ); prevSWOL = edge._sWOL;
// const_cast< SMDS_MeshNode* >( tgtNode )->setXYZ( p.X(), p.Y(), p.Z() ); }
// restore shapePos of the last node by already treated _LayerEdge of another _SolidData
const TGeomID baseShapeId = edge._nodes[0]->getshapeId();
if ( baseShapeId != prevBaseId )
{
map< TGeomID, TNode2Edge* >::iterator s2ne = data._s2neMap.find( baseShapeId );
n2eMap = ( s2ne == data._s2neMap.end() ) ? 0 : n2eMap = s2ne->second;
prevBaseId = baseShapeId;
}
if ( n2eMap && (( n2e = n2eMap->find( edge._nodes[0] )) != n2eMap->end() ))
{
_LayerEdge* foundEdge = n2e->second;
const gp_XYZ& foundPos = foundEdge->_pos.back();
SMDS_PositionPtr lastPos = tgtNode->GetPosition();
if ( isOnEdge )
{
SMDS_EdgePosition* epos = static_cast<SMDS_EdgePosition*>( lastPos );
epos->SetUParameter( foundPos.X() );
}
else
{
SMDS_FacePosition* fpos = static_cast<SMDS_FacePosition*>( lastPos );
fpos->SetUParameter( foundPos.X() );
fpos->SetVParameter( foundPos.Y() );
}
} }
// calculate height of the first layer // calculate height of the first layer
double h0; double h0;
@ -3744,11 +3779,13 @@ bool _ViscousBuilder::refine(_SolidData& data)
if ( isOnEdge ) if ( isOnEdge )
{ {
u = pos.X(); u = pos.X();
if ( !node )
pos = curve->Value( u ).Transformed(loc); pos = curve->Value( u ).Transformed(loc);
} }
else else
{ {
uv.SetCoord( pos.X(), pos.Y() ); uv.SetCoord( pos.X(), pos.Y() );
if ( !node )
pos = surface->Value( pos.X(), pos.Y() ).Transformed(loc); pos = surface->Value( pos.X(), pos.Y() ).Transformed(loc);
} }
} }
@ -3777,11 +3814,18 @@ bool _ViscousBuilder::refine(_SolidData& data)
{ {
u = 0.5 * ( u + helper.GetNodeU( geomEdge, node )); u = 0.5 * ( u + helper.GetNodeU( geomEdge, node ));
pos = curve->Value( u ).Transformed(loc); pos = curve->Value( u ).Transformed(loc);
SMDS_EdgePosition* epos = static_cast<SMDS_EdgePosition*>( node->GetPosition() );
epos->SetUParameter( u );
} }
else else
{ {
uv = 0.5 * ( uv + helper.GetNodeUV( geomFace, node )); uv = 0.5 * ( uv + helper.GetNodeUV( geomFace, node ));
pos = surface->Value( uv.X(), uv.Y()).Transformed(loc); pos = surface->Value( uv.X(), uv.Y()).Transformed(loc);
SMDS_FacePosition* fpos = static_cast<SMDS_FacePosition*>( node->GetPosition() );
fpos->SetUParameter( uv.X() );
fpos->SetVParameter( uv.Y() );
} }
} }
node->setXYZ( pos.X(), pos.Y(), pos.Z() ); node->setXYZ( pos.X(), pos.Y(), pos.Z() );