1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

Compare commits

...

2 Commits

Author SHA1 Message Date
kgv
db453edb98 fix index of degenerated vertex within multiple faces 2016-06-15 19:48:20 +03:00
kgv
9a17f43739 0021753: Visualization - improve shaded display of conical objects
StdPrs_ShadedShape - duplicate nodes originated from degenerated edge with normal to triangle.
2016-06-14 16:38:56 +03:00

View File

@@ -140,6 +140,47 @@ namespace
}
}
//! Auxiliary function searching the degenerated node in the triangle.
//! Returns index of node in triangle (0, 1, 2) or -1 if degenerated node is not found.
Standard_Integer findDegenNodeInTri (const Handle(Poly_PolygonOnTriangulation)& theDegenPolygon,
const Standard_Integer* theTriNodeInd)
{
if (theTriNodeInd[0] == theDegenPolygon->Nodes().First()
|| theTriNodeInd[0] == theDegenPolygon->Nodes().Last())
{
return 0;
}
else if (theTriNodeInd[1] == theDegenPolygon->Nodes().First()
|| theTriNodeInd[1] == theDegenPolygon->Nodes().Last())
{
return 1;
}
else if (theTriNodeInd[2] == theDegenPolygon->Nodes().First()
|| theTriNodeInd[2] == theDegenPolygon->Nodes().Last())
{
return 2;
}
return -1;
}
//! Auxiliary function searching the degenerated node in the triangle.
//! Returns index of node in triangle (0, 1, 2) or -1 if degenerated node is not found.
Standard_Integer findDegenNodeInTri (const NCollection_Sequence<Handle(Poly_PolygonOnTriangulation)>& thePolygons,
const Standard_Integer* theTriNodeInd)
{
Standard_Integer aTriNode = -1;
for (NCollection_Sequence<Handle(Poly_PolygonOnTriangulation)>::Iterator anIter (thePolygons);
anIter.More(); anIter.Next())
{
aTriNode = findDegenNodeInTri (anIter.Value(), theTriNodeInd);
if (aTriNode != -1)
{
return aTriNode;
}
}
return -1;
}
//! Gets triangulation of every face of shape and fills output array of triangles
static Handle(Graphic3d_ArrayOfTriangles) fillTriangles (const TopoDS_Shape& theShape,
const Standard_Boolean theHasTexels,
@@ -148,10 +189,12 @@ namespace
const gp_Pnt2d& theUVScale)
{
Handle(Poly_Triangulation) aT;
TopLoc_Location aLoc;
TopLoc_Location aLoc, aLocDummy;
gp_Pnt aPoint;
Standard_Integer aNbTriangles = 0;
Standard_Integer aNbVertices = 0;
Standard_Boolean aNbDupNodes = 0;
Standard_Integer anIndex[3];
// Precision for compare square distances
const Standard_Real aPreci = Precision::SquareConfusion();
@@ -161,12 +204,39 @@ namespace
{
const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Current());
aT = BRep_Tool::Triangulation (aFace, aLoc);
if (!aT.IsNull())
if (aT.IsNull())
{
aNbTriangles += aT->NbTriangles();
aNbVertices += aT->NbNodes();
continue;
}
aNbTriangles += aT->NbTriangles();
aNbVertices += aT->NbNodes();
// estimate number of degenerated nodes to be duplicated
for (TopExp_Explorer anEdgeIt (aFace, TopAbs_EDGE); anEdgeIt.More(); anEdgeIt.Next())
{
const TopoDS_Edge& anEdge = TopoDS::Edge(anEdgeIt.Current());
if (BRep_Tool::Degenerated (anEdge))
{
Handle(Poly_PolygonOnTriangulation) anEdgePoly = BRep_Tool::PolygonOnTriangulation (anEdge, aT, aLocDummy);
if (anEdgePoly.IsNull())
{
continue;
}
for (Standard_Integer aTriIter = 1; aTriIter <= aT->NbTriangles(); ++aTriIter)
{
aT->Triangles().Value (aTriIter).Get (anIndex[0], anIndex[2], anIndex[1]);
Standard_Integer aDegenInTri = findDegenNodeInTri (anEdgePoly, anIndex);
if (aDegenInTri != -1)
{
++aNbDupNodes;
}
}
}
}
}
aNbVertices += aNbDupNodes;
if (aNbVertices < 3 || aNbTriangles <= 0)
{
return Handle(Graphic3d_ArrayOfTriangles)();
@@ -227,7 +297,25 @@ namespace
// Fill array with vertex and edge visibility info
const Poly_Array1OfTriangle& aTriangles = aT->Triangles();
Standard_Integer anIndex[3];
// handle degenerated nodes
NCollection_Sequence<Handle(Poly_PolygonOnTriangulation)> aDegenPolygons;
if (aNbDupNodes > 0)
{
for (TopExp_Explorer anEdgeIt (aFace, TopAbs_EDGE); anEdgeIt.More(); anEdgeIt.Next())
{
const TopoDS_Edge& anEdge = TopoDS::Edge(anEdgeIt.Current());
if (BRep_Tool::Degenerated (anEdge))
{
Handle(Poly_PolygonOnTriangulation) aPoly = BRep_Tool::PolygonOnTriangulation (anEdge, aT, aLocDummy);
if (!aPoly.IsNull())
{
aDegenPolygons.Append (aPoly);
}
}
}
}
for (Standard_Integer aTriIter = 1; aTriIter <= aT->NbTriangles(); ++aTriIter)
{
if ((aFace.Orientation() == TopAbs_REVERSED) ^ isMirrored)
@@ -261,12 +349,42 @@ namespace
aV1.Normalize();
aV2.Normalize();
aV1.Cross (aV2);
if (aV1.SquareMagnitude() > aPreci)
if (aV1.SquareMagnitude() <= aPreci)
{
anArray->AddEdge (anIndex[0] + aDecal);
anArray->AddEdge (anIndex[1] + aDecal);
anArray->AddEdge (anIndex[2] + aDecal);
continue;
}
// duplicate degenerated node using normal to the triangle
const Standard_Integer aDegenInTri = !aDegenPolygons.IsEmpty()
? findDegenNodeInTri (aDegenPolygons, anIndex)
: -1;
if (aDegenInTri != -1)
{
aPoint = aNodes (anIndex[aDegenInTri]);
if (!aLoc.IsIdentity())
{
aPoint.Transform (aTrsf);
aV1.Transform (aTrsf);
if (aV1.SquareMagnitude() > aPreci)
{
aV1.Normalize();
}
}
if (theHasTexels && aUVNodes.Upper() == aNodes.Upper())
{
const gp_Pnt2d aTexel = gp_Pnt2d ((-theUVOrigin.X() + (theUVRepeat.X() * (aUVNodes (anIndex[aDegenInTri]).X() - aUmin)) / dUmax) / theUVScale.X(),
(-theUVOrigin.Y() + (theUVRepeat.Y() * (aUVNodes (anIndex[aDegenInTri]).Y() - aVmin)) / dVmax) / theUVScale.Y());
anIndex[aDegenInTri] = anArray->AddVertex (aPoint, aV1, aTexel) - aDecal;
}
else
{
anIndex[aDegenInTri] = anArray->AddVertex (aPoint, aV1) - aDecal;
}
}
anArray->AddEdge (anIndex[0] + aDecal);
anArray->AddEdge (anIndex[1] + aDecal);
anArray->AddEdge (anIndex[2] + aDecal);
}
}
return anArray;