0024002: Overall code and build procedure refactoring -- automatic
[occt.git] / src / BRepLib / BRepLib.cxx
index 3b72a6f..ecd0eb9 100644 (file)
 //pmn 26/09/97 Add parameters of approximation in BuildCurve3d
 //  Modified by skv - Thu Jun  3 12:39:19 2004 OCC5898
 
-#include <BRepLib.ixx>
-#include <BRepAdaptor_Surface.hxx>
-#include <BRepAdaptor_HSurface.hxx>
-#include <BRepAdaptor_HCurve2d.hxx>
-#include <BRep_Tool.hxx>
+#include <Adaptor3d_CurveOnSurface.hxx>
+#include <AdvApprox_ApproxAFunction.hxx>
+#include <AppParCurves_MultiBSpCurve.hxx>
+#include <AppParCurves_MultiCurve.hxx>
+#include <Approx_CurvilinearParameter.hxx>
+#include <Approx_SameParameter.hxx>
+#include <Bnd_Box.hxx>
 #include <BRep_Builder.hxx>
-#include <Geom_Surface.hxx>
-#include <Geom_RectangularTrimmedSurface.hxx>
-#include <Geom_Plane.hxx>
-#include <Geom_Curve.hxx>
-#include <Geom_BSplineCurve.hxx>
-#include <Geom_TrimmedCurve.hxx>
+#include <BRep_CurveRepresentation.hxx>
+#include <BRep_GCurve.hxx>
+#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
+#include <BRep_ListOfCurveRepresentation.hxx>
+#include <BRep_TEdge.hxx>
+#include <BRep_TFace.hxx>
+#include <BRep_Tool.hxx>
+#include <BRep_TVertex.hxx>
+#include <BRepAdaptor_HCurve2d.hxx>
+#include <BRepAdaptor_HSurface.hxx>
+#include <BRepAdaptor_Surface.hxx>
+#include <BRepBndLib.hxx>
+#include <BRepClass3d_SolidClassifier.hxx>
+#include <BRepLib.hxx>
+#include <BSplCLib.hxx>
+#include <ElSLib.hxx>
+#include <Extrema_LocateExtPC.hxx>
+#include <GCPnts_QuasiUniformDeflection.hxx>
+#include <Geom2d_BSplineCurve.hxx>
 #include <Geom2d_Curve.hxx>
 #include <Geom2d_TrimmedCurve.hxx>
-#include <Geom2d_BSplineCurve.hxx>
+#include <Geom2dAdaptor.hxx>
+#include <Geom2dAdaptor_Curve.hxx>
+#include <Geom2dAdaptor_HCurve.hxx>
+#include <Geom2dConvert.hxx>
+#include <Geom_BSplineCurve.hxx>
+#include <Geom_BSplineSurface.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom_Plane.hxx>
+#include <Geom_RectangularTrimmedSurface.hxx>
+#include <Geom_Surface.hxx>
+#include <Geom_TrimmedCurve.hxx>
+#include <GeomAdaptor_Curve.hxx>
+#include <GeomAdaptor_HCurve.hxx>
+#include <GeomAdaptor_HSurface.hxx>
+#include <GeomAdaptor_Surface.hxx>
 #include <GeomLib.hxx>
-#include <TopExp_Explorer.hxx>
-#include <TopoDS.hxx>
-#include <TopoDS_Edge.hxx>
-#include <TopoDS_Face.hxx>
-#include <TopoDS_Vertex.hxx>
-#include <TopTools_MapOfShape.hxx>
-#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
-#include <TopTools_ListIteratorOfListOfShape.hxx>
-#include <TopExp.hxx>
+#include <GeomLProp_SLProps.hxx>
 #include <gp.hxx>
 #include <gp_Ax2.hxx>
 #include <gp_Pln.hxx>
-#include <Standard_Real.hxx>
+#include <Poly_PolygonOnTriangulation.hxx>
+#include <Poly_Triangulation.hxx>
 #include <Precision.hxx>
-#include <BRep_GCurve.hxx>
-#include <BRep_TEdge.hxx>
-#include <BRep_TFace.hxx>
-#include <AppParCurves_MultiCurve.hxx>
-#include <AppParCurves_MultiBSpCurve.hxx>
-#include <BRep_ListOfCurveRepresentation.hxx>
-#include <BRep_CurveRepresentation.hxx>
-#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
-#include <BRep_TVertex.hxx>
-#include <AdvApprox_ApproxAFunction.hxx>
-#include <Approx_SameParameter.hxx>
+#include <ProjLib_ProjectedCurve.hxx>
+#include <Standard_Real.hxx>
 #include <TColgp_Array1OfPnt.hxx>
 #include <TColgp_Array1OfPnt2d.hxx>
 #include <TColStd_Array1OfReal.hxx>
 #include <TColStd_MapOfTransient.hxx>
-#include <GeomAdaptor_Curve.hxx>
-#include <GeomAdaptor_HCurve.hxx>
-#include <GeomAdaptor_Surface.hxx>
-#include <GeomAdaptor_HSurface.hxx>
-#include <Geom2dAdaptor_Curve.hxx>
-#include <Geom2dAdaptor_HCurve.hxx>
-#include <Geom2dAdaptor.hxx>
-#include <Geom2dConvert.hxx>
-#include <GCPnts_QuasiUniformDeflection.hxx>
-#include <BSplCLib.hxx>
-#include <ElSLib.hxx>
-#include <Adaptor3d_CurveOnSurface.hxx>
-#include <Extrema_LocateExtPC.hxx>
-#include <ProjLib_ProjectedCurve.hxx>
-#include <BRepClass3d_SolidClassifier.hxx>
-#include <Bnd_Box.hxx>
-#include <BRepBndLib.hxx>
-#include <Approx_CurvilinearParameter.hxx>
-#include <Geom_BSplineSurface.hxx>
-
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopoDS_Solid.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <TShort_HArray1OfShortReal.hxx>
 
 // TODO - not thread-safe static variables
 static Standard_Real thePrecision = Precision::Confusion();     
@@ -582,8 +587,7 @@ Standard_Boolean  BRepLib::UpdateEdgeTol(const TopoDS_Edge& AnEdge,
       new Geom2dAdaptor_HCurve(AnAdaptor3dCurve2d) ;
     Handle(GeomAdaptor_HSurface) AnAdaptor3dSurfacePtr =
       new GeomAdaptor_HSurface (AnAdaptor3dSurface) ;
-    curve_on_surface_reference.Load( AnAdaptor3dCurve2dPtr) ;
-    curve_on_surface_reference.Load( AnAdaptor3dSurfacePtr) ;
+    curve_on_surface_reference.Load (AnAdaptor3dCurve2dPtr, AnAdaptor3dSurfacePtr);
     a_sampler.Initialize(curve_on_surface_reference,
       MinToleranceRequested * factor,
       current_first,
@@ -780,7 +784,13 @@ static void SetEdgeTol(const TopoDS_Edge& E,
     gp_Pnt Pc3d = HC->Value(u);
     gp_Pnt2d p2d = pc->Value(u);
     gp_Pnt Pcons = ElSLib::Value(p2d.X(),p2d.Y(),pln);
+    Standard_Real eps = Max(Pc3d.XYZ().SquareModulus(), Pcons.XYZ().SquareModulus());
+    eps = Epsilon(eps);
     Standard_Real temp = Pc3d.SquareDistance(Pcons);
+    if(temp <= eps)
+    {
+      temp = 0.;
+    }
     if(temp > d2) d2 = temp;
   }
   d2 = 1.5*sqrt(d2);
@@ -966,7 +976,7 @@ void BRepLib::SameParameter(const TopoDS_Edge&  AnEdge,
   Handle(Standard_Type) TheType = C3d->DynamicType();
   if( TheType == STANDARD_TYPE(Geom_TrimmedCurve))
   {
-    const Handle(Geom_Curve)& gtC = (*((Handle(Geom_TrimmedCurve)*)&C3d))->BasisCurve();
+    Handle(Geom_Curve) gtC (Handle(Geom_TrimmedCurve)::DownCast (C3d)->BasisCurve());
     m_TrimmedPeriodical = gtC->IsPeriodic();
   }
   // modified by NIZHNY-OCC486  Tue Aug 27 17:15:17 2002 .
@@ -1222,7 +1232,9 @@ void BRepLib::SameParameter(const TopoDS_Edge&  AnEdge,
         if(goodpc){
           //     Approx_SameParameter SameP(HC,HC2d,HS,Tolerance);
           Standard_Real aTol = (isANA && isBSP) ? 1.e-7 : Tolerance;
-          Approx_SameParameter SameP(HC,HC2d,HS,aTol);
+          const Handle(Adaptor3d_HCurve)& aHCurv = HC; // to avoid ambiguity
+          const Handle(Adaptor2d_HCurve2d)& aHCurv2d = HC2d; // to avoid ambiguity
+          Approx_SameParameter SameP(aHCurv,aHCurv2d,HS,aTol);
 
           if (SameP.IsSameParameter()) {
             maxdist = Max(maxdist,SameP.TolReached());
@@ -1313,7 +1325,7 @@ void  BRepLib::UpdateTolerances(const TopoDS_Shape& aShape,
         aB.SetVoid();
         BRepBndLib::Add(curf,aB);
         if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
-          S = (*((Handle(Geom_RectangularTrimmedSurface)*)&S))->BasisSurface();
+          S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
         }
         GeomAdaptor_Surface AS(S);
         switch (AS.GetType()) {
@@ -1651,6 +1663,146 @@ void BRepLib::EncodeRegularity(TopoDS_Edge& E,
   }
 }
 
+//=======================================================================
+// function : EnsureNormalConsistency
+// purpose  : Corrects the normals in Poly_Triangulation of faces.
+//              Returns TRUE if any correction is done.
+//=======================================================================
+Standard_Boolean BRepLib::
+            EnsureNormalConsistency(const TopoDS_Shape& theShape,
+                                    const Standard_Real theAngTol,
+                                    const Standard_Boolean theForceComputeNormals)
+{
+  const Standard_Real aThresDot = cos(theAngTol);
+
+  Standard_Boolean aRetVal = Standard_False, isNormalsFound = Standard_False;
+
+  // compute normals if they are absent
+  TopExp_Explorer anExpFace(theShape,TopAbs_FACE);
+  for (; anExpFace.More(); anExpFace.Next())
+  {
+    const TopoDS_Face& aFace = TopoDS::Face(anExpFace.Current());
+    const Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
+    if(aSurf.IsNull())
+      continue;
+    TopLoc_Location aLoc;
+    const Handle(Poly_Triangulation)& aPT = BRep_Tool::Triangulation(aFace, aLoc);
+    if(aPT.IsNull())
+      continue;
+    if (!theForceComputeNormals && aPT->HasNormals())
+    {
+      isNormalsFound = Standard_True;
+      continue;
+    }
+
+    GeomLProp_SLProps aSLP(aSurf, 2, Precision::Confusion());
+    const Standard_Integer anArrDim = 3*aPT->NbNodes();
+    Handle(TShort_HArray1OfShortReal) aNormArr = new TShort_HArray1OfShortReal(1, anArrDim);
+    Standard_Integer anNormInd = aNormArr->Lower();
+    for(Standard_Integer i = aPT->UVNodes().Lower(); i <= aPT->UVNodes().Upper(); i++)
+    {
+      const gp_Pnt2d &aP2d = aPT->UVNodes().Value(i);
+      aSLP.SetParameters(aP2d.X(), aP2d.Y());
+
+      gp_XYZ aNorm(0.,0.,0.);
+      if(!aSLP.IsNormalDefined())
+      {
+#ifdef OCCT_DEBUG
+        cout << "BRepLib::EnsureNormalConsistency(): Cannot find normal!" << endl;
+#endif
+      }
+      else
+      {
+        aNorm = aSLP.Normal().XYZ();
+        if (aFace.Orientation() == TopAbs_REVERSED)
+          aNorm.Reverse();
+      }
+      aNormArr->ChangeValue(anNormInd++) = static_cast<Standard_ShortReal>(aNorm.X());
+      aNormArr->ChangeValue(anNormInd++) = static_cast<Standard_ShortReal>(aNorm.Y());
+      aNormArr->ChangeValue(anNormInd++) = static_cast<Standard_ShortReal>(aNorm.Z());
+    }
+
+    aRetVal = Standard_True;
+    isNormalsFound = Standard_True;
+    aPT->SetNormals(aNormArr);
+  }
+
+  if(!isNormalsFound)
+  {
+    return aRetVal;
+  }
+
+  // loop by edges
+  TopTools_IndexedDataMapOfShapeListOfShape aMapEF;
+  TopExp::MapShapesAndAncestors(theShape,TopAbs_EDGE,TopAbs_FACE,aMapEF);
+  for(Standard_Integer anInd = 1; anInd <= aMapEF.Extent(); anInd++)
+  {
+    const TopoDS_Edge& anEdg = TopoDS::Edge(aMapEF.FindKey(anInd));
+    const TopTools_ListOfShape& anEdgList = aMapEF.FindFromIndex(anInd);
+    if (anEdgList.Extent() != 2)
+      continue;
+    TopTools_ListIteratorOfListOfShape anItF(anEdgList);
+    const TopoDS_Face aFace1 = TopoDS::Face(anItF.Value());
+    anItF.Next();
+    const TopoDS_Face aFace2 = TopoDS::Face(anItF.Value());
+    TopLoc_Location aLoc1, aLoc2;
+    const Handle(Poly_Triangulation)& aPT1 = BRep_Tool::Triangulation(aFace1, aLoc1);
+    const Handle(Poly_Triangulation)& aPT2 = BRep_Tool::Triangulation(aFace2, aLoc2);
+
+    if(aPT1.IsNull() || aPT2.IsNull())
+      continue;
+
+    if(!aPT1->HasNormals() || !aPT2->HasNormals())
+      continue;
+
+    const Handle(Poly_PolygonOnTriangulation)& aPTEF1 = 
+                                BRep_Tool::PolygonOnTriangulation(anEdg, aPT1, aLoc1);
+    const Handle(Poly_PolygonOnTriangulation)& aPTEF2 = 
+                                BRep_Tool::PolygonOnTriangulation(anEdg, aPT2, aLoc2);
+
+    TShort_Array1OfShortReal& aNormArr1 = aPT1->ChangeNormals();
+    TShort_Array1OfShortReal& aNormArr2 = aPT2->ChangeNormals();
+
+    for(Standard_Integer anEdgNode = aPTEF1->Nodes().Lower();
+                         anEdgNode <= aPTEF1->Nodes().Upper(); anEdgNode++)
+    {
+      //Number of node
+      const Standard_Integer aFNodF1 = aPTEF1->Nodes().Value(anEdgNode);
+      const Standard_Integer aFNodF2 = aPTEF2->Nodes().Value(anEdgNode);
+
+      const Standard_Integer aFNorm1FirstIndex = aNormArr1.Lower() + 3*
+                                                    (aFNodF1 - aPT1->Nodes().Lower());
+      const Standard_Integer aFNorm2FirstIndex = aNormArr2.Lower() + 3*
+                                                    (aFNodF2 - aPT2->Nodes().Lower());
+
+      gp_XYZ aNorm1(aNormArr1.Value(aFNorm1FirstIndex),
+                    aNormArr1.Value(aFNorm1FirstIndex+1),
+                    aNormArr1.Value(aFNorm1FirstIndex+2));
+      gp_XYZ aNorm2(aNormArr2.Value(aFNorm2FirstIndex),
+                    aNormArr2.Value(aFNorm2FirstIndex+1),
+                    aNormArr2.Value(aFNorm2FirstIndex+2));
+      const Standard_Real aDot = aNorm1 * aNorm2;
+
+      if(aDot > aThresDot)
+      {
+        gp_XYZ aNewNorm = (aNorm1 + aNorm2).Normalized();
+        aNormArr1.ChangeValue(aFNorm1FirstIndex) =
+          aNormArr2.ChangeValue(aFNorm2FirstIndex) =
+          static_cast<Standard_ShortReal>(aNewNorm.X());
+        aNormArr1.ChangeValue(aFNorm1FirstIndex+1) =
+          aNormArr2.ChangeValue(aFNorm2FirstIndex+1) =
+          static_cast<Standard_ShortReal>(aNewNorm.Y());
+        aNormArr1.ChangeValue(aFNorm1FirstIndex+2) =
+          aNormArr2.ChangeValue(aFNorm2FirstIndex+2) =
+          static_cast<Standard_ShortReal>(aNewNorm.Z());
+        aRetVal = Standard_True;
+      }
+    }
+  }
+
+  return aRetVal;
+}
+
 //=======================================================================
 //function : SortFaces
 //purpose  : 
@@ -1670,7 +1822,7 @@ void  BRepLib::SortFaces (const TopoDS_Shape& Sh,
     S = BRep_Tool::Surface(F, l);
     if (!S.IsNull()) {
       if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
-        S = (*((Handle(Geom_RectangularTrimmedSurface)*)&S))->BasisSurface();
+        S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
       }
       GeomAdaptor_Surface AS(S);
       switch (AS.GetType()) {
@@ -1728,7 +1880,7 @@ void  BRepLib::ReverseSortFaces (const TopoDS_Shape& Sh,
     S = BRep_Tool::Surface(F, l);
     if (!S.IsNull()) {
       if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
-        S = (*((Handle(Geom_RectangularTrimmedSurface)*)&S))->BasisSurface();
+        S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
       }
       GeomAdaptor_Surface AS(S);
       switch (AS.GetType()) {