diff options
author | Campbell Barton <ideasman42@gmail.com> | 2018-02-06 15:06:23 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2018-02-06 15:06:23 +0300 |
commit | 5376c739f5bf4029e0a32946e9945a732feba217 (patch) | |
tree | b3494e69541d22edf5b971106b532e3a2a2577cd /source/blender | |
parent | 98dcd33238e44984d31d96e2ffd0191a5d1cf7b6 (diff) | |
parent | 486e2547eea3f12bfde70f2526dde08f39a8722b (diff) |
Merge branch 'master' into blender2.8
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/bmesh/tools/bmesh_bevel.c | 174 | ||||
-rw-r--r-- | source/blender/editors/include/ED_object.h | 6 | ||||
-rw-r--r-- | source/blender/editors/object/object_edit.c | 7 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_object_enums.h | 49 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_object_types.h | 21 |
6 files changed, 231 insertions, 27 deletions
diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt index c2fac8fc7d7..7c3b20e03ab 100644 --- a/source/blender/CMakeLists.txt +++ b/source/blender/CMakeLists.txt @@ -67,6 +67,7 @@ set(SRC_DNA_INC ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_node_types.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_object_fluidsim.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_object_force.h + ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_object_enums.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_object_types.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_outliner_types.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_packedFile_types.h diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 51238c92505..e89f54349f7 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -2170,7 +2170,6 @@ static void adjust_offsets(BevelParams *bp) v->visited = true; if (vnext->visited) { if (vnext != vchainstart) { - printf("WHOOPS, adjusting offsets, expected cycle!\n"); break; } adjust_the_cycle_or_chain(vchainstart, true); @@ -3187,6 +3186,173 @@ static void build_square_in_vmesh(BevelParams *bp, BMesh *bm, BevVert *bv, VMesh } } +/* copy whichever of a and b is closer to v into r */ +static void closer_v3_v3v3v3(float r[3], float a[3], float b[3], float v[3]) +{ + if (len_squared_v3v3(a, v) <= len_squared_v3v3(b, v)) + copy_v3_v3(r, a); + else + copy_v3_v3(r, b); +} + +/* Special case of VMesh when profile == 1 and there are 3 or more beveled edges. + * We want the effect of parallel offset lines (n/2 of them) on each side of the center, for even n. + * Wherever they intersect with each other between two successive beveled edges, those intersections + * are part of the vmesh rings. + * We have to move the boundary edges too -- the usual method is to make one profile plane between + * successive BoundVerts, but for the effect we want here, there will be two planes, one on each side + * of the original edge. + */ +static VMesh *square_out_adj_vmesh(BevelParams *bp, BevVert *bv) +{ + int n, ns, ns2, odd, i, j, k, ikind, im1, clstride; + float bndco[3], dir1[3], dir2[3], co1[3], co2[3], meet1[3], meet2[3], v1co[3], v2co[3]; + float *on_edge_cur, *on_edge_prev, *p; + float ns2inv, finalfrac, ang; + BoundVert *bndv; + EdgeHalf *e1, *e2; + VMesh *vm; + float *centerline; + + n = bv->vmesh->count; + ns = bv->vmesh->seg; + ns2 = ns / 2; + odd = ns % 2; + ns2inv = 1.0f / (float) ns2; + vm = new_adj_vmesh(bp->mem_arena, n, ns, bv->vmesh->boundstart); + clstride = 3 * (ns2 + 1); + centerline = MEM_mallocN(clstride * n * sizeof(float), "bevel"); + + /* find on_edge, place on bndv[i]'s elast where offset line would meet, + * averaging with position where next sector's offset line would meet */ + bndv = vm->boundstart; + for (i = 0; i < n; i++) { + copy_v3_v3(bndco, bndv->nv.co); + e1 = bndv->efirst; + e2 = bndv->elast; + sub_v3_v3v3(dir1, e1->e->v1->co, e1->e->v2->co); + sub_v3_v3v3(dir2, e2->e->v1->co, e2->e->v2->co); + add_v3_v3v3(co1, bndco, dir1); + add_v3_v3v3(co2, bndco, dir2); + /* intersect e1 with line through bndv parallel to e2 to get v1co */ + ikind = isect_line_line_v3(e1->e->v1->co, e1->e->v2->co, bndco, co2, meet1, meet2); + + if (ikind == 0) { + /* Placeholder: this should get eliminated by min dist test with adjacent edge */ + mid_v3_v3v3(v1co, e1->e->v1->co, e1->e->v2->co); + } + else { + /* if the lines are skew (ikind == 2), want meet1 which is on e1 */ + copy_v3_v3(v1co, meet1); + } + /* intersect e2 with line through bndv parallel to e1 to get v2co */ + ikind = isect_line_line_v3(e2->e->v1->co, e2->e->v2->co, bndco, co1, meet1, meet2); + if (ikind == 0) { + mid_v3_v3v3(v2co, e2->e->v1->co, e2->e->v2->co); + } + else { + copy_v3_v3(v2co, meet1); + } + + /* want on_edge[i] to be min dist to bv->v of v2co and the v1co of next iteration */ + on_edge_cur = centerline + clstride * i; + on_edge_prev = centerline + clstride * ((i == 0) ? n - 1 : i - 1); + if (i == 0) { + copy_v3_v3(on_edge_cur, v2co); + copy_v3_v3(on_edge_prev, v1co); + } + else if (i == n - 1) { + closer_v3_v3v3v3(on_edge_cur, on_edge_cur, v2co, bv->v->co); + closer_v3_v3v3v3(on_edge_prev, on_edge_prev, v1co, bv->v->co); + } + else { + copy_v3_v3(on_edge_cur, v2co); + closer_v3_v3v3v3(on_edge_prev, on_edge_prev, v1co, bv->v->co); + } + bndv = bndv->next; + } + + /* fill in rest of centerlines by interpolation */ + copy_v3_v3(co2, bv->v->co); + bndv = vm->boundstart; + for (i = 0; i < n; i++) { + if (odd) { + ang = 0.5f * angle_v3v3v3(bndv->nv.co, co1, bndv->next->nv.co); + if (ang > BEVEL_SMALL_ANG) { + /* finalfrac is length along arms of isoceles triangle with top angle 2*ang + * such that the base of the triangle is 1. + * This is used in interpolation along centerline in odd case. + * To avoid too big a drop from bv, cap finalfrac a 0.8 arbitrarily */ + finalfrac = 0.5f / sin(ang); + if (finalfrac > 0.8f) + finalfrac = 0.8f; + } + else { + finalfrac = 0.8f; + } + ns2inv = 1.0f / (ns2 + finalfrac); + } + + p = centerline + clstride * i; + copy_v3_v3(co1, p); + p += 3; + for (j = 1; j <= ns2; j++) { + interp_v3_v3v3(p, co1, co2, j * ns2inv); + p += 3; + } + bndv = bndv->next; + } + + /* coords of edges and mid or near-mid line */ + bndv = vm->boundstart; + for (i = 0; i < n; i++) { + copy_v3_v3(co1, bndv->nv.co); + copy_v3_v3(co2, centerline + clstride * (i == 0 ? n - 1 : i - 1)); + for (j = 0; j < ns2 + odd; j++) { + interp_v3_v3v3(mesh_vert(vm, i, j, 0)->co, co1, co2, j * ns2inv); + } + copy_v3_v3(co2, centerline + clstride * i); + for (k = 1; k <= ns2; k++) { + interp_v3_v3v3(mesh_vert(vm, i, 0, k)->co, co1, co2, k * ns2inv); + } + bndv = bndv->next; + } + if (!odd) + copy_v3_v3(mesh_vert(vm, 0, ns2, ns2)->co, bv->v->co); + vmesh_copy_equiv_verts(vm); + + /* fill in interior points by interpolation from edges to centerlines */ + bndv = vm->boundstart; + for (i = 0; i < n; i++) { + im1 = (i == 0) ? n - 1 : i - 1; + for (j = 1; j < ns2 + odd; j++) { + for (k = 1; k <= ns2; k++) { + ikind = isect_line_line_v3( + mesh_vert(vm, i, 0, k)->co, centerline + clstride * im1 + 3 * k, + mesh_vert(vm, i, j, 0)->co, centerline + clstride * i + 3 * j, + meet1, meet2); + if (ikind == 0) { + /* how can this happen? fall back on interpolation in one direction if it does */ + interp_v3_v3v3(mesh_vert(vm, i, j, k)->co, + mesh_vert(vm, i, 0, k)->co, centerline + clstride * im1 + 3 * k, j * ns2inv); + } + else if (ikind == 1) { + copy_v3_v3(mesh_vert(vm, i, j, k)->co, meet1); + } + else { + mid_v3_v3v3(mesh_vert(vm, i, j, k)->co, meet1, meet2); + } + } + } + bndv = bndv->next; + } + + vmesh_copy_equiv_verts(vm); + + MEM_freeN(centerline); + return vm; +} + /* * Given that the boundary is built and the boundary BMVerts have been made, * calculate the positions of the interior mesh points for the M_ADJ pattern, @@ -3209,9 +3375,13 @@ static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv) odd = ns % 2; BLI_assert(n >= 3 && ns > 1); + vpipe = pipe_test(bv); - if (vpipe) { + if (bp->pro_super_r == PRO_SQUARE_R && bv->selcount >= 3 && !odd) { + vm1 = square_out_adj_vmesh(bp, bv); + } + else if (vpipe) { vm1 = pipe_adj_vmesh(bp, bv, vpipe); } else if (tri_corner_test(bp, bv)) { diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 7ceab58aa33..5c04614f4f1 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -57,6 +57,8 @@ struct PropertyRNA; struct EnumPropertyItem; struct EvaluationContext; +#include "DNA_object_enums.h" + /* object_edit.c */ struct Object *ED_object_context(struct bContext *C); /* context.object */ struct Object *ED_object_active_context(struct bContext *C); /* context.object or context.active_object */ @@ -114,8 +116,8 @@ struct Base *ED_object_add_duplicate(struct Main *bmain, struct Scene *scene, st void ED_object_parent(struct Object *ob, struct Object *parent, const int type, const char *substr); -bool ED_object_mode_compat_set(struct bContext *C, struct Object *ob, int mode, struct ReportList *reports); -void ED_object_toggle_modes(struct bContext *C, int mode); +bool ED_object_mode_compat_set(struct bContext *C, struct Object *ob, eObjectMode mode, struct ReportList *reports); +void ED_object_toggle_modes(struct bContext *C, eObjectMode mode); /* bitflags for enter/exit editmode */ #define EM_FREEDATA 1 diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index c9dc9e6952c..5255f8b507c 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1479,7 +1479,7 @@ static const EnumPropertyItem *object_mode_set_itemsf( return item; } -static const char *object_mode_op_string(int mode) +static const char *object_mode_op_string(eObjectMode mode) { if (mode & OB_MODE_EDIT) return "OBJECT_OT_editmode_toggle"; @@ -1545,7 +1545,7 @@ static bool object_mode_compat_test(Object *ob, eObjectMode mode) * * This is so each mode's exec function can call */ -bool ED_object_mode_compat_set(bContext *C, Object *ob, int mode, ReportList *reports) +bool ED_object_mode_compat_set(bContext *C, Object *ob, eObjectMode mode, ReportList *reports) { bool ok; if (!ELEM(ob->mode, mode, OB_MODE_OBJECT)) { @@ -1664,8 +1664,7 @@ void OBJECT_OT_mode_set(wmOperatorType *ot) RNA_def_property_flag(prop, PROP_SKIP_SAVE); } - -void ED_object_toggle_modes(bContext *C, int mode) +void ED_object_toggle_modes(bContext *C, eObjectMode mode) { if (mode != OB_MODE_OBJECT) { const char *opstring = object_mode_op_string(mode); diff --git a/source/blender/makesdna/DNA_object_enums.h b/source/blender/makesdna/DNA_object_enums.h new file mode 100644 index 00000000000..58f9e29297f --- /dev/null +++ b/source/blender/makesdna/DNA_object_enums.h @@ -0,0 +1,49 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file DNA_object_enums.h + * \ingroup DNA + * + * Enums typedef's for use in public headers. + */ + +#ifndef __DNA_OBJECT_ENUMS_H__ +#define __DNA_OBJECT_ENUMS_H__ + +/* Object.mode */ +typedef enum eObjectMode { + OB_MODE_OBJECT = 0, + OB_MODE_EDIT = 1 << 0, + OB_MODE_SCULPT = 1 << 1, + OB_MODE_VERTEX_PAINT = 1 << 2, + OB_MODE_WEIGHT_PAINT = 1 << 3, + OB_MODE_TEXTURE_PAINT = 1 << 4, + OB_MODE_PARTICLE_EDIT = 1 << 5, + OB_MODE_POSE = 1 << 6, + OB_MODE_GPENCIL = 1 << 7, /* NOTE: Just a dummy to make the UI nicer */ +} eObjectMode; + +/* Any mode where the brush system is used. */ +#define OB_MODE_ALL_PAINT (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT) + +/* Any mode that uses Object.sculpt. */ +#define OB_MODE_ALL_SCULPT (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT) + +#endif /* __DNA_OBJECT_ENUMS_H__ */ diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 7c3ef5e72be..17ee64fd7d8 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -33,6 +33,8 @@ #ifndef __DNA_OBJECT_TYPES_H__ #define __DNA_OBJECT_TYPES_H__ +#include "DNA_object_enums.h" + #include "DNA_defs.h" #include "DNA_listBase.h" #include "DNA_ID.h" @@ -711,25 +713,6 @@ enum { OB_DUPLI_FLAG_RENDER = 1 << 1, }; -/* ob->mode */ -typedef enum eObjectMode { - OB_MODE_OBJECT = 0, - OB_MODE_EDIT = 1 << 0, - OB_MODE_SCULPT = 1 << 1, - OB_MODE_VERTEX_PAINT = 1 << 2, - OB_MODE_WEIGHT_PAINT = 1 << 3, - OB_MODE_TEXTURE_PAINT = 1 << 4, - OB_MODE_PARTICLE_EDIT = 1 << 5, - OB_MODE_POSE = 1 << 6, - OB_MODE_GPENCIL = 1 << 7, /* NOTE: Just a dummy to make the UI nicer */ -} eObjectMode; - -/* any mode where the brush system is used */ -#define OB_MODE_ALL_PAINT (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT) - -/* any mode that uses ob->sculpt */ -#define OB_MODE_ALL_SCULPT (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT) - #define MAX_DUPLI_RECUR 8 #ifdef __cplusplus |