Wm4MeshCurvature.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "Wm4FoundationPCH.h"
00018 #include "Wm4MeshCurvature.h"
00019
00020 namespace Wm4
00021 {
00022
00023 template <class Real>
00024 MeshCurvature<Real>::MeshCurvature (int iVQuantity,
00025 const Vector3<Real>* akVertex, int iTQuantity, const int* aiIndex)
00026 {
00027 m_iVQuantity = iVQuantity;
00028 m_akVertex = akVertex;
00029 m_iTQuantity = iTQuantity;
00030 m_aiIndex = aiIndex;
00031
00032
00033 m_akNormal = WM4_NEW Vector3<Real>[m_iVQuantity];
00034 memset(m_akNormal,0,m_iVQuantity*sizeof(Vector3<Real>));
00035 int i, iV0, iV1, iV2;
00036 for (i = 0; i < m_iTQuantity; i++)
00037 {
00038
00039 iV0 = *aiIndex++;
00040 iV1 = *aiIndex++;
00041 iV2 = *aiIndex++;
00042
00043
00044 Vector3<Real> kEdge1 = m_akVertex[iV1] - m_akVertex[iV0];
00045 Vector3<Real> kEdge2 = m_akVertex[iV2] - m_akVertex[iV0];
00046 Vector3<Real> kNormal = kEdge1.Cross(kEdge2);
00047
00048 m_akNormal[iV0] += kNormal;
00049 m_akNormal[iV1] += kNormal;
00050 m_akNormal[iV2] += kNormal;
00051 }
00052 for (i = 0; i < m_iVQuantity; i++)
00053 {
00054 m_akNormal[i].Normalize();
00055 }
00056
00057
00058 Matrix3<Real>* akDNormal = WM4_NEW Matrix3<Real>[m_iVQuantity];
00059 Matrix3<Real>* akWWTrn = WM4_NEW Matrix3<Real>[m_iVQuantity];
00060 Matrix3<Real>* akDWTrn = WM4_NEW Matrix3<Real>[m_iVQuantity];
00061 memset(akWWTrn,0,m_iVQuantity*sizeof(Matrix3<Real>));
00062 memset(akDWTrn,0,m_iVQuantity*sizeof(Matrix3<Real>));
00063
00064 int iRow, iCol;
00065 aiIndex = m_aiIndex;
00066 for (i = 0; i < m_iTQuantity; i++)
00067 {
00068
00069 int aiV[3];
00070 aiV[0] = *aiIndex++;
00071 aiV[1] = *aiIndex++;
00072 aiV[2] = *aiIndex++;
00073
00074 for (int j = 0; j < 3; j++)
00075 {
00076 iV0 = aiV[j];
00077 iV1 = aiV[(j+1)%3];
00078 iV2 = aiV[(j+2)%3];
00079
00080
00081
00082 Vector3<Real> kE = m_akVertex[iV1] - m_akVertex[iV0];
00083 Vector3<Real> kW = kE - (kE.Dot(m_akNormal[iV0]))*m_akNormal[iV0];
00084 Vector3<Real> kD = m_akNormal[iV1] - m_akNormal[iV0];
00085 for (iRow = 0; iRow < 3; iRow++)
00086 {
00087 for (iCol = 0; iCol < 3; iCol++)
00088 {
00089 akWWTrn[iV0][iRow][iCol] += kW[iRow]*kW[iCol];
00090 akDWTrn[iV0][iRow][iCol] += kD[iRow]*kW[iCol];
00091 }
00092 }
00093
00094
00095
00096 kE = m_akVertex[iV2] - m_akVertex[iV0];
00097 kW = kE - (kE.Dot(m_akNormal[iV0]))*m_akNormal[iV0];
00098 kD = m_akNormal[iV2] - m_akNormal[iV0];
00099 for (iRow = 0; iRow < 3; iRow++)
00100 {
00101 for (iCol = 0; iCol < 3; iCol++)
00102 {
00103 akWWTrn[iV0][iRow][iCol] += kW[iRow]*kW[iCol];
00104 akDWTrn[iV0][iRow][iCol] += kD[iRow]*kW[iCol];
00105 }
00106 }
00107 }
00108 }
00109
00110
00111
00112
00113 for (i = 0; i < m_iVQuantity; i++)
00114 {
00115 for (iRow = 0; iRow < 3; iRow++)
00116 {
00117 for (iCol = 0; iCol < 3; iCol++)
00118 {
00119 akWWTrn[i][iRow][iCol] = ((Real)0.5)*akWWTrn[i][iRow][iCol] +
00120 m_akNormal[i][iRow]*m_akNormal[i][iCol];
00121 akDWTrn[i][iRow][iCol] *= (Real)0.5;
00122 }
00123 }
00124
00125 akDNormal[i] = akDWTrn[i]*akWWTrn[i].Inverse();
00126 }
00127
00128 WM4_DELETE[] akWWTrn;
00129 WM4_DELETE[] akDWTrn;
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 m_afMinCurvature = WM4_NEW Real[m_iVQuantity];
00145 m_afMaxCurvature = WM4_NEW Real[m_iVQuantity];
00146 m_akMinDirection = WM4_NEW Vector3<Real>[m_iVQuantity];
00147 m_akMaxDirection = WM4_NEW Vector3<Real>[m_iVQuantity];
00148 for (i = 0; i < m_iVQuantity; i++)
00149 {
00150
00151 Vector3<Real> kU, kV;
00152 Vector3<Real>::GenerateComplementBasis(kU,kV,m_akNormal[i]);
00153
00154
00155
00156
00157 Real fS01 = kU.Dot(akDNormal[i]*kV);
00158 Real fS10 = kV.Dot(akDNormal[i]*kU);
00159 Real fSAvr = ((Real)0.5)*(fS01+fS10);
00160 Matrix2<Real> kS
00161 (
00162 kU.Dot(akDNormal[i]*kU), fSAvr,
00163 fSAvr, kV.Dot(akDNormal[i]*kV)
00164 );
00165
00166
00167 Real fTrace = kS[0][0] + kS[1][1];
00168 Real fDet = kS[0][0]*kS[1][1] - kS[0][1]*kS[1][0];
00169 Real fDiscr = fTrace*fTrace - ((Real)4.0)*fDet;
00170 Real fRootDiscr = Math<Real>::Sqrt(Math<Real>::FAbs(fDiscr));
00171 m_afMinCurvature[i] = ((Real)0.5)*(fTrace - fRootDiscr);
00172 m_afMaxCurvature[i] = ((Real)0.5)*(fTrace + fRootDiscr);
00173
00174
00175 Vector2<Real> kW0(kS[0][1],m_afMinCurvature[i]-kS[0][0]);
00176 Vector2<Real> kW1(m_afMinCurvature[i]-kS[1][1],kS[1][0]);
00177 if (kW0.SquaredLength() >= kW1.SquaredLength())
00178 {
00179 kW0.Normalize();
00180 m_akMinDirection[i] = kW0.X()*kU + kW0.Y()*kV;
00181 }
00182 else
00183 {
00184 kW1.Normalize();
00185 m_akMinDirection[i] = kW1.X()*kU + kW1.Y()*kV;
00186 }
00187
00188 kW0 = Vector2<Real>(kS[0][1],m_afMaxCurvature[i]-kS[0][0]);
00189 kW1 = Vector2<Real>(m_afMaxCurvature[i]-kS[1][1],kS[1][0]);
00190 if (kW0.SquaredLength() >= kW1.SquaredLength())
00191 {
00192 kW0.Normalize();
00193 m_akMaxDirection[i] = kW0.X()*kU + kW0.Y()*kV;
00194 }
00195 else
00196 {
00197 kW1.Normalize();
00198 m_akMaxDirection[i] = kW1.X()*kU + kW1.Y()*kV;
00199 }
00200 }
00201
00202 WM4_DELETE[] akDNormal;
00203 }
00204
00205 template <class Real>
00206 MeshCurvature<Real>::~MeshCurvature ()
00207 {
00208 WM4_DELETE[] m_akNormal;
00209 WM4_DELETE[] m_afMinCurvature;
00210 WM4_DELETE[] m_afMaxCurvature;
00211 WM4_DELETE[] m_akMinDirection;
00212 WM4_DELETE[] m_akMaxDirection;
00213 }
00214
00215 template <class Real>
00216 int MeshCurvature<Real>::GetVQuantity () const
00217 {
00218 return m_iVQuantity;
00219 }
00220
00221 template <class Real>
00222 const Vector3<Real>* MeshCurvature<Real>::GetVertices () const
00223 {
00224 return m_akVertex;
00225 }
00226
00227 template <class Real>
00228 int MeshCurvature<Real>::GetTQuantity () const
00229 {
00230 return m_iTQuantity;
00231 }
00232
00233 template <class Real>
00234 const int* MeshCurvature<Real>::GetIndices () const
00235 {
00236 return m_aiIndex;
00237 }
00238
00239 template <class Real>
00240 const Vector3<Real>* MeshCurvature<Real>::GetNormals () const
00241 {
00242 return m_akNormal;
00243 }
00244
00245 template <class Real>
00246 const Real* MeshCurvature<Real>::GetMinCurvatures () const
00247 {
00248 return m_afMinCurvature;
00249 }
00250
00251 template <class Real>
00252 const Real* MeshCurvature<Real>::GetMaxCurvatures () const
00253 {
00254 return m_afMaxCurvature;
00255 }
00256
00257 template <class Real>
00258 const Vector3<Real>* MeshCurvature<Real>::GetMinDirections () const
00259 {
00260 return m_akMinDirection;
00261 }
00262
00263 template <class Real>
00264 const Vector3<Real>* MeshCurvature<Real>::GetMaxDirections () const
00265 {
00266 return m_akMaxDirection;
00267 }
00268
00269
00270
00271
00272
00273 template WM4_FOUNDATION_ITEM
00274 class MeshCurvature<float>;
00275
00276 template WM4_FOUNDATION_ITEM
00277 class MeshCurvature<double>;
00278
00279 }