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