Commit | Line | Data |
---|---|---|
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 | ||
40 | static 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 | } |
53 | static 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 | ||
96 | static 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 | ||
115 | Select3D_SensitiveTriangulation:: | |
aec37c15 | 116 | Select3D_SensitiveTriangulation(const Handle(SelectBasics_EntityOwner)& OwnerId, |
117 | const Handle(Poly_Triangulation)& Trg, | |
118 | const TopLoc_Location& Loc, | |
119 | const Standard_Boolean InteriorFlag): | |
ac04d101 | 120 | Select3D_SensitiveEntity(OwnerId), |
7fd59977 | 121 | myTriangul(Trg), |
122 | myiniloc(Loc), | |
123 | myIntFlag(InteriorFlag), | |
124 | myNodes2d(1,Trg->NbNodes()), | |
125 | myDetectedTr(-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 | 185 | Select3D_SensitiveTriangulation:: |
aec37c15 | 186 | Select3D_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 | 192 | Select3D_SensitiveEntity(OwnerId), |
193 | myTriangul(Trg), | |
194 | myiniloc(Loc), | |
195 | myCDG3D(TheCDG), | |
196 | myFreeEdges(FreeEdges), | |
197 | myIntFlag(InteriorFlag), | |
198 | myNodes2d(1,Trg->NbNodes()), | |
199 | myDetectedTr(-1) | |
200 | { | |
201 | } | |
ac04d101 | 202 | |
7fd59977 | 203 | //======================================================================= |
204 | //function : Project | |
4bf18dff | 205 | //purpose : |
7fd59977 | 206 | //======================================================================= |
207 | ||
4bf18dff | 208 | void 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 | 233 | void Select3D_SensitiveTriangulation::Areas(SelectBasics_ListOfBox2d& boxes) |
7fd59977 | 234 | { |
235 | boxes.Append(mybox2d); | |
236 | } | |
237 | ||
7fd59977 | 238 | //======================================================================= |
239 | //function : Matches | |
4bf18dff | 240 | //purpose : |
7fd59977 | 241 | //======================================================================= |
7fd59977 | 242 | |
4269bd1b | 243 | Standard_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 |
340 | Standard_Boolean Select3D_SensitiveTriangulation:: |
341 | Matches(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 | ||
366 | Standard_Boolean Select3D_SensitiveTriangulation:: | |
367 | Matches (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 | 388 | Standard_Integer Select3D_SensitiveTriangulation:: |
aec37c15 | 389 | Status (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 | ||
404 | Standard_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 | 441 | Handle(Select3D_SensitiveEntity) Select3D_SensitiveTriangulation:: |
442 | GetConnected(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 | 461 | void Select3D_SensitiveTriangulation::ResetLocation() |
7fd59977 | 462 | { |
463 | Select3D_SensitiveEntity::ResetLocation(); | |
464 | ComputeTotalTrsf(); | |
465 | } | |
ac04d101 SA |
466 | |
467 | //======================================================================= | |
468 | //function : SetLocation | |
469 | //purpose : | |
470 | //======================================================================= | |
471 | ||
7fd59977 | 472 | void 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 | 483 | void 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 | 509 | Standard_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 | |
630 | Standard_Boolean Select3D_SensitiveTriangulation:: | |
aec37c15 | 631 | DetectedTriangle(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 | |
659 | Standard_Boolean Select3D_SensitiveTriangulation:: | |
aec37c15 | 660 | DetectedTriangle2d(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 | 690 | void 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 | } |