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