b311480e |
1 | // Created on: 1995-03-15 |
2 | // Created by: Robert COUBLANC |
3 | // Copyright (c) 1995-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
8 | // This library is free software; you can redistribute it and/or modify it under |
9 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
10 | // by the Free Software Foundation, with special exception defined in the file |
11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
12 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
7fd59977 |
16 | |
17 | #include <StdSelect_ViewerSelector3d.ixx> |
18 | #include <StdSelect.hxx> |
19 | #include <SelectBasics_SensitiveEntity.hxx> |
20 | #include <Graphic3d_AspectLine3d.hxx> |
21 | #include <gp_Pnt.hxx> |
22 | #include <gp_Lin.hxx> |
23 | #include <gp_Pnt2d.hxx> |
24 | #include <gp_Dir.hxx> |
25 | #include <gp_Ax3.hxx> |
26 | #include <gp_GTrsf.hxx> |
4269bd1b |
27 | #include <gp_Pln.hxx> |
7fd59977 |
28 | #include <Select3D_SensitiveEntity.hxx> |
b8ddfc2f |
29 | #include <Graphic3d_ArrayOfPolylines.hxx> |
51b10cd4 |
30 | #include <Graphic3d_SequenceOfHClipPlane.hxx> |
4269bd1b |
31 | #include <SelectMgr_SelectableObject.hxx> |
7fd59977 |
32 | #include <SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive.hxx> |
33 | #include <SelectBasics_ListOfBox2d.hxx> |
7fd59977 |
34 | #include <TColgp_HArray1OfPnt.hxx> |
35 | #include <TColgp_Array1OfPnt.hxx> |
36 | #include <TColgp_HArray1OfPnt2d.hxx> |
37 | #include <Select3D_SensitiveCurve.hxx> |
38 | #include <Select3D_SensitiveSegment.hxx> |
39 | #include <Select3D_SensitiveFace.hxx> |
40 | #include <Select3D_SensitiveCircle.hxx> |
41 | #include <Select3D_SensitivePoint.hxx> |
42 | #include <Select3D_SensitiveTriangulation.hxx> |
43 | #include <Select3D_SensitiveTriangle.hxx> |
44 | #include <Select3D_SensitiveWire.hxx> |
45 | #include <Select3D_SensitiveEntitySequence.hxx> |
46 | #include <Select3D_ListOfSensitiveTriangle.hxx> |
47 | #include <Select3D_SensitiveBox.hxx> |
48 | #include <Select3D_ListIteratorOfListOfSensitiveTriangle.hxx> |
49 | |
50 | #include <SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation.hxx> |
679ecdee |
51 | #include <Aspect_Grid.hxx> |
7fd59977 |
52 | #include <Aspect_TypeOfMarker.hxx> |
53 | #include <Graphic3d_AspectMarker3d.hxx> |
a577aaab |
54 | #include <Graphic3d_ArrayOfPoints.hxx> |
7fd59977 |
55 | #include <SelectBasics_ListIteratorOfListOfBox2d.hxx> |
56 | #include <Poly_Connect.hxx> |
57 | #include <TColStd_HArray1OfInteger.hxx> |
58 | |
59 | #include <Poly_Array1OfTriangle.hxx> |
60 | #include <Poly_Triangulation.hxx> |
61 | #include <OSD_Environment.hxx> |
62 | #include <V3d.hxx> |
63 | #include <V3d_View.hxx> |
679ecdee |
64 | #include <V3d_Viewer.hxx> |
b8ddfc2f |
65 | #include <TColgp_SequenceOfPnt.hxx> |
66 | |
7fd59977 |
67 | static Standard_Integer StdSel_NumberOfFreeEdges (const Handle(Poly_Triangulation)& Trg) |
68 | { |
69 | Standard_Integer nFree = 0; |
70 | Poly_Connect pc(Trg); |
71 | Standard_Integer t[3]; |
72 | Standard_Integer i, j; |
73 | for (i = 1; i <= Trg->NbTriangles(); i++) |
74 | { |
75 | pc.Triangles (i, t[0], t[1], t[2]); |
76 | for (j = 0; j < 3; j++) |
77 | if (t[j] == 0) nFree++; |
78 | } |
79 | return nFree; |
80 | } |
81 | |
197ac94e |
82 | //======================================================================= |
83 | // Function : Constructor |
84 | // Purpose : |
85 | //======================================================================= |
86 | StdSelect_ViewerSelector3d::StdSelect_ViewerSelector3d() |
87 | : myProjector (new Select3D_Projector()), |
88 | myPrevFOV (0.0), |
89 | myPrevScale (0.0), |
90 | myPrevOrthographic (Standard_True), |
91 | mySensMode (StdSelect_SM_WINDOW), |
92 | myPixelTolerance (2), |
93 | myToUpdateTolerance (Standard_True) |
7fd59977 |
94 | { |
197ac94e |
95 | myPrevAt[0] = 0.0; |
96 | myPrevAt[1] = 0.0; |
97 | myPrevAt[2] = 0.0; |
98 | myPrevUp[0] = 0.0; |
99 | myPrevUp[1] = 0.0; |
100 | myPrevUp[2] = 0.0; |
101 | myPrevProj[0] = 0.0; |
102 | myPrevProj[1] = 0.0; |
103 | myPrevProj[2] = 0.0; |
104 | myPrevAxialScale[0] = 0.0; |
105 | myPrevAxialScale[1] = 0.0; |
106 | myPrevAxialScale[2] = 0.0; |
7fd59977 |
107 | } |
108 | |
197ac94e |
109 | //======================================================================= |
110 | // Function : Constructor |
111 | // Purpose : |
112 | //======================================================================= |
113 | StdSelect_ViewerSelector3d::StdSelect_ViewerSelector3d (const Handle(Select3D_Projector)& theProj) |
114 | : myProjector (theProj), |
115 | myPrevFOV (0.0), |
116 | myPrevScale (0.0), |
117 | myPrevOrthographic (Standard_True), |
118 | mySensMode (StdSelect_SM_WINDOW), |
119 | myPixelTolerance (2), |
120 | myToUpdateTolerance (Standard_True) |
7fd59977 |
121 | { |
197ac94e |
122 | myPrevAt[0] = 0.0; |
123 | myPrevAt[1] = 0.0; |
124 | myPrevAt[2] = 0.0; |
125 | myPrevUp[0] = 0.0; |
126 | myPrevUp[1] = 0.0; |
127 | myPrevUp[2] = 0.0; |
128 | myPrevProj[0] = 0.0; |
129 | myPrevProj[1] = 0.0; |
130 | myPrevProj[2] = 0.0; |
131 | myPrevAxialScale[0] = 0.0; |
132 | myPrevAxialScale[1] = 0.0; |
133 | myPrevAxialScale[2] = 0.0; |
7fd59977 |
134 | } |
135 | |
197ac94e |
136 | //======================================================================= |
7fd59977 |
137 | // Function: Convert |
138 | // Purpose : |
197ac94e |
139 | //======================================================================= |
140 | void StdSelect_ViewerSelector3d::Convert (const Handle(SelectMgr_Selection)& theSel) |
7fd59977 |
141 | { |
197ac94e |
142 | for (theSel->Init(); theSel->More(); theSel->Next()) |
7fd59977 |
143 | { |
197ac94e |
144 | if (theSel->Sensitive()->NeedsConversion()) |
7fd59977 |
145 | { |
197ac94e |
146 | Handle(Select3D_SensitiveEntity) aSE = *((Handle(Select3D_SensitiveEntity)*) &(theSel->Sensitive())); |
147 | aSE->Project (myProjector); |
148 | if (!tosort) |
149 | { |
150 | tosort = Standard_True; |
151 | } |
7fd59977 |
152 | } |
153 | } |
154 | } |
155 | |
197ac94e |
156 | //======================================================================= |
7fd59977 |
157 | // Function: Set |
158 | // Purpose : |
197ac94e |
159 | //======================================================================= |
160 | void StdSelect_ViewerSelector3d::Set (const Handle(Select3D_Projector)& theProj) |
7fd59977 |
161 | { |
197ac94e |
162 | myProjector = theProj; |
163 | toupdate = Standard_True; |
7fd59977 |
164 | } |
165 | |
197ac94e |
166 | //======================================================================= |
3c982548 |
167 | // Function: SetSensitivityMode |
7fd59977 |
168 | // Purpose : |
197ac94e |
169 | //======================================================================= |
170 | void StdSelect_ViewerSelector3d::SetSensitivityMode (const StdSelect_SensitivityMode theMode) |
7fd59977 |
171 | { |
197ac94e |
172 | mySensMode = theMode; |
3c982548 |
173 | toupdate = Standard_True; |
174 | } |
175 | |
197ac94e |
176 | //======================================================================= |
3c982548 |
177 | // Function: SetPixelTolerance |
178 | // Purpose : |
197ac94e |
179 | //======================================================================= |
180 | void StdSelect_ViewerSelector3d::SetPixelTolerance (const Standard_Integer theTolerance) |
3c982548 |
181 | { |
197ac94e |
182 | if (myPixelTolerance != theTolerance) |
3c982548 |
183 | { |
197ac94e |
184 | myPixelTolerance = theTolerance; |
185 | myToUpdateTolerance = Standard_True; |
3c982548 |
186 | } |
7fd59977 |
187 | } |
188 | |
197ac94e |
189 | //======================================================================= |
190 | // Function: Pick |
7fd59977 |
191 | // Purpose : |
197ac94e |
192 | //======================================================================= |
193 | void StdSelect_ViewerSelector3d::Pick (const Standard_Integer theXPix, |
194 | const Standard_Integer theYPix, |
195 | const Handle(V3d_View)& theView) |
7fd59977 |
196 | { |
197ac94e |
197 | SetClipping (theView->GetClipPlanes()); |
198 | UpdateProj (theView); |
679ecdee |
199 | Standard_Real aPnt3d[3]; |
200 | theView->Convert (theXPix, theYPix, |
201 | aPnt3d[0], aPnt3d[1], aPnt3d[2]); |
197ac94e |
202 | |
679ecdee |
203 | gp_Pnt2d aPnt2d; |
204 | myProjector->Project (gp_Pnt (aPnt3d[0], aPnt3d[1], aPnt3d[2]), aPnt2d); |
7fd59977 |
205 | |
679ecdee |
206 | InitSelect (aPnt2d.X(), aPnt2d.Y()); |
197ac94e |
207 | } |
7fd59977 |
208 | |
197ac94e |
209 | //======================================================================= |
210 | // Function: Pick |
7fd59977 |
211 | // Purpose : |
197ac94e |
212 | //======================================================================= |
213 | void StdSelect_ViewerSelector3d::Pick (const Standard_Integer theXPMin, |
214 | const Standard_Integer theYPMin, |
215 | const Standard_Integer theXPMax, |
216 | const Standard_Integer theYPMax, |
217 | const Handle(V3d_View)& theView) |
7fd59977 |
218 | { |
197ac94e |
219 | if (myToUpdateTolerance && SensitivityMode() == StdSelect_SM_WINDOW) |
7fd59977 |
220 | { |
197ac94e |
221 | SetSensitivity (theView->Convert (myPixelTolerance)); |
222 | myToUpdateTolerance = Standard_False; |
7fd59977 |
223 | } |
197ac94e |
224 | |
225 | UpdateProj (theView); |
226 | |
227 | Standard_Real aX1 = 0.0; |
228 | Standard_Real aY1 = 0.0; |
229 | Standard_Real aZ1 = 0.0; |
230 | Standard_Real aX2 = 0.0; |
231 | Standard_Real aY2 = 0.0; |
232 | Standard_Real aZ2 = 0.0; |
233 | gp_Pnt2d aP2d1; |
234 | gp_Pnt2d aP2d2; |
235 | |
236 | theView->Convert (theXPMin, theYPMin, aX1, aY1, aZ1); |
237 | theView->Convert (theXPMax, theYPMax, aX2, aY2, aZ2); |
238 | myProjector->Project (gp_Pnt (aX1, aY1, aZ1), aP2d1); |
239 | myProjector->Project (gp_Pnt (aX2, aY2, aZ2), aP2d2); |
240 | |
241 | InitSelect (Min (aP2d1.X(), aP2d2.X()), |
242 | Min (aP2d1.Y(), aP2d2.Y()), |
243 | Max (aP2d1.X(), aP2d2.X()), |
244 | Max (aP2d1.Y(), aP2d2.Y())); |
7fd59977 |
245 | } |
246 | |
197ac94e |
247 | //======================================================================= |
7fd59977 |
248 | // Function: Pick |
249 | // Purpose : Selection using a polyline |
197ac94e |
250 | //======================================================================= |
251 | void StdSelect_ViewerSelector3d::Pick (const TColgp_Array1OfPnt2d& thePolyline, |
252 | const Handle(V3d_View)& theView) |
7fd59977 |
253 | { |
197ac94e |
254 | if (myToUpdateTolerance && SensitivityMode() == StdSelect_SM_WINDOW) |
7fd59977 |
255 | { |
197ac94e |
256 | SetSensitivity (theView->Convert (myPixelTolerance)); |
257 | myToUpdateTolerance = Standard_False; |
7fd59977 |
258 | } |
259 | |
197ac94e |
260 | UpdateProj (theView); |
7fd59977 |
261 | |
197ac94e |
262 | Standard_Integer aNbPix = thePolyline.Length(); |
7fd59977 |
263 | |
264 | // Convert pixel |
197ac94e |
265 | Handle(TColgp_HArray1OfPnt2d) aP2d = new TColgp_HArray1OfPnt2d (1, aNbPix); |
7fd59977 |
266 | |
197ac94e |
267 | for (Standard_Integer aPntIt = 1; aPntIt <= aNbPix; ++aPntIt) |
7fd59977 |
268 | { |
197ac94e |
269 | Standard_Integer aXP = (Standard_Integer)(thePolyline (aPntIt).X()); |
270 | Standard_Integer aYP = (Standard_Integer)(thePolyline (aPntIt).Y()); |
7fd59977 |
271 | |
197ac94e |
272 | Standard_Real aX = 0.0; |
273 | Standard_Real aY = 0.0; |
274 | Standard_Real aZ = 0.0; |
275 | gp_Pnt2d aPnt2d; |
7fd59977 |
276 | |
197ac94e |
277 | theView->Convert (aXP, aYP, aX, aY, aZ); |
278 | myProjector->Project (gp_Pnt (aX, aY, aZ), aPnt2d); |
279 | |
280 | aP2d->SetValue (aPntIt, aPnt2d); |
7fd59977 |
281 | } |
282 | |
197ac94e |
283 | const TColgp_Array1OfPnt2d& aPolyConvert = aP2d->Array1(); |
7fd59977 |
284 | |
197ac94e |
285 | InitSelect (aPolyConvert); |
7fd59977 |
286 | } |
287 | |
197ac94e |
288 | //======================================================================= |
7fd59977 |
289 | // Function: DisplayAreas |
290 | // Purpose : display the activated areas... |
197ac94e |
291 | //======================================================================= |
292 | void StdSelect_ViewerSelector3d::DisplayAreas (const Handle(V3d_View)& theView) |
7fd59977 |
293 | { |
197ac94e |
294 | if (myToUpdateTolerance && SensitivityMode() == StdSelect_SM_WINDOW) |
7fd59977 |
295 | { |
197ac94e |
296 | SetSensitivity (theView->Convert (myPixelTolerance)); |
297 | myToUpdateTolerance = Standard_False; |
7fd59977 |
298 | } |
197ac94e |
299 | |
300 | UpdateProj (theView); |
7fd59977 |
301 | UpdateSort(); // Updates the activated areas |
302 | |
197ac94e |
303 | if (mystruct.IsNull()) |
304 | { |
305 | mystruct = new Graphic3d_Structure (theView->Viewer()->Viewer()); |
306 | } |
b8ddfc2f |
307 | |
197ac94e |
308 | if (myareagroup.IsNull()) |
309 | { |
310 | myareagroup = new Graphic3d_Group (mystruct); |
311 | } |
7fd59977 |
312 | |
197ac94e |
313 | SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive anIt (myentities); |
314 | Handle(Select3D_Projector) aProjector = StdSelect::GetProjector (theView); |
315 | aProjector->SetView (theView); |
7fd59977 |
316 | |
197ac94e |
317 | Standard_Real aXmin = 0.0; |
318 | Standard_Real aYmin = 0.0; |
319 | Standard_Real aXmax = 0.0; |
320 | Standard_Real aYmax = 0.0; |
321 | gp_Pnt aPbid; |
322 | SelectBasics_ListOfBox2d aBoxList; |
7fd59977 |
323 | |
b8ddfc2f |
324 | TColgp_SequenceOfPnt aSeqLines; |
197ac94e |
325 | for (; anIt.More(); anIt.Next()) |
7fd59977 |
326 | { |
197ac94e |
327 | anIt.Value()->Areas (aBoxList); |
328 | |
329 | for (SelectBasics_ListIteratorOfListOfBox2d aBoxIt (aBoxList); aBoxIt.More(); aBoxIt.Next()) |
7fd59977 |
330 | { |
197ac94e |
331 | aBoxIt.Value().Get (aXmin, aYmin, aXmax, aYmax); |
7fd59977 |
332 | |
197ac94e |
333 | aPbid.SetCoord (aXmin - mytolerance, aYmin - mytolerance, 0.0); |
334 | aProjector->Transform (aPbid, aProjector->InvertedTransformation()); |
335 | aSeqLines.Append (aPbid); |
7fd59977 |
336 | |
197ac94e |
337 | aPbid.SetCoord (aXmax + mytolerance, aYmin - mytolerance, 0.0); |
338 | aProjector->Transform (aPbid, aProjector->InvertedTransformation()); |
339 | aSeqLines.Append (aPbid); |
7fd59977 |
340 | |
197ac94e |
341 | aPbid.SetCoord (aXmax + mytolerance, aYmax + mytolerance, 0.0); |
342 | aProjector->Transform (aPbid, aProjector->InvertedTransformation()); |
343 | aSeqLines.Append (aPbid); |
7fd59977 |
344 | |
197ac94e |
345 | aPbid.SetCoord (aXmin - mytolerance, aYmax + mytolerance, 0.0); |
346 | aProjector->Transform (aPbid, aProjector->InvertedTransformation()); |
347 | aSeqLines.Append (aPbid); |
b8ddfc2f |
348 | } |
349 | } |
7fd59977 |
350 | |
b8ddfc2f |
351 | if (aSeqLines.Length()) |
352 | { |
197ac94e |
353 | Standard_Integer aN = 0; |
354 | Standard_Integer aNp = 0; |
355 | const Standard_Integer aNbl = aSeqLines.Length() / 4; |
356 | |
357 | Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines (5 * aNbl, aNbl); |
358 | for (aNp = 1, aN = 0; aN < aNbl; aN++) |
359 | { |
360 | aPrims->AddBound (5); |
361 | const gp_Pnt &aPnt1 = aSeqLines (aNp++); |
362 | aPrims->AddVertex (aPnt1); |
363 | aPrims->AddVertex (aSeqLines (aNp++)); |
364 | aPrims->AddVertex (aSeqLines (aNp++)); |
365 | aPrims->AddVertex (aSeqLines (aNp++)); |
366 | aPrims->AddVertex (aPnt1); |
7fd59977 |
367 | } |
197ac94e |
368 | myareagroup->AddPrimitiveArray (aPrims); |
7fd59977 |
369 | } |
370 | |
b8ddfc2f |
371 | myareagroup->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_AQUAMARINE1, Aspect_TOL_DASH, 1.0)); |
197ac94e |
372 | myareagroup->Structure()->SetDisplayPriority (10); |
7fd59977 |
373 | myareagroup->Structure()->Display(); |
374 | |
679ecdee |
375 | theView->Update(); |
7fd59977 |
376 | } |
377 | |
197ac94e |
378 | //======================================================================= |
7fd59977 |
379 | // Function: ClearAreas |
380 | // Purpose : |
197ac94e |
381 | //======================================================================= |
382 | void StdSelect_ViewerSelector3d::ClearAreas (const Handle(V3d_View)& theView) |
7fd59977 |
383 | { |
197ac94e |
384 | if (myareagroup.IsNull()) |
385 | { |
386 | return; |
387 | } |
388 | |
7fd59977 |
389 | myareagroup->Clear(); |
197ac94e |
390 | |
679ecdee |
391 | if (!theView.IsNull()) |
197ac94e |
392 | { |
393 | theView->Update(); |
394 | } |
7fd59977 |
395 | } |
396 | |
197ac94e |
397 | //======================================================================= |
398 | // Function: UpdateProj |
399 | // Purpose : |
400 | //======================================================================= |
401 | Standard_Boolean StdSelect_ViewerSelector3d::UpdateProj (const Handle(V3d_View)& theView) |
7fd59977 |
402 | { |
197ac94e |
403 | // Check common properties of camera |
404 | Standard_Real anUp[3]; |
405 | Standard_Real aProj[3]; |
406 | Standard_Real anAxialScale[3]; |
407 | theView->Up (anUp[0], anUp[1], anUp[2]); |
408 | theView->Proj (aProj[0], aProj[1], aProj[2]); |
409 | theView->AxialScale (anAxialScale[0], anAxialScale[1], anAxialScale[2]); |
410 | |
411 | Standard_Boolean isOrthographic = theView->Type() == V3d_ORTHOGRAPHIC; |
412 | Standard_Boolean toUpdateProjector = myPrevOrthographic != isOrthographic |
413 | || myPrevUp[0] != anUp[0] |
414 | || myPrevUp[1] != anUp[1] |
415 | || myPrevUp[2] != anUp[2] |
416 | || myPrevProj[0] != aProj[0] |
417 | || myPrevProj[1] != aProj[1] |
418 | || myPrevProj[2] != aProj[2] |
419 | || myPrevAxialScale[0] != anAxialScale[0] |
420 | || myPrevAxialScale[1] != anAxialScale[1] |
421 | || myPrevAxialScale[2] != anAxialScale[2]; |
422 | |
423 | // Check properties of perspective camera |
424 | Standard_Real anAt[3]; |
425 | Standard_Real aScale = theView->Scale(); |
426 | Standard_Real aFOV = theView->Camera()->FOVy(); |
427 | theView->At (anAt[0], anAt[1], anAt[2]); |
428 | if (!isOrthographic && !toUpdateProjector) |
7fd59977 |
429 | { |
197ac94e |
430 | toUpdateProjector = myPrevAt[0] != anAt[0] |
431 | || myPrevAt[1] != anAt[1] |
432 | || myPrevAt[2] != anAt[2] |
433 | || myPrevScale != aScale |
434 | || myPrevFOV != aFOV; |
7fd59977 |
435 | } |
197ac94e |
436 | |
437 | myToUpdateTolerance = aScale != myPrevScale; |
438 | |
439 | // Update projector if anything changed |
440 | if (toUpdateProjector) |
7fd59977 |
441 | { |
7fd59977 |
442 | toupdate = Standard_True; |
197ac94e |
443 | |
444 | myToUpdateTolerance = Standard_True; |
445 | |
446 | if (isOrthographic) |
7fd59977 |
447 | { |
197ac94e |
448 | // For orthographic view use only direction of projection and up vector |
449 | // Panning, and zooming has no effect on 2D selection sensitives. |
450 | Handle (Graphic3d_Camera) aCamera = new Graphic3d_Camera(); |
451 | |
452 | aCamera->SetProjectionType (Graphic3d_Camera::Projection_Orthographic); |
453 | aCamera->SetCenter (gp::Origin()); |
454 | aCamera->SetDirection (gp_Dir (-aProj[0], -aProj[1], -aProj[2])); |
455 | aCamera->SetUp (gp_Dir (anUp[0], anUp[1], anUp[2])); |
456 | aCamera->SetDistance (1.0); |
457 | aCamera->SetAxialScale (gp_XYZ (anAxialScale[0], anAxialScale[1], anAxialScale[2])); |
458 | |
459 | myProjector = new Select3D_Projector (aCamera->OrientationMatrix(), Graphic3d_Mat4d()); |
7fd59977 |
460 | } |
197ac94e |
461 | else |
7fd59977 |
462 | { |
197ac94e |
463 | // For perspective projection panning, zooming and location of view |
464 | // has effect. Thus, use current view and projection matrices from |
465 | // view camera. Exception is that the projection transformation |
466 | // is scaled from NDC to size of displaying frame of view space in order |
467 | // to maintain consistence with pixel tolerance conversion. |
468 | const Graphic3d_Mat4d& aMVMatrix = theView->Camera()->OrientationMatrix(); |
469 | const Graphic3d_Mat4d& aProjMatrix = theView->Camera()->ProjectionMatrix(); |
470 | gp_XYZ aViewDimensions = theView->Camera()->ViewDimensions(); |
471 | |
472 | Graphic3d_Mat4d aScaledProj; |
473 | aScaledProj.ChangeValue (0, 0) = aViewDimensions.X(); |
474 | aScaledProj.ChangeValue (1, 1) = aViewDimensions.Y(); |
475 | aScaledProj.ChangeValue (2, 2) = aViewDimensions.Z(); |
476 | Graphic3d_Mat4d aScaledProjMatrix = aScaledProj * aProjMatrix; |
477 | |
478 | myProjector = new Select3D_Projector (aMVMatrix, aScaledProjMatrix); |
7fd59977 |
479 | } |
7fd59977 |
480 | } |
481 | |
197ac94e |
482 | myPrevAt[0] = anAt[0]; |
483 | myPrevAt[1] = anAt[1]; |
484 | myPrevAt[2] = anAt[2]; |
485 | myPrevUp[0] = anUp[0]; |
486 | myPrevUp[1] = anUp[1]; |
487 | myPrevUp[2] = anUp[2]; |
488 | myPrevProj[0] = aProj[0]; |
489 | myPrevProj[1] = aProj[1]; |
490 | myPrevProj[2] = aProj[2]; |
491 | myPrevAxialScale[0] = anAxialScale[0]; |
492 | myPrevAxialScale[1] = anAxialScale[1]; |
493 | myPrevAxialScale[2] = anAxialScale[2]; |
494 | myPrevFOV = aFOV; |
495 | myPrevScale = aScale; |
496 | myPrevOrthographic = isOrthographic; |
497 | |
498 | if (myToUpdateTolerance && SensitivityMode() == StdSelect_SM_WINDOW) |
7fd59977 |
499 | { |
197ac94e |
500 | SetSensitivity (theView->Convert (myPixelTolerance)); |
501 | myToUpdateTolerance = Standard_False; |
7fd59977 |
502 | } |
503 | |
197ac94e |
504 | if (toupdate) |
7fd59977 |
505 | { |
197ac94e |
506 | UpdateConversion(); |
7fd59977 |
507 | } |
508 | |
197ac94e |
509 | if (tosort) |
510 | { |
511 | UpdateSort(); |
512 | } |
7fd59977 |
513 | |
514 | return Standard_True; |
515 | } |
516 | |
517 | |
197ac94e |
518 | //======================================================================= |
7fd59977 |
519 | // Function: DisplaySensitive. |
520 | // Purpose : Display active primitives. |
197ac94e |
521 | //======================================================================= |
522 | void StdSelect_ViewerSelector3d::DisplaySensitive (const Handle(V3d_View)& theView) |
7fd59977 |
523 | { |
197ac94e |
524 | if (myToUpdateTolerance && SensitivityMode() == StdSelect_SM_WINDOW) |
525 | { |
526 | SetSensitivity (theView->Convert (myPixelTolerance)); |
527 | myToUpdateTolerance = Standard_False; |
528 | } |
529 | |
530 | if (toupdate) |
531 | { |
532 | UpdateProj (theView); |
533 | } |
534 | |
535 | if (tosort) |
7fd59977 |
536 | { |
197ac94e |
537 | UpdateSort(); // Updates the activated areas |
7fd59977 |
538 | } |
7fd59977 |
539 | |
540 | // Preparation des structures |
197ac94e |
541 | if (mystruct.IsNull()) |
542 | { |
543 | mystruct = new Graphic3d_Structure (theView->Viewer()->Viewer()); |
544 | } |
545 | |
546 | if (mysensgroup.IsNull()) |
547 | { |
548 | mysensgroup = new Graphic3d_Group (mystruct); |
549 | } |
7fd59977 |
550 | |
197ac94e |
551 | Quantity_Color aColor (Quantity_NOC_INDIANRED3); |
552 | Handle(Graphic3d_AspectMarker3d) aMarkerAspect = |
553 | new Graphic3d_AspectMarker3d (Aspect_TOM_O_PLUS, aColor, 2.0); |
7fd59977 |
554 | |
197ac94e |
555 | mysensgroup->SetPrimitivesAspect (aMarkerAspect); |
7fd59977 |
556 | mysensgroup->SetPrimitivesAspect ( |
557 | new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0)); |
558 | |
197ac94e |
559 | SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation anIt (myselections); |
7fd59977 |
560 | |
197ac94e |
561 | for (; anIt.More(); anIt.Next()) |
7fd59977 |
562 | { |
197ac94e |
563 | if (anIt.Value()==0) |
7fd59977 |
564 | { |
197ac94e |
565 | const Handle(SelectMgr_Selection)& aSel = anIt.Key(); |
566 | ComputeSensitivePrs (aSel); |
7fd59977 |
567 | } |
568 | } |
7fd59977 |
569 | |
197ac94e |
570 | mysensgroup->Structure()->SetDisplayPriority (10); |
7fd59977 |
571 | mystruct->Display(); |
197ac94e |
572 | |
679ecdee |
573 | theView->Update(); |
7fd59977 |
574 | } |
575 | |
197ac94e |
576 | //======================================================================= |
7fd59977 |
577 | // Function: ClearSensitive |
578 | // Purpose : |
197ac94e |
579 | //======================================================================= |
580 | void StdSelect_ViewerSelector3d::ClearSensitive (const Handle(V3d_View)& theView) |
7fd59977 |
581 | { |
197ac94e |
582 | if (mysensgroup.IsNull()) |
583 | { |
584 | return; |
585 | } |
586 | |
7fd59977 |
587 | mysensgroup->Clear(); |
7fd59977 |
588 | |
197ac94e |
589 | if (theView.IsNull()) |
590 | { |
591 | return; |
592 | } |
593 | |
679ecdee |
594 | theView->Update(); |
7fd59977 |
595 | } |
596 | |
597 | //======================================================================= |
598 | //function : DisplaySenstive |
599 | //purpose : |
600 | //======================================================================= |
197ac94e |
601 | void StdSelect_ViewerSelector3d::DisplaySensitive (const Handle(SelectMgr_Selection)& theSel, |
602 | const Handle(V3d_View)& theView, |
603 | const Standard_Boolean theToClearOthers) |
7fd59977 |
604 | { |
605 | if (mystruct.IsNull()) |
197ac94e |
606 | { |
607 | mystruct = new Graphic3d_Structure (theView->Viewer()->Viewer()); |
608 | } |
609 | |
7fd59977 |
610 | if (mysensgroup.IsNull()) |
611 | { |
612 | mysensgroup = new Graphic3d_Group (mystruct); |
197ac94e |
613 | Quantity_Color aColor (Quantity_NOC_INDIANRED3); |
614 | Handle(Graphic3d_AspectMarker3d) aMarkerAspect = |
615 | new Graphic3d_AspectMarker3d (Aspect_TOM_O_PLUS, aColor, 2.0); |
616 | |
617 | mysensgroup-> SetPrimitivesAspect (aMarkerAspect); |
7fd59977 |
618 | mysensgroup->SetPrimitivesAspect ( |
619 | new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0)); |
620 | } |
621 | |
197ac94e |
622 | if (theToClearOthers) |
623 | { |
624 | mysensgroup->Clear(); |
625 | } |
7fd59977 |
626 | |
197ac94e |
627 | ComputeSensitivePrs (theSel); |
7fd59977 |
628 | |
197ac94e |
629 | mystruct->SetDisplayPriority (10); |
7fd59977 |
630 | mystruct->Display(); |
679ecdee |
631 | |
632 | theView->Update(); |
7fd59977 |
633 | } |
634 | |
635 | //======================================================================= |
636 | //function : DisplayAreas |
637 | //purpose : |
638 | //======================================================================= |
197ac94e |
639 | void StdSelect_ViewerSelector3d::DisplayAreas (const Handle(SelectMgr_Selection)& theSel, |
640 | const Handle(V3d_View)& theView, |
641 | const Standard_Boolean theToClearOthers) |
7fd59977 |
642 | { |
643 | if (mystruct.IsNull()) |
197ac94e |
644 | { |
645 | mystruct = new Graphic3d_Structure (theView->Viewer()->Viewer()); |
646 | } |
b8ddfc2f |
647 | |
7fd59977 |
648 | if (mysensgroup.IsNull()) |
649 | { |
650 | myareagroup = new Graphic3d_Group (mystruct); |
197ac94e |
651 | myareagroup->SetGroupPrimitivesAspect ( |
652 | new Graphic3d_AspectLine3d (Quantity_NOC_AQUAMARINE1, Aspect_TOL_DASH, 1.0)); |
7fd59977 |
653 | } |
654 | |
197ac94e |
655 | if (theToClearOthers) |
656 | { |
657 | myareagroup->Clear(); |
658 | } |
7fd59977 |
659 | |
197ac94e |
660 | ComputeAreasPrs (theSel); |
7fd59977 |
661 | |
197ac94e |
662 | mystruct->SetDisplayPriority (10); |
7fd59977 |
663 | mystruct->Display(); |
664 | |
679ecdee |
665 | theView->Update(); |
7fd59977 |
666 | } |
667 | |
668 | //======================================================================= |
669 | //function : ComputeSensitivePrs |
670 | //purpose : |
671 | //======================================================================= |
197ac94e |
672 | void StdSelect_ViewerSelector3d::ComputeSensitivePrs (const Handle(SelectMgr_Selection)& theSel) |
7fd59977 |
673 | { |
b8ddfc2f |
674 | TColgp_SequenceOfPnt aSeqLines, aSeqFree; |
675 | TColStd_SequenceOfInteger aSeqBnds; |
676 | |
197ac94e |
677 | for (theSel->Init(); theSel->More(); theSel->Next()) |
7fd59977 |
678 | { |
197ac94e |
679 | Handle(Select3D_SensitiveEntity) Ent = Handle(Select3D_SensitiveEntity)::DownCast(theSel->Sensitive()); |
b8ddfc2f |
680 | const Standard_Boolean hasloc = (Ent.IsNull()? Standard_False : Ent->HasLocation()); |
7fd59977 |
681 | |
682 | TopLoc_Location theloc; |
683 | if(hasloc) |
684 | theloc = Ent->Location(); |
685 | |
686 | //============== |
687 | // Box |
688 | //============= |
689 | |
690 | if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveBox)) |
691 | { |
692 | const Bnd_Box& B = Handle(Select3D_SensitiveBox)::DownCast (Ent)->Box(); |
693 | Standard_Real xmin, ymin, zmin, xmax, ymax, zmax; |
694 | B.Get (xmin, ymin, zmin, xmax, ymax, zmax); |
b8ddfc2f |
695 | Standard_Integer i; |
7fd59977 |
696 | gp_Pnt theboxpoint[8] = |
697 | { |
698 | gp_Pnt(xmin,ymin,zmin), |
699 | gp_Pnt(xmax,ymin,zmin), |
700 | gp_Pnt(xmax,ymax,zmin), |
701 | gp_Pnt(xmin,ymax,zmin), |
702 | gp_Pnt(xmin,ymin,zmax), |
703 | gp_Pnt(xmax,ymin,zmax), |
704 | gp_Pnt(xmax,ymax,zmax), |
705 | gp_Pnt(xmin,ymax,zmax) |
706 | }; |
707 | if(hasloc) |
708 | { |
b8ddfc2f |
709 | for (i = 0; i <= 7; i++) |
710 | theboxpoint[i].Transform (theloc.Transformation()); |
7fd59977 |
711 | } |
7fd59977 |
712 | |
b8ddfc2f |
713 | aSeqBnds.Append(5); |
714 | for (i = 0; i < 4; i++) |
715 | aSeqLines.Append(theboxpoint[i]); |
716 | aSeqLines.Append(theboxpoint[0]); |
717 | |
718 | aSeqBnds.Append(5); |
719 | for (i = 4; i < 8; i++) |
720 | aSeqLines.Append(theboxpoint[i]); |
721 | aSeqLines.Append(theboxpoint[4]); |
7fd59977 |
722 | |
b8ddfc2f |
723 | for (i = 0; i < 4; i++) |
7fd59977 |
724 | { |
b8ddfc2f |
725 | aSeqBnds.Append(2); |
726 | aSeqLines.Append(theboxpoint[i]); |
727 | aSeqLines.Append(theboxpoint[i+4]); |
7fd59977 |
728 | } |
729 | } |
730 | //============== |
731 | // Face |
732 | //============= |
733 | else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveFace)) |
734 | { |
735 | Handle(Select3D_SensitiveFace) aFace = Handle(Select3D_SensitiveFace)::DownCast(Ent); |
736 | Handle(TColgp_HArray1OfPnt) TheHPts; |
737 | aFace->Points3D(TheHPts); |
738 | const TColgp_Array1OfPnt& ThePts = TheHPts->Array1(); |
739 | |
b8ddfc2f |
740 | aSeqBnds.Append(ThePts.Length()); |
7fd59977 |
741 | for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++) |
742 | { |
743 | if (hasloc) |
b8ddfc2f |
744 | aSeqLines.Append(ThePts(I).Transformed (theloc.Transformation())); |
7fd59977 |
745 | else |
b8ddfc2f |
746 | aSeqLines.Append(ThePts(I)); |
7fd59977 |
747 | } |
7fd59977 |
748 | } |
749 | //============== |
750 | // Curve |
751 | //============= |
752 | else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCurve)) |
753 | { |
754 | Handle(Select3D_SensitiveCurve) aCurve = Handle(Select3D_SensitiveCurve)::DownCast(Ent); |
755 | Handle(TColgp_HArray1OfPnt) TheHPts; |
756 | aCurve->Points3D(TheHPts); |
757 | const TColgp_Array1OfPnt& ThePts = TheHPts->Array1(); |
758 | |
b8ddfc2f |
759 | aSeqBnds.Append(ThePts.Length()); |
7fd59977 |
760 | for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++) |
761 | { |
762 | if (hasloc) |
b8ddfc2f |
763 | aSeqLines.Append(ThePts(I).Transformed (theloc.Transformation())); |
7fd59977 |
764 | else |
b8ddfc2f |
765 | aSeqLines.Append(ThePts(I)); |
7fd59977 |
766 | } |
7fd59977 |
767 | } |
768 | //============== |
769 | // Wire |
770 | //============= |
771 | else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveWire)) |
772 | { |
b8ddfc2f |
773 | Handle(Select3D_SensitiveWire) aWire = Handle(Select3D_SensitiveWire)::DownCast(Ent); |
774 | Select3D_SensitiveEntitySequence EntitySeq; |
775 | aWire->GetEdges (EntitySeq); |
7fd59977 |
776 | |
777 | for (int i = 1; i <= EntitySeq.Length(); i++) |
778 | { |
779 | Handle(Select3D_SensitiveEntity) SubEnt = Handle(Select3D_SensitiveEntity)::DownCast(EntitySeq.Value(i)); |
780 | |
781 | //Segment |
782 | if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveSegment)) |
783 | { |
7fd59977 |
784 | gp_Pnt P1 (Handle(Select3D_SensitiveSegment)::DownCast(SubEnt)->StartPoint().XYZ()); |
785 | gp_Pnt P2 (Handle(Select3D_SensitiveSegment)::DownCast(SubEnt)->EndPoint().XYZ()); |
786 | if (hasloc) |
787 | { |
788 | P1.Transform(theloc.Transformation()); |
789 | P2.Transform(theloc.Transformation()); |
790 | } |
b8ddfc2f |
791 | aSeqBnds.Append(2); |
792 | aSeqLines.Append(P1); |
793 | aSeqLines.Append(P2); |
7fd59977 |
794 | } |
795 | |
796 | //circle |
797 | if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCircle)) |
798 | { |
799 | Handle(Select3D_SensitiveCircle) C = Handle(Select3D_SensitiveCircle)::DownCast(SubEnt); |
800 | Standard_Integer Lo, Up; |
801 | C->ArrayBounds (Lo, Up); |
802 | Standard_Integer II = Lo; |
803 | while (II <= Up - 2) |
804 | { |
7fd59977 |
805 | gp_Pnt ThePts[3] = |
806 | { |
807 | gp_Pnt (C->GetPoint3d (II).XYZ()), |
808 | gp_Pnt (C->GetPoint3d (++II).XYZ()), |
809 | gp_Pnt (C->GetPoint3d (++II).XYZ()) |
810 | }; |
811 | |
812 | if (hasloc) |
813 | { |
814 | for (Standard_Integer jj = 0; jj <= 2; jj++) |
815 | ThePts[jj].Transform (theloc.Transformation()); |
816 | } |
817 | |
b8ddfc2f |
818 | aSeqBnds.Append(4); |
819 | aSeqLines.Append(ThePts[0]); |
820 | aSeqLines.Append(ThePts[1]); |
821 | aSeqLines.Append(ThePts[2]); |
822 | aSeqLines.Append(ThePts[0]); |
7fd59977 |
823 | } |
824 | } |
825 | |
826 | //curve |
827 | if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCurve)) |
828 | { |
829 | Handle(Select3D_SensitiveCurve) aCurve = Handle(Select3D_SensitiveCurve)::DownCast(SubEnt); |
830 | Handle(TColgp_HArray1OfPnt) TheHPts; |
831 | aCurve->Points3D (TheHPts); |
832 | const TColgp_Array1OfPnt& ThePts = TheHPts->Array1(); |
b8ddfc2f |
833 | |
834 | aSeqBnds.Append(ThePts.Length()); |
7fd59977 |
835 | for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++) |
836 | { |
837 | if (hasloc) |
b8ddfc2f |
838 | aSeqLines.Append(ThePts(I).Transformed (theloc.Transformation())); |
7fd59977 |
839 | else |
b8ddfc2f |
840 | aSeqLines.Append(ThePts(I)); |
7fd59977 |
841 | } |
7fd59977 |
842 | } |
843 | } |
844 | } |
845 | //============== |
846 | // Segment |
847 | //============= |
848 | else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveSegment)) |
849 | { |
7fd59977 |
850 | gp_Pnt P1 (Handle(Select3D_SensitiveSegment)::DownCast(Ent)->StartPoint().XYZ()); |
851 | gp_Pnt P2 (Handle(Select3D_SensitiveSegment)::DownCast(Ent)->EndPoint().XYZ()); |
852 | if (hasloc) |
853 | { |
854 | P1.Transform (theloc.Transformation()); |
855 | P2.Transform (theloc.Transformation()); |
856 | } |
b8ddfc2f |
857 | aSeqBnds.Append(2); |
858 | aSeqLines.Append(P1); |
859 | aSeqLines.Append(P2); |
7fd59977 |
860 | } |
861 | //============== |
862 | // Circle |
863 | //============= |
864 | else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCircle)) |
865 | { |
866 | Handle(Select3D_SensitiveCircle) C = Handle(Select3D_SensitiveCircle)::DownCast(Ent); |
867 | Standard_Integer Lo, Up; |
868 | C->ArrayBounds (Lo, Up); |
869 | Standard_Integer II = Lo; |
870 | while (II <= Up - 2) |
871 | { |
7fd59977 |
872 | gp_Pnt ThePts[3] = |
873 | { |
874 | gp_Pnt (C->GetPoint3d (II).XYZ()), |
875 | gp_Pnt (C->GetPoint3d (++II).XYZ()), |
876 | gp_Pnt (C->GetPoint3d (++II).XYZ()) |
877 | }; |
878 | |
879 | if (hasloc) |
880 | { |
881 | for (Standard_Integer jj = 0; jj <= 2; jj++) |
882 | ThePts[jj].Transform (theloc.Transformation()); |
883 | } |
884 | |
b8ddfc2f |
885 | aSeqBnds.Append(4); |
886 | aSeqLines.Append(ThePts[0]); |
887 | aSeqLines.Append(ThePts[1]); |
888 | aSeqLines.Append(ThePts[2]); |
889 | aSeqLines.Append(ThePts[0]); |
7fd59977 |
890 | } |
891 | } |
892 | //============== |
893 | // Point |
894 | //============= |
895 | else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitivePoint)) |
896 | { |
897 | gp_Pnt P = hasloc ? |
898 | Handle(Select3D_SensitivePoint)::DownCast(Ent)->Point() : |
899 | Handle(Select3D_SensitivePoint)::DownCast(Ent)->Point().Transformed (theloc.Transformation()); |
a577aaab |
900 | Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints = new Graphic3d_ArrayOfPoints (1); |
901 | anArrayOfPoints->AddVertex (P.X(), P.Y(), P.Z()); |
902 | mysensgroup->AddPrimitiveArray (anArrayOfPoints); |
7fd59977 |
903 | } |
904 | //============================================================ |
905 | // Triangulation : On met un petit offset ves l'interieur... |
906 | //========================================================== |
907 | else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveTriangulation)) |
908 | { |
909 | const Handle(Poly_Triangulation)& PT = |
910 | (*((Handle(Select3D_SensitiveTriangulation)*) &Ent))->Triangulation(); |
911 | |
912 | const Poly_Array1OfTriangle& triangles = PT->Triangles(); |
913 | const TColgp_Array1OfPnt& Nodes = PT->Nodes(); |
7fd59977 |
914 | Standard_Integer n[3]; |
7fd59977 |
915 | |
916 | TopLoc_Location iloc, bidloc; |
917 | if ((*((Handle(Select3D_SensitiveTriangulation)*) &Ent))->HasInitLocation()) |
918 | bidloc = (*((Handle(Select3D_SensitiveTriangulation)*) &Ent))->GetInitLocation(); |
919 | |
920 | if (bidloc.IsIdentity()) |
921 | iloc = theloc; |
922 | else |
923 | iloc = theloc * bidloc; |
924 | |
925 | Standard_Integer i; |
926 | for (i = 1; i <= PT->NbTriangles(); i++) |
927 | { |
928 | triangles (i).Get (n[0], n[1], n[2]); |
929 | gp_Pnt P1 (Nodes (n[0]).Transformed (iloc)); |
930 | gp_Pnt P2 (Nodes (n[1]).Transformed (iloc)); |
931 | gp_Pnt P3 (Nodes (n[2]).Transformed (iloc)); |
932 | gp_XYZ V1 (P1.XYZ()); |
933 | gp_XYZ V2 (P2.XYZ()); |
934 | gp_XYZ V3 (P3.XYZ()); |
935 | gp_XYZ CDG (P1.XYZ()); CDG += (P2.XYZ()); CDG += (P3.XYZ()); CDG /= 3.0; |
7fd59977 |
936 | V1 -= CDG; V2 -= CDG; V3 -= CDG; |
7fd59977 |
937 | V1 *= 0.9; V2 *= 0.9; V3 *= 0.9; |
938 | V1 += CDG; V2 += CDG; V3 += CDG; |
b8ddfc2f |
939 | |
940 | aSeqBnds.Append(4); |
941 | aSeqLines.Append(gp_Pnt(V1)); |
942 | aSeqLines.Append(gp_Pnt(V2)); |
943 | aSeqLines.Append(gp_Pnt(V3)); |
944 | aSeqLines.Append(gp_Pnt(V1)); |
7fd59977 |
945 | } |
946 | |
947 | // recherche des bords libres... |
948 | |
949 | Handle(TColStd_HArray1OfInteger) FreeEdges = new TColStd_HArray1OfInteger (1, 2 * StdSel_NumberOfFreeEdges (PT)); |
950 | TColStd_Array1OfInteger& FreeE = FreeEdges->ChangeArray1(); |
951 | Poly_Connect pc (PT); |
952 | Standard_Integer t[3]; |
953 | Standard_Integer j; |
954 | Standard_Integer fr (1); |
955 | for (i = 1; i <= PT->NbTriangles(); i++) |
956 | { |
957 | pc.Triangles (i, t[0], t[1], t[2]); |
958 | triangles (i).Get (n[0], n[1], n[2]); |
959 | for (j = 0; j < 3; j++) |
960 | { |
961 | Standard_Integer k = (j + 1) % 3; |
962 | if (t[j] == 0) |
963 | { |
964 | FreeE (fr) = n[j]; |
965 | FreeE (fr + 1)= n[k]; |
966 | fr += 2; |
967 | } |
968 | } |
969 | } |
7fd59977 |
970 | for (Standard_Integer ifri = 1; ifri <= FreeE.Length(); ifri += 2) |
971 | { |
b8ddfc2f |
972 | gp_Pnt pe1 (Nodes (FreeE (ifri)).Transformed (iloc)), pe2 (Nodes (FreeE (ifri + 1)).Transformed (iloc)); |
973 | aSeqFree.Append(pe1); |
974 | aSeqFree.Append(pe2); |
7fd59977 |
975 | } |
7fd59977 |
976 | } |
977 | else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveTriangle)) |
978 | { |
979 | Handle(Select3D_SensitiveTriangle) Str = Handle(Select3D_SensitiveTriangle)::DownCast(Ent); |
b8ddfc2f |
980 | gp_Pnt P1, P2, P3; |
7fd59977 |
981 | Str->Points3D (P1, P2, P3); |
b8ddfc2f |
982 | gp_Pnt CDG = Str->Center3D(); |
7fd59977 |
983 | |
984 | gp_XYZ V1 (P1.XYZ()); V1 -= (CDG.XYZ()); |
985 | gp_XYZ V2 (P2.XYZ()); V2 -= (CDG.XYZ()); |
986 | gp_XYZ V3 (P3.XYZ()); V3 -= (CDG.XYZ()); |
7fd59977 |
987 | V1 *= 0.9; V2 *= 0.9; V3 *= 0.9; |
988 | V1 += CDG.XYZ(); V2 += CDG.XYZ(); V3 += CDG.XYZ(); |
b8ddfc2f |
989 | |
990 | aSeqBnds.Append(4); |
991 | aSeqLines.Append(gp_Pnt(V1)); |
992 | aSeqLines.Append(gp_Pnt(V2)); |
993 | aSeqLines.Append(gp_Pnt(V3)); |
994 | aSeqLines.Append(gp_Pnt(V1)); |
7fd59977 |
995 | } |
996 | } |
b8ddfc2f |
997 | |
998 | Standard_Integer i; |
999 | |
1000 | if (aSeqLines.Length()) |
1001 | { |
1002 | Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(aSeqLines.Length(),aSeqBnds.Length()); |
1003 | for (i = 1; i <= aSeqLines.Length(); i++) |
1004 | aPrims->AddVertex(aSeqLines(i)); |
1005 | for (i = 1; i <= aSeqBnds.Length(); i++) |
1006 | aPrims->AddBound(aSeqBnds(i)); |
1007 | myareagroup->AddPrimitiveArray(aPrims); |
1008 | } |
1009 | |
1010 | if (aSeqFree.Length()) |
1011 | { |
1012 | mysensgroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_GREEN, Aspect_TOL_SOLID, 2.0)); |
1013 | Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(aSeqFree.Length(),aSeqFree.Length()/2); |
1014 | for (i = 1; i <= aSeqFree.Length(); i++) |
197ac94e |
1015 | { |
b8ddfc2f |
1016 | aPrims->AddBound(2); |
1017 | aPrims->AddVertex(aSeqLines(i++)); |
1018 | aPrims->AddVertex(aSeqLines(i)); |
197ac94e |
1019 | } |
b8ddfc2f |
1020 | mysensgroup->AddPrimitiveArray(aPrims); |
1021 | mysensgroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0)); |
1022 | } |
7fd59977 |
1023 | } |
1024 | |
1025 | //======================================================================= |
1026 | //function : ComputeAreaPrs |
1027 | //purpose : |
1028 | //======================================================================= |
197ac94e |
1029 | void StdSelect_ViewerSelector3d::ComputeAreasPrs (const Handle(SelectMgr_Selection)& theSel) |
7fd59977 |
1030 | { |
197ac94e |
1031 | Standard_Real aXmin = 0.0; |
1032 | Standard_Real aYmin = 0.0; |
1033 | Standard_Real aXmax = 0.0; |
1034 | Standard_Real aYmax = 0.0; |
1035 | |
1036 | gp_Pnt aPbid; |
1037 | SelectBasics_ListOfBox2d aBoxList; |
7fd59977 |
1038 | |
b8ddfc2f |
1039 | TColgp_SequenceOfPnt aSeqLines; |
197ac94e |
1040 | for (theSel->Init(); theSel->More(); theSel->Next()) |
7fd59977 |
1041 | { |
197ac94e |
1042 | theSel->Sensitive()->Areas (aBoxList); |
1043 | for (SelectBasics_ListIteratorOfListOfBox2d aBoxIt (aBoxList); aBoxIt.More(); aBoxIt.Next()) |
7fd59977 |
1044 | { |
197ac94e |
1045 | aBoxIt.Value().Get (aXmin, aYmin, aXmax, aYmax); |
7fd59977 |
1046 | |
197ac94e |
1047 | aPbid.SetCoord (aXmin - mytolerance, aYmin - mytolerance, 0.0); |
1048 | myProjector->Transform (aPbid, myProjector->InvertedTransformation()); |
1049 | aSeqLines.Append (aPbid); |
7fd59977 |
1050 | |
197ac94e |
1051 | aPbid.SetCoord (aXmax + mytolerance, aYmin - mytolerance, 0.0); |
1052 | myProjector->Transform (aPbid, myProjector->InvertedTransformation()); |
1053 | aSeqLines.Append (aPbid); |
7fd59977 |
1054 | |
197ac94e |
1055 | aPbid.SetCoord (aXmax + mytolerance, aYmax + mytolerance, 0.0); |
1056 | myProjector->Transform (aPbid, myProjector->InvertedTransformation()); |
1057 | aSeqLines.Append (aPbid); |
7fd59977 |
1058 | |
197ac94e |
1059 | aPbid.SetCoord (aXmin - mytolerance, aYmax + mytolerance, 0.0); |
1060 | myProjector->Transform (aPbid, myProjector->InvertedTransformation()); |
1061 | aSeqLines.Append (aPbid); |
b8ddfc2f |
1062 | } |
1063 | } |
7fd59977 |
1064 | |
b8ddfc2f |
1065 | if (aSeqLines.Length()) |
1066 | { |
197ac94e |
1067 | Standard_Integer aN = 0; |
1068 | Standard_Integer aNP = 0; |
1069 | const Standard_Integer aNBL = aSeqLines.Length() / 4; |
1070 | Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines (5 * aNBL, aNBL); |
1071 | for (aNP = 1, aN = 0; aN < aNBL; aN++) |
1072 | { |
1073 | aPrims->AddBound (5); |
1074 | const gp_Pnt &aP1 = aSeqLines (aNP++); |
1075 | aPrims->AddVertex (aP1); |
1076 | aPrims->AddVertex (aSeqLines (aNP++)); |
1077 | aPrims->AddVertex (aSeqLines (aNP++)); |
1078 | aPrims->AddVertex (aSeqLines (aNP++)); |
1079 | aPrims->AddVertex (aP1); |
7fd59977 |
1080 | } |
197ac94e |
1081 | myareagroup->AddPrimitiveArray (aPrims); |
7fd59977 |
1082 | } |
1083 | } |
1084 | |
1085 | //======================================================================= |
4269bd1b |
1086 | //function : SetClipping |
7fd59977 |
1087 | //purpose : |
1088 | //======================================================================= |
51b10cd4 |
1089 | void StdSelect_ViewerSelector3d::SetClipping (const Graphic3d_SequenceOfHClipPlane& thePlanes) |
7fd59977 |
1090 | { |
4269bd1b |
1091 | myClipPlanes = thePlanes; |
1092 | } |
1093 | |
1094 | //======================================================================= |
1095 | //function : ComputeClipRange |
1096 | //purpose : |
1097 | //======================================================================= |
51b10cd4 |
1098 | void StdSelect_ViewerSelector3d::ComputeClipRange (const Graphic3d_SequenceOfHClipPlane& thePlanes, |
4269bd1b |
1099 | const gp_Lin& thePickLine, |
1100 | Standard_Real& theDepthMin, |
1101 | Standard_Real& theDepthMax) const |
1102 | { |
1103 | theDepthMin = RealFirst(); |
1104 | theDepthMax = RealLast(); |
1105 | Standard_Real aPlaneA, aPlaneB, aPlaneC, aPlaneD; |
1106 | |
51b10cd4 |
1107 | Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (thePlanes); |
4269bd1b |
1108 | for (; aPlaneIt.More(); aPlaneIt.Next()) |
7fd59977 |
1109 | { |
4269bd1b |
1110 | const Handle(Graphic3d_ClipPlane)& aClipPlane = aPlaneIt.Value(); |
1111 | if (!aClipPlane->IsOn()) |
1112 | continue; |
1113 | |
1114 | gp_Pln aGeomPlane = aClipPlane->ToPlane(); |
1115 | |
1116 | aGeomPlane.Coefficients (aPlaneA, aPlaneB, aPlaneC, aPlaneD); |
1117 | |
1118 | const gp_Dir& aPlaneDir = aGeomPlane.Axis().Direction(); |
1119 | const gp_Dir& aPickDir = thePickLine.Direction(); |
1120 | const gp_XYZ& aPntOnLine = thePickLine.Location().XYZ(); |
1121 | const gp_XYZ& aPlaneDirXYZ = aPlaneDir.XYZ(); |
1122 | |
1123 | Standard_Real aDotProduct = aPickDir.Dot (aPlaneDir); |
1124 | Standard_Real aDistance = -(aPntOnLine.Dot (aPlaneDirXYZ) + aPlaneD); |
1125 | |
1126 | // check whether the pick line is parallel to clip plane |
1127 | if (Abs (aDotProduct) < Precision::Angular()) |
7fd59977 |
1128 | { |
4269bd1b |
1129 | if (aDistance > 0.0) |
1130 | { |
1131 | // line lies above the plane, thus no selection is possible |
1132 | theDepthMin = 0.0; |
1133 | theDepthMax = 0.0; |
1134 | return; |
1135 | } |
1136 | |
1137 | // line lies below the plane and is not clipped, skip |
1138 | continue; |
1139 | } |
1140 | |
1141 | // compute distance to point of pick line intersection with the plane |
1142 | Standard_Real aIntDist = aDistance / aDotProduct; |
1143 | |
1144 | // change depth limits for case of opposite and directed planes |
1145 | if (aDotProduct < 0.0) |
1146 | { |
1147 | theDepthMax = Min (aIntDist, theDepthMax); |
1148 | } |
1149 | else if (aIntDist > theDepthMin) |
1150 | { |
1151 | theDepthMin = Max (aIntDist, theDepthMin); |
7fd59977 |
1152 | } |
1153 | } |
1154 | } |
4269bd1b |
1155 | |
1156 | //======================================================================= |
1157 | //function : PickingLine |
1158 | //purpose : |
1159 | //======================================================================= |
1160 | gp_Lin StdSelect_ViewerSelector3d::PickingLine(const Standard_Real theX, const Standard_Real theY) const |
1161 | { |
197ac94e |
1162 | return myProjector->Shoot (theX, theY); |
4269bd1b |
1163 | } |
1164 | |
1165 | //======================================================================= |
1166 | //function : DepthClipping |
1167 | //purpose : |
1168 | //======================================================================= |
1169 | void StdSelect_ViewerSelector3d::DepthClipping (const Standard_Real theX, |
1170 | const Standard_Real theY, |
1171 | Standard_Real& theDepthMin, |
1172 | Standard_Real& theDepthMax) const |
1173 | { |
1174 | return ComputeClipRange (myClipPlanes, PickingLine (theX, theY), theDepthMin, theDepthMax); |
1175 | } |
1176 | |
1177 | //======================================================================= |
1178 | //function : DepthClipping |
1179 | //purpose : |
1180 | //======================================================================= |
1181 | void StdSelect_ViewerSelector3d::DepthClipping (const Standard_Real theX, |
1182 | const Standard_Real theY, |
1183 | const Handle(SelectMgr_EntityOwner)& theOwner, |
1184 | Standard_Real& theDepthMin, |
1185 | Standard_Real& theDepthMax) const |
1186 | { |
1187 | return ComputeClipRange (theOwner->Selectable()->GetClipPlanes(), |
1188 | PickingLine (theX, theY), |
1189 | theDepthMin, theDepthMax); |
1190 | } |
1191 | |
1192 | //======================================================================= |
1193 | //function : HasDepthClipping |
1194 | //purpose : |
1195 | //======================================================================= |
1196 | Standard_Boolean StdSelect_ViewerSelector3d::HasDepthClipping (const Handle(SelectMgr_EntityOwner)& theOwner) const |
1197 | { |
1198 | if (!theOwner->HasSelectable()) |
1199 | { |
1200 | return Standard_False; |
1201 | } |
1202 | |
1203 | const Handle(SelectMgr_SelectableObject)& aSelectable = theOwner->Selectable(); |
1204 | return (aSelectable->GetClipPlanes().Size() > 0); |
1205 | } |