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