0024650: Wrong intersection curves obtained for a surface of revolution and a plane.
[occt.git] / src / Select3D / Select3D_SensitiveFace.cxx
CommitLineData
b311480e 1// Created on: 1995-03-27
2// Created by: Robert COUBLANC
3// Copyright (c) 1995-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.
b311480e 16
7fd59977 17//Modif on jun-24-97 : introduction de CSLib_Class2d de LBR
18// pour teste si on est dedans ou dehors...
19//Modif on jul-21-97 : changement en harray1 pour eventuelles connexions ...
20
21#include <Select3D_SensitiveFace.ixx>
4bf18dff 22#include <Select3D_Projector.hxx>
7fd59977 23#include <SelectBasics_BasicTool.hxx>
24#include <gp_Pnt2d.hxx>
25#include <gp_Pnt.hxx>
26#include <Precision.hxx>
27#include <ElCLib.hxx>
28
29#include <CSLib_Class2d.hxx>
30
7fd59977 31//==================================================
81bba717 32// Function: Hide this constructor to the next version...
33// Purpose : simply avoid interfering with the version update
7fd59977 34//==================================================
35
36Select3D_SensitiveFace::
37Select3D_SensitiveFace(const Handle(SelectBasics_EntityOwner)& OwnerId,
ac04d101
SA
38 const TColgp_Array1OfPnt& ThePoints,
39 const Select3D_TypeOfSensitivity aType):
7fd59977 40Select3D_SensitivePoly(OwnerId, ThePoints),
258ff83b 41mytype (aType)
7fd59977 42{
7fd59977 43}
44
45//==================================================
ac04d101 46// Function: Creation
7fd59977 47// Purpose :
48//==================================================
49
50Select3D_SensitiveFace::
51Select3D_SensitiveFace(const Handle(SelectBasics_EntityOwner)& OwnerId,
ac04d101
SA
52 const Handle(TColgp_HArray1OfPnt)& ThePoints,
53 const Select3D_TypeOfSensitivity aType):
7fd59977 54Select3D_SensitivePoly(OwnerId, ThePoints),
258ff83b 55mytype (aType)
7fd59977 56{
7fd59977 57}
58
59//==================================================
ac04d101 60// Function: Matches
7fd59977 61// Purpose :
62//==================================================
63
4269bd1b 64Standard_Boolean Select3D_SensitiveFace::Matches (const SelectBasics_PickArgs& thePickArgs,
65 Standard_Real& theMatchDMin,
66 Standard_Real& theMatchDepth)
7fd59977 67{
7fd59977 68 Standard_Real DMin2 = 0.;
1d47d8d0 69 Standard_Real Xmin = 0.,Ymin = 0.,Xmax = 0.,Ymax = 0.;
ac04d101
SA
70 if(!Bnd_Box2d(mybox2d).IsVoid())
71 {
7fd59977 72 Bnd_Box2d(mybox2d).Get(Xmin,Ymin,Xmax,Ymax);
73 DMin2 = gp_XY(Xmax-Xmin,Ymax-Ymin).SquareModulus();
74 }
81bba717 75 // calculation of a criterion of minimum distance...
76 // from start Dmin = size of the bounding box 2D,
77 // then min. distance of the polyhedron or cdg...
7fd59977 78
4269bd1b 79 Standard_Real aTol2 = thePickArgs.Tolerance() * thePickArgs.Tolerance();
ceae62f0
A
80 Standard_Integer aSize = mypolyg.Size(), anIndex;
81 gp_XY CDG;
82 for(anIndex=0;anIndex<aSize;++anIndex)
ac04d101 83 {
ceae62f0 84 CDG+=mypolyg.Pnt2d(anIndex);
7fd59977 85 }
ceae62f0
A
86
87 if(aSize>1)
ac04d101 88 {
ceae62f0 89 CDG/=(aSize-1);
7fd59977 90 }
4269bd1b 91 DMin2 = Min (DMin2, gp_XY (CDG.X() - thePickArgs.X(), CDG.Y() - thePickArgs.Y()).SquareModulus());
92 theMatchDMin = Sqrt(DMin2);
ceae62f0 93
7fd59977 94 Standard_Boolean isplane2d(Standard_True);
ceae62f0
A
95
96 for(anIndex=1;anIndex<aSize;++anIndex)
ac04d101 97 {
4269bd1b 98 gp_XY V1(mypolyg.Pnt2d(anIndex)),V(thePickArgs.X(), thePickArgs.Y());
ceae62f0
A
99 V1-=mypolyg.Pnt2d(anIndex-1);
100 V-=mypolyg.Pnt2d(anIndex-1);
7fd59977 101 Standard_Real Vector = V1^V;
102 Standard_Real V1V1 = V1.SquareModulus();
aec37c15 103 DMin2 =
104 (V1V1 <=aTol2) ?
81bba717 105 Min(DMin2,V.SquareModulus()): // if the segment is too small...
7fd59977 106 Min(DMin2,Vector*Vector/V1V1);
107 //cdg ...
ceae62f0
A
108 gp_XY PlaneTest(CDG);
109 PlaneTest-=mypolyg.Pnt2d(anIndex-1);
7fd59977 110 Standard_Real valtst = PlaneTest^V1;
4269bd1b 111 if(isplane2d && Abs(valtst) > thePickArgs.Tolerance()) isplane2d=Standard_False;
7fd59977 112 }
4bf18dff 113 if (isplane2d)
114 {
4269bd1b 115 theMatchDepth = ComputeDepth (thePickArgs.PickLine(),
116 thePickArgs.DepthMin(),
117 thePickArgs.DepthMax());
118
119 return !thePickArgs.IsClipped (theMatchDepth);
7fd59977 120 }
7fd59977 121
81bba717 122 //otherwise it is checked if the point is in the face...
ceae62f0 123 TColgp_Array1OfPnt2d aArrayOf2dPnt(1, aSize);
7fd59977 124 Points2D(aArrayOf2dPnt);
4269bd1b 125 CSLib_Class2d TheInOutTool (aArrayOf2dPnt,
126 thePickArgs.Tolerance(),
127 thePickArgs.Tolerance(),
128 Xmin, Ymin, Xmax, Ymax);
129 Standard_Integer TheStat = TheInOutTool.SiDans (gp_Pnt2d (thePickArgs.X(), thePickArgs.Y()));
ceae62f0 130
7fd59977 131 Standard_Boolean res(Standard_False);
ac04d101
SA
132 switch(TheStat)
133 {
7fd59977 134 case 0:
135 res = Standard_True;
136 case 1:
137 {
ceae62f0 138 if(mytype!=Select3D_TOS_BOUNDARY)
ac04d101 139 res = Standard_True;
7fd59977 140 }
141 }
4bf18dff 142 if (res)
143 {
4269bd1b 144 theMatchDepth = ComputeDepth (thePickArgs.PickLine(),
145 thePickArgs.DepthMin(),
146 thePickArgs.DepthMax());
147
148 return !thePickArgs.IsClipped (theMatchDepth);
4bf18dff 149 }
150 return Standard_False;
7fd59977 151}
152
153//=======================================================================
154//function : Matches
aec37c15 155//purpose :
7fd59977 156//=======================================================================
157
158Standard_Boolean Select3D_SensitiveFace::
159Matches (const Standard_Real XMin,
ac04d101
SA
160 const Standard_Real YMin,
161 const Standard_Real XMax,
162 const Standard_Real YMax,
163 const Standard_Real aTol)
164{
7fd59977 165 Bnd_Box2d BoundBox;
166 BoundBox.Update(XMin-aTol,YMin-aTol,XMax+aTol,YMax+aTol);
ceae62f0
A
167
168 for(Standard_Integer anIndex=0;anIndex<mypolyg.Size();++anIndex)
ac04d101 169 {
ceae62f0
A
170 if(BoundBox.IsOut(mypolyg.Pnt2d(anIndex)))
171 return Standard_False;
7fd59977 172 }
173 return Standard_True;
174}
175
176//=======================================================================
177//function : Matches
aec37c15 178//purpose :
7fd59977 179//=======================================================================
180
181Standard_Boolean Select3D_SensitiveFace::
182Matches (const TColgp_Array1OfPnt2d& aPoly,
ac04d101
SA
183 const Bnd_Box2d& aBox,
184 const Standard_Real aTol)
185{
7fd59977 186 Standard_Real Umin,Vmin,Umax,Vmax;
187 aBox.Get(Umin,Vmin,Umax,Vmax);
7fd59977 188 CSLib_Class2d aClassifier2d(aPoly,aTol,aTol,Umin,Vmin,Umax,Vmax);
189
ceae62f0
A
190 gp_Pnt2d aPnt2d;
191 for(Standard_Integer anIndex=0;anIndex<mypolyg.Size();++anIndex)
ac04d101 192 {
ceae62f0
A
193 Standard_Integer RES = aClassifier2d.SiDans(mypolyg.Pnt2d(anIndex));
194 if(RES!=1)
195 return Standard_False;
7fd59977 196 }
197 return Standard_True;
198}
199
7fd59977 200//=======================================================================
201//function : Dump
aec37c15 202//purpose :
7fd59977 203//=======================================================================
ac04d101 204
7fd59977 205void Select3D_SensitiveFace::Dump(Standard_OStream& S,const Standard_Boolean FullDump) const
206{
207 S<<"\tSensitiveFace 3D :"<<endl;;
208 if(HasLocation())
209 S<<"\t\tExisting Location"<<endl;
aec37c15 210
211 if(mytype==Select3D_TOS_BOUNDARY)
7fd59977 212 S<<"\t\tSelection Of Bounding Polyline Only"<<endl;
aec37c15 213
ac04d101
SA
214 if(FullDump)
215 {
ceae62f0 216 S<<"\t\tNumber Of Points :"<<mypolyg.Size()<<endl;
7fd59977 217 Select3D_SensitiveEntity::DumpBox(S,mybox2d);
218 }
219}
220
221//=======================================================================
222//function : ComputeDepth
aec37c15 223//purpose :
7fd59977 224//=======================================================================
ac04d101 225
4269bd1b 226Standard_Real Select3D_SensitiveFace::ComputeDepth (const gp_Lin& thePickLine,
227 const Standard_Real theDepthMin,
228 const Standard_Real theDepthMax) const
7fd59977 229{
4bf18dff 230 Standard_Real aDepth = Precision::Infinite();
4269bd1b 231 Standard_Real aPointDepth;
ceae62f0
A
232
233 for (Standard_Integer anIndex = 0; anIndex < mypolyg.Size()-1; ++anIndex)
4bf18dff 234 {
4269bd1b 235 aPointDepth = ElCLib::Parameter (thePickLine, mypolyg.Pnt(anIndex));
236 if (aPointDepth < aDepth && (aPointDepth > theDepthMin) && (aPointDepth < theDepthMax))
4bf18dff 237 {
4269bd1b 238 aDepth = aPointDepth;
4bf18dff 239 }
240 }
241 return aDepth;
7fd59977 242}
ac04d101 243
4269bd1b 244//=======================================================================
245//function : ComputeDepth
246//purpose :
247//=======================================================================
248
249void Select3D_SensitiveFace::ComputeDepth(const gp_Lin& /*theEyeLine*/) const
250{
251 // this method is obsolete.
252}
253
ac04d101
SA
254//=======================================================================
255//function : GetConnected
aec37c15 256//purpose :
ac04d101
SA
257//=======================================================================
258
aec37c15 259Handle(Select3D_SensitiveEntity) Select3D_SensitiveFace::GetConnected(const TopLoc_Location &theLocation)
ac04d101 260{
ceae62f0
A
261 // Create a copy of this
262 Standard_Integer aSize = mypolyg.Size();
263 TColgp_Array1OfPnt aPoints(1, aSize);
264 for (Standard_Integer anIndex = 1; anIndex <= aSize; ++anIndex)
ac04d101 265 {
ceae62f0 266 aPoints.SetValue(anIndex, mypolyg.Pnt(anIndex-1));
ac04d101
SA
267 }
268
ceae62f0
A
269 Handle(Select3D_SensitiveEntity) aNewEntity =
270 new Select3D_SensitiveFace(myOwnerId, aPoints, mytype);
ac04d101 271
ceae62f0
A
272 if (HasLocation())
273 aNewEntity->SetLocation(Location());
ac04d101
SA
274
275 aNewEntity->UpdateLocation(theLocation);
276
277 return aNewEntity;
aec37c15 278}