0030679: Attached model hangs most of OCCT common functionality
[occt.git] / src / BRepClass / BRepClass_Intersector.cxx
CommitLineData
b311480e 1// Created on: 1992-11-19
2// Created by: Remi LEQUETTE
3// Copyright (c) 1992-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
42cf5bc1 17
7fd59977 18#include <BRep_Tool.hxx>
19#include <BRepAdaptor_Curve2d.hxx>
20#include <BRepAdaptor_Surface.hxx>
42cf5bc1 21#include <BRepClass_Edge.hxx>
22#include <BRepClass_Intersector.hxx>
7fd59977 23#include <ElCLib.hxx>
42cf5bc1 24#include <Extrema_ExtPC2d.hxx>
25#include <Geom2d_Curve.hxx>
7fd59977 26#include <Geom2d_Line.hxx>
7fd59977 27#include <Geom2dInt_GInter.hxx>
42cf5bc1 28#include <Geom2dLProp_CLProps2d.hxx>
29#include <gp_Dir2d.hxx>
30#include <gp_Lin2d.hxx>
31#include <IntRes2d_Domain.hxx>
312cd1f5 32#include <IntRes2d_IntersectionPoint.hxx>
42cf5bc1 33#include <IntRes2d_Transition.hxx>
34#include <Precision.hxx>
35#include <TopExp.hxx>
36#include <TopoDS_Vertex.hxx>
312cd1f5 37
8f9a9b9d 38static
73cd8a8a 39void RefineTolerance(const TopoDS_Face& aF,
40 const BRepAdaptor_Curve2d& aC,
41 const Standard_Real aT,
42 Standard_Real& aTolZ);
8f9a9b9d 43
7fd59977 44//=======================================================================
45//function : BRepClass_Intersector
46//purpose :
47//=======================================================================
48
49BRepClass_Intersector::BRepClass_Intersector()
50{
51}
52
53//=======================================================================
54//function : Perform
55//purpose :
56//=======================================================================
7fd59977 57void BRepClass_Intersector::Perform(const gp_Lin2d& L,
73cd8a8a 58 const Standard_Real P,
59 const Standard_Real Tol,
60 const BRepClass_Edge& E)
7fd59977 61{
73cd8a8a 62 Standard_Real deb = 0.0, fin = 0.0, aTolZ = Tol;
8f9a9b9d 63 Handle(Geom2d_Curve) aC2D;
64 //
8f9a9b9d 65 const TopoDS_Edge& EE = E.Edge();
66 const TopoDS_Face& F = E.Face();
73cd8a8a 67
8f9a9b9d 68 //
69 aC2D=BRep_Tool::CurveOnSurface(EE, F, deb, fin);
70 if (aC2D.IsNull()) {
7fd59977 71 done = Standard_False; // !IsDone()
8f9a9b9d 72 return;
7fd59977 73 }
8f9a9b9d 74 //
75 BRepAdaptor_Curve2d C(EE, F);
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
73cd8a8a 82 Extrema_ExtPC2d anExtPC2d(L.Location(), C);
8f9a9b9d 83 Standard_Real MinDist = RealLast(), aDist;
84 Standard_Integer MinInd = 0, i;
73cd8a8a 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;
312cd1f5 96 }
97 }
8f9a9b9d 98 }
73cd8a8a 99
8f9a9b9d 100 if (MinInd) {
101 MinDist = sqrt(MinDist);
102 }
103 if (MinDist <= aTolZ) {
73cd8a8a 104 gp_Pnt2d pnt_exact = (anExtPC2d.Point(MinInd)).Value();
105 Standard_Real par = (anExtPC2d.Point(MinInd)).Parameter();
8f9a9b9d 106 //
107 RefineTolerance(F, C, par, aTolZ);
108 //
109 if (MinDist <= aTolZ) {
312cd1f5 110 IntRes2d_Transition tr_on_lin(IntRes2d_Head);
111 IntRes2d_Position pos_on_curve = IntRes2d_Middle;
8f9a9b9d 112 if (Abs(par - deb) <= Precision::Confusion()) {
73cd8a8a 113 pos_on_curve = IntRes2d_Head;
8f9a9b9d 114 }
115 else if (Abs(par - fin) <= Precision::Confusion()) {
73cd8a8a 116 pos_on_curve = IntRes2d_End;
8f9a9b9d 117 }
118 //
312cd1f5 119 IntRes2d_Transition tr_on_curve(pos_on_curve);
120 IntRes2d_IntersectionPoint pnt_inter(pnt_exact, 0., par,
73cd8a8a 121 tr_on_lin, tr_on_curve,
122 Standard_False);
8f9a9b9d 123 //
124 Append(pnt_inter);
312cd1f5 125 done = Standard_True;
126 return;
127 }
7fd59977 128 }
8f9a9b9d 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;
73cd8a8a 134
8f9a9b9d 135 IntRes2d_Domain DL;
136 //
137 if(P!=RealLast()) {
4680b22c 138 DL.SetValues(L.Location(),0.,Precision::PConfusion(),ElCLib::Value(P,L),P,Precision::PConfusion());
8f9a9b9d 139 }
140 else {
4680b22c 141 DL.SetValues(L.Location(),0.,Precision::PConfusion(),Standard_True);
8f9a9b9d 142 }
73cd8a8a 143
8f9a9b9d 144 IntRes2d_Domain DE(pdeb,deb,toldeb,pfin,fin,tolfin);
145 // temporary periodic domain
146 if (C.Curve()->IsPeriodic()) {
147 DE.SetEquivalentParameters(C.FirstParameter(),
73cd8a8a 148 C.FirstParameter() +
149 C.Curve()->LastParameter() -
150 C.Curve()->FirstParameter());
8f9a9b9d 151 }
73cd8a8a 152
8f9a9b9d 153 Handle(Geom2d_Line) GL= new Geom2d_Line(L);
154 Geom2dAdaptor_Curve CGA(GL);
155 Geom2dInt_GInter Inter(CGA,DL,C,DE,
73cd8a8a 156 Precision::PConfusion(),
157 Precision::PIntersection());
8f9a9b9d 158 //
159 SetValues(Inter);
7fd59977 160}
161
162//=======================================================================
163//function : LocalGeometry
164//purpose :
165//=======================================================================
7fd59977 166void BRepClass_Intersector::LocalGeometry(const BRepClass_Edge& E,
73cd8a8a 167 const Standard_Real U,
168 gp_Dir2d& Tang,
169 gp_Dir2d& Norm,
170 Standard_Real& C) const
7fd59977 171{
172 Standard_Real f,l;
173 Geom2dLProp_CLProps2d Prop(BRep_Tool::CurveOnSurface(E.Edge(),E.Face(),f,l),
73cd8a8a 174 U,2,Precision::PConfusion());
7fd59977 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
8f9a9b9d 183//=======================================================================
184//function : RefineTolerance
185//purpose :
186//=======================================================================
187void RefineTolerance(const TopoDS_Face& aF,
73cd8a8a 188 const BRepAdaptor_Curve2d& aC,
189 const Standard_Real aT,
190 Standard_Real& aTolZ)
8f9a9b9d 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 //
ce101cac 213 if (aTolX < Precision::Confusion()) {
214 aTolX = Precision::Confusion();
215 }
216 //
8f9a9b9d 217 if (aTolX<aTolZ) {
218 aTolZ=aTolX;
219 }
220 }
221}
7fd59977 222
223