}
}
+ //! 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,
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();
{
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)();
// 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)
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)
+ {
+ 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 (aNodes (anIndex[aDegenInTri]), aV1, aTexel);
+ }
+ else
+ {
+ anIndex[aDegenInTri] = anArray->AddVertex (aNodes (anIndex[aDegenInTri]), aV1);
+ }
+ }
+
+ anArray->AddEdge (anIndex[0] + aDecal);
+ anArray->AddEdge (anIndex[1] + aDecal);
+ anArray->AddEdge (anIndex[2] + aDecal);
}
}
return anArray;