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