Initial revision
[blender.git] / intern / decimation / intern / LOD_decimation.cpp
1 /**
2  * $Id$
3  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version. The Blender
9  * Foundation also sells licenses for use in proprietary software under
10  * the Blender License.  See http://www.blender.org/BL/ for information
11  * about this.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * The Original Code is: all of this file.
26  *
27  * Contributor(s): none yet.
28  *
29  * ***** END GPL/BL DUAL LICENSE BLOCK *****
30  */
31
32 // implementation of external c api
33
34
35 #include "../extern/LOD_decimation.h"
36 #include "LOD_DecimationClass.h"
37
38 using namespace std;
39
40         int 
41 LOD_LoadMesh(
42         LOD_Decimation_InfoPtr info
43 ) {
44         if (info == NULL) return 0;
45         if (
46                 info->vertex_buffer == NULL ||
47                 info->vertex_normal_buffer == NULL ||
48                 info->triangle_index_buffer == NULL
49         ) {
50                 return 0;
51         }
52
53
54         // create the intern object to hold all 
55         // the decimation classes
56
57         MEM_SmartPtr<LOD_DecimationClass> intern(LOD_DecimationClass::New(info));
58
59         if (intern == NULL) return 0;
60
61         MEM_SmartPtr<vector<LOD_Vertex> > intern_vertex_buffer(new vector<LOD_Vertex>(info->vertex_num));
62         if (intern_vertex_buffer == NULL) return 0;
63
64         vector<LOD_Vertex>::iterator intern_vertex_it(intern_vertex_buffer->begin());
65
66         // now load in the vertices to the mesh
67
68         const int vertex_stride = 3;
69
70         float * vertex_ptr = info->vertex_buffer;
71         const float * vertex_end = vertex_ptr + info->vertex_num*vertex_stride;
72         
73         LOD_ManMesh2 &mesh = intern->Mesh();
74
75         for (;vertex_ptr < vertex_end; vertex_ptr += vertex_stride,++intern_vertex_it) {
76                 intern_vertex_it->pos = MT_Vector3(vertex_ptr);
77         }
78         
79         mesh.SetVertices(intern_vertex_buffer);
80
81         // load in the triangles
82         
83         const int triangle_stride = 3;
84
85         int * triangle_ptr = info->triangle_index_buffer;
86         const int * triangle_end = triangle_ptr + info->face_num*triangle_stride;
87
88         try {
89
90                 for (;triangle_ptr < triangle_end; triangle_ptr += triangle_stride) {
91                         mesh.AddTriangle(triangle_ptr);
92                 }
93         }
94
95         catch (...) {
96                 return 0;
97         }
98
99         // ok we have built the mesh 
100
101         intern->m_e_decimation_state = LOD_DecimationClass::e_loaded;
102
103         info->intern = (void *) (intern.Release());     
104
105         return 1;
106 }
107
108         int 
109 LOD_PreprocessMesh(
110         LOD_Decimation_InfoPtr info
111 ) {
112         if (info == NULL) return 0;
113         if (info->intern == NULL) return 0;
114
115         LOD_DecimationClass *intern = (LOD_DecimationClass *) info->intern;
116         if (intern->m_e_decimation_state != LOD_DecimationClass::e_loaded) return 0;    
117
118         // arm the various internal classes so that we are ready to step
119         // through decimation
120
121         intern->FaceEditor().BuildNormals();
122         if (intern->Decimator().Arm() == false) return 0;
123
124         // ok preprocessing done 
125         intern->m_e_decimation_state = LOD_DecimationClass::e_preprocessed;
126
127         return 1;
128 }
129
130         int 
131 LOD_CollapseEdge(
132         LOD_Decimation_InfoPtr info
133 ){
134         if (info == NULL) return 0;
135         if (info->intern == NULL) return 0;
136         LOD_DecimationClass *intern = (LOD_DecimationClass *) info->intern;
137         if (intern->m_e_decimation_state != LOD_DecimationClass::e_preprocessed) return 0;      
138
139         bool step_result = intern->Decimator().Step();
140
141         return step_result == true ? 1 : 0;
142 }       
143
144         
145         int
146 LOD_FreeDecimationData(
147         LOD_Decimation_InfoPtr info
148 ){
149         if (info == NULL) return 0;
150         if (info->intern == NULL) return 0;
151         LOD_DecimationClass *intern = (LOD_DecimationClass *) info->intern;
152         delete(intern);
153         info->intern = NULL;
154         return 1;
155 }
156