0024459: Exception during clearing object in test case v3d/raytrace/connected in...
[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-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
23 #include <BRepClass_Intersector.ixx>
24 #include <BRep_Tool.hxx>
25 #include <BRepAdaptor_Curve2d.hxx>
26 #include <BRepAdaptor_Surface.hxx>
27 #include <TopoDS_Vertex.hxx>
28 #include <TopExp.hxx>
29 #include <IntRes2d_Domain.hxx>
30 #include <Geom2dLProp_CLProps2d.hxx>
31 #include <Geom2d_Curve.hxx>
32 #include <ElCLib.hxx>
33 #include <Precision.hxx>
34
35 #include <Geom2d_Line.hxx>
36
37 #include <Geom2dInt_GInter.hxx>
38
39 #include <Extrema_ExtPC2d.hxx>
40 #include <IntRes2d_Transition.hxx>
41 #include <IntRes2d_IntersectionPoint.hxx>
42
43 static 
44   void RefineTolerance(const TopoDS_Face& aF,
45                        const BRepAdaptor_Curve2d& aC,
46                        const Standard_Real aT,
47                        Standard_Real& aTolZ);
48
49 //=======================================================================
50 //function : BRepClass_Intersector
51 //purpose  : 
52 //=======================================================================
53
54 BRepClass_Intersector::BRepClass_Intersector()
55 {
56 }
57
58 //=======================================================================
59 //function : Perform
60 //purpose  : 
61 //=======================================================================
62 void  BRepClass_Intersector::Perform(const gp_Lin2d& L, 
63                                      const Standard_Real P, 
64                                      const Standard_Real Tol, 
65                                      const BRepClass_Edge& E)
66 {
67   Standard_Real deb, fin, aTolZ;
68   Handle(Geom2d_Curve) aC2D;
69   //
70   aTolZ=Tol;
71   const TopoDS_Edge& EE = E.Edge();
72   const TopoDS_Face& F = E.Face();
73   //
74   aC2D=BRep_Tool::CurveOnSurface(EE, F, deb, fin);
75   if (aC2D.IsNull()) {
76     done = Standard_False; // !IsDone()
77     return;
78   }
79   //
80   BRepAdaptor_Curve2d C(EE, F);
81   //
82   deb = C.FirstParameter();
83   fin = C.LastParameter();
84   //
85   // Case of "ON": direct check of belonging to edge
86   // taking into account the tolerance
87   Extrema_ExtPC2d theExtPC2d(L.Location(), C);
88   Standard_Real MinDist = RealLast(), aDist;
89   Standard_Integer MinInd = 0, i;
90   if (theExtPC2d.IsDone()) {
91     for (i = 1; i <= theExtPC2d.NbExt(); ++i) {
92       aDist = theExtPC2d.SquareDistance(i);
93       if (aDist < MinDist) {
94         MinDist = aDist;
95         MinInd = i;
96       }
97     }
98   }
99   if (MinInd) {
100     MinDist = sqrt(MinDist);
101   }
102   if (MinDist <= aTolZ) {
103     gp_Pnt2d pnt_exact = (theExtPC2d.Point(MinInd)).Value();
104     Standard_Real par = (theExtPC2d.Point(MinInd)).Parameter();
105     //
106     RefineTolerance(F, C, par, aTolZ);
107     //
108     if (MinDist <= aTolZ) {
109       IntRes2d_Transition tr_on_lin(IntRes2d_Head);
110       IntRes2d_Position pos_on_curve = IntRes2d_Middle;
111       if (Abs(par - deb) <= Precision::Confusion()) {
112         pos_on_curve = IntRes2d_Head;
113       }
114       else if (Abs(par - fin) <= Precision::Confusion()) {
115         pos_on_curve = IntRes2d_End;
116       }
117       //
118       IntRes2d_Transition tr_on_curve(pos_on_curve);
119       IntRes2d_IntersectionPoint pnt_inter(pnt_exact, 0., par,
120                                            tr_on_lin, tr_on_curve, 
121                                            Standard_False);
122       //
123       Append(pnt_inter);
124       done = Standard_True;
125       return;
126     }
127   }
128   //  
129   gp_Pnt2d pdeb,pfin;
130   C.D0(deb,pdeb);
131   C.D0(fin,pfin);
132   Standard_Real toldeb = 1.e-5, tolfin = 1.e-5;
133  
134   IntRes2d_Domain DL;
135   //
136   if(P!=RealLast()) {
137     DL.SetValues(L.Location(),0.,aTolZ,ElCLib::Value(P,L),P,aTolZ);
138   }
139   else { 
140     DL.SetValues(L.Location(),0.,aTolZ,Standard_True);
141   }
142  
143   IntRes2d_Domain DE(pdeb,deb,toldeb,pfin,fin,tolfin);
144   // temporary periodic domain
145   if (C.Curve()->IsPeriodic()) {
146     DE.SetEquivalentParameters(C.FirstParameter(),
147                                C.FirstParameter() + 
148                                C.Curve()->LastParameter() -
149                                C.Curve()->FirstParameter());
150   }
151   
152   Handle(Geom2d_Line) GL= new Geom2d_Line(L);
153   Geom2dAdaptor_Curve CGA(GL);
154   Geom2dInt_GInter Inter(CGA,DL,C,DE,
155                          Precision::PConfusion(),
156                          Precision::PIntersection());
157   //
158   SetValues(Inter);
159 }
160
161 //=======================================================================
162 //function : LocalGeometry
163 //purpose  : 
164 //=======================================================================
165 void  BRepClass_Intersector::LocalGeometry(const BRepClass_Edge& E, 
166                                            const Standard_Real U, 
167                                            gp_Dir2d& Tang, 
168                                            gp_Dir2d& Norm, 
169                                            Standard_Real& C) const 
170 {
171   Standard_Real f,l;
172   Geom2dLProp_CLProps2d Prop(BRep_Tool::CurveOnSurface(E.Edge(),E.Face(),f,l),
173                              U,2,Precision::PConfusion());
174   Prop.Tangent(Tang);
175   C = Prop.Curvature();
176   if (C > Precision::PConfusion())
177     Prop.Normal(Norm);
178   else
179     Norm.SetCoord(Tang.Y(),-Tang.X());
180 }
181
182 //=======================================================================
183 //function : RefineTolerance
184 //purpose  : 
185 //=======================================================================
186 void RefineTolerance(const TopoDS_Face& aF,
187                      const BRepAdaptor_Curve2d& aC,
188                      const Standard_Real aT,
189                      Standard_Real& aTolZ)
190 {
191   GeomAbs_SurfaceType aTypeS;
192   //
193   BRepAdaptor_Surface aBAS(aF, Standard_False);
194   //
195   aTypeS=aBAS.GetType();
196   if (aTypeS==GeomAbs_Cylinder) {
197     Standard_Real aURes, aVRes, aTolX;
198     gp_Pnt2d aP2D;
199     gp_Vec2d aV2D;
200     //
201     aURes=aBAS.UResolution(aTolZ);
202     aVRes=aBAS.VResolution(aTolZ);
203     //
204     aC.D1(aT, aP2D, aV2D);
205     gp_Dir2d aD2D(aV2D);
206     //
207     aTolX=aURes*aD2D.Y()+aVRes*aD2D.X();
208     if (aTolX<0.) {
209       aTolX=-aTolX;
210     }
211     //
212     if (aTolX < Precision::Confusion()) {
213       aTolX = Precision::Confusion();
214     }
215     //
216     if (aTolX<aTolZ) {
217       aTolZ=aTolX;
218     }
219   }
220 }
221
222