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
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.
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.
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.
22 #include <StdSelect_ViewerSelector3d.ixx>
23 #include <StdSelect.hxx>
24 #include <SelectBasics_SensitiveEntity.hxx>
25 #include <Graphic3d_AspectLine3d.hxx>
28 #include <gp_Pnt2d.hxx>
31 #include <gp_GTrsf.hxx>
33 #include <V3d_PerspectiveView.hxx>
34 #include <Select3D_SensitiveEntity.hxx>
35 #include <Graphic3d_ArrayOfPolylines.hxx>
36 #include <Graphic3d_SetOfHClipPlane.hxx>
37 #include <SelectMgr_SelectableObject.hxx>
38 #include <SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive.hxx>
39 #include <SelectBasics_ListOfBox2d.hxx>
40 #include <Visual3d_TransientManager.hxx>
41 #include <TColgp_HArray1OfPnt.hxx>
42 #include <TColgp_Array1OfPnt.hxx>
43 #include <TColgp_HArray1OfPnt2d.hxx>
44 #include <Select3D_SensitiveCurve.hxx>
45 #include <Select3D_SensitiveSegment.hxx>
46 #include <Select3D_SensitiveFace.hxx>
47 #include <Select3D_SensitiveCircle.hxx>
48 #include <Select3D_SensitivePoint.hxx>
49 #include <Select3D_SensitiveTriangulation.hxx>
50 #include <Select3D_SensitiveTriangle.hxx>
51 #include <Select3D_SensitiveWire.hxx>
52 #include <Select3D_SensitiveEntitySequence.hxx>
53 #include <Select3D_ListOfSensitiveTriangle.hxx>
54 #include <Select3D_SensitiveBox.hxx>
55 #include <Select3D_ListIteratorOfListOfSensitiveTriangle.hxx>
57 #include <SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation.hxx>
58 #include <Aspect_TypeOfMarker.hxx>
59 #include <Graphic3d_AspectMarker3d.hxx>
60 #include <Graphic3d_ArrayOfPoints.hxx>
61 #include <SelectBasics_ListIteratorOfListOfBox2d.hxx>
62 #include <Poly_Connect.hxx>
63 #include <TColStd_HArray1OfInteger.hxx>
65 #include <Poly_Array1OfTriangle.hxx>
66 #include <Poly_Triangulation.hxx>
67 #include <OSD_Environment.hxx>
69 #include <V3d_View.hxx>
70 #include <TColgp_SequenceOfPnt.hxx>
73 static Standard_Integer StdSel_NumberOfFreeEdges (const Handle(Poly_Triangulation)& Trg)
75 Standard_Integer nFree = 0;
77 Standard_Integer t[3];
78 Standard_Integer i, j;
79 for (i = 1; i <= Trg->NbTriangles(); i++)
81 pc.Triangles (i, t[0], t[1], t[2]);
82 for (j = 0; j < 3; j++)
83 if (t[j] == 0) nFree++;
88 static Standard_Boolean ReadIsDebugMode()
90 OSD_Environment StdSelectdb ("SELDEBUGMODE");
91 return !StdSelectdb.Value().IsEmpty();
94 static Standard_Boolean StdSelectDebugModeOn()
96 static const Standard_Boolean isDebugMode = ReadIsDebugMode();
100 //==================================================
103 //==================================================
105 StdSelect_ViewerSelector3d
106 ::StdSelect_ViewerSelector3d():
107 myprj(new Select3D_Projector()),
109 mysensmode(StdSelect_SM_WINDOW),
111 myupdatetol(Standard_True)
113 for (Standard_Integer i=0;i<=13;i++) {mycoeff [i] = 0.;myprevcoeff[i]=0.0;}
114 for (Standard_Integer j=0;j<2;j++) {mycenter [j] = 0.;myprevcenter[j]=0.0;}
118 //==================================================
121 //==================================================
123 StdSelect_ViewerSelector3d
124 ::StdSelect_ViewerSelector3d(const Handle(Select3D_Projector)& aProj):
127 mysensmode(StdSelect_SM_WINDOW),
129 myupdatetol(Standard_True)
131 for (Standard_Integer i=0;i<=13;i++) {mycoeff [i] = 0.;myprevcoeff[i]=0.0;}
132 for (Standard_Integer j=0;j<2;j++) {mycenter [j] = 0.;myprevcenter[j]=0.0;}
135 //==================================================
138 //==================================================
140 void StdSelect_ViewerSelector3d::Convert(const Handle(SelectMgr_Selection)& aSel)
142 for(aSel->Init();aSel->More();aSel->Next())
144 if(aSel->Sensitive()->NeedsConversion())
146 Handle(Select3D_SensitiveEntity) SE = *((Handle(Select3D_SensitiveEntity)*) &(aSel->Sensitive()));
148 if(!tosort) tosort=Standard_True;
153 //==================================================
156 //==================================================
158 void StdSelect_ViewerSelector3d
159 ::Set(const Handle(Select3D_Projector)& aProj)
162 toupdate=Standard_True;
165 //==================================================
166 // Function: SetSensitivityMode
168 //==================================================
170 void StdSelect_ViewerSelector3d
171 ::SetSensitivityMode(const StdSelect_SensitivityMode aMode)
174 toupdate = Standard_True;
177 //==================================================
178 // Function: SetPixelTolerance
180 //==================================================
182 void StdSelect_ViewerSelector3d
183 ::SetPixelTolerance(const Standard_Integer aTolerance)
185 if(mypixtol!=aTolerance)
187 mypixtol = aTolerance;
188 myupdatetol = Standard_True;
192 //==================================================
193 // Function: SelectPix
195 //==================================================
197 void StdSelect_ViewerSelector3d
198 ::Pick(const Standard_Integer XPix,
199 const Standard_Integer YPix,
200 const Handle(V3d_View)& aView)
202 SetClipping (aView->GetClipPlanes());
204 Standard_Real Xr3d,Yr3d,Zr3d;
206 aView->Convert(XPix,YPix,Xr3d,Yr3d,Zr3d);
207 myprj->Project(gp_Pnt(Xr3d,Yr3d,Zr3d),P2d);
209 InitSelect(P2d.X(),P2d.Y());
213 //==================================================
214 // Function: InitSelect
216 //==================================================
218 void StdSelect_ViewerSelector3d
219 ::Pick(const Standard_Integer XPMin,
220 const Standard_Integer YPMin,
221 const Standard_Integer XPMax,
222 const Standard_Integer YPMax,
223 const Handle(V3d_View)& aView)
225 if (myupdatetol && SensitivityMode() == StdSelect_SM_WINDOW)
227 SetSensitivity (aView->Convert (mypixtol));
228 myupdatetol = Standard_False;
232 Standard_Real x1,y1,z1,x2,y2,z2;
233 gp_Pnt2d P2d_1,P2d_2;
234 aView->Convert(XPMin,YPMin,x1,y1,z1);
235 aView->Convert(XPMax,YPMax,x2,y2,z2);
236 myprj->Project(gp_Pnt(x1,y1,z1),P2d_1);
237 myprj->Project(gp_Pnt(x2,y2,z2),P2d_2);
239 InitSelect (Min(P2d_1.X(),P2d_2.X()),
240 Min(P2d_1.Y(),P2d_2.Y()),
241 Max(P2d_1.X(),P2d_2.X()),
242 Max(P2d_1.Y(),P2d_2.Y()));
245 //==================================================
247 // Purpose : Selection using a polyline
248 //==================================================
250 void StdSelect_ViewerSelector3d::Pick(const TColgp_Array1OfPnt2d& aPolyline, const Handle(V3d_View)& aView)
252 if (myupdatetol && SensitivityMode() == StdSelect_SM_WINDOW)
254 SetSensitivity (aView->Convert (mypixtol));
255 myupdatetol = Standard_False;
260 Standard_Integer NbPix = aPolyline.Length();
264 Handle(TColgp_HArray1OfPnt2d) P2d = new TColgp_HArray1OfPnt2d(1,NbPix);
266 for (i = 1; i <= NbPix; ++i)
269 Standard_Integer XP = (Standard_Integer)(aPolyline(i).X());
270 Standard_Integer YP = (Standard_Integer)(aPolyline(i).Y());
273 aView->Convert (XP, YP, x, y, z);
274 myprj->Project (gp_Pnt (x, y, z), Pnt2d);
276 P2d->SetValue (i, Pnt2d);
279 const TColgp_Array1OfPnt2d& aPolyConvert = P2d->Array1();
281 InitSelect(aPolyConvert);
284 //==================================================
285 // Function: DisplayAreas
286 // Purpose : display the activated areas...
287 //==================================================
289 void StdSelect_ViewerSelector3d::DisplayAreas(const Handle(V3d_View)& aView)
291 if (myupdatetol && SensitivityMode() == StdSelect_SM_WINDOW)
293 SetSensitivity (aView->Convert (mypixtol));
294 myupdatetol = Standard_False;
297 UpdateSort(); // Updates the activated areas
299 if(mystruct.IsNull())
300 mystruct = new Graphic3d_Structure(aView->Viewer()->Viewer());
302 if(myareagroup.IsNull())
303 myareagroup = new Graphic3d_Group(mystruct);
305 SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive It(myentities);
306 Handle(Select3D_Projector) prj = StdSelect::GetProjector(aView);
309 Standard_Real xmin,ymin,xmax,ymax;
311 SelectBasics_ListOfBox2d BoxList;
313 TColgp_SequenceOfPnt aSeqLines;
314 for (; It.More(); It.Next())
316 It.Value()->Areas(BoxList);
317 for (SelectBasics_ListIteratorOfListOfBox2d itb (BoxList); itb.More(); itb.Next())
319 itb.Value().Get (xmin, ymin, xmax, ymax);
321 Pbid.SetCoord (xmin - mytolerance, ymin - mytolerance, 0.0);
322 prj->Transform (Pbid, prj->InvertedTransformation());
323 aSeqLines.Append(Pbid);
325 Pbid.SetCoord (xmax + mytolerance, ymin - mytolerance, 0.0);
326 prj->Transform (Pbid, prj->InvertedTransformation());
327 aSeqLines.Append(Pbid);
329 Pbid.SetCoord (xmax + mytolerance, ymax + mytolerance, 0.0);
330 prj->Transform (Pbid, prj->InvertedTransformation());
331 aSeqLines.Append(Pbid);
333 Pbid.SetCoord (xmin - mytolerance, ymax + mytolerance, 0.0);
334 prj->Transform (Pbid, prj->InvertedTransformation());
335 aSeqLines.Append(Pbid);
339 if (aSeqLines.Length())
341 Standard_Integer n, np;
342 const Standard_Integer nbl = aSeqLines.Length() / 4;
343 Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(5*nbl,nbl);
344 for (np = 1, n=0; n<nbl; n++) {
346 const gp_Pnt &p1 = aSeqLines(np++);
347 aPrims->AddVertex(p1);
348 aPrims->AddVertex(aSeqLines(np++));
349 aPrims->AddVertex(aSeqLines(np++));
350 aPrims->AddVertex(aSeqLines(np++));
351 aPrims->AddVertex(p1);
353 myareagroup->AddPrimitiveArray(aPrims);
356 myareagroup->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_AQUAMARINE1, Aspect_TOL_DASH, 1.0));
357 myareagroup->Structure()->SetDisplayPriority(10);
358 myareagroup->Structure()->Display();
360 if(aView->TransientManagerBeginDraw())
362 Visual3d_TransientManager::DrawStructure(mystruct);
363 Visual3d_TransientManager::EndDraw();
371 //==================================================
372 // Function: ClearAreas
374 //==================================================
376 void StdSelect_ViewerSelector3d::ClearAreas(const Handle(V3d_View)& aView)
378 if(myareagroup.IsNull()) return;
379 myareagroup->Clear();
380 if(aView.IsNull()) return;
381 if(aView->TransientManagerBeginDraw())
382 Visual3d_TransientManager::EndDraw();
387 //==================================================
388 // Function: updateproj
389 // Purpose : at any time verifies that
390 // the view coefficients did not change :
391 // store current view coeffts
392 // in static array cf [ 0->2 At coordinates XAT YAT ZAT
393 // 3->5 Up coordinates XUP YUP ZUP
394 // 6->8 ProjVect coordinates DX DY DZ
396 // 10 1. if pers 0. else
397 //==================================================
399 Standard_Boolean StdSelect_ViewerSelector3d::UpdateProj(const Handle(V3d_View)& aView)
401 myprevcoeff[ 9] = 0.0;
402 myprevcoeff[10] = 0.0;
403 Standard_Boolean Pers = Standard_False;
404 if (aView->Type() == V3d_PERSPECTIVE)
406 Pers = Standard_True;
407 myprevcoeff[10] = 1.0;
408 myprevcoeff[ 9] = aView->Focale();
410 aView->At (myprevcoeff[0], myprevcoeff[1], myprevcoeff[2]);
411 aView->Up (myprevcoeff[3], myprevcoeff[4], myprevcoeff[5]);
412 aView->Proj (myprevcoeff[6], myprevcoeff[7], myprevcoeff[8]);
413 aView->AxialScale (myprevcoeff[11], myprevcoeff[12], myprevcoeff[13]);
414 aView->Center (myprevcenter[0], myprevcenter[1]);
417 for (ii = 0; ii <= 13 && (myprevcoeff[ii] == mycoeff[ii]); ++ii) {}
418 if (ii <= 13 || (myprevcenter[0] != mycenter[0]) || (myprevcenter[1] != mycenter[1]))
420 if (StdSelectDebugModeOn())
422 cout<<"\t\t\t\t\t VS3d::UpdateProj====> coefficients changes on reprojette"<<endl;
424 for (Standard_Integer i = 1; i <= 9; ++i)
426 cout<<mycoeff[i-1]<<" ";
428 cout<<"\n\t\t\t\t\t";
430 cout<<"focale :"<<mycoeff[9]<<" persp :"<<mycoeff[10]<<endl;
431 cout<<"center :"<<mycenter[0]<<" "<<mycenter[1]<<endl;
433 toupdate = Standard_True;
434 myupdatetol = Standard_True;
435 for (Standard_Integer imod = ii; imod <= 13; ++imod)
437 mycoeff[imod] = myprevcoeff[imod];
439 for (Standard_Integer jmod = 0; jmod < 2; ++jmod)
441 mycenter[jmod] = myprevcenter[jmod];
444 gp_Dir Zpers (mycoeff[6], mycoeff[7], mycoeff[8]);
445 gp_Dir Ypers (mycoeff[3], mycoeff[4], mycoeff[5]);
446 gp_Dir Xpers = Ypers.Crossed (Zpers);
447 gp_XYZ loc (mycoeff[0], mycoeff[1], mycoeff[2]);
449 matrix.SetCols (Xpers.XYZ(), Ypers.XYZ(), Zpers.XYZ());
450 gp_Mat matScale (mycoeff[11], 0, 0, 0, mycoeff[12], 0, 0, 0, mycoeff[13]);
452 loc.Multiply (matrix);
454 matrix.Multiply (matScale);
456 GT.SetTranslationPart (loc);
457 GT.SetVectorialPart (matrix);
459 myprj = new Select3D_Projector (GT, Pers, mycoeff[9]);
461 // SAV 08/05/02 : fix for detection problem in a perspective view
462 if (aView->Type() == V3d_PERSPECTIVE)
463 myprj->SetView (aView);
464 // NKV 31/07/07 : fix for detection problem in case of custom matrix
465 else if (aView->ViewOrientation().IsCustomMatrix())
466 myprj->SetView (aView);
469 if (Abs (aView->Scale() - mylastzoom) > 1.e-3)
471 myupdatetol = Standard_True;
472 mylastzoom = aView->Scale();
475 if (myupdatetol && SensitivityMode() == StdSelect_SM_WINDOW)
477 SetSensitivity (aView->Convert (mypixtol));
478 myupdatetol = Standard_False;
481 if (toupdate) UpdateConversion();
482 if (tosort) UpdateSort();
484 return Standard_True;
488 //=============================
489 // Function: DisplaySensitive.
490 // Purpose : Display active primitives.
491 //=============================
492 void StdSelect_ViewerSelector3d::DisplaySensitive(const Handle(V3d_View)& aViou)
494 if (myupdatetol && SensitivityMode() == StdSelect_SM_WINDOW)
496 SetSensitivity (aViou->Convert (mypixtol));
497 myupdatetol = Standard_False;
499 if(toupdate) UpdateProj(aViou);
500 if(tosort) UpdateSort(); // Updates the activated areas
502 // Preparation des structures
503 if(mystruct.IsNull())
504 mystruct = new Graphic3d_Structure(aViou->Viewer()->Viewer());
506 if(mysensgroup.IsNull())
507 mysensgroup = new Graphic3d_Group(mystruct);
509 Quantity_Color Col(Quantity_NOC_INDIANRED3);
510 Handle(Graphic3d_AspectMarker3d) AM =
511 new Graphic3d_AspectMarker3d(Aspect_TOM_O_PLUS,Col,2.);
512 mysensgroup-> SetPrimitivesAspect (AM);
513 mysensgroup->SetPrimitivesAspect (
514 new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0));
516 // Remplissage de la structure...
518 SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation It(myselections);
520 for (; It.More(); It.Next())
524 const Handle(SelectMgr_Selection)& Sel = It.Key();
525 ComputeSensitivePrs(Sel);
529 mysensgroup->Structure()->SetDisplayPriority(10);
531 if (aViou->TransientManagerBeginDraw())
533 Visual3d_TransientManager::DrawStructure(mystruct);
534 Visual3d_TransientManager::EndDraw();
536 else if (!aViou.IsNull())
542 //=============================
543 // Function: ClearSensitive
545 //=============================
546 void StdSelect_ViewerSelector3d::ClearSensitive(const Handle(V3d_View)& aViou)
548 if(mysensgroup.IsNull()) return;
549 mysensgroup->Clear();
550 if(aViou.IsNull()) return;
552 if(aViou->TransientManagerBeginDraw())
553 Visual3d_TransientManager::EndDraw();
558 //=======================================================================
559 //function : DisplaySenstive
561 //=======================================================================
562 void StdSelect_ViewerSelector3d::
563 DisplaySensitive (const Handle(SelectMgr_Selection)& Sel,
564 const Handle(V3d_View)& aViou,
565 const Standard_Boolean ClearOthers)
567 if (mystruct.IsNull())
568 mystruct = new Graphic3d_Structure (aViou->Viewer()->Viewer());
569 if (mysensgroup.IsNull())
571 mysensgroup = new Graphic3d_Group (mystruct);
572 Quantity_Color Col (Quantity_NOC_INDIANRED3);
573 Handle(Graphic3d_AspectMarker3d) AM =
574 new Graphic3d_AspectMarker3d (Aspect_TOM_O_PLUS, Col, 2.0);
575 mysensgroup-> SetPrimitivesAspect (AM);
576 mysensgroup->SetPrimitivesAspect (
577 new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0));
580 if(ClearOthers) mysensgroup->Clear();
582 ComputeSensitivePrs(Sel);
584 mystruct->SetDisplayPriority(10);
586 if(aViou->TransientManagerBeginDraw())
588 Visual3d_TransientManager::DrawStructure(mystruct);
589 Visual3d_TransientManager::EndDraw();
591 else if(!aViou.IsNull())
597 //=======================================================================
598 //function : DisplayAreas
600 //=======================================================================
602 void StdSelect_ViewerSelector3d::
603 DisplayAreas (const Handle(SelectMgr_Selection)& Sel,
604 const Handle(V3d_View)& aViou,
605 const Standard_Boolean ClearOthers)
607 if (mystruct.IsNull())
608 mystruct = new Graphic3d_Structure (aViou->Viewer()->Viewer());
610 if (mysensgroup.IsNull())
612 myareagroup = new Graphic3d_Group (mystruct);
613 myareagroup->SetGroupPrimitivesAspect(new Graphic3d_AspectLine3d (Quantity_NOC_AQUAMARINE1, Aspect_TOL_DASH, 1.0));
616 if(ClearOthers) myareagroup->Clear();
618 ComputeAreasPrs(Sel);
620 mystruct->SetDisplayPriority(10);
623 if(aViou->TransientManagerBeginDraw())
625 Visual3d_TransientManager::DrawStructure(mystruct);
626 Visual3d_TransientManager::EndDraw();
634 //=======================================================================
635 //function : ComputeSensitivePrs
637 //=======================================================================
639 void StdSelect_ViewerSelector3d::ComputeSensitivePrs(const Handle(SelectMgr_Selection)& Sel)
641 TColgp_SequenceOfPnt aSeqLines, aSeqFree;
642 TColStd_SequenceOfInteger aSeqBnds;
644 for(Sel->Init();Sel->More();Sel->Next())
646 Handle(Select3D_SensitiveEntity) Ent = Handle(Select3D_SensitiveEntity)::DownCast(Sel->Sensitive());
647 const Standard_Boolean hasloc = (Ent.IsNull()? Standard_False : Ent->HasLocation());
649 TopLoc_Location theloc;
651 theloc = Ent->Location();
657 if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveBox))
659 const Bnd_Box& B = Handle(Select3D_SensitiveBox)::DownCast (Ent)->Box();
660 Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
661 B.Get (xmin, ymin, zmin, xmax, ymax, zmax);
663 gp_Pnt theboxpoint[8] =
665 gp_Pnt(xmin,ymin,zmin),
666 gp_Pnt(xmax,ymin,zmin),
667 gp_Pnt(xmax,ymax,zmin),
668 gp_Pnt(xmin,ymax,zmin),
669 gp_Pnt(xmin,ymin,zmax),
670 gp_Pnt(xmax,ymin,zmax),
671 gp_Pnt(xmax,ymax,zmax),
672 gp_Pnt(xmin,ymax,zmax)
676 for (i = 0; i <= 7; i++)
677 theboxpoint[i].Transform (theloc.Transformation());
681 for (i = 0; i < 4; i++)
682 aSeqLines.Append(theboxpoint[i]);
683 aSeqLines.Append(theboxpoint[0]);
686 for (i = 4; i < 8; i++)
687 aSeqLines.Append(theboxpoint[i]);
688 aSeqLines.Append(theboxpoint[4]);
690 for (i = 0; i < 4; i++)
693 aSeqLines.Append(theboxpoint[i]);
694 aSeqLines.Append(theboxpoint[i+4]);
700 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveFace))
702 Handle(Select3D_SensitiveFace) aFace = Handle(Select3D_SensitiveFace)::DownCast(Ent);
703 Handle(TColgp_HArray1OfPnt) TheHPts;
704 aFace->Points3D(TheHPts);
705 const TColgp_Array1OfPnt& ThePts = TheHPts->Array1();
707 aSeqBnds.Append(ThePts.Length());
708 for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
711 aSeqLines.Append(ThePts(I).Transformed (theloc.Transformation()));
713 aSeqLines.Append(ThePts(I));
719 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCurve))
721 Handle(Select3D_SensitiveCurve) aCurve = Handle(Select3D_SensitiveCurve)::DownCast(Ent);
722 Handle(TColgp_HArray1OfPnt) TheHPts;
723 aCurve->Points3D(TheHPts);
724 const TColgp_Array1OfPnt& ThePts = TheHPts->Array1();
726 aSeqBnds.Append(ThePts.Length());
727 for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
730 aSeqLines.Append(ThePts(I).Transformed (theloc.Transformation()));
732 aSeqLines.Append(ThePts(I));
738 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveWire))
740 Handle(Select3D_SensitiveWire) aWire = Handle(Select3D_SensitiveWire)::DownCast(Ent);
741 Select3D_SensitiveEntitySequence EntitySeq;
742 aWire->GetEdges (EntitySeq);
744 for (int i = 1; i <= EntitySeq.Length(); i++)
746 Handle(Select3D_SensitiveEntity) SubEnt = Handle(Select3D_SensitiveEntity)::DownCast(EntitySeq.Value(i));
749 if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveSegment))
751 gp_Pnt P1 (Handle(Select3D_SensitiveSegment)::DownCast(SubEnt)->StartPoint().XYZ());
752 gp_Pnt P2 (Handle(Select3D_SensitiveSegment)::DownCast(SubEnt)->EndPoint().XYZ());
755 P1.Transform(theloc.Transformation());
756 P2.Transform(theloc.Transformation());
759 aSeqLines.Append(P1);
760 aSeqLines.Append(P2);
764 if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCircle))
766 Handle(Select3D_SensitiveCircle) C = Handle(Select3D_SensitiveCircle)::DownCast(SubEnt);
767 Standard_Integer Lo, Up;
768 C->ArrayBounds (Lo, Up);
769 Standard_Integer II = Lo;
774 gp_Pnt (C->GetPoint3d (II).XYZ()),
775 gp_Pnt (C->GetPoint3d (++II).XYZ()),
776 gp_Pnt (C->GetPoint3d (++II).XYZ())
781 for (Standard_Integer jj = 0; jj <= 2; jj++)
782 ThePts[jj].Transform (theloc.Transformation());
786 aSeqLines.Append(ThePts[0]);
787 aSeqLines.Append(ThePts[1]);
788 aSeqLines.Append(ThePts[2]);
789 aSeqLines.Append(ThePts[0]);
794 if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCurve))
796 Handle(Select3D_SensitiveCurve) aCurve = Handle(Select3D_SensitiveCurve)::DownCast(SubEnt);
797 Handle(TColgp_HArray1OfPnt) TheHPts;
798 aCurve->Points3D (TheHPts);
799 const TColgp_Array1OfPnt& ThePts = TheHPts->Array1();
801 aSeqBnds.Append(ThePts.Length());
802 for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
805 aSeqLines.Append(ThePts(I).Transformed (theloc.Transformation()));
807 aSeqLines.Append(ThePts(I));
815 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveSegment))
817 gp_Pnt P1 (Handle(Select3D_SensitiveSegment)::DownCast(Ent)->StartPoint().XYZ());
818 gp_Pnt P2 (Handle(Select3D_SensitiveSegment)::DownCast(Ent)->EndPoint().XYZ());
821 P1.Transform (theloc.Transformation());
822 P2.Transform (theloc.Transformation());
825 aSeqLines.Append(P1);
826 aSeqLines.Append(P2);
831 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCircle))
833 Handle(Select3D_SensitiveCircle) C = Handle(Select3D_SensitiveCircle)::DownCast(Ent);
834 Standard_Integer Lo, Up;
835 C->ArrayBounds (Lo, Up);
836 Standard_Integer II = Lo;
841 gp_Pnt (C->GetPoint3d (II).XYZ()),
842 gp_Pnt (C->GetPoint3d (++II).XYZ()),
843 gp_Pnt (C->GetPoint3d (++II).XYZ())
848 for (Standard_Integer jj = 0; jj <= 2; jj++)
849 ThePts[jj].Transform (theloc.Transformation());
853 aSeqLines.Append(ThePts[0]);
854 aSeqLines.Append(ThePts[1]);
855 aSeqLines.Append(ThePts[2]);
856 aSeqLines.Append(ThePts[0]);
862 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitivePoint))
865 Handle(Select3D_SensitivePoint)::DownCast(Ent)->Point() :
866 Handle(Select3D_SensitivePoint)::DownCast(Ent)->Point().Transformed (theloc.Transformation());
867 Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints = new Graphic3d_ArrayOfPoints (1);
868 anArrayOfPoints->AddVertex (P.X(), P.Y(), P.Z());
869 mysensgroup->AddPrimitiveArray (anArrayOfPoints);
871 //============================================================
872 // Triangulation : On met un petit offset ves l'interieur...
873 //==========================================================
874 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveTriangulation))
876 const Handle(Poly_Triangulation)& PT =
877 (*((Handle(Select3D_SensitiveTriangulation)*) &Ent))->Triangulation();
879 const Poly_Array1OfTriangle& triangles = PT->Triangles();
880 const TColgp_Array1OfPnt& Nodes = PT->Nodes();
881 Standard_Integer n[3];
883 TopLoc_Location iloc, bidloc;
884 if ((*((Handle(Select3D_SensitiveTriangulation)*) &Ent))->HasInitLocation())
885 bidloc = (*((Handle(Select3D_SensitiveTriangulation)*) &Ent))->GetInitLocation();
887 if (bidloc.IsIdentity())
890 iloc = theloc * bidloc;
893 for (i = 1; i <= PT->NbTriangles(); i++)
895 triangles (i).Get (n[0], n[1], n[2]);
896 gp_Pnt P1 (Nodes (n[0]).Transformed (iloc));
897 gp_Pnt P2 (Nodes (n[1]).Transformed (iloc));
898 gp_Pnt P3 (Nodes (n[2]).Transformed (iloc));
899 gp_XYZ V1 (P1.XYZ());
900 gp_XYZ V2 (P2.XYZ());
901 gp_XYZ V3 (P3.XYZ());
902 gp_XYZ CDG (P1.XYZ()); CDG += (P2.XYZ()); CDG += (P3.XYZ()); CDG /= 3.0;
903 V1 -= CDG; V2 -= CDG; V3 -= CDG;
904 V1 *= 0.9; V2 *= 0.9; V3 *= 0.9;
905 V1 += CDG; V2 += CDG; V3 += CDG;
908 aSeqLines.Append(gp_Pnt(V1));
909 aSeqLines.Append(gp_Pnt(V2));
910 aSeqLines.Append(gp_Pnt(V3));
911 aSeqLines.Append(gp_Pnt(V1));
914 // recherche des bords libres...
916 Handle(TColStd_HArray1OfInteger) FreeEdges = new TColStd_HArray1OfInteger (1, 2 * StdSel_NumberOfFreeEdges (PT));
917 TColStd_Array1OfInteger& FreeE = FreeEdges->ChangeArray1();
918 Poly_Connect pc (PT);
919 Standard_Integer t[3];
921 Standard_Integer fr (1);
922 for (i = 1; i <= PT->NbTriangles(); i++)
924 pc.Triangles (i, t[0], t[1], t[2]);
925 triangles (i).Get (n[0], n[1], n[2]);
926 for (j = 0; j < 3; j++)
928 Standard_Integer k = (j + 1) % 3;
932 FreeE (fr + 1)= n[k];
937 for (Standard_Integer ifri = 1; ifri <= FreeE.Length(); ifri += 2)
939 gp_Pnt pe1 (Nodes (FreeE (ifri)).Transformed (iloc)), pe2 (Nodes (FreeE (ifri + 1)).Transformed (iloc));
940 aSeqFree.Append(pe1);
941 aSeqFree.Append(pe2);
944 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveTriangle))
946 Handle(Select3D_SensitiveTriangle) Str = Handle(Select3D_SensitiveTriangle)::DownCast(Ent);
948 Str->Points3D (P1, P2, P3);
949 gp_Pnt CDG = Str->Center3D();
951 gp_XYZ V1 (P1.XYZ()); V1 -= (CDG.XYZ());
952 gp_XYZ V2 (P2.XYZ()); V2 -= (CDG.XYZ());
953 gp_XYZ V3 (P3.XYZ()); V3 -= (CDG.XYZ());
954 V1 *= 0.9; V2 *= 0.9; V3 *= 0.9;
955 V1 += CDG.XYZ(); V2 += CDG.XYZ(); V3 += CDG.XYZ();
958 aSeqLines.Append(gp_Pnt(V1));
959 aSeqLines.Append(gp_Pnt(V2));
960 aSeqLines.Append(gp_Pnt(V3));
961 aSeqLines.Append(gp_Pnt(V1));
967 if (aSeqLines.Length())
969 Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(aSeqLines.Length(),aSeqBnds.Length());
970 for (i = 1; i <= aSeqLines.Length(); i++)
971 aPrims->AddVertex(aSeqLines(i));
972 for (i = 1; i <= aSeqBnds.Length(); i++)
973 aPrims->AddBound(aSeqBnds(i));
974 myareagroup->AddPrimitiveArray(aPrims);
977 if (aSeqFree.Length())
979 mysensgroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_GREEN, Aspect_TOL_SOLID, 2.0));
980 Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(aSeqFree.Length(),aSeqFree.Length()/2);
981 for (i = 1; i <= aSeqFree.Length(); i++)
984 aPrims->AddVertex(aSeqLines(i++));
985 aPrims->AddVertex(aSeqLines(i));
987 mysensgroup->AddPrimitiveArray(aPrims);
988 mysensgroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0));
992 //=======================================================================
993 //function : ComputeAreaPrs
995 //=======================================================================
997 void StdSelect_ViewerSelector3d::ComputeAreasPrs (const Handle(SelectMgr_Selection)& Sel)
999 Standard_Real xmin, ymin, xmax, ymax;
1001 SelectBasics_ListOfBox2d BoxList;
1003 TColgp_SequenceOfPnt aSeqLines;
1004 for (Sel->Init(); Sel->More(); Sel->Next())
1006 Sel->Sensitive()->Areas (BoxList);
1007 for (SelectBasics_ListIteratorOfListOfBox2d itb (BoxList); itb.More(); itb.Next())
1009 itb.Value().Get (xmin, ymin, xmax, ymax);
1011 Pbid.SetCoord (xmin - mytolerance, ymin - mytolerance, 0.0);
1012 myprj->Transform (Pbid, myprj->InvertedTransformation());
1013 aSeqLines.Append(Pbid);
1015 Pbid.SetCoord (xmax + mytolerance, ymin - mytolerance, 0.0);
1016 myprj->Transform (Pbid, myprj->InvertedTransformation());
1017 aSeqLines.Append(Pbid);
1019 Pbid.SetCoord (xmax + mytolerance, ymax + mytolerance, 0.0);
1020 myprj->Transform (Pbid, myprj->InvertedTransformation());
1021 aSeqLines.Append(Pbid);
1023 Pbid.SetCoord (xmin - mytolerance, ymax + mytolerance, 0.0);
1024 myprj->Transform (Pbid, myprj->InvertedTransformation());
1025 aSeqLines.Append(Pbid);
1029 if (aSeqLines.Length())
1031 Standard_Integer n, np;
1032 const Standard_Integer nbl = aSeqLines.Length() / 4;
1033 Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(5*nbl,nbl);
1034 for (np = 1, n=0; n<nbl; n++) {
1035 aPrims->AddBound(5);
1036 const gp_Pnt &p1 = aSeqLines(np++);
1037 aPrims->AddVertex(p1);
1038 aPrims->AddVertex(aSeqLines(np++));
1039 aPrims->AddVertex(aSeqLines(np++));
1040 aPrims->AddVertex(aSeqLines(np++));
1041 aPrims->AddVertex(p1);
1043 myareagroup->AddPrimitiveArray(aPrims);
1047 //=======================================================================
1048 //function : SetClipping
1050 //=======================================================================
1051 void StdSelect_ViewerSelector3d::SetClipping (const Graphic3d_SetOfHClipPlane& thePlanes)
1053 myClipPlanes = thePlanes;
1056 //=======================================================================
1057 //function : ComputeClipRange
1059 //=======================================================================
1060 void StdSelect_ViewerSelector3d::ComputeClipRange (const Graphic3d_SetOfHClipPlane& thePlanes,
1061 const gp_Lin& thePickLine,
1062 Standard_Real& theDepthMin,
1063 Standard_Real& theDepthMax) const
1065 theDepthMin = RealFirst();
1066 theDepthMax = RealLast();
1067 Standard_Real aPlaneA, aPlaneB, aPlaneC, aPlaneD;
1069 Graphic3d_SetOfHClipPlane::Iterator aPlaneIt (thePlanes);
1070 for (; aPlaneIt.More(); aPlaneIt.Next())
1072 const Handle(Graphic3d_ClipPlane)& aClipPlane = aPlaneIt.Value();
1073 if (!aClipPlane->IsOn())
1076 gp_Pln aGeomPlane = aClipPlane->ToPlane();
1078 aGeomPlane.Coefficients (aPlaneA, aPlaneB, aPlaneC, aPlaneD);
1080 const gp_Dir& aPlaneDir = aGeomPlane.Axis().Direction();
1081 const gp_Dir& aPickDir = thePickLine.Direction();
1082 const gp_XYZ& aPntOnLine = thePickLine.Location().XYZ();
1083 const gp_XYZ& aPlaneDirXYZ = aPlaneDir.XYZ();
1085 Standard_Real aDotProduct = aPickDir.Dot (aPlaneDir);
1086 Standard_Real aDistance = -(aPntOnLine.Dot (aPlaneDirXYZ) + aPlaneD);
1088 // check whether the pick line is parallel to clip plane
1089 if (Abs (aDotProduct) < Precision::Angular())
1091 if (aDistance > 0.0)
1093 // line lies above the plane, thus no selection is possible
1099 // line lies below the plane and is not clipped, skip
1103 // compute distance to point of pick line intersection with the plane
1104 Standard_Real aIntDist = aDistance / aDotProduct;
1106 // change depth limits for case of opposite and directed planes
1107 if (aDotProduct < 0.0)
1109 theDepthMax = Min (aIntDist, theDepthMax);
1111 else if (aIntDist > theDepthMin)
1113 theDepthMin = Max (aIntDist, theDepthMin);
1118 //=======================================================================
1119 //function : PickingLine
1121 //=======================================================================
1122 gp_Lin StdSelect_ViewerSelector3d::PickingLine(const Standard_Real theX, const Standard_Real theY) const
1124 return myprj->Shoot (theX, theY);
1127 //=======================================================================
1128 //function : DepthClipping
1130 //=======================================================================
1131 void StdSelect_ViewerSelector3d::DepthClipping (const Standard_Real theX,
1132 const Standard_Real theY,
1133 Standard_Real& theDepthMin,
1134 Standard_Real& theDepthMax) const
1136 return ComputeClipRange (myClipPlanes, PickingLine (theX, theY), theDepthMin, theDepthMax);
1139 //=======================================================================
1140 //function : DepthClipping
1142 //=======================================================================
1143 void StdSelect_ViewerSelector3d::DepthClipping (const Standard_Real theX,
1144 const Standard_Real theY,
1145 const Handle(SelectMgr_EntityOwner)& theOwner,
1146 Standard_Real& theDepthMin,
1147 Standard_Real& theDepthMax) const
1149 return ComputeClipRange (theOwner->Selectable()->GetClipPlanes(),
1150 PickingLine (theX, theY),
1151 theDepthMin, theDepthMax);
1154 //=======================================================================
1155 //function : HasDepthClipping
1157 //=======================================================================
1158 Standard_Boolean StdSelect_ViewerSelector3d::HasDepthClipping (const Handle(SelectMgr_EntityOwner)& theOwner) const
1160 if (!theOwner->HasSelectable())
1162 return Standard_False;
1165 const Handle(SelectMgr_SelectableObject)& aSelectable = theOwner->Selectable();
1166 return (aSelectable->GetClipPlanes().Size() > 0);