Polygon Crucher SDK - Documentation
Documentation
Loading...
Searching...
No Matches
3DFace.h
Go to the documentation of this file.
1//! @file 3DFace.h
2//!
3//! @brief C3DFace class definition for a 3D face, which is a list of indexes that refers to a 3D point list.
4//!
5//////////////////////////////////////////////////////////////////////
6
7#if !defined(AFX_3DFACE_H__CA6BC29D_FAC2_11D1_A0DE_000000000000__INCLUDED_)
8#define AFX_3DFACE_H__CA6BC29D_FAC2_11D1_A0DE_000000000000__INCLUDED_
9
10#ifdef _MSC_VER
11#pragma once
12#endif // _MSC_VER
13
14#include "Face.h"
15
16BEGIN_MOOTOOLS_NAMESPACE
17
18class C3DFacePropertyMethods;
19//! @class C3DFacePropertyData
20//! @brief C3DFacePropertyData is the main data chunk of C3DFaceList and it contains the face flags and its material id.
21class C3DFacePropertyData : public CFacePropertyData
22{
23 friend C3DFacePropertyMethods;
24 friend C3DFaceList;
25 friend C3DFace;
26
27 protected:
28 MaterialID materialid;
29
30 C3DFacePropertyData();
31};
32
33inline C3DFacePropertyData::C3DFacePropertyData()
34{
35 materialid = DEFAULT_MATERIAL_ID;
36}
37
38//! @class C3DFace
39//! @brief A 3D face is a list of indexes of C3DPointList object point list.
40//! @details A 3D face is usually built using a C3DFaceList::GetFace
42class DLL_3DFUNCTION C3DFace : public CFace
43{
44 friend class C3DFaceList;
45
46 public:
47 C3DFace();
48
49 public:
50
51 // Usefuls functions
52 static CTriangulateFaceHelper *InitTriangulation(const CGeomInfo *info);
53 static void ReleaseTriangulation(CTriangulateFaceHelper *helper);
54
55
56 int Triangulate(CTriangulateFaceHelper *helper, int srcfacenbr, int dstfacenbr); //!< Triangulate the face. When called repeatly on multiple CFace of a C3DFaceList, this method is faster than the second one
57
58 //! Triangulate a face
59 //! @param info
60 //! contains the face list as well as related channels which need to be triangulate
61 //! contains the preallocated destination face list and destination channels
62 //! source and destination list might contains only faces
63 //! @param srcfacenbr
64 //! index of the face to triangulate
65 //! @param dstfacenbr
66 //! index to which the new triangulated faces are copied
67 //! If dstfacenbr == -1 => we assume to triangulate only one face, and initialize the destination face list buffer
68 //! @return The number of new faces
69 int Triangulate(const CGeomInfo *, int srcfacenbr, int dstfacenbr); //!< Triangulate the face using CGeomInfo information
70 bool GetNormal(const CGeomInfo *, C3DVector& normal, bool normalize = true); //!< Return false if the normal can't be computed (weird face). In such case, a unit vector is returned (1, 0, 0);
71 void Get2DCoordinates(const CGeomInfo *, C2DPointList& points2d);
72 void GetCenter(const CGeomInfo * info, C3DPoint& center) const;
73 void GetPlane(const CGeomInfo *, C4DVector& plane);
74
75 // Material
76 void SetMaterialID(MaterialID id);
77 MaterialID GetMaterialID() const;
78
79 // Face ! who are you ?
80 double GetCompacityFactor(const CGeomInfo *info) const;
81 double Area(const CGeomInfo *info) const;
82 bool IsPlane(const CGeomInfo *);
83 bool IsConvex(const CGeomInfo *);
84
85protected:
86 void Get2DCoordinates(CTriangulateFaceHelper* helper, C2DPointList& points2d);
87
88};
89
90template<typename TYPE> bool RayIntersectsTriangleTUV(const C3DTPoint<TYPE>& orig, const C3DTVector<TYPE>& dir, const C3DTPoint<TYPE>& v0, const C3DTVector<TYPE>& v01, const C3DTVector<TYPE>& v02, double tuv[], bool allowBothDir = false) // orig + dir*tuv[0] is the point that hit the face
91{
92 C3DTVector<TYPE> h = dir ^ v02; // note: dir must not be (0, 0, 0)
93 double det = v01 * h;
94
95 // ray and triangle are parallel if det is close to 0
96 if (abs(det) < FLOAT_EPSILON3)
97 return false;
98
99 double invDet = 1 / det;
100
102 tuv[1] = invDet * (tvec * h);
103
104 if (tuv[1] < 0.0 || tuv[1] > 1.0)
105 return false;
106
108 tuv[2] = invDet * (dir * qvec);
109
110 if (tuv[2] < 0.0 || tuv[1] + tuv[2] > 1.0)
111 return(false);
112
113 // at this stage we can compute t to find out where
114 // the intersection point is on the line
115 tuv[0] = invDet * (v02 * qvec);
116 if (tuv[0] >= 0.0) // 12/21: was > FLOAT_EPSILON3, but if orig = v0, v1 or v2 the procedure returns false...
117 return true;
118 else // this means that there is a line intersection
119 // but not a ray intersection
120 return allowBothDir;
121}
122
123template<typename TYPE> bool RayIntersectsTriangle(const C3DTPoint<TYPE>& orig, const C3DTVector<TYPE>& dir, const C3DTPoint<TYPE>& v0, const C3DTVector<TYPE>& v01, const C3DTVector<TYPE>& v02, C3DTPoint<TYPE>* hitPt = NULL, bool allowBothDir = false)
124{
125 double tuv[3];
126 if (RayIntersectsTriangleTUV(orig, dir, v0, v01, v02, tuv))
127 {
128 if (hitPt)
129 *hitPt = orig + dir * tuv[0];
130
131 return true;
132 }
133
134 return false;
135}
136
137
138template<typename TYPE>
139bool IsInTriangle(const C3DTPoint<TYPE>& refpt, const C3DTPoint<TYPE>& pt1, const C3DTPoint<TYPE>& pt2, const C3DTPoint<TYPE>& pt3)
140{
141 int sign12, sign23, sign31;
144
145 // First, a quick bounding-box test:
146 // If P is outside triangle bbox, there cannot be an intersection.
147
148#define MIN3(a,b,c) ((((a)<(b))&&((a)<(c))) ? (a) : (((b)<(c)) ? (b) : (c)))
149#define MAX3(a,b,c) ((((a)>(b))&&((a)>(c))) ? (a) : (((b)>(c)) ? (b) : (c)))
150 if (refpt.x > MAX3(pt1.x, pt2.x, pt3.x)) return FALSE;
151 if (refpt.y > MAX3(pt1.y, pt2.y, pt3.y)) return FALSE;
152 if (refpt.z > MAX3(pt1.z, pt2.z, pt3.z)) return FALSE;
153 if (refpt.x < MIN3(pt1.x, pt2.x, pt3.x)) return FALSE;
154 if (refpt.y < MIN3(pt1.y, pt2.y, pt3.y)) return FALSE;
155 if (refpt.z < MIN3(pt1.z, pt2.z, pt3.z)) return FALSE;
156
157 // For each triangle side, make a vector out of it by subtracting vertexes;
158 // make another vector from one vertex to point P.
159 // The crossproduct of these two vectors is orthogonal to both and the
160 // signs of its X,Y,Z components indicate whether P was to the inside or
161 // to the outside of this triangle side.
162
163 /* 10/22: to be tested. https://github.com/erich666/GraphicsGems/blob/master/gemsiii/triangleCube.c
164 the old version of SIGN3 shows some numerical instability, and is improved
165 by using the NEW_SIGN3_CODE that follows */
166 #ifdef NEW_SIGN3_CODE
167 #define SIGN3_EPS 10e-5
168 #define SIGN3( A ) \
169 ((((A).x < SIGN3_EPS) ? 4 : 0) | (((A).x > -SIGN3_EPS) ? 32 : 0) | \
170 (((A).y < SIGN3_EPS) ? 2 : 0) | (((A).y > -SIGN3_EPS) ? 16 : 0) | \
171 (((A).z < SIGN3_EPS) ? 1 : 0) | (((A).z > -SIGN3_EPS) ? 8 : 0))
172 #else
173 #define SIGN3( A ) ((((A).x<0)?4:0) | (((A).y<0)?2:0) | (((A).z<0)?1:0))
174 #endif
175
176 vect12.InitFromPoints(pt1, pt2);
177 vect1h.InitFromPoints(pt1, refpt);
178 if (vect1h.x < PRECISION_LIMIT && vect1h.y < PRECISION_LIMIT && vect1h.z < PRECISION_LIMIT) // refpt is confused with pt1
179 return true;
181 sign12 = SIGN3(cross12_1p); // Extract X,Y,Z signs as 0...7 integer
182
183 vect23.InitFromPoints(pt2, pt3);
184 vect2h.InitFromPoints(pt2, refpt);
185 if (vect2h.x < PRECISION_LIMIT && vect2h.y < PRECISION_LIMIT && vect2h.z < PRECISION_LIMIT) // refpt is confused with pt1
186 return true;
188 sign23 = SIGN3(cross23_2p);
189
190 vect31.InitFromPoints(pt3, pt1);
191 vect3h.InitFromPoints(pt3, refpt);
192 if (vect3h.x < PRECISION_LIMIT && vect3h.y < PRECISION_LIMIT && vect3h.z < PRECISION_LIMIT) // refpt is confused with pt1
193 return true;
196 sign31 = SIGN3(cross31_3p);
197#undef SIGN3
198#undef SIGN3_EPS
199
200 // If all three crossproduct vectors agree in their component signs,
201 // then the point must be inside all three.
202 // P cannot be FALSE all three sides simultaneously.
203
204 /* this is the old test; with the revised SIGN3() macro, the test is modified. */
205#ifdef NEW_SIGN3_CODE
206 return ((sign12 & sign23 & sign31) == 0) ? false : true;
207#else
208 if ((sign12 == sign23) && (sign23 == sign31))
209 return true;
210 else
211 return false;
212#endif
213}
214
215END_MOOTOOLS_NAMESPACE
216
217#endif // !defined(AFX_3DFACE_H__CA6BC29D_FAC2_11D1_A0DE_000000000000__INCLUDED_)
The class handles C2DPoint list of points.
Definition 2DPointList.h:48
A 3D face is a list of indexes of C3DPointList object point list.
Definition 3DFace.h:43
bool GetNormal(const CGeomInfo *, C3DVector &normal, bool normalize=true)
Return false if the normal can't be computed (weird face). In such case, a unit vector is returned (1...
int Triangulate(const CGeomInfo *, int srcfacenbr, int dstfacenbr)
Triangulate the face using CGeomInfo information.
int Triangulate(CTriangulateFaceHelper *helper, int srcfacenbr, int dstfacenbr)
Triangulate the face. When called repeatly on multiple CFace of a C3DFaceList, this method is faster ...
C3DFaceList class which implement a list of C3DFace. Each face contains indexes to 3D points stored i...
Definition 3DFaceList.h:249
The class defines an x, y, z 3D point which can use int, float or double.
Definition 3DPoint.h:27
A CFace contains the information related to a given face in a CFaceList.
Definition Face.h:97
CFacePropertyData is the main data chunk of CFaceList which consists of storing the flags.
Definition Face.h:70
CGeomInfo is an helper class oftenly required by different methods.
Definition GeomInfo.h:71