Salome HOME
Merge remote-tracking branch 'remotes/origin/BR_PlaneGCS' into CodeCleanup
[modules/shaper.git] / src / GeomAPI / GeomAPI_Face.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        GeomAPI_Face.cpp
4 // Created:     2 Dec 2014
5 // Author:      Artem ZHIDKOV
6
7 #include <GeomAPI_Face.h>
8 #include <GeomAPI_Dir.h>
9 #include <GeomAPI_Pln.h>
10 #include <GeomAPI_Pnt.h>
11
12 #include <TopoDS_Shape.hxx>
13 #include <TopoDS_Face.hxx>
14 #include <TopoDS.hxx>
15 #include <BRep_Tool.hxx>
16 #include <BRepAdaptor_Surface.hxx>
17 #include <Geom_Surface.hxx>
18 #include <Geom_Plane.hxx>
19 #include <Geom_CylindricalSurface.hxx>
20 #include <GeomLib_IsPlanarSurface.hxx>
21 #include <Geom_RectangularTrimmedSurface.hxx>
22
23 GeomAPI_Face::GeomAPI_Face()
24   : GeomAPI_Shape()
25 {
26 }
27
28 GeomAPI_Face::GeomAPI_Face(const std::shared_ptr<GeomAPI_Shape>& theShape)
29 {
30   if (!theShape->isNull() && theShape->isFace()) {
31     setImpl(new TopoDS_Shape(theShape->impl<TopoDS_Shape>()));
32   }
33 }
34
35 bool GeomAPI_Face::isEqual(std::shared_ptr<GeomAPI_Shape> theFace) const
36 {
37   if (!theFace->isFace())
38     return false;
39
40   const TopoDS_Shape& aMyShape = const_cast<GeomAPI_Face*>(this)->impl<TopoDS_Shape>();
41   const TopoDS_Shape& aInShape = theFace->impl<TopoDS_Shape>();
42
43   Handle(Geom_Surface) aMySurf = BRep_Tool::Surface(TopoDS::Face(aMyShape));
44   Handle(Geom_Surface) aInSurf = BRep_Tool::Surface(TopoDS::Face(aInShape));
45
46   // Check that surfaces a the same type
47   if (aMySurf->DynamicType() != aInSurf->DynamicType())
48     return false;
49
50   // Get parameters of surfaces
51   double aMyUMin, aMyUMax, aMyVMin, aMyVMax;
52   aMySurf->Bounds(aMyUMin, aMyUMax, aMyVMin, aMyVMax);
53   double aInUMin, aInUMax, aInVMin, aInVMax;
54   aInSurf->Bounds(aInUMin, aInUMax, aInVMin, aInVMax);
55
56   // Check that parameters are the same
57   if (fabs(aMyUMin - aInUMin) > Precision::PConfusion() ||
58       fabs(aMyUMax - aInUMax) > Precision::PConfusion() ||
59       fabs(aMyVMin - aInVMin) > Precision::PConfusion() ||
60       fabs(aMyVMax - aInVMax) > Precision::PConfusion())
61     return false;
62
63   return true;
64 }
65
66 bool GeomAPI_Face::isPlanar() const
67 {
68   const TopoDS_Shape& aShape = const_cast<GeomAPI_Face*>(this)->impl<TopoDS_Shape>();
69   Handle(Geom_Surface) aSurf = BRep_Tool::Surface(TopoDS::Face(aShape));
70   Handle(Geom_RectangularTrimmedSurface) aTrimmed = 
71     Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurf);
72   if (!aTrimmed.IsNull())
73     aSurf = aTrimmed->BasisSurface();
74   GeomLib_IsPlanarSurface isPlanar(aSurf);
75   return isPlanar.IsPlanar() == Standard_True;
76 }
77
78 bool GeomAPI_Face::isCylindrical() const
79 {
80   const TopoDS_Shape& aShape = const_cast<GeomAPI_Face*>(this)->impl<TopoDS_Shape>();
81   Handle(Geom_Surface) aSurf = BRep_Tool::Surface(TopoDS::Face(aShape));
82   Handle(Geom_RectangularTrimmedSurface) aTrimmed = 
83     Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurf);
84   if (!aTrimmed.IsNull())
85     aSurf = aTrimmed->BasisSurface();
86   return aSurf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface)) == Standard_True;
87 }
88
89 std::shared_ptr<GeomAPI_Pln> GeomAPI_Face::getPlane() const
90 {
91   const TopoDS_Shape& aShape = const_cast<GeomAPI_Face*>(this)->impl<TopoDS_Shape>();
92   BRepAdaptor_Surface aSurfAdapt(TopoDS::Face(aShape));
93
94   if (aSurfAdapt.GetType() != GeomAbs_Plane)
95     return std::shared_ptr<GeomAPI_Pln>();
96
97   // Obtain central point
98   double aUMin, aUMax, aVMin, aVMax;
99   aUMin = aSurfAdapt.FirstUParameter();
100   aUMax = aSurfAdapt.LastUParameter();
101   aVMin = aSurfAdapt.FirstVParameter();
102   aVMax = aSurfAdapt.LastVParameter();
103   gp_Pnt aCentralPnt;
104   gp_Vec aDU, aDV;
105   aSurfAdapt.D1((aUMin+aUMax)*0.5, (aVMin+aVMax)*0.5, aCentralPnt, aDU, aDV);
106   std::shared_ptr<GeomAPI_Pnt> aCenter(
107       new GeomAPI_Pnt(aCentralPnt.X(), aCentralPnt.Y(), aCentralPnt.Z()));
108
109   // Obtain plane direction
110   gp_XYZ aNormalVec = aDU.XYZ().Crossed(aDV.XYZ());
111   if (aNormalVec.SquareModulus() < Precision::Confusion() * Precision::Confusion())
112     return std::shared_ptr<GeomAPI_Pln>();
113   std::shared_ptr<GeomAPI_Dir> aNormal(
114       new GeomAPI_Dir(aNormalVec.X(), aNormalVec.Y(), aNormalVec.Z()));
115
116   std::shared_ptr<GeomAPI_Pln> aResult(new GeomAPI_Pln(aCenter, aNormal));
117   return aResult;
118 }