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