|
Blender
V2.59
|
00001 /* 00002 * $Id: customdata.c 38866 2011-07-31 02:24:06Z nicholasbishop $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2006 Blender Foundation. 00021 * All rights reserved. 00022 * 00023 * The Original Code is: all of this file. 00024 * 00025 * Contributor(s): Ben Batt <benbatt@gmail.com> 00026 * 00027 * ***** END GPL LICENSE BLOCK ***** 00028 * 00029 * Implementation of CustomData. 00030 * 00031 * BKE_customdata.h contains the function prototypes for this file. 00032 * 00033 */ 00034 00040 #include <math.h> 00041 #include <string.h> 00042 #include <assert.h> 00043 00044 #include "MEM_guardedalloc.h" 00045 00046 #include "DNA_meshdata_types.h" 00047 #include "DNA_ID.h" 00048 00049 #include "BLI_blenlib.h" 00050 #include "BLI_path_util.h" 00051 #include "BLI_linklist.h" 00052 #include "BLI_math.h" 00053 #include "BLI_mempool.h" 00054 #include "BLI_utildefines.h" 00055 00056 #include "BKE_customdata.h" 00057 #include "BKE_customdata_file.h" 00058 #include "BKE_global.h" 00059 #include "BKE_main.h" 00060 #include "BKE_utildefines.h" 00061 #include "BKE_multires.h" 00062 00063 /* number of layers to add when growing a CustomData object */ 00064 #define CUSTOMDATA_GROW 5 00065 00066 /********************* Layer type information **********************/ 00067 typedef struct LayerTypeInfo { 00068 int size; /* the memory size of one element of this layer's data */ 00069 const char *structname; /* name of the struct used, for file writing */ 00070 int structnum; /* number of structs per element, for file writing */ 00071 const char *defaultname; /* default layer name */ 00072 00073 /* a function to copy count elements of this layer's data 00074 * (deep copy if appropriate) 00075 * if NULL, memcpy is used 00076 */ 00077 void (*copy)(const void *source, void *dest, int count); 00078 00079 /* a function to free any dynamically allocated components of this 00080 * layer's data (note the data pointer itself should not be freed) 00081 * size should be the size of one element of this layer's data (e.g. 00082 * LayerTypeInfo.size) 00083 */ 00084 void (*free)(void *data, int count, int size); 00085 00086 /* a function to interpolate between count source elements of this 00087 * layer's data and store the result in dest 00088 * if weights == NULL or sub_weights == NULL, they should default to 1 00089 * 00090 * weights gives the weight for each element in sources 00091 * sub_weights gives the sub-element weights for each element in sources 00092 * (there should be (sub element count)^2 weights per element) 00093 * count gives the number of elements in sources 00094 */ 00095 void (*interp)(void **sources, float *weights, float *sub_weights, 00096 int count, void *dest); 00097 00098 /* a function to swap the data in corners of the element */ 00099 void (*swap)(void *data, const int *corner_indices); 00100 00101 /* a function to set a layer's data to default values. if NULL, the 00102 default is assumed to be all zeros */ 00103 void (*set_default)(void *data, int count); 00104 00105 /* a function to read data from a cdf file */ 00106 int (*read)(CDataFile *cdf, void *data, int count); 00107 00108 /* a function to write data to a cdf file */ 00109 int (*write)(CDataFile *cdf, void *data, int count); 00110 00111 /* a function to determine file size */ 00112 size_t (*filesize)(CDataFile *cdf, void *data, int count); 00113 00114 /* a function to validate layer contents depending on 00115 * sub-elements count 00116 */ 00117 void (*validate)(void *source, int sub_elements); 00118 } LayerTypeInfo; 00119 00120 static void layerCopy_mdeformvert(const void *source, void *dest, 00121 int count) 00122 { 00123 int i, size = sizeof(MDeformVert); 00124 00125 memcpy(dest, source, count * size); 00126 00127 for(i = 0; i < count; ++i) { 00128 MDeformVert *dvert = (MDeformVert *)((char *)dest + i * size); 00129 00130 if(dvert->totweight) { 00131 MDeformWeight *dw = MEM_callocN(dvert->totweight * sizeof(*dw), 00132 "layerCopy_mdeformvert dw"); 00133 00134 memcpy(dw, dvert->dw, dvert->totweight * sizeof(*dw)); 00135 dvert->dw = dw; 00136 } 00137 else 00138 dvert->dw = NULL; 00139 } 00140 } 00141 00142 static void layerFree_mdeformvert(void *data, int count, int size) 00143 { 00144 int i; 00145 00146 for(i = 0; i < count; ++i) { 00147 MDeformVert *dvert = (MDeformVert *)((char *)data + i * size); 00148 00149 if(dvert->dw) { 00150 MEM_freeN(dvert->dw); 00151 dvert->dw = NULL; 00152 dvert->totweight = 0; 00153 } 00154 } 00155 } 00156 00157 static void linklist_free_simple(void *link) 00158 { 00159 MEM_freeN(link); 00160 } 00161 00162 static void layerInterp_mdeformvert(void **sources, float *weights, 00163 float *UNUSED(sub_weights), int count, void *dest) 00164 { 00165 MDeformVert *dvert = dest; 00166 LinkNode *dest_dw = NULL; /* a list of lists of MDeformWeight pointers */ 00167 LinkNode *node; 00168 int i, j, totweight; 00169 00170 if(count <= 0) return; 00171 00172 /* build a list of unique def_nrs for dest */ 00173 totweight = 0; 00174 for(i = 0; i < count; ++i) { 00175 MDeformVert *source = sources[i]; 00176 float interp_weight = weights ? weights[i] : 1.0f; 00177 00178 for(j = 0; j < source->totweight; ++j) { 00179 MDeformWeight *dw = &source->dw[j]; 00180 00181 for(node = dest_dw; node; node = node->next) { 00182 MDeformWeight *tmp_dw = (MDeformWeight *)node->link; 00183 00184 if(tmp_dw->def_nr == dw->def_nr) { 00185 tmp_dw->weight += dw->weight * interp_weight; 00186 break; 00187 } 00188 } 00189 00190 /* if this def_nr is not in the list, add it */ 00191 if(!node) { 00192 MDeformWeight *tmp_dw = MEM_callocN(sizeof(*tmp_dw), 00193 "layerInterp_mdeformvert tmp_dw"); 00194 tmp_dw->def_nr = dw->def_nr; 00195 tmp_dw->weight = dw->weight * interp_weight; 00196 BLI_linklist_prepend(&dest_dw, tmp_dw); 00197 totweight++; 00198 } 00199 } 00200 } 00201 00202 /* now we know how many unique deform weights there are, so realloc */ 00203 if(dvert->dw) MEM_freeN(dvert->dw); 00204 00205 if(totweight) { 00206 dvert->dw = MEM_callocN(sizeof(*dvert->dw) * totweight, 00207 "layerInterp_mdeformvert dvert->dw"); 00208 dvert->totweight = totweight; 00209 00210 for(i = 0, node = dest_dw; node; node = node->next, ++i) 00211 dvert->dw[i] = *((MDeformWeight *)node->link); 00212 } 00213 else 00214 memset(dvert, 0, sizeof(*dvert)); 00215 00216 BLI_linklist_free(dest_dw, linklist_free_simple); 00217 } 00218 00219 00220 static void layerInterp_msticky(void **sources, float *weights, 00221 float *UNUSED(sub_weights), int count, void *dest) 00222 { 00223 float co[2], w; 00224 MSticky *mst; 00225 int i; 00226 00227 co[0] = co[1] = 0.0f; 00228 for(i = 0; i < count; i++) { 00229 w = weights ? weights[i] : 1.0f; 00230 mst = (MSticky*)sources[i]; 00231 00232 co[0] += w*mst->co[0]; 00233 co[1] += w*mst->co[1]; 00234 } 00235 00236 mst = (MSticky*)dest; 00237 mst->co[0] = co[0]; 00238 mst->co[1] = co[1]; 00239 } 00240 00241 00242 static void layerCopy_tface(const void *source, void *dest, int count) 00243 { 00244 const MTFace *source_tf = (const MTFace*)source; 00245 MTFace *dest_tf = (MTFace*)dest; 00246 int i; 00247 00248 for(i = 0; i < count; ++i) 00249 dest_tf[i] = source_tf[i]; 00250 } 00251 00252 static void layerInterp_tface(void **sources, float *weights, 00253 float *sub_weights, int count, void *dest) 00254 { 00255 MTFace *tf = dest; 00256 int i, j, k; 00257 float uv[4][2]; 00258 float *sub_weight; 00259 00260 if(count <= 0) return; 00261 00262 memset(uv, 0, sizeof(uv)); 00263 00264 sub_weight = sub_weights; 00265 for(i = 0; i < count; ++i) { 00266 float weight = weights ? weights[i] : 1; 00267 MTFace *src = sources[i]; 00268 00269 for(j = 0; j < 4; ++j) { 00270 if(sub_weights) { 00271 for(k = 0; k < 4; ++k, ++sub_weight) { 00272 float w = (*sub_weight) * weight; 00273 float *tmp_uv = src->uv[k]; 00274 00275 uv[j][0] += tmp_uv[0] * w; 00276 uv[j][1] += tmp_uv[1] * w; 00277 } 00278 } else { 00279 uv[j][0] += src->uv[j][0] * weight; 00280 uv[j][1] += src->uv[j][1] * weight; 00281 } 00282 } 00283 } 00284 00285 *tf = *(MTFace *)sources[0]; 00286 for(j = 0; j < 4; ++j) { 00287 tf->uv[j][0] = uv[j][0]; 00288 tf->uv[j][1] = uv[j][1]; 00289 } 00290 } 00291 00292 static void layerSwap_tface(void *data, const int *corner_indices) 00293 { 00294 MTFace *tf = data; 00295 float uv[4][2]; 00296 static const short pin_flags[4] = 00297 { TF_PIN1, TF_PIN2, TF_PIN3, TF_PIN4 }; 00298 static const char sel_flags[4] = 00299 { TF_SEL1, TF_SEL2, TF_SEL3, TF_SEL4 }; 00300 short unwrap = tf->unwrap & ~(TF_PIN1 | TF_PIN2 | TF_PIN3 | TF_PIN4); 00301 char flag = tf->flag & ~(TF_SEL1 | TF_SEL2 | TF_SEL3 | TF_SEL4); 00302 int j; 00303 00304 for(j = 0; j < 4; ++j) { 00305 int source_index = corner_indices[j]; 00306 00307 uv[j][0] = tf->uv[source_index][0]; 00308 uv[j][1] = tf->uv[source_index][1]; 00309 00310 // swap pinning flags around 00311 if(tf->unwrap & pin_flags[source_index]) { 00312 unwrap |= pin_flags[j]; 00313 } 00314 00315 // swap selection flags around 00316 if(tf->flag & sel_flags[source_index]) { 00317 flag |= sel_flags[j]; 00318 } 00319 } 00320 00321 memcpy(tf->uv, uv, sizeof(tf->uv)); 00322 tf->unwrap = unwrap; 00323 tf->flag = flag; 00324 } 00325 00326 static void layerDefault_tface(void *data, int count) 00327 { 00328 static MTFace default_tf = {{{0, 0}, {1, 0}, {1, 1}, {0, 1}}, NULL, 00329 0, 0, TF_DYNAMIC, 0, 0}; 00330 MTFace *tf = (MTFace*)data; 00331 int i; 00332 00333 for(i = 0; i < count; i++) 00334 tf[i] = default_tf; 00335 } 00336 00337 static void layerCopy_origspace_face(const void *source, void *dest, int count) 00338 { 00339 const OrigSpaceFace *source_tf = (const OrigSpaceFace*)source; 00340 OrigSpaceFace *dest_tf = (OrigSpaceFace*)dest; 00341 int i; 00342 00343 for(i = 0; i < count; ++i) 00344 dest_tf[i] = source_tf[i]; 00345 } 00346 00347 static void layerInterp_origspace_face(void **sources, float *weights, 00348 float *sub_weights, int count, void *dest) 00349 { 00350 OrigSpaceFace *osf = dest; 00351 int i, j, k; 00352 float uv[4][2]; 00353 float *sub_weight; 00354 00355 if(count <= 0) return; 00356 00357 memset(uv, 0, sizeof(uv)); 00358 00359 sub_weight = sub_weights; 00360 for(i = 0; i < count; ++i) { 00361 float weight = weights ? weights[i] : 1; 00362 OrigSpaceFace *src = sources[i]; 00363 00364 for(j = 0; j < 4; ++j) { 00365 if(sub_weights) { 00366 for(k = 0; k < 4; ++k, ++sub_weight) { 00367 float w = (*sub_weight) * weight; 00368 float *tmp_uv = src->uv[k]; 00369 00370 uv[j][0] += tmp_uv[0] * w; 00371 uv[j][1] += tmp_uv[1] * w; 00372 } 00373 } else { 00374 uv[j][0] += src->uv[j][0] * weight; 00375 uv[j][1] += src->uv[j][1] * weight; 00376 } 00377 } 00378 } 00379 00380 *osf = *(OrigSpaceFace *)sources[0]; 00381 for(j = 0; j < 4; ++j) { 00382 osf->uv[j][0] = uv[j][0]; 00383 osf->uv[j][1] = uv[j][1]; 00384 } 00385 } 00386 00387 static void layerSwap_origspace_face(void *data, const int *corner_indices) 00388 { 00389 OrigSpaceFace *osf = data; 00390 float uv[4][2]; 00391 int j; 00392 00393 for(j = 0; j < 4; ++j) { 00394 uv[j][0] = osf->uv[corner_indices[j]][0]; 00395 uv[j][1] = osf->uv[corner_indices[j]][1]; 00396 } 00397 memcpy(osf->uv, uv, sizeof(osf->uv)); 00398 } 00399 00400 static void layerDefault_origspace_face(void *data, int count) 00401 { 00402 static OrigSpaceFace default_osf = {{{0, 0}, {1, 0}, {1, 1}, {0, 1}}}; 00403 OrigSpaceFace *osf = (OrigSpaceFace*)data; 00404 int i; 00405 00406 for(i = 0; i < count; i++) 00407 osf[i] = default_osf; 00408 } 00409 00410 static void layerSwap_mdisps(void *data, const int *ci) 00411 { 00412 MDisps *s = data; 00413 float (*d)[3] = NULL; 00414 int corners, cornersize, S; 00415 00416 if(s->disps) { 00417 int nverts= (ci[1] == 3) ? 4 : 3; /* silly way to know vertex count of face */ 00418 corners= multires_mdisp_corners(s); 00419 cornersize= s->totdisp/corners; 00420 00421 if(corners!=nverts) { 00422 /* happens when face changed vertex count in edit mode 00423 if it happened, just forgot displacement */ 00424 00425 MEM_freeN(s->disps); 00426 s->totdisp= (s->totdisp/corners)*nverts; 00427 s->disps= MEM_callocN(s->totdisp*sizeof(float)*3, "mdisp swap"); 00428 return; 00429 } 00430 00431 d= MEM_callocN(sizeof(float) * 3 * s->totdisp, "mdisps swap"); 00432 00433 for(S = 0; S < corners; S++) 00434 memcpy(d + cornersize*S, s->disps + cornersize*ci[S], cornersize*3*sizeof(float)); 00435 00436 MEM_freeN(s->disps); 00437 s->disps= d; 00438 } 00439 } 00440 00441 static void layerInterp_mdisps(void **sources, float *UNUSED(weights), 00442 float *sub_weights, int count, void *dest) 00443 { 00444 MDisps *d = dest; 00445 MDisps *s = NULL; 00446 int st, stl; 00447 int i, x, y; 00448 int side, S, dst_corners, src_corners; 00449 float crn_weight[4][2]; 00450 float (*sw)[4] = (void*)sub_weights; 00451 float (*disps)[3], (*out)[3]; 00452 00453 /* happens when flipping normals of newly created mesh */ 00454 if(!d->totdisp) 00455 return; 00456 00457 s = sources[0]; 00458 dst_corners = multires_mdisp_corners(d); 00459 src_corners = multires_mdisp_corners(s); 00460 00461 if(sub_weights && count == 2 && src_corners == 3) { 00462 src_corners = multires_mdisp_corners(sources[1]); 00463 00464 /* special case -- converting two triangles to quad */ 00465 if(src_corners == 3 && dst_corners == 4) { 00466 MDisps tris[2]; 00467 int vindex[4] = {0}; 00468 00469 for(i = 0; i < 2; i++) 00470 for(y = 0; y < 4; y++) 00471 for(x = 0; x < 4; x++) 00472 if(sw[x+i*4][y]) 00473 vindex[x] = y; 00474 00475 for(i = 0; i < 2; i++) { 00476 float sw_m4[4][4] = {{0}}; 00477 int a = 7 & ~(1 << vindex[i*2] | 1 << vindex[i*2+1]); 00478 00479 sw_m4[0][vindex[i*2+1]] = 1; 00480 sw_m4[1][vindex[i*2]] = 1; 00481 00482 for(x = 0; x < 3; x++) 00483 if(a & (1 << x)) 00484 sw_m4[2][x] = 1; 00485 00486 tris[i] = *((MDisps*)sources[i]); 00487 tris[i].disps = MEM_dupallocN(tris[i].disps); 00488 layerInterp_mdisps(&sources[i], NULL, (float*)sw_m4, 1, &tris[i]); 00489 } 00490 00491 mdisp_join_tris(d, &tris[0], &tris[1]); 00492 00493 for(i = 0; i < 2; i++) 00494 MEM_freeN(tris[i].disps); 00495 00496 return; 00497 } 00498 } 00499 00500 /* For now, some restrictions on the input */ 00501 if(count != 1 || !sub_weights) { 00502 for(i = 0; i < d->totdisp; ++i) 00503 zero_v3(d->disps[i]); 00504 00505 return; 00506 } 00507 00508 /* Initialize the destination */ 00509 disps = MEM_callocN(3*d->totdisp*sizeof(float), "iterp disps"); 00510 00511 side = sqrt(d->totdisp / dst_corners); 00512 st = (side<<1)-1; 00513 stl = st - 1; 00514 00515 sw= (void*)sub_weights; 00516 for(i = 0; i < 4; ++i) { 00517 crn_weight[i][0] = 0 * sw[i][0] + stl * sw[i][1] + stl * sw[i][2] + 0 * sw[i][3]; 00518 crn_weight[i][1] = 0 * sw[i][0] + 0 * sw[i][1] + stl * sw[i][2] + stl * sw[i][3]; 00519 } 00520 00521 multires_mdisp_smooth_bounds(s); 00522 00523 out = disps; 00524 for(S = 0; S < dst_corners; S++) { 00525 float base[2], axis_x[2], axis_y[2]; 00526 00527 mdisp_apply_weight(S, dst_corners, 0, 0, st, crn_weight, &base[0], &base[1]); 00528 mdisp_apply_weight(S, dst_corners, side-1, 0, st, crn_weight, &axis_x[0], &axis_x[1]); 00529 mdisp_apply_weight(S, dst_corners, 0, side-1, st, crn_weight, &axis_y[0], &axis_y[1]); 00530 00531 sub_v2_v2(axis_x, base); 00532 sub_v2_v2(axis_y, base); 00533 normalize_v2(axis_x); 00534 normalize_v2(axis_y); 00535 00536 for(y = 0; y < side; ++y) { 00537 for(x = 0; x < side; ++x, ++out) { 00538 int crn; 00539 float face_u, face_v, crn_u, crn_v; 00540 00541 mdisp_apply_weight(S, dst_corners, x, y, st, crn_weight, &face_u, &face_v); 00542 crn = mdisp_rot_face_to_quad_crn(src_corners, st, face_u, face_v, &crn_u, &crn_v); 00543 00544 old_mdisps_bilinear((*out), &s->disps[crn*side*side], side, crn_u, crn_v); 00545 mdisp_flip_disp(crn, dst_corners, axis_x, axis_y, *out); 00546 } 00547 } 00548 } 00549 00550 MEM_freeN(d->disps); 00551 d->disps = disps; 00552 } 00553 00554 static void layerCopy_mdisps(const void *source, void *dest, int count) 00555 { 00556 int i; 00557 const MDisps *s = source; 00558 MDisps *d = dest; 00559 00560 for(i = 0; i < count; ++i) { 00561 if(s[i].disps) { 00562 d[i].disps = MEM_dupallocN(s[i].disps); 00563 d[i].totdisp = s[i].totdisp; 00564 } 00565 else { 00566 d[i].disps = NULL; 00567 d[i].totdisp = 0; 00568 } 00569 00570 } 00571 } 00572 00573 static void layerValidate_mdisps(void *data, int sub_elements) 00574 { 00575 MDisps *disps = data; 00576 if(disps->disps) { 00577 int corners = multires_mdisp_corners(disps); 00578 00579 if(corners != sub_elements) { 00580 MEM_freeN(disps->disps); 00581 disps->totdisp = disps->totdisp / corners * sub_elements; 00582 disps->disps = MEM_callocN(3*disps->totdisp*sizeof(float), "layerValidate_mdisps"); 00583 } 00584 } 00585 } 00586 00587 static void layerFree_mdisps(void *data, int count, int UNUSED(size)) 00588 { 00589 int i; 00590 MDisps *d = data; 00591 00592 for(i = 0; i < count; ++i) { 00593 if(d[i].disps) 00594 MEM_freeN(d[i].disps); 00595 d[i].disps = NULL; 00596 d[i].totdisp = 0; 00597 } 00598 } 00599 00600 static int layerRead_mdisps(CDataFile *cdf, void *data, int count) 00601 { 00602 MDisps *d = data; 00603 int i; 00604 00605 for(i = 0; i < count; ++i) { 00606 if(!d[i].disps) 00607 d[i].disps = MEM_callocN(sizeof(float)*3*d[i].totdisp, "mdisps read"); 00608 00609 if(!cdf_read_data(cdf, d[i].totdisp*3*sizeof(float), d[i].disps)) { 00610 printf("failed to read multires displacement %d/%d %d\n", i, count, d[i].totdisp); 00611 return 0; 00612 } 00613 } 00614 00615 return 1; 00616 } 00617 00618 static int layerWrite_mdisps(CDataFile *cdf, void *data, int count) 00619 { 00620 MDisps *d = data; 00621 int i; 00622 00623 for(i = 0; i < count; ++i) { 00624 if(!cdf_write_data(cdf, d[i].totdisp*3*sizeof(float), d[i].disps)) { 00625 printf("failed to write multires displacement %d/%d %d\n", i, count, d[i].totdisp); 00626 return 0; 00627 } 00628 } 00629 00630 return 1; 00631 } 00632 00633 static size_t layerFilesize_mdisps(CDataFile *UNUSED(cdf), void *data, int count) 00634 { 00635 MDisps *d = data; 00636 size_t size = 0; 00637 int i; 00638 00639 for(i = 0; i < count; ++i) 00640 size += d[i].totdisp*3*sizeof(float); 00641 00642 return size; 00643 } 00644 00645 /* --------- */ 00646 00647 static void layerDefault_mloopcol(void *data, int count) 00648 { 00649 static MLoopCol default_mloopcol = {255,255,255,255}; 00650 MLoopCol *mlcol = (MLoopCol*)data; 00651 int i; 00652 for(i = 0; i < count; i++) 00653 mlcol[i] = default_mloopcol; 00654 00655 } 00656 00657 static void layerInterp_mloopcol(void **sources, float *weights, 00658 float *sub_weights, int count, void *dest) 00659 { 00660 MLoopCol *mc = dest; 00661 int i; 00662 float *sub_weight; 00663 struct { 00664 float a; 00665 float r; 00666 float g; 00667 float b; 00668 } col; 00669 col.a = col.r = col.g = col.b = 0; 00670 00671 sub_weight = sub_weights; 00672 for(i = 0; i < count; ++i){ 00673 float weight = weights ? weights[i] : 1; 00674 MLoopCol *src = sources[i]; 00675 if(sub_weights){ 00676 col.a += src->a * (*sub_weight) * weight; 00677 col.r += src->r * (*sub_weight) * weight; 00678 col.g += src->g * (*sub_weight) * weight; 00679 col.b += src->b * (*sub_weight) * weight; 00680 sub_weight++; 00681 } else { 00682 col.a += src->a * weight; 00683 col.r += src->r * weight; 00684 col.g += src->g * weight; 00685 col.b += src->b * weight; 00686 } 00687 } 00688 00689 /* Subdivide smooth or fractal can cause problems without clamping 00690 * although weights should also not cause this situation */ 00691 CLAMP(col.a, 0.0f, 255.0f); 00692 CLAMP(col.r, 0.0f, 255.0f); 00693 CLAMP(col.g, 0.0f, 255.0f); 00694 CLAMP(col.b, 0.0f, 255.0f); 00695 00696 mc->a = (int)col.a; 00697 mc->r = (int)col.r; 00698 mc->g = (int)col.g; 00699 mc->b = (int)col.b; 00700 } 00701 static void layerInterp_mloopuv(void **sources, float *weights, 00702 float *sub_weights, int count, void *dest) 00703 { 00704 MLoopUV *mluv = dest; 00705 int i; 00706 float *sub_weight; 00707 struct { 00708 float u; 00709 float v; 00710 }uv; 00711 uv.u = uv.v = 0.0; 00712 00713 sub_weight = sub_weights; 00714 for(i = 0; i < count; ++i){ 00715 float weight = weights ? weights[i] : 1; 00716 MLoopUV *src = sources[i]; 00717 if(sub_weights){ 00718 uv.u += src->uv[0] * (*sub_weight) * weight; 00719 uv.v += src->uv[1] * (*sub_weight) * weight; 00720 sub_weight++; 00721 } else { 00722 uv.u += src->uv[0] * weight; 00723 uv.v += src->uv[1] * weight; 00724 } 00725 } 00726 mluv->uv[0] = uv.u; 00727 mluv->uv[1] = uv.v; 00728 } 00729 00730 static void layerInterp_mcol(void **sources, float *weights, 00731 float *sub_weights, int count, void *dest) 00732 { 00733 MCol *mc = dest; 00734 int i, j, k; 00735 struct { 00736 float a; 00737 float r; 00738 float g; 00739 float b; 00740 } col[4]; 00741 float *sub_weight; 00742 00743 if(count <= 0) return; 00744 00745 memset(col, 0, sizeof(col)); 00746 00747 sub_weight = sub_weights; 00748 for(i = 0; i < count; ++i) { 00749 float weight = weights ? weights[i] : 1; 00750 00751 for(j = 0; j < 4; ++j) { 00752 if(sub_weights) { 00753 MCol *src = sources[i]; 00754 for(k = 0; k < 4; ++k, ++sub_weight, ++src) { 00755 col[j].a += src->a * (*sub_weight) * weight; 00756 col[j].r += src->r * (*sub_weight) * weight; 00757 col[j].g += src->g * (*sub_weight) * weight; 00758 col[j].b += src->b * (*sub_weight) * weight; 00759 } 00760 } else { 00761 MCol *src = sources[i]; 00762 col[j].a += src[j].a * weight; 00763 col[j].r += src[j].r * weight; 00764 col[j].g += src[j].g * weight; 00765 col[j].b += src[j].b * weight; 00766 } 00767 } 00768 } 00769 00770 for(j = 0; j < 4; ++j) { 00771 00772 /* Subdivide smooth or fractal can cause problems without clamping 00773 * although weights should also not cause this situation */ 00774 CLAMP(col[j].a, 0.0f, 255.0f); 00775 CLAMP(col[j].r, 0.0f, 255.0f); 00776 CLAMP(col[j].g, 0.0f, 255.0f); 00777 CLAMP(col[j].b, 0.0f, 255.0f); 00778 00779 mc[j].a = (int)col[j].a; 00780 mc[j].r = (int)col[j].r; 00781 mc[j].g = (int)col[j].g; 00782 mc[j].b = (int)col[j].b; 00783 } 00784 } 00785 00786 static void layerSwap_mcol(void *data, const int *corner_indices) 00787 { 00788 MCol *mcol = data; 00789 MCol col[4]; 00790 int j; 00791 00792 for(j = 0; j < 4; ++j) 00793 col[j] = mcol[corner_indices[j]]; 00794 00795 memcpy(mcol, col, sizeof(col)); 00796 } 00797 00798 static void layerDefault_mcol(void *data, int count) 00799 { 00800 static MCol default_mcol = {255, 255, 255, 255}; 00801 MCol *mcol = (MCol*)data; 00802 int i; 00803 00804 for(i = 0; i < 4*count; i++) 00805 mcol[i] = default_mcol; 00806 } 00807 00808 00809 00810 static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { 00811 {sizeof(MVert), "MVert", 1, NULL, NULL, NULL, NULL, NULL, NULL}, 00812 {sizeof(MSticky), "MSticky", 1, NULL, NULL, NULL, layerInterp_msticky, NULL, 00813 NULL}, 00814 {sizeof(MDeformVert), "MDeformVert", 1, NULL, layerCopy_mdeformvert, 00815 layerFree_mdeformvert, layerInterp_mdeformvert, NULL, NULL}, 00816 {sizeof(MEdge), "MEdge", 1, NULL, NULL, NULL, NULL, NULL, NULL}, 00817 {sizeof(MFace), "MFace", 1, NULL, NULL, NULL, NULL, NULL, NULL}, 00818 {sizeof(MTFace), "MTFace", 1, "UVTex", layerCopy_tface, NULL, 00819 layerInterp_tface, layerSwap_tface, layerDefault_tface}, 00820 /* 4 MCol structs per face */ 00821 {sizeof(MCol)*4, "MCol", 4, "Col", NULL, NULL, layerInterp_mcol, 00822 layerSwap_mcol, layerDefault_mcol}, 00823 {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, 00824 /* 3 floats per normal vector */ 00825 {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, 00826 {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, 00827 {sizeof(MFloatProperty), "MFloatProperty",1,"Float",NULL,NULL,NULL,NULL}, 00828 {sizeof(MIntProperty), "MIntProperty",1,"Int",NULL,NULL,NULL,NULL}, 00829 {sizeof(MStringProperty), "MStringProperty",1,"String",NULL,NULL,NULL,NULL}, 00830 {sizeof(OrigSpaceFace), "OrigSpaceFace", 1, "UVTex", layerCopy_origspace_face, NULL, 00831 layerInterp_origspace_face, layerSwap_origspace_face, layerDefault_origspace_face}, 00832 {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, 00833 {sizeof(MTexPoly), "MTexPoly", 1, "Face Texture", NULL, NULL, NULL, NULL, NULL}, 00834 {sizeof(MLoopUV), "MLoopUV", 1, "UV coord", NULL, NULL, layerInterp_mloopuv, NULL, NULL}, 00835 {sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, layerDefault_mloopcol}, 00836 {sizeof(float)*4*4, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, 00837 {sizeof(MDisps), "MDisps", 1, NULL, layerCopy_mdisps, 00838 layerFree_mdisps, layerInterp_mdisps, layerSwap_mdisps, NULL, layerRead_mdisps, layerWrite_mdisps, 00839 layerFilesize_mdisps, layerValidate_mdisps}, 00840 {sizeof(MCol)*4, "MCol", 4, "WeightCol", NULL, NULL, layerInterp_mcol, 00841 layerSwap_mcol, layerDefault_mcol}, 00842 {sizeof(MCol)*4, "MCol", 4, "IDCol", NULL, NULL, layerInterp_mcol, 00843 layerSwap_mcol, layerDefault_mcol}, 00844 {sizeof(MCol)*4, "MCol", 4, "TexturedCol", NULL, NULL, layerInterp_mcol, 00845 layerSwap_mcol, layerDefault_mcol}, 00846 {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL} 00847 }; 00848 00849 static const char *LAYERTYPENAMES[CD_NUMTYPES] = { 00850 /* 0-4 */ "CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", 00851 /* 5-9 */ "CDMTFace", "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags", 00852 /* 10-14 */ "CDMFloatProperty", "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco", 00853 /* 15-19 */ "CDMTexPoly", "CDMLoopUV", "CDMloopCol", "CDTangent", "CDMDisps", 00854 /* 20-23 */"CDWeightMCol", "CDIDMCol", "CDTextureMCol", "CDClothOrco" 00855 }; 00856 00857 const CustomDataMask CD_MASK_BAREMESH = 00858 CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE; 00859 const CustomDataMask CD_MASK_MESH = 00860 CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE | 00861 CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MCOL | 00862 CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS; 00863 const CustomDataMask CD_MASK_EDITMESH = 00864 CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | 00865 CD_MASK_MCOL|CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS; 00866 const CustomDataMask CD_MASK_DERIVEDMESH = 00867 CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | 00868 CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_CLOTH_ORCO | 00869 CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_TANGENT | CD_MASK_WEIGHT_MCOL; 00870 const CustomDataMask CD_MASK_BMESH = 00871 CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR; 00872 const CustomDataMask CD_MASK_FACECORNERS = 00873 CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV | 00874 CD_MASK_MLOOPCOL; 00875 00876 00877 static const LayerTypeInfo *layerType_getInfo(int type) 00878 { 00879 if(type < 0 || type >= CD_NUMTYPES) return NULL; 00880 00881 return &LAYERTYPEINFO[type]; 00882 } 00883 00884 static const char *layerType_getName(int type) 00885 { 00886 if(type < 0 || type >= CD_NUMTYPES) return NULL; 00887 00888 return LAYERTYPENAMES[type]; 00889 } 00890 00891 /********************* CustomData functions *********************/ 00892 static void customData_update_offsets(CustomData *data); 00893 00894 static CustomDataLayer *customData_add_layer__internal(CustomData *data, 00895 int type, int alloctype, void *layerdata, int totelem, const char *name); 00896 00897 void CustomData_merge(const struct CustomData *source, struct CustomData *dest, 00898 CustomDataMask mask, int alloctype, int totelem) 00899 { 00900 /*const LayerTypeInfo *typeInfo;*/ 00901 CustomDataLayer *layer, *newlayer; 00902 int i, type, number = 0, lasttype = -1, lastactive = 0, lastrender = 0, lastclone = 0, lastmask = 0, lastflag = 0; 00903 00904 for(i = 0; i < source->totlayer; ++i) { 00905 layer = &source->layers[i]; 00906 /*typeInfo = layerType_getInfo(layer->type);*/ /*UNUSED*/ 00907 00908 type = layer->type; 00909 00910 if (type != lasttype) { 00911 number = 0; 00912 lastactive = layer->active; 00913 lastrender = layer->active_rnd; 00914 lastclone = layer->active_clone; 00915 lastmask = layer->active_mask; 00916 lasttype = type; 00917 lastflag = layer->flag; 00918 } 00919 else 00920 number++; 00921 00922 if(lastflag & CD_FLAG_NOCOPY) continue; 00923 else if(!((int)mask & (int)(1 << (int)type))) continue; 00924 else if(number < CustomData_number_of_layers(dest, type)) continue; 00925 00926 if((alloctype == CD_ASSIGN) && (lastflag & CD_FLAG_NOFREE)) 00927 newlayer = customData_add_layer__internal(dest, type, CD_REFERENCE, 00928 layer->data, totelem, layer->name); 00929 else 00930 newlayer = customData_add_layer__internal(dest, type, alloctype, 00931 layer->data, totelem, layer->name); 00932 00933 if(newlayer) { 00934 newlayer->active = lastactive; 00935 newlayer->active_rnd = lastrender; 00936 newlayer->active_clone = lastclone; 00937 newlayer->active_mask = lastmask; 00938 newlayer->flag |= lastflag & (CD_FLAG_EXTERNAL|CD_FLAG_IN_MEMORY); 00939 } 00940 } 00941 } 00942 00943 void CustomData_copy(const struct CustomData *source, struct CustomData *dest, 00944 CustomDataMask mask, int alloctype, int totelem) 00945 { 00946 memset(dest, 0, sizeof(*dest)); 00947 00948 if(source->external) 00949 dest->external= MEM_dupallocN(source->external); 00950 00951 CustomData_merge(source, dest, mask, alloctype, totelem); 00952 } 00953 00954 static void customData_free_layer__internal(CustomDataLayer *layer, int totelem) 00955 { 00956 const LayerTypeInfo *typeInfo; 00957 00958 if(!(layer->flag & CD_FLAG_NOFREE) && layer->data) { 00959 typeInfo = layerType_getInfo(layer->type); 00960 00961 if(typeInfo->free) 00962 typeInfo->free(layer->data, totelem, typeInfo->size); 00963 00964 if(layer->data) 00965 MEM_freeN(layer->data); 00966 } 00967 } 00968 00969 static void CustomData_external_free(CustomData *data) 00970 { 00971 if(data->external) { 00972 MEM_freeN(data->external); 00973 data->external= NULL; 00974 } 00975 } 00976 00977 void CustomData_free(CustomData *data, int totelem) 00978 { 00979 int i; 00980 00981 for(i = 0; i < data->totlayer; ++i) 00982 customData_free_layer__internal(&data->layers[i], totelem); 00983 00984 if(data->layers) 00985 MEM_freeN(data->layers); 00986 00987 CustomData_external_free(data); 00988 00989 memset(data, 0, sizeof(*data)); 00990 } 00991 00992 static void customData_update_offsets(CustomData *data) 00993 { 00994 const LayerTypeInfo *typeInfo; 00995 int i, offset = 0; 00996 00997 for(i = 0; i < data->totlayer; ++i) { 00998 typeInfo = layerType_getInfo(data->layers[i].type); 00999 01000 data->layers[i].offset = offset; 01001 offset += typeInfo->size; 01002 } 01003 01004 data->totsize = offset; 01005 } 01006 01007 int CustomData_get_layer_index(const CustomData *data, int type) 01008 { 01009 int i; 01010 01011 for(i=0; i < data->totlayer; ++i) 01012 if(data->layers[i].type == type) 01013 return i; 01014 01015 return -1; 01016 } 01017 01018 int CustomData_get_named_layer_index(const CustomData *data, int type, const char *name) 01019 { 01020 int i; 01021 01022 for(i=0; i < data->totlayer; ++i) 01023 if(data->layers[i].type == type && strcmp(data->layers[i].name, name)==0) 01024 return i; 01025 01026 return -1; 01027 } 01028 01029 int CustomData_get_active_layer_index(const CustomData *data, int type) 01030 { 01031 int i; 01032 01033 for(i=0; i < data->totlayer; ++i) 01034 if(data->layers[i].type == type) 01035 return i + data->layers[i].active; 01036 01037 return -1; 01038 } 01039 01040 int CustomData_get_render_layer_index(const CustomData *data, int type) 01041 { 01042 int i; 01043 01044 for(i=0; i < data->totlayer; ++i) 01045 if(data->layers[i].type == type) 01046 return i + data->layers[i].active_rnd; 01047 01048 return -1; 01049 } 01050 01051 int CustomData_get_clone_layer_index(const CustomData *data, int type) 01052 { 01053 int i; 01054 01055 for(i=0; i < data->totlayer; ++i) 01056 if(data->layers[i].type == type) 01057 return i + data->layers[i].active_clone; 01058 01059 return -1; 01060 } 01061 01062 int CustomData_get_stencil_layer_index(const CustomData *data, int type) 01063 { 01064 int i; 01065 01066 for(i=0; i < data->totlayer; ++i) 01067 if(data->layers[i].type == type) 01068 return i + data->layers[i].active_mask; 01069 01070 return -1; 01071 } 01072 01073 int CustomData_get_active_layer(const CustomData *data, int type) 01074 { 01075 int i; 01076 01077 for(i=0; i < data->totlayer; ++i) 01078 if(data->layers[i].type == type) 01079 return data->layers[i].active; 01080 01081 return -1; 01082 } 01083 01084 int CustomData_get_render_layer(const CustomData *data, int type) 01085 { 01086 int i; 01087 01088 for(i=0; i < data->totlayer; ++i) 01089 if(data->layers[i].type == type) 01090 return data->layers[i].active_rnd; 01091 01092 return -1; 01093 } 01094 01095 int CustomData_get_clone_layer(const CustomData *data, int type) 01096 { 01097 int i; 01098 01099 for(i=0; i < data->totlayer; ++i) 01100 if(data->layers[i].type == type) 01101 return data->layers[i].active_clone; 01102 01103 return -1; 01104 } 01105 01106 int CustomData_get_stencil_layer(const CustomData *data, int type) 01107 { 01108 int i; 01109 01110 for(i=0; i < data->totlayer; ++i) 01111 if(data->layers[i].type == type) 01112 return data->layers[i].active_mask; 01113 01114 return -1; 01115 } 01116 01117 void CustomData_set_layer_active(CustomData *data, int type, int n) 01118 { 01119 int i; 01120 01121 for(i=0; i < data->totlayer; ++i) 01122 if(data->layers[i].type == type) 01123 data->layers[i].active = n; 01124 } 01125 01126 void CustomData_set_layer_render(CustomData *data, int type, int n) 01127 { 01128 int i; 01129 01130 for(i=0; i < data->totlayer; ++i) 01131 if(data->layers[i].type == type) 01132 data->layers[i].active_rnd = n; 01133 } 01134 01135 void CustomData_set_layer_clone(CustomData *data, int type, int n) 01136 { 01137 int i; 01138 01139 for(i=0; i < data->totlayer; ++i) 01140 if(data->layers[i].type == type) 01141 data->layers[i].active_clone = n; 01142 } 01143 01144 void CustomData_set_layer_stencil(CustomData *data, int type, int n) 01145 { 01146 int i; 01147 01148 for(i=0; i < data->totlayer; ++i) 01149 if(data->layers[i].type == type) 01150 data->layers[i].active_mask = n; 01151 } 01152 01153 /* for using with an index from CustomData_get_active_layer_index and CustomData_get_render_layer_index */ 01154 void CustomData_set_layer_active_index(CustomData *data, int type, int n) 01155 { 01156 int i; 01157 01158 for(i=0; i < data->totlayer; ++i) 01159 if(data->layers[i].type == type) 01160 data->layers[i].active = n-i; 01161 } 01162 01163 void CustomData_set_layer_render_index(CustomData *data, int type, int n) 01164 { 01165 int i; 01166 01167 for(i=0; i < data->totlayer; ++i) 01168 if(data->layers[i].type == type) 01169 data->layers[i].active_rnd = n-i; 01170 } 01171 01172 void CustomData_set_layer_clone_index(CustomData *data, int type, int n) 01173 { 01174 int i; 01175 01176 for(i=0; i < data->totlayer; ++i) 01177 if(data->layers[i].type == type) 01178 data->layers[i].active_clone = n-i; 01179 } 01180 01181 void CustomData_set_layer_stencil_index(CustomData *data, int type, int n) 01182 { 01183 int i; 01184 01185 for(i=0; i < data->totlayer; ++i) 01186 if(data->layers[i].type == type) 01187 data->layers[i].active_mask = n-i; 01188 } 01189 01190 void CustomData_set_layer_flag(struct CustomData *data, int type, int flag) 01191 { 01192 int i; 01193 01194 for(i=0; i < data->totlayer; ++i) 01195 if(data->layers[i].type == type) 01196 data->layers[i].flag |= flag; 01197 } 01198 01199 static int customData_resize(CustomData *data, int amount) 01200 { 01201 CustomDataLayer *tmp = MEM_callocN(sizeof(*tmp)*(data->maxlayer + amount), 01202 "CustomData->layers"); 01203 if(!tmp) return 0; 01204 01205 data->maxlayer += amount; 01206 if (data->layers) { 01207 memcpy(tmp, data->layers, sizeof(*tmp) * data->totlayer); 01208 MEM_freeN(data->layers); 01209 } 01210 data->layers = tmp; 01211 01212 return 1; 01213 } 01214 01215 static CustomDataLayer *customData_add_layer__internal(CustomData *data, 01216 int type, int alloctype, void *layerdata, int totelem, const char *name) 01217 { 01218 const LayerTypeInfo *typeInfo= layerType_getInfo(type); 01219 int size = typeInfo->size * totelem, flag = 0, index = data->totlayer; 01220 void *newlayerdata; 01221 01222 if (!typeInfo->defaultname && CustomData_has_layer(data, type)) 01223 return &data->layers[CustomData_get_layer_index(data, type)]; 01224 01225 if((alloctype == CD_ASSIGN) || (alloctype == CD_REFERENCE)) { 01226 newlayerdata = layerdata; 01227 } 01228 else { 01229 newlayerdata = MEM_callocN(size, layerType_getName(type)); 01230 if(!newlayerdata) 01231 return NULL; 01232 } 01233 01234 if (alloctype == CD_DUPLICATE) { 01235 if(typeInfo->copy) 01236 typeInfo->copy(layerdata, newlayerdata, totelem); 01237 else 01238 memcpy(newlayerdata, layerdata, size); 01239 } 01240 else if (alloctype == CD_DEFAULT) { 01241 if(typeInfo->set_default) 01242 typeInfo->set_default((char*)newlayerdata, totelem); 01243 } 01244 else if (alloctype == CD_REFERENCE) 01245 flag |= CD_FLAG_NOFREE; 01246 01247 if(index >= data->maxlayer) { 01248 if(!customData_resize(data, CUSTOMDATA_GROW)) { 01249 if(newlayerdata != layerdata) 01250 MEM_freeN(newlayerdata); 01251 return NULL; 01252 } 01253 } 01254 01255 data->totlayer++; 01256 01257 /* keep layers ordered by type */ 01258 for( ; index > 0 && data->layers[index - 1].type > type; --index) 01259 data->layers[index] = data->layers[index - 1]; 01260 01261 data->layers[index].type = type; 01262 data->layers[index].flag = flag; 01263 data->layers[index].data = newlayerdata; 01264 if(name || (name=typeInfo->defaultname)) { 01265 BLI_strncpy(data->layers[index].name, name, 32); 01266 CustomData_set_layer_unique_name(data, index); 01267 } 01268 else 01269 data->layers[index].name[0] = '\0'; 01270 01271 if(index > 0 && data->layers[index-1].type == type) { 01272 data->layers[index].active = data->layers[index-1].active; 01273 data->layers[index].active_rnd = data->layers[index-1].active_rnd; 01274 data->layers[index].active_clone = data->layers[index-1].active_clone; 01275 data->layers[index].active_mask = data->layers[index-1].active_mask; 01276 } else { 01277 data->layers[index].active = 0; 01278 data->layers[index].active_rnd = 0; 01279 data->layers[index].active_clone = 0; 01280 data->layers[index].active_mask = 0; 01281 } 01282 01283 customData_update_offsets(data); 01284 01285 return &data->layers[index]; 01286 } 01287 01288 void *CustomData_add_layer(CustomData *data, int type, int alloctype, 01289 void *layerdata, int totelem) 01290 { 01291 CustomDataLayer *layer; 01292 const LayerTypeInfo *typeInfo= layerType_getInfo(type); 01293 01294 layer = customData_add_layer__internal(data, type, alloctype, layerdata, 01295 totelem, typeInfo->defaultname); 01296 01297 if(layer) 01298 return layer->data; 01299 01300 return NULL; 01301 } 01302 01303 /*same as above but accepts a name*/ 01304 void *CustomData_add_layer_named(CustomData *data, int type, int alloctype, 01305 void *layerdata, int totelem, const char *name) 01306 { 01307 CustomDataLayer *layer; 01308 01309 layer = customData_add_layer__internal(data, type, alloctype, layerdata, 01310 totelem, name); 01311 01312 if(layer) 01313 return layer->data; 01314 01315 return NULL; 01316 } 01317 01318 01319 int CustomData_free_layer(CustomData *data, int type, int totelem, int index) 01320 { 01321 int i; 01322 01323 if (index < 0) return 0; 01324 01325 customData_free_layer__internal(&data->layers[index], totelem); 01326 01327 for (i=index+1; i < data->totlayer; ++i) 01328 data->layers[i-1] = data->layers[i]; 01329 01330 data->totlayer--; 01331 01332 /* if layer was last of type in array, set new active layer */ 01333 if ((index >= data->totlayer) || (data->layers[index].type != type)) { 01334 i = CustomData_get_layer_index(data, type); 01335 01336 if (i >= 0) 01337 for (; i < data->totlayer && data->layers[i].type == type; i++) { 01338 data->layers[i].active--; 01339 data->layers[i].active_rnd--; 01340 data->layers[i].active_clone--; 01341 data->layers[i].active_mask--; 01342 } 01343 } 01344 01345 if (data->totlayer <= data->maxlayer-CUSTOMDATA_GROW) 01346 customData_resize(data, -CUSTOMDATA_GROW); 01347 01348 customData_update_offsets(data); 01349 01350 return 1; 01351 } 01352 01353 int CustomData_free_layer_active(CustomData *data, int type, int totelem) 01354 { 01355 int index = 0; 01356 index = CustomData_get_active_layer_index(data, type); 01357 if (index < 0) return 0; 01358 return CustomData_free_layer(data, type, totelem, index); 01359 } 01360 01361 01362 void CustomData_free_layers(CustomData *data, int type, int totelem) 01363 { 01364 while (CustomData_has_layer(data, type)) 01365 CustomData_free_layer_active(data, type, totelem); 01366 } 01367 01368 int CustomData_has_layer(const CustomData *data, int type) 01369 { 01370 return (CustomData_get_layer_index(data, type) != -1); 01371 } 01372 01373 int CustomData_number_of_layers(const CustomData *data, int type) 01374 { 01375 int i, number = 0; 01376 01377 for(i = 0; i < data->totlayer; i++) 01378 if(data->layers[i].type == type) 01379 number++; 01380 01381 return number; 01382 } 01383 01384 void *CustomData_duplicate_referenced_layer(struct CustomData *data, int type) 01385 { 01386 CustomDataLayer *layer; 01387 int layer_index; 01388 01389 /* get the layer index of the first layer of type */ 01390 layer_index = CustomData_get_active_layer_index(data, type); 01391 if(layer_index < 0) return NULL; 01392 01393 layer = &data->layers[layer_index]; 01394 01395 if (layer->flag & CD_FLAG_NOFREE) { 01396 layer->data = MEM_dupallocN(layer->data); 01397 layer->flag &= ~CD_FLAG_NOFREE; 01398 } 01399 01400 return layer->data; 01401 } 01402 01403 void *CustomData_duplicate_referenced_layer_named(struct CustomData *data, 01404 int type, const char *name) 01405 { 01406 CustomDataLayer *layer; 01407 int layer_index; 01408 01409 /* get the layer index of the desired layer */ 01410 layer_index = CustomData_get_named_layer_index(data, type, name); 01411 if(layer_index < 0) return NULL; 01412 01413 layer = &data->layers[layer_index]; 01414 01415 if (layer->flag & CD_FLAG_NOFREE) { 01416 layer->data = MEM_dupallocN(layer->data); 01417 layer->flag &= ~CD_FLAG_NOFREE; 01418 } 01419 01420 return layer->data; 01421 } 01422 01423 void CustomData_free_temporary(CustomData *data, int totelem) 01424 { 01425 CustomDataLayer *layer; 01426 int i, j; 01427 01428 for(i = 0, j = 0; i < data->totlayer; ++i) { 01429 layer = &data->layers[i]; 01430 01431 if (i != j) 01432 data->layers[j] = data->layers[i]; 01433 01434 if ((layer->flag & CD_FLAG_TEMPORARY) == CD_FLAG_TEMPORARY) 01435 customData_free_layer__internal(layer, totelem); 01436 else 01437 j++; 01438 } 01439 01440 data->totlayer = j; 01441 01442 if(data->totlayer <= data->maxlayer-CUSTOMDATA_GROW) 01443 customData_resize(data, -CUSTOMDATA_GROW); 01444 01445 customData_update_offsets(data); 01446 } 01447 01448 void CustomData_set_only_copy(const struct CustomData *data, 01449 CustomDataMask mask) 01450 { 01451 int i; 01452 01453 for(i = 0; i < data->totlayer; ++i) 01454 if(!((int)mask & (int)(1 << (int)data->layers[i].type))) 01455 data->layers[i].flag |= CD_FLAG_NOCOPY; 01456 } 01457 01458 void CustomData_copy_data(const CustomData *source, CustomData *dest, 01459 int source_index, int dest_index, int count) 01460 { 01461 const LayerTypeInfo *typeInfo; 01462 int src_i, dest_i; 01463 int src_offset; 01464 int dest_offset; 01465 01466 /* copies a layer at a time */ 01467 dest_i = 0; 01468 for(src_i = 0; src_i < source->totlayer; ++src_i) { 01469 01470 /* find the first dest layer with type >= the source type 01471 * (this should work because layers are ordered by type) 01472 */ 01473 while(dest_i < dest->totlayer 01474 && dest->layers[dest_i].type < source->layers[src_i].type) 01475 ++dest_i; 01476 01477 /* if there are no more dest layers, we're done */ 01478 if(dest_i >= dest->totlayer) return; 01479 01480 /* if we found a matching layer, copy the data */ 01481 if(dest->layers[dest_i].type == source->layers[src_i].type) { 01482 char *src_data = source->layers[src_i].data; 01483 char *dest_data = dest->layers[dest_i].data; 01484 01485 typeInfo = layerType_getInfo(source->layers[src_i].type); 01486 01487 src_offset = source_index * typeInfo->size; 01488 dest_offset = dest_index * typeInfo->size; 01489 01490 if(typeInfo->copy) 01491 typeInfo->copy(src_data + src_offset, 01492 dest_data + dest_offset, 01493 count); 01494 else 01495 memcpy(dest_data + dest_offset, 01496 src_data + src_offset, 01497 count * typeInfo->size); 01498 01499 /* if there are multiple source & dest layers of the same type, 01500 * we don't want to copy all source layers to the same dest, so 01501 * increment dest_i 01502 */ 01503 ++dest_i; 01504 } 01505 } 01506 } 01507 01508 void CustomData_free_elem(CustomData *data, int index, int count) 01509 { 01510 int i; 01511 const LayerTypeInfo *typeInfo; 01512 01513 for(i = 0; i < data->totlayer; ++i) { 01514 if(!(data->layers[i].flag & CD_FLAG_NOFREE)) { 01515 typeInfo = layerType_getInfo(data->layers[i].type); 01516 01517 if(typeInfo->free) { 01518 int offset = typeInfo->size * index; 01519 01520 typeInfo->free((char *)data->layers[i].data + offset, 01521 count, typeInfo->size); 01522 } 01523 } 01524 } 01525 } 01526 01527 #define SOURCE_BUF_SIZE 100 01528 01529 void CustomData_interp(const CustomData *source, CustomData *dest, 01530 int *src_indices, float *weights, float *sub_weights, 01531 int count, int dest_index) 01532 { 01533 int src_i, dest_i; 01534 int dest_offset; 01535 int j; 01536 void *source_buf[SOURCE_BUF_SIZE]; 01537 void **sources = source_buf; 01538 01539 /* slow fallback in case we're interpolating a ridiculous number of 01540 * elements 01541 */ 01542 if(count > SOURCE_BUF_SIZE) 01543 sources = MEM_callocN(sizeof(*sources) * count, 01544 "CustomData_interp sources"); 01545 01546 /* interpolates a layer at a time */ 01547 dest_i = 0; 01548 for(src_i = 0; src_i < source->totlayer; ++src_i) { 01549 const LayerTypeInfo *typeInfo= layerType_getInfo(source->layers[src_i].type); 01550 if(!typeInfo->interp) continue; 01551 01552 /* find the first dest layer with type >= the source type 01553 * (this should work because layers are ordered by type) 01554 */ 01555 while(dest_i < dest->totlayer 01556 && dest->layers[dest_i].type < source->layers[src_i].type) 01557 ++dest_i; 01558 01559 /* if there are no more dest layers, we're done */ 01560 if(dest_i >= dest->totlayer) return; 01561 01562 /* if we found a matching layer, copy the data */ 01563 if(dest->layers[dest_i].type == source->layers[src_i].type) { 01564 void *src_data = source->layers[src_i].data; 01565 01566 for(j = 0; j < count; ++j) 01567 sources[j] = (char *)src_data 01568 + typeInfo->size * src_indices[j]; 01569 01570 dest_offset = dest_index * typeInfo->size; 01571 01572 typeInfo->interp(sources, weights, sub_weights, count, 01573 (char *)dest->layers[dest_i].data + dest_offset); 01574 01575 /* if there are multiple source & dest layers of the same type, 01576 * we don't want to copy all source layers to the same dest, so 01577 * increment dest_i 01578 */ 01579 ++dest_i; 01580 } 01581 } 01582 01583 if(count > SOURCE_BUF_SIZE) MEM_freeN(sources); 01584 } 01585 01586 void CustomData_swap(struct CustomData *data, int index, const int *corner_indices) 01587 { 01588 const LayerTypeInfo *typeInfo; 01589 int i; 01590 01591 for(i = 0; i < data->totlayer; ++i) { 01592 typeInfo = layerType_getInfo(data->layers[i].type); 01593 01594 if(typeInfo->swap) { 01595 int offset = typeInfo->size * index; 01596 01597 typeInfo->swap((char *)data->layers[i].data + offset, corner_indices); 01598 } 01599 } 01600 } 01601 01602 void *CustomData_get(const CustomData *data, int index, int type) 01603 { 01604 int offset; 01605 int layer_index; 01606 01607 /* get the layer index of the active layer of type */ 01608 layer_index = CustomData_get_active_layer_index(data, type); 01609 if(layer_index < 0) return NULL; 01610 01611 /* get the offset of the desired element */ 01612 offset = layerType_getInfo(type)->size * index; 01613 01614 return (char *)data->layers[layer_index].data + offset; 01615 } 01616 01617 void *CustomData_get_layer(const CustomData *data, int type) 01618 { 01619 /* get the layer index of the active layer of type */ 01620 int layer_index = CustomData_get_active_layer_index(data, type); 01621 if(layer_index < 0) return NULL; 01622 01623 return data->layers[layer_index].data; 01624 } 01625 01626 void *CustomData_get_layer_n(const CustomData *data, int type, int n) 01627 { 01628 /* get the layer index of the active layer of type */ 01629 int layer_index = CustomData_get_layer_index(data, type); 01630 if(layer_index < 0) return NULL; 01631 01632 return data->layers[layer_index+n].data; 01633 } 01634 01635 void *CustomData_get_layer_named(const struct CustomData *data, int type, 01636 const char *name) 01637 { 01638 int layer_index = CustomData_get_named_layer_index(data, type, name); 01639 if(layer_index < 0) return NULL; 01640 01641 return data->layers[layer_index].data; 01642 } 01643 01644 void *CustomData_set_layer(const CustomData *data, int type, void *ptr) 01645 { 01646 /* get the layer index of the first layer of type */ 01647 int layer_index = CustomData_get_active_layer_index(data, type); 01648 01649 if(layer_index < 0) return NULL; 01650 01651 data->layers[layer_index].data = ptr; 01652 01653 return ptr; 01654 } 01655 01656 void *CustomData_set_layer_n(const struct CustomData *data, int type, int n, void *ptr) 01657 { 01658 /* get the layer index of the first layer of type */ 01659 int layer_index = CustomData_get_layer_index(data, type); 01660 if(layer_index < 0) return NULL; 01661 01662 data->layers[layer_index+n].data = ptr; 01663 01664 return ptr; 01665 } 01666 01667 void CustomData_set(const CustomData *data, int index, int type, void *source) 01668 { 01669 void *dest = CustomData_get(data, index, type); 01670 const LayerTypeInfo *typeInfo = layerType_getInfo(type); 01671 01672 if(!dest) return; 01673 01674 if(typeInfo->copy) 01675 typeInfo->copy(source, dest, 1); 01676 else 01677 memcpy(dest, source, typeInfo->size); 01678 } 01679 01680 /* EditMesh functions */ 01681 01682 void CustomData_em_free_block(CustomData *data, void **block) 01683 { 01684 const LayerTypeInfo *typeInfo; 01685 int i; 01686 01687 if(!*block) return; 01688 01689 for(i = 0; i < data->totlayer; ++i) { 01690 if(!(data->layers[i].flag & CD_FLAG_NOFREE)) { 01691 typeInfo = layerType_getInfo(data->layers[i].type); 01692 01693 if(typeInfo->free) { 01694 int offset = data->layers[i].offset; 01695 typeInfo->free((char*)*block + offset, 1, typeInfo->size); 01696 } 01697 } 01698 } 01699 01700 MEM_freeN(*block); 01701 *block = NULL; 01702 } 01703 01704 static void CustomData_em_alloc_block(CustomData *data, void **block) 01705 { 01706 /* TODO: optimize free/alloc */ 01707 01708 if (*block) 01709 CustomData_em_free_block(data, block); 01710 01711 if (data->totsize > 0) 01712 *block = MEM_callocN(data->totsize, "CustomData EM block"); 01713 else 01714 *block = NULL; 01715 } 01716 01717 void CustomData_em_copy_data(const CustomData *source, CustomData *dest, 01718 void *src_block, void **dest_block) 01719 { 01720 const LayerTypeInfo *typeInfo; 01721 int dest_i, src_i; 01722 01723 if (!*dest_block) 01724 CustomData_em_alloc_block(dest, dest_block); 01725 01726 /* copies a layer at a time */ 01727 dest_i = 0; 01728 for(src_i = 0; src_i < source->totlayer; ++src_i) { 01729 01730 /* find the first dest layer with type >= the source type 01731 * (this should work because layers are ordered by type) 01732 */ 01733 while(dest_i < dest->totlayer 01734 && dest->layers[dest_i].type < source->layers[src_i].type) 01735 ++dest_i; 01736 01737 /* if there are no more dest layers, we're done */ 01738 if(dest_i >= dest->totlayer) return; 01739 01740 /* if we found a matching layer, copy the data */ 01741 if(dest->layers[dest_i].type == source->layers[src_i].type && 01742 strcmp(dest->layers[dest_i].name, source->layers[src_i].name) == 0) { 01743 char *src_data = (char*)src_block + source->layers[src_i].offset; 01744 char *dest_data = (char*)*dest_block + dest->layers[dest_i].offset; 01745 01746 typeInfo = layerType_getInfo(source->layers[src_i].type); 01747 01748 if(typeInfo->copy) 01749 typeInfo->copy(src_data, dest_data, 1); 01750 else 01751 memcpy(dest_data, src_data, typeInfo->size); 01752 01753 /* if there are multiple source & dest layers of the same type, 01754 * we don't want to copy all source layers to the same dest, so 01755 * increment dest_i 01756 */ 01757 ++dest_i; 01758 } 01759 } 01760 } 01761 01762 void CustomData_em_validate_data(CustomData *data, void *block, int sub_elements) 01763 { 01764 int i; 01765 for(i = 0; i < data->totlayer; i++) { 01766 const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[i].type); 01767 char *leayer_data = (char*)block + data->layers[i].offset; 01768 01769 if(typeInfo->validate) 01770 typeInfo->validate(leayer_data, sub_elements); 01771 } 01772 } 01773 01774 void *CustomData_em_get(const CustomData *data, void *block, int type) 01775 { 01776 int layer_index; 01777 01778 /* get the layer index of the first layer of type */ 01779 layer_index = CustomData_get_active_layer_index(data, type); 01780 if(layer_index < 0) return NULL; 01781 01782 return (char *)block + data->layers[layer_index].offset; 01783 } 01784 01785 void *CustomData_em_get_n(const CustomData *data, void *block, int type, int n) 01786 { 01787 int layer_index; 01788 01789 /* get the layer index of the first layer of type */ 01790 layer_index = CustomData_get_layer_index(data, type); 01791 if(layer_index < 0) return NULL; 01792 01793 return (char *)block + data->layers[layer_index+n].offset; 01794 } 01795 01796 void CustomData_em_set(CustomData *data, void *block, int type, void *source) 01797 { 01798 void *dest = CustomData_em_get(data, block, type); 01799 const LayerTypeInfo *typeInfo = layerType_getInfo(type); 01800 01801 if(!dest) return; 01802 01803 if(typeInfo->copy) 01804 typeInfo->copy(source, dest, 1); 01805 else 01806 memcpy(dest, source, typeInfo->size); 01807 } 01808 01809 void CustomData_em_set_n(CustomData *data, void *block, int type, int n, void *source) 01810 { 01811 void *dest = CustomData_em_get_n(data, block, type, n); 01812 const LayerTypeInfo *typeInfo = layerType_getInfo(type); 01813 01814 if(!dest) return; 01815 01816 if(typeInfo->copy) 01817 typeInfo->copy(source, dest, 1); 01818 else 01819 memcpy(dest, source, typeInfo->size); 01820 } 01821 01822 void CustomData_em_interp(CustomData *data, void **src_blocks, float *weights, 01823 float *sub_weights, int count, void *dest_block) 01824 { 01825 int i, j; 01826 void *source_buf[SOURCE_BUF_SIZE]; 01827 void **sources = source_buf; 01828 01829 /* slow fallback in case we're interpolating a ridiculous number of 01830 * elements 01831 */ 01832 if(count > SOURCE_BUF_SIZE) 01833 sources = MEM_callocN(sizeof(*sources) * count, 01834 "CustomData_interp sources"); 01835 01836 /* interpolates a layer at a time */ 01837 for(i = 0; i < data->totlayer; ++i) { 01838 CustomDataLayer *layer = &data->layers[i]; 01839 const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type); 01840 01841 if(typeInfo->interp) { 01842 for(j = 0; j < count; ++j) 01843 sources[j] = (char *)src_blocks[j] + layer->offset; 01844 01845 typeInfo->interp(sources, weights, sub_weights, count, 01846 (char *)dest_block + layer->offset); 01847 } 01848 } 01849 01850 if(count > SOURCE_BUF_SIZE) MEM_freeN(sources); 01851 } 01852 01853 void CustomData_em_set_default(CustomData *data, void **block) 01854 { 01855 const LayerTypeInfo *typeInfo; 01856 int i; 01857 01858 if (!*block) 01859 CustomData_em_alloc_block(data, block); 01860 01861 for(i = 0; i < data->totlayer; ++i) { 01862 int offset = data->layers[i].offset; 01863 01864 typeInfo = layerType_getInfo(data->layers[i].type); 01865 01866 if(typeInfo->set_default) 01867 typeInfo->set_default((char*)*block + offset, 1); 01868 } 01869 } 01870 01871 void CustomData_to_em_block(const CustomData *source, CustomData *dest, 01872 int src_index, void **dest_block) 01873 { 01874 const LayerTypeInfo *typeInfo; 01875 int dest_i, src_i, src_offset; 01876 01877 if (!*dest_block) 01878 CustomData_em_alloc_block(dest, dest_block); 01879 01880 /* copies a layer at a time */ 01881 dest_i = 0; 01882 for(src_i = 0; src_i < source->totlayer; ++src_i) { 01883 01884 /* find the first dest layer with type >= the source type 01885 * (this should work because layers are ordered by type) 01886 */ 01887 while(dest_i < dest->totlayer 01888 && dest->layers[dest_i].type < source->layers[src_i].type) 01889 ++dest_i; 01890 01891 /* if there are no more dest layers, we're done */ 01892 if(dest_i >= dest->totlayer) return; 01893 01894 /* if we found a matching layer, copy the data */ 01895 if(dest->layers[dest_i].type == source->layers[src_i].type) { 01896 int offset = dest->layers[dest_i].offset; 01897 char *src_data = source->layers[src_i].data; 01898 char *dest_data = (char*)*dest_block + offset; 01899 01900 typeInfo = layerType_getInfo(dest->layers[dest_i].type); 01901 src_offset = src_index * typeInfo->size; 01902 01903 if(typeInfo->copy) 01904 typeInfo->copy(src_data + src_offset, dest_data, 1); 01905 else 01906 memcpy(dest_data, src_data + src_offset, typeInfo->size); 01907 01908 /* if there are multiple source & dest layers of the same type, 01909 * we don't want to copy all source layers to the same dest, so 01910 * increment dest_i 01911 */ 01912 ++dest_i; 01913 } 01914 } 01915 } 01916 01917 void CustomData_from_em_block(const CustomData *source, CustomData *dest, 01918 void *src_block, int dest_index) 01919 { 01920 const LayerTypeInfo *typeInfo; 01921 int dest_i, src_i, dest_offset; 01922 01923 /* copies a layer at a time */ 01924 dest_i = 0; 01925 for(src_i = 0; src_i < source->totlayer; ++src_i) { 01926 01927 /* find the first dest layer with type >= the source type 01928 * (this should work because layers are ordered by type) 01929 */ 01930 while(dest_i < dest->totlayer 01931 && dest->layers[dest_i].type < source->layers[src_i].type) 01932 ++dest_i; 01933 01934 /* if there are no more dest layers, we're done */ 01935 if(dest_i >= dest->totlayer) return; 01936 01937 /* if we found a matching layer, copy the data */ 01938 if(dest->layers[dest_i].type == source->layers[src_i].type) { 01939 int offset = source->layers[src_i].offset; 01940 char *src_data = (char*)src_block + offset; 01941 char *dest_data = dest->layers[dest_i].data; 01942 01943 typeInfo = layerType_getInfo(dest->layers[dest_i].type); 01944 dest_offset = dest_index * typeInfo->size; 01945 01946 if(typeInfo->copy) 01947 typeInfo->copy(src_data, dest_data + dest_offset, 1); 01948 else 01949 memcpy(dest_data + dest_offset, src_data, typeInfo->size); 01950 01951 /* if there are multiple source & dest layers of the same type, 01952 * we don't want to copy all source layers to the same dest, so 01953 * increment dest_i 01954 */ 01955 ++dest_i; 01956 } 01957 } 01958 01959 } 01960 01961 /*Bmesh functions*/ 01962 /*needed to convert to/from different face reps*/ 01963 void CustomData_to_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata) 01964 { 01965 int i; 01966 for(i=0; i < fdata->totlayer; i++){ 01967 if(fdata->layers[i].type == CD_MTFACE){ 01968 CustomData_add_layer(pdata, CD_MTEXPOLY, CD_CALLOC, &(fdata->layers[i].name), 0); 01969 CustomData_add_layer(ldata, CD_MLOOPUV, CD_CALLOC, &(fdata->layers[i].name), 0); 01970 } 01971 else if(fdata->layers[i].type == CD_MCOL) 01972 CustomData_add_layer(ldata, CD_MLOOPCOL, CD_CALLOC, &(fdata->layers[i].name), 0); 01973 } 01974 } 01975 void CustomData_from_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata, int total){ 01976 int i; 01977 for(i=0; i < pdata->totlayer; i++){ 01978 if(pdata->layers[i].type == CD_MTEXPOLY) 01979 CustomData_add_layer(fdata, CD_MTFACE, CD_CALLOC, &(pdata->layers[i].name), total); 01980 } 01981 for(i=0; i < ldata->totlayer; i++){ 01982 if(ldata->layers[i].type == CD_MLOOPCOL) 01983 CustomData_add_layer(fdata, CD_MCOL, CD_CALLOC, &(ldata->layers[i].name), total); 01984 } 01985 } 01986 01987 01988 void CustomData_bmesh_init_pool(CustomData *data, int allocsize){ 01989 if(data->totlayer)data->pool = BLI_mempool_create(data->totsize, allocsize, allocsize, 0); 01990 } 01991 01992 void CustomData_bmesh_free_block(CustomData *data, void **block) 01993 { 01994 const LayerTypeInfo *typeInfo; 01995 int i; 01996 01997 if(!*block) return; 01998 for(i = 0; i < data->totlayer; ++i) { 01999 if(!(data->layers[i].flag & CD_FLAG_NOFREE)) { 02000 typeInfo = layerType_getInfo(data->layers[i].type); 02001 02002 if(typeInfo->free) { 02003 int offset = data->layers[i].offset; 02004 typeInfo->free((char*)*block + offset, 1, typeInfo->size); 02005 } 02006 } 02007 } 02008 02009 BLI_mempool_free(data->pool, *block); 02010 *block = NULL; 02011 } 02012 02013 static void CustomData_bmesh_alloc_block(CustomData *data, void **block) 02014 { 02015 02016 if (*block) 02017 CustomData_bmesh_free_block(data, block); 02018 02019 if (data->totsize > 0) 02020 *block = BLI_mempool_calloc(data->pool); 02021 else 02022 *block = NULL; 02023 } 02024 02025 void CustomData_bmesh_copy_data(const CustomData *source, CustomData *dest, 02026 void *src_block, void **dest_block) 02027 { 02028 const LayerTypeInfo *typeInfo; 02029 int dest_i, src_i; 02030 02031 if (!*dest_block) 02032 CustomData_bmesh_alloc_block(dest, dest_block); 02033 02034 /* copies a layer at a time */ 02035 dest_i = 0; 02036 for(src_i = 0; src_i < source->totlayer; ++src_i) { 02037 02038 /* find the first dest layer with type >= the source type 02039 * (this should work because layers are ordered by type) 02040 */ 02041 while(dest_i < dest->totlayer 02042 && dest->layers[dest_i].type < source->layers[src_i].type) 02043 ++dest_i; 02044 02045 /* if there are no more dest layers, we're done */ 02046 if(dest_i >= dest->totlayer) return; 02047 02048 /* if we found a matching layer, copy the data */ 02049 if(dest->layers[dest_i].type == source->layers[src_i].type && 02050 strcmp(dest->layers[dest_i].name, source->layers[src_i].name) == 0) { 02051 char *src_data = (char*)src_block + source->layers[src_i].offset; 02052 char *dest_data = (char*)*dest_block + dest->layers[dest_i].offset; 02053 02054 typeInfo = layerType_getInfo(source->layers[src_i].type); 02055 02056 if(typeInfo->copy) 02057 typeInfo->copy(src_data, dest_data, 1); 02058 else 02059 memcpy(dest_data, src_data, typeInfo->size); 02060 02061 /* if there are multiple source & dest layers of the same type, 02062 * we don't want to copy all source layers to the same dest, so 02063 * increment dest_i 02064 */ 02065 ++dest_i; 02066 } 02067 } 02068 } 02069 02070 /*Bmesh Custom Data Functions. Should replace editmesh ones with these as well, due to more effecient memory alloc*/ 02071 void *CustomData_bmesh_get(const CustomData *data, void *block, int type) 02072 { 02073 int layer_index; 02074 02075 /* get the layer index of the first layer of type */ 02076 layer_index = CustomData_get_active_layer_index(data, type); 02077 if(layer_index < 0) return NULL; 02078 02079 return (char *)block + data->layers[layer_index].offset; 02080 } 02081 02082 void *CustomData_bmesh_get_n(const CustomData *data, void *block, int type, int n) 02083 { 02084 int layer_index; 02085 02086 /* get the layer index of the first layer of type */ 02087 layer_index = CustomData_get_layer_index(data, type); 02088 if(layer_index < 0) return NULL; 02089 02090 return (char *)block + data->layers[layer_index+n].offset; 02091 } 02092 02093 void CustomData_bmesh_set(const CustomData *data, void *block, int type, void *source) 02094 { 02095 void *dest = CustomData_bmesh_get(data, block, type); 02096 const LayerTypeInfo *typeInfo = layerType_getInfo(type); 02097 02098 if(!dest) return; 02099 02100 if(typeInfo->copy) 02101 typeInfo->copy(source, dest, 1); 02102 else 02103 memcpy(dest, source, typeInfo->size); 02104 } 02105 02106 void CustomData_bmesh_set_n(CustomData *data, void *block, int type, int n, void *source) 02107 { 02108 void *dest = CustomData_bmesh_get_n(data, block, type, n); 02109 const LayerTypeInfo *typeInfo = layerType_getInfo(type); 02110 02111 if(!dest) return; 02112 02113 if(typeInfo->copy) 02114 typeInfo->copy(source, dest, 1); 02115 else 02116 memcpy(dest, source, typeInfo->size); 02117 } 02118 02119 void CustomData_bmesh_interp(CustomData *data, void **src_blocks, float *weights, 02120 float *sub_weights, int count, void *dest_block) 02121 { 02122 int i, j; 02123 void *source_buf[SOURCE_BUF_SIZE]; 02124 void **sources = source_buf; 02125 02126 /* slow fallback in case we're interpolating a ridiculous number of 02127 * elements 02128 */ 02129 if(count > SOURCE_BUF_SIZE) 02130 sources = MEM_callocN(sizeof(*sources) * count, 02131 "CustomData_interp sources"); 02132 02133 /* interpolates a layer at a time */ 02134 for(i = 0; i < data->totlayer; ++i) { 02135 CustomDataLayer *layer = &data->layers[i]; 02136 const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type); 02137 if(typeInfo->interp) { 02138 for(j = 0; j < count; ++j) 02139 sources[j] = (char *)src_blocks[j] + layer->offset; 02140 02141 typeInfo->interp(sources, weights, sub_weights, count, 02142 (char *)dest_block + layer->offset); 02143 } 02144 } 02145 02146 if(count > SOURCE_BUF_SIZE) MEM_freeN(sources); 02147 } 02148 02149 void CustomData_bmesh_set_default(CustomData *data, void **block) 02150 { 02151 const LayerTypeInfo *typeInfo; 02152 int i; 02153 02154 if (!*block) 02155 CustomData_bmesh_alloc_block(data, block); 02156 02157 for(i = 0; i < data->totlayer; ++i) { 02158 int offset = data->layers[i].offset; 02159 02160 typeInfo = layerType_getInfo(data->layers[i].type); 02161 02162 if(typeInfo->set_default) 02163 typeInfo->set_default((char*)*block + offset, 1); 02164 } 02165 } 02166 02167 void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest, 02168 int src_index, void **dest_block) 02169 { 02170 const LayerTypeInfo *typeInfo; 02171 int dest_i, src_i, src_offset; 02172 02173 if (!*dest_block) 02174 CustomData_bmesh_alloc_block(dest, dest_block); 02175 02176 /* copies a layer at a time */ 02177 dest_i = 0; 02178 for(src_i = 0; src_i < source->totlayer; ++src_i) { 02179 02180 /* find the first dest layer with type >= the source type 02181 * (this should work because layers are ordered by type) 02182 */ 02183 while(dest_i < dest->totlayer 02184 && dest->layers[dest_i].type < source->layers[src_i].type) 02185 ++dest_i; 02186 02187 /* if there are no more dest layers, we're done */ 02188 if(dest_i >= dest->totlayer) return; 02189 02190 /* if we found a matching layer, copy the data */ 02191 if(dest->layers[dest_i].type == source->layers[src_i].type) { 02192 int offset = dest->layers[dest_i].offset; 02193 char *src_data = source->layers[src_i].data; 02194 char *dest_data = (char*)*dest_block + offset; 02195 02196 typeInfo = layerType_getInfo(dest->layers[dest_i].type); 02197 src_offset = src_index * typeInfo->size; 02198 02199 if(typeInfo->copy) 02200 typeInfo->copy(src_data + src_offset, dest_data, 1); 02201 else 02202 memcpy(dest_data, src_data + src_offset, typeInfo->size); 02203 02204 /* if there are multiple source & dest layers of the same type, 02205 * we don't want to copy all source layers to the same dest, so 02206 * increment dest_i 02207 */ 02208 ++dest_i; 02209 } 02210 } 02211 } 02212 02213 void CustomData_from_bmesh_block(const CustomData *source, CustomData *dest, 02214 void *src_block, int dest_index) 02215 { 02216 const LayerTypeInfo *typeInfo; 02217 int dest_i, src_i, dest_offset; 02218 02219 /* copies a layer at a time */ 02220 dest_i = 0; 02221 for(src_i = 0; src_i < source->totlayer; ++src_i) { 02222 02223 /* find the first dest layer with type >= the source type 02224 * (this should work because layers are ordered by type) 02225 */ 02226 while(dest_i < dest->totlayer 02227 && dest->layers[dest_i].type < source->layers[src_i].type) 02228 ++dest_i; 02229 02230 /* if there are no more dest layers, we're done */ 02231 if(dest_i >= dest->totlayer) return; 02232 02233 /* if we found a matching layer, copy the data */ 02234 if(dest->layers[dest_i].type == source->layers[src_i].type) { 02235 int offset = source->layers[src_i].offset; 02236 char *src_data = (char*)src_block + offset; 02237 char *dest_data = dest->layers[dest_i].data; 02238 02239 typeInfo = layerType_getInfo(dest->layers[dest_i].type); 02240 dest_offset = dest_index * typeInfo->size; 02241 02242 if(typeInfo->copy) 02243 typeInfo->copy(src_data, dest_data + dest_offset, 1); 02244 else 02245 memcpy(dest_data + dest_offset, src_data, typeInfo->size); 02246 02247 /* if there are multiple source & dest layers of the same type, 02248 * we don't want to copy all source layers to the same dest, so 02249 * increment dest_i 02250 */ 02251 ++dest_i; 02252 } 02253 } 02254 02255 } 02256 02257 void CustomData_file_write_info(int type, const char **structname, int *structnum) 02258 { 02259 const LayerTypeInfo *typeInfo = layerType_getInfo(type); 02260 02261 *structname = typeInfo->structname; 02262 *structnum = typeInfo->structnum; 02263 } 02264 02265 int CustomData_sizeof(int type) 02266 { 02267 const LayerTypeInfo *typeInfo = layerType_getInfo(type); 02268 02269 return typeInfo->size; 02270 } 02271 02272 const char *CustomData_layertype_name(int type) 02273 { 02274 return layerType_getName(type); 02275 } 02276 02277 static int CustomData_is_property_layer(int type) 02278 { 02279 if((type == CD_PROP_FLT) || (type == CD_PROP_INT) || (type == CD_PROP_STR)) 02280 return 1; 02281 return 0; 02282 } 02283 02284 static int cd_layer_find_dupe(CustomData *data, const char *name, int type, int index) 02285 { 02286 int i; 02287 /* see if there is a duplicate */ 02288 for(i=0; i<data->totlayer; i++) { 02289 if(i != index) { 02290 CustomDataLayer *layer= &data->layers[i]; 02291 02292 if(CustomData_is_property_layer(type)) { 02293 if(CustomData_is_property_layer(layer->type) && strcmp(layer->name, name)==0) { 02294 return 1; 02295 } 02296 } 02297 else{ 02298 if(i!=index && layer->type==type && strcmp(layer->name, name)==0) { 02299 return 1; 02300 } 02301 } 02302 } 02303 } 02304 02305 return 0; 02306 } 02307 02308 static int customdata_unique_check(void *arg, const char *name) 02309 { 02310 struct {CustomData *data; int type; int index;} *data_arg= arg; 02311 return cd_layer_find_dupe(data_arg->data, name, data_arg->type, data_arg->index); 02312 } 02313 02314 void CustomData_set_layer_unique_name(CustomData *data, int index) 02315 { 02316 CustomDataLayer *nlayer= &data->layers[index]; 02317 const LayerTypeInfo *typeInfo= layerType_getInfo(nlayer->type); 02318 02319 struct {CustomData *data; int type; int index;} data_arg; 02320 data_arg.data= data; 02321 data_arg.type= nlayer->type; 02322 data_arg.index= index; 02323 02324 if (!typeInfo->defaultname) 02325 return; 02326 02327 BLI_uniquename_cb(customdata_unique_check, &data_arg, typeInfo->defaultname, '.', nlayer->name, sizeof(nlayer->name)); 02328 } 02329 02330 int CustomData_verify_versions(struct CustomData *data, int index) 02331 { 02332 const LayerTypeInfo *typeInfo; 02333 CustomDataLayer *layer = &data->layers[index]; 02334 int i, keeplayer = 1; 02335 02336 if (layer->type >= CD_NUMTYPES) { 02337 keeplayer = 0; /* unknown layer type from future version */ 02338 } 02339 else { 02340 typeInfo = layerType_getInfo(layer->type); 02341 02342 if (!typeInfo->defaultname && (index > 0) && 02343 data->layers[index-1].type == layer->type) 02344 keeplayer = 0; /* multiple layers of which we only support one */ 02345 } 02346 02347 if (!keeplayer) { 02348 for (i=index+1; i < data->totlayer; ++i) 02349 data->layers[i-1] = data->layers[i]; 02350 data->totlayer--; 02351 } 02352 02353 return keeplayer; 02354 } 02355 02356 /****************************** External Files *******************************/ 02357 02358 static void customdata_external_filename(char filename[FILE_MAX], ID *id, CustomDataExternal *external) 02359 { 02360 char *path = (id->lib)? id->lib->filepath: G.main->name; 02361 02362 BLI_strncpy(filename, external->filename, FILE_MAX); 02363 BLI_path_abs(filename, path); 02364 } 02365 02366 void CustomData_external_reload(CustomData *data, ID *UNUSED(id), CustomDataMask mask, int totelem) 02367 { 02368 CustomDataLayer *layer; 02369 const LayerTypeInfo *typeInfo; 02370 int i; 02371 02372 for(i=0; i<data->totlayer; i++) { 02373 layer = &data->layers[i]; 02374 typeInfo = layerType_getInfo(layer->type); 02375 02376 if(!(mask & (1<<layer->type))); 02377 else if((layer->flag & CD_FLAG_EXTERNAL) && (layer->flag & CD_FLAG_IN_MEMORY)) { 02378 if(typeInfo->free) 02379 typeInfo->free(layer->data, totelem, typeInfo->size); 02380 layer->flag &= ~CD_FLAG_IN_MEMORY; 02381 } 02382 } 02383 } 02384 02385 void CustomData_external_read(CustomData *data, ID *id, CustomDataMask mask, int totelem) 02386 { 02387 CustomDataExternal *external= data->external; 02388 CustomDataLayer *layer; 02389 CDataFile *cdf; 02390 CDataFileLayer *blay; 02391 char filename[FILE_MAX]; 02392 const LayerTypeInfo *typeInfo; 02393 int i, update = 0; 02394 02395 if(!external) 02396 return; 02397 02398 for(i=0; i<data->totlayer; i++) { 02399 layer = &data->layers[i]; 02400 typeInfo = layerType_getInfo(layer->type); 02401 02402 if(!(mask & (1<<layer->type))); 02403 else if(layer->flag & CD_FLAG_IN_MEMORY); 02404 else if((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read) 02405 update= 1; 02406 } 02407 02408 if(!update) 02409 return; 02410 02411 customdata_external_filename(filename, id, external); 02412 02413 cdf= cdf_create(CDF_TYPE_MESH); 02414 if(!cdf_read_open(cdf, filename)) { 02415 fprintf(stderr, "Failed to read %s layer from %s.\n", layerType_getName(layer->type), filename); 02416 return; 02417 } 02418 02419 for(i=0; i<data->totlayer; i++) { 02420 layer = &data->layers[i]; 02421 typeInfo = layerType_getInfo(layer->type); 02422 02423 if(!(mask & (1<<layer->type))); 02424 else if(layer->flag & CD_FLAG_IN_MEMORY); 02425 else if((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read) { 02426 blay= cdf_layer_find(cdf, layer->type, layer->name); 02427 02428 if(blay) { 02429 if(cdf_read_layer(cdf, blay)) { 02430 if(typeInfo->read(cdf, layer->data, totelem)); 02431 else break; 02432 layer->flag |= CD_FLAG_IN_MEMORY; 02433 } 02434 else 02435 break; 02436 } 02437 } 02438 } 02439 02440 cdf_read_close(cdf); 02441 cdf_free(cdf); 02442 } 02443 02444 void CustomData_external_write(CustomData *data, ID *id, CustomDataMask mask, int totelem, int free) 02445 { 02446 CustomDataExternal *external= data->external; 02447 CustomDataLayer *layer; 02448 CDataFile *cdf; 02449 CDataFileLayer *blay; 02450 const LayerTypeInfo *typeInfo; 02451 int i, update = 0; 02452 char filename[FILE_MAX]; 02453 02454 if(!external) 02455 return; 02456 02457 /* test if there is anything to write */ 02458 for(i=0; i<data->totlayer; i++) { 02459 layer = &data->layers[i]; 02460 typeInfo = layerType_getInfo(layer->type); 02461 02462 if(!(mask & (1<<layer->type))); 02463 else if((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) 02464 update= 1; 02465 } 02466 02467 if(!update) 02468 return; 02469 02470 /* make sure data is read before we try to write */ 02471 CustomData_external_read(data, id, mask, totelem); 02472 customdata_external_filename(filename, id, external); 02473 02474 cdf= cdf_create(CDF_TYPE_MESH); 02475 02476 for(i=0; i<data->totlayer; i++) { 02477 layer = &data->layers[i]; 02478 typeInfo = layerType_getInfo(layer->type); 02479 02480 if((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->filesize) { 02481 if(layer->flag & CD_FLAG_IN_MEMORY) { 02482 cdf_layer_add(cdf, layer->type, layer->name, 02483 typeInfo->filesize(cdf, layer->data, totelem)); 02484 } 02485 else { 02486 cdf_free(cdf); 02487 return; /* read failed for a layer! */ 02488 } 02489 } 02490 } 02491 02492 if(!cdf_write_open(cdf, filename)) { 02493 fprintf(stderr, "Failed to open %s for writing.\n", filename); 02494 return; 02495 } 02496 02497 for(i=0; i<data->totlayer; i++) { 02498 layer = &data->layers[i]; 02499 typeInfo = layerType_getInfo(layer->type); 02500 02501 if((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) { 02502 blay= cdf_layer_find(cdf, layer->type, layer->name); 02503 02504 if(cdf_write_layer(cdf, blay)) { 02505 if(typeInfo->write(cdf, layer->data, totelem)); 02506 else break; 02507 } 02508 else 02509 break; 02510 } 02511 } 02512 02513 if(i != data->totlayer) { 02514 fprintf(stderr, "Failed to write data to %s.\n", filename); 02515 cdf_free(cdf); 02516 return; 02517 } 02518 02519 for(i=0; i<data->totlayer; i++) { 02520 layer = &data->layers[i]; 02521 typeInfo = layerType_getInfo(layer->type); 02522 02523 if((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) { 02524 if(free) { 02525 if(typeInfo->free) 02526 typeInfo->free(layer->data, totelem, typeInfo->size); 02527 layer->flag &= ~CD_FLAG_IN_MEMORY; 02528 } 02529 } 02530 } 02531 02532 cdf_write_close(cdf); 02533 cdf_free(cdf); 02534 } 02535 02536 void CustomData_external_add(CustomData *data, ID *UNUSED(id), int type, int UNUSED(totelem), const char *filename) 02537 { 02538 CustomDataExternal *external= data->external; 02539 CustomDataLayer *layer; 02540 int layer_index; 02541 02542 layer_index = CustomData_get_active_layer_index(data, type); 02543 if(layer_index < 0) return; 02544 02545 layer = &data->layers[layer_index]; 02546 02547 if(layer->flag & CD_FLAG_EXTERNAL) 02548 return; 02549 02550 if(!external) { 02551 external= MEM_callocN(sizeof(CustomDataExternal), "CustomDataExternal"); 02552 data->external= external; 02553 } 02554 BLI_strncpy(external->filename, filename, sizeof(external->filename)); 02555 02556 layer->flag |= CD_FLAG_EXTERNAL|CD_FLAG_IN_MEMORY; 02557 } 02558 02559 void CustomData_external_remove(CustomData *data, ID *id, int type, int totelem) 02560 { 02561 CustomDataExternal *external= data->external; 02562 CustomDataLayer *layer; 02563 //char filename[FILE_MAX]; 02564 int layer_index; // i, remove_file; 02565 02566 layer_index = CustomData_get_active_layer_index(data, type); 02567 if(layer_index < 0) return; 02568 02569 layer = &data->layers[layer_index]; 02570 02571 if(!external) 02572 return; 02573 02574 if(layer->flag & CD_FLAG_EXTERNAL) { 02575 if(!(layer->flag & CD_FLAG_IN_MEMORY)) 02576 CustomData_external_read(data, id, (1<<layer->type), totelem); 02577 02578 layer->flag &= ~CD_FLAG_EXTERNAL; 02579 02580 #if 0 02581 remove_file= 1; 02582 for(i=0; i<data->totlayer; i++) 02583 if(data->layers[i].flag & CD_FLAG_EXTERNAL) 02584 remove_file= 0; 02585 02586 if(remove_file) { 02587 customdata_external_filename(filename, id, external); 02588 cdf_remove(filename); 02589 CustomData_external_free(data); 02590 } 02591 #endif 02592 } 02593 } 02594 02595 int CustomData_external_test(CustomData *data, int type) 02596 { 02597 CustomDataLayer *layer; 02598 int layer_index; 02599 02600 layer_index = CustomData_get_active_layer_index(data, type); 02601 if(layer_index < 0) return 0; 02602 02603 layer = &data->layers[layer_index]; 02604 return (layer->flag & CD_FLAG_EXTERNAL); 02605 } 02606 02607 #if 0 02608 void CustomData_external_remove_object(CustomData *data, ID *id) 02609 { 02610 CustomDataExternal *external= data->external; 02611 char filename[FILE_MAX]; 02612 02613 if(!external) 02614 return; 02615 02616 customdata_external_filename(filename, id, external); 02617 cdf_remove(filename); 02618 CustomData_external_free(data); 02619 } 02620 #endif 02621