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