// purpose or non-infringement. Please see the License for the specific terms
// and conditions governing the rights and limitations under the License.
-
-
#include <StdPrs_ToolShadedShape.ixx>
+
+#include <BRep_Tool.hxx>
+#include <BRepAdaptor_Surface.hxx>
+#include <GeomAbs_SurfaceType.hxx>
+#include <GeomLib.hxx>
+#include <gp_Vec.hxx>
+#include <Poly_Connect.hxx>
#include <Poly_Triangulation.hxx>
+#include <Precision.hxx>
#include <TColgp_HArray1OfPnt.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
-#include <Poly_Connect.hxx>
#include <TopAbs_Orientation.hxx>
-#include <GeomAbs_SurfaceType.hxx>
-//#include <CSLib.hxx>
-#include <GeomLib.hxx>
-#include <gp_Vec.hxx>
-#include <Precision.hxx>
-#include <BRepAdaptor_Surface.hxx>
-#include <BRep_Tool.hxx>
#include <TopLoc_Location.hxx>
#include <TShort_HArray1OfShortReal.hxx>
#include <TShort_Array1OfShortReal.hxx>
//=======================================================================
//function : IsClosed
-//purpose :
+//purpose :
//=======================================================================
-
-Standard_Boolean StdPrs_ToolShadedShape::IsClosed(const TopoDS_Shape& aShape)
+Standard_Boolean StdPrs_ToolShadedShape::IsClosed (const TopoDS_Shape& theShape)
{
- return aShape.Closed();
+ return theShape.Closed();
}
-
//=======================================================================
//function : Triangulation
-//purpose :
+//purpose :
//=======================================================================
-
-Handle(Poly_Triangulation) StdPrs_ToolShadedShape::Triangulation
- (const TopoDS_Face& aFace,
- TopLoc_Location& loc)
+Handle(Poly_Triangulation) StdPrs_ToolShadedShape::Triangulation (const TopoDS_Face& theFace,
+ TopLoc_Location& theLoc)
{
- return BRep_Tool::Triangulation(aFace, loc);
+ return BRep_Tool::Triangulation (theFace, theLoc);
}
-
//=======================================================================
//function : Normal
-//purpose :
+//purpose :
//=======================================================================
-
-void StdPrs_ToolShadedShape::Normal(const TopoDS_Face& aFace,
- Poly_Connect& pc,
- TColgp_Array1OfDir& Nor)
+void StdPrs_ToolShadedShape::Normal (const TopoDS_Face& theFace,
+ Poly_Connect& thePolyConnect,
+ TColgp_Array1OfDir& theNormals)
{
- const Handle(Poly_Triangulation)& T = pc.Triangulation();
- BRepAdaptor_Surface S;
- Standard_Boolean hasUV = T->HasUVNodes();
- Standard_Integer i;
- TopLoc_Location l;
- // move to zero
- TopoDS_Face zeroFace = TopoDS::Face(aFace.Located(TopLoc_Location()));
- //take in face the surface location
-
- //Handle(Geom_Surface) GS = BRep_Tool::Surface(aFace, l);
- Handle(Geom_Surface) GS = BRep_Tool::Surface(zeroFace);
-
- if(T->HasNormals()) {
- const TColgp_Array1OfPnt& Nodes = T->Nodes();
- const TShort_Array1OfShortReal& Normals = T->Normals();
- const Standard_ShortReal * arrN = &(Normals.Value(Normals.Lower()));
- for( i = Nodes.Lower(); i <= Nodes.Upper(); i++) {
- Standard_Integer in = 3*(i-Nodes.Lower());
- gp_Dir N(arrN[in + 0], arrN[in + 1], arrN[in + 2]);
- Nor(i) = N;
+ const Handle(Poly_Triangulation)& aPolyTri = thePolyConnect.Triangulation();
+ const TColgp_Array1OfPnt& aNodes = aPolyTri->Nodes();
+ if (aPolyTri->HasNormals())
+ {
+ // normals pre-computed in triangulation structure
+ const TShort_Array1OfShortReal& aNormals = aPolyTri->Normals();
+ const Standard_ShortReal* aNormArr = &(aNormals.Value (aNormals.Lower()));
+ for (Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
+ {
+ const Standard_Integer anId = 3 * (aNodeIter - aNodes.Lower());
+ const gp_Dir aNorm (aNormArr[anId + 0],
+ aNormArr[anId + 1],
+ aNormArr[anId + 2]);
+ theNormals (aNodeIter) = aNorm;
}
- if (aFace.Orientation() == TopAbs_REVERSED) {
- for( i = Nodes.Lower(); i <= Nodes.Upper(); i++) {
- Nor.ChangeValue(i).Reverse();
+ if (theFace.Orientation() == TopAbs_REVERSED)
+ {
+ for (Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
+ {
+ theNormals.ChangeValue (aNodeIter).Reverse();
}
}
-
-
+ return;
}
- else if (hasUV && !GS.IsNull()) {
- Standard_Integer nbNormVal = T->NbNodes() * 3;
- Handle(TShort_HArray1OfShortReal) Normals =
- new TShort_HArray1OfShortReal(1, nbNormVal);
-
- const TColgp_Array1OfPnt2d& UVNodes = T->UVNodes();
- Standard_Real Tol = Precision::Confusion();
- for (i = UVNodes.Lower(); i <= UVNodes.Upper(); i++) {
-
- if(GeomLib::NormEstim(GS, UVNodes(i), Tol, Nor(i)) > 1) {
- const TColgp_Array1OfPnt& Nodes = T->Nodes();
- Standard_Integer n[3];
- const Poly_Array1OfTriangle& triangles = T->Triangles();
-
- gp_XYZ eqPlan(0, 0, 0);
-
- Standard_Real modmax = 0.;
- for (pc.Initialize(i); pc.More(); pc.Next()) {
- triangles(pc.Value()).Get(n[0], n[1], n[2]);
- gp_XYZ v1(Nodes(n[1]).Coord()-Nodes(n[0]).Coord());
- gp_XYZ v2(Nodes(n[2]).Coord()-Nodes(n[1]).Coord());
- gp_XYZ vv = v1^v2;
- Standard_Real mod = vv.Modulus();
-
- if(mod < Tol) continue;
-
- eqPlan += vv/mod;
- }
-
- modmax = eqPlan.Modulus();
- if(modmax > Tol) Nor(i) = gp_Dir(eqPlan);
- else Nor(i) = gp_Dir(0., 0., 1.);
+ // take in face the surface location
+ const TopoDS_Face aZeroFace = TopoDS::Face (theFace.Located (TopLoc_Location()));
+ Handle(Geom_Surface) aSurf = BRep_Tool::Surface (aZeroFace);
+ const Standard_Real aTol = Precision::Confusion();
+ Handle(TShort_HArray1OfShortReal) aNormals = new TShort_HArray1OfShortReal (1, aPolyTri->NbNodes() * 3);
+ const Poly_Array1OfTriangle& aTriangles = aPolyTri->Triangles();
+ const TColgp_Array1OfPnt2d* aNodesUV = aPolyTri->HasUVNodes() && !aSurf.IsNull()
+ ? &aPolyTri->UVNodes()
+ : NULL;
+ Standard_Integer aTri[3];
+ for (Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
+ {
+ // try to retrieve normal from real surface first, when UV coordinates are available
+ if (aNodesUV == NULL
+ || GeomLib::NormEstim (aSurf, aNodesUV->Value (aNodeIter), aTol, theNormals (aNodeIter)) > 1)
+ {
+ // compute flat normals
+ gp_XYZ eqPlan (0.0, 0.0, 0.0);
+ for (thePolyConnect.Initialize (aNodeIter); thePolyConnect.More(); thePolyConnect.Next())
+ {
+ aTriangles (thePolyConnect.Value()).Get (aTri[0], aTri[1], aTri[2]);
+ const gp_XYZ v1 (aNodes (aTri[1]).Coord() - aNodes (aTri[0]).Coord());
+ const gp_XYZ v2 (aNodes (aTri[2]).Coord() - aNodes (aTri[1]).Coord());
+ const gp_XYZ vv = v1 ^ v2;
+ const Standard_Real aMod = vv.Modulus();
+ if (aMod >= aTol)
+ {
+ eqPlan += vv / aMod;
+ }
}
-
- Standard_Integer j = (i - UVNodes.Lower()) * 3;
- Normals->SetValue(j + 1, Nor(i).X());
- Normals->SetValue(j + 2, Nor(i).Y());
- Normals->SetValue(j + 3, Nor(i).Z());
-
- if (aFace.Orientation() == TopAbs_REVERSED) (Nor(i)).Reverse();
-
+ const Standard_Real aModMax = eqPlan.Modulus();
+ theNormals (aNodeIter) = (aModMax > aTol) ? gp_Dir (eqPlan) : gp::DZ();
}
- T->SetNormals(Normals);
+ const Standard_Integer anId = (aNodeIter - aNodes.Lower()) * 3;
+ aNormals->SetValue (anId + 1, (Standard_ShortReal )theNormals (aNodeIter).X());
+ aNormals->SetValue (anId + 2, (Standard_ShortReal )theNormals (aNodeIter).Y());
+ aNormals->SetValue (anId + 3, (Standard_ShortReal )theNormals (aNodeIter).Z());
}
- else {
- Standard_Integer nbNormVal = T->NbNodes() * 3;
- Handle(TShort_HArray1OfShortReal) Normals =
- new TShort_HArray1OfShortReal(1, nbNormVal);
-
- const TColgp_Array1OfPnt& Nodes = T->Nodes();
- Standard_Integer n[3];
- const Poly_Array1OfTriangle& triangles = T->Triangles();
- Standard_Real Tol = Precision::Confusion();
-
- for (i = Nodes.Lower(); i <= Nodes.Upper(); i++) {
- gp_XYZ eqPlan(0, 0, 0);
- for (pc.Initialize(i); pc.More(); pc.Next()) {
- triangles(pc.Value()).Get(n[0], n[1], n[2]);
- gp_XYZ v1(Nodes(n[1]).Coord()-Nodes(n[0]).Coord());
- gp_XYZ v2(Nodes(n[2]).Coord()-Nodes(n[1]).Coord());
- gp_XYZ vv = v1^v2;
- Standard_Real mod = vv.Modulus();
-
- if(mod < Tol) continue;
-
- eqPlan += vv/mod;
- }
-
- Standard_Real modmax = eqPlan.Modulus();
-
- if(modmax > Tol) Nor(i) = gp_Dir(eqPlan);
- else Nor(i) = gp_Dir(0., 0., 1.);
-
- Nor(i) = gp_Dir(eqPlan);
-
- Standard_Integer j = (i - Nodes.Lower()) * 3;
- Normals->SetValue(j + 1, Nor(i).X());
- Normals->SetValue(j + 2, Nor(i).Y());
- Normals->SetValue(j + 3, Nor(i).Z());
-
- if (aFace.Orientation() == TopAbs_REVERSED) (Nor(i)).Reverse();
+ aPolyTri->SetNormals (aNormals);
+ if (theFace.Orientation() == TopAbs_REVERSED)
+ {
+ for (Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
+ {
+ theNormals.ChangeValue (aNodeIter).Reverse();
}
-
- T->SetNormals(Normals);
}
-
-
}
-