0022554: Application hangs on selection
[occt.git] / src / Select3D / Select3D_SensitiveCurve.cxx
CommitLineData
7fd59977 1// Copyright: Matra-Datavision 1995
2// File: Select3D_SensitiveCurve.cxx
3// Created: Mon Mar 13 09:57:58 1995
4// Author: Robert COUBLANC
5// <rob>
6
7
8
9#include <Select3D_SensitiveCurve.ixx>
10#include <SelectBasics_BasicTool.hxx>
11#include <gp_Lin2d.hxx>
12#include <Precision.hxx>
13#include <ElCLib.hxx>
14#include <CSLib_Class2d.hxx>
15
16
17//==================================================
ac04d101 18// Function: Creation
7fd59977 19// Purpose :
20//==================================================
21
22Select3D_SensitiveCurve
23::Select3D_SensitiveCurve(const Handle(SelectBasics_EntityOwner)& OwnerId,
ac04d101
SA
24 const Handle(Geom_Curve)& C,
25 const Standard_Integer NbPoints):
7fd59977 26Select3D_SensitivePoly(OwnerId, NbPoints),
ac04d101
SA
27mylastseg(0),
28myCurve(C)
7fd59977 29{
30 LoadPoints(C,NbPoints);
31}
ac04d101 32
7fd59977 33//==================================================
34// Function: Creation
35// Purpose :
36//==================================================
ac04d101 37
7fd59977 38Select3D_SensitiveCurve
39::Select3D_SensitiveCurve(const Handle(SelectBasics_EntityOwner)& OwnerId,
ac04d101 40 const Handle(TColgp_HArray1OfPnt)& ThePoints):
7fd59977 41Select3D_SensitivePoly(OwnerId, ThePoints),
ac04d101 42mylastseg(0)
7fd59977 43{
44}
ac04d101 45
7fd59977 46//==================================================
47// Function: Creation
48// Purpose :
49//==================================================
ac04d101 50
7fd59977 51Select3D_SensitiveCurve
52::Select3D_SensitiveCurve(const Handle(SelectBasics_EntityOwner)& OwnerId,
ac04d101 53 const TColgp_Array1OfPnt& ThePoints):
7fd59977 54Select3D_SensitivePoly(OwnerId, ThePoints),
ac04d101 55mylastseg(0)
7fd59977 56{
57}
58
59//==================================================
60// Function: Matches
61// Purpose :
62//==================================================
ac04d101 63
7fd59977 64Standard_Boolean Select3D_SensitiveCurve
65::Matches(const Standard_Real X,
ac04d101
SA
66 const Standard_Real Y,
67 const Standard_Real aTol,
68 Standard_Real& DMin)
7fd59977 69{
70 Standard_Integer Rank;
ceae62f0 71 TColgp_Array1OfPnt2d aArrayOf2dPnt(1, mypolyg.Size());
7fd59977 72 Points2D(aArrayOf2dPnt);
4952a30a 73 if (SelectBasics_BasicTool::MatchPolyg2d (aArrayOf2dPnt,
74 X, Y,
75 aTol,
76 DMin,
77 Rank))
78 {
7fd59977 79 mylastseg = Rank;
4952a30a 80 // compute and validate the depth (::Depth()) along the eyeline
81 return Select3D_SensitiveEntity::Matches (X, Y, aTol, DMin);
7fd59977 82 }
4952a30a 83 return Standard_False;
7fd59977 84}
ac04d101 85
7fd59977 86//==================================================
87// Function: Matches
88// Purpose : know if a box touches the projected polygon
89// of the Curve.
90//==================================================
91
92Standard_Boolean Select3D_SensitiveCurve::
93Matches (const Standard_Real XMin,
ac04d101
SA
94 const Standard_Real YMin,
95 const Standard_Real XMax,
96 const Standard_Real YMax,
97 const Standard_Real aTol)
98{
7fd59977 99 Bnd_Box2d BoundBox;
100 BoundBox.Update(XMin-aTol,YMin-aTol,XMax+aTol,YMax+aTol);
101
ceae62f0 102 for(Standard_Integer anIndex=0; anIndex<mypolyg.Size(); ++anIndex)
7fd59977 103 {
ceae62f0
A
104 if(BoundBox.IsOut(mypolyg.Pnt2d(anIndex)))
105 return Standard_False;
7fd59977 106 }
107 return Standard_True;
108}
109
110//=======================================================================
111//function : Matches
112//purpose :
113//=======================================================================
114
115Standard_Boolean Select3D_SensitiveCurve::
116Matches (const TColgp_Array1OfPnt2d& aPoly,
ac04d101
SA
117 const Bnd_Box2d& aBox,
118 const Standard_Real aTol)
119{
7fd59977 120 Standard_Real Umin,Vmin,Umax,Vmax;
121 aBox.Get(Umin,Vmin,Umax,Vmax);
122 Standard_Real Tolu,Tolv;
123 Tolu = 1e-7;
124 Tolv = 1e-7;
125 CSLib_Class2d aClassifier2d(aPoly,aTol,aTol,Umin,Vmin,Umax,Vmax);
126
ceae62f0 127 for(Standard_Integer anIndex=0;anIndex<mypolyg.Size();++anIndex)
ac04d101 128 {
ceae62f0
A
129 Standard_Integer RES = aClassifier2d.SiDans(mypolyg.Pnt2d(anIndex));
130 if(RES!=1)
131 return Standard_False;
7fd59977 132 }
133 return Standard_True;
134}
135
7fd59977 136//==================================================
ac04d101 137// Function: LoadPoints
7fd59977 138// Purpose :
139//==================================================
140
141void Select3D_SensitiveCurve
142::LoadPoints (const Handle(Geom_Curve)& aCurve,const Standard_Integer NbP)
143{
144 /*this method is private and it used only inside of constructor.
145 That's why check !NbP==mypolyg3d->Length() was removed*/
146
147 Standard_Real Step = (aCurve->LastParameter()- aCurve->FirstParameter())/(NbP-1);
148 Standard_Real Curparam = aCurve->FirstParameter();
ceae62f0
A
149 for(Standard_Integer anIndex=0;anIndex<mypolyg.Size();++anIndex)
150 {
151 mypolyg.SetPnt(anIndex, aCurve->Value(Curparam));
152 Curparam+=Step;
153 }
7fd59977 154}
155
156//=======================================================================
157//function : Dump
158//purpose :
159//=======================================================================
160
161void Select3D_SensitiveCurve::Dump(Standard_OStream& S,const Standard_Boolean FullDump) const
162{
163 S<<"\tSensitiveCurve 3D :"<<endl;
ceae62f0 164 if (HasLocation())
7fd59977 165 S<<"\t\tExisting Location"<<endl;
166
ceae62f0 167 S<<"\t\tNumber Of Points :"<<mypolyg.Size()<<endl;
7fd59977 168
ac04d101
SA
169 if(FullDump)
170 {
7fd59977 171 Select3D_SensitiveEntity::DumpBox(S,mybox2d);
172 }
173}
ac04d101 174
7fd59977 175//=======================================================================
176//function : ComputeDepth
177//purpose :
178//=======================================================================
179
180Standard_Real Select3D_SensitiveCurve::ComputeDepth(const gp_Lin& EyeLine) const
181{
ceae62f0
A
182 Standard_Real aDepth = Precision::Infinite();
183
184 // Not implemented
185 if(mylastseg==0)
186 return aDepth;
187
188 gp_XYZ aCDG;
189 // In case if mylastseg and mylastseg+1 are not valid
190 // the depth will be infinite
191 if (mylastseg < mypolyg.Size())
192 {
193 aCDG = mypolyg.Pnt(mylastseg);
194 if (mylastseg+1 < mypolyg.Size())
195 {
196 aCDG += mypolyg.Pnt(mylastseg+1);
197 aCDG /= 2.;
198 }
199 aDepth = ElCLib::Parameter(EyeLine,gp_Pnt(aCDG));
200 }
201
202 return aDepth;
7fd59977 203}
ac04d101
SA
204
205//=======================================================================
206//function : GetConnected
207//purpose :
208//=======================================================================
209
210Handle(Select3D_SensitiveEntity) Select3D_SensitiveCurve::GetConnected(const TopLoc_Location &theLocation)
211{
212 // Create a copy of this
213 Handle(Select3D_SensitiveEntity) aNewEntity;
214 // this was constructed using Handle(Geom_Curve)
215 if (!myCurve.IsNull())
216 {
217 aNewEntity = new Select3D_SensitiveCurve(myOwnerId, myCurve);
218 }
219 // this was constructed using TColgp_HArray1OfPnt
220 else
221 {
ceae62f0
A
222 Standard_Integer aSize = mypolyg.Size();
223 Handle(TColgp_HArray1OfPnt) aPoints = new TColgp_HArray1OfPnt(1, aSize);
ac04d101 224 // Fill the array with points from mypolyg3d
ceae62f0 225 for (Standard_Integer anIndex = 1; anIndex <= aSize; ++anIndex)
ac04d101 226 {
ceae62f0 227 aPoints->SetValue(anIndex, mypolyg.Pnt(anIndex-1));
ac04d101 228 }
ceae62f0 229 aNewEntity = new Select3D_SensitiveCurve(myOwnerId, aPoints);
ac04d101
SA
230 }
231
232 if (HasLocation())
233 aNewEntity->SetLocation(Location());
234
235 aNewEntity->UpdateLocation(theLocation);
236
237 return aNewEntity;
238}