6 * function [Nx,Ny,Nz]=patchnormals_double(Fa,Fb,Fc,Vx,Vy,Vz)
\r
10 /* Coordinates to index */
\r
11 int mindex3(int x, int y, int z, int sizx, int sizy) { return z*sizx*sizy+y*sizx+x;}
\r
12 int mindex2(int x, int y, int sizx) { return y*sizx+x;}
\r
14 /* The matlab mex function */
\r
15 void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
\r
18 double *FacesA, *FacesB, *FacesC, *VerticesX, *VerticesY, *VerticesZ;
\r
20 /* All outputs, Vertex Normals */
\r
21 double *NormalsX, *NormalsY, *NormalsZ;
\r
23 /* Temporary Face Normals */
\r
24 double *FaceNormalsX, *FaceNormalsY, *FaceNormalsZ;
\r
26 /* Temporary Face angles */
\r
27 double *AnglesA, *AnglesB, *AnglesC;
\r
29 /* Number of faces */
\r
30 const mwSize *FacesDims;
\r
33 /* Number of vertices */
\r
34 const mwSize *VertexDims;
\r
36 int VertexNA[1]={0};
\r
39 int index0, index1, index2;
\r
41 /* Edge coordinates and lenght */
\r
42 double e0x, e0y, e0z, e0l;
\r
43 double e1x, e1y, e1z, e1l;
\r
44 double e2x, e2y, e2z, e2l;
\r
46 /* Length of normal */
\r
52 /* Check for proper number of arguments. */
\r
54 mexErrMsgTxt("6 inputs are required.");
\r
55 } else if(nlhs!=3) {
\r
56 mexErrMsgTxt("3 outputs are required");
\r
59 /* Read all inputs (faces and vertices) */
\r
60 FacesA=mxGetPr(prhs[0]);
\r
61 FacesB=mxGetPr(prhs[1]);
\r
62 FacesC=mxGetPr(prhs[2]);
\r
63 VerticesX=mxGetPr(prhs[3]);
\r
64 VerticesY=mxGetPr(prhs[4]);
\r
65 VerticesZ=mxGetPr(prhs[5]);
\r
67 /* Get number of FacesN */
\r
68 FacesDims = mxGetDimensions(prhs[0]);
\r
69 FacesN=FacesDims[0]*FacesDims[1];
\r
71 /* Get number of VertexN */
\r
72 VertexDims = mxGetDimensions(prhs[3]);
\r
73 VertexN=VertexDims[0]*VertexDims[1];
\r
75 /* Create Output arrays for the Normal coordinates */
\r
76 VertexNA[0]=VertexN;
\r
77 plhs[0] = mxCreateNumericArray(1, VertexNA, mxDOUBLE_CLASS, mxREAL);
\r
78 plhs[1] = mxCreateNumericArray(1, VertexNA, mxDOUBLE_CLASS, mxREAL);
\r
79 plhs[2] = mxCreateNumericArray(1, VertexNA, mxDOUBLE_CLASS, mxREAL);
\r
80 NormalsX = mxGetPr(plhs[0]);
\r
81 NormalsY = mxGetPr(plhs[1]);
\r
82 NormalsZ = mxGetPr(plhs[2]);
\r
85 FaceNormalsX = (double *)malloc( FacesN* sizeof(double) );
\r
86 FaceNormalsY = (double *)malloc( FacesN* sizeof(double) );
\r
87 FaceNormalsZ = (double *)malloc( FacesN* sizeof(double) );
\r
89 AnglesA = (double *)malloc( FacesN* sizeof(double) );
\r
90 AnglesB = (double *)malloc( FacesN* sizeof(double) );
\r
91 AnglesC = (double *)malloc( FacesN* sizeof(double) );
\r
94 /* Calculate all face normals and angles */
\r
95 for (i=0; i<FacesN; i++)
\r
97 /* Get indices of face vertices */
\r
98 index0=(int)FacesA[i]-1;
\r
99 index1=(int)FacesB[i]-1;
\r
100 index2=(int)FacesC[i]-1;
\r
102 /* Make edge vectors */
\r
103 e0x=VerticesX[index0]-VerticesX[index1];
\r
104 e0y=VerticesY[index0]-VerticesY[index1];
\r
105 e0z=VerticesZ[index0]-VerticesZ[index1];
\r
107 e1x=VerticesX[index1]-VerticesX[index2];
\r
108 e1y=VerticesY[index1]-VerticesY[index2];
\r
109 e1z=VerticesZ[index1]-VerticesZ[index2];
\r
111 e2x=VerticesX[index2]-VerticesX[index0];
\r
112 e2y=VerticesY[index2]-VerticesY[index0];
\r
113 e2z=VerticesZ[index2]-VerticesZ[index0];
\r
115 /* Normalize the edge vectors */
\r
116 e0l = sqrt(e0x*e0x+e0y*e0y+e0z*e0z)+1e-14;
\r
117 e0x/=e0l; e0y/=e0l; e0z/=e0l;
\r
118 e1l = sqrt(e1x*e1x+e1y*e1y+e1z*e1z)+1e-14;
\r
119 e1x/=e1l; e1y/=e1l; e1z/=e1l;
\r
120 e2l = sqrt(e2x*e2x+e2y*e2y+e2z*e2z)+1e-14;
\r
121 e2x/=e2l; e2y/=e2l; e2z/=e2l;
\r
123 /* Calculate angles of face seen from vertices */
\r
124 AnglesA[i]= acos(e0x*(-e2x)+e0y*(-e2y)+e0z*(-e2z));
\r
125 AnglesB[i]= acos(e1x*(-e0x)+e1y*(-e0y)+e1z*(-e0z));
\r
126 AnglesC[i]= acos(e2x*(-e1x)+e2y*(-e1y)+e2z*(-e1z));
\r
128 /* Normal of the face */
\r
129 FaceNormalsX[i]=e0y*(e2z) - e0z * (e2y);
\r
130 FaceNormalsY[i]=e0z*(e2x) - e0x * (e2z);
\r
131 FaceNormalsZ[i]=e0x*(e2y) - e0y * (e2x);
\r
134 /* Calculate all vertex normals and angles */
\r
135 for (i=0; i<FacesN; i++)
\r
137 index0=(int)FacesA[i]-1;
\r
138 NormalsX[index0]+= FaceNormalsX[i]*AnglesA[i];
\r
139 NormalsY[index0]+= FaceNormalsY[i]*AnglesA[i];
\r
140 NormalsZ[index0]+= FaceNormalsZ[i]*AnglesA[i];
\r
141 index1=(int)FacesB[i]-1;
\r
142 NormalsX[index1]+= FaceNormalsX[i]*AnglesB[i];
\r
143 NormalsY[index1]+= FaceNormalsY[i]*AnglesB[i];
\r
144 NormalsZ[index1]+= FaceNormalsZ[i]*AnglesB[i];
\r
145 index2=(int)FacesC[i]-1;
\r
146 NormalsX[index2]+= FaceNormalsX[i]*AnglesC[i];
\r
147 NormalsY[index2]+= FaceNormalsY[i]*AnglesC[i];
\r
148 NormalsZ[index2]+= FaceNormalsZ[i]*AnglesC[i];
\r
151 /* Normalize the Normals */
\r
152 for (i=0; i<VertexN; i++)
\r
154 nl= sqrt(NormalsX[i]*NormalsX[i]+NormalsY[i]*NormalsY[i]+NormalsZ[i]*NormalsZ[i])+1e-14; ;
\r
155 NormalsX[i]/=nl; NormalsY[i]/=nl; NormalsZ[i]/=nl;
\r
159 free(FaceNormalsX);
\r
160 free(FaceNormalsY);
\r
161 free(FaceNormalsZ);
\r