1 // Created on: 1995-03-15
2 // Created by: Robert COUBLANC
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <StdSelect_ViewerSelector3d.ixx>
18 #include <StdSelect.hxx>
19 #include <SelectBasics_SensitiveEntity.hxx>
20 #include <Graphic3d_AspectLine3d.hxx>
23 #include <gp_Pnt2d.hxx>
26 #include <gp_GTrsf.hxx>
28 #include <Select3D_SensitiveEntity.hxx>
29 #include <Graphic3d_ArrayOfPolylines.hxx>
30 #include <Graphic3d_SequenceOfHClipPlane.hxx>
31 #include <SelectMgr_SelectableObject.hxx>
32 #include <SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive.hxx>
33 #include <SelectBasics_ListOfBox2d.hxx>
34 #include <Visual3d_TransientManager.hxx>
35 #include <TColgp_HArray1OfPnt.hxx>
36 #include <TColgp_Array1OfPnt.hxx>
37 #include <TColgp_HArray1OfPnt2d.hxx>
38 #include <Select3D_SensitiveCurve.hxx>
39 #include <Select3D_SensitiveSegment.hxx>
40 #include <Select3D_SensitiveFace.hxx>
41 #include <Select3D_SensitiveCircle.hxx>
42 #include <Select3D_SensitivePoint.hxx>
43 #include <Select3D_SensitiveTriangulation.hxx>
44 #include <Select3D_SensitiveTriangle.hxx>
45 #include <Select3D_SensitiveWire.hxx>
46 #include <Select3D_SensitiveEntitySequence.hxx>
47 #include <Select3D_ListOfSensitiveTriangle.hxx>
48 #include <Select3D_SensitiveBox.hxx>
49 #include <Select3D_ListIteratorOfListOfSensitiveTriangle.hxx>
51 #include <SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation.hxx>
52 #include <Aspect_TypeOfMarker.hxx>
53 #include <Graphic3d_AspectMarker3d.hxx>
54 #include <Graphic3d_ArrayOfPoints.hxx>
55 #include <SelectBasics_ListIteratorOfListOfBox2d.hxx>
56 #include <Poly_Connect.hxx>
57 #include <TColStd_HArray1OfInteger.hxx>
59 #include <Poly_Array1OfTriangle.hxx>
60 #include <Poly_Triangulation.hxx>
61 #include <OSD_Environment.hxx>
63 #include <V3d_View.hxx>
64 #include <TColgp_SequenceOfPnt.hxx>
67 static Standard_Integer StdSel_NumberOfFreeEdges (const Handle(Poly_Triangulation)& Trg)
69 Standard_Integer nFree = 0;
71 Standard_Integer t[3];
72 Standard_Integer i, j;
73 for (i = 1; i <= Trg->NbTriangles(); i++)
75 pc.Triangles (i, t[0], t[1], t[2]);
76 for (j = 0; j < 3; j++)
77 if (t[j] == 0) nFree++;
82 static Standard_Boolean ReadIsDebugMode()
84 OSD_Environment StdSelectdb ("SELDEBUGMODE");
85 return !StdSelectdb.Value().IsEmpty();
88 static Standard_Boolean StdSelectDebugModeOn()
90 static const Standard_Boolean isDebugMode = ReadIsDebugMode();
94 //==================================================
97 //==================================================
99 StdSelect_ViewerSelector3d
100 ::StdSelect_ViewerSelector3d():
101 myprj(new Select3D_Projector()),
103 mysensmode(StdSelect_SM_WINDOW),
105 myupdatetol(Standard_True)
107 for (Standard_Integer i=0;i<=13;i++) {mycoeff [i] = 0.;myprevcoeff[i]=0.0;}
108 for (Standard_Integer j=0;j<2;j++) {mycenter [j] = 0.;myprevcenter[j]=0.0;}
112 //==================================================
115 //==================================================
117 StdSelect_ViewerSelector3d
118 ::StdSelect_ViewerSelector3d(const Handle(Select3D_Projector)& aProj):
121 mysensmode(StdSelect_SM_WINDOW),
123 myupdatetol(Standard_True)
125 for (Standard_Integer i=0;i<=13;i++) {mycoeff [i] = 0.;myprevcoeff[i]=0.0;}
126 for (Standard_Integer j=0;j<2;j++) {mycenter [j] = 0.;myprevcenter[j]=0.0;}
129 //==================================================
132 //==================================================
134 void StdSelect_ViewerSelector3d::Convert(const Handle(SelectMgr_Selection)& aSel)
136 for(aSel->Init();aSel->More();aSel->Next())
138 if(aSel->Sensitive()->NeedsConversion())
140 Handle(Select3D_SensitiveEntity) SE = *((Handle(Select3D_SensitiveEntity)*) &(aSel->Sensitive()));
142 if(!tosort) tosort=Standard_True;
147 //==================================================
150 //==================================================
152 void StdSelect_ViewerSelector3d
153 ::Set(const Handle(Select3D_Projector)& aProj)
156 toupdate=Standard_True;
159 //==================================================
160 // Function: SetSensitivityMode
162 //==================================================
164 void StdSelect_ViewerSelector3d
165 ::SetSensitivityMode(const StdSelect_SensitivityMode aMode)
168 toupdate = Standard_True;
171 //==================================================
172 // Function: SetPixelTolerance
174 //==================================================
176 void StdSelect_ViewerSelector3d
177 ::SetPixelTolerance(const Standard_Integer aTolerance)
179 if(mypixtol!=aTolerance)
181 mypixtol = aTolerance;
182 myupdatetol = Standard_True;
186 //==================================================
187 // Function: SelectPix
189 //==================================================
191 void StdSelect_ViewerSelector3d
192 ::Pick(const Standard_Integer XPix,
193 const Standard_Integer YPix,
194 const Handle(V3d_View)& aView)
196 SetClipping (aView->GetClipPlanes());
198 Standard_Real Xr3d,Yr3d,Zr3d;
200 aView->Convert(XPix,YPix,Xr3d,Yr3d,Zr3d);
201 myprj->Project(gp_Pnt(Xr3d,Yr3d,Zr3d),P2d);
203 InitSelect(P2d.X(),P2d.Y());
207 //==================================================
208 // Function: InitSelect
210 //==================================================
212 void StdSelect_ViewerSelector3d
213 ::Pick(const Standard_Integer XPMin,
214 const Standard_Integer YPMin,
215 const Standard_Integer XPMax,
216 const Standard_Integer YPMax,
217 const Handle(V3d_View)& aView)
219 if (myupdatetol && SensitivityMode() == StdSelect_SM_WINDOW)
221 SetSensitivity (aView->Convert (mypixtol));
222 myupdatetol = Standard_False;
226 Standard_Real x1,y1,z1,x2,y2,z2;
227 gp_Pnt2d P2d_1,P2d_2;
228 aView->Convert(XPMin,YPMin,x1,y1,z1);
229 aView->Convert(XPMax,YPMax,x2,y2,z2);
230 myprj->Project(gp_Pnt(x1,y1,z1),P2d_1);
231 myprj->Project(gp_Pnt(x2,y2,z2),P2d_2);
233 InitSelect (Min(P2d_1.X(),P2d_2.X()),
234 Min(P2d_1.Y(),P2d_2.Y()),
235 Max(P2d_1.X(),P2d_2.X()),
236 Max(P2d_1.Y(),P2d_2.Y()));
239 //==================================================
241 // Purpose : Selection using a polyline
242 //==================================================
244 void StdSelect_ViewerSelector3d::Pick(const TColgp_Array1OfPnt2d& aPolyline, const Handle(V3d_View)& aView)
246 if (myupdatetol && SensitivityMode() == StdSelect_SM_WINDOW)
248 SetSensitivity (aView->Convert (mypixtol));
249 myupdatetol = Standard_False;
254 Standard_Integer NbPix = aPolyline.Length();
258 Handle(TColgp_HArray1OfPnt2d) P2d = new TColgp_HArray1OfPnt2d(1,NbPix);
260 for (i = 1; i <= NbPix; ++i)
263 Standard_Integer XP = (Standard_Integer)(aPolyline(i).X());
264 Standard_Integer YP = (Standard_Integer)(aPolyline(i).Y());
267 aView->Convert (XP, YP, x, y, z);
268 myprj->Project (gp_Pnt (x, y, z), Pnt2d);
270 P2d->SetValue (i, Pnt2d);
273 const TColgp_Array1OfPnt2d& aPolyConvert = P2d->Array1();
275 InitSelect(aPolyConvert);
278 //==================================================
279 // Function: DisplayAreas
280 // Purpose : display the activated areas...
281 //==================================================
283 void StdSelect_ViewerSelector3d::DisplayAreas(const Handle(V3d_View)& aView)
285 if (myupdatetol && SensitivityMode() == StdSelect_SM_WINDOW)
287 SetSensitivity (aView->Convert (mypixtol));
288 myupdatetol = Standard_False;
291 UpdateSort(); // Updates the activated areas
293 if(mystruct.IsNull())
294 mystruct = new Graphic3d_Structure(aView->Viewer()->Viewer());
296 if(myareagroup.IsNull())
297 myareagroup = new Graphic3d_Group(mystruct);
299 SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive It(myentities);
300 Handle(Select3D_Projector) prj = StdSelect::GetProjector(aView);
303 Standard_Real xmin,ymin,xmax,ymax;
305 SelectBasics_ListOfBox2d BoxList;
307 TColgp_SequenceOfPnt aSeqLines;
308 for (; It.More(); It.Next())
310 It.Value()->Areas(BoxList);
311 for (SelectBasics_ListIteratorOfListOfBox2d itb (BoxList); itb.More(); itb.Next())
313 itb.Value().Get (xmin, ymin, xmax, ymax);
315 Pbid.SetCoord (xmin - mytolerance, ymin - mytolerance, 0.0);
316 prj->Transform (Pbid, prj->InvertedTransformation());
317 aSeqLines.Append(Pbid);
319 Pbid.SetCoord (xmax + mytolerance, ymin - mytolerance, 0.0);
320 prj->Transform (Pbid, prj->InvertedTransformation());
321 aSeqLines.Append(Pbid);
323 Pbid.SetCoord (xmax + mytolerance, ymax + mytolerance, 0.0);
324 prj->Transform (Pbid, prj->InvertedTransformation());
325 aSeqLines.Append(Pbid);
327 Pbid.SetCoord (xmin - mytolerance, ymax + mytolerance, 0.0);
328 prj->Transform (Pbid, prj->InvertedTransformation());
329 aSeqLines.Append(Pbid);
333 if (aSeqLines.Length())
335 Standard_Integer n, np;
336 const Standard_Integer nbl = aSeqLines.Length() / 4;
337 Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(5*nbl,nbl);
338 for (np = 1, n=0; n<nbl; n++) {
340 const gp_Pnt &p1 = aSeqLines(np++);
341 aPrims->AddVertex(p1);
342 aPrims->AddVertex(aSeqLines(np++));
343 aPrims->AddVertex(aSeqLines(np++));
344 aPrims->AddVertex(aSeqLines(np++));
345 aPrims->AddVertex(p1);
347 myareagroup->AddPrimitiveArray(aPrims);
350 myareagroup->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_AQUAMARINE1, Aspect_TOL_DASH, 1.0));
351 myareagroup->Structure()->SetDisplayPriority(10);
352 myareagroup->Structure()->Display();
354 if(aView->TransientManagerBeginDraw())
356 Visual3d_TransientManager::DrawStructure(mystruct);
357 Visual3d_TransientManager::EndDraw();
365 //==================================================
366 // Function: ClearAreas
368 //==================================================
370 void StdSelect_ViewerSelector3d::ClearAreas(const Handle(V3d_View)& aView)
372 if(myareagroup.IsNull()) return;
373 myareagroup->Clear();
374 if(aView.IsNull()) return;
375 if(aView->TransientManagerBeginDraw())
376 Visual3d_TransientManager::EndDraw();
381 //==================================================
382 // Function: updateproj
383 // Purpose : at any time verifies that
384 // the view coefficients did not change :
385 // store current view coeffts
386 // in static array cf [ 0->2 At coordinates XAT YAT ZAT
387 // 3->5 Up coordinates XUP YUP ZUP
388 // 6->8 ProjVect coordinates DX DY DZ
390 // 10 1. if pers 0. else
391 //==================================================
393 Standard_Boolean StdSelect_ViewerSelector3d::UpdateProj(const Handle(V3d_View)& aView)
395 myprevcoeff[ 9] = 0.0;
396 myprevcoeff[10] = 0.0;
397 Standard_Boolean Pers = Standard_False;
398 if (aView->Type() == V3d_PERSPECTIVE)
400 Pers = Standard_True;
401 myprevcoeff[10] = 1.0;
402 myprevcoeff[ 9] = aView->Focale();
404 aView->At (myprevcoeff[0], myprevcoeff[1], myprevcoeff[2]);
405 aView->Up (myprevcoeff[3], myprevcoeff[4], myprevcoeff[5]);
406 aView->Proj (myprevcoeff[6], myprevcoeff[7], myprevcoeff[8]);
407 aView->AxialScale (myprevcoeff[11], myprevcoeff[12], myprevcoeff[13]);
408 aView->Center (myprevcenter[0], myprevcenter[1]);
411 for (ii = 0; ii <= 13 && (myprevcoeff[ii] == mycoeff[ii]); ++ii) {}
412 if (ii <= 13 || (myprevcenter[0] != mycenter[0]) || (myprevcenter[1] != mycenter[1]))
414 if (StdSelectDebugModeOn())
416 cout<<"\t\t\t\t\t VS3d::UpdateProj====> coefficients changes on reprojette"<<endl;
418 for (Standard_Integer i = 1; i <= 9; ++i)
420 cout<<mycoeff[i-1]<<" ";
422 cout<<"\n\t\t\t\t\t";
424 cout<<"focale :"<<mycoeff[9]<<" persp :"<<mycoeff[10]<<endl;
425 cout<<"center :"<<mycenter[0]<<" "<<mycenter[1]<<endl;
427 toupdate = Standard_True;
428 myupdatetol = Standard_True;
429 for (Standard_Integer imod = ii; imod <= 13; ++imod)
431 mycoeff[imod] = myprevcoeff[imod];
433 for (Standard_Integer jmod = 0; jmod < 2; ++jmod)
435 mycenter[jmod] = myprevcenter[jmod];
438 myprj = new Select3D_Projector (aView);
442 if (Abs (aView->Scale() - mylastzoom) > 1.e-3)
444 myupdatetol = Standard_True;
445 mylastzoom = aView->Scale();
448 if (myupdatetol && SensitivityMode() == StdSelect_SM_WINDOW)
450 SetSensitivity (aView->Convert (mypixtol));
451 myupdatetol = Standard_False;
454 if (toupdate) UpdateConversion();
455 if (tosort) UpdateSort();
457 return Standard_True;
461 //=============================
462 // Function: DisplaySensitive.
463 // Purpose : Display active primitives.
464 //=============================
465 void StdSelect_ViewerSelector3d::DisplaySensitive(const Handle(V3d_View)& aViou)
467 if (myupdatetol && SensitivityMode() == StdSelect_SM_WINDOW)
469 SetSensitivity (aViou->Convert (mypixtol));
470 myupdatetol = Standard_False;
472 if(toupdate) UpdateProj(aViou);
473 if(tosort) UpdateSort(); // Updates the activated areas
475 // Preparation des structures
476 if(mystruct.IsNull())
477 mystruct = new Graphic3d_Structure(aViou->Viewer()->Viewer());
479 if(mysensgroup.IsNull())
480 mysensgroup = new Graphic3d_Group(mystruct);
482 Quantity_Color Col(Quantity_NOC_INDIANRED3);
483 Handle(Graphic3d_AspectMarker3d) AM =
484 new Graphic3d_AspectMarker3d(Aspect_TOM_O_PLUS,Col,2.);
485 mysensgroup-> SetPrimitivesAspect (AM);
486 mysensgroup->SetPrimitivesAspect (
487 new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0));
489 // Remplissage de la structure...
491 SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation It(myselections);
493 for (; It.More(); It.Next())
497 const Handle(SelectMgr_Selection)& Sel = It.Key();
498 ComputeSensitivePrs(Sel);
502 mysensgroup->Structure()->SetDisplayPriority(10);
504 if (aViou->TransientManagerBeginDraw())
506 Visual3d_TransientManager::DrawStructure(mystruct);
507 Visual3d_TransientManager::EndDraw();
509 else if (!aViou.IsNull())
515 //=============================
516 // Function: ClearSensitive
518 //=============================
519 void StdSelect_ViewerSelector3d::ClearSensitive(const Handle(V3d_View)& aViou)
521 if(mysensgroup.IsNull()) return;
522 mysensgroup->Clear();
523 if(aViou.IsNull()) return;
525 if(aViou->TransientManagerBeginDraw())
526 Visual3d_TransientManager::EndDraw();
531 //=======================================================================
532 //function : DisplaySenstive
534 //=======================================================================
535 void StdSelect_ViewerSelector3d::
536 DisplaySensitive (const Handle(SelectMgr_Selection)& Sel,
537 const Handle(V3d_View)& aViou,
538 const Standard_Boolean ClearOthers)
540 if (mystruct.IsNull())
541 mystruct = new Graphic3d_Structure (aViou->Viewer()->Viewer());
542 if (mysensgroup.IsNull())
544 mysensgroup = new Graphic3d_Group (mystruct);
545 Quantity_Color Col (Quantity_NOC_INDIANRED3);
546 Handle(Graphic3d_AspectMarker3d) AM =
547 new Graphic3d_AspectMarker3d (Aspect_TOM_O_PLUS, Col, 2.0);
548 mysensgroup-> SetPrimitivesAspect (AM);
549 mysensgroup->SetPrimitivesAspect (
550 new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0));
553 if(ClearOthers) mysensgroup->Clear();
555 ComputeSensitivePrs(Sel);
557 mystruct->SetDisplayPriority(10);
559 if(aViou->TransientManagerBeginDraw())
561 Visual3d_TransientManager::DrawStructure(mystruct);
562 Visual3d_TransientManager::EndDraw();
564 else if(!aViou.IsNull())
570 //=======================================================================
571 //function : DisplayAreas
573 //=======================================================================
575 void StdSelect_ViewerSelector3d::
576 DisplayAreas (const Handle(SelectMgr_Selection)& Sel,
577 const Handle(V3d_View)& aViou,
578 const Standard_Boolean ClearOthers)
580 if (mystruct.IsNull())
581 mystruct = new Graphic3d_Structure (aViou->Viewer()->Viewer());
583 if (mysensgroup.IsNull())
585 myareagroup = new Graphic3d_Group (mystruct);
586 myareagroup->SetGroupPrimitivesAspect(new Graphic3d_AspectLine3d (Quantity_NOC_AQUAMARINE1, Aspect_TOL_DASH, 1.0));
589 if(ClearOthers) myareagroup->Clear();
591 ComputeAreasPrs(Sel);
593 mystruct->SetDisplayPriority(10);
596 if(aViou->TransientManagerBeginDraw())
598 Visual3d_TransientManager::DrawStructure(mystruct);
599 Visual3d_TransientManager::EndDraw();
607 //=======================================================================
608 //function : ComputeSensitivePrs
610 //=======================================================================
612 void StdSelect_ViewerSelector3d::ComputeSensitivePrs(const Handle(SelectMgr_Selection)& Sel)
614 TColgp_SequenceOfPnt aSeqLines, aSeqFree;
615 TColStd_SequenceOfInteger aSeqBnds;
617 for(Sel->Init();Sel->More();Sel->Next())
619 Handle(Select3D_SensitiveEntity) Ent = Handle(Select3D_SensitiveEntity)::DownCast(Sel->Sensitive());
620 const Standard_Boolean hasloc = (Ent.IsNull()? Standard_False : Ent->HasLocation());
622 TopLoc_Location theloc;
624 theloc = Ent->Location();
630 if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveBox))
632 const Bnd_Box& B = Handle(Select3D_SensitiveBox)::DownCast (Ent)->Box();
633 Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
634 B.Get (xmin, ymin, zmin, xmax, ymax, zmax);
636 gp_Pnt theboxpoint[8] =
638 gp_Pnt(xmin,ymin,zmin),
639 gp_Pnt(xmax,ymin,zmin),
640 gp_Pnt(xmax,ymax,zmin),
641 gp_Pnt(xmin,ymax,zmin),
642 gp_Pnt(xmin,ymin,zmax),
643 gp_Pnt(xmax,ymin,zmax),
644 gp_Pnt(xmax,ymax,zmax),
645 gp_Pnt(xmin,ymax,zmax)
649 for (i = 0; i <= 7; i++)
650 theboxpoint[i].Transform (theloc.Transformation());
654 for (i = 0; i < 4; i++)
655 aSeqLines.Append(theboxpoint[i]);
656 aSeqLines.Append(theboxpoint[0]);
659 for (i = 4; i < 8; i++)
660 aSeqLines.Append(theboxpoint[i]);
661 aSeqLines.Append(theboxpoint[4]);
663 for (i = 0; i < 4; i++)
666 aSeqLines.Append(theboxpoint[i]);
667 aSeqLines.Append(theboxpoint[i+4]);
673 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveFace))
675 Handle(Select3D_SensitiveFace) aFace = Handle(Select3D_SensitiveFace)::DownCast(Ent);
676 Handle(TColgp_HArray1OfPnt) TheHPts;
677 aFace->Points3D(TheHPts);
678 const TColgp_Array1OfPnt& ThePts = TheHPts->Array1();
680 aSeqBnds.Append(ThePts.Length());
681 for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
684 aSeqLines.Append(ThePts(I).Transformed (theloc.Transformation()));
686 aSeqLines.Append(ThePts(I));
692 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCurve))
694 Handle(Select3D_SensitiveCurve) aCurve = Handle(Select3D_SensitiveCurve)::DownCast(Ent);
695 Handle(TColgp_HArray1OfPnt) TheHPts;
696 aCurve->Points3D(TheHPts);
697 const TColgp_Array1OfPnt& ThePts = TheHPts->Array1();
699 aSeqBnds.Append(ThePts.Length());
700 for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
703 aSeqLines.Append(ThePts(I).Transformed (theloc.Transformation()));
705 aSeqLines.Append(ThePts(I));
711 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveWire))
713 Handle(Select3D_SensitiveWire) aWire = Handle(Select3D_SensitiveWire)::DownCast(Ent);
714 Select3D_SensitiveEntitySequence EntitySeq;
715 aWire->GetEdges (EntitySeq);
717 for (int i = 1; i <= EntitySeq.Length(); i++)
719 Handle(Select3D_SensitiveEntity) SubEnt = Handle(Select3D_SensitiveEntity)::DownCast(EntitySeq.Value(i));
722 if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveSegment))
724 gp_Pnt P1 (Handle(Select3D_SensitiveSegment)::DownCast(SubEnt)->StartPoint().XYZ());
725 gp_Pnt P2 (Handle(Select3D_SensitiveSegment)::DownCast(SubEnt)->EndPoint().XYZ());
728 P1.Transform(theloc.Transformation());
729 P2.Transform(theloc.Transformation());
732 aSeqLines.Append(P1);
733 aSeqLines.Append(P2);
737 if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCircle))
739 Handle(Select3D_SensitiveCircle) C = Handle(Select3D_SensitiveCircle)::DownCast(SubEnt);
740 Standard_Integer Lo, Up;
741 C->ArrayBounds (Lo, Up);
742 Standard_Integer II = Lo;
747 gp_Pnt (C->GetPoint3d (II).XYZ()),
748 gp_Pnt (C->GetPoint3d (++II).XYZ()),
749 gp_Pnt (C->GetPoint3d (++II).XYZ())
754 for (Standard_Integer jj = 0; jj <= 2; jj++)
755 ThePts[jj].Transform (theloc.Transformation());
759 aSeqLines.Append(ThePts[0]);
760 aSeqLines.Append(ThePts[1]);
761 aSeqLines.Append(ThePts[2]);
762 aSeqLines.Append(ThePts[0]);
767 if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCurve))
769 Handle(Select3D_SensitiveCurve) aCurve = Handle(Select3D_SensitiveCurve)::DownCast(SubEnt);
770 Handle(TColgp_HArray1OfPnt) TheHPts;
771 aCurve->Points3D (TheHPts);
772 const TColgp_Array1OfPnt& ThePts = TheHPts->Array1();
774 aSeqBnds.Append(ThePts.Length());
775 for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
778 aSeqLines.Append(ThePts(I).Transformed (theloc.Transformation()));
780 aSeqLines.Append(ThePts(I));
788 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveSegment))
790 gp_Pnt P1 (Handle(Select3D_SensitiveSegment)::DownCast(Ent)->StartPoint().XYZ());
791 gp_Pnt P2 (Handle(Select3D_SensitiveSegment)::DownCast(Ent)->EndPoint().XYZ());
794 P1.Transform (theloc.Transformation());
795 P2.Transform (theloc.Transformation());
798 aSeqLines.Append(P1);
799 aSeqLines.Append(P2);
804 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCircle))
806 Handle(Select3D_SensitiveCircle) C = Handle(Select3D_SensitiveCircle)::DownCast(Ent);
807 Standard_Integer Lo, Up;
808 C->ArrayBounds (Lo, Up);
809 Standard_Integer II = Lo;
814 gp_Pnt (C->GetPoint3d (II).XYZ()),
815 gp_Pnt (C->GetPoint3d (++II).XYZ()),
816 gp_Pnt (C->GetPoint3d (++II).XYZ())
821 for (Standard_Integer jj = 0; jj <= 2; jj++)
822 ThePts[jj].Transform (theloc.Transformation());
826 aSeqLines.Append(ThePts[0]);
827 aSeqLines.Append(ThePts[1]);
828 aSeqLines.Append(ThePts[2]);
829 aSeqLines.Append(ThePts[0]);
835 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitivePoint))
838 Handle(Select3D_SensitivePoint)::DownCast(Ent)->Point() :
839 Handle(Select3D_SensitivePoint)::DownCast(Ent)->Point().Transformed (theloc.Transformation());
840 Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints = new Graphic3d_ArrayOfPoints (1);
841 anArrayOfPoints->AddVertex (P.X(), P.Y(), P.Z());
842 mysensgroup->AddPrimitiveArray (anArrayOfPoints);
844 //============================================================
845 // Triangulation : On met un petit offset ves l'interieur...
846 //==========================================================
847 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveTriangulation))
849 const Handle(Poly_Triangulation)& PT =
850 (*((Handle(Select3D_SensitiveTriangulation)*) &Ent))->Triangulation();
852 const Poly_Array1OfTriangle& triangles = PT->Triangles();
853 const TColgp_Array1OfPnt& Nodes = PT->Nodes();
854 Standard_Integer n[3];
856 TopLoc_Location iloc, bidloc;
857 if ((*((Handle(Select3D_SensitiveTriangulation)*) &Ent))->HasInitLocation())
858 bidloc = (*((Handle(Select3D_SensitiveTriangulation)*) &Ent))->GetInitLocation();
860 if (bidloc.IsIdentity())
863 iloc = theloc * bidloc;
866 for (i = 1; i <= PT->NbTriangles(); i++)
868 triangles (i).Get (n[0], n[1], n[2]);
869 gp_Pnt P1 (Nodes (n[0]).Transformed (iloc));
870 gp_Pnt P2 (Nodes (n[1]).Transformed (iloc));
871 gp_Pnt P3 (Nodes (n[2]).Transformed (iloc));
872 gp_XYZ V1 (P1.XYZ());
873 gp_XYZ V2 (P2.XYZ());
874 gp_XYZ V3 (P3.XYZ());
875 gp_XYZ CDG (P1.XYZ()); CDG += (P2.XYZ()); CDG += (P3.XYZ()); CDG /= 3.0;
876 V1 -= CDG; V2 -= CDG; V3 -= CDG;
877 V1 *= 0.9; V2 *= 0.9; V3 *= 0.9;
878 V1 += CDG; V2 += CDG; V3 += CDG;
881 aSeqLines.Append(gp_Pnt(V1));
882 aSeqLines.Append(gp_Pnt(V2));
883 aSeqLines.Append(gp_Pnt(V3));
884 aSeqLines.Append(gp_Pnt(V1));
887 // recherche des bords libres...
889 Handle(TColStd_HArray1OfInteger) FreeEdges = new TColStd_HArray1OfInteger (1, 2 * StdSel_NumberOfFreeEdges (PT));
890 TColStd_Array1OfInteger& FreeE = FreeEdges->ChangeArray1();
891 Poly_Connect pc (PT);
892 Standard_Integer t[3];
894 Standard_Integer fr (1);
895 for (i = 1; i <= PT->NbTriangles(); i++)
897 pc.Triangles (i, t[0], t[1], t[2]);
898 triangles (i).Get (n[0], n[1], n[2]);
899 for (j = 0; j < 3; j++)
901 Standard_Integer k = (j + 1) % 3;
905 FreeE (fr + 1)= n[k];
910 for (Standard_Integer ifri = 1; ifri <= FreeE.Length(); ifri += 2)
912 gp_Pnt pe1 (Nodes (FreeE (ifri)).Transformed (iloc)), pe2 (Nodes (FreeE (ifri + 1)).Transformed (iloc));
913 aSeqFree.Append(pe1);
914 aSeqFree.Append(pe2);
917 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveTriangle))
919 Handle(Select3D_SensitiveTriangle) Str = Handle(Select3D_SensitiveTriangle)::DownCast(Ent);
921 Str->Points3D (P1, P2, P3);
922 gp_Pnt CDG = Str->Center3D();
924 gp_XYZ V1 (P1.XYZ()); V1 -= (CDG.XYZ());
925 gp_XYZ V2 (P2.XYZ()); V2 -= (CDG.XYZ());
926 gp_XYZ V3 (P3.XYZ()); V3 -= (CDG.XYZ());
927 V1 *= 0.9; V2 *= 0.9; V3 *= 0.9;
928 V1 += CDG.XYZ(); V2 += CDG.XYZ(); V3 += CDG.XYZ();
931 aSeqLines.Append(gp_Pnt(V1));
932 aSeqLines.Append(gp_Pnt(V2));
933 aSeqLines.Append(gp_Pnt(V3));
934 aSeqLines.Append(gp_Pnt(V1));
940 if (aSeqLines.Length())
942 Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(aSeqLines.Length(),aSeqBnds.Length());
943 for (i = 1; i <= aSeqLines.Length(); i++)
944 aPrims->AddVertex(aSeqLines(i));
945 for (i = 1; i <= aSeqBnds.Length(); i++)
946 aPrims->AddBound(aSeqBnds(i));
947 myareagroup->AddPrimitiveArray(aPrims);
950 if (aSeqFree.Length())
952 mysensgroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_GREEN, Aspect_TOL_SOLID, 2.0));
953 Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(aSeqFree.Length(),aSeqFree.Length()/2);
954 for (i = 1; i <= aSeqFree.Length(); i++)
957 aPrims->AddVertex(aSeqLines(i++));
958 aPrims->AddVertex(aSeqLines(i));
960 mysensgroup->AddPrimitiveArray(aPrims);
961 mysensgroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0));
965 //=======================================================================
966 //function : ComputeAreaPrs
968 //=======================================================================
970 void StdSelect_ViewerSelector3d::ComputeAreasPrs (const Handle(SelectMgr_Selection)& Sel)
972 Standard_Real xmin, ymin, xmax, ymax;
974 SelectBasics_ListOfBox2d BoxList;
976 TColgp_SequenceOfPnt aSeqLines;
977 for (Sel->Init(); Sel->More(); Sel->Next())
979 Sel->Sensitive()->Areas (BoxList);
980 for (SelectBasics_ListIteratorOfListOfBox2d itb (BoxList); itb.More(); itb.Next())
982 itb.Value().Get (xmin, ymin, xmax, ymax);
984 Pbid.SetCoord (xmin - mytolerance, ymin - mytolerance, 0.0);
985 myprj->Transform (Pbid, myprj->InvertedTransformation());
986 aSeqLines.Append(Pbid);
988 Pbid.SetCoord (xmax + mytolerance, ymin - mytolerance, 0.0);
989 myprj->Transform (Pbid, myprj->InvertedTransformation());
990 aSeqLines.Append(Pbid);
992 Pbid.SetCoord (xmax + mytolerance, ymax + mytolerance, 0.0);
993 myprj->Transform (Pbid, myprj->InvertedTransformation());
994 aSeqLines.Append(Pbid);
996 Pbid.SetCoord (xmin - mytolerance, ymax + mytolerance, 0.0);
997 myprj->Transform (Pbid, myprj->InvertedTransformation());
998 aSeqLines.Append(Pbid);
1002 if (aSeqLines.Length())
1004 Standard_Integer n, np;
1005 const Standard_Integer nbl = aSeqLines.Length() / 4;
1006 Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(5*nbl,nbl);
1007 for (np = 1, n=0; n<nbl; n++) {
1008 aPrims->AddBound(5);
1009 const gp_Pnt &p1 = aSeqLines(np++);
1010 aPrims->AddVertex(p1);
1011 aPrims->AddVertex(aSeqLines(np++));
1012 aPrims->AddVertex(aSeqLines(np++));
1013 aPrims->AddVertex(aSeqLines(np++));
1014 aPrims->AddVertex(p1);
1016 myareagroup->AddPrimitiveArray(aPrims);
1020 //=======================================================================
1021 //function : SetClipping
1023 //=======================================================================
1024 void StdSelect_ViewerSelector3d::SetClipping (const Graphic3d_SequenceOfHClipPlane& thePlanes)
1026 myClipPlanes = thePlanes;
1029 //=======================================================================
1030 //function : ComputeClipRange
1032 //=======================================================================
1033 void StdSelect_ViewerSelector3d::ComputeClipRange (const Graphic3d_SequenceOfHClipPlane& thePlanes,
1034 const gp_Lin& thePickLine,
1035 Standard_Real& theDepthMin,
1036 Standard_Real& theDepthMax) const
1038 theDepthMin = RealFirst();
1039 theDepthMax = RealLast();
1040 Standard_Real aPlaneA, aPlaneB, aPlaneC, aPlaneD;
1042 Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (thePlanes);
1043 for (; aPlaneIt.More(); aPlaneIt.Next())
1045 const Handle(Graphic3d_ClipPlane)& aClipPlane = aPlaneIt.Value();
1046 if (!aClipPlane->IsOn())
1049 gp_Pln aGeomPlane = aClipPlane->ToPlane();
1051 aGeomPlane.Coefficients (aPlaneA, aPlaneB, aPlaneC, aPlaneD);
1053 const gp_Dir& aPlaneDir = aGeomPlane.Axis().Direction();
1054 const gp_Dir& aPickDir = thePickLine.Direction();
1055 const gp_XYZ& aPntOnLine = thePickLine.Location().XYZ();
1056 const gp_XYZ& aPlaneDirXYZ = aPlaneDir.XYZ();
1058 Standard_Real aDotProduct = aPickDir.Dot (aPlaneDir);
1059 Standard_Real aDistance = -(aPntOnLine.Dot (aPlaneDirXYZ) + aPlaneD);
1061 // check whether the pick line is parallel to clip plane
1062 if (Abs (aDotProduct) < Precision::Angular())
1064 if (aDistance > 0.0)
1066 // line lies above the plane, thus no selection is possible
1072 // line lies below the plane and is not clipped, skip
1076 // compute distance to point of pick line intersection with the plane
1077 Standard_Real aIntDist = aDistance / aDotProduct;
1079 // change depth limits for case of opposite and directed planes
1080 if (aDotProduct < 0.0)
1082 theDepthMax = Min (aIntDist, theDepthMax);
1084 else if (aIntDist > theDepthMin)
1086 theDepthMin = Max (aIntDist, theDepthMin);
1091 //=======================================================================
1092 //function : PickingLine
1094 //=======================================================================
1095 gp_Lin StdSelect_ViewerSelector3d::PickingLine(const Standard_Real theX, const Standard_Real theY) const
1097 return myprj->Shoot (theX, theY);
1100 //=======================================================================
1101 //function : DepthClipping
1103 //=======================================================================
1104 void StdSelect_ViewerSelector3d::DepthClipping (const Standard_Real theX,
1105 const Standard_Real theY,
1106 Standard_Real& theDepthMin,
1107 Standard_Real& theDepthMax) const
1109 return ComputeClipRange (myClipPlanes, PickingLine (theX, theY), theDepthMin, theDepthMax);
1112 //=======================================================================
1113 //function : DepthClipping
1115 //=======================================================================
1116 void StdSelect_ViewerSelector3d::DepthClipping (const Standard_Real theX,
1117 const Standard_Real theY,
1118 const Handle(SelectMgr_EntityOwner)& theOwner,
1119 Standard_Real& theDepthMin,
1120 Standard_Real& theDepthMax) const
1122 return ComputeClipRange (theOwner->Selectable()->GetClipPlanes(),
1123 PickingLine (theX, theY),
1124 theDepthMin, theDepthMax);
1127 //=======================================================================
1128 //function : HasDepthClipping
1130 //=======================================================================
1131 Standard_Boolean StdSelect_ViewerSelector3d::HasDepthClipping (const Handle(SelectMgr_EntityOwner)& theOwner) const
1133 if (!theOwner->HasSelectable())
1135 return Standard_False;
1138 const Handle(SelectMgr_SelectableObject)& aSelectable = theOwner->Selectable();
1139 return (aSelectable->GetClipPlanes().Size() > 0);