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