CFx SDK Documentation  2020SP3
SiVolume.h
Go to the documentation of this file.
1 // Copyright (C) 2002-2017, Open Design Alliance (the "Alliance").
3 // All rights reserved.
4 //
5 // This software and its documentation and related materials are owned by
6 // the Alliance. The software may only be incorporated into application
7 // programs owned by members of the Alliance, subject to a signed
8 // Membership Agreement and Supplemental Software License Agreement with the
9 // Alliance. The structure and organization of this software are the valuable
10 // trade secrets of the Alliance and its suppliers. The software is also
11 // protected by copyright law and international treaty provisions. Application
12 // programs incorporating this software must include the following statement
13 // with their copyright notices:
14 //
15 // This application incorporates Teigha(R) software pursuant to a license
16 // agreement with Open Design Alliance.
17 // Teigha(R) Copyright (C) 2002-2017 by Open Design Alliance.
18 // All rights reserved.
19 //
20 // By use of this software, its documentation or related materials, you
21 // acknowledge and accept the above terms.
23 // Volumetric spatial index query shape. For perspective mode projections.
24 
25 #ifndef _SpVolume_h_Included_
26 #define _SpVolume_h_Included_
27 
28 #include "TD_PackPush.h"
29 
30 #include "Si/SiSpatialIndex.h"
31 #include "Ge/GePlane.h"
32 
33 namespace OdSi
34 {
35 
36 class Volume : public OdSiShape
37 {
38  protected:
39  // Subset of OdGePlane functionality. Optimized allocation, transforms and accessibility.
40  class PlaneImpl
41  {
42  OdGePoint3d m_origin;
43  OdGeVector3d m_normal;
44  double m_dist;
45  public:
46  PlaneImpl() : m_dist(0.0) { }
47  PlaneImpl(const PlaneImpl &pl2) : m_origin(pl2.m_origin), m_normal(pl2.m_normal), m_dist(pl2.m_dist) { }
49  {
50  m_origin = pl2.m_origin; m_normal = pl2.m_normal; m_dist = pl2.m_dist;
51  return *this;
52  }
53 
54  void set(const OdGePoint3d &origin, const OdGeVector3d &normal)
55  {
56  m_origin = origin;
57  m_normal = normal;
58  m_dist = -m_normal.dotProduct(m_origin.asVector());
59  }
60  void transformBy(const OdGeMatrix3d &xfm)
61  {
62  m_origin.transformBy(xfm);
63  m_normal.transformBy(xfm);
64  m_normal.normalize();
65  m_dist = -m_normal.dotProduct(m_origin.asVector());
66  }
67  void getCoefficients(double& a, double& b, double& c, double& d) const
68  {
69  a = m_normal.x; b = m_normal.y; c = m_normal.z; d = m_dist;
70  }
71  };
73  //OdGePlane m_plane[6];
75  bool m_planeValid[6];
76  public:
77  Volume() : m_nPlanes(0) {}
79  {
80  for (OdUInt32 npl = 0; npl < m_nPlanes; npl++)
81  {
82  if (source.m_planeValid[npl])
83  m_plane[npl] = source.m_plane[npl];
84  m_planeValid[npl] = source.m_planeValid[npl];
85  }
86  }
87  Volume( const OdGePoint3d& origin, const OdGeVector3d& zAxis, const OdGeVector3d& yAxis, const OdGeVector3d& xAxis,
88  double xFov, double yFov, bool xFovAsAspect = false, bool yFovAsAspect = false,
89  bool bNearPlane = false, double fNearPlane = 0.01,
90  bool bFarPlane = false, double fFarPlane = 1.0 );
91 
92  // Si interface
93  virtual bool contains( const OdGeExtents3d& extents, bool planar = false, const OdGeTol& tol = OdGeContext::gTol ) const;
94 
95  virtual bool intersects( const OdGeExtents3d& extents, bool planar = false, const OdGeTol& tol = OdGeContext::gTol ) const;
96 
97  virtual OdSiShape* clone() const
98  {
99  return new Volume(*this);
100  }
101 
102  virtual void transform(const OdGeMatrix3d& mtx)
103  {
104  for (OdUInt32 npl = 0; npl < m_nPlanes; npl++)
105  {
106  if (m_planeValid[npl])
107  m_plane[npl].transformBy(mtx);
108  }
109  }
110 
111  // misc
112  static double fovToPlane(double fov, double len)
113  {
114  return 2.0 * (len * tan(fov * 0.5));
115  }
116  static double fovFromPlane(double plane, double len)
117  {
118  return atan(plane / len * .5) * 2.0;
119  }
120  protected:
121  static bool planeFromTri(const OdGePoint3d &A, const OdGePoint3d &B, const OdGePoint3d &C, /*OdGePlane*/ PlaneImpl &pl)
122  {
123  OdGeVector3d u = B - A;
124  OdGeVector3d v = C - A;
125  if (!u.isZeroLength(1e-100) && !v.isZeroLength(1e-100))
126  {
127  u.normalize(1e-100);
128  v.normalize(1e-100);
129  }
130  else
131  {
132  return false;
133  }
134  pl.set(A, u.crossProduct(v).normal());
135  return true;
136  }
137  static bool aabbInsidePlane(const OdGePoint3d &min, const OdGePoint3d &max, const /*OdGePlane*/ PlaneImpl &plane, const OdGeTol &tol)
138  {
139  double pt[3];
140  double pl[4];
141  plane.getCoefficients(pl[0], pl[1], pl[2], pl[3]);
142  pt[0] = (pl[0] > 0.0) ? max.x : min.x;
143  pt[1] = (pl[1] > 0.0) ? max.y : min.y;
144  pt[2] = (pl[2] > 0.0) ? max.z : min.z;
145  return pl[0] * pt[0] + pl[1] * pt[1] + pl[2] * pt[2] + pl[3] >= /*0.0*/ -tol.equalVector();
146  }
147 };
148 
149 inline
150 Volume::Volume( const OdGePoint3d& origin, const OdGeVector3d& zAxis, const OdGeVector3d& yAxis, const OdGeVector3d& xAxis,
151  double xFov, double yFov, bool xFovAsAspect, bool yFovAsAspect,
152  bool bNearPlane, double fNearPlane,
153  bool bFarPlane, double fFarPlane )
154 {
155  // Aspect is width/height, so x is y*aspect, y is x/aspect
156  ODA_ASSERT(!(xFovAsAspect && yFovAsAspect));
157  double nearPlane_ = odmax(fNearPlane, 1.0); // near plane is required for plane calculation
158  double planeWidth = 1., planeHeight = 1.;
159  if (!xFovAsAspect)
160  planeWidth = fovToPlane(xFov, nearPlane_);
161  if (!yFovAsAspect)
162  planeHeight = fovToPlane(yFov, nearPlane_);
163  if (xFovAsAspect)
164  planeWidth = xFov * planeHeight;
165  if (yFovAsAspect)
166  planeHeight = planeWidth / yFov;
167  OdGeVector3d basisX(xAxis.normal()), basisY(yAxis.normal()), basisZ(zAxis.normal());
168  //basisX = basisZ.crossProduct(basisY).normal(); // from input, for support isotropy
169  OdGeVector3d deltaX = basisX * (planeWidth * 0.5);
170  OdGeVector3d deltaY = basisY * (planeHeight * 0.5);
171  OdGePoint3d nearPlane = origin + basisZ * nearPlane_;
172  OdGePoint3d planeQuad[4] =
173  {
174  nearPlane - deltaX - deltaY,
175  nearPlane + deltaX - deltaY,
176  nearPlane + deltaX + deltaY,
177  nearPlane - deltaX + deltaY
178  };
179  m_planeValid[0] = planeFromTri(planeQuad[0], origin, planeQuad[1], m_plane[0]);
180  m_planeValid[1] = planeFromTri(planeQuad[1], origin, planeQuad[2], m_plane[1]);
181  m_planeValid[2] = planeFromTri(planeQuad[2], origin, planeQuad[3], m_plane[2]);
182  m_planeValid[3] = planeFromTri(planeQuad[3], origin, planeQuad[0], m_plane[3]);
183  if (bNearPlane || bFarPlane)
184  {
185  m_planeValid[4] = bNearPlane;
186  if (bNearPlane)
187  m_plane[4].set(origin + basisZ * fNearPlane, basisZ);
188  if (bFarPlane)
189  {
190  m_planeValid[5] = true;
191  m_plane[5].set(origin + basisZ * fFarPlane, -basisZ);
192  m_nPlanes = 6;
193  }
194  else
195  m_nPlanes = 5;
196  }
197  else
198  m_nPlanes = 4;
199 }
200 
201 inline
202 bool Volume::contains( const OdGeExtents3d& extents, bool planar, const OdGeTol& tol ) const
203 {
204  ODA_ASSERT( planar == false );
205  OdUInt32 i;
206  for (i = 0; i < m_nPlanes; i++)
207  {
208  if (!m_planeValid[i])
209  continue;
210  if (!aabbInsidePlane(extents.minPoint(), extents.maxPoint(), m_plane[i], tol))
211  return false; // entirely outside
212  }
213  for (i = 0; i < m_nPlanes; i++)
214  {
215  if (!m_planeValid[i])
216  continue;
217  if (!aabbInsidePlane(extents.maxPoint(), extents.minPoint(), m_plane[i], tol))
218  return false; // intersects
219  }
220  return true; // entirely inside
221 }
222 
223 inline
224 bool Volume::intersects( const OdGeExtents3d& extents, bool planar, const OdGeTol& tol ) const
225 {
226  ODA_ASSERT( planar == false );
227  for (OdUInt32 i = 0; i < m_nPlanes; i++)
228  {
229  if (!m_planeValid[i])
230  continue;
231  if (!aabbInsidePlane(extents.minPoint(), extents.maxPoint(), m_plane[i], tol))
232  return false;
233  }
234  return true;
235 }
236 
237 } // OdSi
238 
239 #include "TD_PackPop.h"
240 
241 #endif // _SpVolume_h_Included_
OdGeVector3d::normalize
OdGeVector3d & normalize(const OdGeTol &tol=OdGeContext::gTol)
OdGeVector3d
Definition: GeVector3d.h:54
OdSi::Volume::m_planeValid
bool m_planeValid[6]
Definition: SiVolume.h:75
OdSi::Volume::m_nPlanes
OdUInt32 m_nPlanes
Definition: SiVolume.h:72
OdSi
Definition: SiVolume.h:34
OdSi::Volume::fovFromPlane
static double fovFromPlane(double plane, double len)
Definition: SiVolume.h:116
tol
tol
Definition: DimVarDefs.h:2287
OdSi::Volume::PlaneImpl::PlaneImpl
PlaneImpl(const PlaneImpl &pl2)
Definition: SiVolume.h:47
OdGeVector3d::x
double x
Definition: GeVector3d.h:601
OdSi::Volume::clone
virtual OdSiShape * clone() const
Definition: SiVolume.h:97
OdGeVector3d::z
double z
Definition: GeVector3d.h:603
source
GLsizei GLsizei GLchar * source
Definition: gles2_ext.h:282
OdSi::Volume::PlaneImpl::getCoefficients
void getCoefficients(double &a, double &b, double &c, double &d) const
Definition: SiVolume.h:67
FacetModelerProfile2DBool::min
const T & min(const T &x, const T &y)
Definition: FMImpProfile2DBool.h:98
SiSpatialIndex.h
TD_PackPop.h
GePlane.h
OdGeVector3d::normal
OdGeVector3d normal(const OdGeTol &tol=OdGeContext::gTol) const
OdUInt32
unsigned int OdUInt32
Definition: OdPlatformSettings.h:783
OdGeMatrix3d
Definition: GeMatrix3d.h:73
OdSi::Volume::Volume
Volume()
Definition: SiVolume.h:77
OdSi::Volume::PlaneImpl
Definition: SiVolume.h:41
OdGeExtents3d::minPoint
const OdGePoint3d & minPoint() const
Definition: GeExtents3d.h:237
OdSi::Volume::planeFromTri
static bool planeFromTri(const OdGePoint3d &A, const OdGePoint3d &B, const OdGePoint3d &C, PlaneImpl &pl)
Definition: SiVolume.h:121
OdSi::Volume::PlaneImpl::PlaneImpl
PlaneImpl()
Definition: SiVolume.h:46
OdSi::Volume::transform
virtual void transform(const OdGeMatrix3d &mtx)
Definition: SiVolume.h:102
OdSi::Volume::Volume
Volume(const Volume &source)
Definition: SiVolume.h:78
OdGePoint3d::asVector
const OdGeVector3d & asVector() const
Definition: GePoint3d.h:246
OdSi::Volume::PlaneImpl::transformBy
void transformBy(const OdGeMatrix3d &xfm)
Definition: SiVolume.h:60
OdGePoint3d
Definition: GePoint3d.h:55
OdSi::Volume::m_plane
PlaneImpl m_plane[6]
Definition: SiVolume.h:74
OdGeVector3d::crossProduct
OdGeVector3d crossProduct(const OdGeVector3d &vect) const
OdGeVector3d::transformBy
OdGeVector3d & transformBy(const OdGeMatrix3d &xfm)
FacetModelerProfile2DBool::max
const T & max(const T &x, const T &y)
Definition: FMImpProfile2DBool.h:105
OdSi::Volume::intersects
virtual bool intersects(const OdGeExtents3d &extents, bool planar=false, const OdGeTol &tol=OdGeContext::gTol) const
Definition: SiVolume.h:224
v
const GLfloat * v
Definition: gles2_ext.h:315
OdSi::Volume::contains
virtual bool contains(const OdGeExtents3d &extents, bool planar=false, const OdGeTol &tol=OdGeContext::gTol) const
Definition: SiVolume.h:202
OdGeVector3d::isZeroLength
bool isZeroLength(const OdGeTol &tol=OdGeContext::gTol) const
TD_PackPush.h
OdSiShape
Definition: SiSpatialIndex.h:51
OdSi::Volume::aabbInsidePlane
static bool aabbInsidePlane(const OdGePoint3d &min, const OdGePoint3d &max, const PlaneImpl &plane, const OdGeTol &tol)
Definition: SiVolume.h:137
odmax
#define odmax(X, Y)
Definition: OdPlatform.h:35
OdGeExtents3d::maxPoint
const OdGePoint3d & maxPoint() const
Definition: GeExtents3d.h:242
OdSi::Volume
Definition: SiVolume.h:37
ODA_ASSERT
#define ODA_ASSERT(exp)
Definition: DebugStuff.h:49
OdGeContext::gTol
static GE_STATIC_EXPORT OdGeTol gTol
Definition: GeGbl.h:60
OdGeExtents3d
Definition: GeExtents3d.h:45
OdGePoint3d::transformBy
OdGePoint3d & transformBy(const OdGeMatrix3d &xfm)
OdSi::Volume::fovToPlane
static double fovToPlane(double fov, double len)
Definition: SiVolume.h:112
OdSi::Volume::PlaneImpl::set
void set(const OdGePoint3d &origin, const OdGeVector3d &normal)
Definition: SiVolume.h:54
OdGeTol
Definition: GeTol.h:49
OdGeVector3d::y
double y
Definition: GeVector3d.h:602
OdSi::Volume::PlaneImpl::operator=
PlaneImpl & operator=(const PlaneImpl &pl2)
Definition: SiVolume.h:48
OdGeVector3d::dotProduct
double dotProduct(const OdGeVector3d &vect) const
Definition: GeVector3d.h:487