1 // Created on: 2014-05-22
2 // Created by: Varvara POSKONINA
3 // Copyright (c) 2005-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <SelectMgr_BaseFrustum.hxx>
17
18 #include <Message.hxx>
19 #include <SelectMgr_FrustumBuilder.hxx>
20 #include <Standard_Dump.hxx>
21
IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_BaseFrustum,SelectMgr_BaseIntersector)22 IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_BaseFrustum, SelectMgr_BaseIntersector)
23
24 //=======================================================================
25 // function : SelectMgr_BaseFrustum
26 // purpose :
27 //=======================================================================
28 SelectMgr_BaseFrustum::SelectMgr_BaseFrustum()
29 : myPixelTolerance (2)
30 {
31 myBuilder = new SelectMgr_FrustumBuilder();
32 }
33
34 //=======================================================================
35 // function : SetCamera
36 // purpose :
37 //=======================================================================
SetCamera(const Handle (Graphic3d_Camera)& theCamera)38 void SelectMgr_BaseFrustum::SetCamera (const Handle(Graphic3d_Camera)& theCamera)
39 {
40 SelectMgr_BaseIntersector::SetCamera (theCamera);
41 if (!myBuilder.IsNull())
42 {
43 myBuilder->SetCamera (theCamera);
44 myBuilder->InvalidateViewport();
45 }
46 }
47
48 //=======================================================================
49 // function : SetViewport
50 // purpose : Passes viewport parameters to builder
51 //=======================================================================
SetViewport(const Standard_Real theX,const Standard_Real theY,const Standard_Real theWidth,const Standard_Real theHeight)52 void SelectMgr_BaseFrustum::SetViewport (const Standard_Real theX,
53 const Standard_Real theY,
54 const Standard_Real theWidth,
55 const Standard_Real theHeight)
56 {
57 myBuilder->SetViewport (theX, theY, theWidth, theHeight);
58 }
59
60 //=======================================================================
61 // function : SetPixelTolerance
62 // purpose :
63 //=======================================================================
SetPixelTolerance(const Standard_Integer theTol)64 void SelectMgr_BaseFrustum::SetPixelTolerance (const Standard_Integer theTol)
65 {
66 myPixelTolerance = theTol;
67 }
68
69 //=======================================================================
70 // function : SetWindowSize
71 // purpose :
72 //=======================================================================
SetWindowSize(const Standard_Integer theWidth,const Standard_Integer theHeight)73 void SelectMgr_BaseFrustum::SetWindowSize (const Standard_Integer theWidth, const Standard_Integer theHeight)
74 {
75 myBuilder->SetWindowSize (theWidth, theHeight);
76 }
77
78 //=======================================================================
79 // function : WindowSize
80 // purpose :
81 //=======================================================================
WindowSize(Standard_Integer & theWidth,Standard_Integer & theHeight) const82 void SelectMgr_BaseFrustum::WindowSize (Standard_Integer& theWidth,
83 Standard_Integer& theHeight) const
84 {
85 myBuilder->WindowSize (theWidth, theHeight);
86 }
87
88 //=======================================================================
89 // function : SetBuilder
90 // purpose :
91 //=======================================================================
SetBuilder(const Handle (SelectMgr_FrustumBuilder)& theBuilder)92 void SelectMgr_BaseFrustum::SetBuilder (const Handle(SelectMgr_FrustumBuilder)& theBuilder)
93 {
94 myBuilder.Nullify();
95 myBuilder = theBuilder;
96 if (!myBuilder.IsNull())
97 {
98 myCamera = myBuilder->Camera();
99 }
100 }
101
102 //=======================================================================
103 // function : IsBoundariesIntersectSphere
104 // purpose :
105 //=======================================================================
IsBoundaryIntersectSphere(const gp_Pnt & theCenter,const Standard_Real theRadius,const gp_Dir & thePlaneNormal,const TColgp_Array1OfPnt & theBoundaries,Standard_Boolean & theBoundaryInside) const106 Standard_Boolean SelectMgr_BaseFrustum::IsBoundaryIntersectSphere (const gp_Pnt& theCenter,
107 const Standard_Real theRadius,
108 const gp_Dir& thePlaneNormal,
109 const TColgp_Array1OfPnt& theBoundaries,
110 Standard_Boolean& theBoundaryInside) const
111 {
112 for (Standard_Integer anIdx = theBoundaries.Lower(); anIdx < theBoundaries.Upper(); ++anIdx)
113 {
114 const Standard_Integer aNextIdx = ((anIdx + 1) == theBoundaries.Upper()) ? theBoundaries.Lower() : (anIdx + 1);
115 const gp_Pnt aPnt1 = theBoundaries.Value (anIdx);
116 const gp_Pnt aPnt2 = theBoundaries.Value (aNextIdx);
117 if (aPnt1.Distance (aPnt2) < Precision::Confusion())
118 {
119 continue;
120 }
121
122 // Projections of the points on the plane
123 const gp_Pnt aPntProj1 = aPnt1.XYZ() - thePlaneNormal.XYZ() * aPnt1.XYZ().Dot (thePlaneNormal.XYZ());
124 const gp_Pnt aPntProj2 = aPnt2.XYZ() - thePlaneNormal.XYZ() * aPnt2.XYZ().Dot (thePlaneNormal.XYZ());
125 if (aPntProj1.Distance (theCenter) < theRadius || aPntProj2.Distance (theCenter) < theRadius) // polygon intersects the sphere
126 {
127 theBoundaryInside = Standard_True;
128 return Standard_True;
129 }
130
131 gp_Dir aRayDir (gp_Vec (aPntProj1, aPntProj2));
132 Standard_Real aTimeEnter = 0.0, aTimeLeave = 0.0;
133 if (RaySphereIntersection (theCenter, theRadius, aPntProj1, aRayDir, aTimeEnter, aTimeLeave))
134 {
135 if ((aTimeEnter > 0 && aTimeEnter < aPntProj1.Distance (aPntProj2))
136 || (aTimeLeave > 0 && aTimeLeave < aPntProj1.Distance (aPntProj2)))
137 {
138 return Standard_True; // polygon crosses the sphere
139 }
140 }
141 }
142 return Standard_False;
143 }
144
145 //=======================================================================
146 //function : DumpJson
147 //purpose :
148 //=======================================================================
DumpJson(Standard_OStream & theOStream,Standard_Integer theDepth) const149 void SelectMgr_BaseFrustum::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
150 {
151 OCCT_DUMP_CLASS_BEGIN (theOStream, SelectMgr_BaseFrustum)
152 OCCT_DUMP_BASE_CLASS (theOStream, theDepth, SelectMgr_BaseIntersector)
153
154 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myPixelTolerance)
155 OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, myBuilder)
156 }
157