0023022: This is desirable to access OpenGl extensions and core API (1.2+) in one...
[occt.git] / src / Select3D / Select3D_SensitiveFace.cxx
CommitLineData
7fd59977 1// Copyright: Matra-Datavision 1995
2// File: Select3D_SensitiveFace.cxx
3// Created: Mon Mar 27 10:15:15 1995
4// Author: Robert COUBLANC
5// <rob>
6//Modif on jun-24-97 : introduction de CSLib_Class2d de LBR
7// pour teste si on est dedans ou dehors...
8//Modif on jul-21-97 : changement en harray1 pour eventuelles connexions ...
9
10#include <Select3D_SensitiveFace.ixx>
4bf18dff 11#include <Select3D_Projector.hxx>
7fd59977 12#include <SelectBasics_BasicTool.hxx>
13#include <gp_Pnt2d.hxx>
14#include <gp_Pnt.hxx>
15#include <Precision.hxx>
16#include <ElCLib.hxx>
17
18#include <CSLib_Class2d.hxx>
19
20
21#define AutoInterMask 0x01
22#define AutoComputeMask 0x02
23// Standard_True if the flag is one
24#define AutoInterFlag(aflag) ( aflag & AutoInterMask )
25#define AutoComputeFlag(aflag) ( aflag & AutoComputeMask )
26// set the flag to one
27#define SetAutoInterFlag(aflag) ( aflag = aflag & AutoInterMask)
28#define SetAutoComputeFlag(aflag) ( aflag = aflag & AutoComputeMask)
29// Initialize flags
30#define AutoInitFlags(aflag) (aflag = 0)
31
32//==================================================
81bba717 33// Function: Hide this constructor to the next version...
34// Purpose : simply avoid interfering with the version update
7fd59977 35//==================================================
36
37Select3D_SensitiveFace::
38Select3D_SensitiveFace(const Handle(SelectBasics_EntityOwner)& OwnerId,
ac04d101
SA
39 const TColgp_Array1OfPnt& ThePoints,
40 const Select3D_TypeOfSensitivity aType):
7fd59977 41Select3D_SensitivePoly(OwnerId, ThePoints),
42mytype (aType),
43myDetectedIndex(-1)
44{
45 AutoInitFlags(myautointer);
46}
47
48//==================================================
ac04d101 49// Function: Creation
7fd59977 50// Purpose :
51//==================================================
52
53Select3D_SensitiveFace::
54Select3D_SensitiveFace(const Handle(SelectBasics_EntityOwner)& OwnerId,
ac04d101
SA
55 const Handle(TColgp_HArray1OfPnt)& ThePoints,
56 const Select3D_TypeOfSensitivity aType):
7fd59977 57Select3D_SensitivePoly(OwnerId, ThePoints),
58mytype (aType),
59myDetectedIndex(-1)
60{
61 AutoInitFlags(myautointer);
62}
63
64//==================================================
ac04d101 65// Function: Matches
7fd59977 66// Purpose :
67//==================================================
68
69Standard_Boolean Select3D_SensitiveFace::
70Matches(const Standard_Real X,
ac04d101
SA
71 const Standard_Real Y,
72 const Standard_Real aTol,
73 Standard_Real& DMin)
7fd59977 74{
75#ifndef DEB
76 Standard_Real DMin2 = 0.;
77#else
78 Standard_Real DMin2;
79#endif
80 Standard_Real Xmin,Ymin,Xmax,Ymax;
ac04d101
SA
81 if(!Bnd_Box2d(mybox2d).IsVoid())
82 {
7fd59977 83 Bnd_Box2d(mybox2d).Get(Xmin,Ymin,Xmax,Ymax);
84 DMin2 = gp_XY(Xmax-Xmin,Ymax-Ymin).SquareModulus();
85 }
81bba717 86 // calculation of a criterion of minimum distance...
87 // from start Dmin = size of the bounding box 2D,
88 // then min. distance of the polyhedron or cdg...
7fd59977 89
90 Standard_Real aTol2 = aTol*aTol;
ceae62f0
A
91 Standard_Integer aSize = mypolyg.Size(), anIndex;
92 gp_XY CDG;
93 for(anIndex=0;anIndex<aSize;++anIndex)
ac04d101 94 {
ceae62f0 95 CDG+=mypolyg.Pnt2d(anIndex);
7fd59977 96 }
ceae62f0
A
97
98 if(aSize>1)
ac04d101 99 {
ceae62f0 100 CDG/=(aSize-1);
7fd59977 101 }
102 DMin2=Min(DMin2,gp_XY(CDG.X()-X,CDG.Y()-Y).SquareModulus());
103 DMin = Sqrt(DMin2);
ceae62f0 104
7fd59977 105 Standard_Boolean isplane2d(Standard_True);
ceae62f0
A
106
107 for(anIndex=1;anIndex<aSize;++anIndex)
ac04d101 108 {
ceae62f0
A
109 gp_XY V1(mypolyg.Pnt2d(anIndex)),V(X,Y);
110 V1-=mypolyg.Pnt2d(anIndex-1);
111 V-=mypolyg.Pnt2d(anIndex-1);
7fd59977 112 Standard_Real Vector = V1^V;
113 Standard_Real V1V1 = V1.SquareModulus();
114 DMin2 =
115 (V1V1 <=aTol2) ?
81bba717 116 Min(DMin2,V.SquareModulus()): // if the segment is too small...
7fd59977 117 Min(DMin2,Vector*Vector/V1V1);
118 //cdg ...
ceae62f0
A
119 gp_XY PlaneTest(CDG);
120 PlaneTest-=mypolyg.Pnt2d(anIndex-1);
7fd59977 121 Standard_Real valtst = PlaneTest^V1;
122 if(isplane2d && Abs(valtst)>aTol) isplane2d=Standard_False;
123 }
4bf18dff 124 if (isplane2d)
125 {
126 return Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin);
7fd59977 127 }
7fd59977 128
81bba717 129 //otherwise it is checked if the point is in the face...
ceae62f0 130 TColgp_Array1OfPnt2d aArrayOf2dPnt(1, aSize);
7fd59977 131 Points2D(aArrayOf2dPnt);
132 CSLib_Class2d TheInOutTool(aArrayOf2dPnt,aTol,aTol,Xmin,Ymin,Xmax,Ymax);
133 Standard_Integer TheStat = TheInOutTool.SiDans(gp_Pnt2d(X,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 {
148 return Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin);
149 }
150 return Standard_False;
7fd59977 151}
152
153//=======================================================================
154//function : Matches
155//purpose :
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
178//purpose :
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);
188 Standard_Real Tolu,Tolv;
189 Tolu = 1e-7;
190 Tolv = 1e-7;
191 CSLib_Class2d aClassifier2d(aPoly,aTol,aTol,Umin,Vmin,Umax,Vmax);
192
ceae62f0
A
193 gp_Pnt2d aPnt2d;
194 for(Standard_Integer anIndex=0;anIndex<mypolyg.Size();++anIndex)
ac04d101 195 {
ceae62f0
A
196 Standard_Integer RES = aClassifier2d.SiDans(mypolyg.Pnt2d(anIndex));
197 if(RES!=1)
198 return Standard_False;
7fd59977 199 }
200 return Standard_True;
201}
202
7fd59977 203//=======================================================================
204//function : Dump
205//purpose :
206//=======================================================================
ac04d101 207
7fd59977 208void Select3D_SensitiveFace::Dump(Standard_OStream& S,const Standard_Boolean FullDump) const
209{
210 S<<"\tSensitiveFace 3D :"<<endl;;
211 if(HasLocation())
212 S<<"\t\tExisting Location"<<endl;
213
214 if(mytype==Select3D_TOS_BOUNDARY)
215 S<<"\t\tSelection Of Bounding Polyline Only"<<endl;
216
ac04d101
SA
217 if(FullDump)
218 {
ceae62f0 219 S<<"\t\tNumber Of Points :"<<mypolyg.Size()<<endl;
7fd59977 220 Select3D_SensitiveEntity::DumpBox(S,mybox2d);
221 }
222}
223
224//=======================================================================
225//function : ComputeDepth
226//purpose :
227//=======================================================================
ac04d101 228
7fd59977 229Standard_Real Select3D_SensitiveFace::ComputeDepth(const gp_Lin& EyeLine) const
230{
4bf18dff 231 Standard_Real aDepth = Precision::Infinite();
ceae62f0 232
4bf18dff 233 Standard_Real aDepthMin = !mylastprj.IsNull() ? mylastprj->DepthMin() : -Precision::Infinite();
234 Standard_Real aDepthMax = !mylastprj.IsNull() ? mylastprj->DepthMax() : Precision::Infinite();
235 Standard_Real aDepthTest;
ceae62f0
A
236
237 for (Standard_Integer anIndex = 0; anIndex < mypolyg.Size()-1; ++anIndex)
4bf18dff 238 {
ceae62f0 239 aDepthTest = ElCLib::Parameter (EyeLine, mypolyg.Pnt(anIndex));
4bf18dff 240 if (aDepthTest < aDepth && (aDepthTest > aDepthMin) && (aDepthTest < aDepthMax))
241 {
242 aDepth = aDepthTest;
243 }
244 }
245 return aDepth;
7fd59977 246}
ac04d101
SA
247
248//=======================================================================
249//function : GetConnected
250//purpose :
251//=======================================================================
252
253Handle(Select3D_SensitiveEntity) Select3D_SensitiveFace::GetConnected(const TopLoc_Location &theLocation)
254{
ceae62f0
A
255 // Create a copy of this
256 Standard_Integer aSize = mypolyg.Size();
257 TColgp_Array1OfPnt aPoints(1, aSize);
258 for (Standard_Integer anIndex = 1; anIndex <= aSize; ++anIndex)
ac04d101 259 {
ceae62f0 260 aPoints.SetValue(anIndex, mypolyg.Pnt(anIndex-1));
ac04d101
SA
261 }
262
ceae62f0
A
263 Handle(Select3D_SensitiveEntity) aNewEntity =
264 new Select3D_SensitiveFace(myOwnerId, aPoints, mytype);
ac04d101 265
ceae62f0
A
266 if (HasLocation())
267 aNewEntity->SetLocation(Location());
ac04d101
SA
268
269 aNewEntity->UpdateLocation(theLocation);
270
271 return aNewEntity;
272}