0024070: OpenGL capped object-level clipping planes
[occt.git] / src / Select3D / Select3D_SensitiveSegment.cxx
CommitLineData
b311480e 1// Created on: 1995-01-25
2// Created by: Mister rmi
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
22
23#include <Select3D_SensitiveSegment.ixx>
24#include <SelectBasics_BasicTool.hxx>
25#include <gp_Vec.hxx>
26#include <gp_Vec2d.hxx>
27#include <Bnd_Box2d.hxx>
28#include <gp_Pnt2d.hxx>
29#include <gp_Dir2d.hxx>
30#include <gp_Lin2d.hxx>
31#include <ElCLib.hxx>
32#include <Extrema_ExtElC.hxx>
33#include <Extrema_POnCurv.hxx>
34#include <TColgp_Array1OfPnt2d.hxx>
35#include <Precision.hxx>
36#include <SelectBasics_ListIteratorOfListOfBox2d.hxx>
37
38#include <CSLib_Class2d.hxx>
39
40//=====================================================
41// Function : Create
42// Purpose :Constructor
43//=====================================================
44
7fd59977 45Select3D_SensitiveSegment::
aec37c15 46Select3D_SensitiveSegment(const Handle(SelectBasics_EntityOwner)& OwnerId,
ac04d101
SA
47 const gp_Pnt& FirstP,
48 const gp_Pnt& LastP,
49 const Standard_Integer MaxRect):
7fd59977 50Select3D_SensitiveEntity(OwnerId),
51mymaxrect(MaxRect)
52{
53 mystart = FirstP;
54 myend = LastP;
55}
56
57//=====================================================
58// Function :
59// Purpose :
60//=====================================================
ac04d101 61
7fd59977 62void Select3D_SensitiveSegment
4952a30a 63::Project(const Handle(Select3D_Projector)& aProj)
7fd59977 64{
7fd59977 65 gp_Pnt2d aPoint2dStart;
66 gp_Pnt2d aPoint2dEnd;
aec37c15 67
68 if(HasLocation())
ac04d101 69 {
7fd59977 70 gp_Pnt aStart(mystart.x, mystart.y, mystart.z);
71 gp_Pnt aEnd(myend.x, myend.y, myend.z);
4952a30a 72 aProj->Project(aStart.Transformed(Location().Transformation()),aPoint2dStart);
73 aProj->Project(aEnd.Transformed(Location().Transformation()),aPoint2dEnd);
7fd59977 74 }
aec37c15 75 else
ac04d101 76 {
4952a30a 77 aProj->Project(mystart,aPoint2dStart);
78 aProj->Project(myend,aPoint2dEnd);
7fd59977 79 }
80 myprojstart = aPoint2dStart;
81 myprojend = aPoint2dEnd;
82}
83
84//=====================================================
aec37c15 85// Function : Areas
7fd59977 86// Purpose :
87//=====================================================
ac04d101 88
7fd59977 89void Select3D_SensitiveSegment
90::Areas(SelectBasics_ListOfBox2d& theareas)
91{
92// gp_Dir2d dy (0.,1.);
93 gp_Pnt2d aPStart(myprojstart.x,myprojstart.y);
aec37c15 94 if(aPStart.Distance(myprojend)<=Precision::Confusion())
ac04d101 95 {
7fd59977 96 Bnd_Box2d curbox;
97 curbox.Set(myprojstart);
98 theareas.Append(curbox);
ac04d101 99 }
aec37c15 100 else
ac04d101 101 {
7fd59977 102 gp_Vec2d MyVec(myprojstart,myprojend);//,VAxx(gp_Dir2d(0.,1.));
103 Standard_Real theangle = Abs(gp_Dir2d(0.,1.).Angle(gp_Vec2d(myprojstart,myprojend)));
c6541a0c
D
104 if(theangle>=M_PI/2.) theangle-=M_PI/2;
105 if(theangle>=M_PI/12. && theangle <=5*M_PI/12.)
aec37c15 106 {
107 TColgp_Array1OfPnt2d BoxPoint (1,mymaxrect+1);
ac04d101 108 BoxPoint (1) = myprojstart;
aec37c15 109 BoxPoint(mymaxrect+1)=myprojend;
ac04d101 110 gp_Vec2d Vtr = MyVec/mymaxrect;
aec37c15 111 Standard_Integer i;
112 for ( i=2;i<=mymaxrect;i++)
113 {
114 BoxPoint (i) = BoxPoint (i-1).Translated(Vtr);
115 }
116 for (i=2;i<=mymaxrect+1;i++)
117 {
ac04d101
SA
118 Bnd_Box2d curbox;
119 curbox.Set(BoxPoint(i-1));
120 curbox.Add(BoxPoint(i));
121 theareas.Append(curbox);
122 }
7fd59977 123 }
124 else
aec37c15 125 {
126 Bnd_Box2d curbox;
127 curbox.Set(myprojstart);
128 curbox.Add(myprojend);
ac04d101 129 theareas.Append(curbox);
7fd59977 130 }
131 }
132}
133
134//=====================================================
135// Function : Matches
136// Purpose :
137//=====================================================
ac04d101 138
4269bd1b 139Standard_Boolean Select3D_SensitiveSegment::Matches (const SelectBasics_PickArgs& thePickArgs,
140 Standard_Real& theMatchDMin,
141 Standard_Real& theMatchDepth)
7fd59977 142{
4269bd1b 143 gp_Pnt2d aPStart (myprojstart.x,myprojstart.y);
144 gp_Pnt2d aPEnd (myprojend.x,myprojend.y);
145 if (!SelectBasics_BasicTool::MatchSegment (aPStart, aPEnd,
146 thePickArgs.X(),
147 thePickArgs.Y(),
148 thePickArgs.Tolerance(),
149 theMatchDMin))
150 {
7fd59977 151 return Standard_False;
4269bd1b 152 }
153
154 theMatchDepth = ComputeDepth (thePickArgs.PickLine());
155
156 return !thePickArgs.IsClipped (theMatchDepth);
7fd59977 157}
158
ac04d101
SA
159//=====================================================
160// Function : Matches
161// Purpose :
162//=====================================================
163
7fd59977 164Standard_Boolean Select3D_SensitiveSegment::
165Matches (const Standard_Real XMin,
ac04d101
SA
166 const Standard_Real YMin,
167 const Standard_Real XMax,
168 const Standard_Real YMax,
169 const Standard_Real aTol)
7fd59977 170{
171 Bnd_Box2d BoundBox;
172 BoundBox.Update(XMin-aTol,YMin-aTol,XMax+aTol,YMax+aTol);
173 if(BoundBox.IsOut(myprojstart)) return Standard_False;
174 if( BoundBox.IsOut(myprojend)) return Standard_False;
175 return Standard_True;
176}
177
7fd59977 178//=======================================================================
179//function : Matches
aec37c15 180//purpose :
7fd59977 181//=======================================================================
182
183Standard_Boolean Select3D_SensitiveSegment::
184Matches (const TColgp_Array1OfPnt2d& aPoly,
ac04d101
SA
185 const Bnd_Box2d& aBox,
186 const Standard_Real aTol)
aec37c15 187{
7fd59977 188 Standard_Real Umin,Vmin,Umax,Vmax;
189 aBox.Get(Umin,Vmin,Umax,Vmax);
7fd59977 190 CSLib_Class2d aClassifier2d(aPoly,aTol,aTol,Umin,Vmin,Umax,Vmax);
191
192 Standard_Integer RES = aClassifier2d.SiDans(myprojstart);
193 if (RES!=1) return Standard_False;
194
195 RES = aClassifier2d.SiDans(myprojend);
196 if (RES!=1) return Standard_False;
197
198 return Standard_True;
199}
200
201
202//=======================================================================
203//function : GetConnected
aec37c15 204//purpose :
7fd59977 205//=======================================================================
ac04d101
SA
206
207Handle(Select3D_SensitiveEntity) Select3D_SensitiveSegment::
aec37c15 208GetConnected(const TopLoc_Location& aLoc)
7fd59977 209{
aec37c15 210 Handle(Select3D_SensitiveSegment) NiouEnt =
ac04d101
SA
211 new Select3D_SensitiveSegment(myOwnerId,mystart,myend,mymaxrect);
212
7fd59977 213 if(HasLocation()) NiouEnt->SetLocation(Location());
214 NiouEnt->UpdateLocation(aLoc);
215 return NiouEnt;
216}
217
218//=======================================================================
219//function : Dump
aec37c15 220//purpose :
7fd59977 221//=======================================================================
222
35e08fe8 223void Select3D_SensitiveSegment::Dump(Standard_OStream& S,const Standard_Boolean /*FullDump*/) const
7fd59977 224{
225 S<<"\tSensitivePoint 3D :"<<endl;
226 if(HasLocation())
227 S<<"\t\tExisting Location"<<endl;
228 S<<"\t\t P1 [ "<<mystart.x<<" , "<<mystart.y <<" , "<<mystart.z <<" ]"<<endl;
229 S<<"\t\t P2 [ "<<myend.x<<" , "<<myend.y <<" , "<<myend.z <<" ]"<<endl;
230 S<<"\t\t maxrect ="<<mymaxrect<<endl;
aec37c15 231
7fd59977 232}
233//=======================================================================
234//function : ComputeDepth
aec37c15 235//purpose :
7fd59977 236//=======================================================================
237
238Standard_Real Select3D_SensitiveSegment::ComputeDepth(const gp_Lin& EyeLine) const
239{
240 gp_Pnt aP0 = mystart;
241 gp_Pnt aP1 = myend;
242
243 // if segment is degenerated (zero length), just use depth of the end
244 gp_XYZ aV = aP1.XYZ() - aP0.XYZ();
245 Standard_Real aNorm = aV.Modulus();
246 if ( aNorm <= gp::Resolution() )
247 return ElCLib::Parameter (EyeLine, aP0);
248
249 // else compute point on segment closest to the line
250 gp_Lin aLine (aP0, aV);
251 Extrema_ExtElC aTool (aLine, EyeLine, Precision::Angular());
252 if ( aTool.IsDone() && ! aTool.IsParallel() )
253 {
254 for (Standard_Integer i=1; i <= aTool.NbExt(); i++)
255 {
256 Extrema_POnCurv POL1, POL2;
257 aTool.Points (i, POL1, POL2);
258 // use point found by extrema only if it is inside segment
259 if ( POL1.Parameter() > 0. && POL1.Parameter() < aNorm )
260 return ElCLib::Parameter (EyeLine, POL1.Value());
261 }
262 }
263
264 // if extrema failed or lines are parallel, return closest of the segment ends
265 return Min (ElCLib::Parameter (EyeLine, aP0),
266 ElCLib::Parameter (EyeLine, aP1));
267}