a141f56d054b0e563f22f26ec7e0228f1d04b092
[occt.git] / src / BRepClass / BRepClass_Intersector.cxx
1 // Created on: 1992-11-19
2 // Created by: Remi LEQUETTE
3 // Copyright (c) 1992-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <BRep_Tool.hxx>
19 #include <BRepAdaptor_Curve2d.hxx>
20 #include <BRepAdaptor_Surface.hxx>
21 #include <BRepClass_Edge.hxx>
22 #include <BRepClass_Intersector.hxx>
23 #include <ElCLib.hxx>
24 #include <Extrema_ExtPC2d.hxx>
25 #include <Geom2d_Curve.hxx>
26 #include <Geom2d_Line.hxx>
27 #include <Geom2dInt_GInter.hxx>
28 #include <Geom2dLProp_CLProps2d.hxx>
29 #include <gp_Dir2d.hxx>
30 #include <gp_Lin2d.hxx>
31 #include <IntRes2d_Domain.hxx>
32 #include <IntRes2d_IntersectionPoint.hxx>
33 #include <IntRes2d_Transition.hxx>
34 #include <Precision.hxx>
35 #include <TopExp.hxx>
36 #include <TopoDS_Vertex.hxx>
37
38 static 
39 void RefineTolerance(const TopoDS_Face& aF,
40                      const Geom2dAdaptor_Curve& aC,
41                      const Standard_Real aT,
42                      Standard_Real& aTolZ);
43
44 //=======================================================================
45 //function : BRepClass_Intersector
46 //purpose  : 
47 //=======================================================================
48
49 BRepClass_Intersector::BRepClass_Intersector()
50 {
51 }
52
53 //=======================================================================
54 //function : Perform
55 //purpose  : 
56 //=======================================================================
57 void  BRepClass_Intersector::Perform(const gp_Lin2d& L, 
58                                      const Standard_Real P, 
59                                      const Standard_Real Tol, 
60                                      const BRepClass_Edge& E)
61 {
62   Standard_Real deb = 0.0, fin = 0.0, aTolZ = Tol;
63   Handle(Geom2d_Curve) aC2D;
64   //
65   const TopoDS_Edge& EE = E.Edge();
66   const TopoDS_Face& F = E.Face();
67
68   //
69   aC2D=BRep_Tool::CurveOnSurface(EE, F, deb, fin);
70   if (aC2D.IsNull()) {
71     done = Standard_False; // !IsDone()
72     return;
73   }
74   //
75   Geom2dAdaptor_Curve C(aC2D, deb, fin);
76   //
77   deb = C.FirstParameter();
78   fin = C.LastParameter();
79   //
80   // Case of "ON": direct check of belonging to edge
81   // taking into account the tolerance
82   Extrema_ExtPC2d anExtPC2d(L.Location(), C);
83   Standard_Real MinDist = RealLast(), aDist;
84   Standard_Integer MinInd = 0, i;
85   if (anExtPC2d.IsDone())
86   {
87     const Standard_Integer aNbPnts = anExtPC2d.NbExt();
88     for (i = 1; i <= aNbPnts; ++i)
89     {
90       aDist = anExtPC2d.SquareDistance(i);
91
92       if (aDist < MinDist)
93       {
94         MinDist = aDist;
95         MinInd = i;
96       }
97     }
98   }
99
100   if (MinInd) {
101     MinDist = sqrt(MinDist);
102   }
103   if (MinDist <= aTolZ) {
104     gp_Pnt2d pnt_exact = (anExtPC2d.Point(MinInd)).Value();
105     Standard_Real par = (anExtPC2d.Point(MinInd)).Parameter();
106     //
107     RefineTolerance(F, C, par, aTolZ);
108     //
109     if (MinDist <= aTolZ) {
110       IntRes2d_Transition tr_on_lin(IntRes2d_Head);
111       IntRes2d_Position pos_on_curve = IntRes2d_Middle;
112       if (Abs(par - deb) <= Precision::Confusion()) {
113         pos_on_curve = IntRes2d_Head;
114       }
115       else if (Abs(par - fin) <= Precision::Confusion()) {
116         pos_on_curve = IntRes2d_End;
117       }
118       //
119       IntRes2d_Transition tr_on_curve(pos_on_curve);
120       IntRes2d_IntersectionPoint pnt_inter(pnt_exact, 0., par,
121         tr_on_lin, tr_on_curve, 
122         Standard_False);
123       //
124       Append(pnt_inter);
125       done = Standard_True;
126       return;
127     }
128   }
129   //  
130   gp_Pnt2d pdeb,pfin;
131   C.D0(deb,pdeb);
132   C.D0(fin,pfin);
133   Standard_Real toldeb = 1.e-5, tolfin = 1.e-5;
134
135   IntRes2d_Domain DL;
136   //
137   if(P!=RealLast()) {
138     DL.SetValues(L.Location(),0.,Precision::PConfusion(),ElCLib::Value(P,L),P,Precision::PConfusion());
139   }
140   else { 
141     DL.SetValues(L.Location(),0.,Precision::PConfusion(),Standard_True);
142   }
143
144   IntRes2d_Domain DE(pdeb,deb,toldeb,pfin,fin,tolfin);
145   // temporary periodic domain
146   if (C.Curve()->IsPeriodic()) {
147     DE.SetEquivalentParameters(C.FirstParameter(),
148       C.FirstParameter() + 
149       C.Curve()->LastParameter() -
150       C.Curve()->FirstParameter());
151   }
152
153   Handle(Geom2d_Line) GL= new Geom2d_Line(L);
154   Geom2dAdaptor_Curve CGA(GL);
155   Geom2dInt_GInter Inter(CGA,DL,C,DE,
156     Precision::PConfusion(),
157     Precision::PIntersection());
158   //
159   SetValues(Inter);
160 }
161
162 //=======================================================================
163 //function : LocalGeometry
164 //purpose  : 
165 //=======================================================================
166 void  BRepClass_Intersector::LocalGeometry(const BRepClass_Edge& E, 
167                                            const Standard_Real U, 
168                                            gp_Dir2d& Tang, 
169                                            gp_Dir2d& Norm, 
170                                            Standard_Real& C) const 
171 {
172   Standard_Real f,l;
173   Geom2dLProp_CLProps2d Prop(BRep_Tool::CurveOnSurface(E.Edge(),E.Face(),f,l),
174     U,2,Precision::PConfusion());
175   Prop.Tangent(Tang);
176   C = Prop.Curvature();
177   if (C > Precision::PConfusion())
178     Prop.Normal(Norm);
179   else
180     Norm.SetCoord(Tang.Y(),-Tang.X());
181 }
182
183 //=======================================================================
184 //function : RefineTolerance
185 //purpose  : 
186 //=======================================================================
187 void RefineTolerance(const TopoDS_Face& aF,
188                      const Geom2dAdaptor_Curve& aC,
189                      const Standard_Real aT,
190                      Standard_Real& aTolZ)
191 {
192   GeomAbs_SurfaceType aTypeS;
193   //
194   BRepAdaptor_Surface aBAS(aF, Standard_False);
195   //
196   aTypeS=aBAS.GetType();
197   if (aTypeS==GeomAbs_Cylinder) {
198     Standard_Real aURes, aVRes, aTolX;
199     gp_Pnt2d aP2D;
200     gp_Vec2d aV2D;
201     //
202     aURes=aBAS.UResolution(aTolZ);
203     aVRes=aBAS.VResolution(aTolZ);
204     //
205     aC.D1(aT, aP2D, aV2D);
206     gp_Dir2d aD2D(aV2D);
207     //
208     aTolX=aURes*aD2D.Y()+aVRes*aD2D.X();
209     if (aTolX<0.) {
210       aTolX=-aTolX;
211     }
212     //
213     if (aTolX < Precision::Confusion()) {
214       aTolX = Precision::Confusion();
215     }
216     //
217     if (aTolX<aTolZ) {
218       aTolZ=aTolX;
219     }
220   }
221 }
222
223