LEFT | RIGHT |
1 /* | 1 /* |
2 * $Id$ | 2 * ***** BEGIN GPL LICENSE BLOCK ***** |
3 * | 3 * |
4 * ***** BEGIN GPL LICENSE BLOCK ***** | 4 * This program is free software; you can redistribute it and/or |
5 * | 5 * modify it under the terms of the GNU General Public License |
6 * This program is free software; you can redistribute it and/or | 6 * as published by the Free Software Foundation; either version 2 |
7 * modify it under the terms of the GNU General Public License | 7 * of the License, or (at your option) any later version. |
8 * as published by the Free Software Foundation; either version 2 | 8 * |
9 * of the License, or (at your option) any later version. | 9 * This program is distributed in the hope that it will be useful, |
10 * | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 * This program is distributed in the hope that it will be useful, | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 * GNU General Public License for more details. |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 * |
14 * GNU General Public License for more details. | 14 * You should have received a copy of the GNU General Public License |
15 * | 15 * along with this program; if not, write to the Free Software Foundation, |
16 * You should have received a copy of the GNU General Public License | 16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
17 * along with this program; if not, write to the Free Software Foundation, | 17 * |
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 18 * The Original Code is Copyright (C) 2006 Blender Foundation. |
19 * | 19 * All rights reserved. |
20 * The Original Code is Copyright (C) 2006 Blender Foundation. | 20 * |
21 * All rights reserved. | 21 * The Original Code is: all of this file. |
22 * | 22 * |
23 * The Original Code is: all of this file. | 23 * Contributor(s): Ben Batt <benbatt@gmail.com> |
24 * | 24 * |
25 * Contributor(s): Ben Batt <benbatt@gmail.com> | 25 * ***** END GPL LICENSE BLOCK ***** |
26 * | 26 * |
27 * ***** END GPL LICENSE BLOCK ***** | 27 * Implementation of CDDerivedMesh. |
28 * | 28 * |
29 * Implementation of CDDerivedMesh. | 29 * BKE_cdderivedmesh.h contains the function prototypes for this file. |
30 * | 30 * |
31 * BKE_cdderivedmesh.h contains the function prototypes for this file. | 31 */ |
32 * | |
33 */ | |
34 | 32 |
35 /** \file blender/blenkernel/intern/cdderivedmesh.c | 33 /** \file blender/blenkernel/intern/cdderivedmesh.c |
36 * \ingroup bke | 34 * \ingroup bke |
37 */ | 35 */ |
38 · | 36 |
39 | 37 #include "GL/glew.h" |
40 /* TODO maybe BIF_gl.h should include string.h? */ | 38 |
41 #include <string.h> | 39 #include "BLI_math.h" |
42 #include "BIF_gl.h" | |
43 | |
44 #include "BLI_blenlib.h" | 40 #include "BLI_blenlib.h" |
45 #include "BLI_edgehash.h" | 41 #include "BLI_edgehash.h" |
46 #include "BLI_editVert.h" | |
47 #include "BLI_math.h" | 42 #include "BLI_math.h" |
48 #include "BLI_pbvh.h" | 43 #include "BLI_smallhash.h" |
49 #include "BLI_utildefines.h" | 44 #include "BLI_utildefines.h" |
50 | 45 #include "BLI_scanfill.h" |
| 46 |
| 47 #include "BKE_pbvh.h" |
51 #include "BKE_cdderivedmesh.h" | 48 #include "BKE_cdderivedmesh.h" |
52 #include "BKE_global.h" | 49 #include "BKE_global.h" |
53 #include "BKE_mesh.h" | 50 #include "BKE_mesh.h" |
54 #include "BKE_paint.h" | 51 #include "BKE_paint.h" |
55 | 52 #include "BKE_editmesh.h" |
56 | 53 #include "BKE_curve.h" |
| 54 |
| 55 #include "DNA_mesh_types.h" |
57 #include "DNA_meshdata_types.h" | 56 #include "DNA_meshdata_types.h" |
58 #include "DNA_object_types.h" | 57 #include "DNA_object_types.h" |
59 #include "DNA_curve_types.h" /* for Curve */ | 58 #include "DNA_curve_types.h" /* for Curve */ |
60 | 59 |
61 #include "MEM_guardedalloc.h" | 60 #include "MEM_guardedalloc.h" |
62 | 61 |
63 #include "GPU_buffers.h" | 62 #include "GPU_buffers.h" |
64 #include "GPU_draw.h" | 63 #include "GPU_draw.h" |
65 #include "GPU_extensions.h" | 64 #include "GPU_extensions.h" |
66 #include "GPU_material.h" | 65 #include "GPU_material.h" |
67 | 66 |
68 #include <string.h> | 67 #include <string.h> |
69 #include <limits.h> | 68 #include <limits.h> |
70 #include <math.h> | 69 #include <math.h> |
71 | 70 |
| 71 extern GLubyte stipple_quarttone[128]; /* glutil.c, bad level data */ |
| 72 |
72 typedef struct { | 73 typedef struct { |
73 DerivedMesh dm; | 74 DerivedMesh dm; |
74 | 75 |
75 /* these point to data in the DerivedMesh custom data layers, | 76 /* these point to data in the DerivedMesh custom data layers, |
76 » they are only here for efficiency and convenience **/ | 77 » * they are only here for efficiency and convenience **/ |
77 MVert *mvert; | 78 MVert *mvert; |
78 MEdge *medge; | 79 MEdge *medge; |
79 MFace *mface; | 80 MFace *mface; |
| 81 MLoop *mloop; |
| 82 MPoly *mpoly; |
80 | 83 |
81 /* Cached */ | 84 /* Cached */ |
82 struct PBVH *pbvh; | 85 struct PBVH *pbvh; |
83 int pbvh_draw; | 86 int pbvh_draw; |
84 | 87 |
85 /* Mesh connectivity */ | 88 /* Mesh connectivity */ |
86 » struct ListBase *fmap; | 89 » MeshElemMap *pmap; |
87 » struct IndexNode *fmap_mem; | 90 » int *pmap_mem; |
88 } CDDerivedMesh; | 91 } CDDerivedMesh; |
89 | 92 |
90 /**************** DerivedMesh interface functions ****************/ | 93 /**************** DerivedMesh interface functions ****************/ |
91 static int cdDM_getNumVerts(DerivedMesh *dm) | 94 static int cdDM_getNumVerts(DerivedMesh *dm) |
92 { | 95 { |
93 return dm->numVertData; | 96 return dm->numVertData; |
94 } | 97 } |
95 | 98 |
96 static int cdDM_getNumEdges(DerivedMesh *dm) | 99 static int cdDM_getNumEdges(DerivedMesh *dm) |
97 { | 100 { |
98 return dm->numEdgeData; | 101 return dm->numEdgeData; |
99 } | 102 } |
100 | 103 |
101 static int cdDM_getNumFaces(DerivedMesh *dm) | 104 static int cdDM_getNumTessFaces(DerivedMesh *dm) |
102 { | 105 { |
103 » return dm->numFaceData; | 106 » /* uncomment and add a breakpoint on the printf() |
| 107 » * to help debug tessfaces issues since BMESH merge. */ |
| 108 #if 0 |
| 109 » if (dm->numTessFaceData == 0 && dm->numPolyData != 0) { |
| 110 » » printf("%s: has no faces!, call DM_ensure_tessface() if you need
them\n"); |
| 111 » } |
| 112 #endif |
| 113 » return dm->numTessFaceData; |
| 114 } |
| 115 |
| 116 static int cdDM_getNumLoops(DerivedMesh *dm) |
| 117 { |
| 118 » return dm->numLoopData; |
| 119 } |
| 120 |
| 121 static int cdDM_getNumPolys(DerivedMesh *dm) |
| 122 { |
| 123 » return dm->numPolyData; |
104 } | 124 } |
105 | 125 |
106 static void cdDM_getVert(DerivedMesh *dm, int index, MVert *vert_r) | 126 static void cdDM_getVert(DerivedMesh *dm, int index, MVert *vert_r) |
107 { | 127 { |
108 CDDerivedMesh *cddm = (CDDerivedMesh *)dm; | 128 CDDerivedMesh *cddm = (CDDerivedMesh *)dm; |
109 *vert_r = cddm->mvert[index]; | 129 *vert_r = cddm->mvert[index]; |
110 } | 130 } |
111 | 131 |
112 static void cdDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r) | 132 static void cdDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r) |
113 { | 133 { |
114 CDDerivedMesh *cddm = (CDDerivedMesh *)dm; | 134 CDDerivedMesh *cddm = (CDDerivedMesh *)dm; |
115 *edge_r = cddm->medge[index]; | 135 *edge_r = cddm->medge[index]; |
116 } | 136 } |
117 | 137 |
118 static void cdDM_getFace(DerivedMesh *dm, int index, MFace *face_r) | 138 static void cdDM_getTessFace(DerivedMesh *dm, int index, MFace *face_r) |
119 { | 139 { |
120 CDDerivedMesh *cddm = (CDDerivedMesh *)dm; | 140 CDDerivedMesh *cddm = (CDDerivedMesh *)dm; |
121 *face_r = cddm->mface[index]; | 141 *face_r = cddm->mface[index]; |
122 } | 142 } |
123 | 143 |
124 static void cdDM_copyVertArray(DerivedMesh *dm, MVert *vert_r) | 144 static void cdDM_copyVertArray(DerivedMesh *dm, MVert *vert_r) |
125 { | 145 { |
126 CDDerivedMesh *cddm = (CDDerivedMesh *)dm; | 146 CDDerivedMesh *cddm = (CDDerivedMesh *)dm; |
127 memcpy(vert_r, cddm->mvert, sizeof(*vert_r) * dm->numVertData); | 147 memcpy(vert_r, cddm->mvert, sizeof(*vert_r) * dm->numVertData); |
128 } | 148 } |
129 | 149 |
130 static void cdDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r) | 150 static void cdDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r) |
131 { | 151 { |
132 CDDerivedMesh *cddm = (CDDerivedMesh *)dm; | 152 CDDerivedMesh *cddm = (CDDerivedMesh *)dm; |
133 memcpy(edge_r, cddm->medge, sizeof(*edge_r) * dm->numEdgeData); | 153 memcpy(edge_r, cddm->medge, sizeof(*edge_r) * dm->numEdgeData); |
134 } | 154 } |
135 | 155 |
136 static void cdDM_copyFaceArray(DerivedMesh *dm, MFace *face_r) | 156 static void cdDM_copyTessFaceArray(DerivedMesh *dm, MFace *face_r) |
137 { | 157 { |
138 CDDerivedMesh *cddm = (CDDerivedMesh *)dm; | 158 CDDerivedMesh *cddm = (CDDerivedMesh *)dm; |
139 » memcpy(face_r, cddm->mface, sizeof(*face_r) * dm->numFaceData); | 159 » memcpy(face_r, cddm->mface, sizeof(*face_r) * dm->numTessFaceData); |
| 160 } |
| 161 |
| 162 static void cdDM_copyLoopArray(DerivedMesh *dm, MLoop *loop_r) |
| 163 { |
| 164 » CDDerivedMesh *cddm = (CDDerivedMesh *)dm; |
| 165 » memcpy(loop_r, cddm->mloop, sizeof(*loop_r) * dm->numLoopData); |
| 166 } |
| 167 |
| 168 static void cdDM_copyPolyArray(DerivedMesh *dm, MPoly *poly_r) |
| 169 { |
| 170 » CDDerivedMesh *cddm = (CDDerivedMesh *)dm; |
| 171 » memcpy(poly_r, cddm->mpoly, sizeof(*poly_r) * dm->numPolyData); |
140 } | 172 } |
141 | 173 |
142 static void cdDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) | 174 static void cdDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) |
143 { | 175 { |
144 » CDDerivedMesh *cddm = (CDDerivedMesh*) dm; | 176 » CDDerivedMesh *cddm = (CDDerivedMesh *) dm; |
145 int i; | 177 int i; |
146 | 178 |
147 if (dm->numVertData) { | 179 if (dm->numVertData) { |
148 » » for (i=0; i<dm->numVertData; i++) { | 180 » » for (i = 0; i < dm->numVertData; i++) { |
149 » » » DO_MINMAX(cddm->mvert[i].co, min_r, max_r); | 181 » » » minmax_v3v3_v3(min_r, max_r, cddm->mvert[i].co); |
150 » » } | 182 » » } |
151 » } else { | 183 » } |
152 » » min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2]
= 0.0; | 184 » else { |
| 185 » » zero_v3(min_r); |
| 186 » » zero_v3(max_r); |
153 } | 187 } |
154 } | 188 } |
155 | 189 |
156 static void cdDM_getVertCo(DerivedMesh *dm, int index, float co_r[3]) | 190 static void cdDM_getVertCo(DerivedMesh *dm, int index, float co_r[3]) |
157 { | 191 { |
158 » CDDerivedMesh *cddm = (CDDerivedMesh*) dm; | 192 » CDDerivedMesh *cddm = (CDDerivedMesh *) dm; |
159 | 193 |
160 » VECCOPY(co_r, cddm->mvert[index].co); | 194 » copy_v3_v3(co_r, cddm->mvert[index].co); |
161 } | 195 } |
162 | 196 |
163 static void cdDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3]) | 197 static void cdDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3]) |
164 { | 198 { |
165 MVert *mv = CDDM_get_verts(dm); | 199 MVert *mv = CDDM_get_verts(dm); |
166 int i; | 200 int i; |
167 | 201 |
168 » for(i = 0; i < dm->numVertData; i++, mv++) | 202 » for (i = 0; i < dm->numVertData; i++, mv++) |
169 » » VECCOPY(cos_r[i], mv->co); | 203 » » copy_v3_v3(cos_r[i], mv->co); |
170 } | 204 } |
171 | 205 |
172 static void cdDM_getVertNo(DerivedMesh *dm, int index, float no_r[3]) | 206 static void cdDM_getVertNo(DerivedMesh *dm, int index, float no_r[3]) |
173 { | 207 { |
174 » CDDerivedMesh *cddm = (CDDerivedMesh*) dm; | 208 » CDDerivedMesh *cddm = (CDDerivedMesh *) dm; |
175 » short *no = cddm->mvert[index].no; | 209 » normal_short_to_float_v3(no_r, cddm->mvert[index].no); |
176 | 210 } |
177 » no_r[0] = no[0]/32767.f; | 211 |
178 » no_r[1] = no[1]/32767.f; | 212 static const MeshElemMap *cdDM_getPolyMap(Object *ob, DerivedMesh *dm) |
179 » no_r[2] = no[2]/32767.f; | 213 { |
180 } | 214 » CDDerivedMesh *cddm = (CDDerivedMesh *) dm; |
181 | 215 |
182 static ListBase *cdDM_getFaceMap(Object *ob, DerivedMesh *dm) | 216 » if (!cddm->pmap && ob->type == OB_MESH) { |
183 { | 217 » » Mesh *me = ob->data; |
184 » CDDerivedMesh *cddm = (CDDerivedMesh*) dm; | 218 |
185 | 219 » » BKE_mesh_vert_poly_map_create(&cddm->pmap, &cddm->pmap_mem, |
186 » if(!cddm->fmap && ob->type == OB_MESH) { | 220 » » me->mpoly, me->mloop, |
187 » » Mesh *me= ob->data; | 221 » » me->totvert, me->totpoly, me->totloop); |
188 | 222 » } |
189 » » create_vert_face_map(&cddm->fmap, &cddm->fmap_mem, me->mface, | 223 |
190 » » » » » me->totvert, me->totface); | 224 » return cddm->pmap; |
191 » } | |
192 | |
193 » return cddm->fmap; | |
194 } | 225 } |
195 | 226 |
196 static int can_pbvh_draw(Object *ob, DerivedMesh *dm) | 227 static int can_pbvh_draw(Object *ob, DerivedMesh *dm) |
197 { | 228 { |
198 » CDDerivedMesh *cddm = (CDDerivedMesh*) dm; | 229 » CDDerivedMesh *cddm = (CDDerivedMesh *) dm; |
199 » Mesh *me= ob->data; | 230 » Mesh *me = ob->data; |
200 | 231 » int deformed = 0; |
201 » if(ob->sculpt->modifiers_active) return 0; | 232 |
202 | 233 » /* active modifiers means extra deformation, which can't be handled corr
ect |
203 » return (cddm->mvert == me->mvert) || ob->sculpt->kb; | 234 » * on birth of PBVH and sculpt "layer" levels, so use PBVH only for inte
rnal brush |
204 } | 235 » * stuff and show final DerivedMesh so user would see actual object shap
e */ |
205 | 236 » deformed |= ob->sculpt->modifiers_active; |
206 static struct PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm) | 237 |
207 { | 238 » /* as in case with modifiers, we can't synchronize deformation made agai
nst |
208 » CDDerivedMesh *cddm = (CDDerivedMesh*) dm; | 239 » * PBVH and non-locked keyblock, so also use PBVH only for brushes and |
209 | 240 » * final DM to give final result to user */ |
210 » if(!ob) { | 241 » deformed |= ob->sculpt->kb && (ob->shapeflag & OB_SHAPE_LOCK) == 0; |
211 » » cddm->pbvh= NULL; | 242 |
| 243 » if (deformed) |
| 244 » » return 0; |
| 245 |
| 246 » return cddm->mvert == me->mvert || ob->sculpt->kb; |
| 247 } |
| 248 |
| 249 static PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm) |
| 250 { |
| 251 » CDDerivedMesh *cddm = (CDDerivedMesh *) dm; |
| 252 |
| 253 » if (!ob) { |
| 254 » » cddm->pbvh = NULL; |
212 return NULL; | 255 return NULL; |
213 } | 256 } |
214 | 257 |
215 » if(!ob->sculpt) | 258 » if (!ob->sculpt) |
216 return NULL; | 259 return NULL; |
217 » if(ob->sculpt->pbvh) { | 260 |
218 » » cddm->pbvh= ob->sculpt->pbvh; | 261 » if (ob->sculpt->pbvh) { |
| 262 » » cddm->pbvh = ob->sculpt->pbvh; |
219 cddm->pbvh_draw = can_pbvh_draw(ob, dm); | 263 cddm->pbvh_draw = can_pbvh_draw(ob, dm); |
220 } | 264 } |
221 | 265 |
| 266 /* Sculpting on a BMesh (dynamic-topology) gets a special PBVH */ |
| 267 if (!cddm->pbvh && ob->sculpt->bm) { |
| 268 cddm->pbvh = BKE_pbvh_new(); |
| 269 cddm->pbvh_draw = TRUE; |
| 270 |
| 271 BKE_pbvh_build_bmesh(cddm->pbvh, ob->sculpt->bm, |
| 272 ob->sculpt->bm_smooth_shading, |
| 273 ob->sculpt->bm_log); |
| 274 } |
| 275 ················ |
| 276 |
222 /* always build pbvh from original mesh, and only use it for drawing if | 277 /* always build pbvh from original mesh, and only use it for drawing if |
223 » this derivedmesh is just original mesh. it's the multires subsurf dm | 278 » * this derivedmesh is just original mesh. it's the multires subsurf dm |
224 » that this is actually for, to support a pbvh on a modified mesh */ | 279 » * that this is actually for, to support a pbvh on a modified mesh */ |
225 » if(!cddm->pbvh && ob->type == OB_MESH) { | 280 » if (!cddm->pbvh && ob->type == OB_MESH) { |
226 » » Mesh *me= ob->data; | 281 » » SculptSession *ss = ob->sculpt; |
227 » » cddm->pbvh = BLI_pbvh_new(); | 282 » » Mesh *me = ob->data; |
| 283 » » int deformed = 0; |
| 284 |
| 285 » » cddm->pbvh = BKE_pbvh_new(); |
228 cddm->pbvh_draw = can_pbvh_draw(ob, dm); | 286 cddm->pbvh_draw = can_pbvh_draw(ob, dm); |
229 » » BLI_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert, | 287 |
230 » » » » me->totface, me->totvert); | 288 » » pbvh_show_diffuse_color_set(cddm->pbvh, ob->sculpt->show_diffuse
_color); |
231 | 289 |
232 » » if(ob->sculpt->modifiers_active) { | 290 » » BKE_mesh_tessface_ensure(me); |
| 291 » »······· |
| 292 » » BKE_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert, |
| 293 » » me->totface, me->totvert, &me->vdata); |
| 294 |
| 295 » » deformed = ss->modifiers_active || me->key; |
| 296 |
| 297 » » if (deformed && ob->derivedDeform) { |
| 298 » » » DerivedMesh *deformdm = ob->derivedDeform; |
233 float (*vertCos)[3]; | 299 float (*vertCos)[3]; |
234 int totvert; | 300 int totvert; |
235 | 301 |
236 » » » totvert= dm->getNumVerts(dm); | 302 » » » totvert = deformdm->getNumVerts(deformdm); |
237 » » » vertCos= MEM_callocN(3*totvert*sizeof(float), "cdDM_getP
BVH vertCos"); | 303 » » » vertCos = MEM_callocN(3 * totvert * sizeof(float), "cdDM
_getPBVH vertCos"); |
238 » » » dm->getVertCos(dm, vertCos); | 304 » » » deformdm->getVertCos(deformdm, vertCos); |
239 » » » BLI_pbvh_apply_vertCos(cddm->pbvh, vertCos); | 305 » » » BKE_pbvh_apply_vertCos(cddm->pbvh, vertCos); |
240 MEM_freeN(vertCos); | 306 MEM_freeN(vertCos); |
241 } | 307 } |
242 } | 308 } |
243 | 309 |
244 return cddm->pbvh; | 310 return cddm->pbvh; |
245 } | 311 } |
246 | 312 |
247 /* update vertex normals so that drawing smooth faces works during sculpt | 313 /* update vertex normals so that drawing smooth faces works during sculpt |
248 TODO: proper fix is to support the pbvh in all drawing modes */ | 314 * TODO: proper fix is to support the pbvh in all drawing modes */ |
249 static void cdDM_update_normals_from_pbvh(DerivedMesh *dm) | 315 static void cdDM_update_normals_from_pbvh(DerivedMesh *dm) |
250 { | 316 { |
251 » CDDerivedMesh *cddm = (CDDerivedMesh*) dm; | 317 » CDDerivedMesh *cddm = (CDDerivedMesh *) dm; |
252 float (*face_nors)[3]; | 318 float (*face_nors)[3]; |
253 | 319 |
254 » if(!cddm->pbvh || !cddm->pbvh_draw || !dm->numFaceData) | 320 » if (!cddm->pbvh || !cddm->pbvh_draw || !dm->numTessFaceData) |
255 return; | 321 return; |
256 | 322 |
257 face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL); | 323 face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL); |
258 | 324 |
259 » BLI_pbvh_update(cddm->pbvh, PBVH_UpdateNormals, face_nors); | 325 » BKE_pbvh_update(cddm->pbvh, PBVH_UpdateNormals, face_nors); |
260 } | 326 } |
261 | 327 |
262 static void cdDM_drawVerts(DerivedMesh *dm) | 328 static void cdDM_drawVerts(DerivedMesh *dm) |
263 { | 329 { |
264 » CDDerivedMesh *cddm = (CDDerivedMesh*) dm; | 330 » CDDerivedMesh *cddm = (CDDerivedMesh *) dm; |
265 MVert *mv = cddm->mvert; | 331 MVert *mv = cddm->mvert; |
266 int i; | 332 int i; |
267 | 333 |
268 » if( GPU_buffer_legacy(dm) ) { | 334 » if (GPU_buffer_legacy(dm)) { |
269 glBegin(GL_POINTS); | 335 glBegin(GL_POINTS); |
270 » » for(i = 0; i < dm->numVertData; i++, mv++) | 336 » » for (i = 0; i < dm->numVertData; i++, mv++) |
271 glVertex3fv(mv->co); | 337 glVertex3fv(mv->co); |
272 glEnd(); | 338 glEnd(); |
273 } | 339 } |
274 » else {» /* use OpenGL VBOs or Vertex Arrays instead for better, faster r
endering */ | 340 » else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster r
endering */ |
275 GPU_vertex_setup(dm); | 341 GPU_vertex_setup(dm); |
276 » » if( !GPU_buffer_legacy(dm) ) { | 342 » » if (!GPU_buffer_legacy(dm)) { |
277 » » » if(dm->drawObject->nelements)» glDrawArrays(GL_POINTS,0
, dm->drawObject->nelements); | 343 » » » if (dm->drawObject->tot_triangle_point) |
278 » » » else» » » » » » »
glDrawArrays(GL_POINTS,0, dm->drawObject->nlooseverts); | 344 » » » » glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_t
riangle_point); |
| 345 » » » else |
| 346 » » » » glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_l
oose_point); |
279 } | 347 } |
280 GPU_buffer_unbind(); | 348 GPU_buffer_unbind(); |
281 } | 349 } |
282 } | 350 } |
283 | 351 |
284 static void cdDM_drawUVEdges(DerivedMesh *dm) | 352 static void cdDM_drawUVEdges(DerivedMesh *dm) |
285 { | 353 { |
286 » CDDerivedMesh *cddm = (CDDerivedMesh*) dm; | 354 » CDDerivedMesh *cddm = (CDDerivedMesh *) dm; |
287 MFace *mf = cddm->mface; | 355 MFace *mf = cddm->mface; |
288 » MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE); | 356 » MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE); |
289 int i; | 357 int i; |
290 | 358 |
291 » if(mf) { | 359 » if (mf) { |
292 » » if( GPU_buffer_legacy(dm) ) { | 360 » » if (GPU_buffer_legacy(dm)) { |
293 glBegin(GL_LINES); | 361 glBegin(GL_LINES); |
294 » » » for(i = 0; i < dm->numFaceData; i++, mf++, tf++) { | 362 » » » for (i = 0; i < dm->numTessFaceData; i++, mf++, tf++) { |
295 » » » » if(!(mf->flag&ME_HIDE)) { | 363 » » » » if (!(mf->flag & ME_HIDE)) { |
296 glVertex2fv(tf->uv[0]); | 364 glVertex2fv(tf->uv[0]); |
297 glVertex2fv(tf->uv[1]); | 365 glVertex2fv(tf->uv[1]); |
298 | 366 |
299 glVertex2fv(tf->uv[1]); | 367 glVertex2fv(tf->uv[1]); |
300 glVertex2fv(tf->uv[2]); | 368 glVertex2fv(tf->uv[2]); |
301 | 369 |
302 » » » » » if(!mf->v4) { | 370 » » » » » if (!mf->v4) { |
303 glVertex2fv(tf->uv[2]); | 371 glVertex2fv(tf->uv[2]); |
304 glVertex2fv(tf->uv[0]); | 372 glVertex2fv(tf->uv[0]); |
305 » » » » » } else { | 373 » » » » » } |
| 374 » » » » » else { |
306 glVertex2fv(tf->uv[2]); | 375 glVertex2fv(tf->uv[2]); |
307 glVertex2fv(tf->uv[3]); | 376 glVertex2fv(tf->uv[3]); |
308 | 377 |
309 glVertex2fv(tf->uv[3]); | 378 glVertex2fv(tf->uv[3]); |
310 glVertex2fv(tf->uv[0]); | 379 glVertex2fv(tf->uv[0]); |
311 } | 380 } |
312 } | 381 } |
313 } | 382 } |
314 glEnd(); | 383 glEnd(); |
315 } | 384 } |
316 else { | 385 else { |
317 int prevstart = 0; | 386 int prevstart = 0; |
318 int prevdraw = 1; | 387 int prevdraw = 1; |
319 int draw = 1; | 388 int draw = 1; |
320 int curpos = 0; | 389 int curpos = 0; |
321 | 390 |
322 GPU_uvedge_setup(dm); | 391 GPU_uvedge_setup(dm); |
323 » » » if( !GPU_buffer_legacy(dm) ) { | 392 » » » if (!GPU_buffer_legacy(dm)) { |
324 » » » » for(i = 0; i < dm->numFaceData; i++, mf++) { | 393 » » » » for (i = 0; i < dm->numTessFaceData; i++, mf++)
{ |
325 » » » » » if(!(mf->flag&ME_HIDE)) { | 394 » » » » » if (!(mf->flag & ME_HIDE)) { |
326 draw = 1; | 395 draw = 1; |
327 » » » » » } | 396 » » » » » } |
328 else { | 397 else { |
329 draw = 0; | 398 draw = 0; |
330 } | 399 } |
331 » » » » » if( prevdraw != draw ) { | 400 » » » » » if (prevdraw != draw) { |
332 » » » » » » if( prevdraw > 0 && (curpos-prev
start) > 0) { | 401 » » » » » » if (prevdraw > 0 && (curpos - pr
evstart) > 0) { |
333 » » » » » » » glDrawArrays(GL_LINES,pr
evstart,curpos-prevstart); | 402 » » » » » » » glDrawArrays(GL_LINES, p
revstart, curpos - prevstart); |
334 } | 403 } |
335 prevstart = curpos; | 404 prevstart = curpos; |
336 } | 405 } |
337 » » » » » if( mf->v4 ) { | 406 » » » » » if (mf->v4) { |
338 curpos += 8; | 407 curpos += 8; |
339 } | 408 } |
340 else { | 409 else { |
341 curpos += 6; | 410 curpos += 6; |
342 } | 411 } |
343 prevdraw = draw; | 412 prevdraw = draw; |
344 } | 413 } |
345 » » » » if( prevdraw > 0 && (curpos-prevstart) > 0 ) { | 414 » » » » if (prevdraw > 0 && (curpos - prevstart) > 0) { |
346 » » » » » glDrawArrays(GL_LINES,prevstart,curpos-p
revstart); | 415 » » » » » glDrawArrays(GL_LINES, prevstart, curpos
- prevstart); |
347 } | 416 } |
348 } | 417 } |
349 GPU_buffer_unbind(); | 418 GPU_buffer_unbind(); |
350 } | 419 } |
351 } | 420 } |
352 } | 421 } |
353 | 422 |
354 static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges
) | 423 static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges
) |
355 { | 424 { |
356 » CDDerivedMesh *cddm = (CDDerivedMesh*) dm; | 425 » CDDerivedMesh *cddm = (CDDerivedMesh *) dm; |
357 MVert *mvert = cddm->mvert; | 426 MVert *mvert = cddm->mvert; |
358 MEdge *medge = cddm->medge; | 427 MEdge *medge = cddm->medge; |
359 int i; | 428 int i; |
| 429 |
| 430 if (cddm->pbvh && cddm->pbvh_draw && |
| 431 BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH) |
| 432 { |
| 433 BKE_pbvh_draw(cddm->pbvh, NULL, NULL, NULL, TRUE); |
| 434 |
| 435 return; |
| 436 } |
360 ········ | 437 ········ |
361 » if( GPU_buffer_legacy(dm) ) { | 438 » if (GPU_buffer_legacy(dm)) { |
362 » » DEBUG_VBO( "Using legacy code. cdDM_drawEdges\n" ); | 439 » » DEBUG_VBO("Using legacy code. cdDM_drawEdges\n"); |
363 glBegin(GL_LINES); | 440 glBegin(GL_LINES); |
364 » » for(i = 0; i < dm->numEdgeData; i++, medge++) { | 441 » » for (i = 0; i < dm->numEdgeData; i++, medge++) { |
365 » » » if((drawAllEdges || (medge->flag&ME_EDGEDRAW)) | 442 » » » if ((drawAllEdges || (medge->flag & ME_EDGEDRAW)) && |
366 » » » && (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) { | 443 » » » (drawLooseEdges || !(medge->flag & ME_LOOSEEDGE))) |
| 444 » » » { |
367 glVertex3fv(mvert[medge->v1].co); | 445 glVertex3fv(mvert[medge->v1].co); |
368 glVertex3fv(mvert[medge->v2].co); | 446 glVertex3fv(mvert[medge->v2].co); |
369 } | 447 } |
370 } | 448 } |
371 glEnd(); | 449 glEnd(); |
372 } | 450 } |
373 » else {» /* use OpenGL VBOs or Vertex Arrays instead for better, faster r
endering */ | 451 » else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster r
endering */ |
| 452 » » int prevstart = 0; |
| 453 » » int prevdraw = 1; |
| 454 » » int draw = TRUE; |
| 455 |
| 456 » » GPU_edge_setup(dm); |
| 457 » » if (!GPU_buffer_legacy(dm)) { |
| 458 » » » for (i = 0; i < dm->numEdgeData; i++, medge++) { |
| 459 » » » » if ((drawAllEdges || (medge->flag & ME_EDGEDRAW)
) && |
| 460 » » » » (drawLooseEdges || !(medge->flag & ME_LOOSEE
DGE))) |
| 461 » » » » { |
| 462 » » » » » draw = TRUE; |
| 463 » » » » } |
| 464 » » » » else { |
| 465 » » » » » draw = FALSE; |
| 466 » » » » } |
| 467 » » » » if (prevdraw != draw) { |
| 468 » » » » » if (prevdraw > 0 && (i - prevstart) > 0)
{ |
| 469 » » » » » » GPU_buffer_draw_elements(dm->dra
wObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2); |
| 470 » » » » » } |
| 471 » » » » » prevstart = i; |
| 472 » » » » } |
| 473 » » » » prevdraw = draw; |
| 474 » » » } |
| 475 » » » if (prevdraw > 0 && (i - prevstart) > 0) { |
| 476 » » » » GPU_buffer_draw_elements(dm->drawObject->edges,
GL_LINES, prevstart * 2, (i - prevstart) * 2); |
| 477 » » » } |
| 478 » » } |
| 479 » » GPU_buffer_unbind(); |
| 480 » } |
| 481 } |
| 482 |
| 483 static void cdDM_drawLooseEdges(DerivedMesh *dm) |
| 484 { |
| 485 » CDDerivedMesh *cddm = (CDDerivedMesh *) dm; |
| 486 » MVert *mvert = cddm->mvert; |
| 487 » MEdge *medge = cddm->medge; |
| 488 » int i; |
| 489 |
| 490 » if (GPU_buffer_legacy(dm)) { |
| 491 » » DEBUG_VBO("Using legacy code. cdDM_drawLooseEdges\n"); |
| 492 » » glBegin(GL_LINES); |
| 493 » » for (i = 0; i < dm->numEdgeData; i++, medge++) { |
| 494 » » » if (medge->flag & ME_LOOSEEDGE) { |
| 495 » » » » glVertex3fv(mvert[medge->v1].co); |
| 496 » » » » glVertex3fv(mvert[medge->v2].co); |
| 497 » » » } |
| 498 » » } |
| 499 » » glEnd(); |
| 500 » } |
| 501 » else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster r
endering */ |
374 int prevstart = 0; | 502 int prevstart = 0; |
375 int prevdraw = 1; | 503 int prevdraw = 1; |
376 int draw = 1; | 504 int draw = 1; |
377 | 505 |
378 GPU_edge_setup(dm); | 506 GPU_edge_setup(dm); |
379 » » if( !GPU_buffer_legacy(dm) ) { | 507 » » if (!GPU_buffer_legacy(dm)) { |
380 » » » for(i = 0; i < dm->numEdgeData; i++, medge++) { | 508 » » » for (i = 0; i < dm->numEdgeData; i++, medge++) { |
381 » » » » if((drawAllEdges || (medge->flag&ME_EDGEDRAW)) | 509 » » » » if (medge->flag & ME_LOOSEEDGE) { |
382 » » » » && (drawLooseEdges || !(medge->flag&ME_LOOSEE
DGE))) { | |
383 draw = 1; | 510 draw = 1; |
384 » » » » } | 511 » » » » } |
385 else { | 512 else { |
386 draw = 0; | 513 draw = 0; |
387 } | 514 } |
388 » » » » if( prevdraw != draw ) { | 515 » » » » if (prevdraw != draw) { |
389 » » » » » if( prevdraw > 0 && (i-prevstart) > 0 )
{ | 516 » » » » » if (prevdraw > 0 && (i - prevstart) > 0)
{ |
390 » » » » » » GPU_buffer_draw_elements( dm->dr
awObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2 ); | 517 » » » » » » GPU_buffer_draw_elements(dm->dra
wObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2); |
391 } | 518 } |
392 prevstart = i; | 519 prevstart = i; |
393 } | 520 } |
394 prevdraw = draw; | 521 prevdraw = draw; |
395 } | 522 } |
396 » » » if( prevdraw > 0 && (i-prevstart) > 0 ) { | 523 » » » if (prevdraw > 0 && (i - prevstart) > 0) { |
397 » » » » GPU_buffer_draw_elements( dm->drawObject->edges,
GL_LINES, prevstart*2, (i-prevstart)*2 ); | 524 » » » » GPU_buffer_draw_elements(dm->drawObject->edges,
GL_LINES, prevstart * 2, (i - prevstart) * 2); |
398 } | 525 } |
399 } | 526 } |
400 GPU_buffer_unbind(); | 527 GPU_buffer_unbind(); |
401 } | 528 } |
402 } | 529 } |
403 | 530 |
404 static void cdDM_drawLooseEdges(DerivedMesh *dm) | |
405 { | |
406 CDDerivedMesh *cddm = (CDDerivedMesh*) dm; | |
407 MVert *mvert = cddm->mvert; | |
408 MEdge *medge = cddm->medge; | |
409 int i; | |
410 | |
411 if( GPU_buffer_legacy(dm) ) { | |
412 DEBUG_VBO( "Using legacy code. cdDM_drawLooseEdges\n" ); | |
413 glBegin(GL_LINES); | |
414 for(i = 0; i < dm->numEdgeData; i++, medge++) { | |
415 if(medge->flag&ME_LOOSEEDGE) { | |
416 glVertex3fv(mvert[medge->v1].co); | |
417 glVertex3fv(mvert[medge->v2].co); | |
418 } | |
419 } | |
420 glEnd(); | |
421 } | |
422 else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster r
endering */ | |
423 int prevstart = 0; | |
424 int prevdraw = 1; | |
425 int draw = 1; | |
426 | |
427 GPU_edge_setup(dm); | |
428 if( !GPU_buffer_legacy(dm) ) { | |
429 for(i = 0; i < dm->numEdgeData; i++, medge++) { | |
430 if(medge->flag&ME_LOOSEEDGE) { | |
431 draw = 1; | |
432 }· | |
433 else { | |
434 draw = 0; | |
435 } | |
436 if( prevdraw != draw ) { | |
437 if( prevdraw > 0 && (i-prevstart) > 0) { | |
438 GPU_buffer_draw_elements( dm->dr
awObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2 ); | |
439 } | |
440 prevstart = i; | |
441 } | |
442 prevdraw = draw; | |
443 } | |
444 if( prevdraw > 0 && (i-prevstart) > 0 ) { | |
445 GPU_buffer_draw_elements( dm->drawObject->edges,
GL_LINES, prevstart*2, (i-prevstart)*2 ); | |
446 } | |
447 } | |
448 GPU_buffer_unbind(); | |
449 } | |
450 } | |
451 | |
452 static void cdDM_drawFacesSolid(DerivedMesh *dm, | 531 static void cdDM_drawFacesSolid(DerivedMesh *dm, |
453 » » » » float (*partial_redraw_planes)[4], | 532 float (*partial_redraw_planes)[4], |
454 » » » » int UNUSED(fast), int (*setMaterial)(int, void *
attribs)) | 533 int UNUSED(fast), DMSetMaterial setMaterial) |
455 { | 534 { |
456 » CDDerivedMesh *cddm = (CDDerivedMesh*) dm; | 535 » CDDerivedMesh *cddm = (CDDerivedMesh *) dm; |
457 MVert *mvert = cddm->mvert; | 536 MVert *mvert = cddm->mvert; |
458 MFace *mface = cddm->mface; | 537 MFace *mface = cddm->mface; |
459 » float *nors= dm->getFaceDataArray(dm, CD_NORMAL); | 538 » float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL); |
460 int a, glmode = -1, shademodel = -1, matnr = -1, drawCurrentMat = 1; | 539 int a, glmode = -1, shademodel = -1, matnr = -1, drawCurrentMat = 1; |
461 | 540 |
462 #define PASSVERT(index) { \ | 541 #define PASSVERT(index) { \ |
463 » if(shademodel == GL_SMOOTH) {» » » » \ | 542 » if (shademodel == GL_SMOOTH) {» » » » \ |
464 short *no = mvert[index].no; \ | 543 short *no = mvert[index].no; \ |
465 glNormal3sv(no);
\ | 544 glNormal3sv(no);
\ |
466 }
\ | 545 }
\ |
467 » glVertex3fv(mvert[index].co);» \ | 546 » glVertex3fv(mvert[index].co);» » » » \ |
468 } | 547 } (void)0 |
469 | 548 |
470 » if(cddm->pbvh && cddm->pbvh_draw) { | 549 » if (cddm->pbvh && cddm->pbvh_draw) { |
471 » » if(dm->numFaceData) { | 550 » » if (dm->numTessFaceData) { |
472 float (*face_nors)[3] = CustomData_get_layer(&dm->faceDa
ta, CD_NORMAL); | 551 float (*face_nors)[3] = CustomData_get_layer(&dm->faceDa
ta, CD_NORMAL); |
473 | 552 |
474 » » » /* should be per face */ | 553 » » » BKE_pbvh_draw(cddm->pbvh, partial_redraw_planes, face_no
rs, |
475 » » » if(!setMaterial(mface->mat_nr+1, NULL)) | 554 » » » setMaterial, FALSE); |
476 » » » » return; | |
477 | |
478 » » » glShadeModel((mface->flag & ME_SMOOTH)? GL_SMOOTH: GL_FL
AT); | |
479 » » » BLI_pbvh_draw(cddm->pbvh, partial_redraw_planes, face_no
rs, (mface->flag & ME_SMOOTH)); | |
480 glShadeModel(GL_FLAT); | 555 glShadeModel(GL_FLAT); |
481 } | 556 } |
482 | 557 |
483 return; | 558 return; |
484 } | 559 } |
485 | 560 |
486 » if( GPU_buffer_legacy(dm) ) { | 561 » if (GPU_buffer_legacy(dm)) { |
487 » » DEBUG_VBO( "Using legacy code. cdDM_drawFacesSolid\n" ); | 562 » » DEBUG_VBO("Using legacy code. cdDM_drawFacesSolid\n"); |
488 glBegin(glmode = GL_QUADS); | 563 glBegin(glmode = GL_QUADS); |
489 » » for(a = 0; a < dm->numFaceData; a++, mface++) { | 564 » » for (a = 0; a < dm->numTessFaceData; a++, mface++) { |
490 int new_glmode, new_matnr, new_shademodel; | 565 int new_glmode, new_matnr, new_shademodel; |
491 | 566 |
492 » » » new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES; | 567 » » » new_glmode = mface->v4 ? GL_QUADS : GL_TRIANGLES; |
493 new_matnr = mface->mat_nr + 1; | 568 new_matnr = mface->mat_nr + 1; |
494 » » » new_shademodel = (mface->flag & ME_SMOOTH)?GL_SMOOTH:GL_
FLAT; | 569 » » » new_shademodel = (mface->flag & ME_SMOOTH) ? GL_SMOOTH :
GL_FLAT; |
495 ························ | 570 ························ |
496 » » » if(new_glmode != glmode || new_matnr != matnr | 571 » » » if (new_glmode != glmode || new_matnr != matnr || new_sh
ademodel != shademodel) { |
497 » » » || new_shademodel != shademodel) { | |
498 glEnd(); | 572 glEnd(); |
499 | 573 |
500 drawCurrentMat = setMaterial(matnr = new_matnr,
NULL); | 574 drawCurrentMat = setMaterial(matnr = new_matnr,
NULL); |
501 | 575 |
502 glShadeModel(shademodel = new_shademodel); | 576 glShadeModel(shademodel = new_shademodel); |
503 glBegin(glmode = new_glmode); | 577 glBegin(glmode = new_glmode); |
504 » » » } | 578 » » » } |
505 ························ | 579 ························ |
506 » » » if(drawCurrentMat) { | 580 » » » if (drawCurrentMat) { |
507 » » » » if(shademodel == GL_FLAT) { | 581 » » » » if (shademodel == GL_FLAT) { |
508 if (nors) { | 582 if (nors) { |
509 glNormal3fv(nors); | 583 glNormal3fv(nors); |
510 } | 584 } |
511 else { | 585 else { |
512 /* TODO make this better (cache
facenormals as layer?) */ | 586 /* TODO make this better (cache
facenormals as layer?) */ |
513 float nor[3]; | 587 float nor[3]; |
514 » » » » » » if(mface->v4) { | 588 » » » » » » if (mface->v4) { |
515 » » » » » » » normal_quad_v3( nor,mver
t[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co); | 589 » » » » » » » normal_quad_v3(nor, mver
t[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co); |
516 » » » » » » } else { | 590 » » » » » » } |
517 » » » » » » » normal_tri_v3( nor,mvert
[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co); | 591 » » » » » » else { |
| 592 » » » » » » » normal_tri_v3(nor, mvert
[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co); |
518 } | 593 } |
519 glNormal3fv(nor); | 594 glNormal3fv(nor); |
520 } | 595 } |
521 } | 596 } |
522 | 597 |
523 PASSVERT(mface->v1); | 598 PASSVERT(mface->v1); |
524 PASSVERT(mface->v2); | 599 PASSVERT(mface->v2); |
525 PASSVERT(mface->v3); | 600 PASSVERT(mface->v3); |
526 » » » » if(mface->v4) { | 601 » » » » if (mface->v4) { |
527 PASSVERT(mface->v4); | 602 PASSVERT(mface->v4); |
528 } | 603 } |
529 } | 604 } |
530 | 605 |
531 » » » if(nors) nors += 3; | 606 » » » if (nors) nors += 3; |
532 } | 607 } |
533 glEnd(); | 608 glEnd(); |
534 } | 609 } |
535 » else {» /* use OpenGL VBOs or Vertex Arrays instead for better, faster r
endering */ | 610 » else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster r
endering */ |
536 » » GPU_vertex_setup( dm ); | 611 » » GPU_vertex_setup(dm); |
537 » » GPU_normal_setup( dm ); | 612 » » GPU_normal_setup(dm); |
538 » » if( !GPU_buffer_legacy(dm) ) { | 613 » » if (!GPU_buffer_legacy(dm)) { |
539 glShadeModel(GL_SMOOTH); | 614 glShadeModel(GL_SMOOTH); |
540 » » » for( a = 0; a < dm->drawObject->nmaterials; a++ ) { | 615 » » » for (a = 0; a < dm->drawObject->totmaterial; a++) { |
541 » » » » if( setMaterial(dm->drawObject->materials[a].mat
_nr+1, NULL) ) | 616 » » » » if (setMaterial(dm->drawObject->materials[a].mat
_nr + 1, NULL)) { |
542 » » » » » glDrawArrays(GL_TRIANGLES, dm->drawObjec
t->materials[a].start, dm->drawObject->materials[a].end-dm->drawObject->material
s[a].start); | 617 » » » » » glDrawArrays(GL_TRIANGLES, dm->drawObjec
t->materials[a].start, |
543 » » » } | 618 » » » » » dm->drawObject->materials[a
].totpoint); |
544 » » } | 619 » » » » } |
545 » » GPU_buffer_unbind( ); | 620 » » » } |
| 621 » » } |
| 622 » » GPU_buffer_unbind(); |
546 } | 623 } |
547 | 624 |
548 #undef PASSVERT | 625 #undef PASSVERT |
549 glShadeModel(GL_FLAT); | 626 glShadeModel(GL_FLAT); |
550 } | 627 } |
551 | 628 |
552 static void cdDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned cha
r *col1, unsigned char *col2) | 629 static void cdDM_drawFacesTex_common(DerivedMesh *dm, |
553 { | 630 DMSetDrawOptionsTex drawParams, |
554 » CDDerivedMesh *cddm = (CDDerivedMesh*) dm; | 631 DMSetDrawOptions drawParamsMapped, |
555 » int a, glmode; | 632 DMCompareDrawOptions compareDrawOptions, |
556 » unsigned char *cp1, *cp2; | 633 void *userData) |
557 » MVert *mvert = cddm->mvert; | 634 { |
558 » MFace *mface = cddm->mface; | 635 » CDDerivedMesh *cddm = (CDDerivedMesh *) dm; |
559 | 636 » MVert *mv = cddm->mvert; |
560 » cp1 = col1; | 637 » MFace *mf = DM_get_tessface_data_layer(dm, CD_MFACE); |
561 » if(col2) { | 638 » float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL); |
562 » » cp2 = col2; | 639 » MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE); |
563 » } else { | 640 » MCol *mcol; |
564 » » cp2 = NULL; | 641 » int i, orig; |
565 » » useTwoSided = 0; | 642 » int colType, startFace = 0; |
566 » } | 643 |
567 | 644 » /* double lookup */ |
568 » /* there's a conflict here... twosided colors versus culling...? */ | 645 » const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX
); |
569 » /* defined by history, only texture faces have culling option */ | 646 » const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); |
570 » /* we need that as mesh option builtin, next to double sided lighting */ | 647 » if (index_mf_to_mpoly == NULL) { |
571 » if(col1 && col2) | 648 » » index_mp_to_orig = NULL; |
572 » » glEnable(GL_CULL_FACE); | 649 » } |
| 650 |
| 651 » /* TODO: not entirely correct, but currently dynamic topology will |
| 652 » * destroy UVs anyway, so textured display wouldn't work anyway |
| 653 » * |
| 654 » * this will do more like solid view with lights set up for |
| 655 » * textured view, but object itself will be displayed gray |
| 656 » * (the same as it'll display without UV maps in textured view) |
| 657 » */ |
| 658 » if (cddm->pbvh && cddm->pbvh_draw && BKE_pbvh_type(cddm->pbvh) == PBVH_B
MESH) { |
| 659 » » if (dm->numTessFaceData) { |
| 660 » » » GPU_set_tpage(NULL, false, false); |
| 661 » » » BKE_pbvh_draw(cddm->pbvh, NULL, NULL, NULL, FALSE); |
| 662 » » } |
| 663 |
| 664 » » return; |
| 665 » } |
| 666 |
| 667 » colType = CD_TEXTURE_MCOL; |
| 668 » mcol = dm->getTessFaceDataArray(dm, colType); |
| 669 » if (!mcol) { |
| 670 » » colType = CD_PREVIEW_MCOL; |
| 671 » » mcol = dm->getTessFaceDataArray(dm, colType); |
| 672 » } |
| 673 » if (!mcol) { |
| 674 » » colType = CD_MCOL; |
| 675 » » mcol = dm->getTessFaceDataArray(dm, colType); |
| 676 » } |
573 | 677 |
574 cdDM_update_normals_from_pbvh(dm); | 678 cdDM_update_normals_from_pbvh(dm); |
575 | 679 |
576 » if( GPU_buffer_legacy(dm) ) { | 680 » if (GPU_buffer_legacy(dm)) { |
577 » » DEBUG_VBO( "Using legacy code. cdDM_drawFacesColored\n" ); | 681 » » DEBUG_VBO("Using legacy code. cdDM_drawFacesTex_common\n"); |
578 » » glShadeModel(GL_SMOOTH); | 682 » » for (i = 0; i < dm->numTessFaceData; i++, mf++) { |
579 » » glBegin(glmode = GL_QUADS); | |
580 » » for(a = 0; a < dm->numFaceData; a++, mface++, cp1 += 16) { | |
581 » » » int new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES; | |
582 | |
583 » » » if(new_glmode != glmode) { | |
584 » » » » glEnd(); | |
585 » » » » glBegin(glmode = new_glmode); | |
586 » » » } | |
587 » » » »······· | |
588 » » » glColor3ub(cp1[0], cp1[1], cp1[2]); | |
589 » » » glVertex3fv(mvert[mface->v1].co); | |
590 » » » glColor3ub(cp1[4], cp1[5], cp1[6]); | |
591 » » » glVertex3fv(mvert[mface->v2].co); | |
592 » » » glColor3ub(cp1[8], cp1[9], cp1[10]); | |
593 » » » glVertex3fv(mvert[mface->v3].co); | |
594 » » » if(mface->v4) { | |
595 » » » » glColor3ub(cp1[12], cp1[13], cp1[14]); | |
596 » » » » glVertex3fv(mvert[mface->v4].co); | |
597 » » » } | |
598 » » » »······· | |
599 » » » if(useTwoSided) { | |
600 » » » » glColor3ub(cp2[8], cp2[9], cp2[10]); | |
601 » » » » glVertex3fv(mvert[mface->v3].co ); | |
602 » » » » glColor3ub(cp2[4], cp2[5], cp2[6]); | |
603 » » » » glVertex3fv(mvert[mface->v2].co ); | |
604 » » » » glColor3ub(cp2[0], cp2[1], cp2[2]); | |
605 » » » » glVertex3fv(mvert[mface->v1].co ); | |
606 » » » » if(mface->v4) { | |
607 » » » » » glColor3ub(cp2[12], cp2[13], cp2[14]); | |
608 » » » » » glVertex3fv(mvert[mface->v4].co ); | |
609 » » » » } | |
610 » » » } | |
611 » » » if(col2) cp2 += 16; | |
612 » » } | |
613 » » glEnd(); | |
614 » } | |
615 » else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster re
ndering */ | |
616 » » GPU_color4_upload(dm,cp1); | |
617 » » GPU_vertex_setup(dm); | |
618 » » GPU_color_setup(dm); | |
619 » » if( !GPU_buffer_legacy(dm) ) { | |
620 » » » glShadeModel(GL_SMOOTH); | |
621 » » » glDrawArrays(GL_TRIANGLES, 0, dm->drawObject->nelements)
; | |
622 | |
623 » » » if( useTwoSided ) { | |
624 » » » » GPU_color4_upload(dm,cp2); | |
625 » » » » GPU_color_setup(dm); | |
626 » » » » glCullFace(GL_FRONT); | |
627 » » » » glDrawArrays(GL_TRIANGLES, 0, dm->drawObject->ne
lements); | |
628 » » » » glCullFace(GL_BACK); | |
629 » » » } | |
630 » » } | |
631 » » GPU_buffer_unbind(); | |
632 » } | |
633 | |
634 » glShadeModel(GL_FLAT); | |
635 » glDisable(GL_CULL_FACE); | |
636 } | |
637 | |
638 static void cdDM_drawFacesTex_common(DerivedMesh *dm, | |
639 » » » int (*drawParams)(MTFace *tface, MCol *mcol, int matn
r), | |
640 » » » int (*drawParamsMapped)(void *userData, int index), | |
641 » » » void *userData)· | |
642 { | |
643 » CDDerivedMesh *cddm = (CDDerivedMesh*) dm; | |
644 » MVert *mv = cddm->mvert; | |
645 » MFace *mf = DM_get_face_data_layer(dm, CD_MFACE); | |
646 » MCol *realcol = dm->getFaceDataArray(dm, CD_TEXTURE_MCOL); | |
647 » float *nors= dm->getFaceDataArray(dm, CD_NORMAL); | |
648 » MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE); | |
649 » int i, j, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX); | |
650 » int startFace = 0, lastFlag = 0xdeadbeef; | |
651 » MCol *mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL); | |
652 » if(!mcol) | |
653 » » mcol = dm->getFaceDataArray(dm, CD_MCOL); | |
654 | |
655 » cdDM_update_normals_from_pbvh(dm); | |
656 | |
657 » if( GPU_buffer_legacy(dm) ) { | |
658 » » DEBUG_VBO( "Using legacy code. cdDM_drawFacesTex_common\n" ); | |
659 » » for(i = 0; i < dm->numFaceData; i++, mf++) { | |
660 MVert *mvert; | 683 MVert *mvert; |
661 » » » int flag; | 684 » » » DMDrawOption draw_option; |
662 unsigned char *cp = NULL; | 685 unsigned char *cp = NULL; |
663 | 686 |
664 » » » if(drawParams) { | 687 » » » if (drawParams) { |
665 » » » » flag = drawParams(tf? &tf[i]: NULL, mcol? &mcol[
i*4]: NULL, mf->mat_nr); | 688 » » » » draw_option = drawParams(tf ? &tf[i] : NULL, (mc
ol != NULL), mf->mat_nr); |
666 } | 689 } |
667 else { | 690 else { |
668 » » » » if(index) { | 691 » » » » if (index_mf_to_mpoly) { |
669 » » » » » orig = *index++; | 692 » » » » » orig = DM_origindex_mface_mpoly(index_mf
_to_mpoly, index_mp_to_orig, i); |
670 » » » » » if(orig == ORIGINDEX_NONE)» »
{ if(nors) nors += 3; continue; } | 693 » » » » » if (orig == ORIGINDEX_NONE) { |
671 » » » » » if(drawParamsMapped) flag = drawParamsMa
pped(userData, orig); | 694 » » » » » » /* XXX, this is not really corre
ct |
672 » » » » » else» { if(nors) nors += 3; continue;
} | 695 » » » » » » * it will draw the previous fac
es context for this one when we don't know its settings. |
673 » » » » } | 696 » » » » » » * but better then skipping it a
ltogether. - campbell */ |
674 » » » » else | 697 » » » » » » draw_option = DM_DRAW_OPTION_NOR
MAL; |
675 » » » » » if(drawParamsMapped) flag = drawParamsMa
pped(userData, i); | 698 » » » » » } |
676 » » » » » else» { if(nors) nors += 3; continue;
} | 699 » » » » » else if (drawParamsMapped) { |
| 700 » » » » » » draw_option = drawParamsMapped(u
serData, orig); |
| 701 » » » » » } |
| 702 » » » » » else { |
| 703 » » » » » » if (nors) { |
| 704 » » » » » » » nors += 3; |
| 705 » » » » » » } |
| 706 » » » » » » continue; |
| 707 » » » » » } |
| 708 » » » » } |
| 709 » » » » else if (drawParamsMapped) { |
| 710 » » » » » draw_option = drawParamsMapped(userData,
i); |
| 711 » » » » } |
| 712 » » » » else { |
| 713 » » » » » if (nors) { |
| 714 » » » » » » nors += 3; |
| 715 » » » » » } |
| 716 » » » » » continue; |
| 717 » » » » } |
677 } | 718 } |
678 ························ | 719 ························ |
679 » » » if(flag != 0) { | 720 » » » if (draw_option != DM_DRAW_OPTION_SKIP) { |
680 » » » » if (flag==1 && mcol) | 721 » » » » if (draw_option != DM_DRAW_OPTION_NO_MCOL && mco
l) |
681 » » » » » cp= (unsigned char*) &mcol[i*4]; | 722 » » » » » cp = (unsigned char *) &mcol[i * 4]; |
682 | 723 |
683 » » » » if(!(mf->flag&ME_SMOOTH)) { | 724 » » » » if (!(mf->flag & ME_SMOOTH)) { |
684 if (nors) { | 725 if (nors) { |
685 glNormal3fv(nors); | 726 glNormal3fv(nors); |
686 } | 727 } |
687 else { | 728 else { |
688 float nor[3]; | 729 float nor[3]; |
689 » » » » » » if(mf->v4) { | 730 » » » » » » if (mf->v4) { |
690 » » » » » » » normal_quad_v3( nor,mv[m
f->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co); | 731 » » » » » » » normal_quad_v3(nor, mv[m
f->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co); |
691 » » » » » » } else { | 732 » » » » » » } |
692 » » » » » » » normal_tri_v3( nor,mv[mf
->v1].co, mv[mf->v2].co, mv[mf->v3].co); | 733 » » » » » » else { |
| 734 » » » » » » » normal_tri_v3(nor, mv[mf
->v1].co, mv[mf->v2].co, mv[mf->v3].co); |
693 } | 735 } |
694 glNormal3fv(nor); | 736 glNormal3fv(nor); |
695 } | 737 } |
696 } | 738 } |
697 | 739 |
698 » » » » glBegin(mf->v4?GL_QUADS:GL_TRIANGLES); | 740 » » » » glBegin(mf->v4 ? GL_QUADS : GL_TRIANGLES); |
699 » » » » if(tf) glTexCoord2fv(tf[i].uv[0]); | 741 » » » » if (tf) glTexCoord2fv(tf[i].uv[0]); |
700 » » » » if(cp) glColor3ub(cp[3], cp[2], cp[1]); | 742 » » » » if (cp) glColor3ub(cp[3], cp[2], cp[1]); |
701 mvert = &mv[mf->v1]; | 743 mvert = &mv[mf->v1]; |
702 » » » » if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no); | 744 » » » » if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no)
; |
703 glVertex3fv(mvert->co); | 745 glVertex3fv(mvert->co); |
704 ········································ | 746 ········································ |
705 » » » » if(tf) glTexCoord2fv(tf[i].uv[1]); | 747 » » » » if (tf) glTexCoord2fv(tf[i].uv[1]); |
706 » » » » if(cp) glColor3ub(cp[7], cp[6], cp[5]); | 748 » » » » if (cp) glColor3ub(cp[7], cp[6], cp[5]); |
707 mvert = &mv[mf->v2]; | 749 mvert = &mv[mf->v2]; |
708 » » » » if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no); | 750 » » » » if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no)
; |
709 glVertex3fv(mvert->co); | 751 glVertex3fv(mvert->co); |
710 | 752 |
711 » » » » if(tf) glTexCoord2fv(tf[i].uv[2]); | 753 » » » » if (tf) glTexCoord2fv(tf[i].uv[2]); |
712 » » » » if(cp) glColor3ub(cp[11], cp[10], cp[9]); | 754 » » » » if (cp) glColor3ub(cp[11], cp[10], cp[9]); |
713 mvert = &mv[mf->v3]; | 755 mvert = &mv[mf->v3]; |
714 » » » » if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no); | 756 » » » » if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no)
; |
715 glVertex3fv(mvert->co); | 757 glVertex3fv(mvert->co); |
716 | 758 |
717 » » » » if(mf->v4) { | 759 » » » » if (mf->v4) { |
718 » » » » » if(tf) glTexCoord2fv(tf[i].uv[3]); | 760 » » » » » if (tf) glTexCoord2fv(tf[i].uv[3]); |
719 » » » » » if(cp) glColor3ub(cp[15], cp[14], cp[13]
); | 761 » » » » » if (cp) glColor3ub(cp[15], cp[14], cp[13
]); |
720 mvert = &mv[mf->v4]; | 762 mvert = &mv[mf->v4]; |
721 » » » » » if(mf->flag&ME_SMOOTH) glNormal3sv(mvert
->no); | 763 » » » » » if (mf->flag & ME_SMOOTH) glNormal3sv(mv
ert->no); |
722 glVertex3fv(mvert->co); | 764 glVertex3fv(mvert->co); |
723 } | 765 } |
724 glEnd(); | 766 glEnd(); |
725 } | 767 } |
726 ························ | 768 ························ |
727 » » » if(nors) nors += 3; | 769 » » » if (nors) nors += 3; |
728 » » } | 770 » » } |
729 » } else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster
rendering */ | 771 » } |
730 » » MCol *col = realcol; | 772 » else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster re
ndering */ |
731 » » if(!col) | 773 » » GPU_vertex_setup(dm); |
732 » » » col = mcol; | 774 » » GPU_normal_setup(dm); |
733 | 775 » » GPU_uv_setup(dm); |
734 » » GPU_vertex_setup( dm ); | 776 » » if (mcol) { |
735 » » GPU_normal_setup( dm ); | 777 » » » GPU_color_setup(dm, colType); |
736 » » GPU_uv_setup( dm ); | 778 » » } |
737 » » if( col != NULL ) { | 779 |
738 » » » /*if( realcol && dm->drawObject->colType == CD_TEXTURE_M
COL ) { | 780 » » if (!GPU_buffer_legacy(dm)) { |
739 » » » » col = 0; | 781 » » » int tottri = dm->drawObject->tot_triangle_point / 3; |
740 » » » } else if( mcol && dm->drawObject->colType == CD_MCOL )
{ | 782 » » » int next_actualFace = dm->drawObject->triangle_to_mface[
0]; |
741 » » » » col = 0; | 783 |
742 » » » } | 784 » » » glShadeModel(GL_SMOOTH); |
743 » » »······· | 785 » » » /* lastFlag = 0; */ /* UNUSED */ |
744 » » » if( col != 0 ) {*/ | 786 » » » for (i = 0; i < tottri; i++) { |
745 » » » » unsigned char *colors = MEM_mallocN(dm->getNumFa
ces(dm)*4*3*sizeof(unsigned char), "cdDM_drawFacesTex_common"); | 787 » » » » int actualFace = next_actualFace; |
746 » » » » for( i=0; i < dm->getNumFaces(dm); i++ ) { | 788 » » » » DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL
; |
747 » » » » » for( j=0; j < 4; j++ ) { | 789 » » » » int flush = 0; |
748 » » » » » » colors[i*12+j*3] = col[i*4+j].r; | 790 |
749 » » » » » » colors[i*12+j*3+1] = col[i*4+j].
g; | 791 » » » » if (i != tottri - 1) |
750 » » » » » » colors[i*12+j*3+2] = col[i*4+j].
b; | 792 » » » » » next_actualFace = dm->drawObject->triang
le_to_mface[i + 1]; |
751 » » » » » } | 793 |
752 » » » » } | 794 » » » » if (drawParams) { |
753 » » » » GPU_color3_upload(dm,colors); | 795 » » » » » draw_option = drawParams(tf ? &tf[actual
Face] : NULL, (mcol != NULL), mf[actualFace].mat_nr); |
754 » » » » MEM_freeN(colors); | |
755 » » » » if(realcol) | |
756 » » » » » dm->drawObject->colType = CD_TEXTURE_MCO
L; | |
757 » » » » else if(mcol) | |
758 » » » » » dm->drawObject->colType = CD_MCOL; | |
759 » » » //} | |
760 » » » GPU_color_setup( dm ); | |
761 » » } | |
762 | |
763 » » if( !GPU_buffer_legacy(dm) ) { | |
764 » » » glShadeModel( GL_SMOOTH ); | |
765 » » » lastFlag = 0; | |
766 » » » for(i = 0; i < dm->drawObject->nelements/3; i++) { | |
767 » » » » int actualFace = dm->drawObject->faceRemap[i]; | |
768 » » » » int flag = 1; | |
769 | |
770 » » » » if(drawParams) { | |
771 » » » » » flag = drawParams(tf? &tf[actualFace]: N
ULL, mcol? &mcol[actualFace*4]: NULL, mf[actualFace].mat_nr); | |
772 } | 796 } |
773 else { | 797 else { |
774 » » » » » if(index) { | 798 » » » » » if (index_mf_to_mpoly) { |
775 » » » » » » orig = index[actualFace]; | 799 » » » » » » orig = DM_origindex_mface_mpoly(
index_mf_to_mpoly, index_mp_to_orig, actualFace); |
776 » » » » » » if(orig == ORIGINDEX_NONE) conti
nue; | 800 » » » » » » if (orig == ORIGINDEX_NONE) { |
777 » » » » » » if(drawParamsMapped) | 801 » » » » » » » /* XXX, this is not real
ly correct |
778 » » » » » » » flag = drawParamsMapped(
userData, orig); | 802 » » » » » » » * it will draw the prev
ious faces context for this one when we don't know its settings. |
779 » » » » » } | 803 » » » » » » » * but better then skipp
ing it altogether. - campbell */ |
780 » » » » » else | 804 » » » » » » » draw_option = DM_DRAW_OP
TION_NORMAL; |
781 » » » » » » if(drawParamsMapped) | |
782 » » » » » » » flag = drawParamsMapped(
userData, actualFace); | |
783 » » » » } | |
784 » » » » if( flag != lastFlag ) { | |
785 » » » » » if( startFace < i ) { | |
786 » » » » » » if( lastFlag != 0 ) { /* if the
flag is 0 it means the face is hidden or invisible */ | |
787 » » » » » » » if (lastFlag==1 && col) | |
788 » » » » » » » » GPU_color_switch
(1); | |
789 » » » » » » » else | |
790 » » » » » » » » GPU_color_switch
(0); | |
791 » » » » » » » glDrawArrays(GL_TRIANGLE
S,startFace*3,(i-startFace)*3); | |
792 } | 805 } |
793 » » » » » } | 806 » » » » » » else if (drawParamsMapped) { |
794 » » » » » lastFlag = flag; | 807 » » » » » » » draw_option = drawParams
Mapped(userData, orig); |
795 » » » » » startFace = i; | 808 » » » » » » } |
796 » » » » } | 809 » » » » » } |
797 » » » } | 810 » » » » » else if (drawParamsMapped) { |
798 » » » if( startFace < dm->drawObject->nelements/3 ) { | 811 » » » » » » draw_option = drawParamsMapped(u
serData, actualFace); |
799 » » » » if( lastFlag != 0 ) { /* if the flag is 0 it mea
ns the face is hidden or invisible */ | 812 » » » » » } |
800 » » » » » if (lastFlag==1 && col) | 813 » » » » } |
801 » » » » » » GPU_color_switch(1); | 814 |
802 » » » » » else | 815 » » » » /* flush buffer if current triangle isn't drawab
le or it's last triangle */ |
803 » » » » » » GPU_color_switch(0); | 816 » » » » flush = (draw_option == DM_DRAW_OPTION_SKIP) ||
(i == tottri - 1); |
804 » » » » » glDrawArrays(GL_TRIANGLES,startFace*3,dm
->drawObject->nelements-startFace*3); | 817 |
| 818 » » » » if (!flush && compareDrawOptions) { |
| 819 » » » » » /* also compare draw options and flush b
uffer if they're different |
| 820 » » » » » * need for face selection highlight in
edit mode */ |
| 821 » » » » » flush |= compareDrawOptions(userData, ac
tualFace, next_actualFace) == 0; |
| 822 » » » » } |
| 823 |
| 824 » » » » if (flush) { |
| 825 » » » » » int first = startFace * 3; |
| 826 » » » » » /* Add one to the length if we're drawin
g at the end of the array */ |
| 827 » » » » » int count = (i - startFace + (draw_optio
n != DM_DRAW_OPTION_SKIP ? 1 : 0)) * 3; |
| 828 |
| 829 » » » » » if (count) { |
| 830 » » » » » » if (mcol && draw_option != DM_DR
AW_OPTION_NO_MCOL) |
| 831 » » » » » » » GPU_color_switch(1); |
| 832 » » » » » » else |
| 833 » » » » » » » GPU_color_switch(0); |
| 834 |
| 835 » » » » » » glDrawArrays(GL_TRIANGLES, first
, count); |
| 836 » » » » » } |
| 837 |
| 838 » » » » » startFace = i + 1; |
805 } | 839 } |
806 } | 840 } |
807 } | 841 } |
808 | 842 |
809 GPU_buffer_unbind(); | 843 GPU_buffer_unbind(); |
810 » » glShadeModel( GL_FLAT ); | 844 » » glShadeModel(GL_FLAT); |
811 » } | 845 » } |
812 } | 846 } |
813 | 847 |
814 static void cdDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tfa
ce, MCol *mcol, int matnr)) | 848 static void cdDM_drawFacesTex(DerivedMesh *dm, |
815 { | 849 DMSetDrawOptionsTex setDrawOptions, |
816 » cdDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL); | 850 DMCompareDrawOptions compareDrawOptions, |
817 } | 851 void *userData) |
818 | 852 { |
819 static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
erData, int index, int *drawSmooth_r), void *userData, int useColors, int (*setM
aterial)(int, void *attribs)) | 853 » cdDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, u
serData); |
820 { | 854 } |
821 » CDDerivedMesh *cddm = (CDDerivedMesh*) dm; | 855 |
| 856 static void cdDM_drawMappedFaces(DerivedMesh *dm, |
| 857 DMSetDrawOptions setDrawOptions, |
| 858 DMSetMaterial setMaterial, |
| 859 DMCompareDrawOptions compareDrawOptions, |
| 860 void *userData, DMDrawFlag flag) |
| 861 { |
| 862 » CDDerivedMesh *cddm = (CDDerivedMesh *) dm; |
822 MVert *mv = cddm->mvert; | 863 MVert *mv = cddm->mvert; |
823 MFace *mf = cddm->mface; | 864 MFace *mf = cddm->mface; |
824 » MCol *mc; | 865 » MCol *mcol; |
825 » float *nors= dm->getFaceDataArray(dm, CD_NORMAL); | 866 » float *nors = DM_get_tessface_data_layer(dm, CD_NORMAL); |
826 » int i, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX); | 867 » int colType, useColors = flag & DM_DRAW_USE_COLORS; |
827 | 868 » int i, orig; |
828 » mc = DM_get_face_data_layer(dm, CD_ID_MCOL); | 869 |
829 » if(!mc) | 870 |
830 » » mc = DM_get_face_data_layer(dm, CD_WEIGHT_MCOL); | 871 » /* double lookup */ |
831 » if(!mc) | 872 » const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX
); |
832 » » mc = DM_get_face_data_layer(dm, CD_MCOL); | 873 » const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); |
| 874 » if (index_mf_to_mpoly == NULL) { |
| 875 » » index_mp_to_orig = NULL; |
| 876 » } |
| 877 |
| 878 |
| 879 » colType = CD_ID_MCOL; |
| 880 » mcol = DM_get_tessface_data_layer(dm, colType); |
| 881 » if (!mcol) { |
| 882 » » colType = CD_PREVIEW_MCOL; |
| 883 » » mcol = DM_get_tessface_data_layer(dm, colType); |
| 884 » } |
| 885 » if (!mcol) { |
| 886 » » colType = CD_MCOL; |
| 887 » » mcol = DM_get_tessface_data_layer(dm, colType); |
| 888 » } |
833 | 889 |
834 cdDM_update_normals_from_pbvh(dm); | 890 cdDM_update_normals_from_pbvh(dm); |
835 | 891 |
836 /* back-buffer always uses legacy since VBO's would need the | 892 /* back-buffer always uses legacy since VBO's would need the |
837 * color array temporarily overwritten for drawing, then reset. */ | 893 * color array temporarily overwritten for drawing, then reset. */ |
838 » if( GPU_buffer_legacy(dm) || G.f & G_BACKBUFSEL) { | 894 » if (GPU_buffer_legacy(dm) || G.f & G_BACKBUFSEL) { |
839 » » DEBUG_VBO( "Using legacy code. cdDM_drawMappedFaces\n" ); | 895 » » DEBUG_VBO("Using legacy code. cdDM_drawMappedFaces\n"); |
840 » » for(i = 0; i < dm->numFaceData; i++, mf++) { | 896 » » for (i = 0; i < dm->numTessFaceData; i++, mf++) { |
841 » » » int drawSmooth = (mf->flag & ME_SMOOTH); | 897 » » » int drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : (m
f->flag & ME_SMOOTH); |
842 » » » int draw= 1; | 898 » » » DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL; |
843 | 899 |
844 » » » orig= (index==NULL) ? i : *index++; | 900 » » » orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(in
dex_mf_to_mpoly, index_mp_to_orig, i) : i; |
845 ························ | 901 ························ |
846 » » » if(orig == ORIGINDEX_NONE) | 902 » » » if (orig == ORIGINDEX_NONE) |
847 » » » » draw= setMaterial(mf->mat_nr + 1, NULL); | 903 » » » » draw_option = setMaterial(mf->mat_nr + 1, NULL); |
848 else if (setDrawOptions != NULL) | 904 else if (setDrawOptions != NULL) |
849 » » » » draw= setDrawOptions(userData, orig, &drawSmooth
); | 905 » » » » draw_option = setDrawOptions(userData, orig); |
850 | 906 |
851 » » » if(draw) { | 907 » » » if (draw_option != DM_DRAW_OPTION_SKIP) { |
852 unsigned char *cp = NULL; | 908 unsigned char *cp = NULL; |
853 | 909 |
854 » » » » if(useColors && mc) | 910 » » » » if (draw_option == DM_DRAW_OPTION_STIPPLE) { |
855 » » » » » cp = (unsigned char *)&mc[i * 4]; | 911 » » » » » glEnable(GL_POLYGON_STIPPLE); |
856 | 912 » » » » » glPolygonStipple(stipple_quarttone); |
857 » » » » glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT); | 913 » » » » } |
858 » » » » glBegin(mf->v4?GL_QUADS:GL_TRIANGLES); | 914 |
| 915 » » » » if (useColors && mcol) |
| 916 » » » » » cp = (unsigned char *)&mcol[i * 4]; |
| 917 |
| 918 » » » » /* no need to set shading mode to flat because |
| 919 » » » » * normals are already used to change shading *
/ |
| 920 » » » » glShadeModel(GL_SMOOTH); |
| 921 » » » » glBegin(mf->v4 ? GL_QUADS : GL_TRIANGLES); |
859 | 922 |
860 if (!drawSmooth) { | 923 if (!drawSmooth) { |
861 if (nors) { | 924 if (nors) { |
862 glNormal3fv(nors); | 925 glNormal3fv(nors); |
863 } | 926 } |
864 else { | 927 else { |
865 float nor[3]; | 928 float nor[3]; |
866 » » » » » » if(mf->v4) { | 929 » » » » » » if (mf->v4) { |
867 » » » » » » » normal_quad_v3( nor,mv[m
f->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co); | 930 » » » » » » » normal_quad_v3(nor, mv[m
f->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co); |
868 » » » » » » } else { | 931 » » » » » » } |
869 » » » » » » » normal_tri_v3( nor,mv[mf
->v1].co, mv[mf->v2].co, mv[mf->v3].co); | 932 » » » » » » else { |
| 933 » » » » » » » normal_tri_v3(nor, mv[mf
->v1].co, mv[mf->v2].co, mv[mf->v3].co); |
870 } | 934 } |
871 glNormal3fv(nor); | 935 glNormal3fv(nor); |
872 } | 936 } |
873 | 937 |
874 » » » » » if(cp) glColor3ub(cp[3], cp[2], cp[1]); | 938 » » » » » if (cp) glColor3ub(cp[3], cp[2], cp[1]); |
875 glVertex3fv(mv[mf->v1].co); | 939 glVertex3fv(mv[mf->v1].co); |
876 » » » » » if(cp) glColor3ub(cp[7], cp[6], cp[5]); | 940 » » » » » if (cp) glColor3ub(cp[7], cp[6], cp[5]); |
877 glVertex3fv(mv[mf->v2].co); | 941 glVertex3fv(mv[mf->v2].co); |
878 » » » » » if(cp) glColor3ub(cp[11], cp[10], cp[9])
; | 942 » » » » » if (cp) glColor3ub(cp[11], cp[10], cp[9]
); |
879 glVertex3fv(mv[mf->v3].co); | 943 glVertex3fv(mv[mf->v3].co); |
880 » » » » » if(mf->v4) { | 944 » » » » » if (mf->v4) { |
881 » » » » » » if(cp) glColor3ub(cp[15], cp[14]
, cp[13]); | 945 » » » » » » if (cp) glColor3ub(cp[15], cp[14
], cp[13]); |
882 glVertex3fv(mv[mf->v4].co); | 946 glVertex3fv(mv[mf->v4].co); |
883 } | 947 } |
884 » » » » } else { | 948 » » » » } |
885 » » » » » if(cp) glColor3ub(cp[3], cp[2], cp[1]); | 949 » » » » else { |
| 950 » » » » » if (cp) glColor3ub(cp[3], cp[2], cp[1]); |
886 glNormal3sv(mv[mf->v1].no); | 951 glNormal3sv(mv[mf->v1].no); |
887 glVertex3fv(mv[mf->v1].co); | 952 glVertex3fv(mv[mf->v1].co); |
888 » » » » » if(cp) glColor3ub(cp[7], cp[6], cp[5]); | 953 » » » » » if (cp) glColor3ub(cp[7], cp[6], cp[5]); |
889 glNormal3sv(mv[mf->v2].no); | 954 glNormal3sv(mv[mf->v2].no); |
890 glVertex3fv(mv[mf->v2].co); | 955 glVertex3fv(mv[mf->v2].co); |
891 » » » » » if(cp) glColor3ub(cp[11], cp[10], cp[9])
; | 956 » » » » » if (cp) glColor3ub(cp[11], cp[10], cp[9]
); |
892 glNormal3sv(mv[mf->v3].no); | 957 glNormal3sv(mv[mf->v3].no); |
893 glVertex3fv(mv[mf->v3].co); | 958 glVertex3fv(mv[mf->v3].co); |
894 » » » » » if(mf->v4) { | 959 » » » » » if (mf->v4) { |
895 » » » » » » if(cp) glColor3ub(cp[15], cp[14]
, cp[13]); | 960 » » » » » » if (cp) glColor3ub(cp[15], cp[14
], cp[13]); |
896 glNormal3sv(mv[mf->v4].no); | 961 glNormal3sv(mv[mf->v4].no); |
897 glVertex3fv(mv[mf->v4].co); | 962 glVertex3fv(mv[mf->v4].co); |
898 } | 963 } |
899 } | 964 } |
900 | 965 |
901 glEnd(); | 966 glEnd(); |
| 967 |
| 968 if (draw_option == DM_DRAW_OPTION_STIPPLE) |
| 969 glDisable(GL_POLYGON_STIPPLE); |
902 } | 970 } |
903 ························ | 971 ························ |
904 if (nors) nors += 3; | 972 if (nors) nors += 3; |
905 } | 973 } |
906 } | 974 } |
907 else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster re
ndering */ | 975 else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster re
ndering */ |
908 int prevstart = 0; | 976 int prevstart = 0; |
909 GPU_vertex_setup(dm); | 977 GPU_vertex_setup(dm); |
910 GPU_normal_setup(dm); | 978 GPU_normal_setup(dm); |
911 » » if( useColors && mc ) | 979 » » if (useColors && mcol) { |
912 » » » GPU_color_setup(dm); | 980 » » » GPU_color_setup(dm, colType); |
913 » » if( !GPU_buffer_legacy(dm) ) { | 981 » » } |
914 » » » int tottri = dm->drawObject->nelements/3; | 982 » » if (!GPU_buffer_legacy(dm)) { |
| 983 » » » int tottri = dm->drawObject->tot_triangle_point / 3; |
915 glShadeModel(GL_SMOOTH); | 984 glShadeModel(GL_SMOOTH); |
916 ························ | 985 ························ |
917 » » » if(tottri == 0) { | 986 » » » if (tottri == 0) { |
918 /* avoid buffer problems in following code */ | 987 /* avoid buffer problems in following code */ |
919 } | 988 } |
920 » » » if(setDrawOptions == NULL) { | 989 » » » if (setDrawOptions == NULL) { |
921 /* just draw the entire face array */ | 990 /* just draw the entire face array */ |
922 » » » » glDrawArrays(GL_TRIANGLES, 0, (tottri-1) * 3); | 991 » » » » glDrawArrays(GL_TRIANGLES, 0, (tottri) * 3); |
923 } | 992 } |
924 else { | 993 else { |
925 /* we need to check if the next material changes
*/ | 994 /* we need to check if the next material changes
*/ |
926 » » » » int next_actualFace= dm->drawObject->faceRemap[0
]; | 995 » » » » int next_actualFace = dm->drawObject->triangle_t
o_mface[0]; |
927 ································ | 996 ································ |
928 » » » » for( i = 0; i < tottri; i++ ) { | 997 » » » » for (i = 0; i < tottri; i++) { |
929 » » » » » //int actualFace = dm->drawObject->faceR
emap[i]; | 998 » » » » » //int actualFace = dm->drawObject->trian
gle_to_mface[i]; |
930 int actualFace = next_actualFace; | 999 int actualFace = next_actualFace; |
931 » » » » » MFace *mface= mf + actualFace; | 1000 » » » » » MFace *mface = mf + actualFace; |
932 » » » » » int drawSmooth= (mface->flag & ME_SMOOTH
); | 1001 » » » » » /*int drawSmooth = (flag & DM_DRAW_ALWAY
S_SMOOTH) ? 1 : (mface->flag & ME_SMOOTH);*/ /* UNUSED */ |
933 » » » » » int draw = 1; | 1002 » » » » » DMDrawOption draw_option = DM_DRAW_OPTIO
N_NORMAL; |
934 | 1003 » » » » » int flush = 0; |
935 » » » » » if(i != tottri-1) | 1004 |
936 » » » » » » next_actualFace= dm->drawObject-
>faceRemap[i+1]; | 1005 » » » » » if (i != tottri - 1) |
937 | 1006 » » » » » » next_actualFace = dm->drawObject
->triangle_to_mface[i + 1]; |
938 » » » » » orig= (index==NULL) ? actualFace : index
[actualFace]; | 1007 |
939 | 1008 » » » » » orig = (index_mf_to_mpoly) ? DM_originde
x_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace) : actualFace; |
940 » » » » » if(orig == ORIGINDEX_NONE) | 1009 |
941 » » » » » » draw= setMaterial(mface->mat_nr
+ 1, NULL); | 1010 » » » » » if (orig == ORIGINDEX_NONE) |
| 1011 » » » » » » draw_option = setMaterial(mface-
>mat_nr + 1, NULL); |
942 else if (setDrawOptions != NULL) | 1012 else if (setDrawOptions != NULL) |
943 » » » » » » draw= setDrawOptions(userData, o
rig, &drawSmooth); | 1013 » » » » » » draw_option = setDrawOptions(use
rData, orig); |
| 1014 |
| 1015 » » » » » if (draw_option == DM_DRAW_OPTION_STIPPL
E) { |
| 1016 » » » » » » glEnable(GL_POLYGON_STIPPLE); |
| 1017 » » » » » » glPolygonStipple(stipple_quartto
ne); |
| 1018 » » » » » } |
944 ········ | 1019 ········ |
945 /* Goal is to draw as long of a contiguo
us triangle | 1020 /* Goal is to draw as long of a contiguo
us triangle |
946 » » » » » array as possible, so draw when we hi
t either an | 1021 » » » » » * array as possible, so draw when we hi
t either an |
947 » » » » » invisible triangle or at the end of t
he array */ | 1022 » » » » » * invisible triangle or at the end of t
he array */ |
948 » » » » » if(!draw || i == tottri - 1 || mf[actual
Face].mat_nr != mf[next_actualFace].mat_nr) { | 1023 |
949 » » » » » » if(prevstart != i) | 1024 » » » » » /* flush buffer if current triangle isn'
t drawable or it's last triangle... */ |
950 » » » » » » » /* Add one to the length
(via `draw') | 1025 » » » » » flush = (ELEM(draw_option, DM_DRAW_OPTIO
N_SKIP, DM_DRAW_OPTION_STIPPLE)) || (i == tottri - 1); |
951 » » » » » » » if we're drawing at t
he end of the array */ | 1026 |
952 » » » » » » » glDrawArrays(GL_TRIANGLE
S,prevstart*3, (i-prevstart+draw)*3); | 1027 » » » » » /* ... or when material setting is dissf
erent */ |
| 1028 » » » » » flush |= mf[actualFace].mat_nr != mf[nex
t_actualFace].mat_nr; |
| 1029 |
| 1030 » » » » » if (!flush && compareDrawOptions) { |
| 1031 » » » » » » flush |= compareDrawOptions(user
Data, actualFace, next_actualFace) == 0; |
| 1032 » » » » » } |
| 1033 |
| 1034 » » » » » if (flush) { |
| 1035 » » » » » » int first = prevstart * 3; |
| 1036 » » » » » » /* Add one to the length if we'r
e drawing at the end of the array */ |
| 1037 » » » » » » int count = (i - prevstart + (dr
aw_option != DM_DRAW_OPTION_SKIP ? 1 : 0)) * 3; |
| 1038 |
| 1039 » » » » » » if (count) |
| 1040 » » » » » » » glDrawArrays(GL_TRIANGLE
S, first, count); |
| 1041 |
953 prevstart = i + 1; | 1042 prevstart = i + 1; |
| 1043 |
| 1044 if (draw_option == DM_DRAW_OPTIO
N_STIPPLE) |
| 1045 glDisable(GL_POLYGON_STI
PPLE); |
954 } | 1046 } |
955 } | 1047 } |
956 } | 1048 } |
957 | 1049 |
958 glShadeModel(GL_FLAT); | 1050 glShadeModel(GL_FLAT); |
959 } | 1051 } |
960 GPU_buffer_unbind(); | 1052 GPU_buffer_unbind(); |
961 } | 1053 } |
962 } | 1054 } |
963 | 1055 |
964 static void cdDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void
*userData, int index), void *userData) | 1056 static void cdDM_drawMappedFacesTex(DerivedMesh *dm, |
965 { | 1057 DMSetDrawOptions setDrawOptions, |
966 » cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData); | 1058 DMCompareDrawOptions compareDrawOptions, |
967 } | 1059 void *userData) |
968 | 1060 { |
969 static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo
id *attribs), int (*setDrawOptions)(void *userData, int index), void *userData) | 1061 » cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, u
serData); |
970 { | 1062 } |
971 » CDDerivedMesh *cddm = (CDDerivedMesh*) dm; | |
972 » GPUVertexAttribs gattribs; | |
973 » DMVertexAttribs attribs; | |
974 » MVert *mvert = cddm->mvert; | |
975 » MFace *mface = cddm->mface; | |
976 MTFace *tf = dm->getFaceDataArray(dm, CD_MTFACE); | 1063 MTFace *tf = dm->getFaceDataArray(dm, CD_MTFACE); |
977 float (*nors)[3] = dm->getFaceDataArray(dm, CD_NORMAL); | 1064 float (*nors)[3] = dm->getFaceDataArray(dm, CD_NORMAL); |
978 int a, b, dodraw, matnr, new_matnr; | 1065 int a, b, dodraw, matnr, new_matnr; |
| 1066 int transp, new_transp, orig_transp; |
979 int orig, *index = dm->getFaceDataArray(dm, CD_ORIGINDEX); | 1067 int orig, *index = dm->getFaceDataArray(dm, CD_ORIGINDEX); |
980 | 1068 |
981 cdDM_update_normals_from_pbvh(dm); | 1069 cdDM_update_normals_from_pbvh(dm); |
982 | 1070 |
983 matnr = -1; | 1071 matnr = -1; |
984 dodraw = 0; | 1072 dodraw = 0; |
| 1073 transp = GPU_get_material_blend_mode(); |
| 1074 orig_transp = transp; |
985 | 1075 |
986 glShadeModel(GL_SMOOTH); | 1076 glShadeModel(GL_SMOOTH); |
987 | 1077 |
988 if( GPU_buffer_legacy(dm) || setDrawOptions != NULL ) { | |
989 DEBUG_VBO( "Using legacy code. cdDM_drawMappedFacesGLSL\n" ); | |
990 memset(&attribs, 0, sizeof(attribs)); | |
991 | |
992 glBegin(GL_QUADS); | |
993 | |
994 for(a = 0; a < dm->numFaceData; a++, mface++) { | |
995 const int smoothnormal = (mface->flag & ME_SMOOTH); | |
996 new_matnr = mface->mat_nr + 1; | |
997 | |
998 if(new_matnr != matnr) { | |
999 glEnd(); | |
1000 | |
1001 dodraw = setMaterial(matnr = new_matnr, &gattrib
s); | |
1002 if(dodraw) | |
1003 DM_vertex_attributes_from_gpu(dm, &gattr
ibs, &attribs); | |
1004 | |
1005 glBegin(GL_QUADS); | |
1006 } | |
1007 | |
1008 if(!dodraw) { | |
1009 continue; | |
1010 } | |
1011 else if(setDrawOptions) { | |
1012 orig = (index)? index[a]: a; | |
1013 | |
1014 if(orig == ORIGINDEX_NONE) { | |
1015 /* since the material is set by setMater
ial(), faces with no | |
1016 * origin can be assumed to be generated
by a modifier */· | |
1017 ········································ | |
1018 /* continue */ | |
1019 } | |
1020 else if(!setDrawOptions(userData, orig)) | |
1021 continue; | |
1022 } | |
1023 | |
1024 if(!smoothnormal) { | |
1025 if(nors) { | |
1026 glNormal3fv(nors[a]); | |
1027 } | |
1028 else { | |
1029 /* TODO ideally a normal layer should al
ways be available */ | |
1030 float nor[3]; | |
1031 if(mface->v4) { | |
1032 normal_quad_v3( nor,mvert[mface-
>v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co); | |
1033 } else { | |
1034 normal_tri_v3( nor,mvert[mface->
v1].co, mvert[mface->v2].co, mvert[mface->v3].co); | |
1035 } | |
1036 glNormal3fv(nor); | |
1037 } | |
1038 } | |
1039 | |
1040 #define PASSVERT(index, vert) {
\ | |
1041 if(attribs.totorco)
\ | |
1042 glVertexAttrib3fvARB(attribs.orco.glIndex, attribs.orco.
array[index]); \ | |
1043 for(b = 0; b < attribs.tottface; b++) {
\ | |
1044 MTFace *tf = &attribs.tface[b].array[a];
\ | |
1045 glVertexAttrib2fvARB(attribs.tface[b].glIndex, tf->uv[ve
rt]); \ | |
1046 }
\ | |
1047 for(b = 0; b < attribs.totmcol; b++) {
\ | |
1048 MCol *cp = &attribs.mcol[b].array[a*4 + vert];
\ | |
1049 GLubyte col[4];
\ | |
1050 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp-
>a; \ | |
1051 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col);
\ | |
1052 }
\ | |
1053 if(attribs.tottang) {
\ | |
1054 float *tang = attribs.tang.array[a*4 + vert];
\ | |
1055 glVertexAttrib4fvARB(attribs.tang.glIndex, tang);
\ | |
1056 }
\ | |
1057 if(smoothnormal)
\ | |
1058 glNormal3sv(mvert[index].no);
\ | |
1059 glVertex3fv(mvert[index].co);
\ | |
1060 } | |
1061 | |
1062 PASSVERT(mface->v1, 0); | |
1063 PASSVERT(mface->v2, 1); | |
1064 PASSVERT(mface->v3, 2); | |
1065 if(mface->v4) | |
1066 PASSVERT(mface->v4, 3) | |
1067 else | |
1068 PASSVERT(mface->v3, 2) | |
1069 | |
1070 #undef PASSVERT | |
1071 } | |
1072 glEnd(); | |
1073 } | |
1074 else { | |
1075 GPUBuffer *buffer = NULL; | |
1076 char *varray = NULL; | |
1077 int numdata = 0, elementsize = 0, offset; | |
1078 int start = 0, numfaces = 0, prevdraw = 0, curface = 0; | |
1079 int i; | |
1080 | |
1081 MFace *mf = mface; | |
1082 GPUAttrib datatypes[GPU_MAX_ATTRIB]; /* TODO, messing up when sw
itching materials many times - [#21056]*/ | |
1083 memset(&attribs, 0, sizeof(attribs)); | |
1084 | |
1085 GPU_vertex_setup(dm); | |
1086 GPU_normal_setup(dm); | |
1087 | |
1088 if( !GPU_buffer_legacy(dm) ) { | |
1089 for( i = 0; i < dm->drawObject->nelements/3; i++ ) { | |
1090 | |
1091 a = dm->drawObject->faceRemap[i]; | |
1092 | |
1093 mface = mf + a; | |
1094 new_matnr = mface->mat_nr + 1; | |
1095 | |
1096 if(new_matnr != matnr ) { | |
1097 numfaces = curface - start; | |
1098 if( numfaces > 0 ) { | |
1099 | |
1100 if( dodraw ) { | |
1101 | |
1102 if( numdata != 0 ) { | |
1103 | |
1104 GPU_buffer_unloc
k(buffer); | |
1105 | |
1106 GPU_interleaved_
attrib_setup(buffer,datatypes,numdata); | |
1107 } | |
1108 | |
1109 glDrawArrays(GL_TRIANGLE
S,start*3,numfaces*3); | |
1110 | |
1111 if( numdata != 0 ) { | |
1112 | |
1113 GPU_buffer_free(
buffer, NULL); | |
1114 | |
1115 buffer = NULL; | |
1116 } | |
1117 | |
1118 } | |
1119 } | |
1120 numdata = 0; | |
1121 start = curface; | |
1122 prevdraw = dodraw; | |
1123 dodraw = setMaterial(matnr = new_matnr,
&gattribs); | |
1124 if(dodraw) { | |
1125 DM_vertex_attributes_from_gpu(dm
, &gattribs, &attribs); | |
1126 | |
1127 if(attribs.totorco) { | |
1128 datatypes[numdata].index
= attribs.orco.glIndex; | |
1129 datatypes[numdata].size
= 3; | |
1130 datatypes[numdata].type
= GL_FLOAT; | |
1131 numdata++; | |
1132 } | |
1133 for(b = 0; b < attribs.tottface;
b++) { | |
1134 datatypes[numdata].index
= attribs.tface[b].glIndex; | |
1135 datatypes[numdata].size
= 2; | |
1136 datatypes[numdata].type
= GL_FLOAT; | |
1137 numdata++; | |
1138 }······· | |
1139 for(b = 0; b < attribs.totmcol;
b++) { | |
1140 datatypes[numdata].index
= attribs.mcol[b].glIndex; | |
1141 datatypes[numdata].size
= 4; | |
1142 datatypes[numdata].type
= GL_UNSIGNED_BYTE; | |
1143 numdata++; | |
1144 }······· | |
1145 if(attribs.tottang) { | |
1146 datatypes[numdata].index
= attribs.tang.glIndex; | |
1147 datatypes[numdata].size
= 4; | |
1148 datatypes[numdata].type
= GL_FLOAT; | |
1149 numdata++; | |
1150 } | |
1151 if( numdata != 0 ) { | |
1152 elementsize = GPU_attrib
_element_size( datatypes, numdata ); | |
1153 buffer = GPU_buffer_allo
c( elementsize*dm->drawObject->nelements, NULL ); | |
1154 if( buffer == NULL ) { | |
1155 GPU_buffer_unbin
d(); | |
1156 dm->drawObject->
legacy = 1; | |
1157 return; | |
1158 } | |
1159 varray = GPU_buffer_lock
_stream(buffer); | |
1160 if( varray == NULL ) { | |
1161 GPU_buffer_unbin
d(); | |
1162 GPU_buffer_free(
buffer, NULL); | |
1163 dm->drawObject->
legacy = 1; | |
1164 return; | |
1165 } | |
1166 } | |
1167 else { | |
1168 /* if the buffer was set
, dont use it again. | |
1169 * prevdraw was assumed
true but didnt run so set to false - [#21036] */ | |
1170 prevdraw= 0; | |
1171 buffer= NULL; | |
1172 } | |
1173 } | |
1174 } | |
1175 if(!dodraw) { | |
1176 continue; | |
1177 } | |
1178 | |
1179 if( numdata != 0 ) { | |
1180 offset = 0; | |
1181 if(attribs.totorco) { | |
1182 VECCOPY((float *)&varray[element
size*curface*3],(float *)attribs.orco.array[mface->v1]); | |
1183 VECCOPY((float *)&varray[element
size*curface*3+elementsize],(float *)attribs.orco.array[mface->v2]); | |
1184 VECCOPY((float *)&varray[element
size*curface*3+elementsize*2],(float *)attribs.orco.array[mface->v3]); | |
1185 offset += sizeof(float)*3; | |
1186 } | |
1187 for(b = 0; b < attribs.tottface; b++) { | |
1188 MTFace *tf = &attribs.tface[b].a
rray[a]; | |
1189 VECCOPY2D((float *)&varray[eleme
ntsize*curface*3+offset],tf->uv[0]); | |
1190 VECCOPY2D((float *)&varray[eleme
ntsize*curface*3+offset+elementsize],tf->uv[1]); | |
1191 | |
1192 VECCOPY2D((float *)&varray[eleme
ntsize*curface*3+offset+elementsize*2],tf->uv[2]); | |
1193 offset += sizeof(float)*2; | |
1194 } | |
1195 for(b = 0; b < attribs.totmcol; b++) { | |
1196 MCol *cp = &attribs.mcol[b].arra
y[a*4 + 0]; | |
1197 GLubyte col[4]; | |
1198 col[0]= cp->b; col[1]= cp->g; co
l[2]= cp->r; col[3]= cp->a; | |
1199 QUATCOPY((unsigned char *)&varra
y[elementsize*curface*3+offset], col); | |
1200 cp = &attribs.mcol[b].array[a*4
+ 1]; | |
1201 col[0]= cp->b; col[1]= cp->g; co
l[2]= cp->r; col[3]= cp->a; | |
1202 QUATCOPY((unsigned char *)&varra
y[elementsize*curface*3+offset+elementsize], col); | |
1203 cp = &attribs.mcol[b].array[a*4
+ 2]; | |
1204 col[0]= cp->b; col[1]= cp->g; co
l[2]= cp->r; col[3]= cp->a; | |
1205 QUATCOPY((unsigned char *)&varra
y[elementsize*curface*3+offset+elementsize*2], col); | |
1206 offset += sizeof(unsigned char)*
4; | |
1207 }······· | |
1208 if(attribs.tottang) { | |
1209 float *tang = attribs.tang.array
[a*4 + 0]; | |
1210 QUATCOPY((float *)&varray[elemen
tsize*curface*3+offset], tang); | |
1211 tang = attribs.tang.array[a*4 +
1]; | |
1212 QUATCOPY((float *)&varray[elemen
tsize*curface*3+offset+elementsize], tang); | |
1213 tang = attribs.tang.array[a*4 +
2]; | |
1214 QUATCOPY((float *)&varray[elemen
tsize*curface*3+offset+elementsize*2], tang); | |
1215 offset += sizeof(float)*4; | |
1216 } | |
1217 } | |
1218 curface++; | |
1219 if(mface->v4) { | |
1220 if( numdata != 0 ) { | |
1221 offset = 0; | |
1222 if(attribs.totorco) { | |
1223 VECCOPY((float *)&varray
[elementsize*curface*3],(float *)attribs.orco.array[mface->v3]); | |
1224 VECCOPY((float *)&varray
[elementsize*curface*3+elementsize],(float *)attribs.orco.array[mface->v4]); | |
1225 VECCOPY((float *)&varray
[elementsize*curface*3+elementsize*2],(float *)attribs.orco.array[mface->v1]); | |
1226 offset += sizeof(float)*
3; | |
1227 } | |
1228 for(b = 0; b < attribs.tottface;
b++) { | |
1229 MTFace *tf = &attribs.tf
ace[b].array[a]; | |
1230 VECCOPY2D((float *)&varr
ay[elementsize*curface*3+offset],tf->uv[2]); | |
1231 VECCOPY2D((float *)&varr
ay[elementsize*curface*3+offset+elementsize],tf->uv[3]); | |
1232 VECCOPY2D((float *)&varr
ay[elementsize*curface*3+offset+elementsize*2],tf->uv[0]); | |
1233 offset += sizeof(float)*
2; | |
1234 } | |
1235 for(b = 0; b < attribs.totmcol;
b++) { | |
1236 MCol *cp = &attribs.mcol
[b].array[a*4 + 2]; | |
1237 GLubyte col[4]; | |
1238 col[0]= cp->b; col[1]= c
p->g; col[2]= cp->r; col[3]= cp->a; | |
1239 QUATCOPY((unsigned char
*)&varray[elementsize*curface*3+offset], col); | |
1240 cp = &attribs.mcol[b].ar
ray[a*4 + 3]; | |
1241 col[0]= cp->b; col[1]= c
p->g; col[2]= cp->r; col[3]= cp->a; | |
1242 QUATCOPY((unsigned char
*)&varray[elementsize*curface*3+offset+elementsize], col); | |
1243 cp = &attribs.mcol[b].ar
ray[a*4 + 0]; | |
1244 col[0]= cp->b; col[1]= c
p->g; col[2]= cp->r; col[3]= cp->a; | |
1245 QUATCOPY((unsigned char
*)&varray[elementsize*curface*3+offset+elementsize*2], col); | |
1246 offset += sizeof(unsigne
d char)*4; | |
1247 }······· | |
1248 if(attribs.tottang) { | |
1249 float *tang = attribs.ta
ng.array[a*4 + 2]; | |
1250 QUATCOPY((float *)&varra
y[elementsize*curface*3+offset], tang); | |
1251 tang = attribs.tang.arra
y[a*4 + 3]; | |
1252 QUATCOPY((float *)&varra
y[elementsize*curface*3+offset+elementsize], tang); | |
1253 tang = attribs.tang.arra
y[a*4 + 0]; | |
1254 QUATCOPY((float *)&varra
y[elementsize*curface*3+offset+elementsize*2], tang); | |
1255 offset += sizeof(float)*
4; | |
1256 } | |
1257 } | |
1258 curface++; | |
1259 i++; | |
1260 } | |
1261 } | |
1262 numfaces = curface - start; | |
1263 if( numfaces > 0 ) { | |
1264 if( dodraw ) { | |
1265 if( numdata != 0 ) { | |
1266 GPU_buffer_unlock(buffer); | |
1267 GPU_interleaved_attrib_setup(buf
fer,datatypes,numdata); | |
1268 } | |
1269 glDrawArrays(GL_TRIANGLES,start*3,(curfa
ce-start)*3); | |
1270 } | |
1271 } | |
1272 GPU_buffer_unbind(); | |
1273 } | |
1274 GPU_buffer_free( buffer, NULL ); | |
1275 } | |
1276 | |
1277 glShadeModel(GL_FLAT); | |
1278 } | |
1279 | |
1280 static void cdDM_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *at
tribs)) | |
1281 { | |
1282 dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL); | |
1283 } | |
1284 | |
1285 static void cdDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *us
erData, int index), void *userData) | |
1286 { | |
1287 CDDerivedMesh *cddm = (CDDerivedMesh*) dm; | |
1288 MVert *vert = cddm->mvert; | |
1289 MEdge *edge = cddm->medge; | |
1290 int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX); | |
1291 | |
1292 glBegin(GL_LINES); | |
1293 for(i = 0; i < dm->numEdgeData; i++, edge++) { | |
1294 if(index) { | |
1295 orig = *index++; | |
1296 if(setDrawOptions && orig == ORIGINDEX_NONE) continue; | |
1297 } | |
1298 else | |
1299 orig = i; | |
1300 | |
1301 if(!setDrawOptions || setDrawOptions(userData, orig)) { | |
1302 glVertex3fv(vert[edge->v1].co); | |
1303 glVertex3fv(vert[edge->v2].co); | |
1304 } | |
1305 } | |
1306 glEnd(); | |
1307 } | |
1308 | |
1309 static void cdDM_foreachMappedVert( | |
1310 DerivedMesh *dm, | |
1311 void (*func)(void *userData,
int index, float *co, | |
1312
float *no_f, short *no_s), | |
1313 void *userData) | |
1314 { | |
1315 MVert *mv = CDDM_get_verts(dm); | |
1316 int i, orig, *index = DM_get_vert_data_layer(dm, CD_ORIGINDEX); | |
1317 | |
1318 for(i = 0; i < dm->numVertData; i++, mv++) { | |
1319 if(index) { | |
1320 orig = *index++; | |
1321 if(orig == ORIGINDEX_NONE) continue; | |
1322 func(userData, orig, mv->co, NULL, mv->no); | |
1323 } | |
1324 else | |
1325 func(userData, i, mv->co, NULL, mv->no); | |
1326 } | |
1327 } | |
1328 | |
1329 static void cdDM_foreachMappedEdge( | |
1330 DerivedMesh *dm, | |
1331 void (*func)(void *userData,
int index, | |
1332
float *v0co, float *v1co), | |
1333 void *userData) | |
1334 { | |
1335 CDDerivedMesh *cddm = (CDDerivedMesh*) dm; | |
1336 MVert *mv = cddm->mvert; | |
1337 MEdge *med = cddm->medge; | |
1338 int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX); | |
1339 | |
1340 for(i = 0; i < dm->numEdgeData; i++, med++) { | |
1341 if (index) { | |
1342 orig = *index++; | |
1343 if(orig == ORIGINDEX_NONE) continue; | |
1344 func(userData, orig, mv[med->v1].co, mv[med->v2].co); | |
1345 } | |
1346 else | |
1347 func(userData, i, mv[med->v1].co, mv[med->v2].co); | |
1348 } | |
1349 } | |
1350 | |
1351 static void cdDM_foreachMappedFaceCenter( | |
1352 DerivedMesh *dm, | |
1353 void (*func)(void *userData,
int index, | |
1354
float *cent, float *no), | |
1355 void *userData) | |
1356 { | |
1357 CDDerivedMesh *cddm = (CDDerivedMesh*)dm; | |
1358 MVert *mv = cddm->mvert; | |
1359 MFace *mf = cddm->mface; | |
1360 int i, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX); | |
1361 | |
1362 for(i = 0; i < dm->numFaceData; i++, mf++) { | |
1363 float cent[3]; | |
1364 float no[3]; | |
1365 | |
1366 if (index) { | |
1367 orig = *index++; | |
1368 if(orig == ORIGINDEX_NONE) continue; | |
1369 } | |
1370 else | |
1371 orig = i; | |
1372 | |
1373 VECCOPY(cent, mv[mf->v1].co); | |
1374 add_v3_v3(cent, mv[mf->v2].co); | |
1375 add_v3_v3(cent, mv[mf->v3].co); | |
1376 | |
1377 if (mf->v4) { | |
1378 normal_quad_v3( no,mv[mf->v1].co, mv[mf->v2].co, mv[mf->
v3].co, mv[mf->v4].co); | |
1379 add_v3_v3(cent, mv[mf->v4].co); | |
1380 mul_v3_fl(cent, 0.25f); | |
1381 } else { | |
1382 normal_tri_v3( no,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v
3].co); | |
1383 mul_v3_fl(cent, 0.33333333333f); | |
1384 } | |
1385 | |
1386 func(userData, orig, cent, no); | |
1387 } | |
1388 } | |
1389 | |
1390 static void cdDM_free_internal(CDDerivedMesh *cddm) | |
1391 { | |
1392 if(cddm->fmap) MEM_freeN(cddm->fmap); | |
1393 if(cddm->fmap_mem) MEM_freeN(cddm->fmap_mem); | |
1394 } | |
1395 | |
1396 static void cdDM_release(DerivedMesh *dm) | |
1397 { | |
1398 CDDerivedMesh *cddm = (CDDerivedMesh*)dm; | |
1399 | |
1400 if (DM_release(dm)) { | |
1401 cdDM_free_internal(cddm); | |
1402 MEM_freeN(cddm); | |
1403 } | |
1404 } | |
1405 | |
1406 /**************** CDDM interface functions ****************/ | |
1407 static CDDerivedMesh *cdDM_create(const char *desc) | |
1408 { | |
1409 CDDerivedMesh *cddm; | |
1410 DerivedMesh *dm; | |
1411 | |
1412 cddm = MEM_callocN(sizeof(*cddm), desc); | |
1413 dm = &cddm->dm; | |
1414 | |
1415 dm->getMinMax = cdDM_getMinMax; | |
1416 | |
1417 dm->getNumVerts = cdDM_getNumVerts; | |
1418 dm->getNumFaces = cdDM_getNumFaces; | |
1419 dm->getNumEdges = cdDM_getNumEdges; | |
1420 | |
1421 dm->getVert = cdDM_getVert; | |
1422 dm->getEdge = cdDM_getEdge; | |
1423 dm->getFace = cdDM_getFace; | |
1424 dm->copyVertArray = cdDM_copyVertArray; | |
1425 dm->copyEdgeArray = cdDM_copyEdgeArray; | |
1426 dm->copyFaceArray = cdDM_copyFaceArray; | |
1427 dm->getVertData = DM_get_vert_data; | |
1428 dm->getEdgeData = DM_get_edge_data; | |
1429 dm->getFaceData = DM_get_face_data; | |
1430 dm->getVertDataArray = DM_get_vert_data_layer; | |
1431 dm->getEdgeDataArray = DM_get_edge_data_layer; | |
1432 dm->getFaceDataArray = DM_get_face_data_layer; | |
1433 | |
1434 dm->getVertCos = cdDM_getVertCos; | |
1435 dm->getVertCo = cdDM_getVertCo; | |
1436 dm->getVertNo = cdDM_getVertNo; | |
1437 | |
1438 dm->getPBVH = cdDM_getPBVH; | |
1439 dm->getFaceMap = cdDM_getFaceMap; | |
1440 | |
1441 dm->drawVerts = cdDM_drawVerts; | |
1442 | |
1443 dm->drawUVEdges = cdDM_drawUVEdges; | |
1444 dm->drawEdges = cdDM_drawEdges; | |
1445 dm->drawLooseEdges = cdDM_drawLooseEdges; | |
1446 dm->drawMappedEdges = cdDM_drawMappedEdges; | |
1447 | |
1448 dm->drawFacesSolid = cdDM_drawFacesSolid; | |
1449 dm->drawFacesColored = cdDM_drawFacesColored; | |
1450 dm->drawFacesTex = cdDM_drawFacesTex; | |
1451 dm->drawFacesGLSL = cdDM_drawFacesGLSL; | |
1452 dm->drawMappedFaces = cdDM_drawMappedFaces; | |
1453 dm->drawMappedFacesTex = cdDM_drawMappedFacesTex; | |
1454 dm->drawMappedFacesGLSL = cdDM_drawMappedFacesGLSL; | |
1455 | |
1456 dm->foreachMappedVert = cdDM_foreachMappedVert; | |
1457 dm->foreachMappedEdge = cdDM_foreachMappedEdge; | |
1458 dm->foreachMappedFaceCenter = cdDM_foreachMappedFaceCenter; | |
1459 | |
1460 dm->release = cdDM_release; | |
1461 | |
1462 return cddm; | |
1463 } | |
1464 | |
1465 DerivedMesh *CDDM_new(int numVerts, int numEdges, int numFaces) | |
1466 { | |
1467 CDDerivedMesh *cddm = cdDM_create("CDDM_new dm"); | |
1468 DerivedMesh *dm = &cddm->dm; | |
1469 | |
1470 DM_init(dm, DM_TYPE_CDDM, numVerts, numEdges, numFaces); | |
1471 | |
1472 CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVe
rts); | |
1473 CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEd
ges); | |
1474 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numFa
ces); | |
1475 | |
1476 CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts)
; | |
1477 CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges)
; | |
1478 CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numFaces)
; | |
1479 | |
1480 cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT); | |
1481 cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE); | |
1482 cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE); | |
1483 | |
1484 return dm; | |
1485 } | |
1486 | |
1487 DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob)) | |
1488 { | |
1489 CDDerivedMesh *cddm = cdDM_create("CDDM_from_mesh dm"); | |
1490 DerivedMesh *dm = &cddm->dm; | |
1491 CustomDataMask mask = CD_MASK_MESH & (~CD_MASK_MDISPS); | |
1492 int alloctype; | |
1493 | |
1494 /* this does a referenced copy, with an exception for fluidsim */ | |
1495 | |
1496 DM_init(dm, DM_TYPE_CDDM, mesh->totvert, mesh->totedge, mesh->totface); | |
1497 | |
1498 dm->deformedOnly = 1; | |
1499 | |
1500 alloctype= CD_REFERENCE; | |
1501 | |
1502 CustomData_merge(&mesh->vdata, &dm->vertData, mask, alloctype, | |
1503 mesh->totvert); | |
1504 CustomData_merge(&mesh->edata, &dm->edgeData, mask, alloctype, | |
1505 mesh->totedge); | |
1506 CustomData_merge(&mesh->fdata, &dm->faceData, mask, alloctype, | |
1507 mesh->totface); | |
1508 | |
1509 cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT); | |
1510 cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE); | |
1511 cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE); | |
1512 | |
1513 return dm; | |
1514 } | |
1515 | |
1516 DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *UNUSED(me)) | |
1517 { | |
1518 DerivedMesh *dm = CDDM_new(BLI_countlist(&em->verts), | |
1519 BLI_countlist(&em->ed
ges), | |
1520 BLI_countlist(&em->fa
ces)); | |
1521 CDDerivedMesh *cddm = (CDDerivedMesh*)dm; | |
1522 EditVert *eve; | |
1523 EditEdge *eed; | |
1524 EditFace *efa; | |
1525 MVert *mvert = cddm->mvert; | |
1526 MEdge *medge = cddm->medge; | |
1527 MFace *mface = cddm->mface; | |
1528 int i, *index; | |
1529 | |
1530 dm->deformedOnly = 1; | |
1531 | |
1532 CustomData_merge(&em->vdata, &dm->vertData, CD_MASK_DERIVEDMESH, | |
1533 CD_CALLOC, dm->numVertData); | |
1534 /* CustomData_merge(&em->edata, &dm->edgeData, CD_MASK_DERIVEDMESH, | |
1535 CD_CALLOC, dm->numEdgeData); */ | |
1536 CustomData_merge(&em->fdata, &dm->faceData, CD_MASK_DERIVEDMESH, | |
1537 CD_CALLOC, dm->numFaceData); | |
1538 | |
1539 /* set eve->hash to vert index */ | |
1540 for(i = 0, eve = em->verts.first; eve; eve = eve->next, ++i) | |
1541 eve->tmp.l = i; | |
1542 | |
1543 /* Need to be able to mark loose edges */ | |
1544 for(eed = em->edges.first; eed; eed = eed->next) { | |
1545 eed->f2 = 0; | |
1546 } | |
1547 for(efa = em->faces.first; efa; efa = efa->next) { | |
1548 efa->e1->f2 = 1; | |
1549 efa->e2->f2 = 1; | |
1550 efa->e3->f2 = 1; | |
1551 if(efa->e4) efa->e4->f2 = 1; | |
1552 } | |
1553 | |
1554 index = dm->getVertDataArray(dm, CD_ORIGINDEX); | |
1555 for(i = 0, eve = em->verts.first; i < dm->numVertData; | |
1556 i++, eve = eve->next, index++) { | |
1557 MVert *mv = &mvert[i]; | |
1558 | |
1559 VECCOPY(mv->co, eve->co); | |
1560 | |
1561 mv->no[0] = eve->no[0] * 32767.0; | |
1562 mv->no[1] = eve->no[1] * 32767.0; | |
1563 mv->no[2] = eve->no[2] * 32767.0; | |
1564 mv->bweight = (unsigned char) (eve->bweight * 255.0f); | |
1565 | |
1566 mv->flag = 0; | |
1567 | |
1568 *index = i; | |
1569 | |
1570 CustomData_from_em_block(&em->vdata, &dm->vertData, eve->data, i
); | |
1571 } | |
1572 | |
1573 index = dm->getEdgeDataArray(dm, CD_ORIGINDEX); | |
1574 for(i = 0, eed = em->edges.first; i < dm->numEdgeData; | |
1575 i++, eed = eed->next, index++) { | |
1576 MEdge *med = &medge[i]; | |
1577 | |
1578 med->v1 = eed->v1->tmp.l; | |
1579 med->v2 = eed->v2->tmp.l; | |
1580 med->crease = (unsigned char) (eed->crease * 255.0f); | |
1581 med->bweight = (unsigned char) (eed->bweight * 255.0f); | |
1582 med->flag = ME_EDGEDRAW|ME_EDGERENDER; | |
1583 ················ | |
1584 if(eed->seam) med->flag |= ME_SEAM; | |
1585 if(eed->sharp) med->flag |= ME_SHARP; | |
1586 if(!eed->f2) med->flag |= ME_LOOSEEDGE; | |
1587 | |
1588 *index = i; | |
1589 | |
1590 /* CustomData_from_em_block(&em->edata, &dm->edgeData, eed->data
, i); */ | |
1591 } | |
1592 | |
1593 index = dm->getFaceDataArray(dm, CD_ORIGINDEX); | |
1594 for(i = 0, efa = em->faces.first; i < dm->numFaceData; | |
1595 i++, efa = efa->next, index++) { | |
1596 MFace *mf = &mface[i]; | |
1597 | |
1598 mf->v1 = efa->v1->tmp.l; | |
1599 mf->v2 = efa->v2->tmp.l; | |
1600 mf->v3 = efa->v3->tmp.l; | |
1601 mf->v4 = efa->v4 ? efa->v4->tmp.l : 0; | |
1602 mf->mat_nr = efa->mat_nr; | |
1603 mf->flag = efa->flag; | |
1604 | |
1605 *index = i; | |
1606 | |
1607 CustomData_from_em_block(&em->fdata, &dm->faceData, efa->data, i
); | |
1608 test_index_face(mf, &dm->faceData, i, efa->v4?4:3); | |
1609 } | |
1610 | |
1611 return dm; | |
1612 } | |
1613 | |
1614 DerivedMesh *CDDM_from_curve(Object *ob) | |
1615 { | |
1616 return CDDM_from_curve_customDB(ob, &ob->disp); | |
1617 } | |
1618 | |
1619 DerivedMesh *CDDM_from_curve_customDB(Object *ob, ListBase *dispbase) | |
1620 { | |
1621 DerivedMesh *dm; | |
1622 CDDerivedMesh *cddm; | |
1623 MVert *allvert; | |
1624 MEdge *alledge; | |
1625 MFace *allface; | |
1626 int totvert, totedge, totface; | |
1627 | |
1628 if (nurbs_to_mdata_customdb(ob, dispbase, &allvert, &totvert, &alledge, | |
1629 &totedge, &allface, &totface) != 0) { | |
1630 /* Error initializing mdata. This often happens when curve is em
pty */ | |
1631 return CDDM_new(0, 0, 0); | |
1632 } | |
1633 | |
1634 dm = CDDM_new(totvert, totedge, totface); | |
1635 dm->deformedOnly = 1; | |
1636 | |
1637 cddm = (CDDerivedMesh*)dm; | |
1638 | |
1639 memcpy(cddm->mvert, allvert, totvert*sizeof(MVert)); | |
1640 memcpy(cddm->medge, alledge, totedge*sizeof(MEdge)); | |
1641 memcpy(cddm->mface, allface, totface*sizeof(MFace)); | |
1642 | |
1643 MEM_freeN(allvert); | |
1644 MEM_freeN(alledge); | |
1645 MEM_freeN(allface); | |
1646 | |
1647 return dm; | |
1648 } | |
1649 | |
1650 DerivedMesh *CDDM_copy(DerivedMesh *source) | |
1651 { | |
1652 CDDerivedMesh *cddm = cdDM_create("CDDM_copy cddm"); | |
1653 DerivedMesh *dm = &cddm->dm; | |
1654 int numVerts = source->numVertData; | |
1655 int numEdges = source->numEdgeData; | |
1656 int numFaces = source->numFaceData; | |
1657 | |
1658 /* ensure these are created if they are made on demand */ | |
1659 source->getVertDataArray(source, CD_ORIGINDEX); | |
1660 source->getEdgeDataArray(source, CD_ORIGINDEX); | |
1661 source->getFaceDataArray(source, CD_ORIGINDEX); | |
1662 | |
1663 /* this initializes dm, and copies all non mvert/medge/mface layers */ | |
1664 DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numFaces)
; | |
1665 dm->deformedOnly = source->deformedOnly; | |
1666 | |
1667 CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts); | |
1668 CustomData_copy_data(&source->edgeData, &dm->edgeData, 0, 0, numEdges); | |
1669 CustomData_copy_data(&source->faceData, &dm->faceData, 0, 0, numFaces); | |
1670 | |
1671 /* now add mvert/medge/mface layers */ | |
1672 cddm->mvert = source->dupVertArray(source); | |
1673 cddm->medge = source->dupEdgeArray(source); | |
1674 cddm->mface = source->dupFaceArray(source); | |
1675 | |
1676 CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, cddm->mvert, nu
mVerts); | |
1677 CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, cddm->medge, nu
mEdges); | |
1678 CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, cddm->mface, nu
mFaces); | |
1679 | |
1680 return dm; | |
1681 } | |
1682 | |
1683 /* note, the CD_ORIGINDEX layers are all 0, so if there is a direct | |
1684 * relationship betwen mesh data this needs to be set by the caller. */ | |
1685 DerivedMesh *CDDM_from_template(DerivedMesh *source, | |
1686 int numVerts, in
t numEdges, int numFaces) | |
1687 { | |
1688 CDDerivedMesh *cddm = cdDM_create("CDDM_from_template dest"); | |
1689 DerivedMesh *dm = &cddm->dm; | |
1690 | |
1691 /* ensure these are created if they are made on demand */ | |
1692 source->getVertDataArray(source, CD_ORIGINDEX); | |
1693 source->getEdgeDataArray(source, CD_ORIGINDEX); | |
1694 source->getFaceDataArray(source, CD_ORIGINDEX); | |
1695 | |
1696 /* this does a copy of all non mvert/medge/mface layers */ | |
1697 DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numFaces)
; | |
1698 | |
1699 /* now add mvert/medge/mface layers */ | |
1700 CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts)
; | |
1701 CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges)
; | |
1702 CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numFaces)
; | |
1703 | |
1704 if(!CustomData_get_layer(&dm->vertData, CD_ORIGINDEX)) | |
1705 CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NUL
L, numVerts); | |
1706 if(!CustomData_get_layer(&dm->edgeData, CD_ORIGINDEX)) | |
1707 CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NUL
L, numEdges); | |
1708 if(!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX)) | |
1709 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NUL
L, numFaces); | |
1710 | |
1711 cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT); | |
1712 cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE); | |
1713 cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE); | |
1714 | |
1715 return dm; | |
1716 } | |
1717 | |
1718 void CDDM_apply_vert_coords(DerivedMesh *dm, float (*vertCoords)[3]) | |
1719 { | |
1720 CDDerivedMesh *cddm = (CDDerivedMesh*)dm; | |
1721 MVert *vert; | |
1722 int i; | |
1723 | |
1724 /* this will just return the pointer if it wasn't a referenced layer */ | |
1725 vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT); | |
1726 cddm->mvert = vert; | |
1727 | |
1728 for(i = 0; i < dm->numVertData; ++i, ++vert) | |
1729 VECCOPY(vert->co, vertCoords[i]); | |
1730 } | |
1731 | |
1732 void CDDM_apply_vert_normals(DerivedMesh *dm, short (*vertNormals)[3]) | |
1733 { | |
1734 CDDerivedMesh *cddm = (CDDerivedMesh*)dm; | |
1735 MVert *vert; | |
1736 int i; | |
1737 | |
1738 /* this will just return the pointer if it wasn't a referenced layer */ | |
1739 vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT); | |
1740 cddm->mvert = vert; | |
1741 | |
1742 for(i = 0; i < dm->numVertData; ++i, ++vert) | |
1743 VECCOPY(vert->no, vertNormals[i]); | |
1744 } | |
1745 | |
1746 /* adapted from mesh_calc_normals */ | |
1747 void CDDM_calc_normals(DerivedMesh *dm) | |
1748 { | |
1749 CDDerivedMesh *cddm = (CDDerivedMesh*)dm; | |
1750 float (*temp_nors)[3]; | |
1751 float (*face_nors)[3]; | |
1752 int i; | |
1753 int numVerts = dm->numVertData; | |
1754 int numFaces = dm->numFaceData; | |
1755 MFace *mf; | |
1756 MVert *mv; | |
1757 | |
1758 if(numVerts == 0) return; | |
1759 | |
1760 temp_nors = MEM_callocN(numVerts * sizeof(*temp_nors), | |
1761 "CDDM_calc_normals temp_
nors"); | |
1762 | |
1763 /* we don't want to overwrite any referenced layers */ | |
1764 mv = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT); | |
1765 cddm->mvert = mv; | |
1766 | |
1767 /* make a face normal layer if not present */ | |
1768 face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL); | |
1769 if(!face_nors) | |
1770 face_nors = CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_CA
LLOC, | |
1771
NULL, dm->numFaceData); | |
1772 | |
1773 /* calculate face normals and add to vertex normals */ | |
1774 mf = CDDM_get_faces(dm); | |
1775 for(i = 0; i < numFaces; i++, mf++) { | |
1776 float *f_no = face_nors[i]; | |
1777 | |
1778 if(mf->v4) | |
1779 normal_quad_v3( f_no,mv[mf->v1].co, mv[mf->v2].co, mv[mf
->v3].co, mv[mf->v4].co); | |
1780 else | |
1781 normal_tri_v3( f_no,mv[mf->v1].co, mv[mf->v2].co, mv[mf-
>v3].co); | |
1782 ················ | |
1783 add_v3_v3(temp_nors[mf->v1], f_no); | |
1784 add_v3_v3(temp_nors[mf->v2], f_no); | |
1785 add_v3_v3(temp_nors[mf->v3], f_no); | |
1786 if(mf->v4) | |
1787 add_v3_v3(temp_nors[mf->v4], f_no); | |
1788 } | |
1789 | |
1790 /* normalize vertex normals and assign */ | |
1791 for(i = 0; i < numVerts; i++, mv++) { | |
1792 float *no = temp_nors[i]; | |
1793 ················ | |
1794 if (normalize_v3(no) == 0.0) | |
1795 normalize_v3_v3(no, mv->co); | |
1796 | |
1797 normal_float_to_short_v3(mv->no, no); | |
1798 } | |
1799 ········ | |
1800 MEM_freeN(temp_nors); | |
1801 } | |
1802 | |
1803 void CDDM_calc_edges(DerivedMesh *dm) | |
1804 { | |
1805 CDDerivedMesh *cddm = (CDDerivedMesh*)dm; | |
1806 CustomData edgeData; | |
1807 EdgeHashIterator *ehi; | |
1808 MFace *mf = cddm->mface; | |
1809 MEdge *med; | |
1810 EdgeHash *eh = BLI_edgehash_new(); | |
1811 int i, *index, numEdges, maxFaces = dm->numFaceData; | |
1812 | |
1813 for (i = 0; i < maxFaces; i++, mf++) { | |
1814 if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2)) | |
1815 BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL); | |
1816 if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3)) | |
1817 BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL); | |
1818 ················ | |
1819 if (mf->v4) { | |
1820 if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4)) | |
1821 BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL); | |
1822 if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1)) | |
1823 BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL); | |
1824 } else { | |
1825 if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1)) | |
1826 BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL); | |
1827 } | |
1828 } | |
1829 | |
1830 numEdges = BLI_edgehash_size(eh); | |
1831 | |
1832 /* write new edges into a temporary CustomData */ | |
1833 memset(&edgeData, 0, sizeof(edgeData)); | |
1834 CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges); | |
1835 CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges)
; | |
1836 | |
1837 ehi = BLI_edgehashIterator_new(eh); | |
1838 med = CustomData_get_layer(&edgeData, CD_MEDGE); | |
1839 index = CustomData_get_layer(&edgeData, CD_ORIGINDEX); | |
1840 for(i = 0; !BLI_edgehashIterator_isDone(ehi); | |
1841 BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) { | |
1842 BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2)
; | |
1843 | |
1844 med->flag = ME_EDGEDRAW|ME_EDGERENDER; | |
1845 *index = ORIGINDEX_NONE; | |
1846 } | |
1847 BLI_edgehashIterator_free(ehi); | |
1848 | |
1849 /* free old CustomData and assign new one */ | |
1850 CustomData_free(&dm->edgeData, dm->numEdgeData); | |
1851 dm->edgeData = edgeData; | |
1852 dm->numEdgeData = numEdges; | |
1853 | |
1854 cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE); | |
1855 | |
1856 BLI_edgehash_free(eh, NULL); | |
1857 } | |
1858 | |
1859 void CDDM_lower_num_verts(DerivedMesh *dm, int numVerts) | |
1860 { | |
1861 if (numVerts < dm->numVertData) | |
1862 CustomData_free_elem(&dm->vertData, numVerts, dm->numVertData-nu
mVerts); | |
1863 | |
1864 dm->numVertData = numVerts; | |
1865 } | |
1866 | |
1867 void CDDM_lower_num_edges(DerivedMesh *dm, int numEdges) | |
1868 { | |
1869 if (numEdges < dm->numEdgeData) | |
1870 CustomData_free_elem(&dm->edgeData, numEdges, dm->numEdgeData-nu
mEdges); | |
1871 | |
1872 dm->numEdgeData = numEdges; | |
1873 } | |
1874 | |
1875 void CDDM_lower_num_faces(DerivedMesh *dm, int numFaces) | |
1876 { | |
1877 if (numFaces < dm->numFaceData) | |
1878 CustomData_free_elem(&dm->faceData, numFaces, dm->numFaceData-nu
mFaces); | |
1879 | |
1880 dm->numFaceData = numFaces; | |
1881 } | |
1882 | |
1883 MVert *CDDM_get_vert(DerivedMesh *dm, int index) | |
1884 { | |
1885 return &((CDDerivedMesh*)dm)->mvert[index]; | |
1886 } | |
1887 | |
1888 MEdge *CDDM_get_edge(DerivedMesh *dm, int index) | |
1889 { | |
1890 return &((CDDerivedMesh*)dm)->medge[index]; | |
1891 } | |
1892 | |
1893 MFace *CDDM_get_face(DerivedMesh *dm, int index) | |
1894 { | |
1895 return &((CDDerivedMesh*)dm)->mface[index]; | |
1896 } | |
1897 | |
1898 MVert *CDDM_get_verts(DerivedMesh *dm) | |
1899 { | |
1900 return ((CDDerivedMesh*)dm)->mvert; | |
1901 } | |
1902 | |
1903 MEdge *CDDM_get_edges(DerivedMesh *dm) | |
1904 { | |
1905 return ((CDDerivedMesh*)dm)->medge; | |
1906 } | |
1907 | |
1908 MFace *CDDM_get_faces(DerivedMesh *dm) | |
1909 { | |
1910 return ((CDDerivedMesh*)dm)->mface; | |
1911 } | |
1912 | |
LEFT | RIGHT |