0024070: OpenGL capped object-level clipping planes
[occt.git] / src / Select3D / Select3D_SensitiveTriangulation.cxx
CommitLineData
b311480e 1// Created on: 1997-05-15
2// Created by: Robert COUBLANC
3// Copyright (c) 1997-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//Modified Thur Apr 09 98 by rob : No more computation of free edges.
22// fix bug on Compute Depth (don't forget
23// Location...)
24
25#define BUC60858 //GG 27/03/01 Avoid to crash when selecting
26// a triangle containing confused or aligned points.
27
28#include <Select3D_SensitiveTriangulation.ixx>
29#include <gp_Pnt2d.hxx>
4bf18dff 30#include <Poly.hxx>
7fd59977 31#include <Poly_Connect.hxx>
32#include <CSLib_Class2d.hxx>
33#include <TColStd_Array1OfInteger.hxx>
34#include <Select3D_SensitiveTriangle.hxx>
35#include <Precision.hxx>
36#include <ElCLib.hxx>
37#include <CSLib_Class2d.hxx>
38
39
40static Standard_Integer S3D_NumberOfFreeEdges(const Handle(Poly_Triangulation)& Trg)
41{
42 Standard_Integer nFree = 0;
43 Poly_Connect pc(Trg);
44 Standard_Integer t[3];
45 Standard_Integer i,j;
46 for (i = 1; i <= Trg->NbTriangles(); i++) {
47 pc.Triangles(i,t[0],t[1],t[2]);
48 for (j = 0; j < 3; j++)
49 if (t[j] == 0) nFree++;
50 }
4bf18dff 51 return nFree;
7fd59977 52}
53static Standard_Boolean S3D_STriangul_NearSegment (const gp_XY& p0, const gp_XY& p1, const gp_XY& TheP,
54 const Standard_Real aTol, Standard_Real& aDMin)
55{
56 Bnd_Box2d B;
57 B.SetVoid();
58 B.Set(p0);
59 B.Update(p1.X(),p1.Y());
60 B.Enlarge(aTol*3);
61 if(B.IsOut(TheP)) return Standard_False;
62
63 gp_XY V01(p1);V01-=p0;
64 gp_XY Vec(TheP);Vec -= p0;
4bf18dff 65
7fd59977 66 Standard_Real u = Vec*V01.Normalized();
67 if(u<-aTol) return Standard_False;
68 Standard_Real u1 = u-aTol;
69 Standard_Real modmod = V01.SquareModulus();
70 if(u1*u1> modmod) return Standard_False;
71
72 gp_XY N01 (-V01.Y(),V01.X());
73 N01.Normalize();
74 aDMin = Abs (Vec * N01);
75 return aDMin <= aTol;
76}
77
78// static Standard_Real S3D_SquareDistanceFromEdge(gp_Pnt2d PCur,
79// gp_Pnt2d PEdg1,
80// gp_Pnt2d PEdg2,
81// const Standard_Real TolTol)
82// {
83// gp_XY VEdg (PEdg1.XY());
84// gp_XY VCur (PEdg1.XY());
85// VEdg-= PEdg2.XY();
86// VCur-=PCur.XY();
87// Standard_Real long1 = VEdg.SquareModulus();
4bf18dff 88
7fd59977 89// if(long1<=TolTol)
90// return VCur.SquareModulus();
91// Standard_Real Val = VEdg^VCur;
92// return Val*Val/long1;
4bf18dff 93
7fd59977 94// }
95
96static Standard_Boolean S3D_IsEdgeIn(const Standard_Integer e1,
ac04d101
SA
97 const Standard_Integer e2,
98 const Standard_Integer N1,
99 const Standard_Integer N2,
100 const Standard_Integer N3)
7fd59977 101{
102 Standard_Integer bid1 = (e1 == N1) ? N1 : ((e1 == N2) ? N2 : ( e1==N3 ? N3 : 0));
103 if(bid1==0) return Standard_False;
104 Standard_Integer bid2 = (e2 == N1) ? N1 : ((e2 == N2) ? N2 : ( e2==N3 ? N3 : 0));
105
106 if(bid2==0 || bid2 ==bid1) return Standard_False;
107 return Standard_True;
108}
109
7fd59977 110//=======================================================================
111//function : Select3D_SensitiveTriangulation
4bf18dff 112//purpose :
7fd59977 113//=======================================================================
114
115Select3D_SensitiveTriangulation::
aec37c15 116Select3D_SensitiveTriangulation(const Handle(SelectBasics_EntityOwner)& OwnerId,
117 const Handle(Poly_Triangulation)& Trg,
118 const TopLoc_Location& Loc,
119 const Standard_Boolean InteriorFlag):
ac04d101 120Select3D_SensitiveEntity(OwnerId),
7fd59977 121myTriangul(Trg),
122myiniloc(Loc),
123myIntFlag(InteriorFlag),
124myNodes2d(1,Trg->NbNodes()),
125myDetectedTr(-1)
126{
81bba717 127 // calculate free edges and cdg 3d of the triangulation:
128 // This code should have been integrated in poly_triangulation...
7fd59977 129
130 Standard_Integer fr = 1;
131 const Poly_Array1OfTriangle& triangles = myTriangul->Triangles();
4bf18dff 132 const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes();
7fd59977 133 Standard_Integer nbTriangles (myTriangul->NbTriangles());
134 gp_XYZ cdg(0,0,0);
135 Standard_Integer n[3];
aec37c15 136
81bba717 137 // to find connections in case when the border is not concerned...
aec37c15 138 if(!myIntFlag)
ac04d101 139 {
7fd59977 140 myFreeEdges = new TColStd_HArray1OfInteger(1,2*S3D_NumberOfFreeEdges(Trg));
141 TColStd_Array1OfInteger& FreeE = myFreeEdges->ChangeArray1();
142 Poly_Connect pc(myTriangul);
143 Standard_Integer t[3];
144 Standard_Integer i,j;
aec37c15 145 for ( i = 1; i <= nbTriangles; i++)
ac04d101 146 {
7fd59977 147 pc.Triangles(i,t[0],t[1],t[2]);
148 triangles(i).Get(n[0],n[1],n[2]);
149 cdg += (Nodes(n[0]).XYZ() + Nodes(n[1]).XYZ()+ Nodes(n[2]).XYZ())/3.;
aec37c15 150 for (j = 0; j < 3; j++)
ac04d101 151 {
aec37c15 152 Standard_Integer k = (j+1) % 3;
153 if (t[j] == 0)
ac04d101
SA
154 {
155 FreeE(fr) = n[j];
156 FreeE(fr+1)= n[k];
157 fr += 2;
158 }
7fd59977 159 }
160 }
161 }
162 else{
aec37c15 163 for (Standard_Integer i = 1; i <= nbTriangles; i++)
ac04d101 164 {
7fd59977 165 triangles(i).Get(n[0],n[1],n[2]);
166 cdg += (Nodes(n[0]).XYZ() + Nodes(n[1]).XYZ()+ Nodes(n[2]).XYZ())/3.;
167 }
168 }
169
7fd59977 170 if(nbTriangles!=0) cdg /= nbTriangles;
171 myCDG3D = gp_Pnt(cdg);
4bf18dff 172
7fd59977 173 ComputeTotalTrsf();
174
175 if(myTrsf.Form()!=gp_Identity)
176 myCDG3D.Transform(myTrsf);
177}
178
179
180//=======================================================================
181//function : Select3D_SensitiveTriangulation
4bf18dff 182//purpose :
7fd59977 183//=======================================================================
ac04d101 184
7fd59977 185Select3D_SensitiveTriangulation::
aec37c15 186Select3D_SensitiveTriangulation(const Handle(SelectBasics_EntityOwner)& OwnerId,
187 const Handle(Poly_Triangulation)& Trg,
188 const TopLoc_Location& Loc,
189 const Handle(TColStd_HArray1OfInteger)& FreeEdges,
190 const gp_Pnt& TheCDG,
ac04d101 191 const Standard_Boolean InteriorFlag):
7fd59977 192Select3D_SensitiveEntity(OwnerId),
193myTriangul(Trg),
194myiniloc(Loc),
195myCDG3D(TheCDG),
196myFreeEdges(FreeEdges),
197myIntFlag(InteriorFlag),
198myNodes2d(1,Trg->NbNodes()),
199myDetectedTr(-1)
200{
201}
ac04d101 202
7fd59977 203//=======================================================================
204//function : Project
4bf18dff 205//purpose :
7fd59977 206//=======================================================================
207
4bf18dff 208void Select3D_SensitiveTriangulation::Project(const Handle(Select3D_Projector)& aPrj)
7fd59977 209{
7fd59977 210 mybox2d.SetVoid();
4bf18dff 211 const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes();
212
7fd59977 213 gp_Pnt2d ProjPT;
4bf18dff 214
7fd59977 215 for(Standard_Integer I=1;I<=myTriangul->NbNodes();I++){
216 if(myTrsf.Form()!=gp_Identity)
4bf18dff 217 aPrj->Project(Nodes(I).Transformed(myTrsf),ProjPT);
7fd59977 218 else
4bf18dff 219 aPrj->Project(Nodes(I),ProjPT);
220
7fd59977 221 myNodes2d.SetValue(I,ProjPT);
222 mybox2d.Add(ProjPT);
223 }
4bf18dff 224
225 aPrj->Project(myCDG3D,myCDG2D);
7fd59977 226}
227
228//=======================================================================
229//function : Areas
4bf18dff 230//purpose :
7fd59977 231//=======================================================================
232
4bf18dff 233void Select3D_SensitiveTriangulation::Areas(SelectBasics_ListOfBox2d& boxes)
7fd59977 234{
235 boxes.Append(mybox2d);
236}
237
238//=======================================================================
7fd59977 239//function : Matches
4bf18dff 240//purpose :
7fd59977 241//=======================================================================
7fd59977 242
4269bd1b 243Standard_Boolean Select3D_SensitiveTriangulation::Matches (const SelectBasics_PickArgs& thePickArgs,
244 Standard_Real& theMatchDMin,
245 Standard_Real& theMatchDepth)
246{
247 theMatchDMin = Precision::Infinite();
248 gp_XY BidPoint (thePickArgs.X(), thePickArgs.Y());
7fd59977 249 myDetectedTr = -1;
250 const Poly_Array1OfTriangle& triangles = myTriangul->Triangles();
251
81bba717 252 // it is checked if we are inside the triangle 2d.
7fd59977 253 if(myIntFlag)
254 {
4269bd1b 255 gp_Lin aPickingLine = thePickArgs.PickLine();
256
257 if (myTrsf.Form() != gp_Identity)
258 {
259 aPickingLine.Transform (myTrsf.Inverted());
260 }
7fd59977 261
262 Standard_Real aMinDepth = Precision::Infinite();
4bf18dff 263 const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes();
7fd59977 264 for (Standard_Integer itr=1; itr<=myTriangul->NbTriangles(); itr++)
265 {
266 Standard_Integer n1,n2,n3;
267 triangles(itr).Get(n1,n2,n3);
268 const gp_XY& aPnt2d1 = myNodes2d(n1).XY();
269 const gp_XY& aPnt2d2 = myNodes2d(n2).XY();
270 const gp_XY& aPnt2d3 = myNodes2d(n3).XY();
4bf18dff 271 gp_XY aUV;
272 Standard_Real aDistSquare = Poly::PointOnTriangle (aPnt2d1, aPnt2d2, aPnt2d3, BidPoint, aUV);
4269bd1b 273 if (aDistSquare > thePickArgs.Tolerance() * thePickArgs.Tolerance())
7fd59977 274 continue;
275
4269bd1b 276 // get interpolated depth of the triangle nodes
277 Standard_Real aDepth1 = ElCLib::Parameter (aPickingLine, Nodes(n1));
278 Standard_Real aDepth2 = ElCLib::Parameter (aPickingLine, Nodes(n2));
279 Standard_Real aDepth3 = ElCLib::Parameter (aPickingLine, Nodes(n3));
4bf18dff 280 Standard_Real aDepth = aDepth1 + aUV.X() * (aDepth2 - aDepth1) +
7fd59977 281 aUV.Y() * (aDepth3 - aDepth1);
282
4269bd1b 283 // accept triangle with lowest depth and within defined depth interval
284 if (aDepth < aMinDepth && !thePickArgs.IsClipped(aDepth))
7fd59977 285 {
286 aMinDepth = aDepth;
287 myDetectedTr = itr;
4269bd1b 288 theMatchDMin = Sqrt (aDistSquare);
7fd59977 289 }
290 }
291 }
aec37c15 292
81bba717 293 // Case only Test on Border of the triangulation...
aec37c15 294 //
7fd59977 295 else
296 {
297 //Standard_Integer ifirst;
298 TColStd_Array1OfInteger& FreeE = myFreeEdges->ChangeArray1();
299 Standard_Integer nn = FreeE.Length(), Node1,Node2;
300 //Standard_Real LEdg;
301 //Standard_Real DMinDMin,TolTol = aTol*aTol;
4bf18dff 302
7fd59977 303 for (Standard_Integer ifri =1; ifri <= nn && myDetectedTr < 0; ifri+=2)
304 {
305 Node1 = FreeE(ifri);
306 Node2 = FreeE(ifri+1);
307 if (S3D_STriangul_NearSegment (myNodes2d(Node1).XY(),
308 myNodes2d(Node2).XY(),
4269bd1b 309 BidPoint, thePickArgs.Tolerance(), theMatchDMin))
7fd59977 310 {
4bf18dff 311 for(Standard_Integer itr=1; itr <= myTriangul->NbTriangles(); itr++)
7fd59977 312 {
313 Standard_Integer n1,n2,n3;
4bf18dff 314 triangles(itr).Get(n1,n2,n3);
315 if(S3D_IsEdgeIn(Node1,Node2,n1,n2,n3))
7fd59977 316 {
4bf18dff 317 myDetectedTr = itr;
7fd59977 318 break; // return first found; selection of closest is not implemented yet
319 }
4bf18dff 320 }
7fd59977 321 }
322 }
4bf18dff 323 }
7fd59977 324 if ( myDetectedTr <= 0 )
325 return Standard_False;
4bf18dff 326
4269bd1b 327 // get precise depth for the detected triangle
328 theMatchDepth = ComputeDepth (thePickArgs.PickLine(), myDetectedTr);
7fd59977 329
4269bd1b 330 // this test should not fail if the topmost triangle is taken from the
331 // first if-case block (for other cases this test make sense?)
332 return !thePickArgs.IsClipped (theMatchDepth);
333}
7fd59977 334
335//=======================================================================
336//function : Matches
4bf18dff 337//purpose :
7fd59977 338//=======================================================================
339
ac04d101
SA
340Standard_Boolean Select3D_SensitiveTriangulation::
341Matches(const Standard_Real XMin,
342 const Standard_Real YMin,
343 const Standard_Real XMax,
344 const Standard_Real YMax,
345 const Standard_Real aTol)
7fd59977 346{
347 Bnd_Box2d B;
348 B.Update(Min(XMin,XMax)-aTol,
ac04d101
SA
349 Min(YMin,YMax)-aTol,
350 Max(XMin,XMax)+aTol,
351 Max(YMin,YMax)+aTol);
4bf18dff 352
ac04d101
SA
353 for(Standard_Integer i=myNodes2d.Lower();i<=myNodes2d.Upper();i++)
354 {
7fd59977 355 if(B.IsOut(myNodes2d(i)))
356 return Standard_False;
357 }
358 return Standard_True;
359}
360
7fd59977 361//=======================================================================
362//function : Matches
4bf18dff 363//purpose :
7fd59977 364//=======================================================================
365
366Standard_Boolean Select3D_SensitiveTriangulation::
367Matches (const TColgp_Array1OfPnt2d& aPoly,
ac04d101
SA
368 const Bnd_Box2d& aBox,
369 const Standard_Real aTol)
4bf18dff 370{
7fd59977 371 Standard_Real Umin,Vmin,Umax,Vmax;
372 aBox.Get(Umin,Vmin,Umax,Vmax);
7fd59977 373 CSLib_Class2d aClassifier2d(aPoly,aTol,aTol,Umin,Vmin,Umax,Vmax);
374
ac04d101
SA
375 for(Standard_Integer j=1;j<=myNodes2d.Length();j++)
376 {
7fd59977 377 Standard_Integer RES = aClassifier2d.SiDans(myNodes2d(j));
378 if(RES!=1) return Standard_False;
379 }
380 return Standard_True;
381}
382
ac04d101
SA
383//=======================================================================
384//function : Status
385//purpose :
386//=======================================================================
7fd59977 387
ac04d101 388Standard_Integer Select3D_SensitiveTriangulation::
aec37c15 389Status (const gp_XY& TheP,
ac04d101
SA
390 const gp_XY& Proj0,
391 const gp_XY& Proj1,
392 const gp_XY& Proj2,
393 const Standard_Real aTol,
394 Standard_Real& DD) const
7fd59977 395{
396 return Select3D_SensitiveTriangle::Status(Proj0,Proj1,Proj2,TheP,aTol,DD);
397}
398
399//=======================================================================
400//function : IsFree
4bf18dff 401//purpose :
7fd59977 402//=======================================================================
403
404Standard_Boolean Select3D_SensitiveTriangulation::IsFree(const Standard_Integer IndexOfTriangle,
ac04d101 405 Standard_Integer& FoundIndex) const
7fd59977 406{
7fd59977 407 FoundIndex=-1;
408 Standard_Integer n[3];
409 const Poly_Array1OfTriangle& triangles = myTriangul->Triangles();
410 triangles(IndexOfTriangle).Get(n[0],n[1],n[2]);
ac04d101 411 TColStd_Array1OfInteger& FreeE = myFreeEdges->ChangeArray1();
4bf18dff 412
ac04d101
SA
413 for(Standard_Integer I=1;I<=FreeE.Length() && FoundIndex==-1;I+=2)
414 {
415 if(FreeE(I) == n[0])
416 {
aec37c15 417 if(FreeE(I+1)== n[1] || FreeE(I+1)== n[2])
ac04d101
SA
418 FoundIndex=I;
419 }
420 else if(FreeE(I) == n[1])
421 {
aec37c15 422 if(FreeE(I+1)== n[0] || FreeE(I+1)== n[2])
ac04d101
SA
423 FoundIndex=I;
424 }
425 else if(FreeE(I) == n[2])
426 {
aec37c15 427 if(FreeE(I+1)== n[0] || FreeE(I+1)== n[1])
ac04d101
SA
428 FoundIndex=I;
429 }
7fd59977 430 }
4bf18dff 431
7fd59977 432 return FoundIndex!=-1;
433}
434
435
436//=======================================================================
437//function : GetConnected
4bf18dff 438//purpose :
7fd59977 439//=======================================================================
ac04d101 440
7fd59977 441Handle(Select3D_SensitiveEntity) Select3D_SensitiveTriangulation::
442GetConnected(const TopLoc_Location& aLoc)
443{
4bf18dff 444 Handle(Select3D_SensitiveTriangulation) NiouEnt =
7fd59977 445 new Select3D_SensitiveTriangulation(myOwnerId,myTriangul,myiniloc,myFreeEdges,myCDG3D,myIntFlag);
4bf18dff 446
aec37c15 447 if(HasLocation())
ac04d101 448 NiouEnt->SetLocation(Location());
7fd59977 449// TopLoc_Location TheLocToApply = HasLocation() ? Location()*aLoc : aLoc;
450// if(!TheLocToApply.IsIdentity())
451 NiouEnt->UpdateLocation(aLoc);
4bf18dff 452
7fd59977 453 return NiouEnt;
454}
455
7fd59977 456//=======================================================================
457//function : ResetLocation
4bf18dff 458//purpose :
7fd59977 459//=======================================================================
ac04d101 460
4bf18dff 461void Select3D_SensitiveTriangulation::ResetLocation()
7fd59977 462{
463 Select3D_SensitiveEntity::ResetLocation();
464 ComputeTotalTrsf();
465}
ac04d101
SA
466
467//=======================================================================
468//function : SetLocation
469//purpose :
470//=======================================================================
471
7fd59977 472void Select3D_SensitiveTriangulation::SetLocation(const TopLoc_Location& aLoc)
473{
474 Select3D_SensitiveEntity::SetLocation(aLoc);
475 ComputeTotalTrsf();
476}
477
478
479//=======================================================================
480//function : Dump
4bf18dff 481//purpose :
7fd59977 482//=======================================================================
4bf18dff 483void Select3D_SensitiveTriangulation::Dump(Standard_OStream& S,const Standard_Boolean FullDump) const
7fd59977 484{
485 S<<"\tSensitiveTriangulation 3D :"<<endl;
486 if(myiniloc.IsIdentity())
487 S<<"\t\tNo Initial Location"<<endl;
488 else
489 S<<"\t\tExisting Initial Location"<<endl;
490 if(HasLocation())
491 S<<"\t\tExisting Location"<<endl;
4bf18dff 492
7fd59977 493 S<<"\t\tNb Triangles : "<<myTriangul->NbTriangles()<<endl;
494 S<<"\t\tNb Nodes : "<<myTriangul->NbNodes()<<endl;
495 S<<"\t\tNb Free Edges: "<<myFreeEdges->Length()/2<<endl;
496
aec37c15 497 if(FullDump)
ac04d101 498 {
7fd59977 499// S<<"\t\t\tOwner:"<<myOwnerId<<endl;
500 Select3D_SensitiveEntity::DumpBox(S,mybox2d);
501 }
502}
503
504//=======================================================================
505//function : ComputeDepth
4bf18dff 506//purpose :
7fd59977 507//=======================================================================
ac04d101 508
4269bd1b 509Standard_Real Select3D_SensitiveTriangulation::ComputeDepth(const gp_Lin& thePickLine,
510 const Standard_Integer theTriangle) const
7fd59977 511{
4269bd1b 512 if (theTriangle == -1)
513 {
514 return Precision::Infinite(); // currently not implemented...
515 }
516
7fd59977 517 const Poly_Array1OfTriangle& triangles = myTriangul->Triangles();
4bf18dff 518 const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes();
519
7fd59977 520 Standard_Integer n1,n2,n3;
4269bd1b 521 triangles (theTriangle).Get (n1,n2,n3);
7fd59977 522 gp_Pnt P[3]={Nodes(n1),Nodes(n2),Nodes(n3)};
523
4269bd1b 524 if (myTrsf.Form() != gp_Identity)
ac04d101 525 {
4269bd1b 526 for (Standard_Integer i =0; i<=2; i++)
ac04d101 527 {
4269bd1b 528 P[i].Transform (myTrsf);
7fd59977 529 }
530 }
aec37c15 531
81bba717 532 // formula calculate the parameter of the point on the intersection
7fd59977 533 // t = (P1P2 ^P1P3)* OP1 / ((P1P2^P1P3)*Dir)
4269bd1b 534 Standard_Real prof (Precision::Infinite());
535 gp_Pnt Oye = thePickLine.Location(); // origin of the target line eye/point...
536 gp_Dir Dir = thePickLine.Direction();
7fd59977 537
4bf18dff 538 gp_Vec Vtr[3];
4269bd1b 539 for (Standard_Integer i=0; i<=2; i++)
540 {
541 Vtr[i] = gp_Vec (P[i%3], P[(i+1)%3]);
542 }
543
7fd59977 544 Vtr[2] = -Vtr[2];
aec37c15 545
81bba717 546 // remove singular cases immediately...
4269bd1b 547 Standard_Integer SingularCase (-1);
548 if (Vtr[0].SquareMagnitude() <= Precision::Confusion())
549 {
7fd59977 550 SingularCase = 0;
4269bd1b 551 }
552
553 if (Vtr[1].SquareMagnitude() <= Precision::Confusion())
554 {
7fd59977 555 SingularCase = (SingularCase == -1) ? 1 : 2;
4269bd1b 556 }
557
7fd59977 558#ifdef BUC60858
4269bd1b 559 if (Vtr[2].SquareMagnitude() <= Precision::Confusion())
560 {
7fd59977 561 if( SingularCase < 0 ) SingularCase = 1;
4269bd1b 562 }
7fd59977 563#endif
aec37c15 564
81bba717 565 // 3 pts mixed...
4269bd1b 566 if (SingularCase ==2)
ac04d101 567 {
4269bd1b 568 prof = ElCLib::Parameter (thePickLine, P[0]);
7fd59977 569 return prof;
570 }
4bf18dff 571
4269bd1b 572 if (SingularCase!=0)
573 {
7fd59977 574 Vtr[0].Normalize();
4269bd1b 575 }
576
577 if (SingularCase!=1 && SingularCase!=2)
578 {
7fd59977 579 Vtr[2].Normalize();
4269bd1b 580 }
581
582 gp_Vec OPo (Oye, P[0]);
583
81bba717 584 // 2 points mixed... the intersection between the segment and the target line eye/point.
4269bd1b 585 if (SingularCase!=-1)
ac04d101 586 {
7fd59977 587 gp_Vec V = SingularCase==0 ? Vtr[2] : Vtr[0];
588 gp_Vec Det = Dir^V;
589 gp_Vec VSM = OPo^V;
4269bd1b 590
591 if (Det.X() > Precision::Confusion())
592 {
593 prof = VSM.X() / Det.X();
594 }
595 else if (Det.Y() > Precision::Confusion())
596 {
597 prof = VSM.Y() / Det.Y();
598 }
599 else if (Det.Z() > Precision::Confusion())
600 {
601 prof = VSM.Z() / Det.Z();
602 }
7fd59977 603 }
aec37c15 604 else
ac04d101 605 {
4269bd1b 606 Standard_Real val1 = OPo.DotCross (Vtr[0], Vtr[2]);
607 Standard_Real val2 = Dir.DotCross (Vtr[0], Vtr[2]);
4bf18dff 608
4269bd1b 609 if (Abs (val2) > Precision::Confusion())
610 {
611 prof = val1 / val2;
612 }
4bf18dff 613 }
4269bd1b 614
615 if (prof == Precision::Infinite())
ac04d101 616 {
4269bd1b 617 prof= ElCLib::Parameter (thePickLine, P[0]);
618 prof = Min (prof, ElCLib::Parameter (thePickLine, P[1]));
619 prof = Min (prof, ElCLib::Parameter (thePickLine, P[2]));
7fd59977 620 }
4bf18dff 621
7fd59977 622 return prof;
623}
624
625//=======================================================================
626//function : DetectedTriangle
4bf18dff 627//purpose :
7fd59977 628//=======================================================================
ac04d101
SA
629
630Standard_Boolean Select3D_SensitiveTriangulation::
aec37c15 631DetectedTriangle(gp_Pnt& P1,
632 gp_Pnt& P2,
ac04d101 633 gp_Pnt& P3) const
7fd59977 634{
81bba717 635 if(myDetectedTr==-1) return Standard_False; // currently not implemented...
7fd59977 636 const Poly_Array1OfTriangle& triangles = myTriangul->Triangles();
4bf18dff 637 const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes();
7fd59977 638 Standard_Integer n1,n2,n3;
639 triangles(myDetectedTr).Get(n1,n2,n3);
4bf18dff 640
7fd59977 641 P1 = Nodes(n1);
642 P2 = Nodes(n2);
643 P3 = Nodes(n3);
aec37c15 644 if(myTrsf.Form()!=gp_Identity)
ac04d101 645 {
7fd59977 646 P1.Transform(myTrsf);
647 P2.Transform(myTrsf);
648 P3.Transform(myTrsf);
649 }
4bf18dff 650
7fd59977 651 return Standard_True;
652}
653
654//=============================================================================
655// Function : DetectedTriangle2d
4bf18dff 656// Purpose :
7fd59977 657//=============================================================================
ac04d101
SA
658
659Standard_Boolean Select3D_SensitiveTriangulation::
aec37c15 660DetectedTriangle2d(gp_Pnt2d& P1,
661 gp_Pnt2d& P2,
ac04d101 662 gp_Pnt2d& P3) const
7fd59977 663{
aec37c15 664 if(myDetectedTr==-1)
81bba717 665 return Standard_False; // currently not implemented...
7fd59977 666 const Poly_Array1OfTriangle& triangles = myTriangul->Triangles();
7fd59977 667 Standard_Integer n1,n2,n3;
668 triangles( myDetectedTr ).Get(n1,n2,n3);
669
670 int aLower = myNodes2d.Lower();
671 int anUpper = myNodes2d.Upper();
4bf18dff 672 if ( n1 >= aLower && n1 <= anUpper &&
7fd59977 673 n2 >= aLower && n2 <= anUpper &&
674 n3 >= aLower && n3 <= anUpper )
675 {
676 P1 = myNodes2d.Value( n1 );
677 P2 = myNodes2d.Value( n2 );
678 P3 = myNodes2d.Value( n3 );
679 return Standard_True;
680 }
4bf18dff 681 else
7fd59977 682 return Standard_False;
7fd59977 683}
684
ac04d101
SA
685//=============================================================================
686// Function : ComputeTotalTrsf
687// Purpose :
688//=============================================================================
689
4bf18dff 690void Select3D_SensitiveTriangulation::ComputeTotalTrsf()
7fd59977 691{
692 Standard_Boolean hasloc = (HasLocation() || !myiniloc.IsIdentity());
4bf18dff 693
ac04d101
SA
694 if(hasloc)
695 {
7fd59977 696 if(myiniloc.IsIdentity())
697 myTrsf = Location().Transformation();
aec37c15 698 else if(HasLocation())
ac04d101 699 {
7fd59977 700 myTrsf = (Location()*myiniloc).Transformation();
701 }
702 else
703 myTrsf = myiniloc.Transformation();
704 }
aec37c15 705 else
ac04d101 706 {
7fd59977 707 gp_Trsf TheId;
708 myTrsf = TheId;
709 }
710}