0024070: OpenGL capped object-level clipping planes
[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::Matches (const SelectBasics_PickArgs& thePickArgs,
80                                                    Standard_Real& theMatchDMin,
81                                                    Standard_Real& theMatchDepth)
82 {
83   Standard_Integer Rank;
84   TColgp_Array1OfPnt2d aArrayOf2dPnt(1, mypolyg.Size());
85   Points2D(aArrayOf2dPnt);
86   if (SelectBasics_BasicTool::MatchPolyg2d (aArrayOf2dPnt,
87                                             thePickArgs.X(), thePickArgs.Y(),
88                                             thePickArgs.Tolerance(),
89                                             theMatchDMin,
90                                             Rank))
91   {
92     // remember detected segment (for GetLastDetected)
93     mylastseg = Rank;
94
95     theMatchDepth = ComputeDepth (thePickArgs.PickLine(), Rank);
96
97     return !thePickArgs.IsClipped (theMatchDepth);
98   }
99
100   return Standard_False;
101 }
102
103 //==================================================
104 // Function: Matches
105 // Purpose : know if a box touches the projected polygon
106 //           of the Curve.
107 //==================================================
108
109 Standard_Boolean Select3D_SensitiveCurve::
110 Matches (const Standard_Real XMin,
111          const Standard_Real YMin,
112          const Standard_Real XMax,
113          const Standard_Real YMax,
114          const Standard_Real aTol)
115 {
116   Bnd_Box2d BoundBox;
117   BoundBox.Update(XMin-aTol,YMin-aTol,XMax+aTol,YMax+aTol);
118
119   for(Standard_Integer anIndex=0; anIndex<mypolyg.Size(); ++anIndex)
120     {
121       if(BoundBox.IsOut(mypolyg.Pnt2d(anIndex)))
122         return Standard_False;
123     }
124   return Standard_True;
125 }
126
127 //=======================================================================
128 //function : Matches
129 //purpose  :
130 //=======================================================================
131
132 Standard_Boolean Select3D_SensitiveCurve::
133 Matches (const TColgp_Array1OfPnt2d& aPoly,
134          const Bnd_Box2d& aBox,
135          const Standard_Real aTol)
136 {
137   Standard_Real Umin,Vmin,Umax,Vmax;
138   aBox.Get(Umin,Vmin,Umax,Vmax);
139   CSLib_Class2d aClassifier2d(aPoly,aTol,aTol,Umin,Vmin,Umax,Vmax);
140
141   for(Standard_Integer anIndex=0;anIndex<mypolyg.Size();++anIndex)
142   {
143     Standard_Integer RES = aClassifier2d.SiDans(mypolyg.Pnt2d(anIndex));
144     if(RES!=1)
145       return Standard_False;
146   }
147   return Standard_True;
148 }
149
150 //==================================================
151 // Function: LoadPoints
152 // Purpose :
153 //==================================================
154
155 void Select3D_SensitiveCurve
156 ::LoadPoints (const Handle(Geom_Curve)& aCurve,const Standard_Integer NbP)
157 {
158   /*this method is private and it used only inside of constructor.
159     That's why check !NbP==mypolyg3d->Length() was removed*/
160
161   Standard_Real Step = (aCurve->LastParameter()- aCurve->FirstParameter())/(NbP-1);
162   Standard_Real Curparam = aCurve->FirstParameter();
163   for(Standard_Integer anIndex=0;anIndex<mypolyg.Size();++anIndex)
164   {
165     mypolyg.SetPnt(anIndex, aCurve->Value(Curparam));
166     Curparam+=Step;
167   }
168 }
169
170 //=======================================================================
171 //function : Dump
172 //purpose  :
173 //=======================================================================
174
175 void Select3D_SensitiveCurve::Dump(Standard_OStream& S,const Standard_Boolean FullDump) const
176 {
177   S<<"\tSensitiveCurve 3D :"<<endl;
178   if (HasLocation())
179     S<<"\t\tExisting Location"<<endl;
180
181   S<<"\t\tNumber Of Points :"<<mypolyg.Size()<<endl;
182
183   if(FullDump)
184   {
185     Select3D_SensitiveEntity::DumpBox(S,mybox2d);
186   }
187 }
188
189 //=======================================================================
190 //function : ComputeDepth
191 //purpose  :
192 //=======================================================================
193
194 Standard_Real Select3D_SensitiveCurve::ComputeDepth (const gp_Lin& thePickLine,
195                                                      const Standard_Integer theSegment) const
196 {
197   if (theSegment == 0)
198   {
199     return Precision::Infinite();
200   }
201
202   // In case if theSegment and theSegment + 1 are not valid
203   // the depth will be infinite
204   if (theSegment >= mypolyg.Size())
205   {
206     return Precision::Infinite();
207   }
208
209   gp_XYZ aCDG = mypolyg.Pnt (theSegment);
210
211   if (theSegment + 1 < mypolyg.Size())
212   {
213     aCDG += mypolyg.Pnt(theSegment + 1);
214     aCDG /= 2.;
215   }
216
217   return ElCLib::Parameter (thePickLine, gp_Pnt (aCDG));
218 }
219
220 //=======================================================================
221 //function : GetConnected
222 //purpose  :
223 //=======================================================================
224
225 Handle(Select3D_SensitiveEntity) Select3D_SensitiveCurve::GetConnected(const TopLoc_Location &theLocation)
226 {
227   // Create a copy of this
228   Handle(Select3D_SensitiveEntity) aNewEntity;
229   // this was constructed using Handle(Geom_Curve)
230   if (!myCurve.IsNull())
231   {
232     aNewEntity = new Select3D_SensitiveCurve(myOwnerId, myCurve);
233   }
234   // this was constructed using TColgp_HArray1OfPnt
235   else
236   {
237     Standard_Integer aSize = mypolyg.Size();
238     Handle(TColgp_HArray1OfPnt) aPoints = new TColgp_HArray1OfPnt(1, aSize);
239     // Fill the array with points from mypolyg3d
240     for (Standard_Integer anIndex = 1; anIndex <= aSize; ++anIndex)
241     {
242       aPoints->SetValue(anIndex, mypolyg.Pnt(anIndex-1));
243     }
244      aNewEntity = new Select3D_SensitiveCurve(myOwnerId, aPoints);
245   }
246
247   if (HasLocation())
248     aNewEntity->SetLocation(Location());
249
250   aNewEntity->UpdateLocation(theLocation);
251
252   return aNewEntity;
253 }