0024157: Parallelization of assembly part of BO
[occt.git] / src / BRepBuilderAPI / BRepBuilderAPI_FindPlane.cxx
1 // Created on: 1995-11-02
2 // Created by: Jing Cheng MEI
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21
22 #include <BRepBuilderAPI_FindPlane.ixx>
23
24 #include <Precision.hxx>
25 #include <gp_Dir.hxx>
26 #include <gp_Vec.hxx>
27 #include <gp_Pln.hxx>
28 #include <TColgp_SequenceOfPnt.hxx>
29 #include <TopoDS.hxx>
30 #include <TopLoc_Location.hxx>
31 #include <TopExp_Explorer.hxx>
32 #include <BRep_Tool.hxx>
33
34 #include <Geom_Line.hxx> 
35 #include <Geom_Conic.hxx>
36 #include <Geom_Circle.hxx> 
37 #include <Geom_Ellipse.hxx> 
38 #include <Geom_Parabola.hxx> 
39 #include <Geom_Hyperbola.hxx> 
40 #include <Geom_BezierCurve.hxx>
41 #include <Geom_BSplineCurve.hxx>
42
43
44
45 //=======================================================================
46 //function : BRepBuilderAPI_FindPlane
47 //purpose  : 
48 //=======================================================================
49
50 BRepBuilderAPI_FindPlane::BRepBuilderAPI_FindPlane() 
51 {
52 }
53
54 //=======================================================================
55 //function : BRepBuilderAPI_FindPlane
56 //purpose  : 
57 //=======================================================================
58
59 BRepBuilderAPI_FindPlane::BRepBuilderAPI_FindPlane(const TopoDS_Shape&    S, 
60                                      const Standard_Real    Tol)
61 {
62   Init(S,Tol);
63 }
64
65 //=======================================================================
66 //function : Init
67 //purpose  : 
68 //=======================================================================
69
70 void BRepBuilderAPI_FindPlane::Init(const TopoDS_Shape&    S, 
71                              const Standard_Real    Tol)
72 {
73   Standard_Real tolerance = Tol;
74   myPlane.Nullify();
75
76   // compute the tolerance
77   TopExp_Explorer ex;
78   for (ex.Init(S,TopAbs_EDGE); ex.More(); ex.Next()) {
79     Standard_Real t = BRep_Tool::Tolerance(TopoDS::Edge(ex.Current()));
80     if (t > tolerance) tolerance = t;
81   }
82   
83   Standard_Real tol2 = tolerance*tolerance;
84   // try to find an analytical curve and calculate points
85   TopLoc_Location loc;
86   Standard_Real first, last;
87   Standard_Boolean found = Standard_False;  
88   Handle(Geom_Plane) P;
89   TColgp_SequenceOfPnt points;
90   Standard_Integer nbPnts;
91
92   for (ex.Init(S,TopAbs_EDGE); ex.More(); ex.Next()) {
93     Handle(Geom_Curve) c3d = 
94       BRep_Tool::Curve(TopoDS::Edge(ex.Current()), loc, first, last);
95
96     if (!c3d.IsNull()) {
97       Handle(Geom_Curve) c3dptr = 
98         Handle(Geom_Curve)::DownCast(c3d->Transformed(loc.Transformation()));
99
100       Handle(Standard_Type) cType = c3dptr->DynamicType();
101       
102       if (cType == STANDARD_TYPE(Geom_Line)) {
103         nbPnts = 3;
104       }
105       else if ((cType == STANDARD_TYPE(Geom_Circle)) ||
106                (cType == STANDARD_TYPE(Geom_Ellipse)) ||
107                (cType == STANDARD_TYPE(Geom_Parabola)) ||
108                (cType == STANDARD_TYPE(Geom_Hyperbola))) {
109         nbPnts = 4; 
110         if (!found) {
111           found = Standard_True;
112           Handle(Geom_Conic) Co = Handle(Geom_Conic)::DownCast(c3dptr);
113           P = new Geom_Plane(gp_Ax3(Co->Position()));
114         }
115       }
116       else if (cType == STANDARD_TYPE(Geom_BezierCurve)) {
117         Handle(Geom_BezierCurve) Co = 
118           Handle(Geom_BezierCurve)::DownCast(c3dptr);
119         nbPnts = Co->NbPoles();
120       }
121       else if (cType == STANDARD_TYPE(Geom_BSplineCurve)) {
122         Handle(Geom_BSplineCurve) Co = 
123           Handle(Geom_BSplineCurve)::DownCast(c3dptr);
124         nbPnts = Co->NbPoles();
125       }
126       else {
127         nbPnts = 10;
128       }
129       
130       gp_Pnt p0;
131       for (Standard_Integer i=1; i<=nbPnts; i++) {
132         if (i == 1) {
133           c3dptr->D0(first, p0);
134         }
135         else if (i == nbPnts) {
136           c3dptr->D0(last, p0);
137         }
138         else {
139           c3dptr->D0(first+(last-first)/(nbPnts-1)*(i-1), p0);
140         }
141         points.Append(p0);
142       }
143     }
144   }
145
146   if (!found) {
147     // try to find a plane with the points
148     if (points.Length() > 2) {    
149
150       Standard_Real disMax = 0.0;
151       gp_Pnt p0 = points(1);
152       gp_Pnt p1;
153       for (Standard_Integer i=2; i<=points.Length(); i++) {
154         Standard_Real dist = p0.SquareDistance(points(i));
155         if (dist > disMax) {
156           disMax = dist;
157           p1 = points(i); // it will be faster to store the point, otherwise it is necessary to find a value in a sequence
158         }
159       }
160
161       if (disMax > tol2) {
162         gp_Vec V1(p0, p1), V3;
163         Standard_Real proMax = 0.0;
164         gp_Pnt p2 = p0 ;
165         for (Standard_Integer j=2; j<=points.Length(); j++) {
166           V3 = V1^gp_Vec(p0, points(j));
167           Standard_Real pro = V3.SquareMagnitude();
168           if (pro > proMax) {
169             proMax = pro;
170             p2 = points(j);
171           }
172         }
173         
174         if (p0.SquareDistance(p2) > tol2) {
175           gp_Dir D1(V1), D2(gp_Vec(p0, p2));
176           if (!D1.IsParallel(D2, Precision::Angular())) {
177             P = new Geom_Plane(gp_Ax3(p0, D1.Crossed(D2), D1));
178             found = Standard_True;
179           }
180         }
181       }
182     }
183   }
184   
185   if (found) {
186     // test if all points are on the plane
187     const gp_Pln& pln = P->Pln();
188     for (Standard_Integer i=1; i<=points.Length(); i++) {
189       if (pln.SquareDistance(points(i)) > tol2) {
190         found = Standard_False;
191         break;
192       }
193     } 
194   }
195   
196   if (found) {
197     myPlane = P;
198   }
199 }
200
201 //=======================================================================
202 //function : Found
203 //purpose  : 
204 //=======================================================================
205
206 Standard_Boolean BRepBuilderAPI_FindPlane::Found() const 
207 {
208   return !myPlane.IsNull();
209 }
210
211 //=======================================================================
212 //function : Plane
213 //purpose  : 
214 //=======================================================================
215
216 Handle(Geom_Plane) BRepBuilderAPI_FindPlane::Plane() const 
217 {
218   return myPlane;
219 }
220