0023634: Eliminate Polyline and Polygon usage in drawers
[occt.git] / src / StdSelect / StdSelect_ViewerSelector3d.cxx
CommitLineData
b311480e 1// Created on: 1995-03-15
2// Created by: Robert COUBLANC
3// Copyright (c) 1995-1999 Matra Datavision
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
7fd59977 21
22#include <StdSelect_ViewerSelector3d.ixx>
23#include <StdSelect.hxx>
24#include <SelectBasics_SensitiveEntity.hxx>
25#include <Graphic3d_AspectLine3d.hxx>
26#include <gp_Pnt.hxx>
27#include <gp_Lin.hxx>
28#include <gp_Pnt2d.hxx>
29#include <gp_Dir.hxx>
30#include <gp_Ax3.hxx>
31#include <gp_GTrsf.hxx>
32#include <V3d_PerspectiveView.hxx>
4952a30a 33#include <V3d_Plane.hxx>
7fd59977 34#include <Select3D_SensitiveEntity.hxx>
b8ddfc2f 35#include <Graphic3d_ArrayOfPolylines.hxx>
7fd59977 36#include <SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive.hxx>
37#include <SelectBasics_ListOfBox2d.hxx>
38#include <Visual3d_TransientManager.hxx>
39#include <TColgp_HArray1OfPnt.hxx>
40#include <TColgp_Array1OfPnt.hxx>
41#include <TColgp_HArray1OfPnt2d.hxx>
42#include <Select3D_SensitiveCurve.hxx>
43#include <Select3D_SensitiveSegment.hxx>
44#include <Select3D_SensitiveFace.hxx>
45#include <Select3D_SensitiveCircle.hxx>
46#include <Select3D_SensitivePoint.hxx>
47#include <Select3D_SensitiveTriangulation.hxx>
48#include <Select3D_SensitiveTriangle.hxx>
49#include <Select3D_SensitiveWire.hxx>
50#include <Select3D_SensitiveEntitySequence.hxx>
51#include <Select3D_ListOfSensitiveTriangle.hxx>
52#include <Select3D_SensitiveBox.hxx>
53#include <Select3D_ListIteratorOfListOfSensitiveTriangle.hxx>
54
55#include <SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation.hxx>
56#include <Aspect_TypeOfMarker.hxx>
57#include <Graphic3d_AspectMarker3d.hxx>
58#include <SelectBasics_ListIteratorOfListOfBox2d.hxx>
59#include <Poly_Connect.hxx>
60#include <TColStd_HArray1OfInteger.hxx>
61
62#include <Poly_Array1OfTriangle.hxx>
63#include <Poly_Triangulation.hxx>
64#include <OSD_Environment.hxx>
65#include <V3d.hxx>
66#include <V3d_View.hxx>
b8ddfc2f 67#include <TColgp_SequenceOfPnt.hxx>
68
7fd59977 69
70static Standard_Integer StdSel_NumberOfFreeEdges (const Handle(Poly_Triangulation)& Trg)
71{
72 Standard_Integer nFree = 0;
73 Poly_Connect pc(Trg);
74 Standard_Integer t[3];
75 Standard_Integer i, j;
76 for (i = 1; i <= Trg->NbTriangles(); i++)
77 {
78 pc.Triangles (i, t[0], t[1], t[2]);
79 for (j = 0; j < 3; j++)
80 if (t[j] == 0) nFree++;
81 }
82 return nFree;
83}
84
85static Standard_Boolean ReadIsDebugMode()
86{
87 OSD_Environment StdSelectdb ("SELDEBUGMODE");
88 return !StdSelectdb.Value().IsEmpty();
89}
90
91static Standard_Boolean StdSelectDebugModeOn()
92{
93 static const Standard_Boolean isDebugMode = ReadIsDebugMode();
94 return isDebugMode;
95}
96
97//==================================================
98// Function:
99// Purpose :
100//==================================================
101
102StdSelect_ViewerSelector3d
103::StdSelect_ViewerSelector3d():
4952a30a 104myprj(new Select3D_Projector()),
7fd59977 105mylastzoom(0.0),
3c982548 106mysensmode(StdSelect_SM_WINDOW),
7fd59977 107mypixtol(2),
108myupdatetol(Standard_True)
109{
110 for (Standard_Integer i=0;i<=13;i++) {mycoeff [i] = 0.;myprevcoeff[i]=0.0;}
111 for (Standard_Integer j=0;j<2;j++) {mycenter [j] = 0.;myprevcenter[j]=0.0;}
112}
113
114
115//==================================================
116// Function:
117// Purpose :
118//==================================================
119
120StdSelect_ViewerSelector3d
4952a30a 121::StdSelect_ViewerSelector3d(const Handle(Select3D_Projector)& aProj):
7fd59977 122myprj(aProj),
123mylastzoom(0.0),
3c982548 124mysensmode(StdSelect_SM_WINDOW),
7fd59977 125mypixtol(2),
126myupdatetol(Standard_True)
127{
128 for (Standard_Integer i=0;i<=13;i++) {mycoeff [i] = 0.;myprevcoeff[i]=0.0;}
129 for (Standard_Integer j=0;j<2;j++) {mycenter [j] = 0.;myprevcenter[j]=0.0;}
130}
131
132//==================================================
133// Function: Convert
134// Purpose :
135//==================================================
136
137void StdSelect_ViewerSelector3d::Convert(const Handle(SelectMgr_Selection)& aSel)
138{
139 for(aSel->Init();aSel->More();aSel->Next())
140 {
141 if(aSel->Sensitive()->NeedsConversion())
142 {
143 Handle(Select3D_SensitiveEntity) SE = *((Handle(Select3D_SensitiveEntity)*) &(aSel->Sensitive()));
144 SE->Project(myprj);
145 if(!tosort) tosort=Standard_True;
146 }
147 }
148}
149
150//==================================================
151// Function: Set
152// Purpose :
153//==================================================
154
155void StdSelect_ViewerSelector3d
3c982548 156::Set(const Handle(Select3D_Projector)& aProj)
7fd59977 157{
3c982548 158 myprj = aProj;
159 toupdate=Standard_True;
7fd59977 160}
161
162//==================================================
3c982548 163// Function: SetSensitivityMode
7fd59977 164// Purpose :
165//==================================================
166
167void StdSelect_ViewerSelector3d
3c982548 168::SetSensitivityMode(const StdSelect_SensitivityMode aMode)
7fd59977 169{
3c982548 170 mysensmode = aMode;
171 toupdate = Standard_True;
172}
173
174//==================================================
175// Function: SetPixelTolerance
176// Purpose :
177//==================================================
178
179void StdSelect_ViewerSelector3d
180::SetPixelTolerance(const Standard_Integer aTolerance)
181{
182 if(mypixtol!=aTolerance)
183 {
184 mypixtol = aTolerance;
185 myupdatetol = Standard_True;
186 }
7fd59977 187}
188
189//==================================================
190// Function: SelectPix
191// Purpose :
192//==================================================
193
194void StdSelect_ViewerSelector3d
195::Pick(const Standard_Integer XPix,
196 const Standard_Integer YPix,
197 const Handle(V3d_View)& aView)
198{
199 UpdateProj(aView);
200 Standard_Real Xr3d,Yr3d,Zr3d;
201 gp_Pnt2d P2d;
202 aView->Convert(XPix,YPix,Xr3d,Yr3d,Zr3d);
4952a30a 203 myprj->Project(gp_Pnt(Xr3d,Yr3d,Zr3d),P2d);
204
205 // compute depth limits if clipping plane(s) enabled
206 gp_Lin anEyeLine = myprj->Shoot (P2d.X(), P2d.Y());
207 Standard_Real aPlaneA, aPlaneB, aPlaneC, aPlaneD;
208 Standard_Real aDepthFrom = ShortRealFirst();
209 Standard_Real aDepthTo = ShortRealLast();
210 for (aView->InitActivePlanes(); aView->MoreActivePlanes(); aView->NextActivePlanes())
211 {
212 aView->ActivePlane()->Plane (aPlaneA, aPlaneB, aPlaneC, aPlaneD);
213 const gp_Dir& anEyeLineDir = anEyeLine.Direction();
214 gp_Dir aPlaneNormal (aPlaneA, aPlaneB, aPlaneC);
215
216 Standard_Real aDotProduct = anEyeLineDir.Dot (aPlaneNormal);
217 Standard_Real aDirection = -(aPlaneD + anEyeLine.Location().XYZ().Dot (aPlaneNormal.XYZ()));
218 if (Abs (aDotProduct) < Precision::Angular())
219 {
220 // eyeline parallel to the clipping plane
221 if (aDirection > 0.0)
222 {
223 // invalidate the interval
224 aDepthTo = ShortRealFirst();
225 aDepthFrom = ShortRealFirst();
226 break;
227 }
228 // just ignore this plane
229 continue;
230 }
231
232 // compute distance along the eyeline from eyeline location to intersection with clipping plane
233 Standard_Real aDepth = aDirection / aDotProduct;
234
235 // reduce depth limits
236 if (aDotProduct < 0.0)
237 {
238 if (aDepth < aDepthTo)
239 {
240 aDepthTo = aDepth;
241 }
242 }
243 else if (aDepth > aDepthFrom)
244 {
245 aDepthFrom = aDepth;
246 }
247 }
248 myprj->DepthMinMax (aDepthFrom, aDepthTo);
249
7fd59977 250 InitSelect(P2d.X(),P2d.Y());
251}
252
253
254//==================================================
255// Function: InitSelect
256// Purpose :
257//==================================================
258
259void StdSelect_ViewerSelector3d
260::Pick(const Standard_Integer XPMin,
261 const Standard_Integer YPMin,
262 const Standard_Integer XPMax,
263 const Standard_Integer YPMax,
264 const Handle(V3d_View)& aView)
265{
3c982548 266 if (myupdatetol && SensitivityMode() == StdSelect_SM_WINDOW)
7fd59977 267 {
268 SetSensitivity (aView->Convert (mypixtol));
269 myupdatetol = Standard_False;
270 }
271 UpdateProj (aView);
272
273 Standard_Real x1,y1,z1,x2,y2,z2;
274 gp_Pnt2d P2d_1,P2d_2;
275 aView->Convert(XPMin,YPMin,x1,y1,z1);
276 aView->Convert(XPMax,YPMax,x2,y2,z2);
4952a30a 277 myprj->Project(gp_Pnt(x1,y1,z1),P2d_1);
278 myprj->Project(gp_Pnt(x2,y2,z2),P2d_2);
7fd59977 279
280 InitSelect (Min(P2d_1.X(),P2d_2.X()),
281 Min(P2d_1.Y(),P2d_2.Y()),
282 Max(P2d_1.X(),P2d_2.X()),
283 Max(P2d_1.Y(),P2d_2.Y()));
284}
285
286//==================================================
287// Function: Pick
288// Purpose : Selection using a polyline
289//==================================================
290
b8ddfc2f 291void StdSelect_ViewerSelector3d::Pick(const TColgp_Array1OfPnt2d& aPolyline, const Handle(V3d_View)& aView)
7fd59977 292{
3c982548 293 if (myupdatetol && SensitivityMode() == StdSelect_SM_WINDOW)
7fd59977 294 {
295 SetSensitivity (aView->Convert (mypixtol));
296 myupdatetol = Standard_False;
297 }
298
299 UpdateProj (aView);
300
301 Standard_Integer NbPix = aPolyline.Length();
302 Standard_Integer i;
303
304 // Convert pixel
b8ddfc2f 305 Handle(TColgp_HArray1OfPnt2d) P2d = new TColgp_HArray1OfPnt2d(1,NbPix);
7fd59977 306
307 for (i = 1; i <= NbPix; ++i)
308 {
309 Standard_Real x,y,z;
310 Standard_Integer XP = (Standard_Integer)(aPolyline(i).X());
311 Standard_Integer YP = (Standard_Integer)(aPolyline(i).Y());
312 gp_Pnt2d Pnt2d;
313
314 aView->Convert (XP, YP, x, y, z);
4952a30a 315 myprj->Project (gp_Pnt (x, y, z), Pnt2d);
7fd59977 316
317 P2d->SetValue (i, Pnt2d);
318 }
319
320 const TColgp_Array1OfPnt2d& aPolyConvert = P2d->Array1();
321
322 InitSelect(aPolyConvert);
323}
324
325//==================================================
326// Function: DisplayAreas
327// Purpose : display the activated areas...
328//==================================================
329
b8ddfc2f 330void StdSelect_ViewerSelector3d::DisplayAreas(const Handle(V3d_View)& aView)
7fd59977 331{
3c982548 332 if (myupdatetol && SensitivityMode() == StdSelect_SM_WINDOW)
7fd59977 333 {
334 SetSensitivity (aView->Convert (mypixtol));
b8ddfc2f 335 myupdatetol = Standard_False;
7fd59977 336 }
337 UpdateProj(aView);
338 UpdateSort(); // Updates the activated areas
339
340 if(mystruct.IsNull())
7fd59977 341 mystruct = new Graphic3d_Structure(aView->Viewer()->Viewer());
b8ddfc2f 342
7fd59977 343 if(myareagroup.IsNull())
7fd59977 344 myareagroup = new Graphic3d_Group(mystruct);
7fd59977 345
346 SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive It(myentities);
4952a30a 347 Handle(Select3D_Projector) prj = StdSelect::GetProjector(aView);
348 prj->SetView(aView);
7fd59977 349
7fd59977 350 Standard_Real xmin,ymin,xmax,ymax;
351 gp_Pnt Pbid;
352 SelectBasics_ListOfBox2d BoxList;
353
b8ddfc2f 354 TColgp_SequenceOfPnt aSeqLines;
7fd59977 355 for (; It.More(); It.Next())
356 {
357 It.Value()->Areas(BoxList);
358 for (SelectBasics_ListIteratorOfListOfBox2d itb (BoxList); itb.More(); itb.Next())
359 {
360 itb.Value().Get (xmin, ymin, xmax, ymax);
361
362 Pbid.SetCoord (xmin - mytolerance, ymin - mytolerance, 0.0);
4952a30a 363 prj->Transform (Pbid, prj->InvertedTransformation());
b8ddfc2f 364 aSeqLines.Append(Pbid);
7fd59977 365
366 Pbid.SetCoord (xmax + mytolerance, ymin - mytolerance, 0.0);
4952a30a 367 prj->Transform (Pbid, prj->InvertedTransformation());
b8ddfc2f 368 aSeqLines.Append(Pbid);
7fd59977 369
370 Pbid.SetCoord (xmax + mytolerance, ymax + mytolerance, 0.0);
4952a30a 371 prj->Transform (Pbid, prj->InvertedTransformation());
b8ddfc2f 372 aSeqLines.Append(Pbid);
7fd59977 373
374 Pbid.SetCoord (xmin - mytolerance, ymax + mytolerance, 0.0);
4952a30a 375 prj->Transform (Pbid, prj->InvertedTransformation());
b8ddfc2f 376 aSeqLines.Append(Pbid);
377 }
378 }
7fd59977 379
b8ddfc2f 380 if (aSeqLines.Length())
381 {
382 Standard_Integer n, np;
383 const Standard_Integer nbl = aSeqLines.Length() / 4;
384 Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(5*nbl,nbl);
385 for (np = 1, n=0; n<nbl; n++) {
386 aPrims->AddBound(5);
387 const gp_Pnt &p1 = aSeqLines(np++);
388 aPrims->AddVertex(p1);
389 aPrims->AddVertex(aSeqLines(np++));
390 aPrims->AddVertex(aSeqLines(np++));
391 aPrims->AddVertex(aSeqLines(np++));
392 aPrims->AddVertex(p1);
7fd59977 393 }
b8ddfc2f 394 myareagroup->AddPrimitiveArray(aPrims);
7fd59977 395 }
396
b8ddfc2f 397 myareagroup->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_AQUAMARINE1, Aspect_TOL_DASH, 1.0));
7fd59977 398 myareagroup->Structure()->SetDisplayPriority(10);
399 myareagroup->Structure()->Display();
400
401 if(aView->TransientManagerBeginDraw())
402 {
403 Visual3d_TransientManager::DrawStructure(mystruct);
404 Visual3d_TransientManager::EndDraw();
405 }
406 else
407 {
408 aView->Update();
409 }
410}
411
412//==================================================
413// Function: ClearAreas
414// Purpose :
415//==================================================
416
b8ddfc2f 417void StdSelect_ViewerSelector3d::ClearAreas(const Handle(V3d_View)& aView)
7fd59977 418{
419 if(myareagroup.IsNull()) return;
420 myareagroup->Clear();
421 if(aView.IsNull()) return;
422 if(aView->TransientManagerBeginDraw())
423 Visual3d_TransientManager::EndDraw();
424 else
425 aView->Update();
426}
427
428//==================================================
429// Function: updateproj
430// Purpose : at any time verifies that
431// the view coefficients did not change :
432// store current view coeffts
433// in static array cf [ 0->2 At coordinates XAT YAT ZAT
434// 3->5 Up coordinates XUP YUP ZUP
435// 6->8 ProjVect coordinates DX DY DZ
436// 9 focale
437// 10 1. if pers 0. else
438//==================================================
439
b8ddfc2f 440Standard_Boolean StdSelect_ViewerSelector3d::UpdateProj(const Handle(V3d_View)& aView)
7fd59977 441{
442 myprevcoeff[ 9] = 0.0;
443 myprevcoeff[10] = 0.0;
444 Standard_Boolean Pers = Standard_False;
445 if (aView->Type() == V3d_PERSPECTIVE)
446 {
447 Pers = Standard_True;
448 myprevcoeff[10] = 1.0;
449 myprevcoeff[ 9] = aView->Focale();
450 }
451 aView->At (myprevcoeff[0], myprevcoeff[1], myprevcoeff[2]);
452 aView->Up (myprevcoeff[3], myprevcoeff[4], myprevcoeff[5]);
453 aView->Proj (myprevcoeff[6], myprevcoeff[7], myprevcoeff[8]);
454 aView->AxialScale (myprevcoeff[11], myprevcoeff[12], myprevcoeff[13]);
455 aView->Center (myprevcenter[0], myprevcenter[1]);
456 Standard_Integer ii;
457
458 for (ii = 0; ii <= 13 && (myprevcoeff[ii] == mycoeff[ii]); ++ii) {}
459 if (ii <= 13 || (myprevcenter[0] != mycenter[0]) || (myprevcenter[1] != mycenter[1]))
460 {
461 if (StdSelectDebugModeOn())
462 {
463 cout<<"\t\t\t\t\t VS3d::UpdateProj====> coefficients changes on reprojette"<<endl;
464 cout<<"\t\t\t\t\t";
465 for (Standard_Integer i = 1; i <= 9; ++i)
466 {
467 cout<<mycoeff[i-1]<<" ";
468 if (i%3==0)
469 cout<<"\n\t\t\t\t\t";
470 }
471 cout<<"focale :"<<mycoeff[9]<<" persp :"<<mycoeff[10]<<endl;
472 cout<<"center :"<<mycenter[0]<<" "<<mycenter[1]<<endl;
473 }
474 toupdate = Standard_True;
475 myupdatetol = Standard_True;
476 for (Standard_Integer imod = ii; imod <= 13; ++imod)
477 {
478 mycoeff[imod] = myprevcoeff[imod];
479 }
480 for (Standard_Integer jmod = 0; jmod < 2; ++jmod)
481 {
482 mycenter[jmod] = myprevcenter[jmod];
483 }
484
485 gp_Dir Zpers (mycoeff[6], mycoeff[7], mycoeff[8]);
486 gp_Dir Ypers (mycoeff[3], mycoeff[4], mycoeff[5]);
487 gp_Dir Xpers = Ypers.Crossed (Zpers);
488 gp_XYZ loc (mycoeff[0], mycoeff[1], mycoeff[2]);
489 gp_Mat matrix;
490 matrix.SetCols (Xpers.XYZ(), Ypers.XYZ(), Zpers.XYZ());
491 gp_Mat matScale (mycoeff[11], 0, 0, 0, mycoeff[12], 0, 0, 0, mycoeff[13]);
492 matrix.Transpose();
493 loc.Multiply (matrix);
494 loc.Reverse ();
495 matrix.Multiply (matScale);
496 gp_GTrsf GT;
497 GT.SetTranslationPart (loc);
498 GT.SetVectorialPart (matrix);
499
4952a30a 500 myprj = new Select3D_Projector (GT, Pers, mycoeff[9]);
7fd59977 501
502 // SAV 08/05/02 : fix for detection problem in a perspective view
503 if (aView->Type() == V3d_PERSPECTIVE)
4952a30a 504 myprj->SetView (aView);
7fd59977 505 // NKV 31/07/07 : fix for detection problem in case of custom matrix
506 else if (aView->ViewOrientation().IsCustomMatrix())
4952a30a 507 myprj->SetView (aView);
7fd59977 508 }
509
510 if (Abs (aView->Scale() - mylastzoom) > 1.e-3)
511 {
512 myupdatetol = Standard_True;
513 mylastzoom = aView->Scale();
514 }
515
3c982548 516 if (myupdatetol && SensitivityMode() == StdSelect_SM_WINDOW)
7fd59977 517 {
518 SetSensitivity (aView->Convert (mypixtol));
519 myupdatetol = Standard_False;
520 }
521
522 if (toupdate) UpdateConversion();
523 if (tosort) UpdateSort();
524
525 return Standard_True;
526}
527
528
529//=============================
530// Function: DisplaySensitive.
531// Purpose : Display active primitives.
532//=============================
533void StdSelect_ViewerSelector3d::DisplaySensitive(const Handle(V3d_View)& aViou)
534{
3c982548 535 if (myupdatetol && SensitivityMode() == StdSelect_SM_WINDOW)
7fd59977 536 {
537 SetSensitivity (aViou->Convert (mypixtol));
538 myupdatetol = Standard_False;
539 }
540 if(toupdate) UpdateProj(aViou);
541 if(tosort) UpdateSort(); // Updates the activated areas
542
543 // Preparation des structures
544 if(mystruct.IsNull())
545 mystruct = new Graphic3d_Structure(aViou->Viewer()->Viewer());
546
547 if(mysensgroup.IsNull())
548 mysensgroup = new Graphic3d_Group(mystruct);
549
550 Quantity_Color Col(Quantity_NOC_INDIANRED3);
551 Handle(Graphic3d_AspectMarker3d) AM =
552 new Graphic3d_AspectMarker3d(Aspect_TOM_O_PLUS,Col,2.);
553 mysensgroup-> SetPrimitivesAspect (AM);
554 mysensgroup->SetPrimitivesAspect (
555 new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0));
556
557 // Remplissage de la structure...
558
559 SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation It(myselections);
7fd59977 560
7fd59977 561 for (; It.More(); It.Next())
562 {
563 if (It.Value()==0)
564 {
565 const Handle(SelectMgr_Selection)& Sel = It.Key();
566 ComputeSensitivePrs(Sel);
567 }
568 }
7fd59977 569
570 mysensgroup->Structure()->SetDisplayPriority(10);
571 mystruct->Display();
572 if (aViou->TransientManagerBeginDraw())
573 {
574 Visual3d_TransientManager::DrawStructure(mystruct);
575 Visual3d_TransientManager::EndDraw();
576 }
577 else if (!aViou.IsNull())
578 {
579 aViou->Update();
580 }
581}
582
583//=============================
584// Function: ClearSensitive
585// Purpose :
586//=============================
587void StdSelect_ViewerSelector3d::ClearSensitive(const Handle(V3d_View)& aViou)
588{
589 if(mysensgroup.IsNull()) return;
590 mysensgroup->Clear();
591 if(aViou.IsNull()) return;
592
593 if(aViou->TransientManagerBeginDraw())
594 Visual3d_TransientManager::EndDraw();
595 else
596 aViou->Update();
597}
598
599//=======================================================================
600//function : DisplaySenstive
601//purpose :
602//=======================================================================
603void StdSelect_ViewerSelector3d::
604DisplaySensitive (const Handle(SelectMgr_Selection)& Sel,
605 const Handle(V3d_View)& aViou,
606 const Standard_Boolean ClearOthers)
607{
608 if (mystruct.IsNull())
609 mystruct = new Graphic3d_Structure (aViou->Viewer()->Viewer());
610 if (mysensgroup.IsNull())
611 {
612 mysensgroup = new Graphic3d_Group (mystruct);
613 Quantity_Color Col (Quantity_NOC_INDIANRED3);
614 Handle(Graphic3d_AspectMarker3d) AM =
615 new Graphic3d_AspectMarker3d (Aspect_TOM_O_PLUS, Col, 2.0);
616 mysensgroup-> SetPrimitivesAspect (AM);
617 mysensgroup->SetPrimitivesAspect (
618 new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0));
619 }
620
621 if(ClearOthers) mysensgroup->Clear();
622
7fd59977 623 ComputeSensitivePrs(Sel);
624
7fd59977 625 mystruct->SetDisplayPriority(10);
626 mystruct->Display();
627 if(aViou->TransientManagerBeginDraw())
628 {
629 Visual3d_TransientManager::DrawStructure(mystruct);
630 Visual3d_TransientManager::EndDraw();
631 }
632 else if(!aViou.IsNull())
633 {
634 aViou->Update();
635 }
636}
637
638//=======================================================================
639//function : DisplayAreas
640//purpose :
641//=======================================================================
642
643void StdSelect_ViewerSelector3d::
644DisplayAreas (const Handle(SelectMgr_Selection)& Sel,
645 const Handle(V3d_View)& aViou,
646 const Standard_Boolean ClearOthers)
647{
648 if (mystruct.IsNull())
649 mystruct = new Graphic3d_Structure (aViou->Viewer()->Viewer());
b8ddfc2f 650
7fd59977 651 if (mysensgroup.IsNull())
652 {
653 myareagroup = new Graphic3d_Group (mystruct);
b8ddfc2f 654 myareagroup->SetGroupPrimitivesAspect(new Graphic3d_AspectLine3d (Quantity_NOC_AQUAMARINE1, Aspect_TOL_DASH, 1.0));
7fd59977 655 }
656
657 if(ClearOthers) myareagroup->Clear();
658
7fd59977 659 ComputeAreasPrs(Sel);
7fd59977 660
661 mystruct->SetDisplayPriority(10);
662 mystruct->Display();
663
664 if(aViou->TransientManagerBeginDraw())
665 {
666 Visual3d_TransientManager::DrawStructure(mystruct);
667 Visual3d_TransientManager::EndDraw();
668 }
669 else
670 {
671 aViou->Update();
672 }
673}
674
675//=======================================================================
676//function : ComputeSensitivePrs
677//purpose :
678//=======================================================================
679
b8ddfc2f 680void StdSelect_ViewerSelector3d::ComputeSensitivePrs(const Handle(SelectMgr_Selection)& Sel)
7fd59977 681{
b8ddfc2f 682 TColgp_SequenceOfPnt aSeqLines, aSeqFree;
683 TColStd_SequenceOfInteger aSeqBnds;
684
7fd59977 685 for(Sel->Init();Sel->More();Sel->Next())
686 {
b8ddfc2f 687 Handle(Select3D_SensitiveEntity) Ent = Handle(Select3D_SensitiveEntity)::DownCast(Sel->Sensitive());
688 const Standard_Boolean hasloc = (Ent.IsNull()? Standard_False : Ent->HasLocation());
7fd59977 689
690 TopLoc_Location theloc;
691 if(hasloc)
692 theloc = Ent->Location();
693
694 //==============
695 // Box
696 //=============
697
698 if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveBox))
699 {
700 const Bnd_Box& B = Handle(Select3D_SensitiveBox)::DownCast (Ent)->Box();
701 Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
702 B.Get (xmin, ymin, zmin, xmax, ymax, zmax);
b8ddfc2f 703 Standard_Integer i;
7fd59977 704 gp_Pnt theboxpoint[8] =
705 {
706 gp_Pnt(xmin,ymin,zmin),
707 gp_Pnt(xmax,ymin,zmin),
708 gp_Pnt(xmax,ymax,zmin),
709 gp_Pnt(xmin,ymax,zmin),
710 gp_Pnt(xmin,ymin,zmax),
711 gp_Pnt(xmax,ymin,zmax),
712 gp_Pnt(xmax,ymax,zmax),
713 gp_Pnt(xmin,ymax,zmax)
714 };
715 if(hasloc)
716 {
b8ddfc2f 717 for (i = 0; i <= 7; i++)
718 theboxpoint[i].Transform (theloc.Transformation());
7fd59977 719 }
7fd59977 720
b8ddfc2f 721 aSeqBnds.Append(5);
722 for (i = 0; i < 4; i++)
723 aSeqLines.Append(theboxpoint[i]);
724 aSeqLines.Append(theboxpoint[0]);
725
726 aSeqBnds.Append(5);
727 for (i = 4; i < 8; i++)
728 aSeqLines.Append(theboxpoint[i]);
729 aSeqLines.Append(theboxpoint[4]);
7fd59977 730
b8ddfc2f 731 for (i = 0; i < 4; i++)
7fd59977 732 {
b8ddfc2f 733 aSeqBnds.Append(2);
734 aSeqLines.Append(theboxpoint[i]);
735 aSeqLines.Append(theboxpoint[i+4]);
7fd59977 736 }
737 }
738 //==============
739 // Face
740 //=============
741 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveFace))
742 {
743 Handle(Select3D_SensitiveFace) aFace = Handle(Select3D_SensitiveFace)::DownCast(Ent);
744 Handle(TColgp_HArray1OfPnt) TheHPts;
745 aFace->Points3D(TheHPts);
746 const TColgp_Array1OfPnt& ThePts = TheHPts->Array1();
747
b8ddfc2f 748 aSeqBnds.Append(ThePts.Length());
7fd59977 749 for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
750 {
751 if (hasloc)
b8ddfc2f 752 aSeqLines.Append(ThePts(I).Transformed (theloc.Transformation()));
7fd59977 753 else
b8ddfc2f 754 aSeqLines.Append(ThePts(I));
7fd59977 755 }
7fd59977 756 }
757 //==============
758 // Curve
759 //=============
760 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCurve))
761 {
762 Handle(Select3D_SensitiveCurve) aCurve = Handle(Select3D_SensitiveCurve)::DownCast(Ent);
763 Handle(TColgp_HArray1OfPnt) TheHPts;
764 aCurve->Points3D(TheHPts);
765 const TColgp_Array1OfPnt& ThePts = TheHPts->Array1();
766
b8ddfc2f 767 aSeqBnds.Append(ThePts.Length());
7fd59977 768 for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
769 {
770 if (hasloc)
b8ddfc2f 771 aSeqLines.Append(ThePts(I).Transformed (theloc.Transformation()));
7fd59977 772 else
b8ddfc2f 773 aSeqLines.Append(ThePts(I));
7fd59977 774 }
7fd59977 775 }
776 //==============
777 // Wire
778 //=============
779 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveWire))
780 {
b8ddfc2f 781 Handle(Select3D_SensitiveWire) aWire = Handle(Select3D_SensitiveWire)::DownCast(Ent);
782 Select3D_SensitiveEntitySequence EntitySeq;
783 aWire->GetEdges (EntitySeq);
7fd59977 784
785 for (int i = 1; i <= EntitySeq.Length(); i++)
786 {
787 Handle(Select3D_SensitiveEntity) SubEnt = Handle(Select3D_SensitiveEntity)::DownCast(EntitySeq.Value(i));
788
789 //Segment
790 if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveSegment))
791 {
7fd59977 792 gp_Pnt P1 (Handle(Select3D_SensitiveSegment)::DownCast(SubEnt)->StartPoint().XYZ());
793 gp_Pnt P2 (Handle(Select3D_SensitiveSegment)::DownCast(SubEnt)->EndPoint().XYZ());
794 if (hasloc)
795 {
796 P1.Transform(theloc.Transformation());
797 P2.Transform(theloc.Transformation());
798 }
b8ddfc2f 799 aSeqBnds.Append(2);
800 aSeqLines.Append(P1);
801 aSeqLines.Append(P2);
7fd59977 802 }
803
804 //circle
805 if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCircle))
806 {
807 Handle(Select3D_SensitiveCircle) C = Handle(Select3D_SensitiveCircle)::DownCast(SubEnt);
808 Standard_Integer Lo, Up;
809 C->ArrayBounds (Lo, Up);
810 Standard_Integer II = Lo;
811 while (II <= Up - 2)
812 {
7fd59977 813 gp_Pnt ThePts[3] =
814 {
815 gp_Pnt (C->GetPoint3d (II).XYZ()),
816 gp_Pnt (C->GetPoint3d (++II).XYZ()),
817 gp_Pnt (C->GetPoint3d (++II).XYZ())
818 };
819
820 if (hasloc)
821 {
822 for (Standard_Integer jj = 0; jj <= 2; jj++)
823 ThePts[jj].Transform (theloc.Transformation());
824 }
825
b8ddfc2f 826 aSeqBnds.Append(4);
827 aSeqLines.Append(ThePts[0]);
828 aSeqLines.Append(ThePts[1]);
829 aSeqLines.Append(ThePts[2]);
830 aSeqLines.Append(ThePts[0]);
7fd59977 831 }
832 }
833
834 //curve
835 if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCurve))
836 {
837 Handle(Select3D_SensitiveCurve) aCurve = Handle(Select3D_SensitiveCurve)::DownCast(SubEnt);
838 Handle(TColgp_HArray1OfPnt) TheHPts;
839 aCurve->Points3D (TheHPts);
840 const TColgp_Array1OfPnt& ThePts = TheHPts->Array1();
b8ddfc2f 841
842 aSeqBnds.Append(ThePts.Length());
7fd59977 843 for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
844 {
845 if (hasloc)
b8ddfc2f 846 aSeqLines.Append(ThePts(I).Transformed (theloc.Transformation()));
7fd59977 847 else
b8ddfc2f 848 aSeqLines.Append(ThePts(I));
7fd59977 849 }
7fd59977 850 }
851 }
852 }
853 //==============
854 // Segment
855 //=============
856 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveSegment))
857 {
7fd59977 858 gp_Pnt P1 (Handle(Select3D_SensitiveSegment)::DownCast(Ent)->StartPoint().XYZ());
859 gp_Pnt P2 (Handle(Select3D_SensitiveSegment)::DownCast(Ent)->EndPoint().XYZ());
860 if (hasloc)
861 {
862 P1.Transform (theloc.Transformation());
863 P2.Transform (theloc.Transformation());
864 }
b8ddfc2f 865 aSeqBnds.Append(2);
866 aSeqLines.Append(P1);
867 aSeqLines.Append(P2);
7fd59977 868 }
869 //==============
870 // Circle
871 //=============
872 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCircle))
873 {
874 Handle(Select3D_SensitiveCircle) C = Handle(Select3D_SensitiveCircle)::DownCast(Ent);
875 Standard_Integer Lo, Up;
876 C->ArrayBounds (Lo, Up);
877 Standard_Integer II = Lo;
878 while (II <= Up - 2)
879 {
7fd59977 880 gp_Pnt ThePts[3] =
881 {
882 gp_Pnt (C->GetPoint3d (II).XYZ()),
883 gp_Pnt (C->GetPoint3d (++II).XYZ()),
884 gp_Pnt (C->GetPoint3d (++II).XYZ())
885 };
886
887 if (hasloc)
888 {
889 for (Standard_Integer jj = 0; jj <= 2; jj++)
890 ThePts[jj].Transform (theloc.Transformation());
891 }
892
b8ddfc2f 893 aSeqBnds.Append(4);
894 aSeqLines.Append(ThePts[0]);
895 aSeqLines.Append(ThePts[1]);
896 aSeqLines.Append(ThePts[2]);
897 aSeqLines.Append(ThePts[0]);
7fd59977 898 }
899 }
900 //==============
901 // Point
902 //=============
903 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitivePoint))
904 {
905 gp_Pnt P = hasloc ?
906 Handle(Select3D_SensitivePoint)::DownCast(Ent)->Point() :
907 Handle(Select3D_SensitivePoint)::DownCast(Ent)->Point().Transformed (theloc.Transformation());
908 Graphic3d_Vertex V (P.X(), P.Y(), P.Z());
909 mysensgroup->Marker (V);
910 }
911 //============================================================
912 // Triangulation : On met un petit offset ves l'interieur...
913 //==========================================================
914 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveTriangulation))
915 {
916 const Handle(Poly_Triangulation)& PT =
917 (*((Handle(Select3D_SensitiveTriangulation)*) &Ent))->Triangulation();
918
919 const Poly_Array1OfTriangle& triangles = PT->Triangles();
920 const TColgp_Array1OfPnt& Nodes = PT->Nodes();
7fd59977 921 Standard_Integer n[3];
7fd59977 922
923 TopLoc_Location iloc, bidloc;
924 if ((*((Handle(Select3D_SensitiveTriangulation)*) &Ent))->HasInitLocation())
925 bidloc = (*((Handle(Select3D_SensitiveTriangulation)*) &Ent))->GetInitLocation();
926
927 if (bidloc.IsIdentity())
928 iloc = theloc;
929 else
930 iloc = theloc * bidloc;
931
932 Standard_Integer i;
933 for (i = 1; i <= PT->NbTriangles(); i++)
934 {
935 triangles (i).Get (n[0], n[1], n[2]);
936 gp_Pnt P1 (Nodes (n[0]).Transformed (iloc));
937 gp_Pnt P2 (Nodes (n[1]).Transformed (iloc));
938 gp_Pnt P3 (Nodes (n[2]).Transformed (iloc));
939 gp_XYZ V1 (P1.XYZ());
940 gp_XYZ V2 (P2.XYZ());
941 gp_XYZ V3 (P3.XYZ());
942 gp_XYZ CDG (P1.XYZ()); CDG += (P2.XYZ()); CDG += (P3.XYZ()); CDG /= 3.0;
7fd59977 943 V1 -= CDG; V2 -= CDG; V3 -= CDG;
7fd59977 944 V1 *= 0.9; V2 *= 0.9; V3 *= 0.9;
945 V1 += CDG; V2 += CDG; V3 += CDG;
b8ddfc2f 946
947 aSeqBnds.Append(4);
948 aSeqLines.Append(gp_Pnt(V1));
949 aSeqLines.Append(gp_Pnt(V2));
950 aSeqLines.Append(gp_Pnt(V3));
951 aSeqLines.Append(gp_Pnt(V1));
7fd59977 952 }
953
954 // recherche des bords libres...
955
956 Handle(TColStd_HArray1OfInteger) FreeEdges = new TColStd_HArray1OfInteger (1, 2 * StdSel_NumberOfFreeEdges (PT));
957 TColStd_Array1OfInteger& FreeE = FreeEdges->ChangeArray1();
958 Poly_Connect pc (PT);
959 Standard_Integer t[3];
960 Standard_Integer j;
961 Standard_Integer fr (1);
962 for (i = 1; i <= PT->NbTriangles(); i++)
963 {
964 pc.Triangles (i, t[0], t[1], t[2]);
965 triangles (i).Get (n[0], n[1], n[2]);
966 for (j = 0; j < 3; j++)
967 {
968 Standard_Integer k = (j + 1) % 3;
969 if (t[j] == 0)
970 {
971 FreeE (fr) = n[j];
972 FreeE (fr + 1)= n[k];
973 fr += 2;
974 }
975 }
976 }
7fd59977 977 for (Standard_Integer ifri = 1; ifri <= FreeE.Length(); ifri += 2)
978 {
b8ddfc2f 979 gp_Pnt pe1 (Nodes (FreeE (ifri)).Transformed (iloc)), pe2 (Nodes (FreeE (ifri + 1)).Transformed (iloc));
980 aSeqFree.Append(pe1);
981 aSeqFree.Append(pe2);
7fd59977 982 }
7fd59977 983 }
984 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveTriangle))
985 {
986 Handle(Select3D_SensitiveTriangle) Str = Handle(Select3D_SensitiveTriangle)::DownCast(Ent);
b8ddfc2f 987 gp_Pnt P1, P2, P3;
7fd59977 988 Str->Points3D (P1, P2, P3);
b8ddfc2f 989 gp_Pnt CDG = Str->Center3D();
7fd59977 990
991 gp_XYZ V1 (P1.XYZ()); V1 -= (CDG.XYZ());
992 gp_XYZ V2 (P2.XYZ()); V2 -= (CDG.XYZ());
993 gp_XYZ V3 (P3.XYZ()); V3 -= (CDG.XYZ());
7fd59977 994 V1 *= 0.9; V2 *= 0.9; V3 *= 0.9;
995 V1 += CDG.XYZ(); V2 += CDG.XYZ(); V3 += CDG.XYZ();
b8ddfc2f 996
997 aSeqBnds.Append(4);
998 aSeqLines.Append(gp_Pnt(V1));
999 aSeqLines.Append(gp_Pnt(V2));
1000 aSeqLines.Append(gp_Pnt(V3));
1001 aSeqLines.Append(gp_Pnt(V1));
7fd59977 1002 }
1003 }
b8ddfc2f 1004
1005 Standard_Integer i;
1006
1007 if (aSeqLines.Length())
1008 {
1009 Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(aSeqLines.Length(),aSeqBnds.Length());
1010 for (i = 1; i <= aSeqLines.Length(); i++)
1011 aPrims->AddVertex(aSeqLines(i));
1012 for (i = 1; i <= aSeqBnds.Length(); i++)
1013 aPrims->AddBound(aSeqBnds(i));
1014 myareagroup->AddPrimitiveArray(aPrims);
1015 }
1016
1017 if (aSeqFree.Length())
1018 {
1019 mysensgroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_GREEN, Aspect_TOL_SOLID, 2.0));
1020 Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(aSeqFree.Length(),aSeqFree.Length()/2);
1021 for (i = 1; i <= aSeqFree.Length(); i++)
1022 {
1023 aPrims->AddBound(2);
1024 aPrims->AddVertex(aSeqLines(i++));
1025 aPrims->AddVertex(aSeqLines(i));
1026 }
1027 mysensgroup->AddPrimitiveArray(aPrims);
1028 mysensgroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0));
1029 }
7fd59977 1030}
1031
1032//=======================================================================
1033//function : ComputeAreaPrs
1034//purpose :
1035//=======================================================================
1036
b8ddfc2f 1037void StdSelect_ViewerSelector3d::ComputeAreasPrs (const Handle(SelectMgr_Selection)& Sel)
7fd59977 1038{
7fd59977 1039 Standard_Real xmin, ymin, xmax, ymax;
1040 gp_Pnt Pbid;
1041 SelectBasics_ListOfBox2d BoxList;
1042
b8ddfc2f 1043 TColgp_SequenceOfPnt aSeqLines;
7fd59977 1044 for (Sel->Init(); Sel->More(); Sel->Next())
1045 {
1046 Sel->Sensitive()->Areas (BoxList);
1047 for (SelectBasics_ListIteratorOfListOfBox2d itb (BoxList); itb.More(); itb.Next())
1048 {
1049 itb.Value().Get (xmin, ymin, xmax, ymax);
1050
1051 Pbid.SetCoord (xmin - mytolerance, ymin - mytolerance, 0.0);
4952a30a 1052 myprj->Transform (Pbid, myprj->InvertedTransformation());
b8ddfc2f 1053 aSeqLines.Append(Pbid);
7fd59977 1054
1055 Pbid.SetCoord (xmax + mytolerance, ymin - mytolerance, 0.0);
4952a30a 1056 myprj->Transform (Pbid, myprj->InvertedTransformation());
b8ddfc2f 1057 aSeqLines.Append(Pbid);
7fd59977 1058
1059 Pbid.SetCoord (xmax + mytolerance, ymax + mytolerance, 0.0);
4952a30a 1060 myprj->Transform (Pbid, myprj->InvertedTransformation());
b8ddfc2f 1061 aSeqLines.Append(Pbid);
7fd59977 1062
1063 Pbid.SetCoord (xmin - mytolerance, ymax + mytolerance, 0.0);
4952a30a 1064 myprj->Transform (Pbid, myprj->InvertedTransformation());
b8ddfc2f 1065 aSeqLines.Append(Pbid);
1066 }
1067 }
7fd59977 1068
b8ddfc2f 1069 if (aSeqLines.Length())
1070 {
1071 Standard_Integer n, np;
1072 const Standard_Integer nbl = aSeqLines.Length() / 4;
1073 Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(5*nbl,nbl);
1074 for (np = 1, n=0; n<nbl; n++) {
1075 aPrims->AddBound(5);
1076 const gp_Pnt &p1 = aSeqLines(np++);
1077 aPrims->AddVertex(p1);
1078 aPrims->AddVertex(aSeqLines(np++));
1079 aPrims->AddVertex(aSeqLines(np++));
1080 aPrims->AddVertex(aSeqLines(np++));
1081 aPrims->AddVertex(p1);
7fd59977 1082 }
b8ddfc2f 1083 myareagroup->AddPrimitiveArray(aPrims);
7fd59977 1084 }
1085}
1086
1087//=======================================================================
1088//function : ReactivateProjector
1089//purpose :
1090//=======================================================================
1091void StdSelect_ViewerSelector3d::ReactivateProjector()
1092{
1093 Handle(SelectBasics_SensitiveEntity) BS;
1094 for (SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive it (myentities); it.More(); it.Next())
1095 {
1096 BS = it.Value();
1097 if (BS->Is3D())
1098 {
1099 (*((Handle(Select3D_SensitiveEntity)*) &BS))->SetLastPrj (myprj);
1100 }
1101 }
1102}