LEFT | RIGHT |
(no file at all) | |
1 /* | 1 /* |
2 * ***** BEGIN GPL LICENSE BLOCK ***** | 2 * ***** BEGIN GPL LICENSE BLOCK ***** |
3 * | 3 * |
4 * This program is free software; you can redistribute it and/or | 4 * This program is free software; you can redistribute it and/or |
5 * modify it under the terms of the GNU General Public License | 5 * modify it under the terms of the GNU General Public License |
6 * as published by the Free Software Foundation; either version 2 | 6 * as published by the Free Software Foundation; either version 2 |
7 * of the License, or (at your option) any later version. | 7 * of the License, or (at your option) any later version. |
8 * | 8 * |
9 * This program is distributed in the hope that it will be useful, | 9 * This program is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 const float *sub_weight; | 316 const float *sub_weight; |
317 | 317 |
318 if (count <= 0) return; | 318 if (count <= 0) return; |
319 | 319 |
320 sub_weight = sub_weights; | 320 sub_weight = sub_weights; |
321 for (i = 0; i < count; ++i) { | 321 for (i = 0; i < count; ++i) { |
322 float weight = weights ? weights[i] : 1; | 322 float weight = weights ? weights[i] : 1; |
323 MTFace *src = sources[i]; | 323 MTFace *src = sources[i]; |
324 | 324 |
325 for (j = 0; j < 4; ++j) { | 325 for (j = 0; j < 4; ++j) { |
326 if (sub_weights) { | |
327 for (k = 0; k < 4; ++k, ++sub_weight) { | |
328 madd_v2_v2fl(uv[j], src->uv[k], (*sub_we
ight) * weight); | |
329 } | |
330 } | |
331 else { | |
332 madd_v2_v2fl(uv[j], src->uv[j], weight); | |
333 } | |
334 } | |
335 } | |
336 | |
337 /* delay writing to the destination incase dest is in sources */ | |
338 *tf = *(MTFace *)(*sources); | |
339 memcpy(tf->uv, uv, sizeof(tf->uv)); | |
340 } | |
341 | |
342 static void layerSwap_tface(void *data, const int *corner_indices) | |
343 { | |
344 MTFace *tf = data; | |
345 float uv[4][2]; | |
346 static const short pin_flags[4] = { TF_PIN1, TF_PIN2, TF_PIN3, TF_PIN4 }
; | |
347 static const char sel_flags[4] = { TF_SEL1, TF_SEL2, TF_SEL3, TF_SEL4 }; | |
348 short unwrap = tf->unwrap & ~(TF_PIN1 | TF_PIN2 | TF_PIN3 | TF_PIN4); | |
349 char flag = tf->flag & ~(TF_SEL1 | TF_SEL2 | TF_SEL3 | TF_SEL4); | |
350 int j; | |
351 | |
352 for (j = 0; j < 4; ++j) { | |
353 const int source_index = corner_indices[j]; | |
354 | |
355 copy_v2_v2(uv[j], tf->uv[source_index]); | |
356 | |
357 /* swap pinning flags around */ | |
358 if (tf->unwrap & pin_flags[source_index]) { | |
359 unwrap |= pin_flags[j]; | |
360 } | |
361 | |
362 /* swap selection flags around */ | |
363 if (tf->flag & sel_flags[source_index]) { | |
364 flag |= sel_flags[j]; | |
365 } | |
366 } | |
367 | |
368 memcpy(tf->uv, uv, sizeof(tf->uv)); | |
369 tf->unwrap = unwrap; | |
370 tf->flag = flag; | |
371 } | |
372 | |
373 static void layerDefault_tface(void *data, int count) | 326 static void layerDefault_tface(void *data, int count) |
374 { | 327 { |
375 static MTFace default_tf = {{{0, 0}, {1, 0}, {1, 1}, {0, 1}}, NULL, | 328 static MTFace default_tf = {{{0, 0}, {1, 0}, {1, 1}, {0, 1}}, NULL, |
376 » » 0, 0, TF_DYNAMIC | TF_CONVERTED, 0, 0}; | 329 » » » » » » » 0, 0, TF_DYNAMIC, 0,
0}; |
377 » MTFace *tf = (MTFace *)data; | 330 » MTFace *tf = (MTFace*)data; |
378 int i; | 331 int i; |
379 | 332 |
380 for (i = 0; i < count; i++) | |
381 tf[i] = default_tf; | |
382 } | |
383 | |
384 static void layerCopy_propFloat(const void *source, void *dest, | |
385 int count) | |
386 { | |
387 memcpy(dest, source, sizeof(MFloatProperty) * count); | |
388 } | |
389 | |
390 static void layerCopy_propInt(const void *source, void *dest, | |
391 int count) | |
392 { | |
393 memcpy(dest, source, sizeof(MIntProperty) * count); | |
394 } | |
395 | |
396 static void layerCopy_propString(const void *source, void *dest, | |
397 int count) | |
398 { | |
399 memcpy(dest, source, sizeof(MStringProperty) * count); | |
400 } | |
401 | |
402 static void layerCopy_origspace_face(const void *source, void *dest, int count) | |
403 { | |
404 const OrigSpaceFace *source_tf = (const OrigSpaceFace *)source; | |
405 OrigSpaceFace *dest_tf = (OrigSpaceFace *)dest; | |
406 int i; | |
407 | |
408 for (i = 0; i < count; ++i) | |
409 dest_tf[i] = source_tf[i]; | |
410 } | |
411 | |
412 static void layerInterp_origspace_face(void **sources, const float *weights, | |
413 const float *sub_weights, int count, void
*dest) | |
414 { | |
415 OrigSpaceFace *osf = dest; | |
416 int i, j, k; | |
417 float uv[4][2] = {{0.0f}}; | |
418 const float *sub_weight; | |
419 | |
420 if (count <= 0) return; | |
421 | |
422 sub_weight = sub_weights; | |
423 for (i = 0; i < count; ++i) { | |
424 float weight = weights ? weights[i] : 1; | |
425 OrigSpaceFace *src = sources[i]; | |
426 | |
427 for (j = 0; j < 4; ++j) { | |
428 if (sub_weights) { | |
429 for (k = 0; k < 4; ++k, ++sub_weight) { | |
430 madd_v2_v2fl(uv[j], src->uv[k], (*sub_we
ight) * weight); | |
431 } | |
432 } | |
433 else { | |
434 madd_v2_v2fl(uv[j], src->uv[j], weight); | |
435 } | |
436 } | |
437 } | |
438 | |
439 /* delay writing to the destination incase dest is in sources */ | |
440 | |
441 #if 0 /* no need, this ONLY contains UV's */ | |
442 *osf = *(OrigSpaceFace *)(*sources); | |
443 #endif | |
444 memcpy(osf->uv, uv, sizeof(osf->uv)); | |
445 } | |
446 | |
447 static void layerSwap_origspace_face(void *data, const int *corner_indices) | |
448 { | |
449 OrigSpaceFace *osf = data; | |
450 float uv[4][2]; | |
451 int j; | |
452 | |
453 for (j = 0; j < 4; ++j) { | |
454 copy_v2_v2(uv[j], osf->uv[corner_indices[j]]); | |
455 } | |
456 memcpy(osf->uv, uv, sizeof(osf->uv)); | |
457 } | |
458 | |
459 static void layerDefault_origspace_face(void *data, int count) | |
460 { | |
461 static OrigSpaceFace default_osf = {{{0, 0}, {1, 0}, {1, 1}, {0, 1}}}; | |
462 OrigSpaceFace *osf = (OrigSpaceFace *)data; | |
463 int i; | |
464 | |
465 for (i = 0; i < count; i++) | |
466 osf[i] = default_osf; | |
467 } | |
468 | |
469 static void layerSwap_mdisps(void *data, const int *ci) | |
470 { | |
471 MDisps *s = data; | |
472 float (*d)[3] = NULL; | |
473 int corners, cornersize, S; | |
474 | |
475 if (s->disps) { | |
476 int nverts = (ci[1] == 3) ? 4 : 3; /* silly way to know vertex c
ount of face */ | |
477 corners = multires_mdisp_corners(s); | |
478 cornersize = s->totdisp / corners; | |
479 | |
480 if (corners != nverts) { | |
481 /* happens when face changed vertex count in edit mode | |
482 * if it happened, just forgot displacement */ | |
483 | |
484 MEM_freeN(s->disps); | |
485 s->totdisp = (s->totdisp / corners) * nverts; | |
486 s->disps = MEM_callocN(s->totdisp * sizeof(float) * 3, "
mdisp swap"); | |
487 return; | |
488 } | |
489 | |
490 d = MEM_callocN(sizeof(float) * 3 * s->totdisp, "mdisps swap"); | |
491 | |
492 for (S = 0; S < corners; S++) | |
493 memcpy(d + cornersize * S, s->disps + cornersize * ci[S]
, cornersize * 3 * sizeof(float)); | |
494 ················ | |
495 MEM_freeN(s->disps); | |
496 s->disps = d; | |
497 } | |
498 } | |
499 | |
500 static void layerCopy_mdisps(const void *source, void *dest, int count) | |
501 { | |
502 int i; | |
503 const MDisps *s = source; | |
504 MDisps *d = dest; | |
505 | |
506 for (i = 0; i < count; ++i) { | |
507 if (s[i].disps) { | |
508 d[i].disps = MEM_dupallocN(s[i].disps); | |
509 d[i].hidden = MEM_dupallocN(s[i].hidden); | |
510 d[i].totdisp = s[i].totdisp; | |
511 d[i].level = s[i].level; | |
512 } | |
513 else { | |
514 d[i].disps = NULL; | |
515 d[i].hidden = NULL; | |
516 d[i].totdisp = 0; | |
517 d[i].level = 0; | |
518 } | |
519 ················ | |
520 } | |
521 } | |
522 | |
523 static void layerFree_mdisps(void *data, int count, int UNUSED(size)) | |
524 { | |
525 int i; | |
526 MDisps *d = data; | |
527 | |
528 for (i = 0; i < count; ++i) { | |
529 if (d[i].disps) | |
530 MEM_freeN(d[i].disps); | |
531 if (d[i].hidden) | |
532 MEM_freeN(d[i].hidden); | |
533 d[i].disps = NULL; | |
534 d[i].hidden = NULL; | |
535 d[i].totdisp = 0; | |
536 d[i].level = 0; | |
537 } | |
538 } | |
539 | |
540 static int layerRead_mdisps(CDataFile *cdf, void *data, int count) | |
541 { | |
542 MDisps *d = data; | |
543 int i; | |
544 | |
545 for (i = 0; i < count; ++i) { | |
546 if (!d[i].disps) | |
547 d[i].disps = MEM_callocN(sizeof(float) * 3 * d[i].totdis
p, "mdisps read"); | |
548 | |
549 if (!cdf_read_data(cdf, d[i].totdisp * 3 * sizeof(float), d[i].d
isps)) { | |
550 printf("failed to read multires displacement %d/%d %d\n"
, i, count, d[i].totdisp); | |
551 return 0; | |
552 } | |
553 } | |
554 | |
555 return 1; | |
556 } | |
557 | |
558 static int layerWrite_mdisps(CDataFile *cdf, void *data, int count) | |
559 { | |
560 MDisps *d = data; | |
561 int i; | |
562 | |
563 for (i = 0; i < count; ++i) { | |
564 if (!cdf_write_data(cdf, d[i].totdisp * 3 * sizeof(float), d[i].
disps)) { | |
565 printf("failed to write multires displacement %d/%d %d\n
", i, count, d[i].totdisp); | |
566 return 0; | |
567 } | |
568 } | |
569 | |
570 return 1; | |
571 } | |
572 | |
573 static size_t layerFilesize_mdisps(CDataFile *UNUSED(cdf), void *data, int count
) | |
574 { | |
575 MDisps *d = data; | |
576 size_t size = 0; | |
577 int i; | |
578 | |
579 for (i = 0; i < count; ++i) | |
580 size += d[i].totdisp * 3 * sizeof(float); | |
581 | |
582 return size; | |
583 } | |
584 | |
585 static void layerCopy_grid_paint_mask(const void *source, void *dest, int count) | |
586 { | |
587 int i; | |
588 const GridPaintMask *s = source; | |
589 GridPaintMask *d = dest; | |
590 | |
591 for (i = 0; i < count; ++i) { | |
592 if (s[i].data) { | |
593 d[i].data = MEM_dupallocN(s[i].data); | |
594 d[i].level = s[i].level; | |
595 } | |
596 else { | |
597 d[i].data = NULL; | |
598 d[i].level = 0; | |
599 } | |
600 ················ | |
601 } | |
602 } | |
603 | |
604 static void layerFree_grid_paint_mask(void *data, int count, int UNUSED(size)) | |
605 { | |
606 int i; | |
607 GridPaintMask *gpm = data; | |
608 | |
609 for (i = 0; i < count; ++i) { | |
610 if (gpm[i].data) | |
611 MEM_freeN(gpm[i].data); | |
612 gpm[i].data = NULL; | |
613 gpm[i].level = 0; | |
614 } | |
615 } | |
616 | |
617 /* --------- */ | |
618 static void layerCopyValue_mloopcol(void *source, void *dest) | |
619 { | |
620 MLoopCol *m1 = source, *m2 = dest; | |
621 ········ | |
622 m2->r = m1->r; | |
623 m2->g = m1->g; | |
624 m2->b = m1->b; | |
625 m2->a = m1->a; | |
626 } | |
627 | |
628 static bool layerEqual_mloopcol(void *data1, void *data2) | |
629 { | |
630 MLoopCol *m1 = data1, *m2 = data2; | |
631 float r, g, b, a; | |
632 | |
633 r = m1->r - m2->r; | |
634 g = m1->g - m2->g; | |
635 b = m1->b - m2->b; | |
636 a = m1->a - m2->a; | |
637 | |
638 return r * r + g * g + b * b + a * a < 0.001f; | |
639 } | |
640 | |
641 static void layerMultiply_mloopcol(void *data, float fac) | |
642 { | |
643 MLoopCol *m = data; | |
644 | |
645 m->r = (float)m->r * fac; | |
646 m->g = (float)m->g * fac; | |
647 m->b = (float)m->b * fac; | |
648 m->a = (float)m->a * fac; | |
649 } | |
650 | |
651 static void layerAdd_mloopcol(void *data1, void *data2) | |
652 { | |
653 MLoopCol *m = data1, *m2 = data2; | |
654 | |
655 m->r += m2->r; | |
656 m->g += m2->g; | |
657 m->b += m2->b; | |
658 m->a += m2->a; | |
659 } | |
660 | |
661 static void layerDoMinMax_mloopcol(void *data, void *vmin, void *vmax) | |
662 { | |
663 MLoopCol *m = data; | |
664 MLoopCol *min = vmin, *max = vmax; | |
665 | |
666 if (m->r < min->r) min->r = m->r; | |
667 if (m->g < min->g) min->g = m->g; | |
668 if (m->b < min->b) min->b = m->b; | |
669 if (m->a < min->a) min->a = m->a; | |
670 ········ | |
671 if (m->r > max->r) max->r = m->r; | |
672 if (m->g > max->g) max->g = m->g; | |
673 if (m->b > max->b) max->b = m->b; | |
674 if (m->a > max->a) max->a = m->a; | |
675 } | |
676 | |
677 static void layerInitMinMax_mloopcol(void *vmin, void *vmax) | |
678 { | |
679 MLoopCol *min = vmin, *max = vmax; | |
680 | |
681 min->r = 255; | |
682 min->g = 255; | |
683 min->b = 255; | |
684 min->a = 255; | |
685 | |
686 max->r = 0; | |
687 max->g = 0; | |
688 max->b = 0; | |
689 max->a = 0; | |
690 } | |
691 | |
692 static void layerDefault_mloopcol(void *data, int count) | |
693 { | |
694 MLoopCol default_mloopcol = {255, 255, 255, 255}; | |
695 MLoopCol *mlcol = (MLoopCol *)data; | |
696 int i; | |
697 for (i = 0; i < count; i++) | |
698 mlcol[i] = default_mloopcol; | |
699 | |
700 } | |
701 | |
702 static void layerInterp_mloopcol(void **sources, const float *weights, | |
703 const float *sub_weights, int count, void *dest
) | |
704 { | |
705 MLoopCol *mc = dest; | |
706 int i; | |
707 const float *sub_weight; | |
708 struct { | |
709 float a; | |
710 float r; | |
711 float g; | |
712 float b; | |
713 } col; | |
714 col.a = col.r = col.g = col.b = 0; | |
715 | |
716 sub_weight = sub_weights; | |
717 for (i = 0; i < count; ++i) { | |
718 float weight = weights ? weights[i] : 1; | |
719 MLoopCol *src = sources[i]; | |
720 if (sub_weights) { | |
721 col.r += src->r * (*sub_weight) * weight; | |
722 col.g += src->g * (*sub_weight) * weight; | |
723 col.b += src->b * (*sub_weight) * weight; | |
724 col.a += src->a * (*sub_weight) * weight; | |
725 sub_weight++; | |
726 } | |
727 else { | |
728 col.r += src->r * weight; | |
729 col.g += src->g * weight; | |
730 col.b += src->b * weight; | |
731 col.a += src->a * weight; | |
732 } | |
733 } | |
734 ········ | |
735 /* Subdivide smooth or fractal can cause problems without clamping | |
736 * although weights should also not cause this situation */ | |
737 CLAMP(col.a, 0.0f, 255.0f); | |
738 CLAMP(col.r, 0.0f, 255.0f); | |
739 CLAMP(col.g, 0.0f, 255.0f); | |
740 CLAMP(col.b, 0.0f, 255.0f); | |
741 | |
742 /* delay writing to the destination incase dest is in sources */ | |
743 mc->r = (int)col.r; | |
744 mc->g = (int)col.g; | |
745 mc->b = (int)col.b; | |
746 mc->a = (int)col.a; | |
747 } | |
748 | |
749 static void layerCopyValue_mloopuv(void *source, void *dest) | |
750 { | |
751 MLoopUV *luv1 = source, *luv2 = dest; | |
752 | |
753 copy_v2_v2(luv2->uv, luv1->uv); | |
754 } | |
755 | |
756 static bool layerEqual_mloopuv(void *data1, void *data2) | |
757 { | |
758 MLoopUV *luv1 = data1, *luv2 = data2; | |
759 | |
760 return len_squared_v2v2(luv1->uv, luv2->uv) < 0.00001f; | |
761 } | |
762 | |
763 static void layerMultiply_mloopuv(void *data, float fac) | |
764 { | |
765 MLoopUV *luv = data; | |
766 | |
767 mul_v2_fl(luv->uv, fac); | |
768 } | |
769 | |
770 static void layerInitMinMax_mloopuv(void *vmin, void *vmax) | |
771 { | |
772 MLoopUV *min = vmin, *max = vmax; | |
773 | |
774 INIT_MINMAX2(min->uv, max->uv); | |
775 } | |
776 | |
777 static void layerDoMinMax_mloopuv(void *data, void *vmin, void *vmax) | |
778 { | |
779 MLoopUV *min = vmin, *max = vmax, *luv = data; | |
780 | |
781 minmax_v2v2_v2(min->uv, max->uv, luv->uv); | |
782 } | |
783 | |
784 static void layerAdd_mloopuv(void *data1, void *data2) | |
785 { | |
786 MLoopUV *l1 = data1, *l2 = data2; | |
787 | |
788 add_v2_v2(l1->uv, l2->uv); | |
789 } | |
790 | |
791 static void layerInterp_mloopuv(void **sources, const float *weights, | |
792 const float *sub_weights, int count, void *dest) | |
793 { | |
794 float uv[2]; | |
795 int i; | |
796 | |
797 zero_v2(uv); | |
798 | |
799 if (sub_weights) { | |
800 const float *sub_weight = sub_weights; | |
801 for (i = 0; i < count; i++) { | |
802 float weight = weights ? weights[i] : 1.0f; | |
803 MLoopUV *src = sources[i]; | |
804 madd_v2_v2fl(uv, src->uv, (*sub_weight) * weight); | |
805 sub_weight++; | |
806 } | |
807 } | |
808 else { | |
809 for (i = 0; i < count; i++) { | |
810 float weight = weights ? weights[i] : 1; | |
811 MLoopUV *src = sources[i]; | |
812 madd_v2_v2fl(uv, src->uv, weight); | |
813 } | |
814 } | |
815 | |
816 /* delay writing to the destination incase dest is in sources */ | |
817 copy_v2_v2(((MLoopUV *)dest)->uv, uv); | |
818 } | |
819 | |
820 /* origspace is almost exact copy of mloopuv's, keep in sync */ | |
821 static void layerCopyValue_mloop_origspace(void *source, void *dest) | |
822 { | |
823 OrigSpaceLoop *luv1 = source, *luv2 = dest; | |
824 | |
825 copy_v2_v2(luv2->uv, luv1->uv); | |
826 } | |
827 | |
828 static bool layerEqual_mloop_origspace(void *data1, void *data2) | |
829 { | |
830 OrigSpaceLoop *luv1 = data1, *luv2 = data2; | |
831 | |
832 return len_squared_v2v2(luv1->uv, luv2->uv) < 0.00001f; | |
833 } | |
834 | |
835 static void layerMultiply_mloop_origspace(void *data, float fac) | |
836 { | |
837 OrigSpaceLoop *luv = data; | |
838 | |
839 mul_v2_fl(luv->uv, fac); | |
840 } | |
841 | |
842 static void layerInitMinMax_mloop_origspace(void *vmin, void *vmax) | |
843 { | |
844 OrigSpaceLoop *min = vmin, *max = vmax; | |
845 | |
846 INIT_MINMAX2(min->uv, max->uv); | |
847 } | |
848 | |
849 static void layerDoMinMax_mloop_origspace(void *data, void *vmin, void *vmax) | |
850 { | |
851 OrigSpaceLoop *min = vmin, *max = vmax, *luv = data; | |
852 | |
853 minmax_v2v2_v2(min->uv, max->uv, luv->uv); | |
854 } | |
855 | |
856 static void layerAdd_mloop_origspace(void *data1, void *data2) | |
857 { | |
858 OrigSpaceLoop *l1 = data1, *l2 = data2; | |
859 | |
860 add_v2_v2(l1->uv, l2->uv); | |
861 } | |
862 | |
863 static void layerInterp_mloop_origspace(void **sources, const float *weights, | |
864 const float *sub_weights, int count, voi
d *dest) | |
865 { | |
866 float uv[2]; | |
867 int i; | |
868 | |
869 zero_v2(uv); | |
870 | |
871 if (sub_weights) { | |
872 const float *sub_weight = sub_weights; | |
873 for (i = 0; i < count; i++) { | |
874 float weight = weights ? weights[i] : 1.0f; | |
875 OrigSpaceLoop *src = sources[i]; | |
876 madd_v2_v2fl(uv, src->uv, (*sub_weight) * weight); | |
877 sub_weight++; | |
878 } | |
879 } | |
880 else { | |
881 for (i = 0; i < count; i++) { | |
882 float weight = weights ? weights[i] : 1.0f; | |
883 OrigSpaceLoop *src = sources[i]; | |
884 madd_v2_v2fl(uv, src->uv, weight); | |
885 } | |
886 } | |
887 | |
888 /* delay writing to the destination incase dest is in sources */ | |
889 copy_v2_v2(((OrigSpaceLoop *)dest)->uv, uv); | |
890 } | |
891 /* --- end copy */ | |
892 | |
893 static void layerInterp_mcol(void **sources, const float *weights, | |
894 const float *sub_weights, int count, void *dest) | |
895 { | |
896 MCol *mc = dest; | |
897 int i, j, k; | |
898 struct { | |
899 float a; | |
900 float r; | |
901 float g; | |
902 float b; | |
903 } col[4] = {{0.0f}}; | |
904 | |
905 const float *sub_weight; | |
906 | |
907 if (count <= 0) return; | |
908 ········ | |
909 sub_weight = sub_weights; | |
910 for (i = 0; i < count; ++i) { | |
911 float weight = weights ? weights[i] : 1; | |
912 | |
913 for (j = 0; j < 4; ++j) { | |
914 if (sub_weights) { | |
915 MCol *src = sources[i]; | |
916 for (k = 0; k < 4; ++k, ++sub_weight, ++src) { | |
917 const float w = (*sub_weight) * weight; | |
918 col[j].a += src->a * w; | |
919 col[j].r += src->r * w; | |
920 col[j].g += src->g * w; | |
921 col[j].b += src->b * w; | |
922 } | |
923 } | |
924 else { | |
925 MCol *src = sources[i]; | |
926 col[j].a += src[j].a * weight; | |
927 col[j].r += src[j].r * weight; | |
928 col[j].g += src[j].g * weight; | |
929 col[j].b += src[j].b * weight; | |
930 } | |
931 } | |
932 } | |
933 | |
934 /* delay writing to the destination incase dest is in sources */ | |
935 for (j = 0; j < 4; ++j) { | |
936 ················ | |
937 /* Subdivide smooth or fractal can cause problems without clampi
ng | |
938 * although weights should also not cause this situation */ | |
939 CLAMP(col[j].a, 0.0f, 255.0f); | |
940 CLAMP(col[j].r, 0.0f, 255.0f); | |
941 CLAMP(col[j].g, 0.0f, 255.0f); | |
942 CLAMP(col[j].b, 0.0f, 255.0f); | |
943 ················ | |
944 mc[j].a = (int)col[j].a; | |
945 mc[j].r = (int)col[j].r; | |
946 mc[j].g = (int)col[j].g; | |
947 mc[j].b = (int)col[j].b; | |
948 } | |
949 } | |
950 | |
951 static void layerSwap_mcol(void *data, const int *corner_indices) | |
952 { | |
953 MCol *mcol = data; | |
954 MCol col[4]; | |
955 int j; | |
956 | |
957 for (j = 0; j < 4; ++j) | |
958 col[j] = mcol[corner_indices[j]]; | |
959 | |
960 memcpy(mcol, col, sizeof(col)); | |
961 } | |
962 | |
963 static void layerDefault_mcol(void *data, int count) | |
964 { | |
965 static MCol default_mcol = {255, 255, 255, 255}; | |
966 MCol *mcol = (MCol *)data; | |
967 int i; | |
968 | |
969 for (i = 0; i < 4 * count; i++) { | |
970 mcol[i] = default_mcol; | |
971 } | |
972 } | |
973 | |
974 static void layerDefault_origindex(void *data, int count) | |
975 { | |
976 fill_vn_i((int *)data, count, ORIGINDEX_NONE); | |
977 } | |
978 | |
979 static void layerInterp_bweight(void **sources, const float *weights, | |
980 const float *UNUSED(sub_weights), int count, voi
d *dest) | |
981 { | |
982 float f; | |
983 float **in = (float **)sources; | |
984 int i; | |
985 ········ | |
986 if (count <= 0) return; | |
987 | |
988 f = 0.0f; | |
989 | |
990 if (weights) { | |
991 for (i = 0; i < count; ++i) { | |
992 f += *in[i] * weights[i]; | |
993 } | |
994 } | |
995 else { | |
996 for (i = 0; i < count; ++i) { | |
997 f += *in[i]; | |
998 } | |
999 } | |
1000 | |
1001 /* delay writing to the destination incase dest is in sources */ | |
1002 *((float *)dest) = f; | |
1003 } | |
1004 | |
1005 static void layerInterp_shapekey(void **sources, const float *weights, | |
1006 const float *UNUSED(sub_weights), int count, vo
id *dest) | |
1007 { | |
1008 float co[3]; | |
1009 float **in = (float **)sources; | |
1010 int i; | |
1011 | |
1012 if (count <= 0) return; | |
1013 | |
1014 zero_v3(co); | |
1015 | |
1016 if (weights) { | |
1017 for (i = 0; i < count; ++i) { | |
1018 madd_v3_v3fl(co, in[i], weights[i]); | |
1019 } | |
1020 } | |
1021 else { | |
1022 for (i = 0; i < count; ++i) { | |
1023 add_v3_v3(co, in[i]); | |
1024 } | |
1025 } | |
1026 | |
1027 /* delay writing to the destination incase dest is in sources */ | |
1028 copy_v3_v3((float *)dest, co); | |
1029 } | |
1030 | |
1031 static void layerDefault_mvert_skin(void *data, int count) | |
1032 { | |
1033 MVertSkin *vs = data; | |
1034 int i; | |
1035 ········ | |
1036 for (i = 0; i < count; i++) { | |
1037 copy_v3_fl(vs[i].radius, 0.25f); | |
1038 vs[i].flag = 0; | |
1039 } | |
1040 } | |
1041 | |
1042 static void layerInterp_mvert_skin(void **sources, const float *weights, | |
1043 const float *UNUSED(sub_weights), | |
1044 int count, void *dest) | |
1045 { | |
1046 float radius[3], w; | |
1047 MVertSkin *vs; | |
1048 int i; | |
1049 | |
1050 zero_v3(radius); | |
1051 for (i = 0; i < count; i++) { | |
1052 w = weights ? weights[i] : 1.0f; | |
1053 vs = sources[i]; | |
1054 | |
1055 madd_v3_v3fl(radius, vs->radius, w); | |
1056 } | |
1057 | |
1058 /* delay writing to the destination incase dest is in sources */ | |
1059 vs = dest; | |
1060 copy_v3_v3(vs->radius, radius); | |
1061 vs->flag &= ~MVERT_SKIN_ROOT; | |
1062 } | |
1063 | |
1064 static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { | |
1065 /* 0: CD_MVERT */ | |
1066 {sizeof(MVert), "MVert", 1, NULL, NULL, NULL, NULL, NULL, NULL}, | |
1067 /* 1: CD_MSTICKY */ /* DEPRECATED */ | |
1068 {sizeof(float) * 2, "", 1, NULL, NULL, NULL, NULL, NULL, | |
1069 NULL}, | |
1070 /* 2: CD_MDEFORMVERT */ | |
1071 {sizeof(MDeformVert), "MDeformVert", 1, NULL, layerCopy_mdeformvert, | |
1072 layerFree_mdeformvert, layerInterp_mdeformvert, NULL, NULL}, | |
1073 /* 3: CD_MEDGE */ | |
1074 {sizeof(MEdge), "MEdge", 1, NULL, NULL, NULL, NULL, NULL, NULL}, | |
1075 /* 4: CD_MFACE */ | |
1076 {sizeof(MFace), "MFace", 1, NULL, NULL, NULL, NULL, NULL, NULL}, | |
1077 /* 5: CD_MTFACE */ | |
1078 {sizeof(MTFace), "MTFace", 1, N_("UVMap"), layerCopy_tface, NULL, | |
1079 layerInterp_tface, layerSwap_tface, layerDefault_tface}, | |
1080 /* 6: CD_MCOL */ | |
1081 /* 4 MCol structs per face */ | |
1082 {sizeof(MCol) * 4, "MCol", 4, N_("Col"), NULL, NULL, layerInterp_mcol, | |
1083 layerSwap_mcol, layerDefault_mcol}, | |
1084 /* 7: CD_ORIGINDEX */ | |
1085 {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, layerDefault_originde
x}, | |
1086 /* 8: CD_NORMAL */ | |
1087 /* 3 floats per normal vector */ | |
1088 {sizeof(float) * 3, "vec3f", 1, NULL, NULL, NULL, NULL, NULL, NULL}, | |
1089 /* 9: CD_POLYINDEX (deprecated) */ | |
1090 {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, | |
1091 /* 10: CD_PROP_FLT */ | |
1092 {sizeof(MFloatProperty), "MFloatProperty", 1, N_("Float"), layerCopy_pro
pFloat, NULL, NULL, NULL}, | |
1093 /* 11: CD_PROP_INT */ | |
1094 {sizeof(MIntProperty), "MIntProperty", 1, N_("Int"), layerCopy_propInt,
NULL, NULL, NULL}, | |
1095 /* 12: CD_PROP_STR */ | |
1096 {sizeof(MStringProperty), "MStringProperty", 1, N_("String"), layerCopy_
propString, NULL, NULL, NULL}, | |
1097 /* 13: CD_ORIGSPACE */ | |
1098 {sizeof(OrigSpaceFace), "OrigSpaceFace", 1, N_("UVMap"), layerCopy_origs
pace_face, NULL, | |
1099 layerInterp_origspace_face, layerSwap_origspace_face, layerDefault_orig
space_face}, | |
1100 /* 14: CD_ORCO */ | |
1101 {sizeof(float) * 3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, | |
1102 /* 15: CD_MTEXPOLY */ | |
1103 /* note, when we expose the UV Map / TexFace split to the user, change t
his back to face Texture */ | |
1104 {sizeof(MTexPoly), "MTexPoly", 1, N_("UVMap") /* "Face Texture" */, NULL
, NULL, NULL, NULL, NULL}, | |
1105 /* 16: CD_MLOOPUV */ | |
1106 {sizeof(MLoopUV), "MLoopUV", 1, N_("UV coord"), NULL, NULL, layerInterp_
mloopuv, NULL, NULL, | |
1107 layerEqual_mloopuv, layerMultiply_mloopuv, layerInitMinMax_mloopuv,· | |
1108 layerAdd_mloopuv, layerDoMinMax_mloopuv, layerCopyValue_mloopuv}, | |
1109 /* 17: CD_MLOOPCOL */ | |
1110 {sizeof(MLoopCol), "MLoopCol", 1, N_("Col"), NULL, NULL, layerInterp_mlo
opcol, NULL, | |
1111 layerDefault_mloopcol, layerEqual_mloopcol, layerMultiply_mloopcol, lay
erInitMinMax_mloopcol,· | |
1112 layerAdd_mloopcol, layerDoMinMax_mloopcol, layerCopyValue_mloopcol}, | |
1113 /* 18: CD_TANGENT */ | |
1114 {sizeof(float) * 4 * 4, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, | |
1115 /* 19: CD_MDISPS */ | |
1116 {sizeof(MDisps), "MDisps", 1, NULL, layerCopy_mdisps, | |
1117 layerFree_mdisps, NULL, layerSwap_mdisps, NULL, | |
1118 NULL, NULL, NULL, NULL, NULL, NULL,· | |
1119 layerRead_mdisps, layerWrite_mdisps, layerFilesize_mdisps}, | |
1120 /* 20: CD_PREVIEW_MCOL */ | |
1121 {sizeof(MCol) * 4, "MCol", 4, N_("PreviewCol"), NULL, NULL, layerInterp_
mcol, | |
1122 layerSwap_mcol, layerDefault_mcol}, | |
1123 /* 21: CD_ID_MCOL */ | |
1124 {sizeof(MCol) * 4, "MCol", 4, N_("IDCol"), NULL, NULL, layerInterp_mcol, | |
1125 layerSwap_mcol, layerDefault_mcol}, | |
1126 /* 22: CD_TEXTURE_MCOL */ | |
1127 {sizeof(MCol) * 4, "MCol", 4, N_("TexturedCol"), NULL, NULL, layerInterp
_mcol, | |
1128 layerSwap_mcol, layerDefault_mcol}, | |
1129 /* 23: CD_CLOTH_ORCO */ | |
1130 {sizeof(float) * 3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, | |
1131 /* 24: CD_RECAST */ | |
1132 {sizeof(MRecast), "MRecast", 1, N_("Recast"), NULL, NULL, NULL, NULL}, | |
1133 | |
1134 /* BMESH ONLY */ | |
1135 /* 25: CD_MPOLY */ | |
1136 {sizeof(MPoly), "MPoly", 1, N_("NGon Face"), NULL, NULL, NULL, NULL, NUL
L}, | |
1137 /* 26: CD_MLOOP */ | |
1138 {sizeof(MLoop), "MLoop", 1, N_("NGon Face-Vertex"), NULL, NULL, NULL, NU
LL, NULL}, | |
1139 /* 27: CD_SHAPE_KEYINDEX */ | |
1140 {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, | |
1141 /* 28: CD_SHAPEKEY */ | |
1142 {sizeof(float) * 3, "", 0, N_("ShapeKey"), NULL, NULL, layerInterp_shape
key}, | |
1143 /* 29: CD_BWEIGHT */ | |
1144 {sizeof(float), "", 0, N_("BevelWeight"), NULL, NULL, layerInterp_bweigh
t}, | |
1145 /* 30: CD_CREASE */ | |
1146 {sizeof(float), "", 0, N_("SubSurfCrease"), NULL, NULL, layerInterp_bwei
ght}, | |
1147 /* 31: CD_ORIGSPACE_MLOOP */ | |
1148 {sizeof(OrigSpaceLoop), "OrigSpaceLoop", 1, N_("OS Loop"), NULL, NULL, l
ayerInterp_mloop_origspace, NULL, NULL, | |
1149 layerEqual_mloop_origspace, layerMultiply_mloop_origspace, layerInitMin
Max_mloop_origspace, | |
1150 layerAdd_mloop_origspace, layerDoMinMax_mloop_origspace, layerCopyValue
_mloop_origspace}, | |
1151 /* 32: CD_PREVIEW_MLOOPCOL */ | |
1152 {sizeof(MLoopCol), "MLoopCol", 1, N_("PreviewLoopCol"), NULL, NULL, laye
rInterp_mloopcol, NULL, | |
1153 layerDefault_mloopcol, layerEqual_mloopcol, layerMultiply_mloopcol, lay
erInitMinMax_mloopcol, | |
1154 layerAdd_mloopcol, layerDoMinMax_mloopcol, layerCopyValue_mloopcol}, | |
1155 /* 33: CD_BM_ELEM_PYPTR */ | |
1156 {sizeof(void *), "", 1, NULL, layerCopy_bmesh_elem_py_ptr, | |
1157 layerFree_bmesh_elem_py_ptr, NULL, NULL, NULL}, | |
1158 | |
1159 /* END BMESH ONLY */ | |
1160 | |
1161 /* 34: CD_PAINT_MASK */ | |
1162 {sizeof(float), "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, | |
1163 /* 35: CD_GRID_PAINT_MASK */ | |
1164 {sizeof(GridPaintMask), "GridPaintMask", 1, NULL, layerCopy_grid_paint_m
ask, | |
1165 layerFree_grid_paint_mask, NULL, NULL, NULL}, | |
1166 /* 36: CD_SKIN_NODE */ | |
1167 {sizeof(MVertSkin), "MVertSkin", 1, NULL, NULL, NULL, | |
1168 layerInterp_mvert_skin, NULL, layerDefault_mvert_skin}, | |
1169 /* 37: CD_FREESTYLE_EDGE */ | |
1170 {sizeof(FreestyleEdge), "FreestyleEdge", 1, NULL, NULL, NULL, NULL, NULL
, NULL}, | |
1171 /* 38: CD_FREESTYLE_FACE */ | |
1172 {sizeof(FreestyleFace), "FreestyleFace", 1, NULL, NULL, NULL, NULL, NULL
, NULL} | |
1173 }; | |
1174 | |
1175 /* note, numbers are from trunk and need updating for bmesh */ | |
1176 | |
1177 static const char *LAYERTYPENAMES[CD_NUMTYPES] = { | |
1178 /* 0-4 */ "CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace
", | |
1179 /* 5-9 */ "CDMTFace", "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags", | |
1180 /* 10-14 */ "CDMFloatProperty", "CDMIntProperty", "CDMStringProperty", "
CDOrigSpace", "CDOrco", | |
1181 /* 15-19 */ "CDMTexPoly", "CDMLoopUV", "CDMloopCol", "CDTangent", "CDMDi
sps", | |
1182 /* 20-24 */ "CDPreviewMCol", "CDIDMCol", "CDTextureMCol", "CDClothOrco",
"CDMRecast", | |
1183 | |
1184 /* BMESH ONLY */ | |
1185 /* 25-29 */ "CDMPoly", "CDMLoop", "CDShapeKeyIndex", "CDShapeKey", "CDBe
velWeight", | |
1186 /* 30-34 */ "CDSubSurfCrease", "CDOrigSpaceLoop", "CDPreviewLoopCol", "C
DBMElemPyPtr", "CDPaintMask", | |
1187 /* 35-36 */ "CDGridPaintMask", "CDMVertSkin", | |
1188 /* 37-38 */ "CDFreestyleEdge", "CDFreestyleFace" | |
1189 }; | |
1190 | |
1191 | |
1192 const CustomDataMask CD_MASK_BAREMESH = | |
1193 CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE | CD_MASK_MLOOP | CD_MASK_MPOL
Y | CD_MASK_BWEIGHT; | |
1194 const CustomDataMask CD_MASK_MESH = | |
1195 CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE | | |
1196 CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MCOL | | |
1197 CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS | | |
1198 CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MPOLY | CD_MASK_MLOOP | | |
1199 CD_MASK_MTEXPOLY | CD_MASK_RECAST | CD_MASK_PAINT_MASK | | |
1200 CD_MASK_GRID_PAINT_MASK | CD_MASK_MVERT_SKIN | CD_MASK_FREESTYLE_EDGE | CD_M
ASK_FREESTYLE_FACE; | |
1201 const CustomDataMask CD_MASK_EDITMESH = | |
1202 CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MLOOPUV | | |
1203 CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_SHAPE_KEYINDEX | | |
1204 CD_MASK_MCOL | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | | |
1205 CD_MASK_MDISPS | CD_MASK_SHAPEKEY | CD_MASK_RECAST | CD_MASK_PAINT_MASK | | |
1206 CD_MASK_GRID_PAINT_MASK | CD_MASK_MVERT_SKIN; | |
1207 const CustomDataMask CD_MASK_DERIVEDMESH = | |
1208 CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | | |
1209 CD_MASK_MCOL | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_CLOTH_ORCO | | |
1210 CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_PREVIEW_MLOO
PCOL | | |
1211 CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORIGSPACE_MLOOP | CD_MASK_ORC
O | CD_MASK_TANGENT | | |
1212 CD_MASK_PREVIEW_MCOL | CD_MASK_SHAPEKEY | CD_MASK_RECAST | | |
1213 CD_MASK_ORIGINDEX | CD_MASK_MVERT_SKIN | CD_MASK_FREESTYLE_EDGE | CD_MASK_FR
EESTYLE_FACE; | |
1214 const CustomDataMask CD_MASK_BMESH = | |
1215 CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | | |
1216 CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT
| | |
1217 CD_MASK_PROP_STR | CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX | CD_MASK_MDISP
S | | |
1218 CD_MASK_CREASE | CD_MASK_BWEIGHT | CD_MASK_RECAST | CD_MASK_PAINT_MASK | | |
1219 CD_MASK_GRID_PAINT_MASK | CD_MASK_MVERT_SKIN | CD_MASK_FREESTYLE_EDGE | CD_M
ASK_FREESTYLE_FACE; | |
1220 const CustomDataMask CD_MASK_FACECORNERS = | |
1221 CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV | | |
1222 CD_MASK_MLOOPCOL; | |
1223 const CustomDataMask CD_MASK_EVERYTHING = | |
1224 CD_MASK_MVERT | CD_MASK_MSTICKY /* DEPRECATED */ | CD_MASK_MDEFORMVERT | CD_
MASK_MEDGE | CD_MASK_MFACE | | |
1225 CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_NORMAL /* | CD_M
ASK_POLYINDEX */ | CD_MASK_PROP_FLT | | |
1226 CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_
MASK_MTEXPOLY | CD_MASK_MLOOPUV | | |
1227 CD_MASK_MLOOPCOL | CD_MASK_TANGENT | CD_MASK_MDISPS | CD_MASK_PREVIEW_MCOL |
CD_MASK_CLOTH_ORCO | CD_MASK_RECAST | | |
1228 /* BMESH ONLY START */ | |
1229 CD_MASK_MPOLY | CD_MASK_MLOOP | CD_MASK_SHAPE_KEYINDEX | CD_MASK_SHAPEKEY |
CD_MASK_BWEIGHT | CD_MASK_CREASE | | |
1230 CD_MASK_ORIGSPACE_MLOOP | CD_MASK_PREVIEW_MLOOPCOL | CD_MASK_BM_ELEM_PYPTR | | |
1231 /* BMESH ONLY END */ | |
1232 CD_MASK_PAINT_MASK | CD_MASK_GRID_PAINT_MASK | CD_MASK_MVERT_SKIN | CD_MASK_
FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE; | |
1233 | |
1234 static const LayerTypeInfo *layerType_getInfo(int type) | |
1235 { | |
1236 if (type < 0 || type >= CD_NUMTYPES) return NULL; | |
1237 | |
1238 return &LAYERTYPEINFO[type]; | |
1239 } | |
1240 | |
1241 static const char *layerType_getName(int type) | |
1242 { | |
1243 if (type < 0 || type >= CD_NUMTYPES) return NULL; | |
1244 | |
1245 return LAYERTYPENAMES[type]; | |
1246 } | |
1247 | |
1248 void customData_mask_layers__print(CustomDataMask mask) | |
1249 { | |
1250 int i; | |
1251 | |
1252 printf("mask=0x%lx:\n", (long unsigned int)mask); | |
1253 for (i = 0; i < CD_NUMTYPES; i++) { | |
1254 if (mask & CD_TYPE_AS_MASK(i)) { | |
1255 printf(" %s\n", layerType_getName(i)); | |
1256 } | |
1257 } | |
1258 } | |
1259 | |
1260 /********************* CustomData functions *********************/ | |
1261 static void customData_update_offsets(CustomData *data); | |
1262 | |
1263 static CustomDataLayer *customData_add_layer__internal(CustomData *data, int typ
e, int alloctype, void *layerdata, | |
1264 int totelem, const char *
name); | |
1265 | |
1266 void CustomData_update_typemap(CustomData *data) | |
1267 { | |
1268 int i, lasttype = -1; | |
1269 | |
1270 for (i = 0; i < CD_NUMTYPES; i++) { | |
1271 data->typemap[i] = -1; | |
1272 } | |
1273 | |
1274 for (i = 0; i < data->totlayer; i++) { | |
1275 if (data->layers[i].type != lasttype) { | |
1276 data->typemap[data->layers[i].type] = i; | |
1277 } | |
1278 lasttype = data->layers[i].type; | |
1279 } | |
1280 } | |
1281 | |
1282 /* currently only used in BLI_assert */ | |
1283 #ifndef NDEBUG | |
1284 static int customdata_typemap_is_valid(const CustomData *data) | |
1285 { | |
1286 CustomData data_copy = *data; | |
1287 CustomData_update_typemap(&data_copy); | |
1288 return (memcmp(data->typemap, data_copy.typemap, sizeof(data->typemap))
== 0); | |
1289 } | |
1290 #endif | |
1291 | |
1292 bool CustomData_merge(const struct CustomData *source, struct CustomData *dest, | |
1293 CustomDataMask mask, int alloctype, int totelem) | |
1294 { | |
1295 /*const LayerTypeInfo *typeInfo;*/ | |
1296 CustomDataLayer *layer, *newlayer; | |
1297 void *data; | |
1298 int i, type, number = 0, lasttype = -1, lastactive = 0, lastrender = 0,
lastclone = 0, lastmask = 0, lastflag = 0; | |
1299 bool change = false; | |
1300 | |
1301 for (i = 0; i < source->totlayer; ++i) { | |
1302 layer = &source->layers[i]; | |
1303 /*typeInfo = layerType_getInfo(layer->type);*/ /*UNUSED*/ | |
1304 | |
1305 type = layer->type; | |
1306 | |
1307 if (type != lasttype) { | |
1308 number = 0; | |
1309 lastactive = layer->active; | |
1310 lastrender = layer->active_rnd; | |
1311 lastclone = layer->active_clone; | |
1312 lastmask = layer->active_mask; | |
1313 lasttype = type; | |
1314 lastflag = layer->flag; | |
1315 } | |
1316 else | |
1317 number++; | |
1318 | |
1319 if (lastflag & CD_FLAG_NOCOPY) continue; | |
1320 else if (!(mask & CD_TYPE_AS_MASK(type))) continue; | |
1321 else if (CustomData_get_layer_named(dest, type, layer->name)) co
ntinue; | |
1322 | |
1323 switch (alloctype) { | |
1324 case CD_ASSIGN: | |
1325 case CD_REFERENCE: | |
1326 case CD_DUPLICATE: | |
1327 data = layer->data; | |
1328 break; | |
1329 default: | |
1330 data = NULL; | |
1331 break; | |
1332 } | |
1333 | |
1334 if ((alloctype == CD_ASSIGN) && (lastflag & CD_FLAG_NOFREE)) | |
1335 newlayer = customData_add_layer__internal(dest, type, CD
_REFERENCE, | |
1336 data, totelem,
layer->name); | |
1337 else | |
1338 newlayer = customData_add_layer__internal(dest, type, al
loctype, | |
1339 data, totelem,
layer->name); | |
1340 ················ | |
1341 if (newlayer) { | |
1342 newlayer->uid = layer->uid; | |
1343 ························ | |
1344 newlayer->active = lastactive; | |
1345 newlayer->active_rnd = lastrender; | |
1346 newlayer->active_clone = lastclone; | |
1347 newlayer->active_mask = lastmask; | |
1348 newlayer->flag |= lastflag & (CD_FLAG_EXTERNAL | CD_FLAG
_IN_MEMORY); | |
1349 change = true; | |
1350 } | |
1351 } | |
1352 | |
1353 CustomData_update_typemap(dest); | |
1354 return change; | |
1355 } | |
1356 | |
1357 void CustomData_copy(const struct CustomData *source, struct CustomData *dest, | |
1358 CustomDataMask mask, int alloctype, int totelem) | |
1359 { | |
1360 CustomData_reset(dest); | |
1361 | |
1362 if (source->external) | |
1363 dest->external = MEM_dupallocN(source->external); | |
1364 | |
1365 CustomData_merge(source, dest, mask, alloctype, totelem); | |
1366 } | |
1367 | |
1368 static void customData_free_layer__internal(CustomDataLayer *layer, int totelem) | |
1369 { | |
1370 const LayerTypeInfo *typeInfo; | |
1371 | |
1372 if (!(layer->flag & CD_FLAG_NOFREE) && layer->data) { | |
1373 typeInfo = layerType_getInfo(layer->type); | |
1374 | |
1375 if (typeInfo->free) | |
1376 typeInfo->free(layer->data, totelem, typeInfo->size); | |
1377 | |
1378 if (layer->data) | |
1379 MEM_freeN(layer->data); | |
1380 } | |
1381 } | |
1382 | |
1383 static void CustomData_external_free(CustomData *data) | |
1384 { | |
1385 if (data->external) { | |
1386 MEM_freeN(data->external); | |
1387 data->external = NULL; | |
1388 } | |
1389 } | |
1390 | |
1391 void CustomData_reset(CustomData *data) | |
1392 { | |
1393 memset(data, 0, sizeof(*data)); | |
1394 fill_vn_i(data->typemap, CD_NUMTYPES, -1); | |
1395 } | |
1396 | |
1397 void CustomData_free(CustomData *data, int totelem) | |
1398 { | |
1399 int i; | |
1400 | |
1401 for (i = 0; i < data->totlayer; ++i) | |
1402 customData_free_layer__internal(&data->layers[i], totelem); | |
1403 | |
1404 if (data->layers) | |
1405 MEM_freeN(data->layers); | |
1406 ········ | |
1407 CustomData_external_free(data); | |
1408 CustomData_reset(data); | |
1409 } | |
1410 | |
1411 static void customData_update_offsets(CustomData *data) | |
1412 { | |
1413 const LayerTypeInfo *typeInfo; | |
1414 int i, offset = 0; | |
1415 | |
1416 for (i = 0; i < data->totlayer; ++i) { | |
1417 typeInfo = layerType_getInfo(data->layers[i].type); | |
1418 | |
1419 data->layers[i].offset = offset; | |
1420 offset += typeInfo->size; | |
1421 } | |
1422 | |
1423 data->totsize = offset; | |
1424 CustomData_update_typemap(data); | |
1425 } | |
1426 | |
1427 /* to use when we're in the middle of modifying layers */ | |
1428 static int CustomData_get_layer_index__notypemap(const CustomData *data, int typ
e) | |
1429 { | |
1430 int i; | |
1431 | |
1432 for (i = 0; i < data->totlayer; ++i) | |
1433 if (data->layers[i].type == type) | |
1434 return i; | |
1435 | |
1436 return -1; | |
1437 } | |
1438 | |
1439 /* -------------------------------------------------------------------- */ | |
1440 /* index values to access the layers (offset from the layer start) */ | |
1441 | |
1442 int CustomData_get_layer_index(const CustomData *data, int type) | |
1443 { | |
1444 BLI_assert(customdata_typemap_is_valid(data)); | |
1445 return data->typemap[type]; | |
1446 } | |
1447 | |
1448 int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n) | |
1449 { | |
1450 int i = CustomData_get_layer_index(data, type); | |
1451 | |
1452 if (i != -1) { | |
1453 BLI_assert(i + n < data->totlayer); | |
1454 i = (data->layers[i + n].type == type) ? (i + n) : (-1); | |
1455 } | |
1456 | |
1457 return i; | |
1458 } | |
1459 | |
1460 int CustomData_get_named_layer_index(const CustomData *data, int type, const cha
r *name) | |
1461 { | |
1462 int i; | |
1463 | |
1464 for (i = 0; i < data->totlayer; ++i) | |
1465 if (data->layers[i].type == type) | |
1466 if (strcmp(data->layers[i].name, name) == 0) | |
1467 return i; | |
1468 | |
1469 return -1; | |
1470 } | |
1471 | |
1472 int CustomData_get_active_layer_index(const CustomData *data, int type) | |
1473 { | |
1474 const int layer_index = data->typemap[type]; | |
1475 BLI_assert(customdata_typemap_is_valid(data)); | |
1476 return (layer_index != -1) ? layer_index + data->layers[layer_index].act
ive: -1; | |
1477 } | |
1478 | |
1479 int CustomData_get_render_layer_index(const CustomData *data, int type) | |
1480 { | |
1481 const int layer_index = data->typemap[type]; | |
1482 BLI_assert(customdata_typemap_is_valid(data)); | |
1483 return (layer_index != -1) ? layer_index + data->layers[layer_index].act
ive_rnd : -1; | |
1484 } | |
1485 | |
1486 int CustomData_get_clone_layer_index(const CustomData *data, int type) | |
1487 { | |
1488 const int layer_index = data->typemap[type]; | |
1489 BLI_assert(customdata_typemap_is_valid(data)); | |
1490 return (layer_index != -1) ? layer_index + data->layers[layer_index].act
ive_clone : -1; | |
1491 } | |
1492 | |
1493 int CustomData_get_stencil_layer_index(const CustomData *data, int type) | |
1494 { | |
1495 const int layer_index = data->typemap[type]; | |
1496 BLI_assert(customdata_typemap_is_valid(data)); | |
1497 return (layer_index != -1) ? layer_index + data->layers[layer_index].act
ive_mask : -1; | |
1498 } | |
1499 | |
1500 | |
1501 /* -------------------------------------------------------------------- */ | |
1502 /* index values per layer type */ | |
1503 | |
1504 int CustomData_get_named_layer(const struct CustomData *data, int type, const ch
ar *name) | |
1505 { | |
1506 const int named_index = CustomData_get_named_layer_index(data, type, nam
e); | |
1507 const int layer_index = data->typemap[type]; | |
1508 BLI_assert(customdata_typemap_is_valid(data)); | |
1509 return (named_index != -1) ? named_index - layer_index : -1; | |
1510 } | |
1511 | |
1512 int CustomData_get_active_layer(const CustomData *data, int type) | |
1513 { | |
1514 const int layer_index = data->typemap[type]; | |
1515 BLI_assert(customdata_typemap_is_valid(data)); | |
1516 return (layer_index != -1) ? data->layers[layer_index].active : -1; | |
1517 } | |
1518 | |
1519 int CustomData_get_render_layer(const CustomData *data, int type) | |
1520 { | |
1521 const int layer_index = data->typemap[type]; | |
1522 BLI_assert(customdata_typemap_is_valid(data)); | |
1523 return (layer_index != -1) ? data->layers[layer_index].active_rnd : -1; | |
1524 } | |
1525 | |
1526 int CustomData_get_clone_layer(const CustomData *data, int type) | |
1527 { | |
1528 const int layer_index = data->typemap[type]; | |
1529 BLI_assert(customdata_typemap_is_valid(data)); | |
1530 return (layer_index != -1) ? data->layers[layer_index].active_clone : -1
; | |
1531 } | |
1532 | |
1533 int CustomData_get_stencil_layer(const CustomData *data, int type) | |
1534 { | |
1535 const int layer_index = data->typemap[type]; | |
1536 BLI_assert(customdata_typemap_is_valid(data)); | |
1537 return (layer_index != -1) ? data->layers[layer_index].active_mask : -1; | |
1538 } | |
1539 | |
1540 void CustomData_set_layer_active(CustomData *data, int type, int n) | |
1541 { | |
1542 int i; | |
1543 | |
1544 for (i = 0; i < data->totlayer; ++i) | |
1545 if (data->layers[i].type == type) | |
1546 data->layers[i].active = n; | |
1547 } | |
1548 | |
1549 void CustomData_set_layer_render(CustomData *data, int type, int n) | |
1550 { | |
1551 int i; | |
1552 | |
1553 for (i = 0; i < data->totlayer; ++i) | |
1554 if (data->layers[i].type == type) | |
1555 data->layers[i].active_rnd = n; | |
1556 } | |
1557 | |
1558 void CustomData_set_layer_clone(CustomData *data, int type, int n) | |
1559 { | |
1560 int i; | |
1561 | |
1562 for (i = 0; i < data->totlayer; ++i) | |
1563 if (data->layers[i].type == type) | |
1564 data->layers[i].active_clone = n; | |
1565 } | |
1566 | |
1567 void CustomData_set_layer_stencil(CustomData *data, int type, int n) | |
1568 { | |
1569 int i; | |
1570 | |
1571 for (i = 0; i < data->totlayer; ++i) | |
1572 if (data->layers[i].type == type) | |
1573 data->layers[i].active_mask = n; | |
1574 } | |
1575 | |
1576 /* for using with an index from CustomData_get_active_layer_index and CustomData
_get_render_layer_index */ | |
1577 void CustomData_set_layer_active_index(CustomData *data, int type, int n) | |
1578 { | |
1579 int i; | |
1580 | |
1581 for (i = 0; i < data->totlayer; ++i) | |
1582 if (data->layers[i].type == type) | |
1583 data->layers[i].active = n - i; | |
1584 } | |
1585 | |
1586 void CustomData_set_layer_render_index(CustomData *data, int type, int n) | |
1587 { | |
1588 int i; | |
1589 | |
1590 for (i = 0; i < data->totlayer; ++i) | |
1591 if (data->layers[i].type == type) | |
1592 data->layers[i].active_rnd = n - i; | |
1593 } | |
1594 | |
1595 void CustomData_set_layer_clone_index(CustomData *data, int type, int n) | |
1596 { | |
1597 int i; | |
1598 | |
1599 for (i = 0; i < data->totlayer; ++i) | |
1600 if (data->layers[i].type == type) | |
1601 data->layers[i].active_clone = n - i; | |
1602 } | |
1603 | |
1604 void CustomData_set_layer_stencil_index(CustomData *data, int type, int n) | |
1605 { | |
1606 int i; | |
1607 | |
1608 for (i = 0; i < data->totlayer; ++i) | |
1609 if (data->layers[i].type == type) | |
1610 data->layers[i].active_mask = n - i; | |
1611 } | |
1612 | |
1613 void CustomData_set_layer_flag(struct CustomData *data, int type, int flag) | |
1614 { | |
1615 int i; | |
1616 | |
1617 for (i = 0; i < data->totlayer; ++i) | |
1618 if (data->layers[i].type == type) | |
1619 data->layers[i].flag |= flag; | |
1620 } | |
1621 | |
1622 static int customData_resize(CustomData *data, int amount) | |
1623 { | |
1624 CustomDataLayer *tmp = MEM_callocN(sizeof(*tmp) * (data->maxlayer + amou
nt), | |
1625 "CustomData->layers"); | |
1626 if (!tmp) return 0; | |
1627 | |
1628 data->maxlayer += amount; | |
1629 if (data->layers) { | |
1630 memcpy(tmp, data->layers, sizeof(*tmp) * data->totlayer); | |
1631 MEM_freeN(data->layers); | |
1632 } | |
1633 data->layers = tmp; | |
1634 | |
1635 return 1; | |
1636 } | |
1637 | |
1638 static CustomDataLayer *customData_add_layer__internal(CustomData *data, int typ
e, int alloctype, void *layerdata, | |
1639 int totelem, const char *
name) | |
1640 { | |
1641 const LayerTypeInfo *typeInfo = layerType_getInfo(type); | |
1642 int size = typeInfo->size * totelem, flag = 0, index = data->totlayer; | |
1643 void *newlayerdata = NULL; | |
1644 | |
1645 /* Passing a layerdata to copy from with an alloctype that won't copy is | |
1646 * most likely a bug */ | |
1647 BLI_assert(!layerdata || | |
1648 (alloctype == CD_ASSIGN) || | |
1649 (alloctype == CD_DUPLICATE) || | |
1650 (alloctype == CD_REFERENCE)); | |
1651 | |
1652 if (!typeInfo->defaultname && CustomData_has_layer(data, type)) | |
1653 return &data->layers[CustomData_get_layer_index(data, type)]; | |
1654 | |
1655 if ((alloctype == CD_ASSIGN) || (alloctype == CD_REFERENCE)) { | |
1656 newlayerdata = layerdata; | |
1657 } | |
1658 else if (size > 0) { | |
1659 newlayerdata = MEM_callocN(size, layerType_getName(type)); | |
1660 if (!newlayerdata) | |
1661 return NULL; | |
1662 } | |
1663 | |
1664 if (alloctype == CD_DUPLICATE && layerdata) { | |
1665 if (typeInfo->copy) | |
1666 typeInfo->copy(layerdata, newlayerdata, totelem); | |
1667 else | |
1668 memcpy(newlayerdata, layerdata, size); | |
1669 } | |
1670 else if (alloctype == CD_DEFAULT) { | |
1671 if (typeInfo->set_default) | |
1672 typeInfo->set_default((char *)newlayerdata, totelem); | |
1673 } | |
1674 else if (alloctype == CD_REFERENCE) | |
1675 flag |= CD_FLAG_NOFREE; | |
1676 | |
1677 if (index >= data->maxlayer) { | |
1678 if (!customData_resize(data, CUSTOMDATA_GROW)) { | |
1679 if (newlayerdata != layerdata) | |
1680 MEM_freeN(newlayerdata); | |
1681 return NULL; | |
1682 } | |
1683 } | |
1684 ········ | |
1685 data->totlayer++; | |
1686 | |
1687 /* keep layers ordered by type */ | |
1688 for (; index > 0 && data->layers[index - 1].type > type; --index) | |
1689 data->layers[index] = data->layers[index - 1]; | |
1690 | |
1691 data->layers[index].type = type; | |
1692 data->layers[index].flag = flag; | |
1693 data->layers[index].data = newlayerdata; | |
1694 | |
1695 if (name || (name = DATA_(typeInfo->defaultname))) { | |
1696 BLI_strncpy(data->layers[index].name, name, sizeof(data->layers[
index].name)); | |
1697 CustomData_set_layer_unique_name(data, index); | |
1698 } | |
1699 else | |
1700 data->layers[index].name[0] = '\0'; | |
1701 | |
1702 if (index > 0 && data->layers[index - 1].type == type) { | |
1703 data->layers[index].active = data->layers[index - 1].active; | |
1704 data->layers[index].active_rnd = data->layers[index - 1].active_
rnd; | |
1705 data->layers[index].active_clone = data->layers[index - 1].activ
e_clone; | |
1706 data->layers[index].active_mask = data->layers[index - 1].active
_mask; | |
1707 } | |
1708 else { | |
1709 data->layers[index].active = 0; | |
1710 data->layers[index].active_rnd = 0; | |
1711 data->layers[index].active_clone = 0; | |
1712 data->layers[index].active_mask = 0; | |
1713 } | |
1714 ········ | |
1715 customData_update_offsets(data); | |
1716 | |
1717 return &data->layers[index]; | |
1718 } | |
1719 | |
1720 void *CustomData_add_layer(CustomData *data, int type, int alloctype, | |
1721 void *layerdata, int totelem) | |
1722 { | |
1723 CustomDataLayer *layer; | |
1724 const LayerTypeInfo *typeInfo = layerType_getInfo(type); | |
1725 ········ | |
1726 layer = customData_add_layer__internal(data, type, alloctype, layerdata, | |
1727 totelem, typeInfo->defaultname); | |
1728 CustomData_update_typemap(data); | |
1729 | |
1730 if (layer) | |
1731 return layer->data; | |
1732 | |
1733 return NULL; | |
1734 } | |
1735 | |
1736 /*same as above but accepts a name*/ | |
1737 void *CustomData_add_layer_named(CustomData *data, int type, int alloctype, | |
1738 void *layerdata, int totelem, const char *name) | |
1739 { | |
1740 CustomDataLayer *layer; | |
1741 ········ | |
1742 layer = customData_add_layer__internal(data, type, alloctype, layerdata, | |
1743 totelem, name); | |
1744 CustomData_update_typemap(data); | |
1745 | |
1746 if (layer) | |
1747 return layer->data; | |
1748 | |
1749 return NULL; | |
1750 } | |
1751 | |
1752 | |
1753 bool CustomData_free_layer(CustomData *data, int type, int totelem, int index) | |
1754 { | |
1755 int i; | |
1756 ········ | |
1757 if (index < 0) return 0; | |
1758 | |
1759 customData_free_layer__internal(&data->layers[index], totelem); | |
1760 | |
1761 for (i = index + 1; i < data->totlayer; ++i) | |
1762 data->layers[i - 1] = data->layers[i]; | |
1763 | |
1764 data->totlayer--; | |
1765 | |
1766 /* if layer was last of type in array, set new active layer */ | |
1767 i = CustomData_get_layer_index__notypemap(data, type); | |
1768 | |
1769 if (i != -1) { | |
1770 /* don't decrement zero index */ | |
1771 const int index_nonzero = index ? index : 1; | |
1772 CustomDataLayer *layer; | |
1773 | |
1774 for (layer = &data->layers[i]; i < data->totlayer && layer->type
== type; i++, layer++) { | |
1775 if (layer->active >= index_nonzero) layer->active-
-; | |
1776 if (layer->active_rnd >= index_nonzero) layer->active_
rnd--; | |
1777 if (layer->active_clone >= index_nonzero) layer->active_
clone--; | |
1778 if (layer->active_mask >= index_nonzero) layer->active_
mask--; | |
1779 } | |
1780 } | |
1781 | |
1782 if (data->totlayer <= data->maxlayer - CUSTOMDATA_GROW) | |
1783 customData_resize(data, -CUSTOMDATA_GROW); | |
1784 | |
1785 customData_update_offsets(data); | |
1786 | |
1787 return 1; | |
1788 } | |
1789 | |
1790 bool CustomData_free_layer_active(CustomData *data, int type, int totelem) | |
1791 { | |
1792 int index = 0; | |
1793 index = CustomData_get_active_layer_index(data, type); | |
1794 if (index < 0) return 0; | |
1795 return CustomData_free_layer(data, type, totelem, index); | |
1796 } | |
1797 | |
1798 | |
1799 void CustomData_free_layers(CustomData *data, int type, int totelem) | |
1800 { | |
1801 while (CustomData_has_layer(data, type)) | |
1802 CustomData_free_layer_active(data, type, totelem); | |
1803 } | |
1804 | |
1805 bool CustomData_has_layer(const CustomData *data, int type) | |
1806 { | |
1807 return (CustomData_get_layer_index(data, type) != -1); | |
1808 } | |
1809 | |
1810 int CustomData_number_of_layers(const CustomData *data, int type) | |
1811 { | |
1812 int i, number = 0; | |
1813 | |
1814 for (i = 0; i < data->totlayer; i++) | |
1815 if (data->layers[i].type == type) | |
1816 number++; | |
1817 ········ | |
1818 return number; | |
1819 } | |
1820 | |
1821 int CustomData_number_of_layers_typemask(const CustomData *data, CustomDataMask
mask) | |
1822 { | |
1823 int i, number = 0; | |
1824 | |
1825 for (i = 0; i < data->totlayer; i++) | |
1826 if (mask & CD_TYPE_AS_MASK(data->layers[i].type)) | |
1827 number++; | |
1828 | |
1829 return number; | |
1830 } | |
1831 | |
1832 void *CustomData_duplicate_referenced_layer(struct CustomData *data, const int t
ype, const int totelem) | |
1833 { | |
1834 CustomDataLayer *layer; | |
1835 int layer_index; | |
1836 | |
1837 /* get the layer index of the first layer of type */ | |
1838 layer_index = CustomData_get_active_layer_index(data, type); | |
1839 if (layer_index < 0) return NULL; | |
1840 | |
1841 layer = &data->layers[layer_index]; | |
1842 | |
1843 if (layer->flag & CD_FLAG_NOFREE) { | |
1844 /* MEM_dupallocN won't work in case of complex layers, like e.g. | |
1845 * CD_MDEFORMVERT, which has pointers to allocated data... | |
1846 * So in case a custom copy function is defined, use it! | |
1847 */ | |
1848 const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type); | |
1849 | |
1850 if (typeInfo->copy) { | |
1851 char *dest_data = MEM_mallocN(typeInfo->size * totelem,
"CD duplicate ref layer"); | |
1852 typeInfo->copy(layer->data, dest_data, totelem); | |
1853 layer->data = dest_data; | |
1854 } | |
1855 else | |
1856 layer->data = MEM_dupallocN(layer->data); | |
1857 | |
1858 layer->flag &= ~CD_FLAG_NOFREE; | |
1859 } | |
1860 | |
1861 return layer->data; | |
1862 } | |
1863 | |
1864 void *CustomData_duplicate_referenced_layer_named(struct CustomData *data, | |
1865 const int type, const char *na
me, const int totelem) | |
1866 { | |
1867 CustomDataLayer *layer; | |
1868 int layer_index; | |
1869 | |
1870 /* get the layer index of the desired layer */ | |
1871 layer_index = CustomData_get_named_layer_index(data, type, name); | |
1872 if (layer_index < 0) return NULL; | |
1873 | |
1874 layer = &data->layers[layer_index]; | |
1875 | |
1876 if (layer->flag & CD_FLAG_NOFREE) { | |
1877 /* MEM_dupallocN won't work in case of complex layers, like e.g. | |
1878 * CD_MDEFORMVERT, which has pointers to allocated data... | |
1879 * So in case a custom copy function is defined, use it! | |
1880 */ | |
1881 const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type); | |
1882 | |
1883 if (typeInfo->copy) { | |
1884 char *dest_data = MEM_mallocN(typeInfo->size * totelem,
"CD duplicate ref layer"); | |
1885 typeInfo->copy(layer->data, dest_data, totelem); | |
1886 layer->data = dest_data; | |
1887 } | |
1888 else | |
1889 layer->data = MEM_dupallocN(layer->data); | |
1890 | |
1891 layer->flag &= ~CD_FLAG_NOFREE; | |
1892 } | |
1893 | |
1894 return layer->data; | |
1895 } | |
1896 | |
1897 bool CustomData_is_referenced_layer(struct CustomData *data, int type) | |
1898 { | |
1899 CustomDataLayer *layer; | |
1900 int layer_index; | |
1901 | |
1902 /* get the layer index of the first layer of type */ | |
1903 layer_index = CustomData_get_active_layer_index(data, type); | |
1904 if (layer_index < 0) return 0; | |
1905 | |
1906 layer = &data->layers[layer_index]; | |
1907 | |
1908 return (layer->flag & CD_FLAG_NOFREE) != 0; | |
1909 } | |
1910 | |
1911 void CustomData_free_temporary(CustomData *data, int totelem) | |
1912 { | |
1913 CustomDataLayer *layer; | |
1914 int i, j; | |
1915 | |
1916 for (i = 0, j = 0; i < data->totlayer; ++i) { | |
1917 layer = &data->layers[i]; | |
1918 | |
1919 if (i != j) | |
1920 data->layers[j] = data->layers[i]; | |
1921 | |
1922 if ((layer->flag & CD_FLAG_TEMPORARY) == CD_FLAG_TEMPORARY) | |
1923 customData_free_layer__internal(layer, totelem); | |
1924 else | |
1925 j++; | |
1926 } | |
1927 | |
1928 data->totlayer = j; | |
1929 | |
1930 if (data->totlayer <= data->maxlayer - CUSTOMDATA_GROW) | |
1931 customData_resize(data, -CUSTOMDATA_GROW); | |
1932 | |
1933 customData_update_offsets(data); | |
1934 } | |
1935 | |
1936 void CustomData_set_only_copy(const struct CustomData *data, | |
1937 CustomDataMask mask) | |
1938 { | |
1939 int i; | |
1940 | |
1941 for (i = 0; i < data->totlayer; ++i) | |
1942 if (!(mask & CD_TYPE_AS_MASK(data->layers[i].type))) | |
1943 data->layers[i].flag |= CD_FLAG_NOCOPY; | |
1944 } | |
1945 | |
1946 void CustomData_copy_elements(int type, void *source, void *dest, int count) | |
1947 { | |
1948 const LayerTypeInfo *typeInfo = layerType_getInfo(type); | |
1949 | |
1950 if (typeInfo->copy) | |
1951 typeInfo->copy(source, dest, count); | |
1952 else | |
1953 memcpy(dest, source, typeInfo->size * count); | |
1954 } | |
1955 | |
1956 static void CustomData_copy_data_layer(const CustomData *source, CustomData *des
t, | |
1957 int src_i, int dest_i, | |
1958 int source_index, int dest_index, int cou
nt) { | |
1959 const LayerTypeInfo *typeInfo; | |
1960 int src_offset; | |
1961 int dest_offset; | |
1962 | |
1963 char *src_data = source->layers[src_i].data; | |
1964 char *dest_data = dest->layers[dest_i].data; | |
1965 | |
1966 typeInfo = layerType_getInfo(source->layers[src_i].type); | |
1967 | |
1968 src_offset = source_index * typeInfo->size; | |
1969 dest_offset = dest_index * typeInfo->size; | |
1970 | |
1971 if (!src_data || !dest_data) { | |
1972 if (!(src_data == NULL && dest_data == NULL)) { | |
1973 printf("%s: warning null data for %s type (%p --> %p), s
kipping\n", | |
1974 __func__, layerType_getName(source->layers[sr
c_i].type), | |
1975 (void *)src_data, (void *)dest_data); | |
1976 } | |
1977 return; | |
1978 } | |
1979 | |
1980 if (typeInfo->copy) | |
1981 typeInfo->copy(src_data + src_offset, | |
1982 dest_data + dest_offset, | |
1983 count); | |
1984 else | |
1985 memcpy(dest_data + dest_offset, | |
1986 src_data + src_offset, | |
1987 count * typeInfo->size); | |
1988 } | |
1989 | |
1990 void CustomData_copy_data_named(const CustomData *source, CustomData *dest, | |
1991 int source_index, int dest_index, int count) | |
1992 { | |
1993 int src_i, dest_i; | |
1994 | |
1995 /* copies a layer at a time */ | |
1996 for (src_i = 0; src_i < source->totlayer; ++src_i) { | |
1997 | |
1998 dest_i = CustomData_get_named_layer_index(dest, source->layers[s
rc_i].type, source->layers[src_i].name); | |
1999 | |
2000 /* if we found a matching layer, copy the data */ | |
2001 if (dest_i > -1) { | |
2002 CustomData_copy_data_layer(source, dest, src_i, dest_i,
source_index, dest_index, count); | |
2003 } | |
2004 } | |
2005 } | |
2006 | |
2007 void CustomData_copy_data(const CustomData *source, CustomData *dest, | |
2008 int source_index, int dest_index, int count) | |
2009 { | |
2010 int src_i, dest_i; | |
2011 | |
2012 /* copies a layer at a time */ | |
2013 dest_i = 0; | |
2014 for (src_i = 0; src_i < source->totlayer; ++src_i) { | |
2015 | |
2016 /* find the first dest layer with type >= the source type | |
2017 * (this should work because layers are ordered by type) | |
2018 */ | |
2019 while (dest_i < dest->totlayer && dest->layers[dest_i].type < so
urce->layers[src_i].type) { | |
2020 dest_i++; | |
2021 } | |
2022 | |
2023 /* if there are no more dest layers, we're done */ | |
2024 if (dest_i >= dest->totlayer) return; | |
2025 | |
2026 /* if we found a matching layer, copy the data */ | |
2027 if (dest->layers[dest_i].type == source->layers[src_i].type) { | |
2028 CustomData_copy_data_layer(source, dest, src_i, dest_i,
source_index, dest_index, count); | |
2029 ························ | |
2030 /* if there are multiple source & dest layers of the sam
e type, | |
2031 * we don't want to copy all source layers to the same d
est, so | |
2032 * increment dest_i | |
2033 */ | |
2034 dest_i++; | |
2035 } | |
2036 } | |
2037 } | |
2038 | |
2039 void CustomData_free_elem(CustomData *data, int index, int count) | |
2040 { | |
2041 int i; | |
2042 const LayerTypeInfo *typeInfo; | |
2043 | |
2044 for (i = 0; i < data->totlayer; ++i) { | |
2045 if (!(data->layers[i].flag & CD_FLAG_NOFREE)) { | |
2046 typeInfo = layerType_getInfo(data->layers[i].type); | |
2047 | |
2048 if (typeInfo->free) { | |
2049 int offset = typeInfo->size * index; | |
2050 | |
2051 typeInfo->free((char *)data->layers[i].data + of
fset, | |
2052 count, typeInfo->size); | |
2053 } | |
2054 } | |
2055 } | |
2056 } | |
2057 | |
2058 #define SOURCE_BUF_SIZE 100 | |
2059 | |
2060 void CustomData_interp(const CustomData *source, CustomData *dest, | |
2061 int *src_indices, float *weights, float *sub_weights, | |
2062 int count, int dest_index) | |
2063 { | |
2064 int src_i, dest_i; | |
2065 int dest_offset; | |
2066 int j; | |
2067 void *source_buf[SOURCE_BUF_SIZE]; | |
2068 void **sources = source_buf; | |
2069 | |
2070 /* slow fallback in case we're interpolating a ridiculous number of | |
2071 * elements | |
2072 */ | |
2073 if (count > SOURCE_BUF_SIZE) | |
2074 sources = MEM_callocN(sizeof(*sources) * count, | |
2075 "CustomData_interp sources"); | |
2076 | |
2077 /* interpolates a layer at a time */ | |
2078 dest_i = 0; | |
2079 for (src_i = 0; src_i < source->totlayer; ++src_i) { | |
2080 const LayerTypeInfo *typeInfo = layerType_getInfo(source->layers
[src_i].type); | |
2081 if (!typeInfo->interp) continue; | |
2082 | |
2083 /* find the first dest layer with type >= the source type | |
2084 * (this should work because layers are ordered by type) | |
2085 */ | |
2086 while (dest_i < dest->totlayer && dest->layers[dest_i].type < so
urce->layers[src_i].type) { | |
2087 dest_i++; | |
2088 } | |
2089 | |
2090 /* if there are no more dest layers, we're done */ | |
2091 if (dest_i >= dest->totlayer) break; | |
2092 | |
2093 /* if we found a matching layer, copy the data */ | |
2094 if (dest->layers[dest_i].type == source->layers[src_i].type) { | |
2095 void *src_data = source->layers[src_i].data; | |
2096 | |
2097 for (j = 0; j < count; ++j) { | |
2098 sources[j] = (char *)src_data + typeInfo->size *
src_indices[j]; | |
2099 } | |
2100 | |
2101 dest_offset = dest_index * typeInfo->size; | |
2102 | |
2103 typeInfo->interp(sources, weights, sub_weights, count, | |
2104 (char *)dest->layers[dest_i].data + des
t_offset); | |
2105 | |
2106 /* if there are multiple source & dest layers of the sam
e type, | |
2107 * we don't want to copy all source layers to the same d
est, so | |
2108 * increment dest_i | |
2109 */ | |
2110 dest_i++; | |
2111 } | |
2112 } | |
2113 | |
2114 if (count > SOURCE_BUF_SIZE) MEM_freeN(sources); | |
2115 } | |
2116 | |
2117 void CustomData_swap(struct CustomData *data, int index, const int *corner_indic
es) | |
2118 { | |
2119 const LayerTypeInfo *typeInfo; | |
2120 int i; | |
2121 | |
2122 for (i = 0; i < data->totlayer; ++i) { | |
2123 typeInfo = layerType_getInfo(data->layers[i].type); | |
2124 | |
2125 if (typeInfo->swap) { | |
2126 int offset = typeInfo->size * index; | |
2127 | |
2128 typeInfo->swap((char *)data->layers[i].data + offset, co
rner_indices); | |
2129 } | |
2130 } | |
2131 } | |
2132 | |
2133 void *CustomData_get(const CustomData *data, int index, int type) | |
2134 { | |
2135 int offset; | |
2136 int layer_index; | |
2137 ········ | |
2138 BLI_assert(index >= 0); | |
2139 | |
2140 /* get the layer index of the active layer of type */ | |
2141 layer_index = CustomData_get_active_layer_index(data, type); | |
2142 if (layer_index < 0) return NULL; | |
2143 | |
2144 /* get the offset of the desired element */ | |
2145 offset = layerType_getInfo(type)->size * index; | |
2146 | |
2147 return (char *)data->layers[layer_index].data + offset; | |
2148 } | |
2149 | |
2150 void *CustomData_get_n(const CustomData *data, int type, int index, int n) | |
2151 { | |
2152 int layer_index; | |
2153 int offset; | |
2154 | |
2155 BLI_assert(index >= 0 && n >= 0); | |
2156 | |
2157 /* get the layer index of the first layer of type */ | |
2158 layer_index = data->typemap[type]; | |
2159 if (layer_index < 0) return NULL; | |
2160 | |
2161 offset = layerType_getInfo(type)->size * index; | |
2162 return (char *)data->layers[layer_index + n].data + offset; | |
2163 } | |
2164 | |
2165 void *CustomData_get_layer(const CustomData *data, int type) | |
2166 { | |
2167 /* get the layer index of the active layer of type */ | |
2168 int layer_index = CustomData_get_active_layer_index(data, type); | |
2169 if (layer_index < 0) return NULL; | |
2170 | |
2171 return data->layers[layer_index].data; | |
2172 } | |
2173 | |
2174 void *CustomData_get_layer_n(const CustomData *data, int type, int n) | |
2175 { | |
2176 /* get the layer index of the active layer of type */ | |
2177 int layer_index = CustomData_get_layer_index_n(data, type, n); | |
2178 if (layer_index < 0) return NULL; | |
2179 | |
2180 return data->layers[layer_index].data; | |
2181 } | |
2182 | |
2183 void *CustomData_get_layer_named(const struct CustomData *data, int type, | |
2184 const char *name) | |
2185 { | |
2186 int layer_index = CustomData_get_named_layer_index(data, type, name); | |
2187 if (layer_index < 0) return NULL; | |
2188 | |
2189 return data->layers[layer_index].data; | |
2190 } | |
2191 | |
2192 int CustomData_get_offset(const CustomData *data, int type) | |
2193 { | |
2194 /* get the layer index of the active layer of type */ | |
2195 int layer_index = CustomData_get_active_layer_index(data, type); | |
2196 if (layer_index < 0) return -1; | |
2197 | |
2198 return data->layers[layer_index].offset; | |
2199 } | |
2200 | |
2201 int CustomData_get_n_offset(const CustomData *data, int type, int n) | |
2202 { | |
2203 /* get the layer index of the active layer of type */ | |
2204 int layer_index = CustomData_get_layer_index_n(data, type, n); | |
2205 if (layer_index < 0) return -1; | |
2206 | |
2207 return data->layers[layer_index].offset; | |
2208 } | |
2209 | |
2210 bool CustomData_set_layer_name(const CustomData *data, int type, int n, const ch
ar *name) | |
2211 { | |
2212 /* get the layer index of the first layer of type */ | |
2213 int layer_index = CustomData_get_layer_index_n(data, type, n); | |
2214 | |
2215 if (layer_index < 0) return false; | |
2216 if (!name) return false; | |
2217 ········ | |
2218 BLI_strncpy(data->layers[layer_index].name, name, sizeof(data->layers[la
yer_index].name)); | |
2219 ········ | |
2220 return true; | |
2221 } | |
2222 | |
2223 void *CustomData_set_layer(const CustomData *data, int type, void *ptr) | |
2224 { | |
2225 /* get the layer index of the first layer of type */ | |
2226 int layer_index = CustomData_get_active_layer_index(data, type); | |
2227 | |
2228 if (layer_index < 0) return NULL; | |
2229 | |
2230 data->layers[layer_index].data = ptr; | |
2231 | |
2232 return ptr; | |
2233 } | |
2234 | |
2235 void *CustomData_set_layer_n(const struct CustomData *data, int type, int n, voi
d *ptr) | |
2236 { | |
2237 /* get the layer index of the first layer of type */ | |
2238 int layer_index = CustomData_get_layer_index_n(data, type, n); | |
2239 if (layer_index < 0) return NULL; | |
2240 | |
2241 data->layers[layer_index].data = ptr; | |
2242 | |
2243 return ptr; | |
2244 } | |
2245 | |
2246 void CustomData_set(const CustomData *data, int index, int type, void *source) | |
2247 { | |
2248 void *dest = CustomData_get(data, index, type); | |
2249 const LayerTypeInfo *typeInfo = layerType_getInfo(type); | |
2250 | |
2251 if (!dest) return; | |
2252 | |
2253 if (typeInfo->copy) | |
2254 typeInfo->copy(source, dest, 1); | |
2255 else | |
2256 memcpy(dest, source, typeInfo->size); | |
2257 } | |
2258 | |
2259 /* BMesh functions */ | |
2260 /* needed to convert to/from different face reps */ | |
2261 void CustomData_to_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *l
data, | |
2262 int totloop, int totpoly) | |
2263 { | |
2264 int i; | |
2265 for (i = 0; i < fdata->totlayer; i++) { | |
2266 if (fdata->layers[i].type == CD_MTFACE) { | |
2267 CustomData_add_layer_named(pdata, CD_MTEXPOLY, CD_CALLOC
, NULL, totpoly, fdata->layers[i].name); | |
2268 CustomData_add_layer_named(ldata, CD_MLOOPUV, CD_CALLOC,
NULL, totloop, fdata->layers[i].name); | |
2269 } | |
2270 else if (fdata->layers[i].type == CD_MCOL) { | |
2271 CustomData_add_layer_named(ldata, CD_MLOOPCOL, CD_CALLOC
, NULL, totloop, fdata->layers[i].name); | |
2272 } | |
2273 else if (fdata->layers[i].type == CD_MDISPS) { | |
2274 CustomData_add_layer_named(ldata, CD_MDISPS, CD_CALLOC,
NULL, totloop, fdata->layers[i].name); | |
2275 } | |
2276 } | |
2277 } | |
2278 | |
2279 void CustomData_from_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData
*ldata, int total) | |
2280 { | |
2281 int i; | |
2282 for (i = 0; i < pdata->totlayer; i++) { | |
2283 if (pdata->layers[i].type == CD_MTEXPOLY) { | |
2284 CustomData_add_layer_named(fdata, CD_MTFACE, CD_CALLOC,
NULL, total, pdata->layers[i].name); | |
2285 } | |
2286 } | |
2287 for (i = 0; i < ldata->totlayer; i++) { | |
2288 if (ldata->layers[i].type == CD_MLOOPCOL) { | |
2289 CustomData_add_layer_named(fdata, CD_MCOL, CD_CALLOC, NU
LL, total, ldata->layers[i].name); | |
2290 } | |
2291 else if (ldata->layers[i].type == CD_PREVIEW_MLOOPCOL) { | |
2292 CustomData_add_layer_named(fdata, CD_PREVIEW_MCOL, CD_CA
LLOC, NULL, total, ldata->layers[i].name); | |
2293 } | |
2294 else if (ldata->layers[i].type == CD_ORIGSPACE_MLOOP) { | |
2295 CustomData_add_layer_named(fdata, CD_ORIGSPACE, CD_CALLO
C, NULL, total, ldata->layers[i].name); | |
2296 } | |
2297 } | |
2298 | |
2299 CustomData_bmesh_update_active_layers(fdata, pdata, ldata); | |
2300 } | |
2301 | |
2302 void CustomData_bmesh_update_active_layers(CustomData *fdata, CustomData *pdata,
CustomData *ldata) | |
2303 { | |
2304 int act; | |
2305 | |
2306 if (CustomData_has_layer(pdata, CD_MTEXPOLY)) { | |
2307 act = CustomData_get_active_layer(pdata, CD_MTEXPOLY); | |
2308 CustomData_set_layer_active(ldata, CD_MLOOPUV, act); | |
2309 CustomData_set_layer_active(fdata, CD_MTFACE, act); | |
2310 | |
2311 act = CustomData_get_render_layer(pdata, CD_MTEXPOLY); | |
2312 CustomData_set_layer_render(ldata, CD_MLOOPUV, act); | |
2313 CustomData_set_layer_render(fdata, CD_MTFACE, act); | |
2314 | |
2315 act = CustomData_get_clone_layer(pdata, CD_MTEXPOLY); | |
2316 CustomData_set_layer_clone(ldata, CD_MLOOPUV, act); | |
2317 CustomData_set_layer_clone(fdata, CD_MTFACE, act); | |
2318 | |
2319 act = CustomData_get_stencil_layer(pdata, CD_MTEXPOLY); | |
2320 CustomData_set_layer_stencil(ldata, CD_MLOOPUV, act); | |
2321 CustomData_set_layer_stencil(fdata, CD_MTFACE, act); | |
2322 } | |
2323 | |
2324 if (CustomData_has_layer(ldata, CD_MLOOPCOL)) { | |
2325 act = CustomData_get_active_layer(ldata, CD_MLOOPCOL); | |
2326 CustomData_set_layer_active(fdata, CD_MCOL, act); | |
2327 | |
2328 act = CustomData_get_render_layer(ldata, CD_MLOOPCOL); | |
2329 CustomData_set_layer_render(fdata, CD_MCOL, act); | |
2330 | |
2331 act = CustomData_get_clone_layer(ldata, CD_MLOOPCOL); | |
2332 CustomData_set_layer_clone(fdata, CD_MCOL, act); | |
2333 | |
2334 act = CustomData_get_stencil_layer(ldata, CD_MLOOPCOL); | |
2335 CustomData_set_layer_stencil(fdata, CD_MCOL, act); | |
2336 } | |
2337 } | |
2338 | |
2339 /* update active indices for active/render/clone/stencil custom data layers | |
2340 * based on indices from fdata layers | |
2341 * used by do_versions in readfile.c when creating pdata and ldata for pre-bmesh | |
2342 * meshes and needed to preserve active/render/clone/stencil flags set in pre-bm
esh files | |
2343 */ | |
2344 void CustomData_bmesh_do_versions_update_active_layers(CustomData *fdata, Custom
Data *pdata, CustomData *ldata) | |
2345 { | |
2346 int act; | |
2347 | |
2348 if (CustomData_has_layer(fdata, CD_MTFACE)) { | |
2349 act = CustomData_get_active_layer(fdata, CD_MTFACE); | |
2350 CustomData_set_layer_active(pdata, CD_MTEXPOLY, act); | |
2351 CustomData_set_layer_active(ldata, CD_MLOOPUV, act); | |
2352 | |
2353 act = CustomData_get_render_layer(fdata, CD_MTFACE); | |
2354 CustomData_set_layer_render(pdata, CD_MTEXPOLY, act); | |
2355 CustomData_set_layer_render(ldata, CD_MLOOPUV, act); | |
2356 | |
2357 act = CustomData_get_clone_layer(fdata, CD_MTFACE); | |
2358 CustomData_set_layer_clone(pdata, CD_MTEXPOLY, act); | |
2359 CustomData_set_layer_clone(ldata, CD_MLOOPUV, act); | |
2360 | |
2361 act = CustomData_get_stencil_layer(fdata, CD_MTFACE); | |
2362 CustomData_set_layer_stencil(pdata, CD_MTEXPOLY, act); | |
2363 CustomData_set_layer_stencil(ldata, CD_MLOOPUV, act); | |
2364 } | |
2365 | |
2366 if (CustomData_has_layer(fdata, CD_MCOL)) { | |
2367 act = CustomData_get_active_layer(fdata, CD_MCOL); | |
2368 CustomData_set_layer_active(ldata, CD_MLOOPCOL, act); | |
2369 | |
2370 act = CustomData_get_render_layer(fdata, CD_MCOL); | |
2371 CustomData_set_layer_render(ldata, CD_MLOOPCOL, act); | |
2372 | |
2373 act = CustomData_get_clone_layer(fdata, CD_MCOL); | |
2374 CustomData_set_layer_clone(ldata, CD_MLOOPCOL, act); | |
2375 | |
2376 act = CustomData_get_stencil_layer(fdata, CD_MCOL); | |
2377 CustomData_set_layer_stencil(ldata, CD_MLOOPCOL, act); | |
2378 } | |
2379 } | |
2380 | |
2381 void CustomData_bmesh_init_pool(CustomData *data, int totelem, const char htype) | |
2382 { | |
2383 int chunksize; | |
2384 | |
2385 /* Dispose old pools before calling here to avoid leaks */ | |
2386 BLI_assert(data->pool == NULL); | |
2387 | |
2388 switch (htype) { | |
2389 case BM_VERT: chunksize = bm_mesh_chunksize_default.totvert; br
eak; | |
2390 case BM_EDGE: chunksize = bm_mesh_chunksize_default.totedge; br
eak; | |
2391 case BM_LOOP: chunksize = bm_mesh_chunksize_default.totloop; br
eak; | |
2392 case BM_FACE: chunksize = bm_mesh_chunksize_default.totface; br
eak; | |
2393 default: | |
2394 BLI_assert(0); | |
2395 chunksize = 512; | |
2396 break; | |
2397 } | |
2398 | |
2399 /* If there are no layers, no pool is needed just yet */ | |
2400 if (data->totlayer) { | |
2401 data->pool = BLI_mempool_create(data->totsize, totelem, chunksiz
e, BLI_MEMPOOL_SYSMALLOC); | |
2402 } | |
2403 } | |
2404 | |
2405 bool CustomData_bmesh_merge(CustomData *source, CustomData *dest, | |
2406 CustomDataMask mask, int alloctype, BMesh *bm, const
char htype) | |
2407 { | |
2408 BMHeader *h; | |
2409 BMIter iter; | |
2410 CustomData destold; | |
2411 void *tmp; | |
2412 int iter_type; | |
2413 int totelem; | |
2414 | |
2415 if (CustomData_number_of_layers_typemask(source, mask) == 0) { | |
2416 return false; | |
2417 } | |
2418 | |
2419 /* copy old layer description so that old data can be copied into | |
2420 * the new allocation */ | |
2421 destold = *dest; | |
2422 if (destold.layers) { | |
2423 destold.layers = MEM_dupallocN(destold.layers); | |
2424 } | |
2425 | |
2426 if (CustomData_merge(source, dest, mask, alloctype, 0) == false) { | |
2427 if (destold.layers) | |
2428 MEM_freeN(destold.layers); | |
2429 return false; | |
2430 } | |
2431 | |
2432 switch (htype) { | |
2433 case BM_VERT: | |
2434 iter_type = BM_VERTS_OF_MESH; | |
2435 totelem = bm->totvert; | |
2436 break; | |
2437 case BM_EDGE: | |
2438 iter_type = BM_EDGES_OF_MESH; | |
2439 totelem = bm->totedge; | |
2440 break; | |
2441 case BM_LOOP: | |
2442 iter_type = BM_LOOPS_OF_FACE; | |
2443 totelem = bm->totloop; | |
2444 break; | |
2445 case BM_FACE: | |
2446 iter_type = BM_FACES_OF_MESH; | |
2447 totelem = bm->totface; | |
2448 break; | |
2449 default: /* should never happen */ | |
2450 BLI_assert(!"invalid type given"); | |
2451 iter_type = BM_VERTS_OF_MESH; | |
2452 totelem = bm->totvert; | |
2453 break; | |
2454 } | |
2455 | |
2456 dest->pool = NULL; | |
2457 CustomData_bmesh_init_pool(dest, totelem, htype); | |
2458 | |
2459 if (iter_type != BM_LOOPS_OF_FACE) { | |
2460 /*ensure all current elements follow new customdata layout*/ | |
2461 BM_ITER_MESH (h, &iter, bm, iter_type) { | |
2462 tmp = NULL; | |
2463 CustomData_bmesh_copy_data(&destold, dest, h->data, &tmp
); | |
2464 CustomData_bmesh_free_block(&destold, &h->data); | |
2465 h->data = tmp; | |
2466 } | |
2467 } | |
2468 else { | |
2469 BMFace *f; | |
2470 BMLoop *l; | |
2471 BMIter liter; | |
2472 | |
2473 /*ensure all current elements follow new customdata layout*/ | |
2474 BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { | |
2475 BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { | |
2476 tmp = NULL; | |
2477 CustomData_bmesh_copy_data(&destold, dest, l->he
ad.data, &tmp); | |
2478 CustomData_bmesh_free_block(&destold, &l->head.d
ata); | |
2479 l->head.data = tmp; | |
2480 } | |
2481 } | |
2482 } | |
2483 | |
2484 if (destold.pool) BLI_mempool_destroy(destold.pool); | |
2485 if (destold.layers) MEM_freeN(destold.layers); | |
2486 return true; | |
2487 } | |
2488 | |
2489 void CustomData_bmesh_free_block(CustomData *data, void **block) | |
2490 { | |
2491 const LayerTypeInfo *typeInfo; | |
2492 int i; | |
2493 | |
2494 if (*block == NULL) | |
2495 return; | |
2496 | |
2497 for (i = 0; i < data->totlayer; ++i) { | |
2498 if (!(data->layers[i].flag & CD_FLAG_NOFREE)) { | |
2499 typeInfo = layerType_getInfo(data->layers[i].type); | |
2500 | |
2501 if (typeInfo->free) { | |
2502 int offset = data->layers[i].offset; | |
2503 typeInfo->free((char *)*block + offset, 1, typeI
nfo->size); | |
2504 } | |
2505 } | |
2506 } | |
2507 | |
2508 if (data->totsize) | |
2509 BLI_mempool_free(data->pool, *block); | |
2510 | |
2511 *block = NULL; | |
2512 } | |
2513 | |
2514 /** | |
2515 * Same as #CustomData_bmesh_free_block but zero the memory rather then freeing. | |
2516 */ | |
2517 void CustomData_bmesh_free_block_data(CustomData *data, void **block) | |
2518 { | |
2519 const LayerTypeInfo *typeInfo; | |
2520 int i; | |
2521 | |
2522 if (*block == NULL) | |
2523 return; | |
2524 | |
2525 for (i = 0; i < data->totlayer; ++i) { | |
2526 if (!(data->layers[i].flag & CD_FLAG_NOFREE)) { | |
2527 typeInfo = layerType_getInfo(data->layers[i].type); | |
2528 | |
2529 if (typeInfo->free) { | |
2530 int offset = data->layers[i].offset; | |
2531 typeInfo->free((char *)*block + offset, 1, typeI
nfo->size); | |
2532 } | |
2533 } | |
2534 } | |
2535 | |
2536 if (data->totsize) | |
2537 memset(*block, 0, data->totsize); | |
2538 } | |
2539 | |
2540 static void CustomData_bmesh_alloc_block(CustomData *data, void **block) | |
2541 { | |
2542 | |
2543 if (*block) | |
2544 CustomData_bmesh_free_block(data, block); | |
2545 | |
2546 if (data->totsize > 0) | |
2547 *block = BLI_mempool_alloc(data->pool); | |
2548 else | |
2549 *block = NULL; | |
2550 } | |
2551 | |
2552 void CustomData_bmesh_copy_data(const CustomData *source, CustomData *dest, | |
2553 void *src_block, void **dest_block) | |
2554 { | |
2555 const LayerTypeInfo *typeInfo; | |
2556 int dest_i, src_i; | |
2557 | |
2558 if (*dest_block == NULL) { | |
2559 CustomData_bmesh_alloc_block(dest, dest_block); | |
2560 if (*dest_block) | |
2561 memset(*dest_block, 0, dest->totsize); | |
2562 } | |
2563 ········ | |
2564 /* copies a layer at a time */ | |
2565 dest_i = 0; | |
2566 for (src_i = 0; src_i < source->totlayer; ++src_i) { | |
2567 | |
2568 /* find the first dest layer with type >= the source type | |
2569 * (this should work because layers are ordered by type) | |
2570 */ | |
2571 while (dest_i < dest->totlayer && dest->layers[dest_i].type < so
urce->layers[src_i].type) { | |
2572 dest_i++; | |
2573 } | |
2574 | |
2575 /* if there are no more dest layers, we're done */ | |
2576 if (dest_i >= dest->totlayer) return; | |
2577 | |
2578 /* if we found a matching layer, copy the data */ | |
2579 if (dest->layers[dest_i].type == source->layers[src_i].type && | |
2580 strcmp(dest->layers[dest_i].name, source->layers[src_i].name
) == 0) | |
2581 { | |
2582 char *src_data = (char *)src_block + source->layers[src_
i].offset; | |
2583 char *dest_data = (char *)*dest_block + dest->layers[des
t_i].offset; | |
2584 | |
2585 typeInfo = layerType_getInfo(source->layers[src_i].type)
; | |
2586 | |
2587 if (typeInfo->copy) | |
2588 typeInfo->copy(src_data, dest_data, 1); | |
2589 else | |
2590 memcpy(dest_data, src_data, typeInfo->size); | |
2591 | |
2592 /* if there are multiple source & dest layers of the sam
e type, | |
2593 * we don't want to copy all source layers to the same d
est, so | |
2594 * increment dest_i | |
2595 */ | |
2596 dest_i++; | |
2597 } | |
2598 } | |
2599 } | |
2600 | |
2601 /*Bmesh Custom Data Functions. Should replace editmesh ones with these as well,
due to more effecient memory alloc*/ | |
2602 void *CustomData_bmesh_get(const CustomData *data, void *block, int type) | |
2603 { | |
2604 int layer_index; | |
2605 ········ | |
2606 /* get the layer index of the first layer of type */ | |
2607 layer_index = CustomData_get_active_layer_index(data, type); | |
2608 if (layer_index < 0) return NULL; | |
2609 | |
2610 return (char *)block + data->layers[layer_index].offset; | |
2611 } | |
2612 | |
2613 void *CustomData_bmesh_get_n(const CustomData *data, void *block, int type, int
n) | |
2614 { | |
2615 int layer_index; | |
2616 ········ | |
2617 /* get the layer index of the first layer of type */ | |
2618 layer_index = CustomData_get_layer_index(data, type); | |
2619 if (layer_index < 0) return NULL; | |
2620 | |
2621 return (char *)block + data->layers[layer_index + n].offset; | |
2622 } | |
2623 | |
2624 /*gets from the layer at physical index n, note: doesn't check type.*/ | |
2625 void *CustomData_bmesh_get_layer_n(const CustomData *data, void *block, int n) | |
2626 { | |
2627 if (n < 0 || n >= data->totlayer) return NULL; | |
2628 | |
2629 return (char *)block + data->layers[n].offset; | |
2630 } | |
2631 | |
2632 bool CustomData_layer_has_math(struct CustomData *data, int layer_n) | |
2633 { | |
2634 const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[layer_n].
type); | |
2635 ········ | |
2636 if (typeInfo->equal && typeInfo->add && typeInfo->multiply &&· | |
2637 typeInfo->initminmax && typeInfo->dominmax) | |
2638 { | |
2639 return true; | |
2640 } | |
2641 ········ | |
2642 return false; | |
2643 } | |
2644 | |
2645 bool CustomData_layer_has_interp(struct CustomData *data, int layer_n) | |
2646 { | |
2647 const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[layer_n].
type); | |
2648 | |
2649 if (typeInfo->interp) { | |
2650 return true; | |
2651 } | |
2652 | |
2653 return false; | |
2654 } | |
2655 | |
2656 bool CustomData_has_math(struct CustomData *data) | |
2657 { | |
2658 int i; | |
2659 | |
2660 /* interpolates a layer at a time */ | |
2661 for (i = 0; i < data->totlayer; ++i) { | |
2662 if (CustomData_layer_has_math(data, i)) { | |
2663 return true; | |
2664 } | |
2665 } | |
2666 | |
2667 return false; | |
2668 } | |
2669 | |
2670 /* a non bmesh version would have to check layer->data */ | |
2671 bool CustomData_bmesh_has_free(struct CustomData *data) | |
2672 { | |
2673 const LayerTypeInfo *typeInfo; | |
2674 int i; | |
2675 | |
2676 for (i = 0; i < data->totlayer; ++i) { | |
2677 if (!(data->layers[i].flag & CD_FLAG_NOFREE)) { | |
2678 typeInfo = layerType_getInfo(data->layers[i].type); | |
2679 if (typeInfo->free) { | |
2680 return true; | |
2681 } | |
2682 } | |
2683 } | |
2684 return false; | |
2685 } | |
2686 | |
2687 bool CustomData_has_interp(struct CustomData *data) | |
2688 { | |
2689 int i; | |
2690 | |
2691 /* interpolates a layer at a time */ | |
2692 for (i = 0; i < data->totlayer; ++i) { | |
2693 if (CustomData_layer_has_interp(data, i)) { | |
2694 return true; | |
2695 } | |
2696 } | |
2697 | |
2698 return false; | |
2699 } | |
2700 | |
2701 /* copies the "value" (e.g. mloopuv uv or mloopcol colors) from one block to | |
2702 * another, while not overwriting anything else (e.g. flags)*/ | |
2703 void CustomData_data_copy_value(int type, void *source, void *dest) | |
2704 { | |
2705 const LayerTypeInfo *typeInfo = layerType_getInfo(type); | |
2706 | |
2707 if (!dest) return; | |
2708 | |
2709 if (typeInfo->copyvalue) | |
2710 typeInfo->copyvalue(source, dest); | |
2711 else | |
2712 memcpy(dest, source, typeInfo->size); | |
2713 } | |
2714 | |
2715 bool CustomData_data_equals(int type, void *data1, void *data2) | |
2716 { | |
2717 const LayerTypeInfo *typeInfo = layerType_getInfo(type); | |
2718 | |
2719 if (typeInfo->equal) | |
2720 return typeInfo->equal(data1, data2); | |
2721 else return !memcmp(data1, data2, typeInfo->size); | |
2722 } | |
2723 | |
2724 void CustomData_data_initminmax(int type, void *min, void *max) | |
2725 { | |
2726 const LayerTypeInfo *typeInfo = layerType_getInfo(type); | |
2727 | |
2728 if (typeInfo->initminmax) | |
2729 typeInfo->initminmax(min, max); | |
2730 } | |
2731 | |
2732 | |
2733 void CustomData_data_dominmax(int type, void *data, void *min, void *max) | |
2734 { | |
2735 const LayerTypeInfo *typeInfo = layerType_getInfo(type); | |
2736 | |
2737 if (typeInfo->dominmax) | |
2738 typeInfo->dominmax(data, min, max); | |
2739 } | |
2740 | |
2741 | |
2742 void CustomData_data_multiply(int type, void *data, float fac) | |
2743 { | |
2744 const LayerTypeInfo *typeInfo = layerType_getInfo(type); | |
2745 | |
2746 if (typeInfo->multiply) | |
2747 typeInfo->multiply(data, fac); | |
2748 } | |
2749 | |
2750 | |
2751 void CustomData_data_add(int type, void *data1, void *data2) | |
2752 { | |
2753 const LayerTypeInfo *typeInfo = layerType_getInfo(type); | |
2754 | |
2755 if (typeInfo->add) | |
2756 typeInfo->add(data1, data2); | |
2757 } | |
2758 | |
2759 void CustomData_bmesh_set(const CustomData *data, void *block, int type, void *s
ource) | |
2760 { | |
2761 void *dest = CustomData_bmesh_get(data, block, type); | |
2762 const LayerTypeInfo *typeInfo = layerType_getInfo(type); | |
2763 | |
2764 if (!dest) return; | |
2765 | |
2766 if (typeInfo->copy) | |
2767 typeInfo->copy(source, dest, 1); | |
2768 else | |
2769 memcpy(dest, source, typeInfo->size); | |
2770 } | |
2771 | |
2772 void CustomData_bmesh_set_n(CustomData *data, void *block, int type, int n, void
*source) | |
2773 { | |
2774 void *dest = CustomData_bmesh_get_n(data, block, type, n); | |
2775 const LayerTypeInfo *typeInfo = layerType_getInfo(type); | |
2776 | |
2777 if (!dest) return; | |
2778 | |
2779 if (typeInfo->copy) | |
2780 typeInfo->copy(source, dest, 1); | |
2781 else | |
2782 memcpy(dest, source, typeInfo->size); | |
2783 } | |
2784 | |
2785 void CustomData_bmesh_set_layer_n(CustomData *data, void *block, int n, void *so
urce) | |
2786 { | |
2787 void *dest = CustomData_bmesh_get_layer_n(data, block, n); | |
2788 const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[n].type); | |
2789 | |
2790 if (!dest) return; | |
2791 | |
2792 if (typeInfo->copy) | |
2793 typeInfo->copy(source, dest, 1); | |
2794 else | |
2795 memcpy(dest, source, typeInfo->size); | |
2796 } | |
2797 | |
2798 /** | |
2799 * \param src_blocks must be pointers to the data, offset by layer->offset alrea
dy. | |
2800 */ | |
2801 void CustomData_bmesh_interp_n(CustomData *data, void **src_blocks, const float
*weights, | |
2802 const float *sub_weights, int count, void *dest_b
lock, int n) | |
2803 { | |
2804 CustomDataLayer *layer = &data->layers[n]; | |
2805 const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type); | |
2806 | |
2807 typeInfo->interp(src_blocks, weights, sub_weights, count, | |
2808 (char *)dest_block + layer->offset); | |
2809 } | |
2810 | |
2811 void CustomData_bmesh_interp(CustomData *data, void **src_blocks, const float *w
eights, | |
2812 const float *sub_weights, int count, void *dest_blo
ck) | |
2813 { | |
2814 int i, j; | |
2815 void *source_buf[SOURCE_BUF_SIZE]; | |
2816 void **sources = source_buf; | |
2817 | |
2818 /* slow fallback in case we're interpolating a ridiculous number of | |
2819 * elements | |
2820 */ | |
2821 if (count > SOURCE_BUF_SIZE) | |
2822 sources = MEM_callocN(sizeof(*sources) * count, | |
2823 "CustomData_interp sources"); | |
2824 | |
2825 /* interpolates a layer at a time */ | |
2826 for (i = 0; i < data->totlayer; ++i) { | |
2827 CustomDataLayer *layer = &data->layers[i]; | |
2828 const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type); | |
2829 if (typeInfo->interp) { | |
2830 for (j = 0; j < count; ++j) { | |
2831 sources[j] = (char *)src_blocks[j] + layer->offs
et; | |
2832 } | |
2833 CustomData_bmesh_interp_n(data, sources, weights, sub_we
ights, count, dest_block, i); | |
2834 } | |
2835 } | |
2836 | |
2837 if (count > SOURCE_BUF_SIZE) MEM_freeN(sources); | |
2838 } | |
2839 | |
2840 static void CustomData_bmesh_set_default_n(CustomData *data, void **block, int n
) | |
2841 { | |
2842 const LayerTypeInfo *typeInfo; | |
2843 int offset = data->layers[n].offset; | |
2844 | |
2845 typeInfo = layerType_getInfo(data->layers[n].type); | |
2846 | |
2847 if (typeInfo->set_default) { | |
2848 typeInfo->set_default((char *)*block + offset, 1); | |
2849 } | |
2850 else { | |
2851 memset((char *)*block + offset, 0, typeInfo->size); | |
2852 } | |
2853 } | |
2854 | |
2855 void CustomData_bmesh_set_default(CustomData *data, void **block) | |
2856 { | |
2857 int i; | |
2858 | |
2859 if (*block == NULL) | |
2860 CustomData_bmesh_alloc_block(data, block); | |
2861 | |
2862 for (i = 0; i < data->totlayer; ++i) { | |
2863 CustomData_bmesh_set_default_n(data, block, i); | |
2864 } | |
2865 } | |
2866 | |
2867 /** | |
2868 * \param use_default_init initializes data which can't be copied, | |
2869 * typically you'll want to use this if the BM_xxx create function | |
2870 * is called with BM_CREATE_SKIP_CD flag | |
2871 */ | |
2872 void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest, | |
2873 int src_index, void **dest_block, bool use_defaul
t_init) | |
2874 { | |
2875 const LayerTypeInfo *typeInfo; | |
2876 int dest_i, src_i, src_offset; | |
2877 | |
2878 if (*dest_block == NULL) | |
2879 CustomData_bmesh_alloc_block(dest, dest_block); | |
2880 ········ | |
2881 /* copies a layer at a time */ | |
2882 dest_i = 0; | |
2883 for (src_i = 0; src_i < source->totlayer; ++src_i) { | |
2884 | |
2885 /* find the first dest layer with type >= the source type | |
2886 * (this should work because layers are ordered by type) | |
2887 */ | |
2888 while (dest_i < dest->totlayer && dest->layers[dest_i].type < so
urce->layers[src_i].type) { | |
2889 if (use_default_init) { | |
2890 CustomData_bmesh_set_default_n(dest, dest_block,
dest_i); | |
2891 } | |
2892 dest_i++; | |
2893 } | |
2894 | |
2895 /* if there are no more dest layers, we're done */ | |
2896 if (dest_i >= dest->totlayer) break; | |
2897 | |
2898 /* if we found a matching layer, copy the data */ | |
2899 if (dest->layers[dest_i].type == source->layers[src_i].type) { | |
2900 int offset = dest->layers[dest_i].offset; | |
2901 char *src_data = source->layers[src_i].data; | |
2902 char *dest_data = (char *)*dest_block + offset; | |
2903 | |
2904 typeInfo = layerType_getInfo(dest->layers[dest_i].type); | |
2905 src_offset = src_index * typeInfo->size; | |
2906 | |
2907 if (typeInfo->copy) | |
2908 typeInfo->copy(src_data + src_offset, dest_data,
1); | |
2909 else | |
2910 memcpy(dest_data, src_data + src_offset, typeInf
o->size); | |
2911 | |
2912 /* if there are multiple source & dest layers of the sam
e type, | |
2913 * we don't want to copy all source layers to the same d
est, so | |
2914 * increment dest_i | |
2915 */ | |
2916 dest_i++; | |
2917 } | |
2918 } | |
2919 | |
2920 if (use_default_init) { | |
2921 while (dest_i < dest->totlayer) { | |
2922 CustomData_bmesh_set_default_n(dest, dest_block, dest_i)
; | |
2923 dest_i++; | |
2924 } | |
2925 } | |
2926 } | |
2927 | |
2928 void CustomData_from_bmesh_block(const CustomData *source, CustomData *dest, | |
2929 void *src_block, int dest_index) | |
2930 { | |
2931 const LayerTypeInfo *typeInfo; | |
2932 int dest_i, src_i, dest_offset; | |
2933 | |
2934 /* copies a layer at a time */ | |
2935 dest_i = 0; | |
2936 for (src_i = 0; src_i < source->totlayer; ++src_i) { | |
2937 | |
2938 /* find the first dest layer with type >= the source type | |
2939 * (this should work because layers are ordered by type) | |
2940 */ | |
2941 while (dest_i < dest->totlayer && dest->layers[dest_i].type < so
urce->layers[src_i].type) { | |
2942 dest_i++; | |
2943 } | |
2944 | |
2945 /* if there are no more dest layers, we're done */ | |
2946 if (dest_i >= dest->totlayer) return; | |
2947 | |
2948 /* if we found a matching layer, copy the data */ | |
2949 if (dest->layers[dest_i].type == source->layers[src_i].type) { | |
2950 int offset = source->layers[src_i].offset; | |
2951 char *src_data = (char *)src_block + offset; | |
2952 char *dest_data = dest->layers[dest_i].data; | |
2953 | |
2954 typeInfo = layerType_getInfo(dest->layers[dest_i].type); | |
2955 dest_offset = dest_index * typeInfo->size; | |
2956 | |
2957 if (typeInfo->copy) | |
2958 typeInfo->copy(src_data, dest_data + dest_offset
, 1); | |
2959 else | |
2960 memcpy(dest_data + dest_offset, src_data, typeIn
fo->size); | |
2961 | |
2962 /* if there are multiple source & dest layers of the sam
e type, | |
2963 * we don't want to copy all source layers to the same d
est, so | |
2964 * increment dest_i | |
2965 */ | |
2966 dest_i++; | |
2967 } | |
2968 } | |
2969 | |
2970 } | |
2971 | |
2972 void CustomData_file_write_info(int type, const char **structname, int *structnu
m) | |
2973 { | |
2974 const LayerTypeInfo *typeInfo = layerType_getInfo(type); | |
2975 | |
2976 *structname = typeInfo->structname; | |
2977 *structnum = typeInfo->structnum; | |
2978 } | |
2979 | |
2980 int CustomData_sizeof(int type) | |
2981 { | |
2982 const LayerTypeInfo *typeInfo = layerType_getInfo(type); | |
2983 | |
2984 return typeInfo->size; | |
2985 } | |
2986 | |
2987 const char *CustomData_layertype_name(int type) | |
2988 { | |
2989 return layerType_getName(type); | |
2990 } | |
2991 | |
2992 | |
2993 /** | |
2994 * Can only ever be one of these. | |
2995 */ | |
2996 bool CustomData_layertype_is_singleton(int type) | |
2997 { | |
2998 const LayerTypeInfo *typeInfo = layerType_getInfo(type); | |
2999 return typeInfo->defaultname == NULL; | |
3000 } | |
3001 | |
3002 static bool CustomData_is_property_layer(int type) | |
3003 { | |
3004 if ((type == CD_PROP_FLT) || (type == CD_PROP_INT) || (type == CD_PROP_S
TR)) | |
3005 return true; | |
3006 return false; | |
3007 } | |
3008 | |
3009 static bool cd_layer_find_dupe(CustomData *data, const char *name, int type, int
index) | |
3010 { | |
3011 int i; | |
3012 /* see if there is a duplicate */ | |
3013 for (i = 0; i < data->totlayer; i++) { | |
3014 if (i != index) { | |
3015 CustomDataLayer *layer = &data->layers[i]; | |
3016 ························ | |
3017 if (CustomData_is_property_layer(type)) { | |
3018 if (CustomData_is_property_layer(layer->type) &&
strcmp(layer->name, name) == 0) { | |
3019 return true; | |
3020 } | |
3021 } | |
3022 else { | |
3023 if (i != index && layer->type == type && strcmp(
layer->name, name) == 0) { | |
3024 return true; | |
3025 } | |
3026 } | |
3027 } | |
3028 } | |
3029 ········ | |
3030 return false; | |
3031 } | |
3032 | |
3033 static bool customdata_unique_check(void *arg, const char *name) | |
3034 { | |
3035 struct {CustomData *data; int type; int index; } *data_arg = arg; | |
3036 return cd_layer_find_dupe(data_arg->data, name, data_arg->type, data_arg
->index); | |
3037 } | |
3038 | |
3039 void CustomData_set_layer_unique_name(CustomData *data, int index) | |
3040 {······· | |
3041 CustomDataLayer *nlayer = &data->layers[index]; | |
3042 const LayerTypeInfo *typeInfo = layerType_getInfo(nlayer->type); | |
3043 | |
3044 struct {CustomData *data; int type; int index; } data_arg; | |
3045 data_arg.data = data; | |
3046 data_arg.type = nlayer->type; | |
3047 data_arg.index = index; | |
3048 | |
3049 if (!typeInfo->defaultname) | |
3050 return; | |
3051 | |
3052 BLI_uniquename_cb(customdata_unique_check, &data_arg, DATA_(typeInfo->de
faultname), '.', nlayer->name, | |
3053 sizeof(nlayer->name)); | |
3054 } | |
3055 | |
3056 void CustomData_validate_layer_name(const CustomData *data, int type, const char
*name, char *outname) | |
3057 { | |
3058 int index = -1; | |
3059 | |
3060 /* if a layer name was given, try to find that layer */ | |
3061 if (name[0]) | |
3062 index = CustomData_get_named_layer_index(data, type, name); | |
3063 | |
3064 if (index < 0) { | |
3065 /* either no layer was specified, or the layer we want has been | |
3066 * deleted, so assign the active layer to name | |
3067 */ | |
3068 index = CustomData_get_active_layer_index(data, type); | |
3069 BLI_strncpy(outname, data->layers[index].name, MAX_CUSTOMDATA_LA
YER_NAME); | |
3070 } | |
3071 else { | |
3072 BLI_strncpy(outname, name, MAX_CUSTOMDATA_LAYER_NAME); | |
3073 } | |
3074 } | |
3075 | |
3076 bool CustomData_verify_versions(struct CustomData *data, int index) | |
3077 { | |
3078 const LayerTypeInfo *typeInfo; | |
3079 CustomDataLayer *layer = &data->layers[index]; | |
3080 bool keeplayer = true; | |
3081 int i; | |
3082 | |
3083 if (layer->type >= CD_NUMTYPES) { | |
3084 keeplayer = false; /* unknown layer type from future version */ | |
3085 } | |
3086 else { | |
3087 typeInfo = layerType_getInfo(layer->type); | |
3088 | |
3089 if (!typeInfo->defaultname && (index > 0) && | |
3090 data->layers[index - 1].type == layer->type) | |
3091 { | |
3092 keeplayer = false; /* multiple layers of which we only s
upport one */ | |
3093 } | |
3094 } | |
3095 | |
3096 if (!keeplayer) { | |
3097 for (i = index + 1; i < data->totlayer; ++i) | |
3098 data->layers[i - 1] = data->layers[i]; | |
3099 data->totlayer--; | |
3100 } | |
3101 | |
3102 return keeplayer; | |
3103 } | |
3104 | |
3105 /****************************** External Files *******************************/ | |
3106 | |
3107 static void customdata_external_filename(char filename[FILE_MAX], ID *id, Custom
DataExternal *external) | |
3108 { | |
3109 BLI_strncpy(filename, external->filename, FILE_MAX); | |
3110 BLI_path_abs(filename, ID_BLEND_PATH(G.main, id)); | |
3111 } | |
3112 | |
3113 void CustomData_external_reload(CustomData *data, ID *UNUSED(id), CustomDataMask
mask, int totelem) | |
3114 { | |
3115 CustomDataLayer *layer; | |
3116 const LayerTypeInfo *typeInfo; | |
3117 int i; | |
3118 | |
3119 for (i = 0; i < data->totlayer; i++) { | |
3120 layer = &data->layers[i]; | |
3121 typeInfo = layerType_getInfo(layer->type); | |
3122 | |
3123 if (!(mask & CD_TYPE_AS_MASK(layer->type))) { | |
3124 /* pass */ | |
3125 } | |
3126 else if ((layer->flag & CD_FLAG_EXTERNAL) && (layer->flag & CD_F
LAG_IN_MEMORY)) { | |
3127 if (typeInfo->free) | |
3128 typeInfo->free(layer->data, totelem, typeInfo->s
ize); | |
3129 layer->flag &= ~CD_FLAG_IN_MEMORY; | |
3130 } | |
3131 } | |
3132 } | |
3133 | |
3134 void CustomData_external_read(CustomData *data, ID *id, CustomDataMask mask, int
totelem) | |
3135 { | |
3136 CustomDataExternal *external = data->external; | |
3137 CustomDataLayer *layer; | |
3138 CDataFile *cdf; | |
3139 CDataFileLayer *blay; | |
3140 char filename[FILE_MAX]; | |
3141 const LayerTypeInfo *typeInfo; | |
3142 int i, update = 0; | |
3143 | |
3144 if (!external) | |
3145 return; | |
3146 ········ | |
3147 for (i = 0; i < data->totlayer; i++) { | |
3148 layer = &data->layers[i]; | |
3149 typeInfo = layerType_getInfo(layer->type); | |
3150 | |
3151 if (!(mask & CD_TYPE_AS_MASK(layer->type))) { | |
3152 /* pass */ | |
3153 } | |
3154 else if (layer->flag & CD_FLAG_IN_MEMORY) { | |
3155 /* pass */ | |
3156 } | |
3157 else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read) { | |
3158 update = 1; | |
3159 } | |
3160 } | |
3161 | |
3162 if (!update) | |
3163 return; | |
3164 | |
3165 customdata_external_filename(filename, id, external); | |
3166 | |
3167 cdf = cdf_create(CDF_TYPE_MESH); | |
3168 if (!cdf_read_open(cdf, filename)) { | |
3169 fprintf(stderr, "Failed to read %s layer from %s.\n", layerType_
getName(layer->type), filename); | |
3170 return; | |
3171 } | |
3172 | |
3173 for (i = 0; i < data->totlayer; i++) { | |
3174 layer = &data->layers[i]; | |
3175 typeInfo = layerType_getInfo(layer->type); | |
3176 | |
3177 if (!(mask & CD_TYPE_AS_MASK(layer->type))) { | |
3178 /* pass */ | |
3179 } | |
3180 else if (layer->flag & CD_FLAG_IN_MEMORY) { | |
3181 /* pass */ | |
3182 } | |
3183 else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read) { | |
3184 blay = cdf_layer_find(cdf, layer->type, layer->name); | |
3185 | |
3186 if (blay) { | |
3187 if (cdf_read_layer(cdf, blay)) { | |
3188 if (typeInfo->read(cdf, layer->data, tot
elem)) { | |
3189 /* pass */ | |
3190 } | |
3191 else { | |
3192 break; | |
3193 } | |
3194 layer->flag |= CD_FLAG_IN_MEMORY; | |
3195 } | |
3196 else | |
3197 break; | |
3198 } | |
3199 } | |
3200 } | |
3201 | |
3202 cdf_read_close(cdf); | |
3203 cdf_free(cdf); | |
3204 } | |
3205 | |
3206 void CustomData_external_write(CustomData *data, ID *id, CustomDataMask mask, in
t totelem, int free) | |
3207 { | |
3208 CustomDataExternal *external = data->external; | |
3209 CustomDataLayer *layer; | |
3210 CDataFile *cdf; | |
3211 CDataFileLayer *blay; | |
3212 const LayerTypeInfo *typeInfo; | |
3213 int i, update = 0; | |
3214 char filename[FILE_MAX]; | |
3215 | |
3216 if (!external) | |
3217 return; | |
3218 | |
3219 /* test if there is anything to write */ | |
3220 for (i = 0; i < data->totlayer; i++) { | |
3221 layer = &data->layers[i]; | |
3222 typeInfo = layerType_getInfo(layer->type); | |
3223 | |
3224 if (!(mask & CD_TYPE_AS_MASK(layer->type))) { | |
3225 /* pass */ | |
3226 } | |
3227 else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) { | |
3228 update = 1; | |
3229 } | |
3230 } | |
3231 | |
3232 if (!update) | |
3233 return; | |
3234 | |
3235 /* make sure data is read before we try to write */ | |
3236 CustomData_external_read(data, id, mask, totelem); | |
3237 customdata_external_filename(filename, id, external); | |
3238 | |
3239 cdf = cdf_create(CDF_TYPE_MESH); | |
3240 | |
3241 for (i = 0; i < data->totlayer; i++) { | |
3242 layer = &data->layers[i]; | |
3243 typeInfo = layerType_getInfo(layer->type); | |
3244 | |
3245 if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->filesize) { | |
3246 if (layer->flag & CD_FLAG_IN_MEMORY) { | |
3247 cdf_layer_add(cdf, layer->type, layer->name, | |
3248 typeInfo->filesize(cdf, layer->dat
a, totelem)); | |
3249 } | |
3250 else { | |
3251 cdf_free(cdf); | |
3252 return; /* read failed for a layer! */ | |
3253 } | |
3254 } | |
3255 } | |
3256 | |
3257 if (!cdf_write_open(cdf, filename)) { | |
3258 fprintf(stderr, "Failed to open %s for writing.\n", filename); | |
3259 return; | |
3260 } | |
3261 | |
3262 for (i = 0; i < data->totlayer; i++) { | |
3263 layer = &data->layers[i]; | |
3264 typeInfo = layerType_getInfo(layer->type); | |
3265 | |
3266 if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) { | |
3267 blay = cdf_layer_find(cdf, layer->type, layer->name); | |
3268 | |
3269 if (cdf_write_layer(cdf, blay)) { | |
3270 if (typeInfo->write(cdf, layer->data, totelem))
{ | |
3271 /* pass */ | |
3272 } | |
3273 else { | |
3274 break; | |
3275 } | |
3276 } | |
3277 else { | |
3278 break; | |
3279 } | |
3280 } | |
3281 } | |
3282 | |
3283 if (i != data->totlayer) { | |
3284 fprintf(stderr, "Failed to write data to %s.\n", filename); | |
3285 cdf_free(cdf); | |
3286 return; | |
3287 } | |
3288 | |
3289 for (i = 0; i < data->totlayer; i++) { | |
3290 layer = &data->layers[i]; | |
3291 typeInfo = layerType_getInfo(layer->type); | |
3292 | |
3293 if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) { | |
3294 if (free) { | |
3295 if (typeInfo->free) | |
3296 typeInfo->free(layer->data, totelem, typ
eInfo->size); | |
3297 layer->flag &= ~CD_FLAG_IN_MEMORY; | |
3298 } | |
3299 } | |
3300 } | |
3301 | |
3302 cdf_write_close(cdf); | |
3303 cdf_free(cdf); | |
3304 } | |
3305 | |
3306 void CustomData_external_add(CustomData *data, ID *UNUSED(id), int type, int UNU
SED(totelem), const char *filename) | |
3307 { | |
3308 CustomDataExternal *external = data->external; | |
3309 CustomDataLayer *layer; | |
3310 int layer_index; | |
3311 | |
3312 layer_index = CustomData_get_active_layer_index(data, type); | |
3313 if (layer_index < 0) return; | |
3314 | |
3315 layer = &data->layers[layer_index]; | |
3316 | |
3317 if (layer->flag & CD_FLAG_EXTERNAL) | |
3318 return; | |
3319 | |
3320 if (!external) { | |
3321 external = MEM_callocN(sizeof(CustomDataExternal), "CustomDataEx
ternal"); | |
3322 data->external = external; | |
3323 } | |
3324 BLI_strncpy(external->filename, filename, sizeof(external->filename)); | |
3325 | |
3326 layer->flag |= CD_FLAG_EXTERNAL | CD_FLAG_IN_MEMORY; | |
3327 } | |
3328 | |
3329 void CustomData_external_remove(CustomData *data, ID *id, int type, int totelem) | |
3330 { | |
3331 CustomDataExternal *external = data->external; | |
3332 CustomDataLayer *layer; | |
3333 //char filename[FILE_MAX]; | |
3334 int layer_index; // i, remove_file; | |
3335 | |
3336 layer_index = CustomData_get_active_layer_index(data, type); | |
3337 if (layer_index < 0) return; | |
3338 | |
3339 layer = &data->layers[layer_index]; | |
3340 | |
3341 if (!external) | |
3342 return; | |
3343 | |
3344 if (layer->flag & CD_FLAG_EXTERNAL) { | |
3345 if (!(layer->flag & CD_FLAG_IN_MEMORY)) | |
3346 CustomData_external_read(data, id, CD_TYPE_AS_MASK(layer
->type), totelem); | |
3347 | |
3348 layer->flag &= ~CD_FLAG_EXTERNAL; | |
3349 | |
3350 #if 0 | |
3351 remove_file = 1; | |
3352 for (i = 0; i < data->totlayer; i++) | |
3353 if (data->layers[i].flag & CD_FLAG_EXTERNAL) | |
3354 remove_file = 0; | |
3355 | |
3356 if (remove_file) { | |
3357 customdata_external_filename(filename, id, external); | |
3358 cdf_remove(filename); | |
3359 CustomData_external_free(data); | |
3360 } | |
3361 #endif | |
3362 } | |
3363 } | |
3364 | |
3365 bool CustomData_external_test(CustomData *data, int type) | |
3366 { | |
3367 CustomDataLayer *layer; | |
3368 int layer_index; | |
3369 | |
3370 layer_index = CustomData_get_active_layer_index(data, type); | |
3371 if (layer_index < 0) return false; | |
3372 | |
3373 layer = &data->layers[layer_index]; | |
3374 return (layer->flag & CD_FLAG_EXTERNAL) != 0; | |
3375 } | |
3376 | |
3377 #if 0 | |
3378 void CustomData_external_remove_object(CustomData *data, ID *id) | |
3379 { | |
3380 CustomDataExternal *external = data->external; | |
3381 char filename[FILE_MAX]; | |
3382 | |
3383 if (!external) | |
3384 return; | |
3385 | |
3386 customdata_external_filename(filename, id, external); | |
3387 cdf_remove(filename); | |
3388 CustomData_external_free(data); | |
3389 } | |
3390 #endif | |
3391 | |
LEFT | RIGHT |