~ubuntu-branches/ubuntu/saucy/blender/saucy-proposed

« back to all changes in this revision

Viewing changes to source/blender/bmesh/tools/BME_bevel.c

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2013-03-06 12:08:47 UTC
  • mfrom: (1.5.1) (14.1.8 experimental)
  • Revision ID: package-import@ubuntu.com-20130306120847-frjfaryb2zrotwcg
Tags: 2.66a-1ubuntu1
* Resynchronize with Debian (LP: #1076930, #1089256, #1052743, #999024,
  #1122888, #1147084)
* debian/control:
  - Lower build-depends on libavcodec-dev since we're not
    doing the libav9 transition in Ubuntu yet

Show diffs side-by-side

added added

removed removed

Lines of Context:
38
38
#include "BLI_ghash.h"
39
39
#include "BLI_memarena.h"
40
40
 
41
 
#include "BKE_utildefines.h"
42
41
#include "BKE_tessmesh.h"
43
42
#include "BKE_bmesh.h"
44
43
 
67
66
 
68
67
/* ------- Bevel code starts here -------- */
69
68
 
70
 
BME_TransData_Head *BME_init_transdata(int bufsize)
 
69
static BME_TransData_Head *BME_init_transdata(int bufsize)
71
70
{
72
71
        BME_TransData_Head *td;
73
72
 
74
73
        td = MEM_callocN(sizeof(BME_TransData_Head), "BM transdata header");
75
 
        td->gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "BME_init_transdata gh");
 
74
        td->gh = BLI_ghash_ptr_new("BME_init_transdata gh");
76
75
        td->ma = BLI_memarena_new(bufsize, "BME_TransData arena");
77
76
        BLI_memarena_use_calloc(td->ma);
78
77
 
86
85
        MEM_freeN(td);
87
86
}
88
87
 
89
 
BME_TransData *BME_assign_transdata(BME_TransData_Head *td, BMesh *bm, BMVert *v,
90
 
                                    float *co, float *org, float *vec, float *loc,
91
 
                                    float factor, float weight, float maxfactor, float *max)
 
88
static BME_TransData *BME_assign_transdata(BME_TransData_Head *td, BMesh *bm, BMVert *v,
 
89
                                           float *co, float *org, float *vec, float *loc,
 
90
                                           float factor, float weight, float maxfactor, float *max)
92
91
{
93
92
        BME_TransData *vtd;
94
 
        int is_new = 0;
 
93
        int is_new = false;
95
94
 
96
95
        if (v == NULL) {
97
96
                return NULL;
101
100
                vtd = BLI_memarena_alloc(td->ma, sizeof(*vtd));
102
101
                BLI_ghash_insert(td->gh, v, vtd);
103
102
                td->len++;
104
 
                is_new = 1;
 
103
                is_new = true;
105
104
        }
106
105
 
107
106
        vtd->bm = bm;
141
140
}
142
141
 
143
142
/* a hack (?) to use the transdata memarena to allocate floats for use with the max limits */
144
 
float *BME_new_transdata_float(BME_TransData_Head *td)
 
143
static float *BME_new_transdata_float(BME_TransData_Head *td)
145
144
{
146
145
        return BLI_memarena_alloc(td->ma, sizeof(float));
147
146
}
152
151
{
153
152
        BMFace *f;
154
153
        BMEdge *e;
155
 
        int done;
 
154
        bool done;
156
155
 
157
156
        if (v->e) {
158
 
                done = 0;
 
157
                done = false;
159
158
                while (!done) {
160
 
                        done = 1;
 
159
                        done = true;
161
160
                        e = v->e; /*loop the edge looking for a edge to dissolve*/
162
161
                        do {
163
162
                                f = NULL;
165
164
                                        f = bmesh_jfke(bm, e->l->f, e->l->radial_next->f, e);
166
165
                                }
167
166
                                if (f) {
168
 
                                        done = 0;
 
167
                                        done = false;
169
168
                                        break;
170
169
                                }
171
170
                                e = bmesh_disk_edge_next(e, v);
172
171
                        } while (e != v->e);
173
172
                }
174
 
                BM_vert_collapse_edge(bm, v->e, v, TRUE);
175
 
                // bmesh_jekv(bm, v->e, v, FALSE);
 
173
                BM_vert_collapse_edge(bm, v->e, v, true);
 
174
                // bmesh_jekv(bm, v->e, v, false);
176
175
        }
177
176
}
178
177
 
195
194
 * the bevel operation as a whole based on the relationship between v1 and v2
196
195
 * (won't necessarily be a vec from v1->co to v2->co, though it probably will be);
197
196
 * the return value is -1 for failure, 0 if we used vert co's, and 1 if we used transform origins */
198
 
static int BME_bevel_get_vec(float *vec, BMVert *v1, BMVert *v2, BME_TransData_Head *td)
 
197
static int BME_bevel_get_vec(float vec[3], BMVert *v1, BMVert *v2, BME_TransData_Head *td)
199
198
{
200
199
        BME_TransData *vtd1, *vtd2;
201
200
 
234
233
 * vec2 is the direction of projection (pointing away from vec1)
235
234
 * up_vec is used for orientation (expected to be normalized)
236
235
 * returns the length of the projected vector that lies along vec1 */
237
 
static float BME_bevel_project_vec(float *vec1, float *vec2, float *up_vec, int is_forward, BME_TransData_Head *UNUSED(td))
 
236
static float BME_bevel_project_vec(float *vec1, float *vec2, float *up_vec,
 
237
                                   int is_forward, BME_TransData_Head *UNUSED(td))
238
238
{
239
239
        float factor, vec3[3], tmp[3], c1, c2;
240
240
 
264
264
 * using the vert and the loop passed, get or make the split vert, set its coordinates
265
265
 * and transform properties, and set the max limits.
266
266
 * Finally, return the split vert. */
267
 
static BMVert *BME_bevel_split_edge(BMesh *bm, BMVert *v, BMVert *v1, BMLoop *l, float *up_vec, float value, BME_TransData_Head *td)
 
267
static BMVert *BME_bevel_split_edge(BMesh *bm, BMVert *v, BMVert *v1, BMLoop *l,
 
268
                                    float *up_vec, float value, BME_TransData_Head *td)
268
269
{
269
270
        BME_TransData *vtd, *vtd1, *vtd2;
270
271
        BMVert *sv, *v2, *v3, *ov;
496
497
}
497
498
#endif
498
499
 
499
 
static BMLoop *BME_bevel_edge(BMesh *bm, BMLoop *l, float value, int UNUSED(options), float *up_vec, BME_TransData_Head *td)
 
500
static BMLoop *BME_bevel_edge(BMesh *bm, BMLoop *l, float value, int UNUSED(options),
 
501
                              float *up_vec, BME_TransData_Head *td)
500
502
{
501
503
        BMVert *v1, *v2, *kv;
502
504
        BMLoop *kl = NULL, *nl;
537
539
                se = l->next->e;
538
540
                jf = NULL;
539
541
                if (kl->v == kv) {
540
 
                        BM_face_split(bm, kl->f, kl->prev->v, kl->next->v, &nl, kl->prev->e, TRUE);
 
542
                        BM_face_split(bm, kl->f, kl->prev->v, kl->next->v, &nl, kl->prev->e, true);
541
543
                        ke = kl->e;
542
544
                        /* BMESH-TODO: jfke doesn't handle customdata */
543
545
                        jf = bmesh_jfke(bm, kl->prev->radial_next->f, kl->f, kl->prev->e);
544
 
                        BM_vert_collapse_edge(bm, ke, kv, FALSE);
 
546
                        BM_vert_collapse_edge(bm, ke, kv, false);
545
547
                }
546
548
                else {
547
 
                        BM_face_split(bm, kl->f, kl->next->next->v, kl->v, &nl, kl->next->e, TRUE);
 
549
                        BM_face_split(bm, kl->f, kl->next->next->v, kl->v, &nl, kl->next->e, true);
548
550
                        ke = kl->e;
549
551
                        /* BMESH-TODO: jfke doesn't handle customdata */
550
552
                        jf = bmesh_jfke(bm, kl->next->radial_next->f, kl->f, kl->next->e);
551
 
                        BM_vert_collapse_edge(bm, ke, kv, FALSE);
 
553
                        BM_vert_collapse_edge(bm, ke, kv, false);
552
554
                }
553
555
                /* find saved loop pointer */
554
556
                l = se->l;
583
585
                se = l->e;
584
586
                jf = NULL;
585
587
                if (kl->v == kv) {
586
 
                        BM_face_split(bm, kl->f, kl->prev->v, kl->next->v, &nl, kl->prev->e, TRUE);
 
588
                        BM_face_split(bm, kl->f, kl->prev->v, kl->next->v, &nl, kl->prev->e, true);
587
589
                        ke = kl->e;
588
590
                        /* BMESH-TODO: jfke doesn't handle customdata */
589
591
                        jf = bmesh_jfke(bm, kl->prev->radial_next->f, kl->f, kl->prev->e);
590
 
                        BM_vert_collapse_edge(bm, ke, kv, FALSE);
 
592
                        BM_vert_collapse_edge(bm, ke, kv, false);
591
593
                }
592
594
                else {
593
 
                        BM_face_split(bm, kl->f, kl->next->next->v, kl->v, &nl, kl->next->e, TRUE);
 
595
                        BM_face_split(bm, kl->f, kl->next->next->v, kl->v, &nl, kl->next->e, true);
594
596
                        ke = kl->e;
595
597
                        /* BMESH-TODO: jfke doesn't handle customdata */
596
598
                        jf = bmesh_jfke(bm, kl->next->radial_next->f, kl->f, kl->next->e);
597
 
                        BM_vert_collapse_edge(bm, ke, kv, FALSE);
 
599
                        BM_vert_collapse_edge(bm, ke, kv, false);
598
600
                }
599
601
                /* find saved loop pointer */
600
602
                l = se->l;
605
607
        }
606
608
 
607
609
        if (!BMO_elem_flag_test(bm, v1, BME_BEVEL_NONMAN) || !BMO_elem_flag_test(bm, v2, BME_BEVEL_NONMAN)) {
608
 
                BM_face_split(bm, f, v2, v1, &l, e, TRUE);
 
610
                BM_face_split(bm, f, v2, v1, &l, e, true);
609
611
                BMO_elem_flag_enable(bm, l->e, BME_BEVEL_BEVEL);
610
612
                l = l->radial_next;
611
613
        }
617
619
        return l;
618
620
}
619
621
 
620
 
static BMLoop *BME_bevel_vert(BMesh *bm, BMLoop *l, float value, int UNUSED(options), float *up_vec, BME_TransData_Head *td)
 
622
static BMLoop *BME_bevel_vert(BMesh *bm, BMLoop *l, float value, int UNUSED(options),
 
623
                              float up_vec[3], BME_TransData_Head *td)
621
624
{
622
625
        BMVert *v1, *v2;
623
626
        /* BMFace *f; */ /* UNUSED */
633
636
        l = l->next->next;
634
637
 
635
638
        /* "cut off" this corner */
636
 
        /* f = */ BM_face_split(bm, l->f, v2, v1, NULL, l->e, TRUE);
 
639
        /* f = */ BM_face_split(bm, l->f, v2, v1, NULL, l->e, true);
637
640
 
638
641
        return l;
639
642
}
686
689
                         BMO_elem_flag_test(bm, l->v, BME_BEVEL_ORIG) &&
687
690
                         !BMO_elem_flag_test(bm, l->prev->e, BME_BEVEL_BEVEL))
688
691
                {
689
 
                        max = 1.0f;
690
 
                        l = BME_bevel_vert(bm, l, value, options, up_vec, td);
 
692
                        /* avoid making double vertices [#33438] */
 
693
                        BME_TransData *vtd;
 
694
                        vtd = BME_get_transdata(td, l->v);
 
695
                        if (vtd->weight == 0.0f) {
 
696
                                BMO_elem_flag_disable(bm, l->v, BME_BEVEL_BEVEL);
 
697
                        }
 
698
                        else {
 
699
                                max = 1.0f;
 
700
                                l = BME_bevel_vert(bm, l, value, options, up_vec, td);
 
701
                        }
691
702
                }
692
703
        }
693
704
 
810
821
        }
811
822
 
812
823
        /* return cosf(angle_diff + 0.001f); */ /* compare with dot product */
813
 
        return (angle_diff / tot_angle) * (M_PI / 2);
 
824
        return (angle_diff / tot_angle) * (float)(M_PI / 2.0);
814
825
}
815
826
 
816
827
static void BME_bevel_add_vweight(BME_TransData_Head *td, BMesh *bm, BMVert *v, float weight, float factor, int options)
894
905
        int count;
895
906
        float weight;
896
907
        BMIter iter;
897
 
        const float threshold = (options & BME_BEVEL_ANGLE) ? cosf(angle + 0.001) : 0.0f;
 
908
        const float threshold = (options & BME_BEVEL_ANGLE) ? cosf(angle + 0.001f) : 0.0f;
898
909
 
899
910
        BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
900
911
                weight = 0.0f;
945
956
        }
946
957
}
947
958
 
948
 
static BMesh *BME_bevel_initialize(BMesh *bm, int options, int UNUSED(defgrp_index), float angle, BME_TransData_Head *td)
 
959
static BMesh *BME_bevel_initialize(BMesh *bm, int options,
 
960
                                   int UNUSED(defgrp_index), float angle, BME_TransData_Head *td)
949
961
{
950
962
        BMVert *v /*, *v2 */;
951
963
        BMEdge *e /*, *curedg */;
953
965
        BMIter iter;
954
966
        int /* wire, */ len;
955
967
 
956
 
        /* tag non-manifold geometr */
 
968
        /* tag non-manifold geometry */
957
969
        BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
958
970
                BMO_elem_flag_enable(bm, v, BME_BEVEL_ORIG);
959
971
                if (v->e) {
1024
1036
#endif
1025
1037
 
1026
1038
/**
1027
 
 *                      BME_bevel_mesh
1028
 
 *
1029
 
 *      Mesh beveling tool:
1030
 
 *
1031
 
 *      Bevels an entire mesh. It currently uses the flags of
1032
 
 *      its vertices and edges to track topological changes.
1033
 
 *  The parameter "value" is the distance to inset (should be negative).
1034
 
 *  The parameter "options" is not currently used.
1035
 
 *
1036
 
 *      Returns -
1037
 
 *  A BMesh pointer to the BM passed as a parameter.
 
1039
 * BME_bevel_mesh
 
1040
 *
 
1041
 * Mesh beveling tool:
 
1042
 *
 
1043
 * Bevels an entire mesh. It currently uses the flags of
 
1044
 * its vertices and edges to track topological changes.
 
1045
 * The parameter "value" is the distance to inset (should be negative).
 
1046
 * The parameter "options" is not currently used.
 
1047
 *
 
1048
 * \return A BMesh pointer to the BM passed as a parameter.
1038
1049
 */
1039
1050
 
1040
 
static BMesh *BME_bevel_mesh(BMesh *bm, float value, int UNUSED(res), int options, int UNUSED(defgrp_index), BME_TransData_Head *td)
 
1051
static BMesh *BME_bevel_mesh(BMesh *bm, float value, int UNUSED(res), int options,
 
1052
                             int UNUSED(defgrp_index), BME_TransData_Head *td)
1041
1053
{
1042
1054
        BMVert *v;
1043
1055
        BMEdge *e, *curedge;
1057
1069
        /* get rid of beveled edge */
1058
1070
        BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
1059
1071
                if (BMO_elem_flag_test(bm, e, BME_BEVEL_BEVEL) && BMO_elem_flag_test(bm, e, BME_BEVEL_ORIG)) {
1060
 
                        BM_faces_join_pair(bm, e->l->f, e->l->radial_next->f, e, TRUE);
 
1072
                        BM_faces_join_pair(bm, e->l->f, e->l->radial_next->f, e, true);
1061
1073
                }
1062
1074
        }
1063
1075
 
1071
1083
                                if (l->v != v) l = l->next;
1072
1084
                                if (l2->v != v) l2 = l2->next;
1073
1085
                                if (l->f->len > 3)
1074
 
                                        BM_face_split(bm, l->f, l->next->v, l->prev->v, &l, l->e, TRUE);  /* clip this corner off */
 
1086
                                        BM_face_split(bm, l->f, l->next->v, l->prev->v, &l, l->e, true);  /* clip this corner off */
1075
1087
                                if (l2->f->len > 3)
1076
 
                                        BM_face_split(bm, l2->f, l2->next->v, l2->prev->v, &l, l2->e, TRUE);  /* clip this corner off */
 
1088
                                        BM_face_split(bm, l2->f, l2->next->v, l2->prev->v, &l, l2->e, true);  /* clip this corner off */
1077
1089
                                curedge = bmesh_disk_edge_next(curedge, v);
1078
1090
                        } while (curedge != v->e);
1079
1091
                        BME_Bevel_Dissolve_Disk(bm, v);
1092
1104
        return bm;
1093
1105
}
1094
1106
 
1095
 
BMesh *BME_bevel(BMEditMesh *em, float value, int res, int options, int defgrp_index, float angle,
1096
 
                 BME_TransData_Head **rtd, int do_tessface)
 
1107
BMesh *BME_bevel(BMesh *bm, float value, int res, int options, int defgrp_index, float angle,
 
1108
                 BME_TransData_Head **rtd)
1097
1109
{
1098
 
        BMesh *bm = em->bm;
1099
1110
        BMVert *v;
1100
1111
        BMIter iter;
1101
1112
 
1102
1113
        BME_TransData_Head *td;
1103
1114
        BME_TransData *vtd;
1104
1115
        int i;
1105
 
        double fac = 1, d;
 
1116
        double fac = 1.0, d;
1106
1117
 
1107
1118
        td = BME_init_transdata(BLI_MEMARENA_STD_BUFSIZE);
1108
1119
        /* recursion math courtesy of Martin Poirier (theeth) */
1109
1120
        for (i = 0; i < res - 1; i++) {
1110
 
                if (i == 0) fac += 1.0f / 3.0f; else fac += 1.0f / (3 * i * 2.0f);
 
1121
                if (i == 0) fac += 1.0 / 3.0;
 
1122
                else        fac += 1.0 / (3.0 * i * 2.0);
1111
1123
        }
1112
 
        d = 1.0f / fac;
 
1124
        d = 1.0 / fac;
 
1125
 
 
1126
        BM_mesh_elem_toolflags_ensure(bm);
1113
1127
 
1114
1128
        for (i = 0; i < res || (res == 0 && i == 0); i++) {
1115
1129
                BMO_push(bm, NULL);
1122
1136
                BMO_pop(bm);
1123
1137
        }
1124
1138
 
1125
 
        /* possibly needed when running as a tool (which is no longer functional)
1126
 
         * but keep as an optioin for now */
1127
 
        if (do_tessface) {
1128
 
                BMEdit_RecalcTessellation(em);
1129
 
        }
1130
 
 
1131
1139
        /* interactive preview? */
1132
1140
        if (rtd) {
1133
1141
                *rtd = td;
1143
1151
                        else {
1144
1152
                                d = value;
1145
1153
                        }
1146
 
                        madd_v3_v3v3fl(v->co, vtd->org, vtd->vec, vtd->factor * d);
 
1154
                        madd_v3_v3v3fl(v->co, vtd->org, vtd->vec, vtd->factor * (float)d);
1147
1155
                }
1148
1156
        }
1149
1157