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> |
4952a30a |
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 | } |
4952a30a |
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; |
4952a30a |
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(); |
4952a30a |
72 | |
7fd59977 |
73 | // if(long1<=TolTol) |
74 | // return VCur.SquareModulus(); |
75 | // Standard_Real Val = VEdg^VCur; |
76 | // return Val*Val/long1; |
4952a30a |
77 | |
7fd59977 |
78 | // } |
79 | |
80 | static Standard_Boolean S3D_IsEdgeIn(const Standard_Integer e1, |
81 | const Standard_Integer e2, |
82 | const Standard_Integer N1, |
83 | const Standard_Integer N2, |
84 | const Standard_Integer N3) |
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 | |
94 | |
95 | |
96 | //======================================================================= |
97 | //function : Select3D_SensitiveTriangulation |
4952a30a |
98 | //purpose : |
7fd59977 |
99 | //======================================================================= |
100 | |
101 | Select3D_SensitiveTriangulation:: |
102 | Select3D_SensitiveTriangulation(const Handle(SelectBasics_EntityOwner)& OwnerId, |
103 | const Handle(Poly_Triangulation)& Trg, |
104 | const TopLoc_Location& Loc, |
105 | const Standard_Boolean InteriorFlag): |
106 | Select3D_SensitiveEntity(OwnerId), |
107 | myTriangul(Trg), |
108 | myiniloc(Loc), |
109 | myIntFlag(InteriorFlag), |
110 | myNodes2d(1,Trg->NbNodes()), |
111 | myDetectedTr(-1) |
112 | { |
113 | // Code honteusement vole a DBRep_DrawableShape::Display... |
114 | // calcul des edges libres et du cdg 3d de la triangulation: |
115 | // Ce code devrait, pour plus de facilites etre integre dans la poly_triangulation... |
116 | |
117 | Standard_Integer fr = 1; |
118 | const Poly_Array1OfTriangle& triangles = myTriangul->Triangles(); |
4952a30a |
119 | const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes(); |
7fd59977 |
120 | Standard_Integer nbTriangles (myTriangul->NbTriangles()); |
121 | gp_XYZ cdg(0,0,0); |
122 | Standard_Integer n[3]; |
4952a30a |
123 | |
7fd59977 |
124 | // pour rechercher les connexions dans le cas ou on ne s'occupe de la frontiere... |
125 | if(!myIntFlag){ |
126 | myFreeEdges = new TColStd_HArray1OfInteger(1,2*S3D_NumberOfFreeEdges(Trg)); |
127 | TColStd_Array1OfInteger& FreeE = myFreeEdges->ChangeArray1(); |
128 | Poly_Connect pc(myTriangul); |
129 | Standard_Integer t[3]; |
130 | Standard_Integer i,j; |
131 | for ( i = 1; i <= nbTriangles; i++) { |
132 | pc.Triangles(i,t[0],t[1],t[2]); |
133 | triangles(i).Get(n[0],n[1],n[2]); |
134 | cdg += (Nodes(n[0]).XYZ() + Nodes(n[1]).XYZ()+ Nodes(n[2]).XYZ())/3.; |
135 | for (j = 0; j < 3; j++) { |
136 | Standard_Integer k = (j+1) % 3; |
137 | if (t[j] == 0) { |
138 | FreeE(fr) = n[j]; |
139 | FreeE(fr+1)= n[k]; |
140 | fr += 2; |
141 | } |
142 | } |
143 | } |
144 | } |
145 | else{ |
146 | for (Standard_Integer i = 1; i <= nbTriangles; i++) { |
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.; |
149 | } |
150 | } |
151 | |
4952a30a |
152 | |
7fd59977 |
153 | if(nbTriangles!=0) cdg /= nbTriangles; |
154 | myCDG3D = gp_Pnt(cdg); |
4952a30a |
155 | |
7fd59977 |
156 | ComputeTotalTrsf(); |
157 | |
158 | if(myTrsf.Form()!=gp_Identity) |
159 | myCDG3D.Transform(myTrsf); |
160 | } |
161 | |
162 | |
163 | //======================================================================= |
164 | //function : Select3D_SensitiveTriangulation |
4952a30a |
165 | //purpose : |
7fd59977 |
166 | //======================================================================= |
167 | Select3D_SensitiveTriangulation:: |
168 | Select3D_SensitiveTriangulation(const Handle(SelectBasics_EntityOwner)& OwnerId, |
169 | const Handle(Poly_Triangulation)& Trg, |
170 | const TopLoc_Location& Loc, |
171 | const Handle(TColStd_HArray1OfInteger)& FreeEdges, |
172 | const gp_Pnt& TheCDG, |
173 | const Standard_Boolean InteriorFlag): |
174 | Select3D_SensitiveEntity(OwnerId), |
175 | myTriangul(Trg), |
176 | myiniloc(Loc), |
177 | myCDG3D(TheCDG), |
178 | myFreeEdges(FreeEdges), |
179 | myIntFlag(InteriorFlag), |
180 | myNodes2d(1,Trg->NbNodes()), |
181 | myDetectedTr(-1) |
182 | { |
183 | } |
184 | //======================================================================= |
185 | //function : Project |
4952a30a |
186 | //purpose : |
7fd59977 |
187 | //======================================================================= |
188 | |
4952a30a |
189 | void Select3D_SensitiveTriangulation::Project(const Handle(Select3D_Projector)& aPrj) |
7fd59977 |
190 | { |
191 | Select3D_SensitiveEntity::Project(aPrj); // to set the field last proj... |
4952a30a |
192 | |
7fd59977 |
193 | mybox2d.SetVoid(); |
4952a30a |
194 | const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes(); |
195 | |
7fd59977 |
196 | gp_Pnt2d ProjPT; |
4952a30a |
197 | |
7fd59977 |
198 | for(Standard_Integer I=1;I<=myTriangul->NbNodes();I++){ |
199 | if(myTrsf.Form()!=gp_Identity) |
4952a30a |
200 | aPrj->Project(Nodes(I).Transformed(myTrsf),ProjPT); |
7fd59977 |
201 | else |
4952a30a |
202 | aPrj->Project(Nodes(I),ProjPT); |
203 | |
7fd59977 |
204 | myNodes2d.SetValue(I,ProjPT); |
205 | mybox2d.Add(ProjPT); |
206 | } |
4952a30a |
207 | |
208 | aPrj->Project(myCDG3D,myCDG2D); |
7fd59977 |
209 | } |
210 | |
211 | //======================================================================= |
212 | //function : Areas |
4952a30a |
213 | //purpose : |
7fd59977 |
214 | //======================================================================= |
215 | |
4952a30a |
216 | void Select3D_SensitiveTriangulation::Areas(SelectBasics_ListOfBox2d& boxes) |
7fd59977 |
217 | { |
218 | boxes.Append(mybox2d); |
219 | } |
220 | |
7fd59977 |
221 | //======================================================================= |
222 | //function : Matches |
4952a30a |
223 | //purpose : |
7fd59977 |
224 | //======================================================================= |
225 | Standard_Boolean Select3D_SensitiveTriangulation::Matches(const Standard_Real X, |
226 | const Standard_Real Y, |
227 | const Standard_Real aTol, |
4952a30a |
228 | Standard_Real& DMin) |
7fd59977 |
229 | { |
230 | // get view direction (necessary for calculation of depth) from field mylastprj of the base class |
4952a30a |
231 | if (mylastprj.IsNull()) |
7fd59977 |
232 | return Standard_False; |
233 | |
234 | DMin = Precision::Infinite(); |
235 | gp_XY BidPoint(X,Y); |
236 | myDetectedTr = -1; |
237 | const Poly_Array1OfTriangle& triangles = myTriangul->Triangles(); |
238 | |
239 | // on regarde si on est a l'interieur d'1 triangle 2d. |
240 | if(myIntFlag) |
241 | { |
4952a30a |
242 | gp_Lin EyeLine = mylastprj->Shoot(X,Y); |
7fd59977 |
243 | if ( myTrsf.Form()!=gp_Identity ) |
244 | EyeLine.Transform (myTrsf.Inverted()); |
245 | |
246 | Standard_Real aMinDepth = Precision::Infinite(); |
4952a30a |
247 | const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes(); |
7fd59977 |
248 | for (Standard_Integer itr=1; itr<=myTriangul->NbTriangles(); itr++) |
249 | { |
250 | Standard_Integer n1,n2,n3; |
251 | triangles(itr).Get(n1,n2,n3); |
252 | const gp_XY& aPnt2d1 = myNodes2d(n1).XY(); |
253 | const gp_XY& aPnt2d2 = myNodes2d(n2).XY(); |
254 | const gp_XY& aPnt2d3 = myNodes2d(n3).XY(); |
4952a30a |
255 | gp_XY aUV; |
256 | Standard_Real aDistSquare = Poly::PointOnTriangle (aPnt2d1, aPnt2d2, aPnt2d3, BidPoint, aUV); |
257 | if ( aDistSquare > aTol * aTol ) |
7fd59977 |
258 | continue; |
259 | |
260 | // compute depth on this triangle |
7fd59977 |
261 | Standard_Real aDepth1 = ElCLib::Parameter (EyeLine, Nodes(n1)); |
262 | Standard_Real aDepth2 = ElCLib::Parameter (EyeLine, Nodes(n2)); |
263 | Standard_Real aDepth3 = ElCLib::Parameter (EyeLine, Nodes(n3)); |
4952a30a |
264 | Standard_Real aDepth = aDepth1 + aUV.X() * (aDepth2 - aDepth1) + |
7fd59977 |
265 | aUV.Y() * (aDepth3 - aDepth1); |
266 | |
4952a30a |
267 | // take triangle with lowest depth and within defined depth interval |
268 | if (aDepth < aMinDepth && |
269 | aDepth > mylastprj->DepthMin() && |
270 | aDepth < mylastprj->DepthMax()) |
7fd59977 |
271 | { |
272 | aMinDepth = aDepth; |
273 | myDetectedTr = itr; |
4952a30a |
274 | DMin = Sqrt (aDistSquare); |
7fd59977 |
275 | } |
276 | } |
277 | } |
4952a30a |
278 | |
7fd59977 |
279 | // Cas Uniquement Test sur Frontiere de la triangulation... |
4952a30a |
280 | // |
7fd59977 |
281 | else |
282 | { |
283 | //Standard_Integer ifirst; |
284 | TColStd_Array1OfInteger& FreeE = myFreeEdges->ChangeArray1(); |
285 | Standard_Integer nn = FreeE.Length(), Node1,Node2; |
286 | //Standard_Real LEdg; |
287 | //Standard_Real DMinDMin,TolTol = aTol*aTol; |
4952a30a |
288 | |
7fd59977 |
289 | for (Standard_Integer ifri =1; ifri <= nn && myDetectedTr < 0; ifri+=2) |
290 | { |
291 | Node1 = FreeE(ifri); |
292 | Node2 = FreeE(ifri+1); |
293 | if (S3D_STriangul_NearSegment (myNodes2d(Node1).XY(), |
294 | myNodes2d(Node2).XY(), |
295 | BidPoint, aTol, DMin) ) |
296 | { |
4952a30a |
297 | for(Standard_Integer itr=1; itr <= myTriangul->NbTriangles(); itr++) |
7fd59977 |
298 | { |
299 | Standard_Integer n1,n2,n3; |
4952a30a |
300 | triangles(itr).Get(n1,n2,n3); |
301 | if(S3D_IsEdgeIn(Node1,Node2,n1,n2,n3)) |
7fd59977 |
302 | { |
4952a30a |
303 | myDetectedTr = itr; |
7fd59977 |
304 | break; // return first found; selection of closest is not implemented yet |
305 | } |
4952a30a |
306 | } |
7fd59977 |
307 | } |
308 | } |
4952a30a |
309 | } |
7fd59977 |
310 | if ( myDetectedTr <= 0 ) |
311 | return Standard_False; |
4952a30a |
312 | |
313 | // compute and validate the depth (::Depth()) along the eyeline |
314 | return Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin); |
7fd59977 |
315 | } |
316 | |
317 | |
318 | //======================================================================= |
319 | //function : Matches |
4952a30a |
320 | //purpose : |
7fd59977 |
321 | //======================================================================= |
322 | |
323 | Standard_Boolean Select3D_SensitiveTriangulation::Matches(const Standard_Real XMin, |
324 | const Standard_Real YMin, |
325 | const Standard_Real XMax, |
326 | const Standard_Real YMax, |
4952a30a |
327 | const Standard_Real aTol) |
7fd59977 |
328 | { |
329 | Bnd_Box2d B; |
330 | B.Update(Min(XMin,XMax)-aTol, |
331 | Min(YMin,YMax)-aTol, |
332 | Max(XMin,XMax)+aTol, |
333 | Max(YMin,YMax)+aTol); |
4952a30a |
334 | |
7fd59977 |
335 | for(Standard_Integer i=myNodes2d.Lower();i<=myNodes2d.Upper();i++){ |
336 | if(B.IsOut(myNodes2d(i))) |
337 | return Standard_False; |
338 | } |
339 | return Standard_True; |
340 | } |
341 | |
342 | |
343 | //======================================================================= |
344 | //function : Matches |
4952a30a |
345 | //purpose : |
7fd59977 |
346 | //======================================================================= |
347 | |
348 | Standard_Boolean Select3D_SensitiveTriangulation:: |
349 | Matches (const TColgp_Array1OfPnt2d& aPoly, |
350 | const Bnd_Box2d& aBox, |
351 | const Standard_Real aTol) |
4952a30a |
352 | { |
7fd59977 |
353 | Standard_Real Umin,Vmin,Umax,Vmax; |
354 | aBox.Get(Umin,Vmin,Umax,Vmax); |
355 | Standard_Real Tolu,Tolv; |
356 | Tolu = 1e-7; |
357 | Tolv = 1e-7; |
358 | CSLib_Class2d aClassifier2d(aPoly,aTol,aTol,Umin,Vmin,Umax,Vmax); |
359 | |
360 | for(Standard_Integer j=1;j<=myNodes2d.Length();j++){ |
361 | Standard_Integer RES = aClassifier2d.SiDans(myNodes2d(j)); |
362 | if(RES!=1) return Standard_False; |
363 | } |
364 | return Standard_True; |
365 | } |
366 | |
367 | |
368 | |
369 | Standard_Integer Select3D_SensitiveTriangulation::Status (const gp_XY& TheP, |
370 | const gp_XY& Proj0, |
371 | const gp_XY& Proj1, |
372 | const gp_XY& Proj2, |
373 | const Standard_Real aTol, |
374 | Standard_Real& DD) const |
375 | { |
376 | return Select3D_SensitiveTriangle::Status(Proj0,Proj1,Proj2,TheP,aTol,DD); |
377 | } |
378 | |
379 | //======================================================================= |
380 | //function : IsFree |
4952a30a |
381 | //purpose : |
7fd59977 |
382 | //======================================================================= |
383 | |
384 | Standard_Boolean Select3D_SensitiveTriangulation::IsFree(const Standard_Integer IndexOfTriangle, |
385 | Standard_Integer& FoundIndex) const |
386 | { |
387 | |
388 | FoundIndex=-1; |
389 | Standard_Integer n[3]; |
390 | const Poly_Array1OfTriangle& triangles = myTriangul->Triangles(); |
391 | triangles(IndexOfTriangle).Get(n[0],n[1],n[2]); |
392 | TColStd_Array1OfInteger& FreeE = myFreeEdges->ChangeArray1(); |
393 | |
394 | for(Standard_Integer I=1;I<=FreeE.Length() && FoundIndex==-1;I+=2){ |
4952a30a |
395 | |
7fd59977 |
396 | if(FreeE(I) == n[0]){ |
4952a30a |
397 | |
7fd59977 |
398 | if(FreeE(I+1)== n[1] || FreeE(I+1)== n[2]) FoundIndex=I;} |
399 | else if(FreeE(I) == n[1]){ |
400 | if(FreeE(I+1)== n[0] || FreeE(I+1)== n[2]) FoundIndex=I;} |
401 | else if(FreeE(I) == n[2]){ |
402 | if(FreeE(I+1)== n[0] || FreeE(I+1)== n[1]) FoundIndex=I;} |
403 | } |
4952a30a |
404 | |
7fd59977 |
405 | return FoundIndex!=-1; |
406 | } |
407 | |
408 | |
409 | //======================================================================= |
410 | //function : GetConnected |
4952a30a |
411 | //purpose : |
7fd59977 |
412 | //======================================================================= |
413 | Handle(Select3D_SensitiveEntity) Select3D_SensitiveTriangulation:: |
414 | GetConnected(const TopLoc_Location& aLoc) |
415 | { |
4952a30a |
416 | |
417 | Handle(Select3D_SensitiveTriangulation) NiouEnt = |
7fd59977 |
418 | new Select3D_SensitiveTriangulation(myOwnerId,myTriangul,myiniloc,myFreeEdges,myCDG3D,myIntFlag); |
4952a30a |
419 | |
7fd59977 |
420 | if(HasLocation()) NiouEnt->SetLocation(Location()); |
421 | // TopLoc_Location TheLocToApply = HasLocation() ? Location()*aLoc : aLoc; |
422 | // if(!TheLocToApply.IsIdentity()) |
423 | NiouEnt->UpdateLocation(aLoc); |
4952a30a |
424 | |
7fd59977 |
425 | |
426 | return NiouEnt; |
427 | } |
428 | |
429 | |
430 | //======================================================================= |
431 | //function : ResetLocation |
4952a30a |
432 | //purpose : |
7fd59977 |
433 | //======================================================================= |
4952a30a |
434 | void Select3D_SensitiveTriangulation::ResetLocation() |
7fd59977 |
435 | { |
436 | Select3D_SensitiveEntity::ResetLocation(); |
437 | ComputeTotalTrsf(); |
438 | } |
439 | void Select3D_SensitiveTriangulation::SetLocation(const TopLoc_Location& aLoc) |
440 | { |
441 | Select3D_SensitiveEntity::SetLocation(aLoc); |
442 | ComputeTotalTrsf(); |
443 | } |
444 | |
445 | |
446 | //======================================================================= |
447 | //function : Dump |
4952a30a |
448 | //purpose : |
7fd59977 |
449 | //======================================================================= |
4952a30a |
450 | void Select3D_SensitiveTriangulation::Dump(Standard_OStream& S,const Standard_Boolean FullDump) const |
7fd59977 |
451 | { |
452 | S<<"\tSensitiveTriangulation 3D :"<<endl; |
453 | if(myiniloc.IsIdentity()) |
454 | S<<"\t\tNo Initial Location"<<endl; |
455 | else |
456 | S<<"\t\tExisting Initial Location"<<endl; |
457 | if(HasLocation()) |
458 | S<<"\t\tExisting Location"<<endl; |
4952a30a |
459 | |
7fd59977 |
460 | S<<"\t\tNb Triangles : "<<myTriangul->NbTriangles()<<endl; |
461 | S<<"\t\tNb Nodes : "<<myTriangul->NbNodes()<<endl; |
462 | S<<"\t\tNb Free Edges: "<<myFreeEdges->Length()/2<<endl; |
463 | |
464 | if(FullDump){ |
465 | // S<<"\t\t\tOwner:"<<myOwnerId<<endl; |
466 | Select3D_SensitiveEntity::DumpBox(S,mybox2d); |
467 | } |
468 | } |
469 | |
470 | //======================================================================= |
471 | //function : ComputeDepth |
4952a30a |
472 | //purpose : |
7fd59977 |
473 | //======================================================================= |
474 | Standard_Real Select3D_SensitiveTriangulation::ComputeDepth(const gp_Lin& EyeLine) const |
475 | { |
476 | if(myDetectedTr==-1) return Precision::Infinite(); // non implemente actuellement... |
477 | const Poly_Array1OfTriangle& triangles = myTriangul->Triangles(); |
4952a30a |
478 | const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes(); |
479 | |
7fd59977 |
480 | Standard_Integer n1,n2,n3; |
481 | triangles(myDetectedTr).Get(n1,n2,n3); |
482 | gp_Pnt P[3]={Nodes(n1),Nodes(n2),Nodes(n3)}; |
483 | |
484 | if(myTrsf.Form()!=gp_Identity){ |
485 | for(Standard_Integer i =0;i<=2;i++){ |
486 | P[i].Transform(myTrsf); |
487 | } |
488 | } |
4952a30a |
489 | |
7fd59977 |
490 | // formule calcul du parametre du point sur l'intersection |
491 | // t = (P1P2 ^P1P3)* OP1 / ((P1P2^P1P3)*Dir) |
492 | Standard_Real prof(Precision::Infinite()); |
493 | gp_Pnt Oye = EyeLine.Location(); // origine de la ligne oeil/point vise... |
494 | gp_Dir Dir = EyeLine.Direction(); |
495 | |
4952a30a |
496 | gp_Vec Vtr[3]; |
7fd59977 |
497 | for(Standard_Integer i=0;i<=2;i++) |
498 | Vtr[i] = gp_Vec(P[i%3],P[(i+1)%3]); |
499 | Vtr[2] = -Vtr[2]; |
4952a30a |
500 | |
7fd59977 |
501 | // eliminons tout de suite les cas singuliers... |
502 | Standard_Integer SingularCase(-1); |
503 | if(Vtr[0].SquareMagnitude()<= Precision::Confusion()) |
504 | SingularCase = 0; |
505 | if(Vtr[1].SquareMagnitude()<= Precision::Confusion()) |
506 | SingularCase = (SingularCase == -1) ? 1 : 2; |
507 | #ifdef BUC60858 |
508 | if(Vtr[2].SquareMagnitude()<= Precision::Confusion()) |
509 | if( SingularCase < 0 ) SingularCase = 1; |
510 | #endif |
4952a30a |
511 | |
7fd59977 |
512 | // 3 pts confondus... |
513 | if(SingularCase ==2){ |
514 | prof= ElCLib::Parameter(EyeLine,P[0]); |
515 | return prof; |
516 | } |
4952a30a |
517 | |
7fd59977 |
518 | if(SingularCase!=0) |
519 | Vtr[0].Normalize(); |
520 | if(SingularCase!=1 && |
521 | SingularCase!=2) |
522 | Vtr[2].Normalize(); |
523 | gp_Vec OPo(Oye,P[0]); |
524 | // 2 points confondus... on recherche l'intersection entre le segment et la ligne oeil/point vise. |
4952a30a |
525 | // |
7fd59977 |
526 | if(SingularCase!=-1){ |
527 | gp_Vec V = SingularCase==0 ? Vtr[2] : Vtr[0]; |
528 | gp_Vec Det = Dir^V; |
529 | gp_Vec VSM = OPo^V; |
530 | if(Det.X()> Precision::Confusion()) |
531 | prof = VSM.X()/Det.X(); |
532 | else if (Det.Y()> Precision::Confusion()) |
533 | prof = VSM.Y()/Det.Y(); |
534 | else if(Det.Z()> Precision::Confusion()) |
535 | prof = VSM.Z()/Det.Z(); |
536 | } |
537 | else{ |
4952a30a |
538 | |
7fd59977 |
539 | Standard_Real val1 = OPo.DotCross(Vtr[0],Vtr[2]); |
540 | Standard_Real val2 = Dir.DotCross(Vtr[0],Vtr[2]); |
4952a30a |
541 | |
7fd59977 |
542 | if(Abs(val2)>Precision::Confusion()) |
543 | prof =val1/val2; |
4952a30a |
544 | } |
7fd59977 |
545 | if (prof==Precision::Infinite()){ |
546 | prof= ElCLib::Parameter(EyeLine,P[0]); |
547 | prof = Min (prof, ElCLib::Parameter(EyeLine,P[1])); |
548 | prof = Min (prof, ElCLib::Parameter(EyeLine,P[2])); |
549 | } |
4952a30a |
550 | |
7fd59977 |
551 | return prof; |
552 | } |
553 | |
554 | //======================================================================= |
555 | //function : DetectedTriangle |
4952a30a |
556 | //purpose : |
7fd59977 |
557 | //======================================================================= |
558 | Standard_Boolean Select3D_SensitiveTriangulation::DetectedTriangle(gp_Pnt& P1, |
559 | gp_Pnt& P2, |
560 | gp_Pnt& P3) const |
561 | { |
562 | if(myDetectedTr==-1) return Standard_False; // non implemente actuellement... |
563 | const Poly_Array1OfTriangle& triangles = myTriangul->Triangles(); |
4952a30a |
564 | const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes(); |
7fd59977 |
565 | Standard_Integer n1,n2,n3; |
566 | triangles(myDetectedTr).Get(n1,n2,n3); |
4952a30a |
567 | |
7fd59977 |
568 | P1 = Nodes(n1); |
569 | P2 = Nodes(n2); |
570 | P3 = Nodes(n3); |
571 | if(myTrsf.Form()!=gp_Identity){ |
572 | P1.Transform(myTrsf); |
573 | P2.Transform(myTrsf); |
574 | P3.Transform(myTrsf); |
575 | } |
4952a30a |
576 | |
7fd59977 |
577 | return Standard_True; |
578 | } |
579 | |
580 | //============================================================================= |
581 | // Function : DetectedTriangle2d |
4952a30a |
582 | // Purpose : |
7fd59977 |
583 | //============================================================================= |
4952a30a |
584 | Standard_Boolean Select3D_SensitiveTriangulation::DetectedTriangle2d( |
7fd59977 |
585 | gp_Pnt2d& P1, gp_Pnt2d& P2, gp_Pnt2d& P3) const |
586 | { |
4952a30a |
587 | if(myDetectedTr==-1) |
7fd59977 |
588 | return Standard_False; // non implemente actuellement... |
589 | const Poly_Array1OfTriangle& triangles = myTriangul->Triangles(); |
4952a30a |
590 | const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes(); |
7fd59977 |
591 | Standard_Integer n1,n2,n3; |
592 | triangles( myDetectedTr ).Get(n1,n2,n3); |
593 | |
594 | int aLower = myNodes2d.Lower(); |
595 | int anUpper = myNodes2d.Upper(); |
4952a30a |
596 | if ( n1 >= aLower && n1 <= anUpper && |
7fd59977 |
597 | n2 >= aLower && n2 <= anUpper && |
598 | n3 >= aLower && n3 <= anUpper ) |
599 | { |
600 | P1 = myNodes2d.Value( n1 ); |
601 | P2 = myNodes2d.Value( n2 ); |
602 | P3 = myNodes2d.Value( n3 ); |
603 | return Standard_True; |
604 | } |
4952a30a |
605 | else |
7fd59977 |
606 | return Standard_False; |
4952a30a |
607 | |
7fd59977 |
608 | } |
609 | |
4952a30a |
610 | void Select3D_SensitiveTriangulation::ComputeTotalTrsf() |
7fd59977 |
611 | { |
612 | Standard_Boolean hasloc = (HasLocation() || !myiniloc.IsIdentity()); |
4952a30a |
613 | |
7fd59977 |
614 | if(hasloc){ |
615 | if(myiniloc.IsIdentity()) |
616 | myTrsf = Location().Transformation(); |
617 | else if(HasLocation()){ |
618 | myTrsf = (Location()*myiniloc).Transformation(); |
619 | } |
620 | else |
621 | myTrsf = myiniloc.Transformation(); |
622 | } |
623 | else{ |
624 | gp_Trsf TheId; |
625 | myTrsf = TheId; |
626 | } |
627 | } |