0022627: Change OCCT memory management defaults
[occt.git] / src / BRepBuilderAPI / BRepBuilderAPI_FindPlane.cxx
CommitLineData
7fd59977 1// File: BRepBuilderAPI_FindPlane.cxx
2// Created: Thu Nov 2 11:47:55 1995
3// Author: Jing Cheng MEI
4// <mei@junon>
5
6#include <BRepBuilderAPI_FindPlane.ixx>
7
8#include <Precision.hxx>
9#include <gp_Dir.hxx>
10#include <gp_Vec.hxx>
11#include <gp_Pln.hxx>
12#include <TColgp_SequenceOfPnt.hxx>
13#include <TopoDS.hxx>
14#include <TopLoc_Location.hxx>
15#include <TopExp_Explorer.hxx>
16#include <BRep_Tool.hxx>
17
18#include <Geom_Line.hxx>
19#include <Geom_Conic.hxx>
20#include <Geom_Circle.hxx>
21#include <Geom_Ellipse.hxx>
22#include <Geom_Parabola.hxx>
23#include <Geom_Hyperbola.hxx>
24#include <Geom_BezierCurve.hxx>
25#include <Geom_BSplineCurve.hxx>
26
27
28
29//=======================================================================
30//function : BRepBuilderAPI_FindPlane
31//purpose :
32//=======================================================================
33
34BRepBuilderAPI_FindPlane::BRepBuilderAPI_FindPlane()
35{
36}
37
38//=======================================================================
39//function : BRepBuilderAPI_FindPlane
40//purpose :
41//=======================================================================
42
43BRepBuilderAPI_FindPlane::BRepBuilderAPI_FindPlane(const TopoDS_Shape& S,
44 const Standard_Real Tol)
45{
46 Init(S,Tol);
47}
48
49//=======================================================================
50//function : Init
51//purpose :
52//=======================================================================
53
54void BRepBuilderAPI_FindPlane::Init(const TopoDS_Shape& S,
55 const Standard_Real Tol)
56{
57 Standard_Real tolerance = Tol;
58 myPlane.Nullify();
59
60 // compute the tolerance
61 TopExp_Explorer ex;
62 for (ex.Init(S,TopAbs_EDGE); ex.More(); ex.Next()) {
63 Standard_Real t = BRep_Tool::Tolerance(TopoDS::Edge(ex.Current()));
64 if (t > tolerance) tolerance = t;
65 }
66
67 Standard_Real tol2 = tolerance*tolerance;
68 // try to find an analytical curve and calculate points
69 TopLoc_Location loc;
70 Standard_Real first, last;
71 Standard_Boolean found = Standard_False;
72 Handle(Geom_Plane) P;
73 TColgp_SequenceOfPnt points;
74 Standard_Integer nbPnts;
75
76 for (ex.Init(S,TopAbs_EDGE); ex.More(); ex.Next()) {
77 Handle(Geom_Curve) c3d =
78 BRep_Tool::Curve(TopoDS::Edge(ex.Current()), loc, first, last);
79
80 if (!c3d.IsNull()) {
81 Handle(Geom_Curve) c3dptr =
82 Handle(Geom_Curve)::DownCast(c3d->Transformed(loc.Transformation()));
83
84 Handle(Standard_Type) cType = c3dptr->DynamicType();
85
86 if (cType == STANDARD_TYPE(Geom_Line)) {
87 nbPnts = 3;
88 }
89 else if ((cType == STANDARD_TYPE(Geom_Circle)) ||
90 (cType == STANDARD_TYPE(Geom_Ellipse)) ||
91 (cType == STANDARD_TYPE(Geom_Parabola)) ||
92 (cType == STANDARD_TYPE(Geom_Hyperbola))) {
93 nbPnts = 4;
94 if (!found) {
95 found = Standard_True;
96 Handle(Geom_Conic) Co = Handle(Geom_Conic)::DownCast(c3dptr);
97 P = new Geom_Plane(gp_Ax3(Co->Position()));
98 }
99 }
100 else if (cType == STANDARD_TYPE(Geom_BezierCurve)) {
101 Handle(Geom_BezierCurve) Co =
102 Handle(Geom_BezierCurve)::DownCast(c3dptr);
103 nbPnts = Co->NbPoles();
104 }
105 else if (cType == STANDARD_TYPE(Geom_BSplineCurve)) {
106 Handle(Geom_BSplineCurve) Co =
107 Handle(Geom_BSplineCurve)::DownCast(c3dptr);
108 nbPnts = Co->NbPoles();
109 }
110 else {
111 nbPnts = 10;
112 }
113
114 gp_Pnt p0;
115 for (Standard_Integer i=1; i<=nbPnts; i++) {
116 if (i == 1) {
117 c3dptr->D0(first, p0);
118 }
119 else if (i == nbPnts) {
120 c3dptr->D0(last, p0);
121 }
122 else {
123 c3dptr->D0(first+(last-first)/(nbPnts-1)*(i-1), p0);
124 }
125 points.Append(p0);
126 }
127 }
128 }
129
130 if (!found) {
131 // try to find a plane with the points
132 if (points.Length() > 2) {
133
134 Standard_Real disMax = 0.0;
135 gp_Pnt p0 = points(1);
136 gp_Pnt p1;
137 for (Standard_Integer i=2; i<=points.Length(); i++) {
138 Standard_Real dist = p0.SquareDistance(points(i));
139 if (dist > disMax) {
140 disMax = dist;
0d969553 141 p1 = points(i); // it will be faster to store the point, otherwise it is necessary to find a value in a sequence
7fd59977 142 }
143 }
144
145 if (disMax > tol2) {
146 gp_Vec V1(p0, p1), V3;
147 Standard_Real proMax = 0.0;
148 gp_Pnt p2 = p0 ;
149 for (Standard_Integer j=2; j<=points.Length(); j++) {
150 V3 = V1^gp_Vec(p0, points(j));
151 Standard_Real pro = V3.SquareMagnitude();
152 if (pro > proMax) {
153 proMax = pro;
154 p2 = points(j);
155 }
156 }
157
158 if (p0.SquareDistance(p2) > tol2) {
159 gp_Dir D1(V1), D2(gp_Vec(p0, p2));
160 if (!D1.IsParallel(D2, Precision::Angular())) {
161 P = new Geom_Plane(gp_Ax3(p0, D1.Crossed(D2), D1));
162 found = Standard_True;
163 }
164 }
165 }
166 }
167 }
168
169 if (found) {
170 // test if all points are on the plane
171 const gp_Pln& pln = P->Pln();
172 for (Standard_Integer i=1; i<=points.Length(); i++) {
173 if (pln.SquareDistance(points(i)) > tol2) {
174 found = Standard_False;
175 break;
176 }
177 }
178 }
179
180 if (found) {
181 myPlane = P;
182 }
183}
184
185//=======================================================================
186//function : Found
187//purpose :
188//=======================================================================
189
190Standard_Boolean BRepBuilderAPI_FindPlane::Found() const
191{
192 return !myPlane.IsNull();
193}
194
195//=======================================================================
196//function : Plane
197//purpose :
198//=======================================================================
199
200Handle(Geom_Plane) BRepBuilderAPI_FindPlane::Plane() const
201{
202 return myPlane;
203}
204