mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-04-08 10:57:26 +05:00
22361: EDF SMESH: Quadrangle (mapping) algorithm: faces with more than 4 edges
+ int GetCorners(const TopoDS_Face& theFace, + SMESH_Mesh & theMesh, + std::list<TopoDS_Edge>& theWire, + std::vector<TopoDS_Vertex>& theVertices, + int & theNbDegenEdges);
This commit is contained in:
parent
73df78c0c4
commit
dacd5b29c7
@ -41,14 +41,17 @@
|
|||||||
#include "StdMeshers_ViscousLayers2D.hxx"
|
#include "StdMeshers_ViscousLayers2D.hxx"
|
||||||
|
|
||||||
#include <BRep_Tool.hxx>
|
#include <BRep_Tool.hxx>
|
||||||
|
#include <GeomAPI_ProjectPointOnSurf.hxx>
|
||||||
#include <Geom_Surface.hxx>
|
#include <Geom_Surface.hxx>
|
||||||
#include <NCollection_DefineArray2.hxx>
|
#include <NCollection_DefineArray2.hxx>
|
||||||
#include <Precision.hxx>
|
#include <Precision.hxx>
|
||||||
#include <TColStd_SequenceOfReal.hxx>
|
#include <Quantity_Parameter.hxx>
|
||||||
#include <TColStd_SequenceOfInteger.hxx>
|
#include <TColStd_SequenceOfInteger.hxx>
|
||||||
|
#include <TColStd_SequenceOfReal.hxx>
|
||||||
#include <TColgp_SequenceOfXY.hxx>
|
#include <TColgp_SequenceOfXY.hxx>
|
||||||
#include <TopExp.hxx>
|
#include <TopExp.hxx>
|
||||||
#include <TopExp_Explorer.hxx>
|
#include <TopExp_Explorer.hxx>
|
||||||
|
#include <TopTools_DataMapOfShapeReal.hxx>
|
||||||
#include <TopTools_ListIteratorOfListOfShape.hxx>
|
#include <TopTools_ListIteratorOfListOfShape.hxx>
|
||||||
#include <TopTools_MapOfShape.hxx>
|
#include <TopTools_MapOfShape.hxx>
|
||||||
#include <TopoDS.hxx>
|
#include <TopoDS.hxx>
|
||||||
@ -71,7 +74,7 @@ typedef SMESH_Comment TComm;
|
|||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
/*!
|
/*!
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
@ -96,7 +99,7 @@ StdMeshers_Quadrangle_2D::StdMeshers_Quadrangle_2D (int hypId, int studyId,
|
|||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
/*!
|
/*!
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
@ -816,165 +819,101 @@ FaceQuadStruct::Ptr StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh &
|
|||||||
error(COMPERR_BAD_SHAPE, TComm("Wrong number of wires: ") << nbWire);
|
error(COMPERR_BAD_SHAPE, TComm("Wrong number of wires: ") << nbWire);
|
||||||
return FaceQuadStruct::Ptr();
|
return FaceQuadStruct::Ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// find corner vertices of the quad
|
||||||
|
vector<TopoDS_Vertex> corners;
|
||||||
|
int nbDegenEdges, nbSides = GetCorners( F, aMesh, edges, corners, nbDegenEdges );
|
||||||
|
if ( nbSides == 0 )
|
||||||
|
{
|
||||||
|
return FaceQuadStruct::Ptr();
|
||||||
|
}
|
||||||
FaceQuadStruct::Ptr quad( new FaceQuadStruct );
|
FaceQuadStruct::Ptr quad( new FaceQuadStruct );
|
||||||
quad->uv_grid = 0;
|
quad->uv_grid = 0;
|
||||||
quad->side.reserve(nbEdgesInWire.front());
|
quad->side.reserve(nbEdgesInWire.front());
|
||||||
quad->face = F;
|
quad->face = F;
|
||||||
|
|
||||||
int nbSides = 0;
|
|
||||||
list< TopoDS_Edge >::iterator edgeIt = edges.begin();
|
list< TopoDS_Edge >::iterator edgeIt = edges.begin();
|
||||||
if (nbEdgesInWire.front() == 3) // exactly 3 edges
|
if ( nbSides == 3 ) // 3 sides and corners[0] is a vertex with myTriaVertexID
|
||||||
{
|
{
|
||||||
SMESH_Comment comment;
|
for ( int iSide = 0; iSide < 3; ++iSide )
|
||||||
SMESHDS_Mesh* meshDS = aMesh.GetMeshDS();
|
|
||||||
if (myTriaVertexID < 1)
|
|
||||||
{
|
{
|
||||||
comment << "No Base vertex parameter provided for a trilateral geometrical face";
|
list< TopoDS_Edge > sideEdges;
|
||||||
|
TopoDS_Vertex nextSideV = corners[( iSide + 1 ) % 3 ];
|
||||||
|
while ( edgeIt != edges.end() &&
|
||||||
|
!nextSideV.IsSame( SMESH_MesherHelper::IthVertex( 0, *edgeIt )))
|
||||||
|
if ( SMESH_Algo::isDegenerated( *edgeIt ))
|
||||||
|
++edgeIt;
|
||||||
|
else
|
||||||
|
sideEdges.push_back( *edgeIt++ );
|
||||||
|
if ( !sideEdges.empty() )
|
||||||
|
quad->side.push_back(new StdMeshers_FaceSide(F, sideEdges, &aMesh, iSide < QUAD_TOP_SIDE,
|
||||||
|
ignoreMediumNodes, myProxyMesh));
|
||||||
|
else
|
||||||
|
--iSide;
|
||||||
}
|
}
|
||||||
else
|
const vector<UVPtStruct>& UVPSleft = quad->side[0]->GetUVPtStruct(true,0);
|
||||||
{
|
/* vector<UVPtStruct>& UVPStop = */quad->side[1]->GetUVPtStruct(false,1);
|
||||||
TopoDS_Vertex V = TopoDS::Vertex(meshDS->IndexToShape(myTriaVertexID));
|
/* vector<UVPtStruct>& UVPSright = */quad->side[2]->GetUVPtStruct(true,1);
|
||||||
if (!V.IsNull()) {
|
const SMDS_MeshNode* aNode = UVPSleft[0].node;
|
||||||
TopoDS_Edge E1,E2,E3;
|
gp_Pnt2d aPnt2d(UVPSleft[0].u, UVPSleft[0].v);
|
||||||
for (; edgeIt != edges.end(); ++edgeIt) {
|
quad->side.push_back(new StdMeshers_FaceSide(quad->side[1], aNode, &aPnt2d));
|
||||||
TopoDS_Edge E = *edgeIt;
|
myNeedSmooth = ( nbDegenEdges > 0 );
|
||||||
TopoDS_Vertex VF, VL;
|
|
||||||
TopExp::Vertices(E, VF, VL, true);
|
|
||||||
if (VF.IsSame(V))
|
|
||||||
E1 = E;
|
|
||||||
else if (VL.IsSame(V))
|
|
||||||
E3 = E;
|
|
||||||
else
|
|
||||||
E2 = E;
|
|
||||||
}
|
|
||||||
if (!E1.IsNull() && !E2.IsNull() && !E3.IsNull())
|
|
||||||
{
|
|
||||||
quad->side.push_back(new StdMeshers_FaceSide(F, E1, &aMesh, true,
|
|
||||||
ignoreMediumNodes, myProxyMesh));
|
|
||||||
quad->side.push_back(new StdMeshers_FaceSide(F, E2, &aMesh, true,
|
|
||||||
ignoreMediumNodes, myProxyMesh));
|
|
||||||
quad->side.push_back(new StdMeshers_FaceSide(F, E3, &aMesh, false,
|
|
||||||
ignoreMediumNodes, myProxyMesh));
|
|
||||||
const vector<UVPtStruct>& UVPSleft = quad->side[0]->GetUVPtStruct(true,0);
|
|
||||||
/* vector<UVPtStruct>& UVPStop = */quad->side[1]->GetUVPtStruct(false,1);
|
|
||||||
/* vector<UVPtStruct>& UVPSright = */quad->side[2]->GetUVPtStruct(true,1);
|
|
||||||
const SMDS_MeshNode* aNode = UVPSleft[0].node;
|
|
||||||
gp_Pnt2d aPnt2d(UVPSleft[0].u, UVPSleft[0].v);
|
|
||||||
quad->side.push_back(new StdMeshers_FaceSide(aNode, aPnt2d, quad->side[1]));
|
|
||||||
return quad;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
comment << "Invalid Base vertex parameter: " << myTriaVertexID << " is not among [";
|
|
||||||
TopTools_MapOfShape vMap;
|
|
||||||
for (TopExp_Explorer v(aShape, TopAbs_VERTEX); v.More(); v.Next())
|
|
||||||
if (vMap.Add(v.Current()))
|
|
||||||
comment << meshDS->ShapeToIndex(v.Current()) << (vMap.Extent()==3 ? "]" : ", ");
|
|
||||||
}
|
|
||||||
error(comment);
|
|
||||||
quad.reset();
|
|
||||||
return quad;
|
return quad;
|
||||||
}
|
}
|
||||||
else if (nbEdgesInWire.front() == 4) // exactly 4 edges
|
else // 4 sides
|
||||||
{
|
{
|
||||||
for (; edgeIt != edges.end(); ++edgeIt, nbSides++)
|
myNeedSmooth = ( corners.size() == 4 && nbDegenEdges > 0 );
|
||||||
quad->side.push_back(new StdMeshers_FaceSide(F, *edgeIt, &aMesh, nbSides < QUAD_TOP_SIDE,
|
int iSide = 0, nbUsedDegen = 0, nbLoops = 0;
|
||||||
ignoreMediumNodes, myProxyMesh));
|
for ( ; edgeIt != edges.end(); ++nbLoops )
|
||||||
}
|
|
||||||
else if (nbEdgesInWire.front() > 4) // more than 4 edges - try to unite some
|
|
||||||
{
|
|
||||||
list< TopoDS_Edge > sideEdges;
|
|
||||||
vector< int > degenSides;
|
|
||||||
while (!edges.empty()) {
|
|
||||||
sideEdges.clear();
|
|
||||||
sideEdges.splice(sideEdges.end(), edges, edges.begin()); // edges.front() -> sideEdges.end()
|
|
||||||
bool sameSide = true;
|
|
||||||
while (!edges.empty() && sameSide) {
|
|
||||||
sameSide = SMESH_Algo::IsContinuous(sideEdges.back(), edges.front());
|
|
||||||
if (sameSide)
|
|
||||||
sideEdges.splice(sideEdges.end(), edges, edges.begin());
|
|
||||||
}
|
|
||||||
if (nbSides == 0) { // go backward from the first edge
|
|
||||||
sameSide = true;
|
|
||||||
while (!edges.empty() && sameSide) {
|
|
||||||
sameSide = SMESH_Algo::IsContinuous(sideEdges.front(), edges.back());
|
|
||||||
if (sameSide)
|
|
||||||
sideEdges.splice(sideEdges.begin(), edges, --edges.end());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( sideEdges.size() == 1 && SMESH_Algo::isDegenerated( sideEdges.front() ))
|
|
||||||
degenSides.push_back( nbSides );
|
|
||||||
|
|
||||||
quad->side.push_back(new StdMeshers_FaceSide(F, sideEdges, &aMesh, nbSides < QUAD_TOP_SIDE,
|
|
||||||
ignoreMediumNodes, myProxyMesh));
|
|
||||||
++nbSides;
|
|
||||||
}
|
|
||||||
if ( !degenSides.empty() && nbSides - degenSides.size() == 4 )
|
|
||||||
{
|
{
|
||||||
myNeedSmooth = true;
|
list< TopoDS_Edge > sideEdges;
|
||||||
for ( unsigned i = QUAD_TOP_SIDE; i < quad->side.size(); ++i )
|
TopoDS_Vertex nextSideV = corners[( iSide + 1 - nbUsedDegen ) % corners.size() ];
|
||||||
quad->side[i]->Reverse();
|
while ( edgeIt != edges.end() &&
|
||||||
|
!nextSideV.IsSame( myHelper->IthVertex( 0, *edgeIt )))
|
||||||
for ( int i = degenSides.size()-1; i > -1; --i )
|
|
||||||
{
|
{
|
||||||
StdMeshers_FaceSide* degenSide = quad->side[ degenSides[ i ]];
|
if ( SMESH_Algo::isDegenerated( *edgeIt ))
|
||||||
delete degenSide;
|
{
|
||||||
quad->side.erase( quad->side.begin() + degenSides[ i ] );
|
if ( myNeedSmooth )
|
||||||
}
|
{
|
||||||
for ( unsigned i = QUAD_TOP_SIDE; i < quad->side.size(); ++i )
|
++edgeIt; // no side on the degenerated EDGE
|
||||||
quad->side[i]->Reverse();
|
}
|
||||||
|
else
|
||||||
nbSides -= degenSides.size();
|
{
|
||||||
}
|
if ( sideEdges.empty() )
|
||||||
// issue 20222. Try to unite only edges shared by two same faces
|
{
|
||||||
if (nbSides < 4)
|
++nbUsedDegen;
|
||||||
{
|
sideEdges.push_back( *edgeIt++ ); // a degenerated side
|
||||||
quad.reset( new FaceQuadStruct );
|
break;
|
||||||
quad->side.reserve(nbEdgesInWire.front());
|
}
|
||||||
nbSides = 0;
|
else
|
||||||
|
{
|
||||||
SMESH_Block::GetOrderedEdges (F, edges, nbEdgesInWire);
|
break; // do not append a degenerated EDGE to a regular side
|
||||||
while (!edges.empty()) {
|
}
|
||||||
sideEdges.clear();
|
|
||||||
sideEdges.splice(sideEdges.end(), edges, edges.begin());
|
|
||||||
bool sameSide = true;
|
|
||||||
while (!edges.empty() && sameSide) {
|
|
||||||
sameSide =
|
|
||||||
SMESH_Algo::IsContinuous(sideEdges.back(), edges.front()) &&
|
|
||||||
twoEdgesMeatAtVertex(sideEdges.back(), edges.front(), aMesh);
|
|
||||||
if (sameSide)
|
|
||||||
sideEdges.splice(sideEdges.end(), edges, edges.begin());
|
|
||||||
}
|
|
||||||
if (nbSides == 0) { // go backward from the first edge
|
|
||||||
sameSide = true;
|
|
||||||
while (!edges.empty() && sameSide) {
|
|
||||||
sameSide =
|
|
||||||
SMESH_Algo::IsContinuous(sideEdges.front(), edges.back()) &&
|
|
||||||
twoEdgesMeatAtVertex(sideEdges.front(), edges.back(), aMesh);
|
|
||||||
if (sameSide)
|
|
||||||
sideEdges.splice(sideEdges.begin(), edges, --edges.end());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
quad->side.push_back(new StdMeshers_FaceSide(F, sideEdges, &aMesh,
|
else
|
||||||
nbSides < QUAD_TOP_SIDE,
|
{
|
||||||
|
sideEdges.push_back( *edgeIt++ );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( !sideEdges.empty() )
|
||||||
|
{
|
||||||
|
quad->side.push_back(new StdMeshers_FaceSide(F, sideEdges, &aMesh, iSide < QUAD_TOP_SIDE,
|
||||||
ignoreMediumNodes, myProxyMesh));
|
ignoreMediumNodes, myProxyMesh));
|
||||||
++nbSides;
|
++iSide;
|
||||||
|
}
|
||||||
|
if ( nbLoops > 8 )
|
||||||
|
{
|
||||||
|
error(TComm("Bug: infinite loop in StdMeshers_Quadrangle_2D::CheckNbEdges()"));
|
||||||
|
quad.reset();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if ( quad->side.size() != 4 )
|
||||||
if (nbSides != 4 ) {
|
{
|
||||||
#ifdef _DEBUG_
|
error(TComm("Bug: ") << quad->side.size() << " sides found instead of 4");
|
||||||
MESSAGE ("StdMeshers_Quadrangle_2D. Edge IDs of " << nbSides << " sides:\n");
|
quad.reset();
|
||||||
for (int i = 0; i < nbSides; ++i) {
|
|
||||||
MESSAGE (" (");
|
|
||||||
for (int e = 0; e < quad->side[i]->NbEdges(); ++e)
|
|
||||||
MESSAGE (aMesh.GetMeshDS()->ShapeToIndex(quad->side[i]->Edge(e)) << " ");
|
|
||||||
MESSAGE (")\n");
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
if (!nbSides)
|
|
||||||
nbSides = nbEdgesInWire.front();
|
|
||||||
error(COMPERR_BAD_SHAPE, TComm("Face must have 4 sides but not ") << nbSides);
|
|
||||||
quad.reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return quad;
|
return quad;
|
||||||
@ -1268,6 +1207,8 @@ bool StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh,
|
|||||||
|
|
||||||
// 3 --- 2D normalized values on unit square [0..1][0..1]
|
// 3 --- 2D normalized values on unit square [0..1][0..1]
|
||||||
|
|
||||||
|
UpdateDegenUV( quad );
|
||||||
|
|
||||||
int nbhoriz = Min(quad->side[0]->NbPoints(), quad->side[2]->NbPoints());
|
int nbhoriz = Min(quad->side[0]->NbPoints(), quad->side[2]->NbPoints());
|
||||||
int nbvertic = Min(quad->side[1]->NbPoints(), quad->side[3]->NbPoints());
|
int nbvertic = Min(quad->side[1]->NbPoints(), quad->side[3]->NbPoints());
|
||||||
|
|
||||||
@ -1287,9 +1228,6 @@ bool StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh,
|
|||||||
//return error("Can't find nodes on sides");
|
//return error("Can't find nodes on sides");
|
||||||
return error(COMPERR_BAD_INPUT_MESH);
|
return error(COMPERR_BAD_INPUT_MESH);
|
||||||
|
|
||||||
if ( myNeedSmooth )
|
|
||||||
UpdateDegenUV( quad );
|
|
||||||
|
|
||||||
// copy data of face boundary
|
// copy data of face boundary
|
||||||
/*if (! quad->isEdgeOut[0])*/ {
|
/*if (! quad->isEdgeOut[0])*/ {
|
||||||
const int j = 0;
|
const int j = 0;
|
||||||
@ -1543,8 +1481,7 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh,
|
|||||||
if (uv_eb.size() != nb || uv_er.size() != nr || uv_et.size() != nt || uv_el.size() != nl)
|
if (uv_eb.size() != nb || uv_er.size() != nr || uv_et.size() != nt || uv_el.size() != nl)
|
||||||
return error(COMPERR_BAD_INPUT_MESH);
|
return error(COMPERR_BAD_INPUT_MESH);
|
||||||
|
|
||||||
if ( myNeedSmooth )
|
UpdateDegenUV( quad );
|
||||||
UpdateDegenUV( quad );
|
|
||||||
|
|
||||||
// arrays for normalized params
|
// arrays for normalized params
|
||||||
TColStd_SequenceOfReal npb, npr, npt, npl;
|
TColStd_SequenceOfReal npb, npr, npt, npl;
|
||||||
@ -2457,8 +2394,7 @@ bool StdMeshers_Quadrangle_2D::ComputeReduced (SMESH_Mesh & aMesh,
|
|||||||
if (uv_eb.size() != nb || uv_er.size() != nr || uv_et.size() != nt || uv_el.size() != nl)
|
if (uv_eb.size() != nb || uv_er.size() != nr || uv_et.size() != nt || uv_el.size() != nl)
|
||||||
return error(COMPERR_BAD_INPUT_MESH);
|
return error(COMPERR_BAD_INPUT_MESH);
|
||||||
|
|
||||||
if ( myNeedSmooth )
|
UpdateDegenUV( quad );
|
||||||
UpdateDegenUV( quad );
|
|
||||||
|
|
||||||
// arrays for normalized params
|
// arrays for normalized params
|
||||||
TColStd_SequenceOfReal npb, npr, npt, npl;
|
TColStd_SequenceOfReal npb, npr, npt, npl;
|
||||||
@ -3265,7 +3201,8 @@ namespace // data for smoothing
|
|||||||
*/
|
*/
|
||||||
struct TSmoothNode
|
struct TSmoothNode
|
||||||
{
|
{
|
||||||
gp_XY _uv;
|
gp_XY _uv;
|
||||||
|
gp_XYZ _xyz;
|
||||||
vector< TTriangle > _triangles; // if empty, then node is not movable
|
vector< TTriangle > _triangles; // if empty, then node is not movable
|
||||||
};
|
};
|
||||||
// --------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------
|
||||||
@ -3287,41 +3224,70 @@ namespace // data for smoothing
|
|||||||
|
|
||||||
void StdMeshers_Quadrangle_2D::UpdateDegenUV(FaceQuadStruct::Ptr quad)
|
void StdMeshers_Quadrangle_2D::UpdateDegenUV(FaceQuadStruct::Ptr quad)
|
||||||
{
|
{
|
||||||
for ( unsigned i = 0; i < quad->side.size(); ++i )
|
if ( myNeedSmooth )
|
||||||
{
|
|
||||||
StdMeshers_FaceSide* side = quad->side[i];
|
|
||||||
const vector<UVPtStruct>& uvVec = side->GetUVPtStruct();
|
|
||||||
|
|
||||||
// find which end of the side is on degenerated shape
|
// Set UV of nodes on degenerated VERTEXes in the middle of degenerated EDGE
|
||||||
int degenInd = -1;
|
// --------------------------------------------------------------------------
|
||||||
if ( myHelper->IsDegenShape( uvVec[0].node->getshapeId() ))
|
for ( unsigned i = 0; i < quad->side.size(); ++i )
|
||||||
degenInd = 0;
|
{
|
||||||
else if ( myHelper->IsDegenShape( uvVec.back().node->getshapeId() ))
|
StdMeshers_FaceSide* side = quad->side[i];
|
||||||
degenInd = uvVec.size() - 1;
|
const vector<UVPtStruct>& uvVec = side->GetUVPtStruct();
|
||||||
else
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// find another side sharing the degenerated shape
|
// find which end of the side is on degenerated shape
|
||||||
bool isPrev = ( degenInd == 0 );
|
int degenInd = -1;
|
||||||
if ( i >= QUAD_TOP_SIDE )
|
if ( myHelper->IsDegenShape( uvVec[0].node->getshapeId() ))
|
||||||
isPrev = !isPrev;
|
degenInd = 0;
|
||||||
int i2 = ( isPrev ? ( i + 3 ) : ( i + 1 )) % 4;
|
else if ( myHelper->IsDegenShape( uvVec.back().node->getshapeId() ))
|
||||||
StdMeshers_FaceSide* side2 = quad->side[ i2 ];
|
degenInd = uvVec.size() - 1;
|
||||||
const vector<UVPtStruct>& uvVec2 = side2->GetUVPtStruct();
|
else
|
||||||
int degenInd2 = -1;
|
continue;
|
||||||
if ( uvVec[ degenInd ].node == uvVec2[0].node )
|
|
||||||
degenInd2 = 0;
|
|
||||||
else if ( uvVec[ degenInd ].node == uvVec2.back().node )
|
|
||||||
degenInd2 = uvVec2.size() - 1;
|
|
||||||
else
|
|
||||||
throw SALOME_Exception( LOCALIZED( "Logical error" ));
|
|
||||||
|
|
||||||
// move UV in the middle
|
// find another side sharing the degenerated shape
|
||||||
uvPtStruct& uv1 = const_cast<uvPtStruct&>( uvVec [ degenInd ]);
|
bool isPrev = ( degenInd == 0 );
|
||||||
uvPtStruct& uv2 = const_cast<uvPtStruct&>( uvVec2[ degenInd2 ]);
|
if ( i >= QUAD_TOP_SIDE )
|
||||||
uv1.u = uv2.u = 0.5 * ( uv1.u + uv2.u );
|
isPrev = !isPrev;
|
||||||
uv1.v = uv2.v = 0.5 * ( uv1.v + uv2.v );
|
int i2 = ( isPrev ? ( i + 3 ) : ( i + 1 )) % 4;
|
||||||
}
|
StdMeshers_FaceSide* side2 = quad->side[ i2 ];
|
||||||
|
const vector<UVPtStruct>& uvVec2 = side2->GetUVPtStruct();
|
||||||
|
int degenInd2 = -1;
|
||||||
|
if ( uvVec[ degenInd ].node == uvVec2[0].node )
|
||||||
|
degenInd2 = 0;
|
||||||
|
else if ( uvVec[ degenInd ].node == uvVec2.back().node )
|
||||||
|
degenInd2 = uvVec2.size() - 1;
|
||||||
|
else
|
||||||
|
throw SALOME_Exception( LOCALIZED( "Logical error" ));
|
||||||
|
|
||||||
|
// move UV in the middle
|
||||||
|
uvPtStruct& uv1 = const_cast<uvPtStruct&>( uvVec [ degenInd ]);
|
||||||
|
uvPtStruct& uv2 = const_cast<uvPtStruct&>( uvVec2[ degenInd2 ]);
|
||||||
|
uv1.u = uv2.u = 0.5 * ( uv1.u + uv2.u );
|
||||||
|
uv1.v = uv2.v = 0.5 * ( uv1.v + uv2.v );
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ( quad->side.size() == 4 )
|
||||||
|
|
||||||
|
// Set number of nodes on a degenerated side to be same as on an opposite side
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
for ( unsigned i = 0; i < quad->side.size(); ++i )
|
||||||
|
{
|
||||||
|
StdMeshers_FaceSide* degSide = quad->side[i];
|
||||||
|
if ( !myHelper->IsDegenShape( degSide->EdgeID(0) ))
|
||||||
|
continue;
|
||||||
|
StdMeshers_FaceSide* oppSide = quad->side[( i+2 ) % quad->side.size() ];
|
||||||
|
if ( degSide->NbSegments() == oppSide->NbSegments() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// make new side data
|
||||||
|
const vector<UVPtStruct>& uvVecDegOld = degSide->GetUVPtStruct();
|
||||||
|
const SMDS_MeshNode* n = uvVecDegOld[0].node;
|
||||||
|
Handle(Geom2d_Curve) c2d = degSide->Curve2d(0);
|
||||||
|
double f = degSide->FirstU(0), l = degSide->LastU(0);
|
||||||
|
gp_Pnt2d p1( uvVecDegOld.front().u, uvVecDegOld.front().v );
|
||||||
|
gp_Pnt2d p2( uvVecDegOld.back().u, uvVecDegOld.back().v );
|
||||||
|
|
||||||
|
delete degSide;
|
||||||
|
quad->side[i] = new StdMeshers_FaceSide( oppSide, n, &p1, &p2, c2d, f, l );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
@ -3339,15 +3305,22 @@ void StdMeshers_Quadrangle_2D::Smooth (FaceQuadStruct::Ptr quad)
|
|||||||
typedef map< const SMDS_MeshNode*, TSmoothNode, TIDCompare > TNo2SmooNoMap;
|
typedef map< const SMDS_MeshNode*, TSmoothNode, TIDCompare > TNo2SmooNoMap;
|
||||||
TNo2SmooNoMap smooNoMap;
|
TNo2SmooNoMap smooNoMap;
|
||||||
|
|
||||||
const TopoDS_Face& geomFace = TopoDS::Face( myHelper->GetSubShape() );
|
const TopoDS_Face& geomFace = TopoDS::Face( myHelper->GetSubShape() );
|
||||||
SMESHDS_Mesh* meshDS = myHelper->GetMeshDS();
|
Handle(Geom_Surface) surface = BRep_Tool::Surface( geomFace );
|
||||||
SMESHDS_SubMesh* fSubMesh = meshDS->MeshElements( geomFace );
|
double U1, U2, V1, V2;
|
||||||
SMDS_NodeIteratorPtr nIt = fSubMesh->GetNodes();
|
surface->Bounds(U1, U2, V1, V2);
|
||||||
|
GeomAPI_ProjectPointOnSurf proj;
|
||||||
|
proj.Init( surface, U1, U2, V1, V2, BRep_Tool::Tolerance( geomFace ) );
|
||||||
|
|
||||||
|
SMESHDS_Mesh* meshDS = myHelper->GetMeshDS();
|
||||||
|
SMESHDS_SubMesh* fSubMesh = meshDS->MeshElements( geomFace );
|
||||||
|
SMDS_NodeIteratorPtr nIt = fSubMesh->GetNodes();
|
||||||
while ( nIt->more() ) // loop on nodes bound to a FACE
|
while ( nIt->more() ) // loop on nodes bound to a FACE
|
||||||
{
|
{
|
||||||
const SMDS_MeshNode* node = nIt->next();
|
const SMDS_MeshNode* node = nIt->next();
|
||||||
TSmoothNode & sNode = smooNoMap[ node ];
|
TSmoothNode & sNode = smooNoMap[ node ];
|
||||||
sNode._uv = myHelper->GetNodeUV( geomFace, node );
|
sNode._uv = myHelper->GetNodeUV( geomFace, node );
|
||||||
|
sNode._xyz = SMESH_TNodeXYZ( node );
|
||||||
|
|
||||||
// set sNode._triangles
|
// set sNode._triangles
|
||||||
SMDS_ElemIteratorPtr fIt = node->GetInverseElementIterator( SMDSAbs_Face );
|
SMDS_ElemIteratorPtr fIt = node->GetInverseElementIterator( SMDSAbs_Face );
|
||||||
@ -3372,6 +3345,7 @@ void StdMeshers_Quadrangle_2D::Smooth (FaceQuadStruct::Ptr quad)
|
|||||||
{
|
{
|
||||||
TSmoothNode & sNode = smooNoMap[ uvVec[j].node ];
|
TSmoothNode & sNode = smooNoMap[ uvVec[j].node ];
|
||||||
sNode._uv.SetCoord( uvVec[j].u, uvVec[j].v );
|
sNode._uv.SetCoord( uvVec[j].u, uvVec[j].v );
|
||||||
|
sNode._xyz = SMESH_TNodeXYZ( uvVec[j].node );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3394,26 +3368,48 @@ void StdMeshers_Quadrangle_2D::Smooth (FaceQuadStruct::Ptr quad)
|
|||||||
if ( sNode._triangles.empty() )
|
if ( sNode._triangles.empty() )
|
||||||
continue; // not movable node
|
continue; // not movable node
|
||||||
|
|
||||||
// compute a new UV
|
// compute a new XYZ
|
||||||
gp_XY newUV (0,0);
|
gp_XYZ newXYZ (0,0,0);
|
||||||
for ( unsigned i = 0; i < sNode._triangles.size(); ++i )
|
for ( unsigned i = 0; i < sNode._triangles.size(); ++i )
|
||||||
newUV += sNode._triangles[i]._n1->_uv;
|
newXYZ += sNode._triangles[i]._n1->_xyz;
|
||||||
newUV /= sNode._triangles.size();
|
newXYZ /= sNode._triangles.size();
|
||||||
|
|
||||||
// check validity of the newUV
|
|
||||||
bool isValid = true;
|
|
||||||
for ( unsigned i = 0; i < sNode._triangles.size() && isValid; ++i )
|
|
||||||
isValid = ( sNode._triangles[i].IsForward( newUV ) == refForward );
|
|
||||||
|
|
||||||
|
// compute a new UV by projection
|
||||||
|
gp_XY newUV;
|
||||||
|
proj.Perform( newXYZ );
|
||||||
|
bool isValid = ( proj.IsDone() && proj.NbPoints() > 0 );
|
||||||
if ( isValid )
|
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 )
|
||||||
|
{
|
||||||
|
// compute a new UV by averaging
|
||||||
|
newUV.SetCoord(0.,0.);
|
||||||
|
for ( unsigned i = 0; i < sNode._triangles.size(); ++i )
|
||||||
|
newUV += sNode._triangles[i]._n1->_uv;
|
||||||
|
newUV /= sNode._triangles.size();
|
||||||
|
|
||||||
|
// check validity of the newUV
|
||||||
|
isValid = true;
|
||||||
|
for ( unsigned i = 0; i < sNode._triangles.size() && isValid; ++i )
|
||||||
|
isValid = ( sNode._triangles[i].IsForward( newUV ) == refForward );
|
||||||
|
}
|
||||||
|
if ( isValid )
|
||||||
|
{
|
||||||
sNode._uv = newUV;
|
sNode._uv = newUV;
|
||||||
|
sNode._xyz = surface->Value( newUV.X(), newUV.Y() ).XYZ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set new XYZ to the smoothed nodes
|
// Set new XYZ to the smoothed nodes
|
||||||
|
|
||||||
Handle(Geom_Surface) surface = BRep_Tool::Surface( geomFace );
|
|
||||||
|
|
||||||
for ( n2sn = smooNoMap.begin(); n2sn != smooNoMap.end(); ++n2sn )
|
for ( n2sn = smooNoMap.begin(); n2sn != smooNoMap.end(); ++n2sn )
|
||||||
{
|
{
|
||||||
TSmoothNode& sNode = n2sn->second;
|
TSmoothNode& sNode = n2sn->second;
|
||||||
@ -3452,3 +3448,238 @@ void StdMeshers_Quadrangle_2D::Smooth (FaceQuadStruct::Ptr quad)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*//================================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Finds vertices at the most sharp face corners
|
||||||
|
* \param [in] theFace - the FACE
|
||||||
|
* \param [in,out] theWire - the ordered edges of the face. It can be modified to
|
||||||
|
* have the first VERTEX of the first EDGE in \a vertices
|
||||||
|
* \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
|
||||||
|
* \return int - number of quad sides found: 0, 3 or 4
|
||||||
|
*/
|
||||||
|
//================================================================================
|
||||||
|
|
||||||
|
int StdMeshers_Quadrangle_2D::GetCorners(const TopoDS_Face& theFace,
|
||||||
|
SMESH_Mesh & theMesh,
|
||||||
|
std::list<TopoDS_Edge>& theWire,
|
||||||
|
std::vector<TopoDS_Vertex>& theVertices,
|
||||||
|
int & theNbDegenEdges)
|
||||||
|
{
|
||||||
|
theNbDegenEdges = 0;
|
||||||
|
|
||||||
|
SMESH_MesherHelper helper( theMesh );
|
||||||
|
|
||||||
|
// sort theVertices by angle
|
||||||
|
multimap<double, TopoDS_Vertex> vertexByAngle;
|
||||||
|
TopTools_DataMapOfShapeReal angleByVertex;
|
||||||
|
TopoDS_Edge prevE = theWire.back();
|
||||||
|
if ( SMESH_Algo::isDegenerated( prevE ))
|
||||||
|
{
|
||||||
|
list<TopoDS_Edge>::reverse_iterator edge = ++theWire.rbegin();
|
||||||
|
while ( SMESH_Algo::isDegenerated( *edge ))
|
||||||
|
++edge;
|
||||||
|
if ( edge == theWire.rend() )
|
||||||
|
return false;
|
||||||
|
prevE = *edge;
|
||||||
|
}
|
||||||
|
list<TopoDS_Edge>::iterator edge = theWire.begin();
|
||||||
|
for ( ; edge != theWire.end(); ++edge )
|
||||||
|
{
|
||||||
|
if ( SMESH_Algo::isDegenerated( *edge ))
|
||||||
|
{
|
||||||
|
++theNbDegenEdges;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
TopoDS_Vertex v = helper.IthVertex( 0, *edge );
|
||||||
|
if ( SMESH_Algo::VertexNode( v, helper.GetMeshDS() ))
|
||||||
|
{
|
||||||
|
double angle = SMESH_MesherHelper::GetAngle( prevE, *edge, theFace );
|
||||||
|
vertexByAngle.insert( make_pair( angle, v ));
|
||||||
|
angleByVertex.Bind( v, angle );
|
||||||
|
}
|
||||||
|
prevE = *edge;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find out required nb of corners (3 or 4)
|
||||||
|
int nbCorners = 4;
|
||||||
|
TopoDS_Shape triaVertex = helper.GetMeshDS()->IndexToShape( myTriaVertexID );
|
||||||
|
if ( !triaVertex.IsNull() &&
|
||||||
|
triaVertex.ShapeType() == TopAbs_VERTEX &&
|
||||||
|
helper.IsSubShape( triaVertex, theFace ))
|
||||||
|
nbCorners = 3;
|
||||||
|
else
|
||||||
|
triaVertex.Nullify();
|
||||||
|
|
||||||
|
// check nb of available corners
|
||||||
|
if ( nbCorners == 3 )
|
||||||
|
{
|
||||||
|
if ( vertexByAngle.size() < 3 )
|
||||||
|
return error(COMPERR_BAD_SHAPE,
|
||||||
|
TComm("Face must have 3 sides but not ") << vertexByAngle.size() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( vertexByAngle.size() == 3 && theNbDegenEdges == 0 )
|
||||||
|
{
|
||||||
|
if ( myTriaVertexID < 1 )
|
||||||
|
return error(COMPERR_BAD_PARMETERS,
|
||||||
|
"No Base vertex provided for a trilateral geometrical face");
|
||||||
|
|
||||||
|
TComm comment("Invalid Base vertex: ");
|
||||||
|
comment << myTriaVertexID << " its ID is not among [ ";
|
||||||
|
multimap<double, TopoDS_Vertex>::iterator a2v = vertexByAngle.begin();
|
||||||
|
comment << helper.GetMeshDS()->ShapeToIndex( a2v->second ) << ", "; a2v++;
|
||||||
|
comment << helper.GetMeshDS()->ShapeToIndex( a2v->second ) << ", "; a2v++;
|
||||||
|
comment << helper.GetMeshDS()->ShapeToIndex( a2v->second ) << " ]";
|
||||||
|
return error(COMPERR_BAD_PARMETERS, comment );
|
||||||
|
}
|
||||||
|
if ( vertexByAngle.size() + ( theNbDegenEdges > 0 ) < 4 &&
|
||||||
|
vertexByAngle.size() + theNbDegenEdges != 4 )
|
||||||
|
return error(COMPERR_BAD_SHAPE,
|
||||||
|
TComm("Face must have 4 sides but not ") << vertexByAngle.size() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// put all corner vertices in a map
|
||||||
|
TopTools_MapOfShape vMap;
|
||||||
|
if ( nbCorners == 3 )
|
||||||
|
vMap.Add( triaVertex );
|
||||||
|
multimap<double, TopoDS_Vertex>::reverse_iterator a2v = vertexByAngle.rbegin();
|
||||||
|
for ( ; a2v != vertexByAngle.rend() && vMap.Extent() < nbCorners; ++a2v )
|
||||||
|
vMap.Add( (*a2v).second );
|
||||||
|
|
||||||
|
// check if there are possible variations in choosing corners
|
||||||
|
bool isThereVariants = false;
|
||||||
|
if ( vertexByAngle.size() > nbCorners )
|
||||||
|
{
|
||||||
|
double lostAngle = a2v->first;
|
||||||
|
double lastAngle = ( --a2v, a2v->first );
|
||||||
|
isThereVariants = ( lostAngle * 1.1 >= lastAngle );
|
||||||
|
}
|
||||||
|
|
||||||
|
// make theWire begin from a corner vertex or triaVertex
|
||||||
|
if ( nbCorners == 3 )
|
||||||
|
while ( !triaVertex.IsSame( ( helper.IthVertex( 0, theWire.front() ))) ||
|
||||||
|
SMESH_Algo::isDegenerated( theWire.front() ))
|
||||||
|
theWire.splice( theWire.end(), theWire, theWire.begin() );
|
||||||
|
else
|
||||||
|
while ( !vMap.Contains( helper.IthVertex( 0, theWire.front() )) ||
|
||||||
|
SMESH_Algo::isDegenerated( theWire.front() ))
|
||||||
|
theWire.splice( theWire.end(), theWire, theWire.begin() );
|
||||||
|
|
||||||
|
// fill the result vector and prepare for its refinement
|
||||||
|
theVertices.clear();
|
||||||
|
vector< double > angles;
|
||||||
|
vector< TopoDS_Edge > edgeVec;
|
||||||
|
vector< int > cornerInd;
|
||||||
|
angles.reserve( vertexByAngle.size() );
|
||||||
|
edgeVec.reserve( vertexByAngle.size() );
|
||||||
|
cornerInd.reserve( nbCorners );
|
||||||
|
for ( edge = theWire.begin(); edge != theWire.end(); ++edge )
|
||||||
|
{
|
||||||
|
if ( SMESH_Algo::isDegenerated( *edge ))
|
||||||
|
continue;
|
||||||
|
TopoDS_Vertex v = helper.IthVertex( 0, *edge );
|
||||||
|
bool isCorner = vMap.Contains( v );
|
||||||
|
if ( isCorner )
|
||||||
|
{
|
||||||
|
theVertices.push_back( v );
|
||||||
|
cornerInd.push_back( angles.size() );
|
||||||
|
}
|
||||||
|
angles.push_back( angleByVertex( v ));
|
||||||
|
edgeVec.push_back( *edge );
|
||||||
|
}
|
||||||
|
|
||||||
|
// refine the result vector - make sides elual by length if
|
||||||
|
// there are several equal angles
|
||||||
|
if ( isThereVariants )
|
||||||
|
{
|
||||||
|
if ( nbCorners == 3 )
|
||||||
|
angles[0] = 2 * M_PI; // not to move the base triangle VERTEX
|
||||||
|
|
||||||
|
set< int > refinedCorners;
|
||||||
|
for ( size_t iC = 0; iC < cornerInd.size(); ++iC )
|
||||||
|
{
|
||||||
|
int iV = cornerInd[iC];
|
||||||
|
if ( !refinedCorners.insert( iV ).second )
|
||||||
|
continue;
|
||||||
|
list< int > equalVertices;
|
||||||
|
equalVertices.push_back( iV );
|
||||||
|
int nbC[2] = { 0, 0 };
|
||||||
|
// find equal angles backward and forward from the iV-th corner vertex
|
||||||
|
for ( int isFwd = 0; isFwd < 2; ++isFwd )
|
||||||
|
{
|
||||||
|
int dV = isFwd ? +1 : -1;
|
||||||
|
int iCNext = helper.WrapIndex( iC + dV, cornerInd.size() );
|
||||||
|
int iVNext = helper.WrapIndex( iV + dV, angles.size() );
|
||||||
|
while ( iVNext != iV )
|
||||||
|
{
|
||||||
|
bool equal = Abs( angles[iV] - angles[iVNext] ) < 0.1 * angles[iV];
|
||||||
|
if ( equal )
|
||||||
|
equalVertices.insert( isFwd ? equalVertices.end() : equalVertices.begin(), iVNext );
|
||||||
|
if ( iVNext == cornerInd[ iCNext ])
|
||||||
|
{
|
||||||
|
if ( !equal )
|
||||||
|
break;
|
||||||
|
nbC[ isFwd ]++;
|
||||||
|
refinedCorners.insert( cornerInd[ iCNext ] );
|
||||||
|
iCNext = helper.WrapIndex( iCNext + dV, cornerInd.size() );
|
||||||
|
}
|
||||||
|
iVNext = helper.WrapIndex( iVNext + dV, angles.size() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// move corners to make sides equal by length
|
||||||
|
int nbEqualV = equalVertices.size();
|
||||||
|
int nbExcessV = nbEqualV - ( 1 + nbC[0] + nbC[1] );
|
||||||
|
if ( nbExcessV > 0 )
|
||||||
|
{
|
||||||
|
// calculate normalized length of each side enclosed between neighbor equalVertices
|
||||||
|
vector< double > curLengths;
|
||||||
|
double totalLen = 0;
|
||||||
|
vector< int > evVec( equalVertices.begin(), equalVertices.end() );
|
||||||
|
int iEV = 0;
|
||||||
|
int iE = cornerInd[ helper.WrapIndex( iC - nbC[0] - 1, cornerInd.size() )];
|
||||||
|
int iEEnd = cornerInd[ helper.WrapIndex( iC + nbC[1] + 1, cornerInd.size() )];
|
||||||
|
while ( curLengths.size() < nbEqualV + 1 )
|
||||||
|
{
|
||||||
|
curLengths.push_back( totalLen );
|
||||||
|
do {
|
||||||
|
curLengths.back() += SMESH_Algo::EdgeLength( edgeVec[ iE ]);
|
||||||
|
iE = helper.WrapIndex( iE + 1, edgeVec.size());
|
||||||
|
if ( iEV < evVec.size() && iE == evVec[ iEV++ ] )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while( iE != iEEnd );
|
||||||
|
totalLen = curLengths.back();
|
||||||
|
}
|
||||||
|
curLengths.resize( equalVertices.size() );
|
||||||
|
for ( size_t iS = 0; iS < curLengths.size(); ++iS )
|
||||||
|
curLengths[ iS ] /= totalLen;
|
||||||
|
|
||||||
|
// find equalVertices most close to the ideal sub-division of all sides
|
||||||
|
int iBestEV = 0;
|
||||||
|
int iCorner = helper.WrapIndex( iC - nbC[0], cornerInd.size() );
|
||||||
|
int nbSides = 2 + nbC[0] + nbC[1];
|
||||||
|
for ( int iS = 1; iS < nbSides; ++iS, ++iBestEV )
|
||||||
|
{
|
||||||
|
double idealLen = iS / double( nbSides );
|
||||||
|
double d, bestDist = 1.;
|
||||||
|
for ( iEV = iBestEV; iEV < curLengths.size(); ++iEV )
|
||||||
|
if (( d = Abs( idealLen - curLengths[ iEV ])) < bestDist )
|
||||||
|
{
|
||||||
|
bestDist = d;
|
||||||
|
iBestEV = iEV;
|
||||||
|
}
|
||||||
|
if ( iBestEV > iS-1 + nbExcessV )
|
||||||
|
iBestEV = iS-1 + nbExcessV;
|
||||||
|
theVertices[ iCorner ] = helper.IthVertex( 0, edgeVec[ evVec[ iBestEV ]]);
|
||||||
|
iCorner = helper.WrapIndex( iCorner + 1, cornerInd.size() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nbCorners;
|
||||||
|
}
|
||||||
|
@ -117,25 +117,25 @@ protected:
|
|||||||
|
|
||||||
void Smooth (FaceQuadStruct::Ptr quad);
|
void Smooth (FaceQuadStruct::Ptr quad);
|
||||||
|
|
||||||
|
int GetCorners(const TopoDS_Face& theFace,
|
||||||
|
SMESH_Mesh & theMesh,
|
||||||
|
std::list<TopoDS_Edge>& theWire,
|
||||||
|
std::vector<TopoDS_Vertex>& theVertices,
|
||||||
|
int & theNbDegenEdges);
|
||||||
|
|
||||||
|
|
||||||
// true if QuadranglePreference hypothesis is assigned that forces
|
// true if QuadranglePreference hypothesis is assigned that forces
|
||||||
// construction of quadrangles if the number of nodes on opposite edges
|
// construction of quadrangles if the number of nodes on opposite edges
|
||||||
// is not the same in the case where the global number of nodes on edges
|
// is not the same in the case where the global number of nodes on edges
|
||||||
// is even
|
// is even
|
||||||
bool myQuadranglePreference;
|
bool myQuadranglePreference;
|
||||||
|
|
||||||
bool myTrianglePreference;
|
bool myTrianglePreference;
|
||||||
|
|
||||||
int myTriaVertexID;
|
int myTriaVertexID;
|
||||||
|
|
||||||
bool myNeedSmooth;
|
bool myNeedSmooth;
|
||||||
|
|
||||||
StdMeshers_QuadType myQuadType;
|
StdMeshers_QuadType myQuadType;
|
||||||
|
|
||||||
SMESH_MesherHelper* myHelper; // tool for working with quadratic elements
|
SMESH_MesherHelper* myHelper; // tool for working with quadratic elements
|
||||||
|
|
||||||
SMESH_ProxyMesh::Ptr myProxyMesh;
|
SMESH_ProxyMesh::Ptr myProxyMesh;
|
||||||
|
|
||||||
FaceQuadStruct::Ptr myQuadStruct;
|
FaceQuadStruct::Ptr myQuadStruct;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user