Blender V2.61 - r43446

dualcon_c_api.cpp

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * Contributor(s): Nicholas Bishop
00019  *
00020  * ***** END GPL LICENSE BLOCK *****
00021  */
00022 
00023 #include <cassert>
00024 #include "dualcon.h"
00025 #include "ModelReader.h"
00026 #include "octree.h"
00027 
00028 #include <cstdio>
00029 
00030 void veccopy(float dst[3], const float src[3])
00031 {
00032     dst[0] = src[0];
00033     dst[1] = src[1];
00034     dst[2] = src[2];
00035 }
00036 
00037 #define GET_FACE(_mesh, _n) \
00038     (*(DualConFaces)(((char*)(_mesh)->faces) + ((_n) * (_mesh)->face_stride)))
00039 
00040 #define GET_CO(_mesh, _n) \
00041     (*(DualConCo)(((char*)(_mesh)->co) + ((_n) * (_mesh)->co_stride)))
00042 
00043 class DualConInputReader : public ModelReader
00044 {
00045 private:
00046     const DualConInput *input_mesh;
00047     int tottri, curface, offset;
00048     float min[3], max[3], maxsize;
00049     float scale;
00050 public:
00051     DualConInputReader(const DualConInput *mesh, float _scale)
00052     : input_mesh(mesh), scale(_scale)
00053     {
00054         reset();
00055     }
00056 
00057     void reset()
00058     {
00059         tottri = 0;
00060         curface = 0;
00061         offset = 0;
00062         maxsize = 0;
00063 
00064         /* initialize tottri */
00065         for(int i = 0; i < input_mesh->totface; i++)
00066             tottri += GET_FACE(input_mesh, i)[3] ? 2 : 1;
00067 
00068         veccopy(min, input_mesh->min);
00069         veccopy(max, input_mesh->max);
00070 
00071         /* initialize maxsize */
00072         for(int i = 0; i < 3; i++) {
00073             float d = max[i] - min[i];
00074             if(d > maxsize)
00075                 maxsize = d;
00076         }
00077 
00078         /* redo the bounds */
00079         for(int i = 0; i < 3; i++)
00080         {
00081             min[i] = (max[i] + min[i]) / 2 - maxsize / 2;
00082             max[i] = (max[i] + min[i]) / 2 + maxsize / 2;
00083         }
00084 
00085         for(int i = 0; i < 3; i++)
00086             min[i] -= maxsize * (1 / scale - 1) / 2;
00087         maxsize *= 1 / scale;
00088     }
00089 
00090     Triangle* getNextTriangle()
00091     {
00092         if(curface == input_mesh->totface)
00093             return 0;
00094 
00095         Triangle* t = new Triangle();
00096         
00097         unsigned int *f = GET_FACE(input_mesh, curface);
00098         if(offset == 0) {
00099             veccopy(t->vt[0], GET_CO(input_mesh, f[0]));
00100             veccopy(t->vt[1], GET_CO(input_mesh, f[1]));
00101             veccopy(t->vt[2], GET_CO(input_mesh, f[2]));
00102         }
00103         else {
00104             veccopy(t->vt[0], GET_CO(input_mesh, f[2]));
00105             veccopy(t->vt[1], GET_CO(input_mesh, f[3]));
00106             veccopy(t->vt[2], GET_CO(input_mesh, f[0]));
00107         }
00108 
00109         if(offset == 0 && f[3])
00110             offset++;
00111         else {
00112             offset = 0;
00113             curface++;
00114         }
00115 
00116         return t;
00117     }
00118 
00119     int getNextTriangle(int t[3])
00120     {
00121         if(curface == input_mesh->totface)
00122             return 0;
00123         
00124         unsigned int *f = GET_FACE(input_mesh, curface);
00125         if(offset == 0) {
00126             t[0] = f[0];
00127             t[1] = f[1];
00128             t[2] = f[2];
00129         }
00130         else {
00131             t[0] = f[2];
00132             t[1] = f[3];
00133             t[2] = f[0];
00134         }
00135 
00136         if(offset == 0 && f[3])
00137             offset++;
00138         else {
00139             offset = 0;
00140             curface++;
00141         }
00142 
00143         return 1;
00144     }
00145 
00146     int getNumTriangles()
00147     {
00148         return tottri;
00149     }
00150 
00151     int getNumVertices()
00152     {
00153         return input_mesh->totco;
00154     }
00155 
00156     float getBoundingBox(float origin[3])
00157     {
00158         veccopy(origin, min);
00159         return maxsize ;
00160     }
00161 
00162     /* output */
00163     void getNextVertex(float v[3])
00164     {
00165         /* not used */
00166     }
00167 
00168     /* stubs */
00169     void printInfo() {}
00170     int getMemory() { return sizeof(DualConInputReader); }
00171 };
00172 
00173 void *dualcon(const DualConInput *input_mesh,
00174               /* callbacks for output */
00175               DualConAllocOutput alloc_output,
00176               DualConAddVert add_vert,
00177               DualConAddQuad add_quad,
00178                      
00179               DualConFlags flags,
00180               DualConMode mode,
00181               float threshold,
00182               float hermite_num,
00183               float scale,
00184               int depth)
00185 {
00186     DualConInputReader r(input_mesh, scale);
00187     Octree o(&r, alloc_output, add_vert, add_quad,
00188              flags, mode, depth, threshold, hermite_num);
00189     o.scanConvert();
00190     return o.getOutputMesh();
00191 }