HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GT_GEOElementArray.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: GT_GEOElementArray.h ( GEO Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __GT_GEOElementArray__
12 #define __GT_GEOElementArray__
13 
14 #include "GT_API.h"
15 #include <UT/UT_Assert.h>
16 #include "GT_DataArray.h"
17 #include "GT_GEOSupport.h"
18 #include <GA/GA_AIFTuple.h>
19 #include <GA/GA_AIFStringTuple.h>
20 #include <GU/GU_Detail.h>
21 #include <GA/GA_Handle.h>
22 
23 class GA_AIFIndexPair;
25 class GA_Attribute;
26 
27 /// @brief A GT Data Array to extract values from a point/primitive attribute.
29 {
30 public:
32  {
33  GT_GEOATTRIB_INVALID = -1,
34 
35  GT_GEOATTRIB_VERTEX = GA_ATTRIB_VERTEX,
36  GT_GEOATTRIB_POINT = GA_ATTRIB_POINT,
37  GT_GEOATTRIB_PRIMITIVE = GA_ATTRIB_PRIMITIVE,
38  GT_GEOATTRIB_GLOBAL = GA_ATTRIB_GLOBAL,
39  GT_GEOATTRIB_DETAIL = GA_ATTRIB_DETAIL,
40 
41  // Point attribute indexed by vertex
43  // Primitive attribute index by vertex
45  // Detail attribute indexed by vertex
47 
48  // Detail attribute indexed by primitive
50  };
51  /// The @c index_mode is used to lookup values. This does @b not
52  /// necessarily have to match the attribute owner, but it must be one of
53  /// the following.
54  /// - @c index_mode := point, @c attribute := point @n
55  /// - @c index_mode := vertex, @c attribute := point @n
56  /// - @c index_mode := vertex, @c attribute := primitive @n
57  /// - @c index_mode := vertex, @c attribute := vertex @n
58  /// - @c index_mode := primitive, @c attribute := primitive @n
59  /// - @c index_mode := detail, @c attribute := detail @n
61  const GA_Attribute *attrib,
63  GA_AttributeOwner offset_owner);
64  GT_GEOElementArray(const GT_GEOElementArray &src_array,
66  GA_AttributeOwner offset_owner);
67  ~GT_GEOElementArray() override;
68 
69  const char *className() const override
70  { return "GT_GEOElementArray"; }
71 
72  /// @{
73  /// Query methods defined on GT_DataArray
74  GT_Storage getStorage() const override
75  { return myStorage; }
76  GT_Size entries() const override
77  {
78  return myOffsets.entries();
79 #if 0
80  switch (myOffsetOwner)
81  {
82  case GA_ATTRIB_VERTEX:
83  return myGdp->getNumVertexOffsets();
84  case GA_ATTRIB_POINT:
85  return myGdp->getNumPointOffsets();
87  return myGdp->getNumPrimitiveOffsets();
88  case GA_ATTRIB_DETAIL:
89  return 1;
90  default:
91  UT_ASSERT(0);
92  }
93 #endif
94  return 0;
95  }
96  GT_Size itemSize(GT_Offset offset) const override;
97  GT_Size getTotalArrayEntries() const override;
98  GT_Size getTupleSize() const override
99  {
100  return myTupleSize;
101  }
102  GT_Type getTypeInfo() const override
103  {
104  GA_TypeInfo info = myAttribute
105  ? myAttribute->getTypeInfo()
106  : GA_TYPE_VOID;
107  // avoid transforming attributes like "rest"
108  switch(info)
109  {
110  case GA_TYPE_POINT:
111  case GA_TYPE_HPOINT:
112  case GA_TYPE_NORMAL:
113  case GA_TYPE_VECTOR:
114  if(!myAttribute->needsTransform())
115  return GT_TYPE_NONE;
116  break;
117 
118  default:
119  break;
120  }
121  return mapTypeInfo(info, myTupleSize);
122  }
123  int64 getMemoryUsage() const override
124  { return sizeof(*this); }
125  bool isValid() const override { return myAttribute != NULL; }
126  bool hasArrayEntries() const override
127  {
128  return myFA.isValid() ||
129  myIA.isValid() ||
130  myIA64.isValid() ||
131  mySSArray ||
132  mySDictArray;
133  }
134  void updateGeoDetail(const GU_ConstDetailHandle &dtl,
135  const char *name,
136  GT_Owner attrib_scope,
137  const int expected_size) override;
138 
139  /// @}
140 
141  /// @{
142  /// Access methods defined on GT_DataArray
143  fpreal16 getF16(GT_Offset offset, int idx) const override
144  { return getValue_t<fpreal32>(offset, idx); }
145  fpreal32 getF32(GT_Offset offset, int idx) const override
146  { return getValue_t<fpreal32>(offset, idx); }
147  fpreal64 getF64(GT_Offset offset, int idx) const override
148  { return getValue_t<fpreal64>(offset, idx); }
149  uint8 getU8(GT_Offset offset, int idx) const override
150  { return getValue_t<int32>(offset, idx); }
151  int32 getI32(GT_Offset offset, int idx) const override
152  { return getValue_t<int32>(offset, idx); }
153  int64 getI64(GT_Offset offset, int idx) const override
154  { return getValue_t<int64>(offset, idx); }
155  GT_String getS(GT_Offset offset, int idx) const override
156  {
157  if (mySTuple)
158  {
159  GA_Offset si = getDataOffset(offset);
160  return mySTuple->getString(myAttribute, si,idx);
161  }
163  }
165  GT_Offset offset) const override
166  {
167  if (mySSArray)
168  {
169  GA_Offset si = getDataOffset(offset);
170  mySSArray->getString(myAttribute, si, a);
171  return true;
172  }
173  return false;
174  }
175  GT_Dict getDict(GT_Offset offset, int idx = 0) const override
176  {
177  if (mySDictTuple)
178  {
179  GA_Offset si = getDataOffset(offset);
180  return mySDictTuple->getDict(myAttribute, si, idx);
181  }
183  }
185  {
186  if (mySDictArray)
187  {
188  GA_Offset si = getDataOffset(offset);
189  mySDictArray->getDict(myAttribute, si, a);
190  return true;
191  }
192  return false;
193  }
194  GT_Size getStringIndexCount() const override;
196  int idx=0) const override;
198  GT_Offset offset) const override;
200  UT_IntArray &) const override;
201 
203  GT_Offset start, GT_Size length) const override;
204 
205  GT_Size getDictIndexCount() const override;
206  GT_Offset getDictIndex(GT_Offset offset, int idx = 0) const override;
208  GT_Offset offset) const override;
210  UT_IntArray &) const override;
211 
213  GT_Offset start, GT_Size length) const override;
214 
215  int getIndexPairObjectSetCount() const override;
217  int s = 0) const override;
218 
220  GT_Offset offset) const override
221  { return getArrayValue_t<fpreal16>(a,offset); }
223  GT_Offset offset) const override
224  { return getArrayValue_t<fpreal32>(a,offset); }
226  GT_Offset offset) const override
227  { return getArrayValue_t<fpreal64>(a,offset); }
229  GT_Offset offset) const override
230  { return getArrayValue_t<uint8>(a,offset); }
232  GT_Offset offset) const override
233  { return getArrayValue_t<int8>(a,offset); }
235  GT_Offset offset) const override
236  { return getArrayValue_t<int16>(a,offset); }
238  GT_Offset offset) const override
239  { return getArrayValue_t<int32>(a,offset); }
241  GT_Offset offset) const override
242  { return getArrayValue_t<int64>(a,offset); }
243  /// @}
244 
245  const uint8 *get(GT_Offset i, uint8 *store, int sz) const override
246  { return GT_DataArray::get(i, store, sz); }
247  const int8 *get(GT_Offset i, int8 *store, int sz) const override
248  { return GT_DataArray::get(i, store, sz); }
249  const int16 *get(GT_Offset i, int16 *store, int sz) const override
250  { return GT_DataArray::get(i, store, sz); }
251  const int32 *get(GT_Offset i, int32 *store, int sz) const override
252  { return getTuple_t(i, store, sz); }
253  const int64 *get(GT_Offset i, int64 *store, int sz) const override
254  { return getTuple_t(i, store, sz); }
255  const fpreal16 *get(GT_Offset i, fpreal16 *store, int z) const override
256  { return GT_DataArray::get(i, store, z); }
257  const fpreal64 *get(GT_Offset i, fpreal64 *store, int z) const override
258  { return getTuple_t(i, store, z); }
259  const fpreal32 *get(GT_Offset idx, fpreal32 *store, int z) const override
260  {
261  if (z == 3 && myV3.isValid())
262  {
263  UT_Vector3 v = myV3.get(getDataOffset(idx));
264  store[0] = v.x();
265  store[1] = v.y();
266  store[2] = v.z();
267  return store;
268  }
269  if (myF.isValid())
270  {
271  GA_Offset o = getDataOffset(idx);
272  for (int i = 0; i < z; ++i)
273  store[i] = myF.get(o, i);
274  return store;
275  }
276  return getTuple_t(idx, store, z);
277  }
278 
279  /// Enlarge a bounding box with values
280  bool computeMinMax(fpreal64 *min, fpreal64 *max) const override;
281 
282  /// @{
283  /// Optimized filling methods
284  void doImport(GT_Offset idx, uint8 *data, GT_Size size) const override;
285  void doImport(GT_Offset idx, int8 *data, GT_Size size) const override;
286  void doImport(GT_Offset idx, int16 *data, GT_Size size) const override;
287  void doImport(GT_Offset idx, int32 *data, GT_Size size) const override;
288  void doImport(GT_Offset idx, int64 *data, GT_Size size) const override;
289  void doImport(GT_Offset idx, fpreal16 *data, GT_Size size) const override;
290  void doImport(GT_Offset idx, fpreal32 *data, GT_Size size) const override;
291  void doImport(GT_Offset idx, fpreal64 *data, GT_Size size) const override;
292  void doImportArray(
293  GT_Offset idx, UT_ValArray<fpreal16> &data) const override;
294  void doImportArray(
295  GT_Offset idx, UT_ValArray<fpreal32> &data) const override;
296  void doImportArray(
297  GT_Offset idx, UT_ValArray<fpreal64> &data) const override;
298  void doImportArray(GT_Offset idx, UT_ValArray<uint8> &data) const override;
299  void doImportArray(GT_Offset idx, UT_ValArray<int8> &data) const override;
300  void doImportArray(GT_Offset idx, UT_ValArray<int16> &data) const override;
301  void doImportArray(GT_Offset idx, UT_ValArray<int32> &data) const override;
302  void doImportArray(GT_Offset idx, UT_ValArray<int64> &data) const override;
304  int tuple_size, int stride) const override;
306  int tuple_size, int stride) const override;
308  int tuple_size, int stride) const override;
310  int tuple_size, int stride) const override;
312  int tuple_size, int stride) const override;
314  int tuple_size, int stride) const override;
316  int tuple_size, int stride) const override;
318  int tuple_size, int stride) const override;
321  UT_BoundingBoxF &bbox, int tsize, int stride) override;
324  UT_BoundingBoxD &bbox, int tsize, int stride) override;
327  int tuple_size, int stride,
328  fpreal black, fpreal white) const override;
331  int tuple_size, int nrepeats, int stride,
332  fpreal black, fpreal white) const override;
334  GT_Offset start, GT_Size length) const override;
336  GT_Offset start, GT_Size length) const override;
338  GT_Offset start, GT_Size length) const override;
340  GT_Offset start, GT_Size length) const override;
342  GT_Offset start, GT_Size length) const override;
344  GT_Offset start, GT_Size length) const override;
346  GT_Offset start, GT_Size length) const override;
348  GT_Offset start, GT_Size length) const override;
349  /// @}
350 
351  bool hasCLBuffer() const;
352  // Accessor to the GA_Attribute holding the CL buffer so GT isn't dependent
353  // on CE.
354  const GA_Attribute *getBufferAttribute();
355 
356  /// @private - This method relies on knowledge of the internal
357  /// implementation. It's only public for threading efficiency.
358  GA_Offset getDataOffset(GT_Offset offset) const
359  {
360  if (myAttributeOwner == GA_ATTRIB_DETAIL)
361  return GA_Offset(0);
362 
363  GA_Offset gaoff = myOffsets(offset);
364  if (myOffsetOwner == GA_ATTRIB_VERTEX &&
365  myOffsetOwner != myAttributeOwner)
366  {
367  if (myAttributeOwner == GA_ATTRIB_POINT)
368  {
369  gaoff = myGdp->vertexPoint(gaoff);
370  }
371  else
372  {
373  UT_ASSERT(myAttributeOwner ==
375  gaoff = myGdp->vertexPrimitive(gaoff);
376  }
377  }
378  return gaoff;
379  }
380 
381 protected:
382  /// GT_GEOAutoNormalArray has no attribute yet when calling constructor.
384  const GT_GEOOffsetList &offsets,
385  GA_AttributeOwner offset_owner);
386 
387  void initAttribute(const GA_Attribute *attrib);
388  void makeInvalid();
389 
390  template <typename T> inline T
391  getValue_t(GT_Offset offset, int idx) const
392  {
393  GA_Offset si = getDataOffset(offset);
394  T val;
395 
396  if (myTuple && myTuple->get(myAttribute, si, val, idx))
397  return val;
398  return 0;
399  }
400 
401  template <typename T> inline const T *
402  getTuple_t(GT_Offset offset, T *store, int size) const
403  {
404  GA_Offset si = getDataOffset(offset);
405  if (myTuple && myTuple->get(myAttribute, si, store, size))
406  return store;
407  return NULL;
408  }
409 
410  template <typename T> inline bool
412  {
413  GA_Offset si = getDataOffset(offset);
414 
415  if (myNumericArray &&
416  myNumericArray->get(myAttribute, si, val))
417  return true;
418  return false;
419  }
420 
421 
422  GT_Type mapTypeInfo(GA_TypeInfo type, int tsize) const;
423 
425  const GU_Detail *myGdp;
436  GA_AttributeOwner myOffsetOwner; // What type of offsets
450 };
451 
452 /// This class is specific to managing a detached, auto-generated
453 /// normal attribute, when no point, vertex, attrib_owner, or offset_owner
454 /// normals are present on the original detail.
456 {
457 public:
459  const GU_ConstDetailHandle &gdp,
460  GA_AttributeOwner attrib_owner,
461  const GT_GEOOffsetList &offsets,
462  GA_AttributeOwner offset_owner,
463  float cusp_angle);
464 
465  int64 getMemoryUsage() const override
466  { return sizeof(*this); }
467 
468 
469  void updateGeoDetail(
470  const GU_ConstDetailHandle &dtl,
471  const char *name,
472  GT_Owner attrib_scope,
473  const int expected_size) override;
474 private:
475  void createAttribute();
476 
477  int64 myPDataId;
478  int64 myTopologyDataId;
479  int64 myPrimitiveListDataId;
480  const float myCuspAngle;
481  const GA_AttributeOwner myAttribOwner;
482 
483  GA_ATINumericUPtr myAttributeHolder;
484 };
485 
486 #endif
GLuint GLsizei const GLuint const GLintptr const GLsizeiptr * sizes
Definition: glcorearb.h:2621
GT_Storage
Definition: GT_Types.h:19
virtual void updateGeoDetail(const GU_ConstDetailHandle &dtl, const char *attrib_name, GT_Owner attrib_owner, const int expected_size)
Update cached data, in case the underlying attribute changed.
Definition: GT_DataArray.h:590
Definition of a geometry attribute.
Definition: GA_Attribute.h:198
Data has no numeric representation.
Definition: GA_Types.h:104
virtual void doFillQuantizedArray(uint8 *data, GT_Offset start, GT_Size length, int tuple_size, int stride, fpreal black, fpreal white) const
Definition: GT_DataArray.h:683
GLsizei GLenum const void * indices
Definition: glcorearb.h:406
Generic Attribute Interface class to access an attribute as a array.
int int32
Definition: SYS_Types.h:39
Generic Attribute Interface class to get/set data as index pairs.
virtual bool getDictIndices(UT_Array< GT_Offset > &indices, GT_Offset offset) const
Definition: GT_DataArray.h:226
GT_Dict getDict(GT_Offset offset, int idx=0) const override
A specialization of GA_AIFDictTuple to access "shared strings".
const GA_Attribute * myAttribute
T getValue_t(GT_Offset offset, int idx) const
fpreal32 getF32(GT_Offset offset, int idx) const override
const T * getTuple_t(GT_Offset offset, T *store, int size) const
bool getIA64(UT_ValArray< int64 > &a, GT_Offset offset) const override
virtual void fillStringArray(UT_StringArray &data, UT_ValArray< int > &sizes, GT_Offset start, GT_Size length) const
Definition: GT_DataArray.h:209
const GA_AIFTuple * myTuple
GT_Storage getStorage() const override
const GLdouble * v
Definition: glcorearb.h:837
int64 getMemoryUsage() const override
bool getDictA(UT_Array< UT_OptionsHolder > &a, GT_Offset offset) const override
GLuint start
Definition: glcorearb.h:475
GA_AttributeOwner myAttributeOwner
int64 getI64(GT_Offset offset, int idx) const override
virtual void doImport(GT_Offset idx, uint8 *data, GT_Size size) const
GLdouble GLdouble GLdouble z
Definition: glcorearb.h:848
#define GT_API
Definition: GT_API.h:13
constexpr SYS_FORCE_INLINE T & z() noexcept
Definition: UT_Vector3.h:667
GT_Type
Definition: GT_Types.h:36
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
GLdouble s
Definition: glad.h:3009
GLuint GLsizei GLsizei * length
Definition: glcorearb.h:795
int64 getMemoryUsage() const override
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
const GA_AIFIndexPair * myIndexPair
bool isValid() const override
virtual GT_Size itemSize(GT_Offset) const
Return the number of elements in the array for the given item.
Definition: GT_DataArray.h:60
float fpreal32
Definition: SYS_Types.h:200
const GA_AIFSharedStringArray * mySSArray
virtual void doFillVec3BBox(fpreal32 *dest, GT_Offset start, GT_Size length, UT_BoundingBoxF &bbox, int, int stride)
Definition: GT_DataArray.h:741
virtual bool computeMinMax(fpreal64 *min, fpreal64 *max) const
Compute the min & max values for an array. This fails for strings.
const GU_Detail * myGdp
GLuint GLsizei const GLuint const GLintptr * offsets
Definition: glcorearb.h:2621
double fpreal64
Definition: SYS_Types.h:201
bool getFA32(UT_ValArray< fpreal32 > &a, GT_Offset offset) const override
unsigned char uint8
Definition: SYS_Types.h:36
GA_Size GA_Offset
Definition: GA_Types.h:646
GU_ConstDetailHandle myGdh
virtual GT_Offset getDictIndex(GT_Offset offset, int idx=0) const =0
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
bool hasArrayEntries() const override
GLintptr offset
Definition: glcorearb.h:665
Abstract data class for an array of float, int or string data.
Definition: GT_DataArray.h:40
virtual GT_Size getStringIndexCount() const =0
const GA_AIFNumericArray * myNumericArray
virtual const uint8 * get(GT_Offset i, uint8 *store, int sz) const
fpreal64 getF64(GT_Offset offset, int idx) const override
void updateGeoDetail(const GU_ConstDetailHandle &dtl, const char *name, GT_Owner attrib_scope, const int expected_size) override
bool getUA8(UT_ValArray< uint8 > &a, GT_Offset offset) const override
static const UT_StringHolder theEmptyString
bool getIA8(UT_ValArray< int8 > &a, GT_Offset offset) const override
A GT Data Array to extract values from a point/primitive attribute.
static const UT_OptionsHolder theEmptyOptions
Definition: UT_Options.h:1230
A specialization of GA_AIFStringArray to access "shared strings".
GLint GLenum GLboolean GLsizei stride
Definition: glcorearb.h:872
bool getIA32(UT_ValArray< int32 > &a, GT_Offset offset) const override
int64 GT_Offset
Definition: GT_Types.h:129
const GA_AIFStringTuple * mySTuple
long long int64
Definition: SYS_Types.h:116
virtual void doFillArray(uint8 *data, GT_Offset start, GT_Size length, int tuple_size, int stride) const
Definition: GT_DataArray.h:633
virtual void getIndexedDicts(UT_Array< UT_OptionsHolder > &dicts, UT_IntArray &indices) const =0
GLuint const GLchar * name
Definition: glcorearb.h:786
virtual GT_Offset getStringIndex(GT_Offset offset, int idx=0) const =0
virtual void getIndexPairObjects(GT_AttributeListHandle &properties, int s=0) const
Definition: GT_DataArray.h:255
signed char int8
Definition: SYS_Types.h:35
GT_Size entries() const override
GA_TypeInfo
Definition: GA_Types.h:101
const char * className() const override
GT_Owner
Definition: GT_Types.h:90
uint8 getU8(GT_Offset offset, int idx) const override
bool getArrayValue_t(UT_ValArray< T > &val, GT_Offset offset) const
int64 GT_Size
Definition: GT_Types.h:128
GT_GEOOffsetList myOffsets
GLsizeiptr size
Definition: glcorearb.h:664
GA_AttributeOwner
Definition: GA_Types.h:35
GT_Size getTupleSize() const override
virtual void doImportArray(GT_Offset idx, UT_ValArray< fpreal16 > &data) const
short int16
Definition: SYS_Types.h:37
GT_Type getTypeInfo() const override
fpreal64 fpreal
Definition: SYS_Types.h:278
virtual int getIndexPairObjectSetCount() const
Definition: GT_DataArray.h:252
Data represents a normal vector. Token "normal".
Definition: GA_Types.h:114
GA_AttributeOwner myOffsetOwner
A specialization of GA_AIFDictArray to access "shared strings".
bool getIA16(UT_ValArray< int16 > &a, GT_Offset offset) const override
A specialization of GA_AIFStringTuple to access "shared strings".
GLuint GLfloat * val
Definition: glcorearb.h:1608
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
Data represents a direction vector. Token "vector".
Definition: GA_Types.h:112
const GA_AIFSharedStringTuple * mySSTuple
Data represents a position in space. Token "point".
Definition: GA_Types.h:106
virtual void doExtendedQuantizedFill(uint8 *data, GT_Offset start, GT_Size length, int tuple_size, int nrepeats, int stride, fpreal black, fpreal white) const
virtual void getIndexedStrings(UT_StringArray &strings, UT_IntArray &indices) const =0
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:156
virtual void fillDictionaryArray(UT_Array< UT_OptionsHolder > &data, UT_ValArray< int > &sizes, GT_Offset start, GT_Size length) const
Definition: GT_DataArray.h:246
const GA_AIFSharedDictArray * mySDictArray
GT_String getS(GT_Offset offset, int idx) const override
bool getSA(UT_StringArray &a, GT_Offset offset) const override
fpreal16 getF16(GT_Offset offset, int idx) const override
virtual bool getStringIndices(UT_Array< GT_Offset > &indices, GT_Offset offset) const
Definition: GT_DataArray.h:180
constexpr SYS_FORCE_INLINE T & y() noexcept
Definition: UT_Vector3.h:665
Generic Attribute Interface class to access an attribute as a tuple.
Definition: GA_AIFTuple.h:32
virtual void doFillArrayAttr(UT_Array< uint8 > &data, UT_Array< int > &sizes, GT_Offset start, GT_Size length) const
Definition: GT_DataArray.h:658
bool getFA16(UT_ValArray< fpreal16 > &a, GT_Offset offset) const override
virtual GT_Size getTotalArrayEntries() const
Definition: GT_DataArray.h:63
UT_UniquePtr< GA_ATINumeric > GA_ATINumericUPtr
Definition: format.h:1821
virtual GT_Size getDictIndexCount() const =0
const GA_AIFSharedDictTuple * mySDictTuple
Generic Attribute Interface class to work with string indices directly, rather than string values...
int32 getI32(GT_Offset offset, int idx) const override
bool getFA64(UT_ValArray< fpreal64 > &a, GT_Offset offset) const override
constexpr SYS_FORCE_INLINE T & x() noexcept
Definition: UT_Vector3.h:663