diff options
author | Antony Riakiotakis <kalast@gmail.com> | 2015-05-07 15:10:00 +0300 |
---|---|---|
committer | Antony Riakiotakis <kalast@gmail.com> | 2015-05-07 15:10:00 +0300 |
commit | 249b3cca61f2d6978939ef7399a2a8183811af91 (patch) | |
tree | 7754e424b8f078b38fefca277ed266d9429bd68c | |
parent | 429741ac198455564806fdbe351d666258711658 (diff) | |
parent | e39ec27bbaebcb85b2541e9756b408c554f602cb (diff) |
Merge branch 'master' into gooseberry
23 files changed, 488 insertions, 179 deletions
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_VertexProxy.rst b/doc/python_api/rst/bge_types/bge.types.KX_VertexProxy.rst index 73d692770d6..d1bd6758cbc 100644 --- a/doc/python_api/rst/bge_types/bge.types.KX_VertexProxy.rst +++ b/doc/python_api/rst/bge_types/bge.types.KX_VertexProxy.rst @@ -25,6 +25,12 @@ base class --- :class:`SCA_IObject` :type: Vector((u, v)) + .. attribute:: uvs + + A list of all the texture coordinates of the vertex. + + :type: list of Vector((u, v)) + .. attribute:: normal The normal of the vertex. @@ -120,18 +126,24 @@ base class --- :class:`SCA_IObject` :arg pos: the new position for this vertex in local coordinates. - .. method:: getUV() + .. method:: getUV(index=0) Gets the UV (texture) coordinates of this vertex. + :arg index: the UV (texture) channel (optional). + :type index: integer + :return: this vertexes UV (texture) coordinates. :rtype: Vector((u, v)) - .. method:: setUV(uv) + .. method:: setUV(uv, index=0) Sets the UV (texture) coordinates of this vertex. - :type: Vector((u, v)) + :arg uv: the UV (texture) coordinate of this vertex. + :type uv: Vector((u, v)) + :arg index: the UV (texture) channel (optional). + :type index: integer .. method:: getUV2() @@ -140,14 +152,16 @@ base class --- :class:`SCA_IObject` :return: this vertexes UV (texture) coordinates. :rtype: Vector((u, v)) - .. method:: setUV2(uv, unit) + .. deprecated:: use :meth:`getUV` + + .. method:: setUV2(uv) Sets the 2nd UV (texture) coordinates of this vertex. - :type: Vector((u, v)) + :arg uv: the 2nd (texture) UV coordinate of this vertex. + :type uv: Vector((u, v)) - :arg unit: optional argument, FLAT==1, SECOND_UV==2, defaults to SECOND_UV - :arg unit: integer + .. deprecated:: use :meth:`setUV` .. method:: getRGBA() diff --git a/intern/cycles/kernel/kernel_bake.h b/intern/cycles/kernel/kernel_bake.h index 7790b9caa5a..2fca83c615f 100644 --- a/intern/cycles/kernel/kernel_bake.h +++ b/intern/cycles/kernel/kernel_bake.h @@ -208,7 +208,7 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input, filter_x = filter_y = 0.5f; } else { - path_rng_2D(kg, &rng, sample, num_samples, PRNG_FILTER_U, &filter_x, &filter_x); + path_rng_2D(kg, &rng, sample, num_samples, PRNG_FILTER_U, &filter_x, &filter_y); } /* subpixel u/v offset */ diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h index 7569580d017..0002241e06f 100644 --- a/intern/cycles/kernel/svm/svm.h +++ b/intern/cycles/kernel/svm/svm.h @@ -276,7 +276,7 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, Shade case NODE_TEX_BRICK: svm_node_tex_brick(kg, sd, stack, node, &offset); break; -#endif +#endif /* __TEXTURES__ */ case NODE_CAMERA: svm_node_camera(kg, sd, stack, node.y, node.z, node.w); break; @@ -303,9 +303,9 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, Shade case NODE_HAIR_INFO: svm_node_hair_info(kg, sd, stack, node.y, node.z); break; -#endif +#endif /* __HAIR__ */ -#endif +#endif /* __EXTRA_NODES__ */ case NODE_CONVERT: svm_node_convert(sd, stack, node.y, node.z, node.w); break; @@ -343,7 +343,7 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, Shade case NODE_HSV: svm_node_hsv(kg, sd, stack, node.y, node.z, node.w, &offset); break; -#endif +#endif /* __EXTRA_NODES__ */ case NODE_ATTR: svm_node_attr(kg, sd, stack, node); break; @@ -354,7 +354,7 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, Shade case NODE_ATTR_BUMP_DY: svm_node_attr_bump_dy(kg, sd, stack, node); break; -#endif +#endif /* __EXTRA_NODES__ */ case NODE_FRESNEL: svm_node_fresnel(sd, stack, node.y, node.z, node.w); break; @@ -389,7 +389,7 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, Shade case NODE_NORMAL: svm_node_normal(kg, sd, stack, node.y, node.z, node.w, &offset); break; -#endif +#endif /* __EXTRA_NODES__ */ case NODE_MAPPING: svm_node_mapping(kg, sd, stack, node.y, node.z, &offset); break; @@ -421,7 +421,7 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, Shade case NODE_LIGHT_FALLOFF: svm_node_light_falloff(sd, stack, node); break; -#endif +#endif /* __EXTRA_NODES__ */ case NODE_TANGENT: svm_node_tangent(kg, sd, stack, node); break; diff --git a/release/scripts/presets/keyconfig/maya.py b/release/scripts/presets/keyconfig/maya.py index 28799d1cf67..cdd16f26877 100644 --- a/release/scripts/presets/keyconfig/maya.py +++ b/release/scripts/presets/keyconfig/maya.py @@ -698,10 +698,10 @@ kmi.properties.level = 5 km = kc.keymaps.new('Knife Tool Modal Map', space_type='EMPTY', region_type='WINDOW', modal=True) kmi = km.keymap_items.new_modal('CANCEL', 'ESC', 'ANY', any=True) +kmi = km.keymap_items.new_modal('ADD_CUT', 'LEFTMOUSE', 'ANY') kmi = km.keymap_items.new_modal('PANNING', 'LEFTMOUSE', 'ANY', alt=True) kmi = km.keymap_items.new_modal('PANNING', 'MIDDLEMOUSE', 'ANY', alt=True) kmi = km.keymap_items.new_modal('PANNING', 'RIGHTMOUSE', 'ANY', alt=True) -kmi = km.keymap_items.new_modal('ADD_CUT', 'LEFTMOUSE', 'PRESS', any=True) kmi = km.keymap_items.new_modal('CANCEL', 'RIGHTMOUSE', 'ANY') kmi = km.keymap_items.new_modal('CONFIRM', 'RET', 'PRESS', any=True) kmi = km.keymap_items.new_modal('CONFIRM', 'NUMPAD_ENTER', 'PRESS', any=True) diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py index a663276e9f6..d55c7541452 100644 --- a/release/scripts/startup/bl_ui/space_node.py +++ b/release/scripts/startup/bl_ui/space_node.py @@ -67,7 +67,7 @@ class NODE_HT_header(Header): if snode_id and not (scene.render.use_shading_nodes == 0 and ob.type == 'LAMP'): layout.prop(snode_id, "use_nodes") - if snode.shader_type == 'WORLD': + if scene.render.use_shading_nodes and snode.shader_type == 'WORLD': row = layout.row() row.enabled = not snode.pin row.template_ID(scene, "world", new="world.new") diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 7494b42d282..d7781bca8d9 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -1490,6 +1490,8 @@ class VIEW3D_PT_sculpt_dyntopo(Panel, View3DPaintPanel): row = sub.row(align=True) row.prop(sculpt, "constant_detail") row.operator("sculpt.sample_detail_size", text="", icon='EYEDROPPER') + elif (sculpt.detail_type_method == 'BRUSH'): + sub.prop(sculpt, "detail_percent") else: sub.prop(sculpt, "detail_size") sub.prop(sculpt, "detail_refine_method", text="") diff --git a/release/windows/installer/00.sconsblender.nsi b/release/windows/installer/00.sconsblender.nsi index f6e5b783faa..2d91b9da7f1 100644 --- a/release/windows/installer/00.sconsblender.nsi +++ b/release/windows/installer/00.sconsblender.nsi @@ -70,6 +70,13 @@ InstallDir $INSTDIR ; $INSTDIR is set inside .onInit BrandingText "Blender Foundation | http://www.blender.org" ComponentText "This will install Blender [VERSION] on your computer." +VIAddVersionKey "ProductName" "Blender" +VIAddVersionKey "CompanyName" "http://www.blender.org" +VIAddVersionKey "FileDescription" "Free open source 3D content creation suite." +VIAddVersionKey "FileVersion" "[SHORTVERSION].0.0" + +VIProductVersion "[SHORTVERSION].0.0" + DirText "Use the field below to specify the folder where you want Blender to be copied to. To specify a different folder, type a new name or use the Browse button to select an existing folder." SilentUnInstall normal diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 95466c4872c..0cfb76325fb 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -301,7 +301,11 @@ static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm, float uv[3] = {0.0f, 0.0f, 0.0f}; /* only first 2 values are written into */ limit[0] = limit[1] = STD_UV_CONNECT_LIMIT; - vmap = BKE_mesh_uv_vert_map_create(mpoly, mloop, mloopuv, totface, totvert, 0, limit, false); + /* previous behaviour here is without accounting for winding, however this causes stretching in + * UV map in really simple cases with mirror + subsurf, see second part of T44530. Also, initially + * intention is to treat merged vertices from mirror modifier as seams, see code below with ME_VERT_MERGED + * This fixes a very old regression (2.49 was correct here) */ + vmap = BKE_mesh_uv_vert_map_create(mpoly, mloop, mloopuv, totface, totvert, 0, limit, true); if (!vmap) return 0; diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index 1966d5af7d1..c901fa40acc 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -1896,6 +1896,47 @@ static void txt_undo_add_charop(Text *text, int op_start, unsigned int c) text->undo_buf[text->undo_pos + 1] = 0; } +/* extends Link */ +struct LinkInt { + struct LinkInt *next, *prev; + int value; +}; + +/* unindentLines points to a ListBase composed of LinkInt elements, listing the numbers + * of the lines that should not be indented back. */ +static void txt_undo_add_unindent_op(Text *text, const ListBase *line_index_mask, const int line_index_mask_len) +{ + struct LinkInt *idata; + + BLI_assert(BLI_listbase_count(line_index_mask) == line_index_mask_len); + + /* OP byte + UInt32 count + counted UInt32 line numbers + UInt32 count + 12-bytes selection + OP byte */ + if (!max_undo_test(text, 1 + 4 + (line_index_mask_len * 4) + 4 + 12 + 1)) { + return; + } + + /* Opening buffer sequence with OP */ + text->undo_pos++; + text->undo_buf[text->undo_pos] = UNDO_UNINDENT; + text->undo_pos++; + /* Adding number of line numbers to read */ + txt_undo_store_uint32(text->undo_buf, &text->undo_pos, line_index_mask_len); + + /* Adding linenumbers of lines that shall not be indented if undoing */ + for (idata = line_index_mask->first; idata; idata = idata->next) { + txt_undo_store_uint32(text->undo_buf, &text->undo_pos, idata->value); + } + + /* Adding number of line numbers to read again */ + txt_undo_store_uint32(text->undo_buf, &text->undo_pos, line_index_mask_len); + /* Adding current selection */ + txt_undo_store_cursors(text); + /* Closing with OP (same as above) */ + text->undo_buf[text->undo_pos] = UNDO_UNINDENT; + /* Marking as last undo operation */ + text->undo_buf[text->undo_pos + 1] = 0; +} + static unsigned short txt_undo_read_uint16(const char *undo_buf, int *undo_pos) { unsigned short val; @@ -2190,7 +2231,6 @@ void txt_do_undo(Text *text) text->undo_pos--; break; case UNDO_INDENT: - case UNDO_UNINDENT: case UNDO_COMMENT: case UNDO_UNCOMMENT: case UNDO_DUPLICATE: @@ -2204,9 +2244,6 @@ void txt_do_undo(Text *text) if (op == UNDO_INDENT) { txt_unindent(text); } - else if (op == UNDO_UNINDENT) { - txt_indent(text); - } else if (op == UNDO_COMMENT) { txt_uncomment(text); } @@ -2225,6 +2262,37 @@ void txt_do_undo(Text *text) text->undo_pos--; break; + case UNDO_UNINDENT: + { + int count; + int i; + /* Get and restore the cursors */ + txt_undo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, selln, selc, 1); + + /* Un-unindent */ + txt_indent(text); + + /* Get the count */ + count = txt_undo_read_uint32(text->undo_buf, &text->undo_pos); + /* Iterate! */ + txt_pop_sel(text); + + for (i = 0; i < count; i++) { + txt_move_to(text, txt_undo_read_uint32(text->undo_buf, &text->undo_pos), 0, 0); + /* Un-un-unindent */ + txt_unindent(text); + } + /* Restore selection */ + txt_move_to(text, curln, curc, 0); + txt_move_to(text, selln, selc, 1); + /* Jumo over count */ + txt_undo_read_uint32(text->undo_buf, &text->undo_pos); + /* Jump over closing OP byte */ + text->undo_pos--; + break; + } default: //XXX error("Undo buffer error - resetting"); text->undo_pos = -1; @@ -2354,7 +2422,6 @@ void txt_do_redo(Text *text) break; case UNDO_INDENT: - case UNDO_UNINDENT: case UNDO_COMMENT: case UNDO_UNCOMMENT: case UNDO_DUPLICATE: @@ -2370,9 +2437,6 @@ void txt_do_redo(Text *text) if (op == UNDO_INDENT) { txt_indent(text); } - else if (op == UNDO_UNINDENT) { - txt_unindent(text); - } else if (op == UNDO_COMMENT) { txt_comment(text); } @@ -2402,6 +2466,26 @@ void txt_do_redo(Text *text) txt_move_to(text, selln, selc, 1); break; + case UNDO_UNINDENT: + { + int count; + int i; + + text->undo_pos++; + /* Scan all the stuff described in txt_undo_add_unindent_op */ + count = txt_redo_read_uint32(text->undo_buf, &text->undo_pos); + for (i = 0; i < count; i++) { + txt_redo_read_uint32(text->undo_buf, &text->undo_pos); + } + /* Count again */ + txt_redo_read_uint32(text->undo_buf, &text->undo_pos); + /* Get the selection and re-unindent */ + txt_redo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, selln, selc, 1); + txt_unindent(text); + break; + } default: //XXX error("Undo buffer error - resetting"); text->undo_pos = -1; @@ -2802,6 +2886,12 @@ void txt_unindent(Text *text) int indentlen = 1; bool unindented_first = false; + /* List of lines that are already at indent level 0, to store them later into the undo buffer */ + ListBase line_index_mask = {NULL, NULL}; + int line_index_mask_len = 0; + int curl_span_init = 0; + + /* hardcoded: TXT_TABSIZE = 4 spaces: */ int spaceslen = TXT_TABSIZE; @@ -2815,6 +2905,10 @@ void txt_unindent(Text *text) indentlen = spaceslen; } + if (!undoing) { + curl_span_init = txt_get_span(text->lines.first, text->curl); + } + while (true) { bool changed = false; if (STREQLEN(text->curl->line, remove, indentlen)) { @@ -2824,6 +2918,16 @@ void txt_unindent(Text *text) memmove(text->curl->line, text->curl->line + indentlen, text->curl->len + 1); changed = true; } + else { + if (!undoing) { + /* Create list element for 0 indent line */ + struct LinkInt *idata = MEM_mallocN(sizeof(struct LinkInt), __func__); + idata->value = curl_span_init + num; + BLI_assert(idata->value == txt_get_span(text->lines.first, text->curl)); + BLI_addtail(&line_index_mask, idata); + line_index_mask_len += 1; + } + } txt_make_dirty(text); txt_clean_text(text); @@ -2836,6 +2940,7 @@ void txt_unindent(Text *text) else { text->curl = text->curl->next; num++; + } } @@ -2849,8 +2954,10 @@ void txt_unindent(Text *text) } if (!undoing) { - txt_undo_add_op(text, UNDO_UNINDENT); + txt_undo_add_unindent_op(text, &line_index_mask, line_index_mask_len); } + + BLI_freelistN(&line_index_mask); } void txt_comment(Text *text) diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index 63e36178e0f..9bc45025456 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -1010,10 +1010,12 @@ int BM_loop_region_loops_count(BMLoop *l) bool BM_vert_is_manifold_region(const BMVert *v) { BMLoop *l_first = BM_vert_find_first_loop((BMVert *)v); - int count, count_total; - - count = BM_loop_region_loops_count_ex(l_first, &count_total); - return (count == count_total); + if (l_first) { + int count, count_total; + count = BM_loop_region_loops_count_ex(l_first, &count_total); + return (count == count_total); + } + return true; } /** diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c index 44c0f83cb9f..c7a7828f3b2 100644 --- a/source/blender/editors/mesh/editmesh_rip.c +++ b/source/blender/editors/mesh/editmesh_rip.c @@ -607,6 +607,11 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, const wmEvent *eve if (ese.ele) { BM_select_history_store(bm, v_new); } + + if (do_fill) { + BM_edge_create(bm, v, v_new, NULL, BM_CREATE_NOP); + } + return OPERATOR_FINISHED; } @@ -719,6 +724,15 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, const wmEvent *eve } } + /* vout[0] == best + * vout[1] == glue + * vout[2+] == splice with glue (when vout_len > 2) + */ + if (vi_best != 0) { + SWAP(BMVert *, vout[0], vout[vi_best]); + vi_best = 0; + } + /* select the vert from the best region */ v = vout[vi_best]; BM_vert_select_set(bm, v, true); @@ -729,21 +743,18 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, const wmEvent *eve /* splice all others back together */ if (vout_len > 2) { - - /* vout[0] == best - * vout[1] == glue - * vout[2+] == splice with glue - */ - if (vi_best != 0) { - SWAP(BMVert *, vout[0], vout[vi_best]); - vi_best = 0; - } - for (i = 2; i < vout_len; i++) { BM_vert_splice(bm, vout[1], vout[i]); } } + if (do_fill) { + if (do_fill) { + /* match extrude vert-order */ + BM_edge_create(bm, vout[1], vout[0], NULL, BM_CREATE_NOP); + } + } + MEM_freeN(vout); return OPERATOR_FINISHED; diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index e291776b9d7..c265913f113 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -238,8 +238,13 @@ static void screen_opengl_views_setup(OGLRender *oglrender) BLI_unlock_thread(LOCK_DRAW_IMAGE); /* will only work for non multiview correctly */ - camera = BKE_camera_multiview_render(oglrender->scene, v3d->camera, "new opengl render view"); - BKE_render_result_stamp_info(oglrender->scene, camera, rr); + if (v3d) { + camera = BKE_camera_multiview_render(oglrender->scene, v3d->camera, "new opengl render view"); + BKE_render_result_stamp_info(oglrender->scene, camera, rr); + } + else { + BKE_render_result_stamp_info(oglrender->scene, oglrender->scene->camera, rr); + } RE_ReleaseResult(oglrender->re); } diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index 70127d0d425..6f34db4e424 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -4664,7 +4664,14 @@ static void *do_projectpaint_thread(void *ph_v) } if (lock_alpha) { - if (is_floatbuf) projPixel->pixel.f_pt[3] = projPixel->origColor.f_pt[3]; + if (is_floatbuf) { + /* slightly more involved case since floats are in premultiplied space we need + * to make sure alpha is consistent, see T44627 */ + float rgb_straight[4]; + premul_to_straight_v4_v4(rgb_straight, projPixel->pixel.f_pt); + rgb_straight[3] = projPixel->origColor.f_pt[3]; + straight_to_premul_v4_v4(projPixel->pixel.f_pt, rgb_straight); + } else projPixel->pixel.ch_pt[3] = projPixel->origColor.ch_pt[3]; } @@ -4833,7 +4840,14 @@ static void *do_projectpaint_thread(void *ph_v) } if (lock_alpha) { - if (is_floatbuf) projPixel->pixel.f_pt[3] = projPixel->origColor.f_pt[3]; + if (is_floatbuf) { + /* slightly more involved case since floats are in premultiplied space we need + * to make sure alpha is consistent, see T44627 */ + float rgb_straight[4]; + premul_to_straight_v4_v4(rgb_straight, projPixel->pixel.f_pt); + rgb_straight[3] = projPixel->origColor.f_pt[3]; + straight_to_premul_v4_v4(projPixel->pixel.f_pt, rgb_straight); + } else projPixel->pixel.ch_pt[3] = projPixel->origColor.ch_pt[3]; } diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 1d2f623bf9d..e2403a57556 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -4379,6 +4379,9 @@ static void sculpt_stroke_update_step(bContext *C, struct PaintStroke *UNUSED(st if (sd->flags & SCULPT_DYNTOPO_DETAIL_CONSTANT) { BKE_pbvh_bmesh_detail_size_set(ss->pbvh, sd->constant_detail / 100.0f); } + else if (sd->flags & SCULPT_DYNTOPO_DETAIL_BRUSH) { + BKE_pbvh_bmesh_detail_size_set(ss->pbvh, ss->cache->radius * sd->detail_percent / 100.0f); + } else { BKE_pbvh_bmesh_detail_size_set( ss->pbvh, @@ -5072,10 +5075,10 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op) ts->sculpt->flags |= SCULPT_DYNTOPO_SUBDIVIDE | SCULPT_DYNTOPO_COLLAPSE; } - if (!ts->sculpt->detail_size) { + if (!ts->sculpt->detail_size) ts->sculpt->detail_size = 12; - } - + if (!ts->sculpt->detail_percent) + ts->sculpt->detail_percent = 25; if (ts->sculpt->constant_detail == 0.0f) ts->sculpt->constant_detail = 30.0f; @@ -5308,6 +5311,10 @@ static int sculpt_set_detail_size_exec(bContext *C, wmOperator *UNUSED(op)) set_brush_rc_props(&props_ptr, "sculpt", "constant_detail", NULL, 0); RNA_string_set(&props_ptr, "data_path_primary", "tool_settings.sculpt.constant_detail"); } + else if (sd->flags & SCULPT_DYNTOPO_DETAIL_BRUSH) { + set_brush_rc_props(&props_ptr, "sculpt", "constant_detail", NULL, 0); + RNA_string_set(&props_ptr, "data_path_primary", "tool_settings.sculpt.detail_percent"); + } else { set_brush_rc_props(&props_ptr, "sculpt", "detail_size", NULL, 0); RNA_string_set(&props_ptr, "data_path_primary", "tool_settings.sculpt.detail_size"); diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 0eb0e8080d2..84db64d7ec7 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -99,8 +99,8 @@ static void drawTransformApply(const struct bContext *C, ARegion *ar, void *arg) static void doEdgeSlide(TransInfo *t, float perc); static void doVertSlide(TransInfo *t, float perc); -static void drawEdgeSlide(const struct bContext *C, TransInfo *t); -static void drawVertSlide(const struct bContext *C, TransInfo *t); +static void drawEdgeSlide(TransInfo *t); +static void drawVertSlide(TransInfo *t); static void len_v3_ensure(float v[3], const float length); static void postInputRotation(TransInfo *t, float values[3]); @@ -1829,8 +1829,8 @@ static void drawTransformView(const struct bContext *C, ARegion *UNUSED(ar), voi drawSnapping(C, t); /* edge slide, vert slide */ - drawEdgeSlide(C, t); - drawVertSlide(C, t); + drawEdgeSlide(t); + drawVertSlide(t); } /* just draw a little warning message in the top-right corner of the viewport to warn that autokeying is enabled */ @@ -5479,6 +5479,19 @@ static void slide_origdata_free_date( /** \name Transform Edge Slide * \{ */ +static void calcEdgeSlideCustomPoints(struct TransInfo *t) +{ + EdgeSlideData *sld = t->customData; + + setCustomPoints(t, &t->mouse, sld->mval_end, sld->mval_start); + + /* setCustomPoints isn't normally changing as the mouse moves, + * in this case apply mouse input immediatly so we don't refresh + * with the value from the previous points */ + applyMouseInput(t, &t->mouse, t->mval, t->values); +} + + static BMEdge *get_other_edge(BMVert *v, BMEdge *e) { BMIter iter; @@ -5494,7 +5507,7 @@ static BMEdge *get_other_edge(BMVert *v, BMEdge *e) } /* interpoaltes along a line made up of 2 segments (used for edge slide) */ -static void interp_line_v3_v3v3v3(float p[3], const float v1[3], const float v2[3], const float v3[3], const float t) +static void interp_line_v3_v3v3v3(float p[3], const float v1[3], const float v2[3], const float v3[3], float t) { float t_mid, t_delta; @@ -5502,17 +5515,28 @@ static void interp_line_v3_v3v3v3(float p[3], const float v1[3], const float v2[ t_mid = line_point_factor_v3(v2, v1, v3); t_delta = t - t_mid; - if (fabsf(t_delta) < FLT_EPSILON) { - copy_v3_v3(p, v2); - } - else if (t_delta < 0.0f) { - interp_v3_v3v3(p, v1, v2, t / t_mid); + if (t_delta < 0.0f) { + if (UNLIKELY(fabsf(t_mid) < FLT_EPSILON)) { + copy_v3_v3(p, v2); + } + else { + interp_v3_v3v3(p, v1, v2, t / t_mid); + } } else { - interp_v3_v3v3(p, v2, v3, (t - t_mid) / (1.0f - t_mid)); + t = t - t_mid; + t_mid = 1.0f - t_mid; + + if (UNLIKELY(fabsf(t_mid) < FLT_EPSILON)) { + copy_v3_v3(p, v3); + } + else { + interp_v3_v3v3(p, v2, v3, t / t_mid); + } } } + static void len_v3_ensure(float v[3], const float length) { normalize_v3(v); @@ -5687,7 +5711,7 @@ static void calcNonProportionalEdgeSlide(TransInfo *t, EdgeSlideData *sld, const for (i = 0; i < sld->totsv; i++, sv++) { /* Set length */ - sv->edge_len = len_v3v3(sv->dir_a, sv->dir_b); + sv->edge_len = len_v3v3(sv->dir_side[0], sv->dir_side[1]); ED_view3d_project_float_v2_m4(ar, sv->v->co, v_proj, projectMat); dist_sq = len_squared_v2v2(mval, v_proj); @@ -5915,14 +5939,14 @@ static bool createEdgeSlideVerts(TransInfo *t) if (l_a || l_a_prev) { BMLoop *l_tmp = BM_loop_other_edge_loop(l_a ? l_a : l_a_prev, v); - sv->v_a = BM_edge_other_vert(l_tmp->e, v); - copy_v3_v3(sv->dir_a, vec_a); + sv->v_side[0] = BM_edge_other_vert(l_tmp->e, v); + copy_v3_v3(sv->dir_side[0], vec_a); } if (l_b || l_b_prev) { BMLoop *l_tmp = BM_loop_other_edge_loop(l_b ? l_b : l_b_prev, v); - sv->v_b = BM_edge_other_vert(l_tmp->e, v); - copy_v3_v3(sv->dir_b, vec_b); + sv->v_side[1] = BM_edge_other_vert(l_tmp->e, v); + copy_v3_v3(sv->dir_side[1], vec_b); } v_prev = v; @@ -5941,23 +5965,23 @@ static bool createEdgeSlideVerts(TransInfo *t) if (l_a) { BMLoop *l_tmp = BM_loop_other_edge_loop(l_a, v); - sv->v_a = BM_edge_other_vert(l_tmp->e, v); + sv->v_side[0] = BM_edge_other_vert(l_tmp->e, v); if (EDGESLIDE_VERT_IS_INNER(v, l_tmp->e)) { - get_next_loop(v, l_a, e_prev, l_tmp->e, sv->dir_a); + get_next_loop(v, l_a, e_prev, l_tmp->e, sv->dir_side[0]); } else { - sub_v3_v3v3(sv->dir_a, BM_edge_other_vert(l_tmp->e, v)->co, v->co); + sub_v3_v3v3(sv->dir_side[0], BM_edge_other_vert(l_tmp->e, v)->co, v->co); } } if (l_b) { BMLoop *l_tmp = BM_loop_other_edge_loop(l_b, v); - sv->v_b = BM_edge_other_vert(l_tmp->e, v); + sv->v_side[1] = BM_edge_other_vert(l_tmp->e, v); if (EDGESLIDE_VERT_IS_INNER(v, l_tmp->e)) { - get_next_loop(v, l_b, e_prev, l_tmp->e, sv->dir_b); + get_next_loop(v, l_b, e_prev, l_tmp->e, sv->dir_side[1]); } else { - sub_v3_v3v3(sv->dir_b, BM_edge_other_vert(l_tmp->e, v)->co, v->co); + sub_v3_v3v3(sv->dir_side[1], BM_edge_other_vert(l_tmp->e, v)->co, v->co); } } @@ -6078,19 +6102,19 @@ static bool createEdgeSlideVerts(TransInfo *t) BLI_assert(sv_table[BM_elem_index_get(v)] != -1); j = sv_table[BM_elem_index_get(v)]; - if (sv_array[j].v_b) { - ED_view3d_project_float_v3_m4(ar, sv_array[j].v_b->co, sco_b, projectMat); + if (sv_array[j].v_side[1]) { + ED_view3d_project_float_v3_m4(ar, sv_array[j].v_side[1]->co, sco_b, projectMat); } else { - add_v3_v3v3(sco_b, v->co, sv_array[j].dir_b); + add_v3_v3v3(sco_b, v->co, sv_array[j].dir_side[1]); ED_view3d_project_float_v3_m4(ar, sco_b, sco_b, projectMat); } - if (sv_array[j].v_a) { - ED_view3d_project_float_v3_m4(ar, sv_array[j].v_a->co, sco_a, projectMat); + if (sv_array[j].v_side[0]) { + ED_view3d_project_float_v3_m4(ar, sv_array[j].v_side[0]->co, sco_a, projectMat); } else { - add_v3_v3v3(sco_a, v->co, sv_array[j].dir_a); + add_v3_v3v3(sco_a, v->co, sv_array[j].dir_side[0]); ED_view3d_project_float_v3_m4(ar, sco_a, sco_a, projectMat); } @@ -6131,8 +6155,8 @@ static bool createEdgeSlideVerts(TransInfo *t) /* switch a/b if loop direction is different from global direction */ l_nr = sv_array->loop_nr; if (dot_v3v3(loop_dir[l_nr], mval_dir) < 0.0f) { - swap_v3_v3(sv_array->dir_a, sv_array->dir_b); - SWAP(BMVert *, sv_array->v_a, sv_array->v_b); + swap_v3_v3(sv_array->dir_side[0], sv_array->dir_side[1]); + SWAP(BMVert *, sv_array->v_side[0], sv_array->v_side[1]); } } @@ -6225,7 +6249,7 @@ static void initEdgeSlide(TransInfo *t) t->customFree = freeEdgeSlideVerts; /* set custom point first if you want value to be initialized by init */ - setCustomPoints(t, &t->mouse, sld->mval_end, sld->mval_start); + calcEdgeSlideCustomPoints(t); initMouseInputMode(t, &t->mouse, INPUT_CUSTOM_RATIO_FLIP); t->idx_max = 0; @@ -6251,6 +6275,7 @@ static eRedrawFlag handleEventEdgeSlide(struct TransInfo *t, const struct wmEven case EKEY: if (event->val == KM_PRESS) { sld->is_proportional = !sld->is_proportional; + calcEdgeSlideCustomPoints(t); return TREDRAW_HARD; } break; @@ -6260,6 +6285,17 @@ static eRedrawFlag handleEventEdgeSlide(struct TransInfo *t, const struct wmEven if (sld->is_proportional == false) { sld->flipped_vtx = !sld->flipped_vtx; } + calcEdgeSlideCustomPoints(t); + return TREDRAW_HARD; + } + break; + } + case CKEY: + { + /* use like a modifier key */ + if (event->val == KM_PRESS) { + t->flag ^= T_ALT_TRANSFORM; + calcEdgeSlideCustomPoints(t); return TREDRAW_HARD; } break; @@ -6280,6 +6316,11 @@ static eRedrawFlag handleEventEdgeSlide(struct TransInfo *t, const struct wmEven } break; } + case MOUSEMOVE: + { + calcEdgeSlideCustomPoints(t); + break; + } default: break; } @@ -6288,23 +6329,16 @@ static eRedrawFlag handleEventEdgeSlide(struct TransInfo *t, const struct wmEven return TREDRAW_NOTHING; } -static void drawEdgeSlide(const struct bContext *C, TransInfo *t) +static void drawEdgeSlide(TransInfo *t) { - if (t->mode == TFM_EDGE_SLIDE) { - EdgeSlideData *sld = (EdgeSlideData *)t->customData; + if ((t->mode == TFM_EDGE_SLIDE) && t->customData) { + EdgeSlideData *sld = t->customData; + const bool is_clamp = !(t->flag & T_ALT_TRANSFORM); + /* Non-Prop mode */ - if (sld && sld->is_proportional == false) { - View3D *v3d = CTX_wm_view3d(C); - float co_a[3], co_b[3], co_mark[3]; - TransDataEdgeSlideVert *curr_sv = &sld->sv[sld->curr_sv_index]; - const float fac = (sld->perc + 1.0f) / 2.0f; - const float ctrl_size = UI_GetThemeValuef(TH_FACEDOT_SIZE) + 1.5f; - const float guide_size = ctrl_size - 0.5f; + if ((sld->is_proportional == false) || (is_clamp == false)) { + View3D *v3d = t->view; const float line_size = UI_GetThemeValuef(TH_OUTLINE_WIDTH) + 0.5f; - const int alpha_shade = -30; - - add_v3_v3v3(co_a, curr_sv->v_co_orig, curr_sv->dir_a); - add_v3_v3v3(co_b, curr_sv->v_co_orig, curr_sv->dir_b); if (v3d && v3d->zbuf) glDisable(GL_DEPTH_TEST); @@ -6317,42 +6351,88 @@ static void drawEdgeSlide(const struct bContext *C, TransInfo *t) glMultMatrixf(t->obedit->obmat); - glLineWidth(line_size); - UI_ThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade); - glBegin(GL_LINES); - if (curr_sv->v_a) { - glVertex3fv(curr_sv->v_a->co); - glVertex3fv(curr_sv->v_co_orig); - } - if (curr_sv->v_b) { - glVertex3fv(curr_sv->v_b->co); - glVertex3fv(curr_sv->v_co_orig); - } - bglEnd(); + if (sld->is_proportional == false) { + float co_a[3], co_b[3], co_mark[3]; + TransDataEdgeSlideVert *curr_sv = &sld->sv[sld->curr_sv_index]; + const float fac = (sld->perc + 1.0f) / 2.0f; + const float ctrl_size = UI_GetThemeValuef(TH_FACEDOT_SIZE) + 1.5f; + const float guide_size = ctrl_size - 0.5f; + const int alpha_shade = -30; + add_v3_v3v3(co_a, curr_sv->v_co_orig, curr_sv->dir_side[0]); + add_v3_v3v3(co_b, curr_sv->v_co_orig, curr_sv->dir_side[1]); - UI_ThemeColorShadeAlpha(TH_SELECT, -30, alpha_shade); - glPointSize(ctrl_size); - bglBegin(GL_POINTS); - if (sld->flipped_vtx) { - if (curr_sv->v_b) bglVertex3fv(curr_sv->v_b->co); - } - else { - if (curr_sv->v_a) bglVertex3fv(curr_sv->v_a->co); - } - bglEnd(); + glLineWidth(line_size); + UI_ThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade); + glBegin(GL_LINES); + if (curr_sv->v_side[0]) { + glVertex3fv(curr_sv->v_side[0]->co); + glVertex3fv(curr_sv->v_co_orig); + } + if (curr_sv->v_side[1]) { + glVertex3fv(curr_sv->v_side[1]->co); + glVertex3fv(curr_sv->v_co_orig); + } + glEnd(); - UI_ThemeColorShadeAlpha(TH_SELECT, 255, alpha_shade); - glPointSize(guide_size); - bglBegin(GL_POINTS); + UI_ThemeColorShadeAlpha(TH_SELECT, -30, alpha_shade); + glPointSize(ctrl_size); + bglBegin(GL_POINTS); + if (sld->flipped_vtx) { + if (curr_sv->v_side[1]) bglVertex3fv(curr_sv->v_side[1]->co); + } + else { + if (curr_sv->v_side[0]) bglVertex3fv(curr_sv->v_side[0]->co); + } + bglEnd(); + + UI_ThemeColorShadeAlpha(TH_SELECT, 255, alpha_shade); + glPointSize(guide_size); + bglBegin(GL_POINTS); #if 0 - interp_v3_v3v3(co_mark, co_b, co_a, fac); - bglVertex3fv(co_mark); + interp_v3_v3v3(co_mark, co_b, co_a, fac); + bglVertex3fv(co_mark); #endif - interp_line_v3_v3v3v3(co_mark, co_b, curr_sv->v_co_orig, co_a, fac); - bglVertex3fv(co_mark); - bglEnd(); + interp_line_v3_v3v3v3(co_mark, co_b, curr_sv->v_co_orig, co_a, fac); + bglVertex3fv(co_mark); + bglEnd(); + } + else { + if (is_clamp == false) { + const int side_index = sld->curr_side_unclamp; + TransDataEdgeSlideVert *sv; + int i; + const int alpha_shade = -160; + + glLineWidth(line_size); + UI_ThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade); + glBegin(GL_LINES); + + sv = sld->sv; + for (i = 0; i < sld->totsv; i++, sv++) { + float a[3], b[3]; + + if (!is_zero_v3(sv->dir_side[side_index])) { + copy_v3_v3(a, sv->dir_side[side_index]); + } + else { + copy_v3_v3(a, sv->dir_side[!side_index]); + } + mul_v3_fl(a, 100.0f); + negate_v3_v3(b, a); + add_v3_v3(a, sv->v_co_orig); + add_v3_v3(b, sv->v_co_orig); + + glVertex3fv(a); + glVertex3fv(b); + } + glEnd(); + } + else { + BLI_assert(0); + } + } glPopMatrix(); glPopAttrib(); @@ -6375,17 +6455,30 @@ static void doEdgeSlide(TransInfo *t, float perc) sv = svlist; if (sld->is_proportional == true) { - for (i = 0; i < sld->totsv; i++, sv++) { - float vec[3]; - if (perc > 0.0f) { - copy_v3_v3(vec, sv->dir_a); - mul_v3_fl(vec, perc); - add_v3_v3v3(sv->v->co, sv->v_co_orig, vec); + const bool is_clamp = !(t->flag & T_ALT_TRANSFORM); + if (is_clamp) { + const int side_index = (perc < 0.0f); + const float perc_final = fabsf(perc); + for (i = 0; i < sld->totsv; i++, sv++) { + madd_v3_v3v3fl(sv->v->co, sv->v_co_orig, sv->dir_side[side_index], perc_final); } - else { - copy_v3_v3(vec, sv->dir_b); - mul_v3_fl(vec, -perc); - add_v3_v3v3(sv->v->co, sv->v_co_orig, vec); + + sld->curr_side_unclamp = side_index; + } + else { + const int side_index = sld->curr_side_unclamp; + const float perc_init = fabsf(perc) * ((sld->curr_side_unclamp == (perc < 0.0f)) ? 1 : -1); + for (i = 0; i < sld->totsv; i++, sv++) { + float dir_flip[3]; + float perc_final = perc_init; + if (!is_zero_v3(sv->dir_side[side_index])) { + copy_v3_v3(dir_flip, sv->dir_side[side_index]); + } + else { + copy_v3_v3(dir_flip, sv->dir_side[!side_index]); + perc_final *= -1; + } + madd_v3_v3v3fl(sv->v->co, sv->v_co_orig, dir_flip, perc_final); } } } @@ -6395,7 +6488,7 @@ static void doEdgeSlide(TransInfo *t, float perc) * a/b verts, this could be changed/improved so the distance is still met but the verts are moved along * their original path (which may not be straight), however how it works now is OK and matches 2.4x - Campbell * - * \note len_v3v3(curr_sv->dir_a, curr_sv->dir_b) + * \note len_v3v3(curr_sv->dir_side[0], curr_sv->dir_side[1]) * is the same as the distance between the original vert locations, same goes for the lines below. */ TransDataEdgeSlideVert *curr_sv = &sld->sv[sld->curr_sv_index]; @@ -6408,8 +6501,8 @@ static void doEdgeSlide(TransInfo *t, float perc) if (sv->edge_len > FLT_EPSILON) { const float fac = min_ff(sv->edge_len, curr_length_perc) / sv->edge_len; - add_v3_v3v3(co_a, sv->v_co_orig, sv->dir_a); - add_v3_v3v3(co_b, sv->v_co_orig, sv->dir_b); + add_v3_v3v3(co_a, sv->v_co_orig, sv->dir_side[0]); + add_v3_v3v3(co_b, sv->v_co_orig, sv->dir_side[1]); if (sld->flipped_vtx) { interp_line_v3_v3v3v3(sv->v->co, co_b, sv->v_co_orig, co_a, fac); @@ -6427,44 +6520,41 @@ static void doEdgeSlide(TransInfo *t, float perc) static void applyEdgeSlide(TransInfo *t, const int UNUSED(mval[2])) { char str[MAX_INFO_LEN]; + size_t ofs = 0; float final; EdgeSlideData *sld = t->customData; bool flipped = sld->flipped_vtx; bool is_proportional = sld->is_proportional; + const bool is_clamp = !(t->flag & T_ALT_TRANSFORM); + const bool is_constrained = !(is_clamp == false || hasNumInput(&t->num)); final = t->values[0]; snapGridIncrement(t, &final); /* only do this so out of range values are not displayed */ - CLAMP(final, -1.0f, 1.0f); + if (is_constrained) { + CLAMP(final, -1.0f, 1.0f); + } applyNumInput(&t->num, &final); + /* header string */ + ofs += BLI_strncpy_rlen(str + ofs, IFACE_("Edge Slide: "), MAX_INFO_LEN - ofs); if (hasNumInput(&t->num)) { char c[NUM_STR_REP_LEN]; - outputNumInput(&(t->num), c, &t->scene->unit); - - if (is_proportional) { - BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Edge Slide: %s (E)ven: %s"), - &c[0], WM_bool_as_string(!is_proportional)); - } - else { - BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Edge Slide: %s (E)ven: %s, (F)lipped: %s"), - &c[0], WM_bool_as_string(!is_proportional), WM_bool_as_string(flipped)); - } - } - else if (is_proportional) { - BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Edge Slide: %.4f (E)ven: %s"), - final, WM_bool_as_string(!is_proportional)); + ofs += BLI_strncpy_rlen(str + ofs, &c[0], MAX_INFO_LEN - ofs); } else { - BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Edge Slide: %.4f (E)ven: %s, (F)lipped: %s"), - final, WM_bool_as_string(!is_proportional), WM_bool_as_string(flipped)); + ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, "%.4f ", final); } - - CLAMP(final, -1.0f, 1.0f); + ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("(E)ven: %s, "), WM_bool_as_string(!is_proportional)); + if (!is_proportional) { + ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("(F)lipped: %s, "), WM_bool_as_string(flipped)); + } + ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Alt or (C)lamp: %s"), WM_bool_as_string(is_clamp)); + /* done with header string */ t->values[0] = final; @@ -6848,19 +6938,20 @@ static eRedrawFlag handleEventVertSlide(struct TransInfo *t, const struct wmEven return TREDRAW_NOTHING; } -static void drawVertSlide(const struct bContext *C, TransInfo *t) +static void drawVertSlide(TransInfo *t) { - if (t->mode == TFM_VERT_SLIDE) { - VertSlideData *sld = (VertSlideData *)t->customData; + if ((t->mode == TFM_VERT_SLIDE) && t->customData) { + VertSlideData *sld = t->customData; + const bool is_clamp = !(t->flag & T_ALT_TRANSFORM); + /* Non-Prop mode */ - if (sld) { - View3D *v3d = CTX_wm_view3d(C); + { + View3D *v3d = t->view; TransDataVertSlideVert *curr_sv = &sld->sv[sld->curr_sv_index]; TransDataVertSlideVert *sv; const float ctrl_size = UI_GetThemeValuef(TH_FACEDOT_SIZE) + 1.5f; const float line_size = UI_GetThemeValuef(TH_OUTLINE_WIDTH) + 0.5f; const int alpha_shade = -160; - const bool is_clamp = !(t->flag & T_ALT_TRANSFORM); int i; if (v3d && v3d->zbuf) diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index c2c054113e8..2672df24d2e 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -213,10 +213,10 @@ typedef struct TransDataEdgeSlideVert { float edge_len; - struct BMVert *v_a, *v_b; + struct BMVert *v_side[2]; /* add origvert.co to get the original locations */ - float dir_a[3], dir_b[3]; + float dir_side[2][3]; int loop_nr; } TransDataEdgeSlideVert; @@ -253,6 +253,9 @@ typedef struct EdgeSlideData { bool flipped_vtx; int curr_sv_index; + + /** when un-clamped - use this index: #TransDataEdgeSlideVert.dir_side */ + int curr_side_unclamp; } EdgeSlideData; diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 75f9ecfe50f..40d2127f22c 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -849,7 +849,7 @@ static void TRANSFORM_OT_edge_slide(struct wmOperatorType *ot) ot->cancel = transform_cancel; ot->poll = ED_operator_editmesh; - RNA_def_float_factor(ot->srna, "value", 0, -1.0f, 1.0f, "Factor", "", -1.0f, 1.0f); + RNA_def_float_factor(ot->srna, "value", 0, -10.0f, 10.0f, "Factor", "", -1.0f, 1.0f); Transform_Properties(ot, P_MIRROR | P_SNAP | P_CORRECT_UV); } diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 5c7f59cc06e..6936ba5d004 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1047,6 +1047,8 @@ typedef struct Sculpt { /* scale for constant detail size */ float constant_detail; + float detail_percent; + float pad; struct Object *gravity_object; void *pad2; @@ -1880,7 +1882,8 @@ typedef enum SculptFlags { SCULPT_DYNTOPO_COLLAPSE = (1 << 11), /* If set, dynamic-topology detail size will be constant in object space */ - SCULPT_DYNTOPO_DETAIL_CONSTANT = (1 << 13) + SCULPT_DYNTOPO_DETAIL_CONSTANT = (1 << 13), + SCULPT_DYNTOPO_DETAIL_BRUSH = (1 << 14), } SculptFlags; typedef enum ImagePaintMode { diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 30e7e8b82b7..294ffc18f7c 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -1472,7 +1472,7 @@ static void rna_def_modifier_mirror(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "tolerance"); RNA_def_property_range(prop, 0, FLT_MAX); RNA_def_property_ui_range(prop, 0, 1, 0.01, 6); - RNA_def_property_ui_text(prop, "Merge Limit", "Distance from axis within which mirrored vertices are merged"); + RNA_def_property_ui_text(prop, "Merge Limit", "Distance within which mirrored vertices are merged"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop = RNA_def_property(srna, "mirror_object", PROP_POINTER, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index f3ed69088c2..4cb4d9ff9fa 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -490,6 +490,8 @@ static void rna_def_sculpt(BlenderRNA *brna) "Relative Detail", "Mesh detail is relative to the brush size and detail size"}, {SCULPT_DYNTOPO_DETAIL_CONSTANT, "CONSTANT", 0, "Constant Detail", "Mesh detail is constant in object space according to detail size"}, + {SCULPT_DYNTOPO_DETAIL_BRUSH, "BRUSH", 0, + "Brush Detail", "Mesh detail is relative to brush radius"}, {0, NULL, 0, NULL, NULL} }; @@ -547,6 +549,11 @@ static void rna_def_sculpt(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Detail Size", "Maximum edge length for dynamic topology sculpting (in pixels)"); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); + prop = RNA_def_property(srna, "detail_percent", PROP_FLOAT, PROP_PERCENTAGE); + RNA_def_property_ui_range(prop, 0.5, 100.0, 10, 2); + RNA_def_property_ui_text(prop, "Detail Percentage", "Maximum edge length for dynamic topology sculpting (in brush percenage)"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); + prop = RNA_def_property(srna, "constant_detail", PROP_FLOAT, PROP_PERCENTAGE); RNA_def_property_range(prop, 0.001, 10000.0); RNA_def_property_ui_range(prop, 0.1, 100.0, 10, 2); diff --git a/source/blender/render/intern/source/bake.c b/source/blender/render/intern/source/bake.c index b602753dff4..0210bec5ab4 100644 --- a/source/blender/render/intern/source/bake.c +++ b/source/blender/render/intern/source/bake.c @@ -34,6 +34,7 @@ #include "MEM_guardedalloc.h" #include "BLI_math.h" +#include "BLI_rand.h" #include "BLI_threads.h" #include "BLI_utildefines.h" @@ -75,6 +76,8 @@ extern struct Render R; typedef struct BakeShade { + int thread; + ShadeSample ssamp; ObjectInstanceRen *obi; VlakRen *vlr; @@ -737,6 +740,9 @@ static void bake_single_vertex(BakeShade *bs, VertRen *vert, float u, float v) MLoopCol *basevcol; MLoop *mloop; + /* per vertex fixed seed */ + BLI_thread_srandom(bs->thread, vert->index); + origindex = RE_vertren_get_origindex(bs->obi->obr, vert, 0); if (!origindex || *origindex == ORIGINDEX_NONE) return; @@ -811,6 +817,9 @@ static void shade_tface(BakeShade *bs) Image *ima = tface->tpage; float vec[4][2]; int a, i1, i2, i3; + + /* per face fixed seed */ + BLI_thread_srandom(bs->thread, vlr->index); /* check valid zspan */ if (ima != bs->ima) { @@ -1037,6 +1046,8 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up /* get the threads running */ for (a = 0; a < re->r.threads; a++) { + handles[a].thread = a; + /* set defaults in handles */ handles[a].ssamp.shi[0].lay = re->lay; diff --git a/source/gameengine/Ketsji/KX_VertexProxy.cpp b/source/gameengine/Ketsji/KX_VertexProxy.cpp index cd1c9eed91b..163416526f3 100644 --- a/source/gameengine/Ketsji/KX_VertexProxy.cpp +++ b/source/gameengine/Ketsji/KX_VertexProxy.cpp @@ -63,11 +63,11 @@ PyTypeObject KX_VertexProxy::Type = { PyMethodDef KX_VertexProxy::Methods[] = { {"getXYZ", (PyCFunction)KX_VertexProxy::sPyGetXYZ,METH_NOARGS}, {"setXYZ", (PyCFunction)KX_VertexProxy::sPySetXYZ,METH_O}, - {"getUV", (PyCFunction)KX_VertexProxy::sPyGetUV1, METH_NOARGS}, - {"setUV", (PyCFunction)KX_VertexProxy::sPySetUV1, METH_O}, + {"getUV", (PyCFunction)KX_VertexProxy::sPyGetUV, METH_VARARGS}, + {"setUV", (PyCFunction)KX_VertexProxy::sPySetUV, METH_VARARGS}, {"getUV2", (PyCFunction)KX_VertexProxy::sPyGetUV2,METH_NOARGS}, - {"setUV2", (PyCFunction)KX_VertexProxy::sPySetUV2,METH_VARARGS}, + {"setUV2", (PyCFunction)KX_VertexProxy::sPySetUV2, METH_O}, {"getRGBA", (PyCFunction)KX_VertexProxy::sPyGetRGBA,METH_NOARGS}, {"setRGBA", (PyCFunction)KX_VertexProxy::sPySetRGBA,METH_O}, @@ -423,7 +423,6 @@ int KX_VertexProxy::pyattr_set_uvs(void *self_v, const struct KX_PYATTRIBUTE_DEF if (PyVecTo(PySequence_GetItem(value, i), vec)) { self->m_vertex->SetUV(i, vec); - self->m_mesh->SetMeshModified(true); } else { @@ -559,25 +558,45 @@ PyObject *KX_VertexProxy::PySetRGBA(PyObject *value) return NULL; } - -PyObject *KX_VertexProxy::PyGetUV1() +PyObject *KX_VertexProxy::PyGetUV(PyObject *args) { - return PyObjectFrom(MT_Vector2(m_vertex->getUV(0))); + int index = 0; + if (!PyArg_ParseTuple(args, "|i:getUV", &index)) + return NULL; + + if (index < 0 || index > (RAS_TexVert::MAX_UNIT - 1)) { + PyErr_Format(PyExc_TypeError, "vert.getUV(index): KX_VertexProxy, expected an int between 0 and %i", (RAS_TexVert::MAX_UNIT - 1)); + return NULL; + } + + return PyObjectFrom(MT_Vector2(m_vertex->getUV(index))); } -PyObject *KX_VertexProxy::PySetUV1(PyObject *value) +PyObject *KX_VertexProxy::PySetUV(PyObject *args) { + PyObject *pyvect; + int index = 0; + if (!PyArg_ParseTuple(args, "O|i:setUV", &pyvect, &index)) + return NULL; + + if (index < 0 || index > (RAS_TexVert::MAX_UNIT - 1)) { + PyErr_Format(PyExc_TypeError, "vert.setUV(uv, index): KX_VertexProxy, expected an int between 0 and %i", (RAS_TexVert::MAX_UNIT - 1)); + return NULL; + } + MT_Point2 vec; - if (!PyVecTo(value, vec)) + if (!PyVecTo(pyvect, vec)) return NULL; - m_vertex->SetUV(0, vec); + m_vertex->SetUV(index, vec); m_mesh->SetMeshModified(true); Py_RETURN_NONE; } PyObject *KX_VertexProxy::PyGetUV2() { + ShowDeprecationWarning("getUV2()", "getUV(1)"); + return PyObjectFrom(MT_Vector2(m_vertex->getUV(1))); } @@ -587,6 +606,8 @@ PyObject *KX_VertexProxy::PySetUV2(PyObject *args) if (!PyVecTo(args, vec)) return NULL; + ShowDeprecationWarning("setUV2(uv)", "setUV(uv, 1)"); + m_vertex->SetUV(1, vec); m_mesh->SetMeshModified(true); Py_RETURN_NONE; diff --git a/source/gameengine/Ketsji/KX_VertexProxy.h b/source/gameengine/Ketsji/KX_VertexProxy.h index 8070825ad11..91cf29deca1 100644 --- a/source/gameengine/Ketsji/KX_VertexProxy.h +++ b/source/gameengine/Ketsji/KX_VertexProxy.h @@ -94,11 +94,11 @@ public: KX_PYMETHOD_NOARGS(KX_VertexProxy,GetXYZ); KX_PYMETHOD_O(KX_VertexProxy,SetXYZ); - KX_PYMETHOD_NOARGS(KX_VertexProxy,GetUV1); - KX_PYMETHOD_O(KX_VertexProxy,SetUV1); + KX_PYMETHOD_VARARGS(KX_VertexProxy, GetUV); + KX_PYMETHOD_VARARGS(KX_VertexProxy, SetUV); KX_PYMETHOD_NOARGS(KX_VertexProxy,GetUV2); - KX_PYMETHOD_VARARGS(KX_VertexProxy,SetUV2); + KX_PYMETHOD_O(KX_VertexProxy, SetUV2); KX_PYMETHOD_NOARGS(KX_VertexProxy,GetRGBA); KX_PYMETHOD_O(KX_VertexProxy,SetRGBA); |