_quadraticMesh = myHelper->IsQuadraticSubMesh(aShape);
myNeedSmooth = false;
- FaceQuadStruct::Ptr quad = CheckNbEdges( aMesh, F );
+ FaceQuadStruct::Ptr quad = CheckNbEdges( aMesh, F, /*considerMesh=*/true );
if (!quad)
return false;
myQuadStruct = quad;
- bool ok = false;
+ updateDegenUV( quad );
+
+ enum { NOT_COMPUTED = -1, COMPUTE_FAILED = 0, COMPUTE_OK = 1 };
+ int res = NOT_COMPUTED;
if (myQuadranglePreference)
{
int n1 = quad->side[0]->NbPoints();
if (nfull == ntmp && ((n1 != n3) || (n2 != n4)))
{
// special path genarating only quandrangle faces
- ok = computeQuadPref( aMesh, F, quad );
+ res = computeQuadPref( aMesh, F, quad );
}
}
else if (myQuadType == QUAD_REDUCED)
if ((n1 == n3 && n2 != n4 && n24tmp == n24) ||
(n2 == n4 && n1 != n3 && n13tmp == n13))
{
- ok = computeReduced( aMesh, F, quad );
+ res = computeReduced( aMesh, F, quad );
}
else
{
}
}
- ok = computeQuadDominant( aMesh, F, quad );
+ if ( res == NOT_COMPUTED )
+ {
+ res = computeQuadDominant( aMesh, F, quad );
+ }
- if ( ok && myNeedSmooth )
+ if ( res == COMPUTE_OK && myNeedSmooth )
smooth( quad );
- return ok;
+ return ( res == COMPUTE_OK );
}
//================================================================================
//=============================================================================
FaceQuadStruct::Ptr StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & aMesh,
- const TopoDS_Shape & aShape)
+ const TopoDS_Shape & aShape,
+ const bool considerMesh)
{
if ( myQuadStruct && myQuadStruct->face.IsSame( aShape ))
return myQuadStruct;
// find corner vertices of the quad
vector<TopoDS_Vertex> corners;
- int nbDegenEdges, nbSides = getCorners( F, aMesh, edges, corners, nbDegenEdges );
+ int nbDegenEdges, nbSides = getCorners( F, aMesh, edges, corners, nbDegenEdges, considerMesh );
if ( nbSides == 0 )
{
return FaceQuadStruct::Ptr();
ignoreMediumNodes, myProxyMesh));
++iSide;
}
+ if ( quad->side.size() == 4 )
+ break;
if ( nbLoops > 8 )
{
error(TComm("Bug: infinite loop in StdMeshers_Quadrangle_2D::CheckNbEdges()"));
// =down
//
- updateDegenUV( quad );
-
int nbhoriz = Min(quad->side[0]->NbPoints(), quad->side[2]->NbPoints());
int nbvertic = Min(quad->side[1]->NbPoints(), quad->side[3]->NbPoints());
bool WisF = true;
int i,j,geomFaceID = meshDS->ShapeToIndex(aFace);
- updateDegenUV( quad );
-
int nb = quad->side[0]->NbPoints();
int nr = quad->side[1]->NbPoints();
int nt = quad->side[2]->NbPoints();
if (uv_eb.size() != nb || uv_er.size() != nr || uv_et.size() != nt || uv_el.size() != nl)
return error(COMPERR_BAD_INPUT_MESH);
- updateDegenUV( quad );
-
// arrays for normalized params
TColStd_SequenceOfReal npb, npr, npt, npl;
for (j = 0; j < nb; j++) {
uv1.v = uv2.v = 0.5 * ( uv1.v + uv2.v );
}
- else if ( quad->side.size() == 4 )
+ else if ( quad->side.size() == 4 && myQuadType == QUAD_STANDARD)
// Set number of nodes on a degenerated side to be same as on an opposite side
// ----------------------------------------------------------------------------
while ( fIt->more() )
{
const SMDS_MeshElement* face = fIt->next();
- const int nbN = face->NbCornerNodes();
- const int nInd = face->GetNodeIndex( node );
+ const int nbN = face->NbCornerNodes();
+ const int nInd = face->GetNodeIndex( node );
const int prevInd = myHelper->WrapIndex( nInd - 1, nbN );
const int nextInd = myHelper->WrapIndex( nInd + 1, nbN );
const SMDS_MeshNode* prevNode = face->GetNode( prevInd );
if ( sNode._triangles.empty() )
continue; // not movable node
- // compute a new XYZ
- gp_XYZ newXYZ (0,0,0);
- for ( unsigned i = 0; i < sNode._triangles.size(); ++i )
- newXYZ += sNode._triangles[i]._n1->_xyz;
- newXYZ /= sNode._triangles.size();
-
- // compute a new UV by projection
gp_XY newUV;
- proj.Perform( newXYZ );
- bool isValid = ( proj.IsDone() && proj.NbPoints() > 0 );
- if ( isValid )
+ bool isValid = false;
+ bool use3D = ( iLoop > 2 ); // 3 loops in 2D and 2, in 3D
+
+ if ( use3D )
{
- // check validity of the newUV
- Quantity_Parameter u,v;
- proj.LowerDistanceParameters( u, v );
- newUV.SetCoord( u, v );
- for ( unsigned i = 0; i < sNode._triangles.size() && isValid; ++i )
- isValid = ( sNode._triangles[i].IsForward( newUV ) == refForward );
+ // compute a new XYZ
+ gp_XYZ newXYZ (0,0,0);
+ for ( unsigned i = 0; i < sNode._triangles.size(); ++i )
+ newXYZ += sNode._triangles[i]._n1->_xyz;
+ newXYZ /= sNode._triangles.size();
+
+ // compute a new UV by projection
+ proj.Perform( newXYZ );
+ isValid = ( proj.IsDone() && proj.NbPoints() > 0 );
+ if ( isValid )
+ {
+ // check validity of the newUV
+ Quantity_Parameter u,v;
+ proj.LowerDistanceParameters( u, v );
+ newUV.SetCoord( u, v );
+ for ( unsigned i = 0; i < sNode._triangles.size() && isValid; ++i )
+ isValid = ( sNode._triangles[i].IsForward( newUV ) == refForward );
+ }
}
if ( !isValid )
{
* \param [out] theVertices - the found corner vertices in the order corresponding to
* the order of EDGEs in \a theWire
* \param [out] theNbDegenEdges - nb of degenerated EDGEs in theFace
+ * \param [in] theConsiderMesh - if \c true, only meshed VERTEXes are considered
+ * as possible corners
* \return int - number of quad sides found: 0, 3 or 4
*/
//================================================================================
SMESH_Mesh & theMesh,
std::list<TopoDS_Edge>& theWire,
std::vector<TopoDS_Vertex>& theVertices,
- int & theNbDegenEdges)
+ int & theNbDegenEdges,
+ const bool theConsiderMesh)
{
theNbDegenEdges = 0;
continue;
}
TopoDS_Vertex v = helper.IthVertex( 0, *edge );
- if ( SMESH_Algo::VertexNode( v, helper.GetMeshDS() ))
+ if ( !theConsiderMesh || SMESH_Algo::VertexNode( v, helper.GetMeshDS() ))
{
double angle = SMESH_MesherHelper::GetAngle( prevE, *edge, theFace );
vertexByAngle.insert( make_pair( angle, v ));
theVertices.clear();
vector< double > angles;
vector< TopoDS_Edge > edgeVec;
- vector< int > cornerInd;
+ vector< int > cornerInd, nbSeg;
angles.reserve( vertexByAngle.size() );
edgeVec.reserve( vertexByAngle.size() );
+ nbSeg.reserve( vertexByAngle.size() );
cornerInd.reserve( nbCorners );
for ( edge = theWire.begin(); edge != theWire.end(); ++edge )
{
}
angles.push_back( angleByVertex.IsBound( v ) ? angleByVertex( v ) : -M_PI );
edgeVec.push_back( *edge );
+ if ( theConsiderMesh && isThereVariants )
+ {
+ if ( SMESHDS_SubMesh* sm = helper.GetMeshDS()->MeshElements( *edge ))
+ nbSeg.push_back( sm->NbNodes() + 1 );
+ else
+ nbSeg.push_back( 0 );
+ }
}
// refine the result vector - make sides elual by length if