Merge with trunk r41342
[blender-staging.git] / intern / decimation / intern / LOD_ExternBufferEditor.h
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  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file decimation/intern/LOD_ExternBufferEditor.h
29  *  \ingroup decimation
30  */
31
32
33 /**
34
35  * Copyright (C) 2001 NaN Technologies B.V.
36  */
37
38 #ifndef NAN_INCLUDED_LOD_ExternBufferEditor_h
39 #define NAN_INCLUDED_LOD_ExternBufferEditor_h
40
41 #include "LOD_MeshPrimitives.h"
42 #include <vector>
43 #include "LOD_ManMesh2.h"
44 #include "../extern/LOD_decimation.h"
45
46
47 // This class syncs external vertex/face buffers 
48 // with the internal mesh representation during
49 // decimation.
50
51 class LOD_ExternBufferEditor 
52 {
53
54 public :
55
56         static 
57                 LOD_ExternBufferEditor *
58         New(
59                 LOD_Decimation_InfoPtr extern_info
60         ){
61                 if (extern_info == NULL) return NULL;
62                 return new LOD_ExternBufferEditor(extern_info);
63         }
64         
65         // update the external vertex buffer with vertices
66         // from the mesh
67
68                 void
69         CopyModifiedVerts(
70                 LOD_ManMesh2 & mesh,
71                 const std::vector<LOD_VertexInd> & mod_vertices
72         ){
73         
74                 std::vector<LOD_VertexInd>::const_iterator v_start = mod_vertices.begin();
75                 std::vector<LOD_VertexInd>::const_iterator v_end = mod_vertices.end();
76
77                 std::vector<LOD_Vertex> & mesh_verts = mesh.VertexSet();
78
79                 float * const extern_vertex_ptr = m_extern_info->vertex_buffer;
80
81                 for (; v_start != v_end; ++v_start) {
82                         float * mod_vert = extern_vertex_ptr + int(*v_start)*3;
83                         mesh_verts[*v_start].CopyPosition(mod_vert);
84                 }
85         }                       
86                 
87         // update the external face buffer with faces from the mesh
88
89                 void
90         CopyModifiedFaces(
91                 LOD_ManMesh2 & mesh,
92                 const std::vector<LOD_FaceInd> & mod_faces
93         ){
94         
95                 std::vector<LOD_FaceInd>::const_iterator f_start = mod_faces.begin();
96                 std::vector<LOD_FaceInd>::const_iterator f_end = mod_faces.end();
97
98                 std::vector<LOD_TriFace> &mesh_faces = mesh.FaceSet();
99
100                 int * const extern_face_ptr = m_extern_info->triangle_index_buffer;
101
102                 for (; f_start != f_end; ++f_start) {
103                         int *mod_face = extern_face_ptr + 3*int(*f_start);
104                         mesh_faces[*f_start].CopyVerts(mod_face);
105                 }
106         }
107
108
109         // Copy the last vertex over the vertex specified by
110         // vi. Decrement the size of the vertex array   
111
112                 void
113         CopyBackVertex(
114                 LOD_VertexInd vi
115         ){
116
117                 float * const extern_vertex_ptr = m_extern_info->vertex_buffer;
118                 int * extern_vertex_num = &(m_extern_info->vertex_num);
119
120                 float * last_external_vert = extern_vertex_ptr + 3*((*extern_vertex_num) - 1);
121                 float * external_vert = extern_vertex_ptr + 3*int(vi);
122
123                 external_vert[0] = last_external_vert[0];
124                 external_vert[1] = last_external_vert[1];
125                 external_vert[2] = last_external_vert[2];
126
127                 *extern_vertex_num -=1;
128         }
129
130         // Copy the last face over the face specified by fi
131         // Decrement the size of the face array
132
133                 void
134         CopyBackFace(
135                 LOD_FaceInd fi
136         ) {
137                 int * const extern_face_ptr = m_extern_info->triangle_index_buffer;
138                 int * extern_face_num = &(m_extern_info->face_num);
139                 
140                 int * last_external_face = extern_face_ptr + 3*((*extern_face_num) -1);
141                 int * external_face = extern_face_ptr + 3*int(fi);
142                 external_face[0] = last_external_face[0];
143                 external_face[1] = last_external_face[1];
144                 external_face[2] = last_external_face[2];
145
146                 *extern_face_num -=1;
147         }       
148
149
150 private :
151                 
152         LOD_ExternBufferEditor(
153                 LOD_Decimation_InfoPtr extern_info      
154         ) :
155                 m_extern_info (extern_info)
156         {
157         }
158
159         LOD_Decimation_InfoPtr const m_extern_info;
160
161 };
162
163 #endif
164