Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntony Riakiotakis <kalast@gmail.com>2015-05-07 15:10:00 +0300
committerAntony Riakiotakis <kalast@gmail.com>2015-05-07 15:10:00 +0300
commit249b3cca61f2d6978939ef7399a2a8183811af91 (patch)
tree7754e424b8f078b38fefca277ed266d9429bd68c
parent429741ac198455564806fdbe351d666258711658 (diff)
parente39ec27bbaebcb85b2541e9756b408c554f602cb (diff)
Merge branch 'master' into gooseberry
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_VertexProxy.rst28
-rw-r--r--intern/cycles/kernel/kernel_bake.h2
-rw-r--r--intern/cycles/kernel/svm/svm.h14
-rw-r--r--release/scripts/presets/keyconfig/maya.py2
-rw-r--r--release/scripts/startup/bl_ui/space_node.py2
-rw-r--r--release/scripts/startup/bl_ui/space_view3d_toolbar.py2
-rw-r--r--release/windows/installer/00.sconsblender.nsi7
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c6
-rw-r--r--source/blender/blenkernel/intern/text.c125
-rw-r--r--source/blender/bmesh/intern/bmesh_queries.c10
-rw-r--r--source/blender/editors/mesh/editmesh_rip.c31
-rw-r--r--source/blender/editors/render/render_opengl.c9
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c18
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c13
-rw-r--r--source/blender/editors/transform/transform.c317
-rw-r--r--source/blender/editors/transform/transform.h7
-rw-r--r--source/blender/editors/transform/transform_ops.c2
-rw-r--r--source/blender/makesdna/DNA_scene_types.h5
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c2
-rw-r--r--source/blender/makesrna/intern/rna_sculpt_paint.c7
-rw-r--r--source/blender/render/intern/source/bake.c11
-rw-r--r--source/gameengine/Ketsji/KX_VertexProxy.cpp41
-rw-r--r--source/gameengine/Ketsji/KX_VertexProxy.h6
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);