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