LEFT | RIGHT |
(no file at all) | |
| 1 /* |
| 2 * ***** BEGIN GPL LICENSE BLOCK ***** |
| 3 * |
| 4 * This program is free software; you can redistribute it and/or |
| 5 * modify it under the terms of the GNU General Public License |
| 6 * as published by the Free Software Foundation; either version 2 |
| 7 * of the License, or (at your option) any later version. |
| 8 * |
| 9 * This program is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 * GNU General Public License for more details. |
| 13 * |
| 14 * You should have received a copy of the GNU General Public License |
| 15 * along with this program; if not, write to the Free Software Foundation, |
| 16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| 17 * |
| 18 * Contributor(s): Nicholas Bishop |
| 19 * |
| 20 * ***** END GPL LICENSE BLOCK ***** |
| 21 */ |
| 22 |
| 23 #include <cassert> |
| 24 #include "dualcon.h" |
| 25 #include "ModelReader.h" |
| 26 #include "octree.h" |
| 27 |
| 28 #include <cstdio> |
| 29 |
| 30 void veccopy(float dst[3], const float src[3]) |
| 31 { |
| 32 dst[0] = src[0]; |
| 33 dst[1] = src[1]; |
| 34 dst[2] = src[2]; |
| 35 } |
| 36 |
| 37 #define GET_FACE(_mesh, _n) \ |
| 38 (*(DualConFaces)(((char*)(_mesh)->faces) + ((_n) * (_mesh)->face_stride)
)) |
| 39 |
| 40 #define GET_CO(_mesh, _n) \ |
| 41 (*(DualConCo)(((char*)(_mesh)->co) + ((_n) * (_mesh)->co_stride))) |
| 42 |
| 43 class DualConInputReader : public ModelReader |
| 44 { |
| 45 private: |
| 46 const DualConInput *input_mesh; |
| 47 int tottri, curface, offset; |
| 48 float min[3], max[3], maxsize; |
| 49 float scale; |
| 50 public: |
| 51 DualConInputReader(const DualConInput *mesh, float _scale) |
| 52 : input_mesh(mesh), scale(_scale) |
| 53 { |
| 54 reset(); |
| 55 } |
| 56 |
| 57 void reset() |
| 58 { |
| 59 tottri = 0; |
| 60 curface = 0; |
| 61 offset = 0; |
| 62 maxsize = 0; |
| 63 |
| 64 /* initialize tottri */ |
| 65 for(int i = 0; i < input_mesh->totface; i++) |
| 66 tottri += GET_FACE(input_mesh, i)[3] ? 2 : 1; |
| 67 |
| 68 veccopy(min, input_mesh->min); |
| 69 veccopy(max, input_mesh->max); |
| 70 |
| 71 /* initialize maxsize */ |
| 72 for(int i = 0; i < 3; i++) { |
| 73 float d = max[i] - min[i]; |
| 74 if(d > maxsize) |
| 75 maxsize = d; |
| 76 } |
| 77 |
| 78 /* redo the bounds */ |
| 79 for(int i = 0; i < 3; i++) |
| 80 { |
| 81 min[i] = (max[i] + min[i]) / 2 - maxsize / 2; |
| 82 max[i] = (max[i] + min[i]) / 2 + maxsize / 2; |
| 83 } |
| 84 |
| 85 for(int i = 0; i < 3; i++) |
| 86 min[i] -= maxsize * (1 / scale - 1) / 2; |
| 87 maxsize *= 1 / scale; |
| 88 } |
| 89 |
| 90 Triangle* getNextTriangle() |
| 91 { |
| 92 if(curface == input_mesh->totface) |
| 93 return 0; |
| 94 |
| 95 Triangle* t = new Triangle(); |
| 96 ················ |
| 97 unsigned int *f = GET_FACE(input_mesh, curface); |
| 98 if(offset == 0) { |
| 99 veccopy(t->vt[0], GET_CO(input_mesh, f[0])); |
| 100 veccopy(t->vt[1], GET_CO(input_mesh, f[1])); |
| 101 veccopy(t->vt[2], GET_CO(input_mesh, f[2])); |
| 102 } |
| 103 else { |
| 104 veccopy(t->vt[0], GET_CO(input_mesh, f[2])); |
| 105 veccopy(t->vt[1], GET_CO(input_mesh, f[3])); |
| 106 veccopy(t->vt[2], GET_CO(input_mesh, f[0])); |
| 107 } |
| 108 |
| 109 if(offset == 0 && f[3]) |
| 110 offset++; |
| 111 else { |
| 112 offset = 0; |
| 113 curface++; |
| 114 } |
| 115 |
| 116 return t; |
| 117 } |
| 118 |
| 119 int getNextTriangle(int t[3]) |
| 120 { |
| 121 if(curface == input_mesh->totface) |
| 122 return 0; |
| 123 ················ |
| 124 unsigned int *f = GET_FACE(input_mesh, curface); |
| 125 if(offset == 0) { |
| 126 t[0] = f[0]; |
| 127 t[1] = f[1]; |
| 128 t[2] = f[2]; |
| 129 } |
| 130 else { |
| 131 t[0] = f[2]; |
| 132 t[1] = f[3]; |
| 133 t[2] = f[0]; |
| 134 } |
| 135 |
| 136 if(offset == 0 && f[3]) |
| 137 offset++; |
| 138 else { |
| 139 offset = 0; |
| 140 curface++; |
| 141 } |
| 142 |
| 143 return 1; |
| 144 } |
| 145 |
| 146 int getNumTriangles() |
| 147 { |
| 148 return tottri; |
| 149 } |
| 150 |
| 151 int getNumVertices() |
| 152 { |
| 153 return input_mesh->totco; |
| 154 } |
| 155 |
| 156 float getBoundingBox(float origin[3]) |
| 157 { |
| 158 veccopy(origin, min); |
| 159 return maxsize ; |
| 160 } |
| 161 |
| 162 /* output */ |
| 163 void getNextVertex(float v[3]) |
| 164 { |
| 165 /* not used */ |
| 166 } |
| 167 |
| 168 /* stubs */ |
| 169 void printInfo() {} |
| 170 int getMemory() { return sizeof(DualConInputReader); } |
| 171 }; |
| 172 |
| 173 void *dualcon(const DualConInput *input_mesh, |
| 174 /* callbacks for output */ |
| 175 DualConAllocOutput alloc_output, |
| 176 DualConAddVert add_vert, |
| 177 DualConAddQuad add_quad, |
| 178 ········································· |
| 179 DualConFlags flags, |
| 180 DualConMode mode, |
| 181 float threshold, |
| 182 float hermite_num, |
| 183 float scale, |
| 184 int depth) |
| 185 { |
| 186 DualConInputReader r(input_mesh, scale); |
| 187 Octree o(&r, alloc_output, add_vert, add_quad, |
| 188 flags, mode, depth, threshold, hermite_num); |
| 189 o.scanConvert(); |
| 190 return o.getOutputMesh(); |
| 191 } |
LEFT | RIGHT |