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:: | |
ac04d101 SA |
116 | Select3D_SensitiveTriangulation(const Handle(SelectBasics_EntityOwner)& OwnerId, |
117 | const Handle(Poly_Triangulation)& Trg, | |
118 | const TopLoc_Location& Loc, | |
119 | const Standard_Boolean InteriorFlag): | |
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]; | |
81bba717 | 136 | |
137 | // to find connections in case when the border is not concerned... | |
ac04d101 SA |
138 | if(!myIntFlag) |
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; | |
ac04d101 SA |
145 | for ( i = 1; i <= nbTriangles; i++) |
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.; | |
ac04d101 SA |
150 | for (j = 0; j < 3; j++) |
151 | { | |
152 | Standard_Integer k = (j+1) % 3; | |
153 | if (t[j] == 0) | |
154 | { | |
155 | FreeE(fr) = n[j]; | |
156 | FreeE(fr+1)= n[k]; | |
157 | fr += 2; | |
158 | } | |
7fd59977 | 159 | } |
160 | } | |
161 | } | |
162 | else{ | |
ac04d101 SA |
163 | for (Standard_Integer i = 1; i <= nbTriangles; i++) |
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:: |
ac04d101 SA |
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, | |
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 | { |
210 | Select3D_SensitiveEntity::Project(aPrj); // to set the field last proj... | |
4bf18dff | 211 | |
7fd59977 | 212 | mybox2d.SetVoid(); |
4bf18dff | 213 | const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes(); |
214 | ||
7fd59977 | 215 | gp_Pnt2d ProjPT; |
4bf18dff | 216 | |
7fd59977 | 217 | for(Standard_Integer I=1;I<=myTriangul->NbNodes();I++){ |
218 | if(myTrsf.Form()!=gp_Identity) | |
4bf18dff | 219 | aPrj->Project(Nodes(I).Transformed(myTrsf),ProjPT); |
7fd59977 | 220 | else |
4bf18dff | 221 | aPrj->Project(Nodes(I),ProjPT); |
222 | ||
7fd59977 | 223 | myNodes2d.SetValue(I,ProjPT); |
224 | mybox2d.Add(ProjPT); | |
225 | } | |
4bf18dff | 226 | |
227 | aPrj->Project(myCDG3D,myCDG2D); | |
7fd59977 | 228 | } |
229 | ||
230 | //======================================================================= | |
231 | //function : Areas | |
4bf18dff | 232 | //purpose : |
7fd59977 | 233 | //======================================================================= |
234 | ||
4bf18dff | 235 | void Select3D_SensitiveTriangulation::Areas(SelectBasics_ListOfBox2d& boxes) |
7fd59977 | 236 | { |
237 | boxes.Append(mybox2d); | |
238 | } | |
239 | ||
7fd59977 | 240 | //======================================================================= |
241 | //function : Matches | |
4bf18dff | 242 | //purpose : |
7fd59977 | 243 | //======================================================================= |
ac04d101 SA |
244 | Standard_Boolean Select3D_SensitiveTriangulation:: |
245 | Matches(const Standard_Real X, | |
246 | const Standard_Real Y, | |
247 | const Standard_Real aTol, | |
248 | Standard_Real& DMin) | |
7fd59977 | 249 | { |
250 | // get view direction (necessary for calculation of depth) from field mylastprj of the base class | |
4bf18dff | 251 | if (mylastprj.IsNull()) |
7fd59977 | 252 | return Standard_False; |
253 | ||
254 | DMin = Precision::Infinite(); | |
255 | gp_XY BidPoint(X,Y); | |
256 | myDetectedTr = -1; | |
257 | const Poly_Array1OfTriangle& triangles = myTriangul->Triangles(); | |
258 | ||
81bba717 | 259 | // it is checked if we are inside the triangle 2d. |
7fd59977 | 260 | if(myIntFlag) |
261 | { | |
4bf18dff | 262 | gp_Lin EyeLine = mylastprj->Shoot(X,Y); |
7fd59977 | 263 | if ( myTrsf.Form()!=gp_Identity ) |
264 | EyeLine.Transform (myTrsf.Inverted()); | |
265 | ||
266 | Standard_Real aMinDepth = Precision::Infinite(); | |
4bf18dff | 267 | const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes(); |
7fd59977 | 268 | for (Standard_Integer itr=1; itr<=myTriangul->NbTriangles(); itr++) |
269 | { | |
270 | Standard_Integer n1,n2,n3; | |
271 | triangles(itr).Get(n1,n2,n3); | |
272 | const gp_XY& aPnt2d1 = myNodes2d(n1).XY(); | |
273 | const gp_XY& aPnt2d2 = myNodes2d(n2).XY(); | |
274 | const gp_XY& aPnt2d3 = myNodes2d(n3).XY(); | |
4bf18dff | 275 | gp_XY aUV; |
276 | Standard_Real aDistSquare = Poly::PointOnTriangle (aPnt2d1, aPnt2d2, aPnt2d3, BidPoint, aUV); | |
277 | if ( aDistSquare > aTol * aTol ) | |
7fd59977 | 278 | continue; |
279 | ||
280 | // compute depth on this triangle | |
7fd59977 | 281 | Standard_Real aDepth1 = ElCLib::Parameter (EyeLine, Nodes(n1)); |
282 | Standard_Real aDepth2 = ElCLib::Parameter (EyeLine, Nodes(n2)); | |
283 | Standard_Real aDepth3 = ElCLib::Parameter (EyeLine, Nodes(n3)); | |
4bf18dff | 284 | Standard_Real aDepth = aDepth1 + aUV.X() * (aDepth2 - aDepth1) + |
7fd59977 | 285 | aUV.Y() * (aDepth3 - aDepth1); |
286 | ||
4bf18dff | 287 | // take triangle with lowest depth and within defined depth interval |
288 | if (aDepth < aMinDepth && | |
289 | aDepth > mylastprj->DepthMin() && | |
290 | aDepth < mylastprj->DepthMax()) | |
7fd59977 | 291 | { |
292 | aMinDepth = aDepth; | |
293 | myDetectedTr = itr; | |
4bf18dff | 294 | DMin = Sqrt (aDistSquare); |
7fd59977 | 295 | } |
296 | } | |
297 | } | |
81bba717 | 298 | |
299 | // Case only Test on Border of the triangulation... | |
300 | // | |
7fd59977 | 301 | else |
302 | { | |
303 | //Standard_Integer ifirst; | |
304 | TColStd_Array1OfInteger& FreeE = myFreeEdges->ChangeArray1(); | |
305 | Standard_Integer nn = FreeE.Length(), Node1,Node2; | |
306 | //Standard_Real LEdg; | |
307 | //Standard_Real DMinDMin,TolTol = aTol*aTol; | |
4bf18dff | 308 | |
7fd59977 | 309 | for (Standard_Integer ifri =1; ifri <= nn && myDetectedTr < 0; ifri+=2) |
310 | { | |
311 | Node1 = FreeE(ifri); | |
312 | Node2 = FreeE(ifri+1); | |
313 | if (S3D_STriangul_NearSegment (myNodes2d(Node1).XY(), | |
314 | myNodes2d(Node2).XY(), | |
315 | BidPoint, aTol, DMin) ) | |
316 | { | |
4bf18dff | 317 | for(Standard_Integer itr=1; itr <= myTriangul->NbTriangles(); itr++) |
7fd59977 | 318 | { |
319 | Standard_Integer n1,n2,n3; | |
4bf18dff | 320 | triangles(itr).Get(n1,n2,n3); |
321 | if(S3D_IsEdgeIn(Node1,Node2,n1,n2,n3)) | |
7fd59977 | 322 | { |
4bf18dff | 323 | myDetectedTr = itr; |
7fd59977 | 324 | break; // return first found; selection of closest is not implemented yet |
325 | } | |
4bf18dff | 326 | } |
7fd59977 | 327 | } |
328 | } | |
4bf18dff | 329 | } |
7fd59977 | 330 | if ( myDetectedTr <= 0 ) |
331 | return Standard_False; | |
4bf18dff | 332 | |
333 | // compute and validate the depth (::Depth()) along the eyeline | |
334 | return Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin); | |
7fd59977 | 335 | } |
336 | ||
337 | ||
338 | //======================================================================= | |
339 | //function : Matches | |
4bf18dff | 340 | //purpose : |
7fd59977 | 341 | //======================================================================= |
342 | ||
ac04d101 SA |
343 | Standard_Boolean Select3D_SensitiveTriangulation:: |
344 | Matches(const Standard_Real XMin, | |
345 | const Standard_Real YMin, | |
346 | const Standard_Real XMax, | |
347 | const Standard_Real YMax, | |
348 | const Standard_Real aTol) | |
7fd59977 | 349 | { |
350 | Bnd_Box2d B; | |
351 | B.Update(Min(XMin,XMax)-aTol, | |
ac04d101 SA |
352 | Min(YMin,YMax)-aTol, |
353 | Max(XMin,XMax)+aTol, | |
354 | Max(YMin,YMax)+aTol); | |
4bf18dff | 355 | |
ac04d101 SA |
356 | for(Standard_Integer i=myNodes2d.Lower();i<=myNodes2d.Upper();i++) |
357 | { | |
7fd59977 | 358 | if(B.IsOut(myNodes2d(i))) |
359 | return Standard_False; | |
360 | } | |
361 | return Standard_True; | |
362 | } | |
363 | ||
7fd59977 | 364 | //======================================================================= |
365 | //function : Matches | |
4bf18dff | 366 | //purpose : |
7fd59977 | 367 | //======================================================================= |
368 | ||
369 | Standard_Boolean Select3D_SensitiveTriangulation:: | |
370 | Matches (const TColgp_Array1OfPnt2d& aPoly, | |
ac04d101 SA |
371 | const Bnd_Box2d& aBox, |
372 | const Standard_Real aTol) | |
4bf18dff | 373 | { |
7fd59977 | 374 | Standard_Real Umin,Vmin,Umax,Vmax; |
375 | aBox.Get(Umin,Vmin,Umax,Vmax); | |
376 | Standard_Real Tolu,Tolv; | |
377 | Tolu = 1e-7; | |
378 | Tolv = 1e-7; | |
379 | CSLib_Class2d aClassifier2d(aPoly,aTol,aTol,Umin,Vmin,Umax,Vmax); | |
380 | ||
ac04d101 SA |
381 | for(Standard_Integer j=1;j<=myNodes2d.Length();j++) |
382 | { | |
7fd59977 | 383 | Standard_Integer RES = aClassifier2d.SiDans(myNodes2d(j)); |
384 | if(RES!=1) return Standard_False; | |
385 | } | |
386 | return Standard_True; | |
387 | } | |
388 | ||
ac04d101 SA |
389 | //======================================================================= |
390 | //function : Status | |
391 | //purpose : | |
392 | //======================================================================= | |
7fd59977 | 393 | |
ac04d101 SA |
394 | Standard_Integer Select3D_SensitiveTriangulation:: |
395 | Status (const gp_XY& TheP, | |
396 | const gp_XY& Proj0, | |
397 | const gp_XY& Proj1, | |
398 | const gp_XY& Proj2, | |
399 | const Standard_Real aTol, | |
400 | Standard_Real& DD) const | |
7fd59977 | 401 | { |
402 | return Select3D_SensitiveTriangle::Status(Proj0,Proj1,Proj2,TheP,aTol,DD); | |
403 | } | |
404 | ||
405 | //======================================================================= | |
406 | //function : IsFree | |
4bf18dff | 407 | //purpose : |
7fd59977 | 408 | //======================================================================= |
409 | ||
410 | Standard_Boolean Select3D_SensitiveTriangulation::IsFree(const Standard_Integer IndexOfTriangle, | |
ac04d101 | 411 | Standard_Integer& FoundIndex) const |
7fd59977 | 412 | { |
7fd59977 | 413 | FoundIndex=-1; |
414 | Standard_Integer n[3]; | |
415 | const Poly_Array1OfTriangle& triangles = myTriangul->Triangles(); | |
416 | triangles(IndexOfTriangle).Get(n[0],n[1],n[2]); | |
ac04d101 | 417 | TColStd_Array1OfInteger& FreeE = myFreeEdges->ChangeArray1(); |
4bf18dff | 418 | |
ac04d101 SA |
419 | for(Standard_Integer I=1;I<=FreeE.Length() && FoundIndex==-1;I+=2) |
420 | { | |
421 | if(FreeE(I) == n[0]) | |
422 | { | |
423 | if(FreeE(I+1)== n[1] || FreeE(I+1)== n[2]) | |
424 | FoundIndex=I; | |
425 | } | |
426 | else if(FreeE(I) == n[1]) | |
427 | { | |
428 | if(FreeE(I+1)== n[0] || FreeE(I+1)== n[2]) | |
429 | FoundIndex=I; | |
430 | } | |
431 | else if(FreeE(I) == n[2]) | |
432 | { | |
433 | if(FreeE(I+1)== n[0] || FreeE(I+1)== n[1]) | |
434 | FoundIndex=I; | |
435 | } | |
7fd59977 | 436 | } |
4bf18dff | 437 | |
7fd59977 | 438 | return FoundIndex!=-1; |
439 | } | |
440 | ||
441 | ||
442 | //======================================================================= | |
443 | //function : GetConnected | |
4bf18dff | 444 | //purpose : |
7fd59977 | 445 | //======================================================================= |
ac04d101 | 446 | |
7fd59977 | 447 | Handle(Select3D_SensitiveEntity) Select3D_SensitiveTriangulation:: |
448 | GetConnected(const TopLoc_Location& aLoc) | |
449 | { | |
4bf18dff | 450 | Handle(Select3D_SensitiveTriangulation) NiouEnt = |
7fd59977 | 451 | new Select3D_SensitiveTriangulation(myOwnerId,myTriangul,myiniloc,myFreeEdges,myCDG3D,myIntFlag); |
4bf18dff | 452 | |
ac04d101 SA |
453 | if(HasLocation()) |
454 | NiouEnt->SetLocation(Location()); | |
7fd59977 | 455 | // TopLoc_Location TheLocToApply = HasLocation() ? Location()*aLoc : aLoc; |
456 | // if(!TheLocToApply.IsIdentity()) | |
457 | NiouEnt->UpdateLocation(aLoc); | |
4bf18dff | 458 | |
7fd59977 | 459 | return NiouEnt; |
460 | } | |
461 | ||
7fd59977 | 462 | //======================================================================= |
463 | //function : ResetLocation | |
4bf18dff | 464 | //purpose : |
7fd59977 | 465 | //======================================================================= |
ac04d101 | 466 | |
4bf18dff | 467 | void Select3D_SensitiveTriangulation::ResetLocation() |
7fd59977 | 468 | { |
469 | Select3D_SensitiveEntity::ResetLocation(); | |
470 | ComputeTotalTrsf(); | |
471 | } | |
ac04d101 SA |
472 | |
473 | //======================================================================= | |
474 | //function : SetLocation | |
475 | //purpose : | |
476 | //======================================================================= | |
477 | ||
7fd59977 | 478 | void Select3D_SensitiveTriangulation::SetLocation(const TopLoc_Location& aLoc) |
479 | { | |
480 | Select3D_SensitiveEntity::SetLocation(aLoc); | |
481 | ComputeTotalTrsf(); | |
482 | } | |
483 | ||
484 | ||
485 | //======================================================================= | |
486 | //function : Dump | |
4bf18dff | 487 | //purpose : |
7fd59977 | 488 | //======================================================================= |
4bf18dff | 489 | void Select3D_SensitiveTriangulation::Dump(Standard_OStream& S,const Standard_Boolean FullDump) const |
7fd59977 | 490 | { |
491 | S<<"\tSensitiveTriangulation 3D :"<<endl; | |
492 | if(myiniloc.IsIdentity()) | |
493 | S<<"\t\tNo Initial Location"<<endl; | |
494 | else | |
495 | S<<"\t\tExisting Initial Location"<<endl; | |
496 | if(HasLocation()) | |
497 | S<<"\t\tExisting Location"<<endl; | |
4bf18dff | 498 | |
7fd59977 | 499 | S<<"\t\tNb Triangles : "<<myTriangul->NbTriangles()<<endl; |
500 | S<<"\t\tNb Nodes : "<<myTriangul->NbNodes()<<endl; | |
501 | S<<"\t\tNb Free Edges: "<<myFreeEdges->Length()/2<<endl; | |
502 | ||
ac04d101 SA |
503 | if(FullDump) |
504 | { | |
7fd59977 | 505 | // S<<"\t\t\tOwner:"<<myOwnerId<<endl; |
506 | Select3D_SensitiveEntity::DumpBox(S,mybox2d); | |
507 | } | |
508 | } | |
509 | ||
510 | //======================================================================= | |
511 | //function : ComputeDepth | |
4bf18dff | 512 | //purpose : |
7fd59977 | 513 | //======================================================================= |
ac04d101 | 514 | |
7fd59977 | 515 | Standard_Real Select3D_SensitiveTriangulation::ComputeDepth(const gp_Lin& EyeLine) const |
516 | { | |
81bba717 | 517 | if(myDetectedTr==-1) return Precision::Infinite(); // currently not implemented... |
7fd59977 | 518 | const Poly_Array1OfTriangle& triangles = myTriangul->Triangles(); |
4bf18dff | 519 | const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes(); |
520 | ||
7fd59977 | 521 | Standard_Integer n1,n2,n3; |
522 | triangles(myDetectedTr).Get(n1,n2,n3); | |
523 | gp_Pnt P[3]={Nodes(n1),Nodes(n2),Nodes(n3)}; | |
524 | ||
ac04d101 SA |
525 | if(myTrsf.Form()!=gp_Identity) |
526 | { | |
527 | for(Standard_Integer i =0;i<=2;i++) | |
528 | { | |
7fd59977 | 529 | P[i].Transform(myTrsf); |
530 | } | |
531 | } | |
81bba717 | 532 | |
533 | // formula calculate the parameter of the point on the intersection | |
7fd59977 | 534 | // t = (P1P2 ^P1P3)* OP1 / ((P1P2^P1P3)*Dir) |
535 | Standard_Real prof(Precision::Infinite()); | |
81bba717 | 536 | gp_Pnt Oye = EyeLine.Location(); // origin of the target line eye/point... |
7fd59977 | 537 | gp_Dir Dir = EyeLine.Direction(); |
538 | ||
4bf18dff | 539 | gp_Vec Vtr[3]; |
7fd59977 | 540 | for(Standard_Integer i=0;i<=2;i++) |
541 | Vtr[i] = gp_Vec(P[i%3],P[(i+1)%3]); | |
542 | Vtr[2] = -Vtr[2]; | |
81bba717 | 543 | |
544 | // remove singular cases immediately... | |
7fd59977 | 545 | Standard_Integer SingularCase(-1); |
546 | if(Vtr[0].SquareMagnitude()<= Precision::Confusion()) | |
547 | SingularCase = 0; | |
548 | if(Vtr[1].SquareMagnitude()<= Precision::Confusion()) | |
549 | SingularCase = (SingularCase == -1) ? 1 : 2; | |
550 | #ifdef BUC60858 | |
551 | if(Vtr[2].SquareMagnitude()<= Precision::Confusion()) | |
552 | if( SingularCase < 0 ) SingularCase = 1; | |
553 | #endif | |
81bba717 | 554 | |
555 | // 3 pts mixed... | |
ac04d101 SA |
556 | if(SingularCase ==2) |
557 | { | |
7fd59977 | 558 | prof= ElCLib::Parameter(EyeLine,P[0]); |
559 | return prof; | |
560 | } | |
4bf18dff | 561 | |
7fd59977 | 562 | if(SingularCase!=0) |
563 | Vtr[0].Normalize(); | |
564 | if(SingularCase!=1 && | |
565 | SingularCase!=2) | |
566 | Vtr[2].Normalize(); | |
567 | gp_Vec OPo(Oye,P[0]); | |
81bba717 | 568 | // 2 points mixed... the intersection between the segment and the target line eye/point. |
569 | // | |
ac04d101 SA |
570 | if(SingularCase!=-1) |
571 | { | |
7fd59977 | 572 | gp_Vec V = SingularCase==0 ? Vtr[2] : Vtr[0]; |
573 | gp_Vec Det = Dir^V; | |
574 | gp_Vec VSM = OPo^V; | |
575 | if(Det.X()> Precision::Confusion()) | |
576 | prof = VSM.X()/Det.X(); | |
577 | else if (Det.Y()> Precision::Confusion()) | |
578 | prof = VSM.Y()/Det.Y(); | |
579 | else if(Det.Z()> Precision::Confusion()) | |
580 | prof = VSM.Z()/Det.Z(); | |
581 | } | |
ac04d101 SA |
582 | else |
583 | { | |
7fd59977 | 584 | Standard_Real val1 = OPo.DotCross(Vtr[0],Vtr[2]); |
585 | Standard_Real val2 = Dir.DotCross(Vtr[0],Vtr[2]); | |
4bf18dff | 586 | |
7fd59977 | 587 | if(Abs(val2)>Precision::Confusion()) |
588 | prof =val1/val2; | |
4bf18dff | 589 | } |
ac04d101 SA |
590 | if (prof==Precision::Infinite()) |
591 | { | |
7fd59977 | 592 | prof= ElCLib::Parameter(EyeLine,P[0]); |
593 | prof = Min (prof, ElCLib::Parameter(EyeLine,P[1])); | |
594 | prof = Min (prof, ElCLib::Parameter(EyeLine,P[2])); | |
595 | } | |
4bf18dff | 596 | |
7fd59977 | 597 | return prof; |
598 | } | |
599 | ||
600 | //======================================================================= | |
601 | //function : DetectedTriangle | |
4bf18dff | 602 | //purpose : |
7fd59977 | 603 | //======================================================================= |
ac04d101 SA |
604 | |
605 | Standard_Boolean Select3D_SensitiveTriangulation:: | |
606 | DetectedTriangle(gp_Pnt& P1, | |
607 | gp_Pnt& P2, | |
608 | gp_Pnt& P3) const | |
7fd59977 | 609 | { |
81bba717 | 610 | if(myDetectedTr==-1) return Standard_False; // currently not implemented... |
7fd59977 | 611 | const Poly_Array1OfTriangle& triangles = myTriangul->Triangles(); |
4bf18dff | 612 | const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes(); |
7fd59977 | 613 | Standard_Integer n1,n2,n3; |
614 | triangles(myDetectedTr).Get(n1,n2,n3); | |
4bf18dff | 615 | |
7fd59977 | 616 | P1 = Nodes(n1); |
617 | P2 = Nodes(n2); | |
618 | P3 = Nodes(n3); | |
ac04d101 SA |
619 | if(myTrsf.Form()!=gp_Identity) |
620 | { | |
7fd59977 | 621 | P1.Transform(myTrsf); |
622 | P2.Transform(myTrsf); | |
623 | P3.Transform(myTrsf); | |
624 | } | |
4bf18dff | 625 | |
7fd59977 | 626 | return Standard_True; |
627 | } | |
628 | ||
629 | //============================================================================= | |
630 | // Function : DetectedTriangle2d | |
4bf18dff | 631 | // Purpose : |
7fd59977 | 632 | //============================================================================= |
ac04d101 SA |
633 | |
634 | Standard_Boolean Select3D_SensitiveTriangulation:: | |
635 | DetectedTriangle2d(gp_Pnt2d& P1, | |
636 | gp_Pnt2d& P2, | |
637 | gp_Pnt2d& P3) const | |
7fd59977 | 638 | { |
81bba717 | 639 | if(myDetectedTr==-1) |
640 | return Standard_False; // currently not implemented... | |
7fd59977 | 641 | const Poly_Array1OfTriangle& triangles = myTriangul->Triangles(); |
7fd59977 | 642 | Standard_Integer n1,n2,n3; |
643 | triangles( myDetectedTr ).Get(n1,n2,n3); | |
644 | ||
645 | int aLower = myNodes2d.Lower(); | |
646 | int anUpper = myNodes2d.Upper(); | |
4bf18dff | 647 | if ( n1 >= aLower && n1 <= anUpper && |
7fd59977 | 648 | n2 >= aLower && n2 <= anUpper && |
649 | n3 >= aLower && n3 <= anUpper ) | |
650 | { | |
651 | P1 = myNodes2d.Value( n1 ); | |
652 | P2 = myNodes2d.Value( n2 ); | |
653 | P3 = myNodes2d.Value( n3 ); | |
654 | return Standard_True; | |
655 | } | |
4bf18dff | 656 | else |
7fd59977 | 657 | return Standard_False; |
7fd59977 | 658 | } |
659 | ||
ac04d101 SA |
660 | //============================================================================= |
661 | // Function : ComputeTotalTrsf | |
662 | // Purpose : | |
663 | //============================================================================= | |
664 | ||
4bf18dff | 665 | void Select3D_SensitiveTriangulation::ComputeTotalTrsf() |
7fd59977 | 666 | { |
667 | Standard_Boolean hasloc = (HasLocation() || !myiniloc.IsIdentity()); | |
4bf18dff | 668 | |
ac04d101 SA |
669 | if(hasloc) |
670 | { | |
7fd59977 | 671 | if(myiniloc.IsIdentity()) |
672 | myTrsf = Location().Transformation(); | |
ac04d101 SA |
673 | else if(HasLocation()) |
674 | { | |
7fd59977 | 675 | myTrsf = (Location()*myiniloc).Transformation(); |
676 | } | |
677 | else | |
678 | myTrsf = myiniloc.Transformation(); | |
679 | } | |
ac04d101 SA |
680 | else |
681 | { | |
7fd59977 | 682 | gp_Trsf TheId; |
683 | myTrsf = TheId; | |
684 | } | |
685 | } |