00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifdef _WIN32
00038 #include <windows.h>
00039 #endif //_WIN32
00040
00041 #include "marchingcubes.h"
00042
00043 #include <time.h>
00044
00045 using namespace EMAN;
00046 #include "transform.h"
00047 #include "emobject.h"
00048 #include "vec3.h"
00049
00050 #define min(a,b)(((a) < (b)) ? (a) : (b))
00051 #define max(a,b)(((a) > (b)) ? (a) : (b))
00052
00053
00054 static const int a2fVertexOffset[8][3] =
00055 {
00056 {0, 0, 0},{1, 0, 0},{1, 1, 0},{0, 1, 0},
00057 {0, 0, 1},{1, 0, 1},{1, 1, 1},{0, 1, 1}
00058 };
00059
00060
00061 static const int a2fPosXOffset[4][3] =
00062 {
00063 {2, 0, 0},{2, 1, 0},
00064 {2, 0, 1},{2, 1, 1}
00065 };
00066
00067 static const int a2fPosYOffset[4][3] =
00068 {
00069 {1, 2, 0},{0, 2, 0},
00070 {1, 2, 1},{0, 2, 1}
00071 };
00072
00073 static const int a2fPosZOffset[4][3] =
00074 {
00075 {0, 0, 2},{1, 0, 2},
00076 {1, 1, 2},{0, 1, 2}
00077 };
00078
00079 static const int a2fPosXPosYOffset[2][3] =
00080 {
00081 {2, 2, 0},{2, 2, 1}
00082 };
00083
00084 static const int a2fPosXPosZOffset[2][3] =
00085 {
00086 {2, 0, 2},{2, 1, 2}
00087 };
00088
00089 static const int a2fPosYPosZOffset[2][3] =
00090 {
00091 {1, 2, 2},{0, 2, 2}
00092 };
00093
00094
00095 static const int a2fPosXPosZPosYOffset[3] =
00096 {
00097 2, 2, 2
00098 };
00099
00100
00101 static const int a2OddXOffset[8] =
00102 {
00103 1,0,0,1,
00104 1,0,0,1
00105 };
00106
00107 static const int a2OddYOffset[8] =
00108 {
00109 1,1,0,0,
00110 1,1,0,0
00111 };
00112
00113 static const int a2OddZOffset[8] =
00114 {
00115 1,1,1,1,
00116 0,0,0,0
00117 };
00118
00119
00120 static const int a2iEdgeConnection[12][2] =
00121 {
00122 {0,1}, {1,2}, {2,3}, {3,0},
00123 {4,5}, {5,6}, {6,7}, {7,4},
00124 {0,4}, {1,5}, {2,6}, {3,7}
00125 };
00126
00127
00128 static const float a2fEdgeDirection[12][3] =
00129 {
00130 {1.0, 0.0, 0.0},{0.0, 1.0, 0.0},{-1.0, 0.0, 0.0},{0.0, -1.0, 0.0},
00131 {1.0, 0.0, 0.0},{0.0, 1.0, 0.0},{-1.0, 0.0, 0.0},{0.0, -1.0, 0.0},
00132 {0.0, 0.0, 1.0},{0.0, 0.0, 1.0},{ 0.0, 0.0, 1.0},{0.0, 0.0, 1.0}
00133 };
00134
00135
00136 static const int edgeLookUp[12][4] =
00137 {
00138 {0,0,0,0},{1,0,0,1},{0,1,0,0},{0,0,0,1},
00139 {0,0,1,0},{1,0,1,1},{0,1,1,0},{0,0,1,1},
00140 {0,0,0,2},{1,0,0,2},{1,1,0,2},{0,1,0,2}
00141 };
00142
00143
00144
00145
00146
00147
00148
00149
00150 int aiCubeEdgeFlags[256]=
00151 {
00152 0x000, 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
00153 0x190, 0x099, 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
00154 0x230, 0x339, 0x033, 0x13a, 0x636, 0x73f, 0x435, 0x53c, 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
00155 0x3a0, 0x2a9, 0x1a3, 0x0aa, 0x7a6, 0x6af, 0x5a5, 0x4ac, 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
00156 0x460, 0x569, 0x663, 0x76a, 0x066, 0x16f, 0x265, 0x36c, 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
00157 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0x0ff, 0x3f5, 0x2fc, 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
00158 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x055, 0x15c, 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
00159 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0x0cc, 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
00160 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc, 0x0cc, 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
00161 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c, 0x15c, 0x055, 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
00162 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc, 0x2fc, 0x3f5, 0x0ff, 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
00163 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c, 0x36c, 0x265, 0x16f, 0x066, 0x76a, 0x663, 0x569, 0x460,
00164 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac, 0x4ac, 0x5a5, 0x6af, 0x7a6, 0x0aa, 0x1a3, 0x2a9, 0x3a0,
00165 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c, 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x033, 0x339, 0x230,
00166 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c, 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x099, 0x190,
00167 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c, 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x000
00168 };
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 int a2iTriangleConnectionTable[256][16] =
00179 {
00180 {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00181 {0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00182 {0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00183 {1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00184 {1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00185 {0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00186 {9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00187 {2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1},
00188 {3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00189 {0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00190 {1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00191 {1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1},
00192 {3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00193 {0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1},
00194 {3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1},
00195 {9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00196 {4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00197 {4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00198 {0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00199 {4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1},
00200 {1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00201 {3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1},
00202 {9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
00203 {2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1},
00204 {8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00205 {11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1},
00206 {9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
00207 {4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1},
00208 {3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1},
00209 {1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1},
00210 {4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1},
00211 {4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1},
00212 {9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00213 {9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00214 {0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00215 {8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1},
00216 {1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00217 {3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
00218 {5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1},
00219 {2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1},
00220 {9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00221 {0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
00222 {0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
00223 {2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1},
00224 {10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1},
00225 {4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1},
00226 {5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1},
00227 {5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1},
00228 {9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00229 {9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1},
00230 {0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1},
00231 {1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00232 {9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1},
00233 {10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1},
00234 {8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1},
00235 {2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1},
00236 {7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1},
00237 {9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1},
00238 {2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1},
00239 {11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1},
00240 {9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1},
00241 {5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1},
00242 {11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1},
00243 {11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00244 {10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00245 {0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00246 {9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00247 {1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
00248 {1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00249 {1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1},
00250 {9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1},
00251 {5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1},
00252 {2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00253 {11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
00254 {0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
00255 {5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1},
00256 {6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1},
00257 {0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1},
00258 {3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1},
00259 {6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1},
00260 {5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00261 {4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1},
00262 {1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
00263 {10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1},
00264 {6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1},
00265 {1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1},
00266 {8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1},
00267 {7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1},
00268 {3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
00269 {5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1},
00270 {0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1},
00271 {9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1},
00272 {8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1},
00273 {5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1},
00274 {0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1},
00275 {6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1},
00276 {10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00277 {4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1},
00278 {10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1},
00279 {8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1},
00280 {1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1},
00281 {3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1},
00282 {0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00283 {8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1},
00284 {10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1},
00285 {0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1},
00286 {3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1},
00287 {6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1},
00288 {9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1},
00289 {8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1},
00290 {3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1},
00291 {6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00292 {7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1},
00293 {0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1},
00294 {10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1},
00295 {10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1},
00296 {1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1},
00297 {2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1},
00298 {7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1},
00299 {7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00300 {2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1},
00301 {2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1},
00302 {1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1},
00303 {11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1},
00304 {8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1},
00305 {0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00306 {7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1},
00307 {7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00308 {7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00309 {3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00310 {0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00311 {8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
00312 {10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00313 {1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
00314 {2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
00315 {6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1},
00316 {7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00317 {7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1},
00318 {2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1},
00319 {1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1},
00320 {10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1},
00321 {10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1},
00322 {0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1},
00323 {7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1},
00324 {6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00325 {3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1},
00326 {8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1},
00327 {9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1},
00328 {6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1},
00329 {1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1},
00330 {4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1},
00331 {10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1},
00332 {8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1},
00333 {0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00334 {1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1},
00335 {1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1},
00336 {8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1},
00337 {10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1},
00338 {4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1},
00339 {10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00340 {4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00341 {0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
00342 {5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
00343 {11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1},
00344 {9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
00345 {6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1},
00346 {7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1},
00347 {3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1},
00348 {7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1},
00349 {9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1},
00350 {3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1},
00351 {6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1},
00352 {9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1},
00353 {1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1},
00354 {4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1},
00355 {7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1},
00356 {6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1},
00357 {3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1},
00358 {0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1},
00359 {6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1},
00360 {1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1},
00361 {0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1},
00362 {11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1},
00363 {6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1},
00364 {5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1},
00365 {9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1},
00366 {1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1},
00367 {1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00368 {1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1},
00369 {10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1},
00370 {0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00371 {10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00372 {11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00373 {11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1},
00374 {5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1},
00375 {10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1},
00376 {11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1},
00377 {0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1},
00378 {9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1},
00379 {7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1},
00380 {2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1},
00381 {8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1},
00382 {9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1},
00383 {9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1},
00384 {1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00385 {0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1},
00386 {9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1},
00387 {9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00388 {5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1},
00389 {5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1},
00390 {0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1},
00391 {10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1},
00392 {2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1},
00393 {0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1},
00394 {0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1},
00395 {9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00396 {2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1},
00397 {5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1},
00398 {3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1},
00399 {5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1},
00400 {8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1},
00401 {0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00402 {8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1},
00403 {9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00404 {4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1},
00405 {0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1},
00406 {1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1},
00407 {3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1},
00408 {4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1},
00409 {9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1},
00410 {11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1},
00411 {11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1},
00412 {2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1},
00413 {9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1},
00414 {3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1},
00415 {1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00416 {4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1},
00417 {4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1},
00418 {4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00419 {4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00420 {9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00421 {3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1},
00422 {0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1},
00423 {3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00424 {1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1},
00425 {3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1},
00426 {0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00427 {3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00428 {2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1},
00429 {9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00430 {2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1},
00431 {1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00432 {1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00433 {0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00434 {0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00435 {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}
00436 };
00437
00438 MarchingCubes::MarchingCubes()
00439 : _isodl(0)
00440 {
00441 }
00442
00443 MarchingCubes::MarchingCubes(EMData * em)
00444 : _isodl(0)
00445 {
00446 set_data(em);
00447 }
00448
00449 void MarchingCubes::clear_min_max_vals()
00450 {
00451 for (vector<EMData*>::iterator it = minvals.begin(); it != minvals.end(); ++it)
00452 {
00453 if ( (*it) != 0 ) delete *it;
00454 }
00455 minvals.clear();
00456
00457 for (vector<EMData*>::iterator it = maxvals.begin(); it != maxvals.end(); ++it)
00458 {
00459 if ( (*it) != 0 ) delete *it;
00460 }
00461 maxvals.clear();
00462 }
00463
00464 bool MarchingCubes::calculate_min_max_vals()
00465 {
00466
00467 if (_emdata == NULL ) throw NullPointerException("Error, cannot generate search tree if the overriding EMData object is NULL");
00468
00469 clear_min_max_vals();
00470
00471 int nx = _emdata->get_xsize();
00472 int ny = _emdata->get_ysize();
00473 int nz = _emdata->get_zsize();
00474
00475
00476 while ( nx > 1 || ny > 1 || nz > 1 )
00477 {
00478 int size = minvals.size();
00479
00480 if ( size == 0 ){
00481 Dict a;
00482
00483
00484 a["search"] = 3;
00485 minvals.push_back(_emdata->process("math.minshrink",a));
00486 maxvals.push_back(_emdata->process("math.maxshrink",a));
00487 }else {
00488 minvals.push_back(minvals[size-1]->process("math.minshrink"));
00489 maxvals.push_back(maxvals[size-1]->process("math.maxshrink"));
00490 }
00491
00492 nx = minvals[size]->get_xsize();
00493 ny = minvals[size]->get_ysize();
00494 nz = minvals[size]->get_zsize();
00495 #if MARCHING_CUBES_DEBUG
00496 cout << "dims are " << nx << " " << ny << " " << nz << endl;
00497 #endif
00498 }
00499
00500 drawing_level = -1;
00501
00502 return true;
00503 }
00504
00505 MarchingCubes::~MarchingCubes() {
00506 clear_min_max_vals();
00507 }
00508
00509 Dict MarchingCubes::get_isosurface()
00510 {
00511 calculate_surface();
00512 Dict d;
00513 d.put("points", (float*)pp.get_data());
00514 for (unsigned int i = 0; i < ff.elem(); ++i ) ff[i] /= 3;
00515 d.put("faces", (unsigned int*)ff.get_data());
00516 d.put("normals", (float*)nn.get_data());
00517 d.put("size", ff.elem());
00518 return d;
00519 }
00520
00521 void MarchingCubes::surface_face_z()
00522 {
00523 float* f = pp.get_data();
00524 float* n = nn.get_data();
00525 for (unsigned int i = 0; i < pp.elem(); i += 3 ) {
00526 if (f[i+2] == 0.5) continue;
00527 Vec3f z(0,0,1.0);
00528 Vec3f axis(-n[i+1],n[i],0);
00529 axis.normalize();
00530
00531 Dict d;
00532 d["type"] = "spin";
00533 d["Omega"] = 90.f;
00534 d["n1"] = axis[0];
00535 d["n2"] = axis[1];
00536 d["n3"] = 0;
00537 Transform t(d);
00538 Vec3f delta = t*z;
00539
00540 f[i] += delta[0]*.25f;
00541 f[i+1] += delta[1]*.25f;
00542 f[i+2] = 0.5;
00543 }
00544
00545 for (unsigned int i = 0; i < nn.elem(); i += 3 ) {
00546 n[i] = 0;
00547 n[i+1] = 0;
00548 n[i+2] = 1;
00549 }
00550 }
00551
00552 void MarchingCubes::set_data(EMData* data)
00553 {
00554 if ( data->get_zsize() == 1 ) throw ImageDimensionException("The z dimension of the image must be greater than 1");
00555 _emdata = data;
00556 calculate_min_max_vals();
00557 }
00558
00559 void MarchingCubes::set_surface_value(const float value) {
00560
00561 if(_surf_value == value) return;
00562
00563 _surf_value = value;
00564
00565 }
00566
00567 void MarchingCubes::calculate_surface() {
00568
00569 if ( _emdata == 0 ) throw NullPointerException("Error, attempt to generate isosurface, but the emdata image object has not been set");
00570 if ( minvals.size() == 0 || maxvals.size() == 0 ) throw NotExistingObjectException("Vector of EMData pointers", "Error, the min and max val search trees have not been created");
00571
00572 point_map.clear();
00573 pp.clear();
00574 nn.clear();
00575 ff.clear();
00576
00577 #if MARCHING_CUBES_DEBUG
00578 int time0 = clock();
00579 #endif
00580
00581 float min = minvals[minvals.size()-1]->get_value_at(0,0,0);
00582 float max = maxvals[minvals.size()-1]->get_value_at(0,0,0);
00583 if ( min < _surf_value && max > _surf_value) draw_cube(0,0,0,minvals.size()-1);
00584
00585 #if MARCHING_CUBES_DEBUG
00586 int time1 = clock();
00587 cout << "It took " << (time1-time0) << " " << (float)(time1-time0)/CLOCKS_PER_SEC << " to traverse the search tree and generate polygons" << endl;
00588 cout << "... using surface value " << _surf_value << endl;
00589 #endif
00590 }
00591
00592 void MarchingCubes::draw_cube(const int x, const int y, const int z, const int cur_level ) {
00593
00594 if ( cur_level == drawing_level )
00595 {
00596 EMData* e;
00597 if ( drawing_level == - 1 ) e = _emdata;
00598 else e = minvals[drawing_level];
00599 if ( x < (e->get_xsize()-1) && y < (e->get_ysize()-1) && z < (e->get_zsize()-1))
00600 marching_cube(x,y,z, cur_level);
00601 }
00602 else
00603 {
00604 EMData* e;
00605 if ( cur_level > 0 ) {
00606 int xsize = minvals[cur_level-1]->get_xsize();
00607 int ysize = minvals[cur_level-1]->get_ysize();
00608 int zsize = minvals[cur_level-1]->get_zsize();
00609 e = minvals[cur_level-1];
00610 for(int i=0; i<8; ++i ) {
00611 int xx = 2*x+a2fVertexOffset[i][0];
00612 if ( xx >= xsize ) continue;
00613 int yy = 2*y+a2fVertexOffset[i][1];
00614 if ( yy >= ysize ) continue;
00615 int zz = 2*z+a2fVertexOffset[i][2];
00616 if ( zz >= zsize ) continue;
00617
00618 float min = minvals[cur_level-1]->get_value_at(xx,yy,zz);
00619 float max = maxvals[cur_level-1]->get_value_at(xx,yy,zz);
00620 if ( min < _surf_value && max > _surf_value)
00621 draw_cube(xx,yy,zz,cur_level-1);
00622 }
00623 }
00624 else {
00625 e = _emdata;
00626 for(int i=0; i<8; ++i ) {
00627 draw_cube(2*x+a2fVertexOffset[i][0],2*y+a2fVertexOffset[i][1],2*z+a2fVertexOffset[i][2],cur_level-1);
00628 }
00629 }
00630
00631 if ( x == (minvals[cur_level]->get_xsize()-1) ) {
00632 if ( e->get_xsize() > 2*x ){
00633 for(int i=0; i<4; ++i ) {
00634 draw_cube(2*x+a2fPosXOffset[i][0],2*y+a2fPosXOffset[i][1],2*z+a2fPosXOffset[i][2],cur_level-1);
00635 }
00636 }
00637 if ( y == (minvals[cur_level]->get_ysize()-1) ) {
00638 if ( e->get_ysize() > 2*y ) {
00639 for(int i=0; i<2; ++i ) {
00640 draw_cube(2*x+a2fPosXPosYOffset[i][0],2*y+a2fPosXPosYOffset[i][1],2*z+a2fPosXPosYOffset[i][2],cur_level-1);
00641 }
00642 }
00643 if ( z == (minvals[cur_level]->get_zsize()-1) ){
00644 if ( e->get_zsize() > 2*z ) {
00645 draw_cube(2*x+2,2*y+2,2*z+2,cur_level-1);
00646 }
00647 }
00648 }
00649 if ( z == (minvals[cur_level]->get_zsize()-1) ) {
00650 if ( e->get_zsize() > 2*z ) {
00651 for(int i=0; i<2; ++i ) {
00652 draw_cube(2*x+a2fPosXPosZOffset[i][0],2*y+a2fPosXPosZOffset[i][1],2*z+a2fPosXPosZOffset[i][2],cur_level-1);
00653 }
00654 }
00655 }
00656 }
00657 if ( y == (minvals[cur_level]->get_ysize()-1) ) {
00658 if ( e->get_ysize() > 2*y ) {
00659 for(int i=0; i<4; ++i ) {
00660 draw_cube(2*x+a2fPosYOffset[i][0],2*y+a2fPosYOffset[i][1],2*z+a2fPosYOffset[i][2],cur_level-1);
00661 }
00662 }
00663 if ( z == (minvals[cur_level]->get_ysize()-1) ) {
00664 if ( e->get_zsize() > 2*z ) {
00665 for(int i=0; i<2; ++i ) {
00666 draw_cube(2*x+a2fPosYPosZOffset[i][0],2*y+a2fPosYPosZOffset[i][1],2*z+a2fPosYPosZOffset[i][2],cur_level-1);
00667 }
00668 }
00669 }
00670 }
00671 if ( z == (minvals[cur_level]->get_zsize()-1) ) {
00672 if ( e->get_zsize() > 2*z ) {
00673 for(int i=0; i<4; ++i ) {
00674 draw_cube(2*x+a2fPosZOffset[i][0],2*y+a2fPosZOffset[i][1],2*z+a2fPosZOffset[i][2],cur_level-1);
00675 }
00676 }
00677 }
00678
00679 }
00680 }
00681
00682 void MarchingCubes::get_normal(Vector3 &normal, int fX, int fY, int fZ)
00683 {
00684 normal[0] = _emdata->get_value_at(fX-1, fY, fZ) - _emdata->get_value_at(fX+1, fY, fZ);
00685 normal[1] = _emdata->get_value_at(fX, fY-1, fZ) - _emdata->get_value_at(fX, fY+1, fZ);
00686 normal[2] = _emdata->get_value_at(fX, fY, fZ-1) - _emdata->get_value_at(fX, fY, fZ+1);
00687 normal.normalize();
00688 }
00689
00690 float MarchingCubes::get_offset(float fValue1, float fValue2, float fValueDesired)
00691 {
00692 float fDelta = fValue2 - fValue1;
00693
00694 if(fDelta == 0.0f)
00695 {
00696 return 0.5f;
00697 }
00698 return (fValueDesired - fValue1)/fDelta;
00699 }
00700
00701 int MarchingCubes::get_edge_num(int x, int y, int z, int edge) {
00702
00703 unsigned int index = 0;
00704 index = (x << 22) | (y << 12) | (z << 2) | edge;
00705 return index;
00706 }
00707
00708 void MarchingCubes::marching_cube(int fX, int fY, int fZ, int cur_level)
00709 {
00710
00711
00712
00713 int iCorner, iVertex, iVertexTest, iEdge, iTriangle, iFlagIndex, iEdgeFlags;
00714 float fOffset;
00715 Vector3 sColor;
00716 float afCubeValue[8];
00717 float asEdgeVertex[12][3];
00718 int pointIndex[12];
00719
00720 int fxScale = 1, fyScale = 1, fzScale = 1;
00721 if ( cur_level != -1 )
00722 {
00723 fxScale = _emdata->get_xsize()/minvals[cur_level]->get_xsize();
00724 fyScale = _emdata->get_ysize()/minvals[cur_level]->get_ysize();
00725 fzScale = _emdata->get_zsize()/minvals[cur_level]->get_zsize();
00726 for(iVertex = 0; iVertex < 8; iVertex++)
00727 {
00728 afCubeValue[iVertex] = _emdata->get_value_at( fxScale*(fX + a2fVertexOffset[iVertex][0]),
00729 fyScale*(fY + a2fVertexOffset[iVertex][1]), fzScale*(fZ + a2fVertexOffset[iVertex][2]));
00730 }
00731 }
00732 else
00733 {
00734
00735 for(iVertex = 0; iVertex < 8; iVertex++)
00736 {
00737 afCubeValue[iVertex] = _emdata->get_value_at( fX + a2fVertexOffset[iVertex][0],
00738 fY + a2fVertexOffset[iVertex][1], fZ + a2fVertexOffset[iVertex][2]);
00739 }
00740 }
00741
00742
00743 iFlagIndex = 0;
00744 for(iVertexTest = 0; iVertexTest < 8; iVertexTest++)
00745 {
00746 if (_surf_value >= 0 ){
00747 if(afCubeValue[iVertexTest] <= _surf_value)
00748 iFlagIndex |= 1<<iVertexTest;
00749 }
00750 else {
00751 if(afCubeValue[iVertexTest] >= _surf_value)
00752 iFlagIndex |= 1<<iVertexTest;
00753 }
00754 }
00755
00756
00757 iEdgeFlags = aiCubeEdgeFlags[iFlagIndex];
00758
00759
00760 if(iEdgeFlags == 0) return;
00761
00762
00763
00764 for(iEdge = 0; iEdge < 12; iEdge++)
00765 {
00766
00767 if(iEdgeFlags & (1<<iEdge))
00768 {
00769 fOffset = get_offset(afCubeValue[ a2iEdgeConnection[iEdge][0] ],
00770 afCubeValue[ a2iEdgeConnection[iEdge][1] ], _surf_value);
00771
00772 if ( cur_level == -1 ){
00773 asEdgeVertex[iEdge][0] = fX + (a2fVertexOffset[ a2iEdgeConnection[iEdge][0] ][0] + fOffset * a2fEdgeDirection[iEdge][0]) + 0.5f;
00774 asEdgeVertex[iEdge][1] = fY + (a2fVertexOffset[ a2iEdgeConnection[iEdge][0] ][1] + fOffset * a2fEdgeDirection[iEdge][1]) + 0.5f;
00775 asEdgeVertex[iEdge][2] = fZ + (a2fVertexOffset[ a2iEdgeConnection[iEdge][0] ][2] + fOffset * a2fEdgeDirection[iEdge][2]) + 0.5f;
00776 } else {
00777 asEdgeVertex[iEdge][0] = fxScale*(fX + (a2fVertexOffset[ a2iEdgeConnection[iEdge][0] ][0] + fOffset * a2fEdgeDirection[iEdge][0])) + 0.5f;
00778 asEdgeVertex[iEdge][1] = fyScale*(fY + (a2fVertexOffset[ a2iEdgeConnection[iEdge][0] ][1] + fOffset * a2fEdgeDirection[iEdge][1])) + 0.5f;
00779 asEdgeVertex[iEdge][2] = fzScale*(fZ + (a2fVertexOffset[ a2iEdgeConnection[iEdge][0] ][2] + fOffset * a2fEdgeDirection[iEdge][2])) + 0.5f;
00780 }
00781
00782 pointIndex[iEdge] = get_edge_num(fX+edgeLookUp[iEdge][0], fY+edgeLookUp[iEdge][1], fZ+edgeLookUp[iEdge][2], edgeLookUp[iEdge][3]);
00783 }
00784 }
00785
00786
00787 for(iTriangle = 0; iTriangle < 5; iTriangle++)
00788 {
00789 if(a2iTriangleConnectionTable[iFlagIndex][3*iTriangle] < 0)
00790 break;
00791
00792 float pts[3][3];
00793 for(iCorner = 0; iCorner < 3; iCorner++)
00794 {
00795 iVertex = a2iTriangleConnectionTable[iFlagIndex][3*iTriangle+iCorner];
00796 memcpy(&pts[iCorner][0], &asEdgeVertex[iVertex][0], 3*sizeof(float));
00797 }
00798
00799
00800
00801 float v1[3] = {pts[1][0]-pts[0][0],pts[1][1]-pts[0][1],pts[1][2]-pts[0][2]};
00802 float v2[3] = {pts[2][0]-pts[1][0],pts[2][1]-pts[1][1],pts[2][2]-pts[1][2]};
00803
00804 float n[3] = { v1[1]*v2[2] - v1[2]*v2[1], v1[2]*v2[0] - v1[0]*v2[2], v1[0]*v2[1] - v1[1]*v2[0] };
00805
00806 for(iCorner = 0; iCorner < 3; iCorner++)
00807 {
00808
00809
00810
00811
00812
00813
00814
00815
00816 iVertex = a2iTriangleConnectionTable[iFlagIndex][3*iTriangle+iCorner];
00817 map<int,int>::iterator it = point_map.find(pointIndex[iVertex]);
00818 if ( it == point_map.end() ){
00819 int ss = pp.elem();
00820 pp.push_back_3(&pts[iCorner][0]);
00821 nn.push_back_3(&n[0]);
00822 ff.push_back(ss);
00823 point_map[pointIndex[iVertex]] = ss;
00824 } else {
00825 int idx = it->second;
00826 ff.push_back(idx);
00827 nn[idx] += n[0];
00828 nn[idx+1] += n[1];
00829 nn[idx+2] += n[2];
00830 }
00831 }
00832 }
00833 }
00834
00835
00836
00837 U3DWriter::U3DWriter() : DIFFUSE_COLOR_COUNT(1),
00838 SPECULAR_COLOR_COUNT(1)
00839 {
00840 }
00841 U3DWriter::~U3DWriter() {}
00842
00843 using std::ofstream;
00844
00845 int U3DWriter::write(const string& filename) {
00846
00847 ofstream of(filename.c_str(), ofstream::binary);
00848 write(of);
00849 of.close();
00850
00851 return 1;
00852 }
00853
00854 ostream& U3DWriter::write(ostream& os) {
00855 write_header(os);
00856 return os;
00857 }
00858
00859 unsigned int U3DWriter::size_of_in_bytes(){
00860
00861
00862 unsigned size = 4+2+2+4+4+8+4+8;
00863 return size;
00864 }
00865 ostream& U3DWriter::write_header(ostream& os)
00866 {
00867
00868 test_type_sizes();
00869
00870 U32 block_type_file_header = 0x00443355;
00871 write( os, block_type_file_header);
00872
00873 I16 major_version = -1;
00874 I16 minor_version = 0;
00875 write( os, major_version);
00876 write( os, minor_version);
00877
00878 U32 profile_identifier = 0x00000000;
00879 write( os, profile_identifier);
00880
00881 U32 declaration_size = size_of_in_bytes();
00882 write( os, declaration_size);
00883
00884 U64 file_size = size_of_in_bytes();
00885 write( os, file_size);
00886
00887 U32 character_encoding = 106;
00888 write( os, character_encoding);
00889
00890 F64 unit_scaling = 1.0;
00891 write( os, unit_scaling);
00892
00893
00894 return os;
00895 }
00896
00897 void U3DWriter::test_type_sizes()
00898 {
00899 bool error = false;
00900 if (sizeof(F64) != 8 ){
00901 cout << "Error, size of double is not 64 bytes, it's " << sizeof(F64)*4 << endl;
00902 error = true;
00903 }
00904 if (sizeof(F32) != 4 ){
00905 cout << "Error, size of float is not 32 bytes, it's " << sizeof(F32)*4 << endl;
00906 error = true;
00907 }
00908 if (sizeof(U64) != 8) {
00909 cout << "Error, size of long unsigned int is not 64 bytes, it's " << sizeof(U64)*4 << endl;
00910 error = true;
00911 }
00912 if (sizeof(U32) != 4) {
00913 cout << "Error, size of unsigned int is not 32 bytes, it's " << sizeof(U32)*4 << endl;
00914 error = true;
00915 }
00916 if (sizeof(I16) != 2) {
00917 cout << "Error, size of short int is not 16 bytes, it's " << sizeof(I16)*4 << endl;
00918 error = true;
00919 }
00920 if (sizeof(U16) != 2) {
00921 cout << "Error, size of short unsigned int is not 16 bytes, it's " << sizeof(U16)*4 << endl;
00922 error = true;
00923 }
00924 if (sizeof(U8) != 1) {
00925 cout << "Error, size of unsigned char is not bytes, it's " << sizeof(U8)*4 << endl;
00926 error = true;
00927 }
00928
00929 if (error) {
00930 throw;
00931 }
00932 }
00933
00934 ostream& U3DWriter::write_clod_mesh_generator_node(ostream& os)
00935 {
00936
00937
00938
00939 U32 block_type_clod_mesh_generator = 0xFFFFFF31;
00940 write( os, block_type_clod_mesh_generator);
00941
00942 string name("testmesh");
00943 write(os,name);
00944
00945 U32 chain_index = 0x00000000;
00946 write( os, chain_index);
00947
00948
00949
00950
00951 U32 mesh_attributes = 0x00000000;
00952 write(os,mesh_attributes);
00953 U32 face_count = ff.elem();
00954 write(os,face_count);
00955 U32 position_count = pp.elem();
00956 write(os,position_count);
00957 U32 normal_count = nn.elem();
00958 write(os,normal_count);
00959 U32 diffuse_color_count = DIFFUSE_COLOR_COUNT;
00960 write(os,diffuse_color_count);
00961 U32 specular_color_count = SPECULAR_COLOR_COUNT;
00962 write(os,specular_color_count);
00963 U32 texture_coord_count = 0x00000000;
00964 write(os,texture_coord_count);
00965 U32 shading_count = 1;
00966 write(os,shading_count);
00967
00968
00969
00970
00971 U32 shading_attributes = 0x00000003;
00972 write(os,shading_attributes);
00973 U32 texture_layout_count = 0x00000000;
00974 write(os,texture_layout_count);
00975 U32 texture_coord_dimensions = 0x00000002;
00976 write(os,texture_coord_dimensions);
00977 U32 original_shading_id = 0;
00978 write(os,original_shading_id);
00979
00980
00981
00982
00983
00984 U32 minimum_resolution = position_count;
00985 write(os,minimum_resolution);
00986 U32 final_maximum_resolution = position_count;
00987 write(os,final_maximum_resolution);
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997 U32 position_quality_factor = 0x00000000;
00998 write(os,position_quality_factor);
00999 U32 normal_quality_factor = 0x00000000;
01000 write(os,normal_quality_factor);
01001 U32 texture_coord_quality_factor = 0x00000000;
01002 write(os,texture_coord_quality_factor);
01003
01004
01005
01006
01007
01008 F32 postion_inverse_quant = 1.0;
01009 write(os,postion_inverse_quant);
01010 F32 normal_inverse_quant = 1.0;
01011 write(os,normal_inverse_quant);
01012 F32 texture_coord_inverse_quant = 1.0;
01013 write(os,texture_coord_inverse_quant);
01014 F32 diffuse_color_inverse_quant = 1.0;
01015 write(os,diffuse_color_inverse_quant);
01016 F32 specular_color_inverse_quant = 1.0;
01017 write(os,specular_color_inverse_quant);
01018
01019
01020
01021
01022
01023
01024 F32 normal_crease_parameter = 1.0;
01025 write(os,normal_crease_parameter);
01026 F32 normal_update_parameter = 0.0;
01027 write(os,normal_update_parameter);
01028 F32 normal_tolerance_parameter = 0.0;
01029 write(os,normal_tolerance_parameter);
01030
01031
01032
01033
01034
01035 U32 bone_count = 0x00000000;
01036 write(os,bone_count);
01037
01038
01039
01041
01042
01043
01044 {
01045 U32 block_type_clod_base_mesh_continuation = 0xFFFFFF3B;
01046 write( os, block_type_clod_base_mesh_continuation);
01047
01048 write(os,name);
01049
01050 U32 chain_index = 0x00000000;
01051 write( os, chain_index);
01052
01053
01054
01055
01056 U32 base_face_count = ff.elem();
01057 write( os, base_face_count);
01058 U32 base_position_count = pp.elem();
01059 write( os, base_position_count);
01060 U32 base_normal_count = nn.elem();
01061 write( os, base_normal_count);
01062 U32 base_diffuse_color_count = DIFFUSE_COLOR_COUNT;
01063 write( os, base_diffuse_color_count);
01064 U32 base_specular_color_count = SPECULAR_COLOR_COUNT;
01065 write( os, base_specular_color_count);
01066 U32 base_texture_coord_count = 0x00000000;
01067 write( os, base_texture_coord_count);
01068
01069
01070
01071
01072
01073
01074 F32* data = pp.get_data();
01075 for(unsigned int i = 0; i < pp.elem(); ++i) {
01076 write(os,data[i]);
01077 }
01078
01079
01080 data = nn.get_data();
01081 for(unsigned int i = 0; i < nn.elem(); ++i) {
01082 write(os,data[i]);
01083 }
01084
01085
01086 F32 diffuse_rgba[4] = {1.0,0.0,0.0,1.0};
01087 for (unsigned int i = 0; i < 4; ++i) {
01088 write(os,diffuse_rgba[i]);
01089 }
01090
01091
01092 F32 specular_rgba[4] = {1.0,0.0,0.0,1.0};
01093 for (unsigned int i = 0; i < 4; ++i) {
01094 write(os,specular_rgba[i]);
01095 }
01096
01097
01098
01099
01100
01101 U32* faces = ff.get_data();
01102 for(unsigned int i = 0; i < pp.elem(); i = i+3) {
01103 U32 shading_id = 0;
01104 write(os,shading_id);
01105
01106
01107 for (unsigned int j =0; j < 3; ++j){
01108 U32 position_index = faces[i+j];
01109 write(os,position_index);
01110
01111 U32 normal_index = position_index;
01112 write(os,normal_index);
01113
01114 U32 base_diffuse_color_index = 0;
01115 write(os,base_diffuse_color_index);
01116
01117 U32 base_specular_color_index = 0;
01118 write(os,base_specular_color_index);
01119
01120
01121
01122 }
01123
01124 }
01125
01126 }
01127 return os;
01128 }
01129
01130 template<>
01131 ostream& U3DWriter::write(ostream& os, const string& s )
01132 {
01133
01134
01135 test_type_sizes();
01136
01137 short unsigned int size = s.size();
01138 write(os,size);
01139
01140
01141 for(unsigned int i = 0; i<size; ++i) {
01142 write(os,s[i]);
01143 }
01144
01145 return os;
01146 }
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162