faceAnalyser.SetSubShape( faceSM->GetSubShape() );
// rotate edges to get the first node being at corner
- // (in principle it's not necessary but so far none SALOME algo can make
+ // (in principle it's not necessary because so far none SALOME algo can make
// such a structured mesh that all corner nodes are not on VERTEXes)
bool isCorner = false;
int nbRemainEdges = nbEdgesInWires.front();
mutable vector<const QFace* > _faces;
mutable gp_Vec _nodeMove;
mutable int _nbMoves;
+ mutable bool _is2dFixed; // is moved along surface or in 3D
QLink(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2, const SMDS_MeshNode* nm):
SMESH_TLink( n1,n2 ), _mediumNode(nm), _nodeMove(0,0,0), _nbMoves(0) {
_faces.reserve(4);
- //if ( MediumPos() != SMDS_TOP_3DSPACE )
- _nodeMove = MediumPnt() - MiddlePnt();
+ _nodeMove = MediumPnt() - MiddlePnt();
+ _is2dFixed = ( MediumPos() != SMDS_TOP_FACE );
}
void SetContinuesFaces() const;
const QFace* GetContinuesFace( const QFace* face ) const;
const SMDS_MeshNode* EndPosNode(SMDS_TypeOfPosition pos) const
{ return EndPos(0) == pos ? node1() : EndPos(1) == pos ? node2() : 0; }
- void Move(const gp_Vec& move, bool sum=false) const
- { _nodeMove += move; _nbMoves += sum ? (_nbMoves==0) : 1; }
+ void Move(const gp_Vec& move, bool sum=false, bool is2dFixed=false) const
+ { _nodeMove += move; _nbMoves += sum ? (_nbMoves==0) : 1; _is2dFixed |= is2dFixed; }
gp_XYZ Move() const { return _nodeMove.XYZ() / _nbMoves; }
bool IsMoved() const { return (_nbMoves > 0 /*&& !IsStraight()*/); }
+ bool IsFixedOnSurface() const { return _is2dFixed; }
bool IsStraight() const
{ return isStraightLink( (XYZ(node1())-XYZ(node2())).SquareModulus(),
_nodeMove.SquareMagnitude());
double r = thePrevLen / fullLen;
gp_Vec move = linkNorm * refProj * ( 1 - r );
- theLink->Move( move, true );
+ theLink->Move( move, /*sum=*/true );
MSG(string(theStep,'.')<<" Move "<< theLink->_mediumNode->GetID()<<
" by " << refProj * ( 1 - r ) << " following " <<
}
else if ( error == ERR_TRI ) { // chain contains continues triangles
TSplitTriaResult res = splitTrianglesIntoChains( rawChain, chains, pos );
- if ( res != _OK ) { // not quadrangles split into triangles
+ if ( res != _OK ) { // not 'quadrangles split into triangles' in chain
fixTriaNearBoundary( rawChain, *this );
break;
}
// mesure chain length and compute link position along the chain
double chainLen = 0;
vector< double > linkPos;
+ TChain savedChain; // backup
MSGBEG( "Link medium nodes: ");
TChain::iterator link0 = chain.begin(), link1 = chain.begin(), link2;
for ( ++link1; link1 != chain.end(); ++link1, ++link0 ) {
MSGBEG( (*link0)->_mediumNode->GetID() << "-" <<(*link1)->_mediumNode->GetID()<<" ");
double len = ((*link0)->MiddlePnt() - (*link1)->MiddlePnt()).Modulus();
while ( len < numeric_limits<double>::min() ) { // remove degenerated link
+ if ( savedChain.empty() ) savedChain = chain;
link1 = chain.erase( link1 );
if ( link1 == chain.end() )
break;
linkPos.push_back( chainLen );
}
MSG("");
- if ( linkPos.size() < 2 )
- continue;
-
+ if ( linkPos.size() <= 2 && savedChain.size() > 2 ) {
+ //continue;
+ linkPos.clear();
+ chainLen = 0;
+ chain = savedChain;
+ for ( link1 = chain.begin(); link1 != chain.end(); ++link1 ) {
+ chainLen += 1;
+ linkPos.push_back( chainLen );
+ }
+ }
gp_Vec move0 = chain.front()->_nodeMove;
gp_Vec move1 = chain.back ()->_nodeMove;
// transform to global
gp_Vec x01( (*link0)->MiddlePnt(), (*link1)->MiddlePnt() );
gp_Vec x12( (*link1)->MiddlePnt(), (*link2)->MiddlePnt() );
- gp_Vec x = x01.Normalized() + x12.Normalized();
- trsf.SetTransformation( gp_Ax3( gp::Origin(), link1->Normal(), x), gp_Ax3() );
+ try {
+ gp_Vec x = x01.Normalized() + x12.Normalized();
+ trsf.SetTransformation( gp_Ax3( gp::Origin(), link1->Normal(), x), gp_Ax3() );
+ } catch ( Standard_Failure ) {
+ trsf.Invert();
+ }
move.Transform(trsf);
+ (*link1)->Move( move, /*sum=*/false, /*is2dFixed=*/false );
}
else {
// compute 3D displacement by 2D one
"newUV: "<<newUV.X()<<", "<<newUV.Y()<<" \t");
}
#endif
+ (*link1)->Move( move, /*sum=*/false, /*is2dFixed=*/true );
}
- (*link1)->Move( move );
MSG( "Move " << (*link1)->_mediumNode->GetID() << " following "
<< chain.front()->_mediumNode->GetID() <<"-"
<< chain.back ()->_mediumNode->GetID() <<
const bool toFixCentralNodes = ( myMesh->NbBiQuadQuadrangles() +
myMesh->NbBiQuadTriangles() +
myMesh->NbTriQuadraticHexas() );
+ double distXYZ[4];
+ faceHlp.ToFixNodeParameters( true );
for ( pLink = links.begin(); pLink != links.end(); ++pLink ) {
if ( pLink->IsMoved() )
{
gp_Pnt p = pLink->MiddlePnt() + pLink->Move();
+
+ // put on surface nodes on FACE but moved in 3D (23050)
+ if ( !pLink->IsFixedOnSurface() )
+ {
+ faceHlp.SetSubShape( pLink->_mediumNode->getshapeId() );
+ if ( faceHlp.GetSubShape().ShapeType() == TopAbs_FACE )
+ {
+ const_cast<SMDS_MeshNode*>( pLink->_mediumNode )->setXYZ( p.X(), p.Y(), p.Z());
+ p.Coord( distXYZ[1], distXYZ[2], distXYZ[3] );
+ gp_XY uv( Precision::Infinite(), 0 );
+ if ( faceHlp.CheckNodeUV( TopoDS::Face( faceHlp.GetSubShape() ), pLink->_mediumNode,
+ uv, /*tol=*/pLink->Move().Modulus(), /*force=*/true, distXYZ ))
+ p.SetCoord( distXYZ[1], distXYZ[2], distXYZ[3] );
+ }
+ }
GetMeshDS()->MoveNode( pLink->_mediumNode, p.X(), p.Y(), p.Z());
// collect bi-quadratic elements