Merge branch 'master' into sculpt-dev
This commit is contained in:
commit
38dce1d29d
|
@ -163,13 +163,13 @@ Now in the button's context menu select *Copy Data Path*, then paste the result
|
|||
|
||||
.. code-block:: python
|
||||
|
||||
bpy.context.active_object.modifiers["Subsurf"].levels
|
||||
bpy.context.active_object.modifiers["Subdivision"].levels
|
||||
|
||||
Press :kbd:`Return` and you'll get the current value of 1. Now try changing the value to 2:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
bpy.context.active_object.modifiers["Subsurf"].levels = 2
|
||||
bpy.context.active_object.modifiers["Subdivision"].levels = 2
|
||||
|
||||
You can see the value update in the Subdivision Surface modifier's UI as well as the cube.
|
||||
|
||||
|
@ -185,43 +185,31 @@ For example, if you want to access the texture of a brush via Python to adjust i
|
|||
#. Start in the default scene and enable Sculpt Mode from the 3D Viewport header.
|
||||
#. From the Sidebar expand the Brush Settings panel's *Texture* subpanel and add a new texture.
|
||||
*Notice the texture data-block menu itself doesn't have very useful links (you can check the tooltips).*
|
||||
#. The contrast setting isn't exposed in the Sidebar, so view the texture in the properties editor:
|
||||
|
||||
- In the properties editor select the Texture tab.
|
||||
- Select brush texture.
|
||||
- Expand the *Colors* panel to locate the *Contrast* number field.
|
||||
#. The contrast setting isn't exposed in the Sidebar, so view the texture in the
|
||||
:ref:`Properties Editor <blender_manual:bpy.types.Texture.contrast`
|
||||
#. Open the context menu of the contrast field and select *Online Python Reference*.
|
||||
This takes you to ``bpy.types.Texture.contrast``. Now you can see that ``contrast`` is a property of texture.
|
||||
#. To find out how to access the texture from the brush check on the references at the bottom of the page.
|
||||
Sometimes there are many references, and it may take some guesswork to find the right one,
|
||||
but in this case it's ``Brush.texture``.
|
||||
|
||||
but in this case it's ``tool_settings.sculpt.brush.texture``.
|
||||
#. Now you know that the texture can be accessed from ``bpy.data.brushes["BrushName"].texture``
|
||||
but normally you *won't* want to access the brush by name, instead you want to access the active brush.
|
||||
So the next step is to check on where brushes are accessed from via the references.
|
||||
In this case there it is simply ``bpy.context.brush``.
|
||||
|
||||
Now you can use the Python console to form the nested properties needed to access brush textures contrast:
|
||||
*Context -> Brush -> Texture -> Contrast*.
|
||||
:menuselection:`Context --> Tool Settings --> Sculpt --> Brush --> Texture --> Contrast`.
|
||||
|
||||
Since the attribute for each is given along the way you can compose the data path in the Python console:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
bpy.context.brush.texture.contrast
|
||||
|
||||
There can be multiple ways to access the same data, which you choose often depends on the task.
|
||||
An alternate path to access the same setting is:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
bpy.context.sculpt.brush.texture.contrast
|
||||
bpy.context.tool_settings.sculpt.brush.texture.contrast
|
||||
|
||||
Or access the brush directly:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
bpy.data.brushes["BrushName"].texture.contrast
|
||||
bpy.data.textures["Texture"].contrast
|
||||
|
||||
|
||||
If you are writing a user tool normally you want to use the :mod:`bpy.context` since the user normally expects
|
||||
|
|
|
@ -35,12 +35,13 @@ but not to fully cover each topic.
|
|||
|
||||
A quick list of helpful things to know before starting:
|
||||
|
||||
- Blender uses Python 3.x; some online documentation still assumes version 2.x.
|
||||
- The interactive console is great for testing one-liners.
|
||||
It also has autocompletion so you can inspect the API quickly.
|
||||
- Button tooltips show Python attributes and operator names.
|
||||
- The context menu of buttons directly links to this API documentation.
|
||||
- More operator examples can be found in the text editor's template menu.
|
||||
- Enable :ref:`Developer Extra <blender_manual:prefs-interface-dev-extras`
|
||||
and :ref:`Python Tooltips <blender_manual:prefs-interface-tooltips-python>`.
|
||||
- The :ref:`Python Console <blender_manual:bpy.types.SpaceConsole>`
|
||||
is great for testing one-liners; it has autocompletion so you can inspect the API quickly.
|
||||
- Button tooltips show Python attributes and operator names (when enabled see above).
|
||||
- The context menu of buttons directly links to this API documentation (when enabled see above).
|
||||
- Many python examples can be found in the text editor's template menu.
|
||||
- To examine further scripts distributed with Blender, see:
|
||||
|
||||
- ``scripts/startup/bl_ui`` for the user interface.
|
||||
|
|
|
@ -24,10 +24,9 @@ The three main use cases for the terminal are:
|
|||
- If the script runs for too long or you accidentally enter an infinite loop,
|
||||
:kbd:`Ctrl-C` in the terminal (:kbd:`Ctrl-Break` on Windows) will quit the script early.
|
||||
|
||||
.. note::
|
||||
.. seealso::
|
||||
|
||||
For Linux and macOS users this means starting the terminal first, then running Blender from within it.
|
||||
On Windows the terminal can be enabled from the Help menu.
|
||||
:ref:`blender_manual:command_line-launch-index`.
|
||||
|
||||
|
||||
Interface Tricks
|
||||
|
|
|
@ -1514,11 +1514,24 @@ class OptiXDevice : public CUDADevice {
|
|||
}
|
||||
else {
|
||||
unsigned int num_instances = 0;
|
||||
unsigned int max_num_instances = 0xFFFFFFFF;
|
||||
|
||||
bvh_optix->as_data.free();
|
||||
bvh_optix->traversable_handle = 0;
|
||||
bvh_optix->motion_transform_data.free();
|
||||
|
||||
optixDeviceContextGetProperty(context,
|
||||
OPTIX_DEVICE_PROPERTY_LIMIT_MAX_INSTANCE_ID,
|
||||
&max_num_instances,
|
||||
sizeof(max_num_instances));
|
||||
// Do not count first bit, which is used to distinguish instanced and non-instanced objects
|
||||
max_num_instances >>= 1;
|
||||
if (bvh->objects.size() > max_num_instances) {
|
||||
progress.set_error(
|
||||
"Failed to build OptiX acceleration structure because there are too many instances");
|
||||
return;
|
||||
}
|
||||
|
||||
// Fill instance descriptions
|
||||
# if OPTIX_ABI_VERSION < 41
|
||||
device_vector<OptixAabb> aabbs(this, "optix tlas aabbs", MEM_READ_ONLY);
|
||||
|
@ -1572,8 +1585,8 @@ class OptiXDevice : public CUDADevice {
|
|||
instance.transform[5] = 1.0f;
|
||||
instance.transform[10] = 1.0f;
|
||||
|
||||
// Set user instance ID to object index
|
||||
instance.instanceId = ob->get_device_index();
|
||||
// Set user instance ID to object index (but leave low bit blank)
|
||||
instance.instanceId = ob->get_device_index() << 1;
|
||||
|
||||
// Have to have at least one bit in the mask, or else instance would always be culled
|
||||
instance.visibilityMask = 1;
|
||||
|
@ -1679,9 +1692,9 @@ class OptiXDevice : public CUDADevice {
|
|||
else {
|
||||
// Disable instance transform if geometry already has it applied to vertex data
|
||||
instance.flags = OPTIX_INSTANCE_FLAG_DISABLE_TRANSFORM;
|
||||
// Non-instanced objects read ID from prim_object, so
|
||||
// distinguish them from instanced objects with high bit set
|
||||
instance.instanceId |= 0x800000;
|
||||
// Non-instanced objects read ID from 'prim_object', so distinguish
|
||||
// them from instanced objects with the low bit set
|
||||
instance.instanceId |= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,13 +45,12 @@ template<bool always = false> ccl_device_forceinline uint get_object_id()
|
|||
uint object = optixGetInstanceId();
|
||||
#endif
|
||||
// Choose between always returning object ID or only for instances
|
||||
if (always)
|
||||
// Can just remove the high bit since instance always contains object ID
|
||||
return object & 0x7FFFFF;
|
||||
// Set to OBJECT_NONE if this is not an instanced object
|
||||
else if (object & 0x800000)
|
||||
object = OBJECT_NONE;
|
||||
return object;
|
||||
if (always || (object & 1) == 0)
|
||||
// Can just remove the low bit since instance always contains object ID
|
||||
return object >> 1;
|
||||
else
|
||||
// Set to OBJECT_NONE if this is not an instanced object
|
||||
return OBJECT_NONE;
|
||||
}
|
||||
|
||||
extern "C" __global__ void __raygen__kernel_optix_path_trace()
|
||||
|
|
|
@ -17,7 +17,7 @@ inkscape_bin = os.environ.get("INKSCAPE_BIN", "inkscape")
|
|||
blender_bin = os.environ.get("BLENDER_BIN", "blender")
|
||||
|
||||
if sys.platform == 'darwin':
|
||||
inkscape_app_path = '/Applications/Inkscape.app/Contents/Resources/script'
|
||||
inkscape_app_path = '/Applications/Inkscape.app/Contents/MacOS/inkscape'
|
||||
if os.path.exists(inkscape_app_path):
|
||||
inkscape_bin = inkscape_app_path
|
||||
blender_app_path = '/Applications/Blender.app/Contents/MacOS/Blender'
|
||||
|
@ -29,8 +29,8 @@ cmd = (
|
|||
os.path.join(BASEDIR, "blender_icons.svg"),
|
||||
"--export-width=602",
|
||||
"--export-height=640",
|
||||
"--without-gui",
|
||||
"--export-png=" + os.path.join(BASEDIR, "blender_icons16.png"),
|
||||
"--export-type=png",
|
||||
"--export-filename=" + os.path.join(BASEDIR, "blender_icons16.png"),
|
||||
)
|
||||
run(cmd)
|
||||
|
||||
|
@ -39,8 +39,8 @@ cmd = (
|
|||
os.path.join(BASEDIR, "blender_icons.svg"),
|
||||
"--export-width=1204",
|
||||
"--export-height=1280",
|
||||
"--without-gui",
|
||||
"--export-png=" + os.path.join(BASEDIR, "blender_icons32.png"),
|
||||
"--export-type=png",
|
||||
"--export-filename=" + os.path.join(BASEDIR, "blender_icons32.png"),
|
||||
)
|
||||
run(cmd)
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ BASEDIR = os.path.abspath(os.path.dirname(__file__))
|
|||
inkscape_path = 'inkscape'
|
||||
|
||||
if sys.platform == 'darwin':
|
||||
inkscape_app_path = '/Applications/Inkscape.app/Contents/Resources/script'
|
||||
inkscape_app_path = '/Applications/Inkscape.app/Contents/MacOS/inkscape'
|
||||
if os.path.exists(inkscape_app_path):
|
||||
inkscape_path = inkscape_app_path
|
||||
|
||||
|
@ -19,7 +19,7 @@ cmd = (
|
|||
os.path.join(BASEDIR, "prvicons.svg"),
|
||||
"--export-width=1792",
|
||||
"--export-height=256",
|
||||
"--without-gui",
|
||||
"--export-png=" + os.path.join(BASEDIR, "prvicons.png"),
|
||||
"--export-type=png",
|
||||
"--export-filename=" + os.path.join(BASEDIR, "prvicons.png"),
|
||||
)
|
||||
subprocess.check_call(cmd)
|
||||
|
|
|
@ -4566,7 +4566,7 @@ def km_mesh(params):
|
|||
op_menu("VIEW3D_MT_edit_mesh_merge", {"type": 'M', "value": 'PRESS'}),
|
||||
op_menu("VIEW3D_MT_edit_mesh_split", {"type": 'M', "value": 'PRESS', "alt": True}),
|
||||
("transform.shrink_fatten", {"type": 'S', "value": 'PRESS', "alt": True}, None),
|
||||
("mesh.edge_face_add", {"type": 'F', "value": 'PRESS'}, None),
|
||||
("mesh.edge_face_add", {"type": 'F', "value": 'PRESS', "repeat": True}, None),
|
||||
("mesh.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True}, None),
|
||||
op_menu("VIEW3D_MT_mesh_add", {"type": 'A', "value": 'PRESS', "shift": True}),
|
||||
("mesh.separate", {"type": 'P', "value": 'PRESS'}, None),
|
||||
|
|
|
@ -27,6 +27,9 @@ def geometry_node_group_empty_new(context):
|
|||
output_node = group.nodes.new('NodeGroupOutput')
|
||||
output_node.is_active_output = True
|
||||
|
||||
input_node.select = False
|
||||
output_node.select = False
|
||||
|
||||
input_node.location.x = -200 - input_node.width
|
||||
output_node.location.x = 200
|
||||
|
||||
|
@ -38,8 +41,8 @@ def geometry_node_group_empty_new(context):
|
|||
def geometry_modifier_poll(context) -> bool:
|
||||
ob = context.object
|
||||
|
||||
# Test object support for geometry node modifier (No volume or hair object support yet)
|
||||
if not ob or ob.type not in {'MESH', 'CURVE', 'SURFACE', 'META', 'FONT', 'POINTCLOUD'}:
|
||||
# Test object support for geometry node modifier (No volume, curve, or hair object support yet)
|
||||
if not ob or ob.type not in {'MESH', 'POINTCLOUD'}:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
@ -62,9 +65,6 @@ class NewGeometryNodesModifier(bpy.types.Operator):
|
|||
if not modifier:
|
||||
return {'CANCELLED'}
|
||||
|
||||
group = geometry_node_group_empty_new(context)
|
||||
modifier.node_group = group
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
|
|
|
@ -969,9 +969,9 @@ class PREFERENCES_OT_app_template_install(Operator):
|
|||
# Studio Light Operations
|
||||
|
||||
class PREFERENCES_OT_studiolight_install(Operator):
|
||||
"""Install a user defined studio light"""
|
||||
"""Install a user defined light"""
|
||||
bl_idname = "preferences.studiolight_install"
|
||||
bl_label = "Install Custom Studio Light"
|
||||
bl_label = "Install Light"
|
||||
|
||||
files: CollectionProperty(
|
||||
name="File Path",
|
||||
|
@ -981,7 +981,7 @@ class PREFERENCES_OT_studiolight_install(Operator):
|
|||
subtype='DIR_PATH',
|
||||
)
|
||||
filter_folder: BoolProperty(
|
||||
name="Filter folders",
|
||||
name="Filter Folders",
|
||||
default=True,
|
||||
options={'HIDDEN'},
|
||||
)
|
||||
|
@ -992,9 +992,9 @@ class PREFERENCES_OT_studiolight_install(Operator):
|
|||
type: EnumProperty(
|
||||
name="Type",
|
||||
items=(
|
||||
('MATCAP', "MatCap", ""),
|
||||
('WORLD', "World", ""),
|
||||
('STUDIO', "Studio", ""),
|
||||
('MATCAP', "MatCap", "Install custom MatCaps"),
|
||||
('WORLD', "World", "Install custom HDRIs"),
|
||||
('STUDIO', "Studio", "Install custom Studio Lights"),
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
@ -974,7 +974,7 @@ class WM_OT_path_open(Operator):
|
|||
return {'FINISHED'}
|
||||
|
||||
|
||||
def _wm_doc_get_id(doc_id, do_url=True, url_prefix=""):
|
||||
def _wm_doc_get_id(doc_id, do_url=True, url_prefix="", report=None):
|
||||
|
||||
def operator_exists_pair(a, b):
|
||||
# Not fast, this is only for docs.
|
||||
|
@ -1025,6 +1025,11 @@ def _wm_doc_get_id(doc_id, do_url=True, url_prefix=""):
|
|||
# Check class for dynamically registered types.
|
||||
rna_class = bpy.types.PropertyGroup.bl_rna_get_subclass_py(class_name)
|
||||
|
||||
if rna_class is None:
|
||||
if report is not None:
|
||||
report({'ERROR'}, iface_("Type \"%s\" can not be found") % class_name)
|
||||
return None
|
||||
|
||||
# Detect if this is a inherited member and use that name instead.
|
||||
rna_parent = rna_class.bl_rna
|
||||
rna_prop = rna_parent.properties.get(class_prop)
|
||||
|
@ -1084,9 +1089,9 @@ class WM_OT_doc_view_manual(Operator):
|
|||
return url
|
||||
|
||||
def execute(self, _context):
|
||||
rna_id = _wm_doc_get_id(self.doc_id, do_url=False)
|
||||
rna_id = _wm_doc_get_id(self.doc_id, do_url=False, report=self.report)
|
||||
if rna_id is None:
|
||||
return {'PASS_THROUGH'}
|
||||
return {'CANCELLED'}
|
||||
|
||||
url = self._lookup_rna_url(rna_id)
|
||||
|
||||
|
@ -1118,9 +1123,9 @@ class WM_OT_doc_view(Operator):
|
|||
_prefix = ("https://docs.blender.org/api/master")
|
||||
|
||||
def execute(self, _context):
|
||||
url = _wm_doc_get_id(self.doc_id, do_url=True, url_prefix=self._prefix)
|
||||
url = _wm_doc_get_id(self.doc_id, do_url=True, url_prefix=self._prefix, report=self.report)
|
||||
if url is None:
|
||||
return {'PASS_THROUGH'}
|
||||
return {'CANCELLED'}
|
||||
|
||||
import webbrowser
|
||||
webbrowser.open(url)
|
||||
|
|
|
@ -486,14 +486,12 @@ class RENDER_PT_eevee_film(RenderButtonsPanel, Panel):
|
|||
col.prop(rd, "film_transparent", text="Transparent")
|
||||
|
||||
col = layout.column(align=False, heading="Overscan")
|
||||
col.use_property_decorate = False
|
||||
row = col.row(align=True)
|
||||
sub = row.row(align=True)
|
||||
sub.prop(props, "use_overscan", text="")
|
||||
sub = sub.row(align=True)
|
||||
sub.active = props.use_overscan
|
||||
sub.prop(props, "overscan_size", text="")
|
||||
row.prop_decorator(props, "overscan_size")
|
||||
|
||||
|
||||
class RENDER_PT_eevee_hair(RenderButtonsPanel, Panel):
|
||||
|
|
|
@ -412,7 +412,19 @@ class SEQUENCER_MT_view(Menu):
|
|||
layout.separator()
|
||||
layout.prop(st, "show_seconds")
|
||||
layout.prop(st, "show_markers")
|
||||
layout.menu("SEQUENCER_MT_view_cache", text="Show Cache")
|
||||
if context.preferences.view.show_developer_ui:
|
||||
layout.menu("SEQUENCER_MT_view_cache", text="Show Cache")
|
||||
|
||||
if is_preview:
|
||||
layout.separator()
|
||||
if st.display_mode == 'IMAGE':
|
||||
layout.prop(st, "use_zoom_to_fit")
|
||||
layout.prop(ed, "show_overlay", text="Show Frame Overlay")
|
||||
layout.prop(st, "show_safe_areas", text="Show Safe Areas")
|
||||
layout.prop(st, "show_metadata", text="Show Metadata")
|
||||
layout.prop(st, "show_annotation", text="Show Annotations")
|
||||
elif st.display_mode == 'WAVEFORM':
|
||||
layout.prop(st, "show_separate_color", text="Show Separate Color Channels")
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
@ -1877,11 +1889,12 @@ class SEQUENCER_PT_adjust_color(SequencerButtonsPanel, Panel):
|
|||
|
||||
class SEQUENCER_PT_cache_settings(SequencerButtonsPanel, Panel):
|
||||
bl_label = "Cache Settings"
|
||||
bl_category = "Proxy & Cache"
|
||||
bl_category = "Cache"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return cls.has_sequencer(context) and context.scene.sequence_editor
|
||||
show_developer_ui = context.preferences.view.show_developer_ui
|
||||
return cls.has_sequencer(context) and context.scene.sequence_editor and show_developer_ui
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
@ -1900,7 +1913,7 @@ class SEQUENCER_PT_cache_settings(SequencerButtonsPanel, Panel):
|
|||
|
||||
class SEQUENCER_PT_proxy_settings(SequencerButtonsPanel, Panel):
|
||||
bl_label = "Proxy Settings"
|
||||
bl_category = "Proxy & Cache"
|
||||
bl_category = "Proxy"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
|
@ -1925,7 +1938,7 @@ class SEQUENCER_PT_proxy_settings(SequencerButtonsPanel, Panel):
|
|||
|
||||
class SEQUENCER_PT_strip_proxy(SequencerButtonsPanel, Panel):
|
||||
bl_label = "Strip Proxy & Timecode"
|
||||
bl_category = "Proxy & Cache"
|
||||
bl_category = "Proxy"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
|
@ -1987,14 +2000,15 @@ class SEQUENCER_PT_strip_proxy(SequencerButtonsPanel, Panel):
|
|||
|
||||
class SEQUENCER_PT_strip_cache(SequencerButtonsPanel, Panel):
|
||||
bl_label = "Strip Cache"
|
||||
bl_category = "Proxy & Cache"
|
||||
bl_category = "Cache"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
show_developer_ui = context.preferences.view.show_developer_ui
|
||||
if not cls.has_sequencer(context):
|
||||
return False
|
||||
if act_strip(context) is not None:
|
||||
if act_strip(context) is not None and show_developer_ui:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
|
|
@ -1547,12 +1547,22 @@ class _defs_weight_paint:
|
|||
|
||||
@ToolDef.from_fn
|
||||
def sample_weight():
|
||||
def draw_settings(context, layout, tool):
|
||||
if context.tool_settings.unified_paint_settings.use_unified_weight:
|
||||
weight = context.tool_settings.unified_paint_settings.weight
|
||||
elif context.tool_settings.weight_paint.brush:
|
||||
weight = context.tool_settings.weight_paint.brush.weight
|
||||
else:
|
||||
return
|
||||
layout.label(text="Weight: %.3f" % weight)
|
||||
return dict(
|
||||
idname="builtin.sample_weight",
|
||||
label="Sample Weight",
|
||||
icon="ops.paint.weight_sample",
|
||||
cursor='EYEDROPPER',
|
||||
widget=None,
|
||||
keymap=(),
|
||||
draw_settings=draw_settings
|
||||
)
|
||||
|
||||
@ToolDef.from_fn
|
||||
|
@ -1561,6 +1571,7 @@ class _defs_weight_paint:
|
|||
idname="builtin.sample_vertex_group",
|
||||
label="Sample Vertex Group",
|
||||
icon="ops.paint.weight_sample_group",
|
||||
cursor='EYEDROPPER',
|
||||
widget=None,
|
||||
keymap=(),
|
||||
)
|
||||
|
|
|
@ -39,7 +39,7 @@ extern "C" {
|
|||
|
||||
/* Blender file format version. */
|
||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||
#define BLENDER_FILE_SUBVERSION 9
|
||||
#define BLENDER_FILE_SUBVERSION 10
|
||||
|
||||
/* Minimum Blender version that supports reading file written with the current
|
||||
* version. Older Blender versions will test this and show a warning if the file
|
||||
|
|
|
@ -49,6 +49,7 @@ int BKE_geometry_set_instances(const struct GeometrySet *geometry_set,
|
|||
float (**r_positions)[3],
|
||||
float (**r_rotations)[3],
|
||||
float (**r_scales)[3],
|
||||
int **r_ids,
|
||||
struct InstancedData **r_instanced_data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -364,6 +364,7 @@ class InstancesComponent : public GeometryComponent {
|
|||
blender::Vector<blender::float3> positions_;
|
||||
blender::Vector<blender::float3> rotations_;
|
||||
blender::Vector<blender::float3> scales_;
|
||||
blender::Vector<int> ids_;
|
||||
blender::Vector<InstancedData> instanced_data_;
|
||||
|
||||
public:
|
||||
|
@ -375,20 +376,24 @@ class InstancesComponent : public GeometryComponent {
|
|||
void add_instance(Object *object,
|
||||
blender::float3 position,
|
||||
blender::float3 rotation = {0, 0, 0},
|
||||
blender::float3 scale = {1, 1, 1});
|
||||
blender::float3 scale = {1, 1, 1},
|
||||
const int id = -1);
|
||||
void add_instance(Collection *collection,
|
||||
blender::float3 position,
|
||||
blender::float3 rotation = {0, 0, 0},
|
||||
blender::float3 scale = {1, 1, 1});
|
||||
blender::float3 scale = {1, 1, 1},
|
||||
const int id = -1);
|
||||
void add_instance(InstancedData data,
|
||||
blender::float3 position,
|
||||
blender::float3 rotation,
|
||||
blender::float3 scale);
|
||||
blender::float3 scale,
|
||||
const int id = -1);
|
||||
|
||||
blender::Span<InstancedData> instanced_data() const;
|
||||
blender::Span<blender::float3> positions() const;
|
||||
blender::Span<blender::float3> rotations() const;
|
||||
blender::Span<blender::float3> scales() const;
|
||||
blender::Span<int> ids() const;
|
||||
blender::MutableSpan<blender::float3> positions();
|
||||
int instances_amount() const;
|
||||
|
||||
|
|
|
@ -229,7 +229,7 @@ struct Mesh *BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph,
|
|||
struct Scene *scene,
|
||||
struct Object *ob_eval,
|
||||
struct ModifierData *md_eval,
|
||||
int build_shapekey_layers);
|
||||
const bool build_shapekey_layers);
|
||||
|
||||
/* Copies a nomain-Mesh into an existing Mesh. */
|
||||
void BKE_mesh_nomain_to_mesh(struct Mesh *mesh_src,
|
||||
|
|
|
@ -110,6 +110,8 @@ void BKE_toolsettings_free(struct ToolSettings *toolsettings);
|
|||
struct Scene *BKE_scene_duplicate(struct Main *bmain, struct Scene *sce, eSceneCopyMethod type);
|
||||
void BKE_scene_groups_relink(struct Scene *sce);
|
||||
|
||||
bool BKE_scene_can_be_removed(const struct Main *bmain, const struct Scene *scene);
|
||||
|
||||
bool BKE_scene_has_view_layer(const struct Scene *scene, const struct ViewLayer *layer);
|
||||
struct Scene *BKE_scene_find_from_collection(const struct Main *bmain,
|
||||
const struct Collection *collection);
|
||||
|
|
|
@ -140,11 +140,8 @@ typedef struct UndoType {
|
|||
UndoTypeForEachIDRefFn foreach_ID_ref_fn,
|
||||
void *user_data);
|
||||
|
||||
/**
|
||||
* This undo type `encode` callback needs a valid context, it will fail otherwise.
|
||||
* \note Callback is still supposed to properly deal with a NULL context pointer.
|
||||
*/
|
||||
bool use_context_for_encode;
|
||||
/** Information for the generic undo system to refine handling of this specific undo type. */
|
||||
uint flags;
|
||||
|
||||
/**
|
||||
* The size of the undo struct 'inherited' from #UndoStep for that specific type. Used for
|
||||
|
@ -152,6 +149,15 @@ typedef struct UndoType {
|
|||
size_t step_size;
|
||||
} UndoType;
|
||||
|
||||
/** #UndoType.flag bitflags. */
|
||||
typedef enum UndoTypeFlags {
|
||||
/**
|
||||
* This undo type `encode` callback needs a valid context, it will fail otherwise.
|
||||
* \note Callback is still supposed to properly deal with a NULL context pointer.
|
||||
*/
|
||||
UNDOTYPE_FLAG_NEED_CONTEXT_FOR_ENCODE = 1 << 0,
|
||||
} UndoTypeFlags;
|
||||
|
||||
/* Expose since we need to perform operations on specific undo types (rarely). */
|
||||
extern const UndoType *BKE_UNDOSYS_TYPE_IMAGE;
|
||||
extern const UndoType *BKE_UNDOSYS_TYPE_MEMFILE;
|
||||
|
|
|
@ -417,7 +417,7 @@ void BKE_blender_atexit_unregister(void (*func)(void *user_data), const void *us
|
|||
free(ae);
|
||||
return;
|
||||
}
|
||||
ae_p = &ae;
|
||||
ae_p = &ae->next;
|
||||
ae = ae->next;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1002,6 +1002,23 @@ static int cloth_selfcollision_response_static(ClothModifierData *clmd,
|
|||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
static bool cloth_bvh_collision_is_active(const ClothModifierData *UNUSED(clmd),
|
||||
const Cloth *cloth,
|
||||
const MVertTri *tri_a)
|
||||
{
|
||||
const ClothVertex *verts = cloth->verts;
|
||||
|
||||
/* Fully pinned triangles don't need collision processing. */
|
||||
const int flags_a = verts[tri_a->tri[0]].flags & verts[tri_a->tri[1]].flags &
|
||||
verts[tri_a->tri[2]].flags;
|
||||
|
||||
if (flags_a & CLOTH_VERT_FLAG_PINNED) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void cloth_collision(void *__restrict userdata,
|
||||
const int index,
|
||||
const TaskParallelTLS *__restrict UNUSED(tls))
|
||||
|
@ -1059,13 +1076,31 @@ static void cloth_collision(void *__restrict userdata,
|
|||
}
|
||||
}
|
||||
|
||||
static bool cloth_bvh_selfcollision_is_active(const Cloth *cloth,
|
||||
static bool cloth_bvh_selfcollision_is_active(const ClothModifierData *clmd,
|
||||
const Cloth *cloth,
|
||||
const MVertTri *tri_a,
|
||||
const MVertTri *tri_b,
|
||||
bool sewing_active)
|
||||
const MVertTri *tri_b)
|
||||
{
|
||||
const ClothVertex *verts = cloth->verts;
|
||||
|
||||
/* Skip when either triangle is excluded. */
|
||||
const int flags_a = verts[tri_a->tri[0]].flags & verts[tri_a->tri[1]].flags &
|
||||
verts[tri_a->tri[2]].flags;
|
||||
const int flags_b = verts[tri_b->tri[0]].flags & verts[tri_b->tri[1]].flags &
|
||||
verts[tri_b->tri[2]].flags;
|
||||
|
||||
if ((flags_a | flags_b) & CLOTH_VERT_FLAG_NOSELFCOLL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Skip when both triangles are pinned. */
|
||||
if ((flags_a & flags_b) & CLOTH_VERT_FLAG_PINNED) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Ignore overlap of neighboring triangles and triangles connected by a sewing edge. */
|
||||
bool sewing_active = (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SEW);
|
||||
|
||||
for (uint i = 0; i < 3; i++) {
|
||||
for (uint j = 0; j < 3; j++) {
|
||||
if (tri_a->tri[i] == tri_b->tri[j]) {
|
||||
|
@ -1080,12 +1115,6 @@ static bool cloth_bvh_selfcollision_is_active(const Cloth *cloth,
|
|||
}
|
||||
}
|
||||
|
||||
if (((verts[tri_a->tri[0]].flags & verts[tri_a->tri[1]].flags & verts[tri_a->tri[2]].flags) |
|
||||
(verts[tri_b->tri[0]].flags & verts[tri_b->tri[1]].flags & verts[tri_b->tri[2]].flags)) &
|
||||
CLOTH_VERT_FLAG_NOSELFCOLL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1106,10 +1135,7 @@ static void cloth_selfcollision(void *__restrict userdata,
|
|||
tri_a = &clmd->clothObject->tri[data->overlap[index].indexA];
|
||||
tri_b = &clmd->clothObject->tri[data->overlap[index].indexB];
|
||||
|
||||
#ifdef DEBUG
|
||||
bool sewing_active = (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SEW);
|
||||
BLI_assert(cloth_bvh_selfcollision_is_active(clmd->clothObject, tri_a, tri_b, sewing_active));
|
||||
#endif
|
||||
BLI_assert(cloth_bvh_selfcollision_is_active(clmd, clmd->clothObject, tri_a, tri_b));
|
||||
|
||||
/* Compute distance and normal. */
|
||||
distance = compute_collision_point_tri_tri(verts1[tri_a->tri[0]].tx,
|
||||
|
@ -1508,6 +1534,18 @@ static int cloth_bvh_selfcollisions_resolve(ClothModifierData *clmd,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static bool cloth_bvh_obj_overlap_cb(void *userdata,
|
||||
int index_a,
|
||||
int UNUSED(index_b),
|
||||
int UNUSED(thread))
|
||||
{
|
||||
ClothModifierData *clmd = (ClothModifierData *)userdata;
|
||||
struct Cloth *clothObject = clmd->clothObject;
|
||||
const MVertTri *tri_a = &clothObject->tri[index_a];
|
||||
|
||||
return cloth_bvh_collision_is_active(clmd, clothObject, tri_a);
|
||||
}
|
||||
|
||||
static bool cloth_bvh_self_overlap_cb(void *userdata, int index_a, int index_b, int UNUSED(thread))
|
||||
{
|
||||
/* No need for equal combinations (eg. (0,1) & (1,0)). */
|
||||
|
@ -1518,9 +1556,7 @@ static bool cloth_bvh_self_overlap_cb(void *userdata, int index_a, int index_b,
|
|||
tri_a = &clothObject->tri[index_a];
|
||||
tri_b = &clothObject->tri[index_b];
|
||||
|
||||
bool sewing_active = (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SEW);
|
||||
|
||||
if (cloth_bvh_selfcollision_is_active(clothObject, tri_a, tri_b, sewing_active)) {
|
||||
if (cloth_bvh_selfcollision_is_active(clmd, clothObject, tri_a, tri_b)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1578,8 +1614,11 @@ int cloth_bvh_collision(
|
|||
/* Move object to position (step) in time. */
|
||||
collision_move_object(collmd, step + dt, step, false);
|
||||
|
||||
overlap_obj[i] = BLI_bvhtree_overlap(
|
||||
cloth_bvh, collmd->bvhtree, &coll_counts_obj[i], NULL, NULL);
|
||||
overlap_obj[i] = BLI_bvhtree_overlap(cloth_bvh,
|
||||
collmd->bvhtree,
|
||||
&coll_counts_obj[i],
|
||||
is_hair ? NULL : cloth_bvh_obj_overlap_cb,
|
||||
clmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -476,34 +476,38 @@ void InstancesComponent::clear()
|
|||
void InstancesComponent::add_instance(Object *object,
|
||||
blender::float3 position,
|
||||
blender::float3 rotation,
|
||||
blender::float3 scale)
|
||||
blender::float3 scale,
|
||||
const int id)
|
||||
{
|
||||
InstancedData data;
|
||||
data.type = INSTANCE_DATA_TYPE_OBJECT;
|
||||
data.data.object = object;
|
||||
this->add_instance(data, position, rotation, scale);
|
||||
this->add_instance(data, position, rotation, scale, id);
|
||||
}
|
||||
|
||||
void InstancesComponent::add_instance(Collection *collection,
|
||||
blender::float3 position,
|
||||
blender::float3 rotation,
|
||||
blender::float3 scale)
|
||||
blender::float3 scale,
|
||||
const int id)
|
||||
{
|
||||
InstancedData data;
|
||||
data.type = INSTANCE_DATA_TYPE_COLLECTION;
|
||||
data.data.collection = collection;
|
||||
this->add_instance(data, position, rotation, scale);
|
||||
this->add_instance(data, position, rotation, scale, id);
|
||||
}
|
||||
|
||||
void InstancesComponent::add_instance(InstancedData data,
|
||||
blender::float3 position,
|
||||
blender::float3 rotation,
|
||||
blender::float3 scale)
|
||||
blender::float3 scale,
|
||||
const int id)
|
||||
{
|
||||
instanced_data_.append(data);
|
||||
positions_.append(position);
|
||||
rotations_.append(rotation);
|
||||
scales_.append(scale);
|
||||
ids_.append(id);
|
||||
}
|
||||
|
||||
Span<InstancedData> InstancesComponent::instanced_data() const
|
||||
|
@ -516,16 +520,21 @@ Span<float3> InstancesComponent::positions() const
|
|||
return positions_;
|
||||
}
|
||||
|
||||
blender::Span<blender::float3> InstancesComponent::rotations() const
|
||||
Span<float3> InstancesComponent::rotations() const
|
||||
{
|
||||
return rotations_;
|
||||
}
|
||||
|
||||
blender::Span<blender::float3> InstancesComponent::scales() const
|
||||
Span<float3> InstancesComponent::scales() const
|
||||
{
|
||||
return scales_;
|
||||
}
|
||||
|
||||
Span<int> InstancesComponent::ids() const
|
||||
{
|
||||
return ids_;
|
||||
}
|
||||
|
||||
MutableSpan<float3> InstancesComponent::positions()
|
||||
{
|
||||
return positions_;
|
||||
|
@ -565,6 +574,7 @@ int BKE_geometry_set_instances(const GeometrySet *geometry_set,
|
|||
float (**r_positions)[3],
|
||||
float (**r_rotations)[3],
|
||||
float (**r_scales)[3],
|
||||
int **r_ids,
|
||||
InstancedData **r_instanced_data)
|
||||
{
|
||||
const InstancesComponent *component = geometry_set->get_component_for_read<InstancesComponent>();
|
||||
|
@ -574,6 +584,8 @@ int BKE_geometry_set_instances(const GeometrySet *geometry_set,
|
|||
*r_positions = (float(*)[3])component->positions().data();
|
||||
*r_rotations = (float(*)[3])component->rotations().data();
|
||||
*r_scales = (float(*)[3])component->scales().data();
|
||||
*r_ids = (int *)component->ids().data();
|
||||
*r_instanced_data = (InstancedData *)component->instanced_data().data();
|
||||
*r_instanced_data = (InstancedData *)component->instanced_data().data();
|
||||
return component->instances_amount();
|
||||
}
|
||||
|
|
|
@ -1407,7 +1407,7 @@ Mesh *BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph,
|
|||
Scene *scene,
|
||||
Object *ob_eval,
|
||||
ModifierData *md_eval,
|
||||
int build_shapekey_layers)
|
||||
const bool build_shapekey_layers)
|
||||
{
|
||||
Mesh *me = ob_eval->runtime.data_orig ? ob_eval->runtime.data_orig : ob_eval->data;
|
||||
const ModifierTypeInfo *mti = BKE_modifier_get_info(md_eval->type);
|
||||
|
|
|
@ -816,9 +816,14 @@ static void make_duplis_instances_component(const DupliContext *ctx)
|
|||
float(*positions)[3];
|
||||
float(*rotations)[3];
|
||||
float(*scales)[3];
|
||||
int *ids;
|
||||
InstancedData *instanced_data;
|
||||
const int amount = BKE_geometry_set_instances(
|
||||
ctx->object->runtime.geometry_set_eval, &positions, &rotations, &scales, &instanced_data);
|
||||
const int amount = BKE_geometry_set_instances(ctx->object->runtime.geometry_set_eval,
|
||||
&positions,
|
||||
&rotations,
|
||||
&scales,
|
||||
&ids,
|
||||
&instanced_data);
|
||||
|
||||
for (int i = 0; i < amount; i++) {
|
||||
InstancedData *data = &instanced_data[i];
|
||||
|
@ -831,17 +836,19 @@ static void make_duplis_instances_component(const DupliContext *ctx)
|
|||
mul_m4_m4m4(instance_offset_matrix, rotation_matrix, scale_matrix);
|
||||
copy_v3_v3(instance_offset_matrix[3], positions[i]);
|
||||
|
||||
const int id = ids[i] != -1 ? ids[i] : i;
|
||||
|
||||
if (data->type == INSTANCE_DATA_TYPE_OBJECT) {
|
||||
Object *object = data->data.object;
|
||||
if (object != NULL) {
|
||||
float matrix[4][4];
|
||||
mul_m4_m4m4(matrix, ctx->object->obmat, instance_offset_matrix);
|
||||
make_dupli(ctx, object, matrix, i);
|
||||
make_dupli(ctx, object, matrix, id);
|
||||
|
||||
float space_matrix[4][4];
|
||||
mul_m4_m4m4(space_matrix, instance_offset_matrix, object->imat);
|
||||
mul_m4_m4_pre(space_matrix, ctx->object->obmat);
|
||||
make_recursive_duplis(ctx, object, space_matrix, i);
|
||||
make_recursive_duplis(ctx, object, space_matrix, id);
|
||||
}
|
||||
}
|
||||
else if (data->type == INSTANCE_DATA_TYPE_COLLECTION) {
|
||||
|
@ -862,8 +869,8 @@ static void make_duplis_instances_component(const DupliContext *ctx)
|
|||
float instance_matrix[4][4];
|
||||
mul_m4_m4m4(instance_matrix, collection_matrix, object->obmat);
|
||||
|
||||
make_dupli(ctx, object, instance_matrix, i);
|
||||
make_recursive_duplis(ctx, object, collection_matrix, i);
|
||||
make_dupli(ctx, object, instance_matrix, id);
|
||||
make_recursive_duplis(ctx, object, collection_matrix, id);
|
||||
}
|
||||
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_END;
|
||||
}
|
||||
|
|
|
@ -1904,7 +1904,6 @@ Scene *BKE_scene_duplicate(Main *bmain, Scene *sce, eSceneCopyMethod type)
|
|||
sce_copy->id.properties = IDP_CopyProperty(sce->id.properties);
|
||||
}
|
||||
|
||||
MEM_freeN(sce_copy->toolsettings);
|
||||
BKE_sound_destroy_scene(sce_copy);
|
||||
|
||||
/* copy color management settings */
|
||||
|
@ -1929,6 +1928,7 @@ Scene *BKE_scene_duplicate(Main *bmain, Scene *sce, eSceneCopyMethod type)
|
|||
sce_copy->display = sce->display;
|
||||
|
||||
/* tool settings */
|
||||
BKE_toolsettings_free(sce_copy->toolsettings);
|
||||
sce_copy->toolsettings = BKE_toolsettings_copy(sce->toolsettings, 0);
|
||||
|
||||
/* make a private copy of the avicodecdata */
|
||||
|
@ -2032,6 +2032,21 @@ void BKE_scene_groups_relink(Scene *sce)
|
|||
}
|
||||
}
|
||||
|
||||
bool BKE_scene_can_be_removed(const Main *bmain, const Scene *scene)
|
||||
{
|
||||
/* Linked scenes can always be removed. */
|
||||
if (ID_IS_LINKED(scene)) {
|
||||
return true;
|
||||
}
|
||||
/* Local scenes can only be removed, when there is at least one local scene left. */
|
||||
LISTBASE_FOREACH (Scene *, other_scene, &bmain->scenes) {
|
||||
if (other_scene != scene && !ID_IS_LINKED(other_scene)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Scene *BKE_scene_add(Main *bmain, const char *name)
|
||||
{
|
||||
Scene *sce;
|
||||
|
|
|
@ -252,9 +252,8 @@ static void undosys_stack_validate(UndoStack *ustack, bool expect_non_empty)
|
|||
}
|
||||
}
|
||||
#else
|
||||
static void undosys_stack_validate(UndoStack *ustack, bool expect_non_empty)
|
||||
static void undosys_stack_validate(UndoStack *UNUSED(ustack), bool UNUSED(expect_non_empty))
|
||||
{
|
||||
UNUSED_VARS(ustack, expect_non_empty);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -501,7 +500,7 @@ UndoPushReturn BKE_undosys_step_push_with_type(UndoStack *ustack,
|
|||
const char *name,
|
||||
const UndoType *ut)
|
||||
{
|
||||
BLI_assert(ut->use_context_for_encode == false || C != NULL);
|
||||
BLI_assert((ut->flags & UNDOTYPE_FLAG_NEED_CONTEXT_FOR_ENCODE) == 0 || C != NULL);
|
||||
|
||||
UNDO_NESTED_ASSERT(false);
|
||||
undosys_stack_validate(ustack, false);
|
||||
|
@ -676,9 +675,11 @@ bool BKE_undosys_step_undo_with_data_ex(UndoStack *ustack,
|
|||
bool use_skip)
|
||||
{
|
||||
UNDO_NESTED_ASSERT(false);
|
||||
if (us) {
|
||||
undosys_stack_validate(ustack, true);
|
||||
if (us == NULL) {
|
||||
return false;
|
||||
}
|
||||
undosys_stack_validate(ustack, true);
|
||||
|
||||
UndoStep *us_prev = us ? us->prev : NULL;
|
||||
if (us) {
|
||||
/* The current state is a copy, we need to load the previous state. */
|
||||
|
@ -754,6 +755,11 @@ bool BKE_undosys_step_redo_with_data_ex(UndoStack *ustack,
|
|||
bool use_skip)
|
||||
{
|
||||
UNDO_NESTED_ASSERT(false);
|
||||
if (us == NULL) {
|
||||
return false;
|
||||
}
|
||||
undosys_stack_validate(ustack, true);
|
||||
|
||||
UndoStep *us_next = us ? us->next : NULL;
|
||||
/* Unlike undo accumulate, we always use the next. */
|
||||
us = us_next;
|
||||
|
|
|
@ -699,6 +699,16 @@ static void do_versions_291_fcurve_handles_limit(FCurve *fcu)
|
|||
}
|
||||
}
|
||||
|
||||
static void do_versions_strip_cache_settings_recursive(const ListBase *seqbase)
|
||||
{
|
||||
LISTBASE_FOREACH (Sequence *, seq, seqbase) {
|
||||
seq->cache_flag = 0;
|
||||
if (seq->type == SEQ_TYPE_META) {
|
||||
do_versions_strip_cache_settings_recursive(&seq->seqbase);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* NOLINTNEXTLINE: readability-function-size */
|
||||
void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
||||
{
|
||||
|
@ -1480,23 +1490,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Versioning code until next subversion bump goes here.
|
||||
*
|
||||
* \note Be sure to check when bumping the version:
|
||||
* - "versioning_userdef.c", #blo_do_versions_userdef
|
||||
* - "versioning_userdef.c", #do_versions_theme
|
||||
*
|
||||
* \note Keep this message at the bottom of the function.
|
||||
*/
|
||||
{
|
||||
/* Keep this block, even when empty. */
|
||||
if (!DNA_struct_elem_find(fd->filesdna, "Brush", "CurveMapping", "*pressure_size_curve")) {
|
||||
LISTBASE_FOREACH (Brush *, br, &bmain->brushes) {
|
||||
BKE_brush_default_input_curves_set(br);
|
||||
}
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_ATLEAST(bmain, 292, 10)) {
|
||||
if (!DNA_struct_find(fd->filesdna, "NodeSetAlpha")) {
|
||||
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
||||
bNodeTree *nodetree = scene->nodetree;
|
||||
|
@ -1515,4 +1509,31 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
||||
Editing *ed = SEQ_editing_get(scene, false);
|
||||
if (ed == NULL) {
|
||||
continue;
|
||||
}
|
||||
ed->cache_flag = (SEQ_CACHE_STORE_RAW | SEQ_CACHE_STORE_FINAL_OUT);
|
||||
do_versions_strip_cache_settings_recursive(&ed->seqbase);
|
||||
}
|
||||
|
||||
/**
|
||||
* Versioning code until next subversion bump goes here.
|
||||
*
|
||||
* \note Be sure to check when bumping the version:
|
||||
* - "versioning_userdef.c", #blo_do_versions_userdef
|
||||
* - "versioning_userdef.c", #do_versions_theme
|
||||
*
|
||||
* \note Keep this message at the bottom of the function.
|
||||
*/
|
||||
{
|
||||
/* Keep this block, even when empty. */
|
||||
if (!DNA_struct_elem_find(fd->filesdna, "Brush", "CurveMapping", "*pressure_size_curve")) {
|
||||
LISTBASE_FOREACH (Brush *, br, &bmain->brushes) {
|
||||
BKE_brush_default_input_curves_set(br);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -330,9 +330,17 @@ static DRWVolumeGrid *volume_grid_cache_get(Volume *volume,
|
|||
format,
|
||||
GPU_DATA_FLOAT,
|
||||
dense_grid.voxels);
|
||||
GPU_texture_swizzle_set(cache_grid->texture, (channels == 3) ? "rgb1" : "rrr1");
|
||||
GPU_texture_wrap_mode(cache_grid->texture, false, false);
|
||||
BKE_volume_dense_float_grid_clear(&dense_grid);
|
||||
/* The texture can be null if the resolution along one axis is larger than
|
||||
* GL_MAX_3D_TEXTURE_SIZE. */
|
||||
if (cache_grid->texture != NULL) {
|
||||
GPU_texture_swizzle_set(cache_grid->texture, (channels == 3) ? "rgb1" : "rrr1");
|
||||
GPU_texture_wrap_mode(cache_grid->texture, false, false);
|
||||
BKE_volume_dense_float_grid_clear(&dense_grid);
|
||||
}
|
||||
else {
|
||||
MEM_freeN(dense_grid.voxels);
|
||||
printf("Error: Could not allocate 3D texture for volume.\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Free grid from memory if it wasn't previously loaded. */
|
||||
|
|
|
@ -249,7 +249,7 @@ void ED_armature_undosys_type(UndoType *ut)
|
|||
|
||||
ut->step_foreach_ID_ref = armature_undosys_foreach_ID_ref;
|
||||
|
||||
ut->use_context_for_encode = true;
|
||||
ut->flags = UNDOTYPE_FLAG_NEED_CONTEXT_FOR_ENCODE;
|
||||
|
||||
ut->step_size = sizeof(ArmatureUndoStep);
|
||||
}
|
||||
|
|
|
@ -1779,7 +1779,7 @@ static void pose_propagate_fcurve(
|
|||
float refVal = 0.0f;
|
||||
bool keyExists;
|
||||
int i, match;
|
||||
short first = 1;
|
||||
bool first = true;
|
||||
|
||||
/* skip if no keyframes to edit */
|
||||
if ((fcu->bezt == NULL) || (fcu->totvert < 2)) {
|
||||
|
@ -1826,7 +1826,7 @@ static void pose_propagate_fcurve(
|
|||
}
|
||||
else if (mode == POSE_PROPAGATE_NEXT_KEY) {
|
||||
/* stop after the first keyframe has been processed */
|
||||
if (first == 0) {
|
||||
if (first == false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1865,7 +1865,7 @@ static void pose_propagate_fcurve(
|
|||
|
||||
/* select keyframe to indicate that it's been changed */
|
||||
bezt->f2 |= SELECT;
|
||||
first = 0;
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -309,7 +309,7 @@ void ED_curve_undosys_type(UndoType *ut)
|
|||
|
||||
ut->step_foreach_ID_ref = curve_undosys_foreach_ID_ref;
|
||||
|
||||
ut->use_context_for_encode = true;
|
||||
ut->flags = UNDOTYPE_FLAG_NEED_CONTEXT_FOR_ENCODE;
|
||||
|
||||
ut->step_size = sizeof(CurveUndoStep);
|
||||
}
|
||||
|
|
|
@ -398,7 +398,7 @@ void ED_font_undosys_type(UndoType *ut)
|
|||
|
||||
ut->step_foreach_ID_ref = font_undosys_foreach_ID_ref;
|
||||
|
||||
ut->use_context_for_encode = true;
|
||||
ut->flags = UNDOTYPE_FLAG_NEED_CONTEXT_FOR_ENCODE;
|
||||
|
||||
ut->step_size = sizeof(FontUndoStep);
|
||||
}
|
||||
|
|
|
@ -424,11 +424,11 @@ bool ED_object_modifier_apply(struct Main *bmain,
|
|||
struct ModifierData *md,
|
||||
int mode,
|
||||
bool keep_modifier);
|
||||
int ED_object_modifier_copy(struct ReportList *reports,
|
||||
struct Main *bmain,
|
||||
struct Scene *scene,
|
||||
struct Object *ob,
|
||||
struct ModifierData *md);
|
||||
bool ED_object_modifier_copy(struct ReportList *reports,
|
||||
struct Main *bmain,
|
||||
struct Scene *scene,
|
||||
struct Object *ob,
|
||||
struct ModifierData *md);
|
||||
void ED_object_modifier_link(struct bContext *C, struct Object *ob_dst, struct Object *ob_src);
|
||||
void ED_object_modifier_copy_to_object(struct bContext *C,
|
||||
struct Object *ob_dst,
|
||||
|
|
|
@ -165,7 +165,6 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *region
|
|||
float *alert_color = tip_colors[UI_TIP_LC_ALERT];
|
||||
|
||||
float background_color[3];
|
||||
float tone_bg;
|
||||
|
||||
wmOrtho2_region_pixelspace(region);
|
||||
|
||||
|
@ -185,7 +184,7 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *region
|
|||
|
||||
/* find the brightness difference between background and text colors */
|
||||
|
||||
tone_bg = rgb_to_grayscale(background_color);
|
||||
const float tone_bg = rgb_to_grayscale(background_color);
|
||||
/* tone_fg = rgb_to_grayscale(main_color); */
|
||||
|
||||
/* mix the colors */
|
||||
|
@ -272,9 +271,7 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *region
|
|||
|
||||
static void ui_tooltip_region_free_cb(ARegion *region)
|
||||
{
|
||||
uiTooltipData *data;
|
||||
|
||||
data = region->regiondata;
|
||||
uiTooltipData *data = region->regiondata;
|
||||
|
||||
for (int i = 0; i < data->fields_len; i++) {
|
||||
const uiTooltipField *field = &data->fields[i];
|
||||
|
@ -1164,16 +1161,13 @@ static ARegion *ui_tooltip_create_with_data(bContext *C,
|
|||
const int winx = WM_window_pixels_x(win);
|
||||
const int winy = WM_window_pixels_y(win);
|
||||
const uiStyle *style = UI_style_get();
|
||||
static ARegionType type;
|
||||
ARegion *region;
|
||||
int fonth, fontw;
|
||||
int h, i;
|
||||
rcti rect_i;
|
||||
int font_flag = 0;
|
||||
|
||||
/* create area region */
|
||||
region = ui_region_temp_add(CTX_wm_screen(C));
|
||||
ARegion *region = ui_region_temp_add(CTX_wm_screen(C));
|
||||
|
||||
static ARegionType type;
|
||||
memset(&type, 0, sizeof(ARegionType));
|
||||
type.draw = ui_tooltip_region_draw_cb;
|
||||
type.free = ui_tooltip_region_free_cb;
|
||||
|
@ -1201,8 +1195,9 @@ static ARegion *ui_tooltip_create_with_data(bContext *C,
|
|||
#define TIP_BORDER_X (16.0f / aspect)
|
||||
#define TIP_BORDER_Y (6.0f / aspect)
|
||||
|
||||
h = BLF_height_max(data->fstyle.uifont_id);
|
||||
int h = BLF_height_max(data->fstyle.uifont_id);
|
||||
|
||||
int i, fonth, fontw;
|
||||
for (i = 0, fontw = 0, fonth = 0; i < data->fields_len; i++) {
|
||||
uiTooltipField *field = &data->fields[i];
|
||||
uiTooltipField *field_next = (i + 1) != data->fields_len ? &data->fields[i + 1] : NULL;
|
||||
|
|
|
@ -41,9 +41,7 @@
|
|||
|
||||
ARegion *ui_region_temp_add(bScreen *screen)
|
||||
{
|
||||
ARegion *region;
|
||||
|
||||
region = MEM_callocN(sizeof(ARegion), "area region");
|
||||
ARegion *region = MEM_callocN(sizeof(ARegion), __func__);
|
||||
BLI_addtail(&screen->regionbase, region);
|
||||
|
||||
region->regiontype = RGN_TYPE_TEMPORARY;
|
||||
|
|
|
@ -2558,7 +2558,7 @@ static void widget_state(uiWidgetType *wt, int state, int drawflag, eUIEmbossTyp
|
|||
wt->wcol_theme = &btheme->tui.wcol_list_item;
|
||||
|
||||
if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE | UI_SEARCH_FILTER_NO_MATCH)) {
|
||||
ui_widget_color_disabled(wt, state & UI_SEARCH_FILTER_NO_MATCH);
|
||||
ui_widget_color_disabled(wt, state);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -439,10 +439,10 @@ void WM_OT_alembic_export(wmOperatorType *ot)
|
|||
|
||||
RNA_def_enum(ot->srna,
|
||||
"ngon_method",
|
||||
rna_enum_modifier_triangulate_quad_method_items,
|
||||
rna_enum_modifier_triangulate_ngon_method_items,
|
||||
MOD_TRIANGULATE_NGON_BEAUTY,
|
||||
"Polygon Method",
|
||||
"Method for splitting the polygons into triangles");
|
||||
"N-gon Method",
|
||||
"Method for splitting the n-gons into triangles");
|
||||
|
||||
RNA_def_boolean(ot->srna,
|
||||
"export_hair",
|
||||
|
|
|
@ -283,7 +283,7 @@ void ED_lattice_undosys_type(UndoType *ut)
|
|||
|
||||
ut->step_foreach_ID_ref = lattice_undosys_foreach_ID_ref;
|
||||
|
||||
ut->use_context_for_encode = true;
|
||||
ut->flags = UNDOTYPE_FLAG_NEED_CONTEXT_FOR_ENCODE;
|
||||
|
||||
ut->step_size = sizeof(LatticeUndoStep);
|
||||
}
|
||||
|
|
|
@ -5340,8 +5340,8 @@ void MESH_OT_quads_convert_to_tris(wmOperatorType *ot)
|
|||
"ngon_method",
|
||||
rna_enum_modifier_triangulate_ngon_method_items,
|
||||
MOD_TRIANGULATE_NGON_BEAUTY,
|
||||
"Polygon Method",
|
||||
"Method for splitting the polygons into triangles");
|
||||
"N-gon Method",
|
||||
"Method for splitting the n-gons into triangles");
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -819,7 +819,7 @@ void ED_mesh_undosys_type(UndoType *ut)
|
|||
|
||||
ut->step_foreach_ID_ref = mesh_undosys_foreach_ID_ref;
|
||||
|
||||
ut->use_context_for_encode = true;
|
||||
ut->flags = UNDOTYPE_FLAG_NEED_CONTEXT_FOR_ENCODE;
|
||||
|
||||
ut->step_size = sizeof(MeshUndoStep);
|
||||
}
|
||||
|
|
|
@ -258,7 +258,7 @@ void ED_mball_undosys_type(UndoType *ut)
|
|||
|
||||
ut->step_foreach_ID_ref = mball_undosys_foreach_ID_ref;
|
||||
|
||||
ut->use_context_for_encode = true;
|
||||
ut->flags = UNDOTYPE_FLAG_NEED_CONTEXT_FOR_ENCODE;
|
||||
|
||||
ut->step_size = sizeof(MBallUndoStep);
|
||||
}
|
||||
|
|
|
@ -2411,7 +2411,7 @@ static const EnumPropertyItem convert_target_items[] = {
|
|||
ICON_OUTLINER_OB_MESH,
|
||||
"Mesh",
|
||||
#ifdef WITH_POINT_CLOUD
|
||||
"Mesh from Curve, Surface, Metaball, Text, or Pointcloud objects"},
|
||||
"Mesh from Curve, Surface, Metaball, Text, or Point Cloud objects"},
|
||||
#else
|
||||
"Mesh from Curve, Surface, Metaball, or Text objects"},
|
||||
#endif
|
||||
|
@ -2424,8 +2424,8 @@ static const EnumPropertyItem convert_target_items[] = {
|
|||
{OB_POINTCLOUD,
|
||||
"POINTCLOUD",
|
||||
ICON_OUTLINER_OB_POINTCLOUD,
|
||||
"Pointcloud",
|
||||
"Pointcloud from Mesh objects"},
|
||||
"Point Cloud",
|
||||
"Point Cloud from Mesh objects"},
|
||||
#endif
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
|
|
@ -441,13 +441,24 @@ static bool bake_object_check(ViewLayer *view_layer,
|
|||
}
|
||||
|
||||
Mesh *me = (Mesh *)ob->data;
|
||||
if (CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV) == -1) {
|
||||
BKE_reportf(
|
||||
reports, RPT_ERROR, "No active UV layer found in the object \"%s\"", ob->id.name + 2);
|
||||
return false;
|
||||
if (target == R_BAKE_TARGET_VERTEX_COLORS) {
|
||||
MPropCol *mcol = CustomData_get_layer(&me->vdata, CD_PROP_COLOR);
|
||||
MLoopCol *mloopcol = CustomData_get_layer(&me->ldata, CD_MLOOPCOL);
|
||||
if (mcol == NULL && mloopcol == NULL) {
|
||||
BKE_reportf(reports,
|
||||
RPT_ERROR,
|
||||
"No vertex colors layer found in the object \"%s\"",
|
||||
ob->id.name + 2);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (target == R_BAKE_TARGET_IMAGE_TEXTURES) {
|
||||
if (CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV) == -1) {
|
||||
BKE_reportf(
|
||||
reports, RPT_ERROR, "No active UV layer found in the object \"%s\"", ob->id.name + 2);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (target == R_BAKE_TARGET_IMAGE_TEXTURES) {
|
||||
for (int i = 0; i < ob->totcol; i++) {
|
||||
bNodeTree *ntree = NULL;
|
||||
bNode *node = NULL;
|
||||
|
|
|
@ -504,7 +504,7 @@ static bool mesh_needs_keyindex(Main *bmain, const Mesh *me)
|
|||
return false; /* will be added */
|
||||
}
|
||||
|
||||
for (const Object *ob = bmain->objects.first; ob; ob = ob->id.next) {
|
||||
LISTBASE_FOREACH (const Object *, ob, &bmain->objects) {
|
||||
if ((ob->parent) && (ob->parent->data == me) && ELEM(ob->partype, PARVERT1, PARVERT3)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -650,12 +650,10 @@ bool ED_object_editmode_exit_ex(Main *bmain, Scene *scene, Object *obedit, int f
|
|||
|
||||
/* freedata only 0 now on file saves and render */
|
||||
if (freedata) {
|
||||
ListBase pidlist;
|
||||
PTCacheID *pid;
|
||||
|
||||
/* flag object caches as outdated */
|
||||
ListBase pidlist;
|
||||
BKE_ptcache_ids_from_object(&pidlist, obedit, scene, 0);
|
||||
for (pid = pidlist.first; pid; pid = pid->next) {
|
||||
LISTBASE_FOREACH (PTCacheID *, pid, &pidlist) {
|
||||
/* particles don't need reset on geometry change */
|
||||
if (pid->type != PTCACHE_TYPE_PARTICLES) {
|
||||
pid->cache->flag |= PTCACHE_OUTDATED;
|
||||
|
@ -1398,7 +1396,7 @@ static int shade_smooth_exec(bContext *C, wmOperator *op)
|
|||
CTX_data_selected_editable_objects(C, &ctx_objects);
|
||||
}
|
||||
|
||||
for (CollectionPointerLink *ctx_ob = ctx_objects.first; ctx_ob; ctx_ob = ctx_ob->next) {
|
||||
LISTBASE_FOREACH (CollectionPointerLink *, ctx_ob, &ctx_objects) {
|
||||
Object *ob = ctx_ob->ptr.data;
|
||||
ID *data = ob->data;
|
||||
if (data != NULL) {
|
||||
|
@ -1406,7 +1404,7 @@ static int shade_smooth_exec(bContext *C, wmOperator *op)
|
|||
}
|
||||
}
|
||||
|
||||
for (CollectionPointerLink *ctx_ob = ctx_objects.first; ctx_ob; ctx_ob = ctx_ob->next) {
|
||||
LISTBASE_FOREACH (CollectionPointerLink *, ctx_ob, &ctx_objects) {
|
||||
/* Always un-tag all object data-blocks irrespective of our ability to operate on them. */
|
||||
Object *ob = ctx_ob->ptr.data;
|
||||
ID *data = ob->data;
|
||||
|
@ -1817,11 +1815,9 @@ struct MoveToCollectionData {
|
|||
static int move_to_collection_menus_create(wmOperator *op, MoveToCollectionData *menu)
|
||||
{
|
||||
int index = menu->index;
|
||||
for (CollectionChild *child = menu->collection->children.first; child != NULL;
|
||||
child = child->next) {
|
||||
LISTBASE_FOREACH (CollectionChild *, child, &menu->collection->children) {
|
||||
Collection *collection = child->collection;
|
||||
MoveToCollectionData *submenu = MEM_callocN(sizeof(MoveToCollectionData),
|
||||
"MoveToCollectionData submenu - expected memleak");
|
||||
MoveToCollectionData *submenu = MEM_callocN(sizeof(MoveToCollectionData), __func__);
|
||||
BLI_addtail(&menu->submenus, submenu);
|
||||
submenu->collection = collection;
|
||||
submenu->index = ++index;
|
||||
|
@ -1833,8 +1829,7 @@ static int move_to_collection_menus_create(wmOperator *op, MoveToCollectionData
|
|||
|
||||
static void move_to_collection_menus_free_recursive(MoveToCollectionData *menu)
|
||||
{
|
||||
for (MoveToCollectionData *submenu = menu->submenus.first; submenu != NULL;
|
||||
submenu = submenu->next) {
|
||||
LISTBASE_FOREACH (MoveToCollectionData *, submenu, &menu->submenus) {
|
||||
move_to_collection_menus_free_recursive(submenu);
|
||||
}
|
||||
BLI_freelistN(&menu->submenus);
|
||||
|
@ -1873,8 +1868,7 @@ static void move_to_collection_menu_create(bContext *C, uiLayout *layout, void *
|
|||
UI_icon_color_from_collection(menu->collection);
|
||||
uiItemIntO(layout, name, icon, menu->ot->idname, "collection_index", menu->index);
|
||||
|
||||
for (MoveToCollectionData *submenu = menu->submenus.first; submenu != NULL;
|
||||
submenu = submenu->next) {
|
||||
LISTBASE_FOREACH (MoveToCollectionData *, submenu, &menu->submenus) {
|
||||
move_to_collection_menus_items(layout, submenu);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -346,7 +346,7 @@ static bool object_modifier_remove(
|
|||
* get called twice on same modifier, so make
|
||||
* sure it is in list. */
|
||||
if (BLI_findindex(&ob->modifiers, md) == -1) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* special cases */
|
||||
|
@ -393,7 +393,7 @@ static bool object_modifier_remove(
|
|||
BKE_modifier_free(md);
|
||||
BKE_object_free_derived_caches(ob);
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ED_object_modifier_remove(
|
||||
|
@ -674,18 +674,18 @@ static Mesh *modifier_apply_create_mesh_for_modifier(Depsgraph *depsgraph,
|
|||
return mesh_applied;
|
||||
}
|
||||
|
||||
static int modifier_apply_shape(Main *bmain,
|
||||
ReportList *reports,
|
||||
Depsgraph *depsgraph,
|
||||
Scene *scene,
|
||||
Object *ob,
|
||||
ModifierData *md_eval)
|
||||
static bool modifier_apply_shape(Main *bmain,
|
||||
ReportList *reports,
|
||||
Depsgraph *depsgraph,
|
||||
Scene *scene,
|
||||
Object *ob,
|
||||
ModifierData *md_eval)
|
||||
{
|
||||
const ModifierTypeInfo *mti = BKE_modifier_get_info(md_eval->type);
|
||||
|
||||
if (mti->isDisabled && mti->isDisabled(scene, md_eval, 0)) {
|
||||
BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* We could investigate using the #CD_ORIGINDEX layer
|
||||
|
@ -699,19 +699,18 @@ static int modifier_apply_shape(Main *bmain,
|
|||
* we can look into supporting them. */
|
||||
|
||||
if (ob->type == OB_MESH) {
|
||||
Mesh *mesh_applied;
|
||||
Mesh *me = ob->data;
|
||||
Key *key = me->key;
|
||||
|
||||
if (!BKE_modifier_is_same_topology(md_eval) || mti->type == eModifierTypeType_NonGeometrical) {
|
||||
BKE_report(reports, RPT_ERROR, "Only deforming modifiers can be applied to shapes");
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
mesh_applied = modifier_apply_create_mesh_for_modifier(depsgraph, ob, md_eval, false);
|
||||
Mesh *mesh_applied = modifier_apply_create_mesh_for_modifier(depsgraph, ob, md_eval, false);
|
||||
if (!mesh_applied) {
|
||||
BKE_report(reports, RPT_ERROR, "Modifier is disabled or returned error, skipping apply");
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (key == NULL) {
|
||||
|
@ -731,29 +730,28 @@ static int modifier_apply_shape(Main *bmain,
|
|||
else {
|
||||
/* TODO: implement for hair, point-clouds and volumes. */
|
||||
BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int modifier_apply_obdata(
|
||||
static bool modifier_apply_obdata(
|
||||
ReportList *reports, Depsgraph *depsgraph, Scene *scene, Object *ob, ModifierData *md_eval)
|
||||
{
|
||||
const ModifierTypeInfo *mti = BKE_modifier_get_info(md_eval->type);
|
||||
|
||||
if (mti->isDisabled && mti->isDisabled(scene, md_eval, 0)) {
|
||||
BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ob->type == OB_MESH) {
|
||||
Mesh *mesh_applied;
|
||||
Mesh *me = ob->data;
|
||||
MultiresModifierData *mmd = find_multires_modifier_before(scene, md_eval);
|
||||
|
||||
if (me->key && mti->type != eModifierTypeType_NonGeometrical) {
|
||||
BKE_report(reports, RPT_ERROR, "Modifier cannot be applied to a mesh with shape keys");
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Multires: ensure that recent sculpting is applied */
|
||||
|
@ -764,14 +762,14 @@ static int modifier_apply_obdata(
|
|||
if (mmd && mmd->totlvl && mti->type == eModifierTypeType_OnlyDeform) {
|
||||
if (!multiresModifier_reshapeFromDeformModifier(depsgraph, ob, mmd, md_eval)) {
|
||||
BKE_report(reports, RPT_ERROR, "Multires modifier returned error, skipping apply");
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mesh_applied = modifier_apply_create_mesh_for_modifier(depsgraph, ob, md_eval, true);
|
||||
Mesh *mesh_applied = modifier_apply_create_mesh_for_modifier(depsgraph, ob, md_eval, true);
|
||||
if (!mesh_applied) {
|
||||
BKE_report(reports, RPT_ERROR, "Modifier returned error, skipping apply");
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
BKE_mesh_nomain_to_mesh(mesh_applied, me, ob, &CD_MASK_MESH, true);
|
||||
|
@ -790,7 +788,7 @@ static int modifier_apply_obdata(
|
|||
if (ELEM(mti->type, eModifierTypeType_Constructive, eModifierTypeType_Nonconstructive)) {
|
||||
BKE_report(
|
||||
reports, RPT_ERROR, "Transform curve to mesh in order to apply constructive modifiers");
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
BKE_report(reports,
|
||||
|
@ -813,7 +811,7 @@ static int modifier_apply_obdata(
|
|||
|
||||
if (ELEM(mti->type, eModifierTypeType_Constructive, eModifierTypeType_Nonconstructive)) {
|
||||
BKE_report(reports, RPT_ERROR, "Constructive modifiers cannot be applied");
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
int numVerts;
|
||||
|
@ -828,7 +826,7 @@ static int modifier_apply_obdata(
|
|||
else {
|
||||
/* TODO: implement for hair, point-clouds and volumes. */
|
||||
BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* lattice modifier can be applied to particle system too */
|
||||
|
@ -842,7 +840,7 @@ static int modifier_apply_obdata(
|
|||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ED_object_modifier_apply(Main *bmain,
|
||||
|
@ -908,20 +906,19 @@ bool ED_object_modifier_apply(Main *bmain,
|
|||
return true;
|
||||
}
|
||||
|
||||
int ED_object_modifier_copy(
|
||||
bool ED_object_modifier_copy(
|
||||
ReportList *UNUSED(reports), Main *bmain, Scene *scene, Object *ob, ModifierData *md)
|
||||
{
|
||||
ModifierData *nmd;
|
||||
|
||||
if (md->type == eModifierType_ParticleSystem) {
|
||||
nmd = object_copy_particle_system(bmain, scene, ob, ((ParticleSystemModifierData *)md)->psys);
|
||||
ModifierData *nmd = object_copy_particle_system(
|
||||
bmain, scene, ob, ((ParticleSystemModifierData *)md)->psys);
|
||||
BLI_remlink(&ob->modifiers, nmd);
|
||||
BLI_insertlinkafter(&ob->modifiers, md, nmd);
|
||||
BKE_object_modifier_set_active(ob, nmd);
|
||||
return true;
|
||||
}
|
||||
|
||||
nmd = BKE_modifier_new(md->type);
|
||||
ModifierData *nmd = BKE_modifier_new(md->type);
|
||||
BKE_modifier_copydata(md, nmd);
|
||||
BLI_insertlinkafter(&ob->modifiers, md, nmd);
|
||||
BKE_modifier_unique_name(&ob->modifiers, nmd);
|
||||
|
@ -929,7 +926,7 @@ int ED_object_modifier_copy(
|
|||
|
||||
nmd->flag |= eModifierFlag_OverrideLibrary_Local;
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -1567,7 +1567,11 @@ static bool allow_make_links_data(const int type, Object *ob_src, Object *ob_dst
|
|||
}
|
||||
break;
|
||||
case MAKE_LINKS_MATERIALS:
|
||||
if (OB_TYPE_SUPPORT_MATERIAL(ob_src->type) && OB_TYPE_SUPPORT_MATERIAL(ob_dst->type)) {
|
||||
if (OB_TYPE_SUPPORT_MATERIAL(ob_src->type) && OB_TYPE_SUPPORT_MATERIAL(ob_dst->type) &&
|
||||
/* Linking non-grease-pencil materials to a grease-pencil object causes issues.
|
||||
* We make sure that if one of the objects is a grease-pencil object, the other must be
|
||||
* as well. */
|
||||
((ob_src->type == OB_GPENCIL) == (ob_dst->type == OB_GPENCIL))) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -3496,6 +3496,21 @@ static int mirror_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static bool mirror_poll(bContext *C)
|
||||
{
|
||||
if (!PE_hair_poll(C)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
PTCacheEdit *edit = PE_get_current(depsgraph, scene, ob);
|
||||
|
||||
/* The operator only works for hairs emitted from faces. */
|
||||
return edit->psys->part->from == PART_FROM_FACE;
|
||||
}
|
||||
|
||||
void PARTICLE_OT_mirror(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
|
@ -3505,7 +3520,7 @@ void PARTICLE_OT_mirror(wmOperatorType *ot)
|
|||
|
||||
/* api callbacks */
|
||||
ot->exec = mirror_exec;
|
||||
ot->poll = PE_hair_poll;
|
||||
ot->poll = mirror_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
|
|
@ -299,7 +299,7 @@ void ED_particle_undosys_type(UndoType *ut)
|
|||
|
||||
ut->step_foreach_ID_ref = particle_undosys_foreach_ID_ref;
|
||||
|
||||
ut->use_context_for_encode = true;
|
||||
ut->flags = UNDOTYPE_FLAG_NEED_CONTEXT_FOR_ENCODE;
|
||||
|
||||
ut->step_size = sizeof(ParticleUndoStep);
|
||||
}
|
||||
|
|
|
@ -240,8 +240,9 @@ static void SCENE_OT_new(wmOperatorType *ot)
|
|||
|
||||
static bool scene_delete_poll(bContext *C)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
return (scene->id.prev || scene->id.next);
|
||||
return BKE_scene_can_be_removed(bmain, scene);
|
||||
}
|
||||
|
||||
static int scene_delete_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
|
|
|
@ -159,7 +159,7 @@ void ED_paintcurve_undosys_type(UndoType *ut)
|
|||
|
||||
ut->step_foreach_ID_ref = paintcurve_undosys_foreach_ID_ref;
|
||||
|
||||
ut->use_context_for_encode = false;
|
||||
ut->flags = 0;
|
||||
|
||||
ut->step_size = sizeof(PaintCurveUndoStep);
|
||||
}
|
||||
|
|
|
@ -91,7 +91,7 @@ typedef struct BrushPainter {
|
|||
Scene *scene;
|
||||
Brush *brush;
|
||||
|
||||
short firsttouch; /* first paint op */
|
||||
bool firsttouch; /* first paint op */
|
||||
|
||||
struct ImagePool *pool; /* image pool */
|
||||
rctf tex_mapping; /* texture coordinate mapping */
|
||||
|
@ -132,8 +132,6 @@ typedef struct ImagePaintState {
|
|||
SpaceImage *sima;
|
||||
View2D *v2d;
|
||||
Scene *scene;
|
||||
bScreen *screen;
|
||||
struct ImagePool *image_pool;
|
||||
|
||||
Brush *brush;
|
||||
short tool, blend;
|
||||
|
@ -142,11 +140,6 @@ typedef struct ImagePaintState {
|
|||
|
||||
bool do_masking;
|
||||
|
||||
/* viewport texture paint only, but _not_ project paint */
|
||||
Object *ob;
|
||||
int faceindex;
|
||||
float uv[2];
|
||||
int do_facesel;
|
||||
int symmetry;
|
||||
|
||||
ImagePaintTile *tiles;
|
||||
|
@ -161,7 +154,7 @@ static BrushPainter *brush_painter_2d_new(Scene *scene, Brush *brush, bool inver
|
|||
|
||||
painter->brush = brush;
|
||||
painter->scene = scene;
|
||||
painter->firsttouch = 1;
|
||||
painter->firsttouch = true;
|
||||
painter->cache_invert = invert;
|
||||
|
||||
return painter;
|
||||
|
@ -1659,7 +1652,7 @@ void paint_2d_stroke(void *ps,
|
|||
}
|
||||
}
|
||||
|
||||
painter->firsttouch = 0;
|
||||
painter->firsttouch = false;
|
||||
}
|
||||
|
||||
void *paint_2d_new_stroke(bContext *C, wmOperator *op, int mode)
|
||||
|
@ -1674,7 +1667,6 @@ void *paint_2d_new_stroke(bContext *C, wmOperator *op, int mode)
|
|||
s->sima = CTX_wm_space_image(C);
|
||||
s->v2d = &CTX_wm_region(C)->v2d;
|
||||
s->scene = scene;
|
||||
s->screen = CTX_wm_screen(C);
|
||||
|
||||
s->brush = brush;
|
||||
s->tool = brush->imagepaint_tool;
|
||||
|
|
|
@ -1576,7 +1576,7 @@ void ED_sculpt_undosys_type(UndoType *ut)
|
|||
ut->step_decode = sculpt_undosys_step_decode;
|
||||
ut->step_free = sculpt_undosys_step_free;
|
||||
|
||||
ut->use_context_for_encode = false;
|
||||
ut->flags = 0;
|
||||
|
||||
ut->step_size = sizeof(SculptUndoStep);
|
||||
}
|
||||
|
|
|
@ -543,7 +543,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
|
|||
/* we need to find the active island here */
|
||||
if (do_island_optimization) {
|
||||
UvElement *element;
|
||||
UvNearestHit hit = UV_NEAREST_HIT_INIT;
|
||||
UvNearestHit hit = UV_NEAREST_HIT_INIT_MAX(®ion->v2d);
|
||||
uv_find_nearest_vert(scene, obedit, co, 0.0f, &hit);
|
||||
|
||||
element = BM_uv_element_get(data->elementMap, hit.efa, hit.l);
|
||||
|
|
|
@ -171,6 +171,8 @@ static GHash *fsmenu_xdg_user_dirs_parse(const char *home)
|
|||
}
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
return xdg_map;
|
||||
}
|
||||
|
||||
|
|
|
@ -997,8 +997,10 @@ void ED_image_undosys_type(UndoType *ut)
|
|||
ut->step_foreach_ID_ref = image_undosys_foreach_ID_ref;
|
||||
|
||||
/* NOTE this is actually a confusing case, since it expects a valid context, but only in a
|
||||
* specific case, see `image_undosys_step_encode` code. */
|
||||
ut->use_context_for_encode = false;
|
||||
* specific case, see `image_undosys_step_encode` code. We cannot specify
|
||||
* `UNDOTYPE_FLAG_NEED_CONTEXT_FOR_ENCODE` though, as it can be called with a NULL context by
|
||||
* current code. */
|
||||
ut->flags = 0;
|
||||
|
||||
ut->step_size = sizeof(ImageUndoStep);
|
||||
}
|
||||
|
|
|
@ -347,17 +347,15 @@ static void outliner_layer_or_collection_pointer_create(Scene *scene,
|
|||
}
|
||||
|
||||
/** Create either a RNA_ObjectBase or a RNA_Object pointer. */
|
||||
static void outliner_base_or_object_pointer_create(ViewLayer *view_layer,
|
||||
Collection *collection,
|
||||
Object *ob,
|
||||
PointerRNA *ptr)
|
||||
static void outliner_base_or_object_pointer_create(
|
||||
Scene *scene, ViewLayer *view_layer, Collection *collection, Object *ob, PointerRNA *ptr)
|
||||
{
|
||||
if (collection) {
|
||||
RNA_id_pointer_create(&ob->id, ptr);
|
||||
}
|
||||
else {
|
||||
Base *base = BKE_view_layer_base_find(view_layer, ob);
|
||||
RNA_pointer_create(&base->object->id, &RNA_ObjectBase, base, ptr);
|
||||
RNA_pointer_create(&scene->id, &RNA_ObjectBase, base, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -384,7 +382,7 @@ static void outliner_collection_set_flag_recursive(Scene *scene,
|
|||
* otherwise we would not take collection exclusion into account. */
|
||||
LISTBASE_FOREACH (CollectionObject *, cob, &layer_collection->collection->gobject) {
|
||||
|
||||
outliner_base_or_object_pointer_create(view_layer, collection, cob->ob, &ptr);
|
||||
outliner_base_or_object_pointer_create(scene, view_layer, collection, cob->ob, &ptr);
|
||||
RNA_property_boolean_set(&ptr, base_or_object_prop, value);
|
||||
|
||||
if (collection) {
|
||||
|
@ -1116,7 +1114,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||
BKE_view_layer_base_find(view_layer, ob);
|
||||
if (base) {
|
||||
PointerRNA base_ptr;
|
||||
RNA_pointer_create(&ob->id, &RNA_ObjectBase, base, &base_ptr);
|
||||
RNA_pointer_create(&scene->id, &RNA_ObjectBase, base, &base_ptr);
|
||||
bt = uiDefIconButR_prop(block,
|
||||
UI_BTYPE_ICON_TOGGLE,
|
||||
0,
|
||||
|
|
|
@ -196,7 +196,7 @@ static void outliner_main_region_listener(wmWindow *UNUSED(win),
|
|||
}
|
||||
break;
|
||||
case NC_ID:
|
||||
if (wmn->action == NA_RENAME) {
|
||||
if (ELEM(wmn->action, NA_RENAME, NA_ADDED)) {
|
||||
ED_region_tag_redraw(region);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -260,7 +260,7 @@ void ED_text_undosys_type(UndoType *ut)
|
|||
|
||||
ut->step_foreach_ID_ref = text_undosys_foreach_ID_ref;
|
||||
|
||||
ut->use_context_for_encode = true;
|
||||
ut->flags = UNDOTYPE_FLAG_NEED_CONTEXT_FOR_ENCODE;
|
||||
|
||||
ut->step_size = sizeof(TextUndoStep);
|
||||
}
|
||||
|
|
|
@ -197,9 +197,10 @@ void createTransCurveVerts(TransInfo *t)
|
|||
TransData *td = tc->data;
|
||||
ListBase *nurbs = BKE_curve_editNurbs_get(cu);
|
||||
LISTBASE_FOREACH (Nurb *, nu, nurbs) {
|
||||
TransData *head, *tail;
|
||||
head = tail = td;
|
||||
bool has_any_selected = false;
|
||||
if (nu->type == CU_BEZIER) {
|
||||
TransData *head, *tail;
|
||||
head = tail = td;
|
||||
for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) {
|
||||
if (bezt->hide == 0) {
|
||||
TransDataCurveHandleFlags *hdata = NULL;
|
||||
|
@ -223,6 +224,7 @@ void createTransCurveVerts(TransInfo *t)
|
|||
|
||||
/* Elements that will be transform (not always a match to selection). */
|
||||
const int bezt_tx = bezt_select_to_transform_triple_flag(bezt, hide_handles);
|
||||
has_any_selected |= bezt_tx != 0;
|
||||
|
||||
if (is_prop_edit || bezt_tx & SEL_F1) {
|
||||
copy_v3_v3(td->iloc, bezt->vec[0]);
|
||||
|
@ -350,28 +352,9 @@ void createTransCurveVerts(TransInfo *t)
|
|||
|
||||
(void)hdata; /* quiet warning */
|
||||
}
|
||||
else if (is_prop_edit && head != tail) {
|
||||
tail->flag |= TD_NOTCONNECTED;
|
||||
td++;
|
||||
tail++;
|
||||
}
|
||||
}
|
||||
if (is_prop_edit && head != tail) {
|
||||
bool cyclic = (nu->flagu & CU_NURB_CYCLIC) != 0;
|
||||
calc_distanceCurveVerts(head, tail - 1, cyclic);
|
||||
}
|
||||
|
||||
/* TODO - in the case of tilt and radius we can also avoid allocating the
|
||||
* initTransDataCurveHandles but for now just don't change handle types */
|
||||
if (ELEM(t->mode, TFM_CURVE_SHRINKFATTEN, TFM_TILT, TFM_DUMMY) == 0) {
|
||||
/* sets the handles based on their selection,
|
||||
* do this after the data is copied to the TransData */
|
||||
BKE_nurb_handles_test(nu, !hide_handles, use_around_origins_for_handles_test);
|
||||
}
|
||||
}
|
||||
else {
|
||||
TransData *head, *tail;
|
||||
head = tail = td;
|
||||
for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a > 0; a--, bp++) {
|
||||
if (bp->hide == 0) {
|
||||
if (is_prop_edit || (bp->f1 & SELECT)) {
|
||||
|
@ -400,6 +383,7 @@ void createTransCurveVerts(TransInfo *t)
|
|||
copy_v3_v3(td->center, td->loc);
|
||||
if (bp->f1 & SELECT) {
|
||||
td->flag = TD_SELECTED;
|
||||
has_any_selected |= true;
|
||||
}
|
||||
else {
|
||||
td->flag = 0;
|
||||
|
@ -427,16 +411,26 @@ void createTransCurveVerts(TransInfo *t)
|
|||
tail++;
|
||||
}
|
||||
}
|
||||
else if (is_prop_edit && head != tail) {
|
||||
tail->flag |= TD_NOTCONNECTED;
|
||||
td++;
|
||||
tail++;
|
||||
}
|
||||
}
|
||||
if (is_prop_edit && head != tail) {
|
||||
tail -= 1;
|
||||
if (!has_any_selected) {
|
||||
for (td = head; td <= tail; td++) {
|
||||
td->flag |= TD_NOTCONNECTED;
|
||||
}
|
||||
}
|
||||
if (is_prop_edit && head != tail) {
|
||||
bool cyclic = (nu->flagu & CU_NURB_CYCLIC) != 0;
|
||||
calc_distanceCurveVerts(head, tail - 1, cyclic);
|
||||
}
|
||||
bool cyclic = (nu->flagu & CU_NURB_CYCLIC) != 0;
|
||||
calc_distanceCurveVerts(head, tail, cyclic);
|
||||
}
|
||||
|
||||
/* TODO - in the case of tilt and radius we can also avoid allocating the
|
||||
* initTransDataCurveHandles but for now just don't change handle types */
|
||||
if ((nu->type == CU_BEZIER) &&
|
||||
ELEM(t->mode, TFM_CURVE_SHRINKFATTEN, TFM_TILT, TFM_DUMMY) == 0) {
|
||||
/* sets the handles based on their selection,
|
||||
* do this after the data is copied to the TransData */
|
||||
BKE_nurb_handles_test(nu, !hide_handles, use_around_origins_for_handles_test);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -282,7 +282,7 @@ void ED_memfile_undosys_type(UndoType *ut)
|
|||
ut->step_decode = memfile_undosys_step_decode;
|
||||
ut->step_free = memfile_undosys_step_free;
|
||||
|
||||
ut->use_context_for_encode = false;
|
||||
ut->flags = 0;
|
||||
|
||||
ut->step_size = sizeof(MemFileUndoStep);
|
||||
}
|
||||
|
|
|
@ -41,13 +41,34 @@ typedef struct UvNearestHit {
|
|||
/** Always set if we have a hit. */
|
||||
struct BMFace *efa;
|
||||
struct BMLoop *l;
|
||||
/** Needs to be set before calling nearest functions. */
|
||||
/**
|
||||
* Needs to be set before calling nearest functions.
|
||||
*
|
||||
* \note When #UV_NEAREST_HIT_INIT_DIST_PX or #UV_NEAREST_HIT_INIT_MAX are used,
|
||||
* this value is pixels squared.
|
||||
*/
|
||||
float dist_sq;
|
||||
|
||||
/** Scale the UV's to account for aspect ratio from the image view. */
|
||||
float scale[2];
|
||||
} UvNearestHit;
|
||||
|
||||
#define UV_NEAREST_HIT_INIT \
|
||||
#define UV_NEAREST_HIT_INIT_DIST_PX(v2d, dist_px) \
|
||||
{ \
|
||||
.dist_sq = square_f(U.pixelsize * dist_px), \
|
||||
.scale = { \
|
||||
UI_view2d_scale_get_x(v2d), \
|
||||
UI_view2d_scale_get_y(v2d), \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define UV_NEAREST_HIT_INIT_MAX(v2d) \
|
||||
{ \
|
||||
.dist_sq = FLT_MAX, \
|
||||
.scale = { \
|
||||
UI_view2d_scale_get_x(v2d), \
|
||||
UI_view2d_scale_get_y(v2d), \
|
||||
}, \
|
||||
}
|
||||
|
||||
bool uv_find_nearest_vert(struct Scene *scene,
|
||||
|
@ -96,7 +117,6 @@ BMLoop *uv_find_nearest_loop_from_edge(struct Scene *scene,
|
|||
void uvedit_live_unwrap_update(struct SpaceImage *sima,
|
||||
struct Scene *scene,
|
||||
struct Object *obedit);
|
||||
void uvedit_pixel_to_float(struct SpaceImage *sima, float pixeldist, float r_dist[2]);
|
||||
|
||||
/* operators */
|
||||
|
||||
|
|
|
@ -186,28 +186,6 @@ void ED_object_assign_active_image(Main *bmain, Object *ob, int mat_nr, Image *i
|
|||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Space Conversion
|
||||
* \{ */
|
||||
|
||||
void uvedit_pixel_to_float(SpaceImage *sima, float pixeldist, float r_dist[2])
|
||||
{
|
||||
int width, height;
|
||||
|
||||
if (sima) {
|
||||
ED_space_image_get_size(sima, &width, &height);
|
||||
}
|
||||
else {
|
||||
width = IMG_SIZE_FALLBACK;
|
||||
height = IMG_SIZE_FALLBACK;
|
||||
}
|
||||
|
||||
r_dist[0] = pixeldist / width;
|
||||
r_dist[1] = pixeldist / height;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Live Unwrap Utilities
|
||||
* \{ */
|
||||
|
@ -1473,7 +1451,7 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
|
|||
Scene *scene = CTX_data_scene(C);
|
||||
const ToolSettings *ts = scene->toolsettings;
|
||||
const bool swap = RNA_boolean_get(op->ptr, "unselected");
|
||||
const int use_face_center = (ts->uv_selectmode == UV_SELECT_FACE);
|
||||
const bool use_face_center = (ts->uv_selectmode == UV_SELECT_FACE);
|
||||
|
||||
uint objects_len = 0;
|
||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
|
||||
|
@ -1605,8 +1583,8 @@ static int uv_reveal_exec(bContext *C, wmOperator *op)
|
|||
Scene *scene = CTX_data_scene(C);
|
||||
const ToolSettings *ts = scene->toolsettings;
|
||||
|
||||
const int use_face_center = (ts->uv_selectmode == UV_SELECT_FACE);
|
||||
const int stickymode = sima ? (sima->sticky != SI_STICKY_DISABLE) : 1;
|
||||
const bool use_face_center = (ts->uv_selectmode == UV_SELECT_FACE);
|
||||
const bool stickymode = sima ? (sima->sticky != SI_STICKY_DISABLE) : 1;
|
||||
const bool select = RNA_boolean_get(op->ptr, "select");
|
||||
|
||||
uint objects_len = 0;
|
||||
|
|
|
@ -574,7 +574,7 @@ static bool uv_shortest_path_pick_ex(const SpaceImage *sima,
|
|||
|
||||
static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
const SpaceImage *sima = CTX_wm_space_image(C);
|
||||
SpaceImage *sima = CTX_wm_space_image(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
const ToolSettings *ts = scene->toolsettings;
|
||||
const char uv_selectmode = ED_uvedit_select_mode_get(scene);
|
||||
|
@ -613,7 +613,7 @@ static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEve
|
|||
BMElem *ele_src = NULL, *ele_dst = NULL;
|
||||
|
||||
if (uv_selectmode == UV_SELECT_FACE) {
|
||||
UvNearestHit hit = UV_NEAREST_HIT_INIT;
|
||||
UvNearestHit hit = UV_NEAREST_HIT_INIT_MAX(®ion->v2d);
|
||||
if (!uv_find_nearest_face(scene, obedit, co, &hit)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
@ -626,7 +626,7 @@ static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEve
|
|||
}
|
||||
|
||||
else if (uv_selectmode & UV_SELECT_EDGE) {
|
||||
UvNearestHit hit = UV_NEAREST_HIT_INIT;
|
||||
UvNearestHit hit = UV_NEAREST_HIT_INIT_MAX(®ion->v2d);
|
||||
if (!uv_find_nearest_edge(scene, obedit, co, &hit)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
@ -652,7 +652,7 @@ static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEve
|
|||
ele_dst = (BMElem *)hit.l;
|
||||
}
|
||||
else {
|
||||
UvNearestHit hit = UV_NEAREST_HIT_INIT;
|
||||
UvNearestHit hit = UV_NEAREST_HIT_INIT_MAX(®ion->v2d);
|
||||
if (!uv_find_nearest_vert(scene, obedit, co, 0.0f, &hit)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
|
|
@ -201,21 +201,6 @@ void ED_uvedit_select_sync_flush(const ToolSettings *ts, BMEditMesh *em, const b
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a penalty to elements that are already selected
|
||||
* so elements that aren't already selected are prioritized.
|
||||
*
|
||||
* \note This is calculated in screen-space otherwise zooming in on a uv-vert and
|
||||
* shift-selecting can consider an adjacent point close enough to add to
|
||||
* the selection rather than de-selecting the closest.
|
||||
*/
|
||||
static float uv_select_penalty_default(SpaceImage *sima)
|
||||
{
|
||||
float penalty[2];
|
||||
uvedit_pixel_to_float(sima, 5.0f / (sima ? sima->zoom : 1.0f), penalty);
|
||||
return len_v2(penalty);
|
||||
}
|
||||
|
||||
static void uvedit_vertex_select_tagged(BMEditMesh *em,
|
||||
Scene *scene,
|
||||
bool select,
|
||||
|
@ -680,6 +665,7 @@ static BMLoop *uvedit_loop_find_other_boundary_loop_with_visible_face(const Scen
|
|||
|
||||
bool uv_find_nearest_edge(Scene *scene, Object *obedit, const float co[2], UvNearestHit *hit)
|
||||
{
|
||||
BLI_assert((hit->scale[0] > 0.0f) && (hit->scale[1] > 0.0f));
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
BMFace *efa;
|
||||
BMLoop *l;
|
||||
|
@ -700,7 +686,13 @@ bool uv_find_nearest_edge(Scene *scene, Object *obedit, const float co[2], UvNea
|
|||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
|
||||
|
||||
const float dist_test_sq = dist_squared_to_line_segment_v2(co, luv->uv, luv_next->uv);
|
||||
float delta[2];
|
||||
closest_to_line_segment_v2(delta, co, luv->uv, luv_next->uv);
|
||||
|
||||
sub_v2_v2(delta, co);
|
||||
mul_v2_v2(delta, hit->scale);
|
||||
|
||||
const float dist_test_sq = len_squared_v2(delta);
|
||||
|
||||
if (dist_test_sq < hit->dist_sq) {
|
||||
hit->efa = efa;
|
||||
|
@ -734,6 +726,7 @@ bool uv_find_nearest_edge_multi(Scene *scene,
|
|||
|
||||
bool uv_find_nearest_face(Scene *scene, Object *obedit, const float co[2], UvNearestHit *hit_final)
|
||||
{
|
||||
BLI_assert((hit_final->scale[0] > 0.0f) && (hit_final->scale[1] > 0.0f));
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
bool found = false;
|
||||
|
||||
|
@ -757,7 +750,11 @@ bool uv_find_nearest_face(Scene *scene, Object *obedit, const float co[2], UvNea
|
|||
float cent[2];
|
||||
BM_face_uv_calc_center_median(efa, cd_loop_uv_offset, cent);
|
||||
|
||||
const float dist_test_sq = len_squared_v2v2(co, cent);
|
||||
float delta[2];
|
||||
sub_v2_v2v2(delta, co, cent);
|
||||
mul_v2_v2(delta, hit.scale);
|
||||
|
||||
const float dist_test_sq = len_squared_v2(delta);
|
||||
|
||||
if (dist_test_sq < hit.dist_sq) {
|
||||
hit.efa = efa;
|
||||
|
@ -805,9 +802,10 @@ bool uv_find_nearest_vert(Scene *scene,
|
|||
const float penalty_dist,
|
||||
UvNearestHit *hit_final)
|
||||
{
|
||||
BLI_assert((hit_final->scale[0] > 0.0f) && (hit_final->scale[1] > 0.0f));
|
||||
bool found = false;
|
||||
|
||||
/* this will fill in hit.vert1 and hit.vert2 */
|
||||
/* This will fill in `hit.l`. */
|
||||
float dist_sq_init = hit_final->dist_sq;
|
||||
UvNearestHit hit = *hit_final;
|
||||
if (uv_find_nearest_edge(scene, obedit, co, &hit)) {
|
||||
|
@ -832,14 +830,17 @@ bool uv_find_nearest_vert(Scene *scene,
|
|||
BMLoop *l;
|
||||
int i;
|
||||
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
|
||||
float dist_test_sq;
|
||||
MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
if (penalty_dist != 0.0f && uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
|
||||
dist_test_sq = len_v2v2(co, luv->uv) + penalty_dist;
|
||||
dist_test_sq = square_f(dist_test_sq);
|
||||
}
|
||||
else {
|
||||
dist_test_sq = len_squared_v2v2(co, luv->uv);
|
||||
|
||||
float delta[2];
|
||||
|
||||
sub_v2_v2v2(delta, co, luv->uv);
|
||||
mul_v2_v2(delta, hit.scale);
|
||||
|
||||
float dist_test_sq = len_squared_v2(delta);
|
||||
|
||||
if ((penalty_dist != 0.0f) && uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
|
||||
dist_test_sq = square_f(sqrtf(dist_test_sq) + penalty_dist);
|
||||
}
|
||||
|
||||
if (dist_test_sq <= hit.dist_sq) {
|
||||
|
@ -1912,15 +1913,18 @@ static int uv_mouse_select_multi(bContext *C,
|
|||
{
|
||||
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
||||
SpaceImage *sima = CTX_wm_space_image(C);
|
||||
const ARegion *region = CTX_wm_region(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
const ToolSettings *ts = scene->toolsettings;
|
||||
UvNearestHit hit = UV_NEAREST_HIT_INIT;
|
||||
UvNearestHit hit = UV_NEAREST_HIT_INIT_DIST_PX(®ion->v2d, 75.0f);
|
||||
int selectmode, sticky;
|
||||
bool found_item = false;
|
||||
/* 0 == don't flush, 1 == sel, -1 == desel; only use when selection sync is enabled */
|
||||
int flush = 0;
|
||||
|
||||
const float penalty_dist = uv_select_penalty_default(sima);
|
||||
/* Penalty (in pixels) applied to elements that are already selected
|
||||
* so elements that aren't already selected are prioritized. */
|
||||
const float penalty_dist = 3.0f * U.pixelsize;
|
||||
|
||||
/* retrieve operation mode */
|
||||
if (ts->uv_flag & UV_SYNC_SELECTION) {
|
||||
|
@ -1945,8 +1949,6 @@ static int uv_mouse_select_multi(bContext *C,
|
|||
if (selectmode == UV_SELECT_VERTEX) {
|
||||
/* find vertex */
|
||||
found_item = uv_find_nearest_vert_multi(scene, objects, objects_len, co, penalty_dist, &hit);
|
||||
found_item = found_item && (!deselect_all || hit.dist_sq < penalty_dist);
|
||||
|
||||
if (found_item) {
|
||||
if ((ts->uv_flag & UV_SYNC_SELECTION) == 0) {
|
||||
BMesh *bm = BKE_editmesh_from_object(hit.ob)->bm;
|
||||
|
@ -1957,8 +1959,6 @@ static int uv_mouse_select_multi(bContext *C,
|
|||
else if (selectmode == UV_SELECT_EDGE) {
|
||||
/* find edge */
|
||||
found_item = uv_find_nearest_edge_multi(scene, objects, objects_len, co, &hit);
|
||||
found_item = found_item && (!deselect_all || hit.dist_sq < penalty_dist);
|
||||
|
||||
if (found_item) {
|
||||
if ((ts->uv_flag & UV_SYNC_SELECTION) == 0) {
|
||||
BMesh *bm = BKE_editmesh_from_object(hit.ob)->bm;
|
||||
|
@ -1969,8 +1969,6 @@ static int uv_mouse_select_multi(bContext *C,
|
|||
else if (selectmode == UV_SELECT_FACE) {
|
||||
/* find face */
|
||||
found_item = uv_find_nearest_face_multi(scene, objects, objects_len, co, &hit);
|
||||
found_item = found_item && (!deselect_all || hit.dist_sq < penalty_dist);
|
||||
|
||||
if (found_item) {
|
||||
BMesh *bm = BKE_editmesh_from_object(hit.ob)->bm;
|
||||
BM_mesh_active_face_set(bm, hit.efa);
|
||||
|
@ -1978,7 +1976,6 @@ static int uv_mouse_select_multi(bContext *C,
|
|||
}
|
||||
else if (selectmode == UV_SELECT_ISLAND) {
|
||||
found_item = uv_find_nearest_edge_multi(scene, objects, objects_len, co, &hit);
|
||||
found_item = found_item && (!deselect_all || hit.dist_sq < penalty_dist);
|
||||
}
|
||||
|
||||
if (!found_item) {
|
||||
|
@ -2173,10 +2170,11 @@ static int uv_mouse_select_loop_generic_multi(bContext *C,
|
|||
enum eUVLoopGenericType loop_type)
|
||||
{
|
||||
SpaceImage *sima = CTX_wm_space_image(C);
|
||||
const ARegion *region = CTX_wm_region(C);
|
||||
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
const ToolSettings *ts = scene->toolsettings;
|
||||
UvNearestHit hit = UV_NEAREST_HIT_INIT;
|
||||
UvNearestHit hit = UV_NEAREST_HIT_INIT_MAX(®ion->v2d);
|
||||
bool found_item = false;
|
||||
/* 0 == don't flush, 1 == sel, -1 == desel; only use when selection sync is enabled */
|
||||
int flush = 0;
|
||||
|
@ -2367,6 +2365,7 @@ void UV_OT_select_edge_ring(wmOperatorType *ot)
|
|||
|
||||
static int uv_select_linked_internal(bContext *C, wmOperator *op, const wmEvent *event, bool pick)
|
||||
{
|
||||
const ARegion *region = CTX_wm_region(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
const ToolSettings *ts = scene->toolsettings;
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
|
@ -2374,7 +2373,7 @@ static int uv_select_linked_internal(bContext *C, wmOperator *op, const wmEvent
|
|||
bool deselect = false;
|
||||
bool select_faces = (ts->uv_flag & UV_SYNC_SELECTION) && (ts->selectmode & SCE_SELECT_FACE);
|
||||
|
||||
UvNearestHit hit = UV_NEAREST_HIT_INIT;
|
||||
UvNearestHit hit = UV_NEAREST_HIT_INIT_MAX(®ion->v2d);
|
||||
|
||||
if (pick) {
|
||||
extend = RNA_boolean_get(op->ptr, "extend");
|
||||
|
@ -2390,8 +2389,6 @@ static int uv_select_linked_internal(bContext *C, wmOperator *op, const wmEvent
|
|||
|
||||
if (event) {
|
||||
/* invoke */
|
||||
const ARegion *region = CTX_wm_region(C);
|
||||
|
||||
UI_view2d_region_to_view(®ion->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
|
||||
RNA_float_set_array(op->ptr, "location", co);
|
||||
}
|
||||
|
|
|
@ -2539,8 +2539,8 @@ static StitchState *stitch_select(bContext *C,
|
|||
{
|
||||
/* add uv under mouse to processed uv's */
|
||||
float co[2];
|
||||
UvNearestHit hit = UV_NEAREST_HIT_INIT;
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
UvNearestHit hit = UV_NEAREST_HIT_INIT_MAX(®ion->v2d);
|
||||
|
||||
UI_view2d_region_to_view(®ion->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
|
||||
|
||||
|
|
|
@ -2229,7 +2229,7 @@ void UV_OT_smart_project(wmOperatorType *ot)
|
|||
0.0f,
|
||||
1.0f,
|
||||
"Area Weight",
|
||||
"Weight projections vector by faces with larger areas",
|
||||
"Weight projection's vector by faces with larger areas",
|
||||
0.0f,
|
||||
1.0f);
|
||||
|
||||
|
|
|
@ -34,6 +34,28 @@
|
|||
|
||||
namespace blender::gpu {
|
||||
|
||||
/* See T82856: AMD drivers since 20.11 running on a polaris architecture doesn't support the
|
||||
* `GL_INT_2_10_10_10_REV` data type correctly. This data type is used to pack normals and flags.
|
||||
* The work around uses `GPU_RGBA16I` but that is only possible for loop normals.
|
||||
*
|
||||
* Vertex and Face normals would still render resulting in undefined behavior during selection and
|
||||
* rendering. */
|
||||
static bool is_faulty_T82856_platform(const char *version, const char *renderer)
|
||||
{
|
||||
/* On Linux the driver does not report its version. Test the OpenGL version in stead. */
|
||||
if (strstr(version, "4.5.14756") || strstr(version, "4.5.14757")) {
|
||||
if (strstr(renderer, " RX 460 ") || strstr(renderer, " RX 470 ") ||
|
||||
strstr(renderer, " RX 480 ") || strstr(renderer, " RX 490 ") ||
|
||||
strstr(renderer, " RX 560 ") || strstr(renderer, " RX 560X ") ||
|
||||
strstr(renderer, " RX 570 ") || strstr(renderer, " RX 580 ") ||
|
||||
strstr(renderer, " RX 590 ") || strstr(renderer, " RX550/550 ") ||
|
||||
strstr(renderer, " (TM) 520 ") || strstr(renderer, " (TM) 530 ") ||
|
||||
strstr(renderer, " R5 ") || strstr(renderer, " R7 ") || strstr(renderer, " R9 ")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Platform
|
||||
* \{ */
|
||||
|
@ -137,6 +159,11 @@ void GLBackend::platform_init()
|
|||
GPG.support_level = GPU_SUPPORT_LEVEL_LIMITED;
|
||||
}
|
||||
}
|
||||
if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_OFFICIAL)) {
|
||||
if (is_faulty_T82856_platform(version, renderer)) {
|
||||
GPG.support_level = GPU_SUPPORT_LEVEL_LIMITED;
|
||||
}
|
||||
}
|
||||
}
|
||||
GPG.create_key(GPG.support_level, vendor, renderer, version);
|
||||
GPG.create_gpu_name(vendor, renderer, version);
|
||||
|
@ -272,20 +299,10 @@ static void detect_workarounds()
|
|||
GCaps.broken_amd_driver = true;
|
||||
}
|
||||
/* See T82856: AMD drivers since 20.11 running on a polaris architecture doesn't support the
|
||||
* `GL_INT_2_10_10_10_REV` data type. This data type is used to pack normals. The work around
|
||||
* uses `GPU_RGBA16I`.*/
|
||||
* `GL_INT_2_10_10_10_REV` data type. */
|
||||
if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_OFFICIAL)) {
|
||||
if (strstr(version, " 20.11.2") || strstr(version, " 20.11.3 ") ||
|
||||
strstr(version, " 20.12.")) {
|
||||
if (strstr(renderer, " RX 460 ") || strstr(renderer, " RX 470 ") ||
|
||||
strstr(renderer, " RX 480 ") || strstr(renderer, " RX 490 ") ||
|
||||
strstr(renderer, " RX 560 ") || strstr(renderer, " RX 560X ") ||
|
||||
strstr(renderer, " RX 570 ") || strstr(renderer, " RX 580 ") ||
|
||||
strstr(renderer, " RX 590 ") || strstr(renderer, " RX550/550 ") ||
|
||||
strstr(renderer, " (TM) 520 ") || strstr(renderer, " (TM) 530 ") ||
|
||||
strstr(renderer, " R5 ") || strstr(renderer, " R7 ") || strstr(renderer, " R9 ")) {
|
||||
GCaps.use_hq_normals_workaround = true;
|
||||
}
|
||||
if (is_faulty_T82856_platform(version, renderer)) {
|
||||
GCaps.use_hq_normals_workaround = true;
|
||||
}
|
||||
}
|
||||
/* There is an issue with the #glBlitFramebuffer on MacOS with radeon pro graphics.
|
||||
|
@ -378,7 +395,7 @@ static void detect_workarounds()
|
|||
if (GLContext::debug_layer_support == false) {
|
||||
GLContext::debug_layer_workaround = true;
|
||||
}
|
||||
}
|
||||
} // namespace blender::gpu
|
||||
|
||||
/** Internal capabilities. */
|
||||
GLint GLContext::max_cubemap_size = 0;
|
||||
|
|
|
@ -314,6 +314,20 @@ typedef struct ID {
|
|||
*/
|
||||
struct ID *orig_id;
|
||||
|
||||
/**
|
||||
* Holds the #PyObject reference to the ID (initialized on demand).
|
||||
*
|
||||
* This isn't essential, it could be removed however it gives some advantages:
|
||||
*
|
||||
* - Every time the #ID is accessed a #BPy_StructRNA doesn't have to be created & destroyed
|
||||
* (consider all the polling and drawing functions that access ID's).
|
||||
*
|
||||
* - When this #ID is deleted, the #BPy_StructRNA can be invalidated
|
||||
* so accessing it from Python raises an exception instead of crashing.
|
||||
*
|
||||
* This is of limited benefit though, as it doesn't apply to non #ID data
|
||||
* that references this ID (the bones of an armature or the modifiers of an object for e.g.).
|
||||
*/
|
||||
void *py_instance;
|
||||
void *_pad1;
|
||||
} ID;
|
||||
|
|
|
@ -77,7 +77,7 @@ const EnumPropertyItem rna_enum_id_type_items[] = {
|
|||
{ID_TXT, "TEXT", ICON_TEXT, "Text", ""},
|
||||
{ID_TE, "TEXTURE", ICON_TEXTURE_DATA, "Texture", ""},
|
||||
{ID_HA, "HAIR", ICON_HAIR_DATA, "Hair", ""},
|
||||
{ID_PT, "POINTCLOUD", ICON_POINTCLOUD_DATA, "PointCloud", ""},
|
||||
{ID_PT, "POINTCLOUD", ICON_POINTCLOUD_DATA, "Point Cloud", ""},
|
||||
{ID_VO, "VOLUME", ICON_VOLUME_DATA, "Volume", ""},
|
||||
{ID_WM, "WINDOWMANAGER", ICON_WINDOW, "Window Manager", ""},
|
||||
{ID_WO, "WORLD", ICON_WORLD_DATA, "World", ""},
|
||||
|
|
|
@ -545,6 +545,17 @@ struct StructRNA {
|
|||
/* function to register/unregister subclasses */
|
||||
StructRegisterFunc reg;
|
||||
StructUnregisterFunc unreg;
|
||||
/**
|
||||
* Optionally support reusing Python instances for this type.
|
||||
*
|
||||
* Without this, an operator class created for #wmOperatorType.invoke (for example)
|
||||
* would have a different instance passed to the #wmOperatorType.modal callback.
|
||||
* So any variables assigned to `self` from Python would not be available to other callbacks.
|
||||
*
|
||||
* Being able to access the instance also has the advantage that we can invalidate
|
||||
* the Python instance when the data has been removed, see: #BPY_DECREF_RNA_INVALIDATE
|
||||
* so accessing the variables from Python raises an exception instead of crashing.
|
||||
*/
|
||||
StructInstanceFunc instance;
|
||||
|
||||
/* callback to get id properties */
|
||||
|
|
|
@ -172,6 +172,9 @@ static Camera *rna_Main_cameras_new(Main *bmain, const char *name)
|
|||
|
||||
ID *id = BKE_camera_add(bmain, safe_name);
|
||||
id_us_min(id);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return (Camera *)id;
|
||||
}
|
||||
|
||||
|
@ -180,16 +183,20 @@ static Scene *rna_Main_scenes_new(Main *bmain, const char *name)
|
|||
char safe_name[MAX_ID_NAME - 2];
|
||||
rna_idname_validate(name, safe_name);
|
||||
|
||||
return BKE_scene_add(bmain, safe_name);
|
||||
Scene *scene = BKE_scene_add(bmain, safe_name);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return scene;
|
||||
}
|
||||
static void rna_Main_scenes_remove(
|
||||
Main *bmain, bContext *C, ReportList *reports, PointerRNA *scene_ptr, bool do_unlink)
|
||||
{
|
||||
/* don't call BKE_id_free(...) directly */
|
||||
Scene *scene = scene_ptr->data;
|
||||
Scene *scene_new;
|
||||
|
||||
if ((scene_new = scene->id.prev) || (scene_new = scene->id.next)) {
|
||||
if (BKE_scene_can_be_removed(bmain, scene)) {
|
||||
Scene *scene_new = scene->id.prev ? scene->id.prev : scene->id.next;
|
||||
if (do_unlink) {
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
|
||||
|
@ -209,8 +216,10 @@ static void rna_Main_scenes_remove(
|
|||
rna_Main_ID_remove(bmain, reports, scene_ptr, do_unlink, true, true);
|
||||
}
|
||||
else {
|
||||
BKE_reportf(
|
||||
reports, RPT_ERROR, "Scene '%s' is the last, cannot be removed", scene->id.name + 2);
|
||||
BKE_reportf(reports,
|
||||
RPT_ERROR,
|
||||
"Scene '%s' is the last local one, cannot be removed",
|
||||
scene->id.name + 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -249,6 +258,8 @@ static Object *rna_Main_objects_new(Main *bmain, ReportList *reports, const char
|
|||
ob->data = data;
|
||||
BKE_object_materials_test(bmain, ob, ob->data);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return ob;
|
||||
}
|
||||
|
||||
|
@ -259,6 +270,9 @@ static Material *rna_Main_materials_new(Main *bmain, const char *name)
|
|||
|
||||
ID *id = (ID *)BKE_material_add(bmain, safe_name);
|
||||
id_us_min(id);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return (Material *)id;
|
||||
}
|
||||
|
||||
|
@ -309,6 +323,9 @@ static Mesh *rna_Main_meshes_new(Main *bmain, const char *name)
|
|||
|
||||
Mesh *me = BKE_mesh_add(bmain, safe_name);
|
||||
id_us_min(&me->id);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return me;
|
||||
}
|
||||
|
||||
|
@ -331,7 +348,12 @@ static Mesh *rna_Main_meshes_new_from_object(Main *bmain,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
return BKE_mesh_new_from_object_to_bmain(bmain, depsgraph, object, preserve_all_data_layers);
|
||||
Mesh *mesh = BKE_mesh_new_from_object_to_bmain(
|
||||
bmain, depsgraph, object, preserve_all_data_layers);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
static Light *rna_Main_lights_new(Main *bmain, const char *name, int type)
|
||||
|
@ -342,6 +364,9 @@ static Light *rna_Main_lights_new(Main *bmain, const char *name, int type)
|
|||
Light *lamp = BKE_light_add(bmain, safe_name);
|
||||
lamp->type = type;
|
||||
id_us_min(&lamp->id);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return lamp;
|
||||
}
|
||||
|
||||
|
@ -371,6 +396,9 @@ static Image *rna_Main_images_new(Main *bmain,
|
|||
is_data,
|
||||
tiled);
|
||||
id_us_min(&image->id);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return image;
|
||||
}
|
||||
static Image *rna_Main_images_load(Main *bmain,
|
||||
|
@ -397,6 +425,9 @@ static Image *rna_Main_images_load(Main *bmain,
|
|||
}
|
||||
|
||||
id_us_min((ID *)ima);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return ima;
|
||||
}
|
||||
|
||||
|
@ -407,6 +438,9 @@ static Lattice *rna_Main_lattices_new(Main *bmain, const char *name)
|
|||
|
||||
Lattice *lt = BKE_lattice_add(bmain, safe_name);
|
||||
id_us_min(<->id);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return lt;
|
||||
}
|
||||
|
||||
|
@ -417,6 +451,9 @@ static Curve *rna_Main_curves_new(Main *bmain, const char *name, int type)
|
|||
|
||||
Curve *cu = BKE_curve_add(bmain, safe_name, type);
|
||||
id_us_min(&cu->id);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return cu;
|
||||
}
|
||||
|
||||
|
@ -427,6 +464,9 @@ static MetaBall *rna_Main_metaballs_new(Main *bmain, const char *name)
|
|||
|
||||
MetaBall *mb = BKE_mball_add(bmain, safe_name);
|
||||
id_us_min(&mb->id);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return mb;
|
||||
}
|
||||
|
||||
|
@ -452,6 +492,9 @@ static VFont *rna_Main_fonts_load(Main *bmain,
|
|||
filepath,
|
||||
errno ? strerror(errno) : TIP_("unsupported font format"));
|
||||
}
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
|
@ -463,6 +506,9 @@ static Tex *rna_Main_textures_new(Main *bmain, const char *name, int type)
|
|||
Tex *tex = BKE_texture_add(bmain, safe_name);
|
||||
BKE_texture_type_set(tex, type);
|
||||
id_us_min(&tex->id);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
|
@ -473,6 +519,9 @@ static Brush *rna_Main_brushes_new(Main *bmain, const char *name, int mode)
|
|||
|
||||
Brush *brush = BKE_brush_add(bmain, safe_name, mode);
|
||||
id_us_min(&brush->id);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return brush;
|
||||
}
|
||||
|
||||
|
@ -490,6 +539,9 @@ static World *rna_Main_worlds_new(Main *bmain, const char *name)
|
|||
|
||||
World *world = BKE_world_add(bmain, safe_name);
|
||||
id_us_min(&world->id);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return world;
|
||||
}
|
||||
|
||||
|
@ -498,7 +550,11 @@ static Collection *rna_Main_collections_new(Main *bmain, const char *name)
|
|||
char safe_name[MAX_ID_NAME - 2];
|
||||
rna_idname_validate(name, safe_name);
|
||||
|
||||
return BKE_collection_add(bmain, NULL, safe_name);
|
||||
Collection *collection = BKE_collection_add(bmain, NULL, safe_name);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return collection;
|
||||
}
|
||||
|
||||
static Speaker *rna_Main_speakers_new(Main *bmain, const char *name)
|
||||
|
@ -508,6 +564,9 @@ static Speaker *rna_Main_speakers_new(Main *bmain, const char *name)
|
|||
|
||||
Speaker *speaker = BKE_speaker_add(bmain, safe_name);
|
||||
id_us_min(&speaker->id);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return speaker;
|
||||
}
|
||||
|
||||
|
@ -523,6 +582,9 @@ static bSound *rna_Main_sounds_load(Main *bmain, const char *name, bool check_ex
|
|||
}
|
||||
|
||||
id_us_min(&sound->id);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return sound;
|
||||
}
|
||||
|
||||
|
@ -531,7 +593,11 @@ static Text *rna_Main_texts_new(Main *bmain, const char *name)
|
|||
char safe_name[MAX_ID_NAME - 2];
|
||||
rna_idname_validate(name, safe_name);
|
||||
|
||||
return BKE_text_add(bmain, safe_name);
|
||||
Text *text = BKE_text_add(bmain, safe_name);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
static Text *rna_Main_texts_load(Main *bmain,
|
||||
|
@ -551,6 +617,9 @@ static Text *rna_Main_texts_load(Main *bmain,
|
|||
filepath,
|
||||
errno ? strerror(errno) : TIP_("unable to load text"));
|
||||
}
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return txt;
|
||||
}
|
||||
|
||||
|
@ -561,6 +630,9 @@ static bArmature *rna_Main_armatures_new(Main *bmain, const char *name)
|
|||
|
||||
bArmature *arm = BKE_armature_add(bmain, safe_name);
|
||||
id_us_min(&arm->id);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return arm;
|
||||
}
|
||||
|
||||
|
@ -571,6 +643,9 @@ static bAction *rna_Main_actions_new(Main *bmain, const char *name)
|
|||
|
||||
bAction *act = BKE_action_add(bmain, safe_name);
|
||||
id_fake_user_clear(&act->id);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return act;
|
||||
}
|
||||
|
||||
|
@ -581,6 +656,9 @@ static ParticleSettings *rna_Main_particles_new(Main *bmain, const char *name)
|
|||
|
||||
ParticleSettings *part = BKE_particlesettings_add(bmain, safe_name);
|
||||
id_us_min(&part->id);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return part;
|
||||
}
|
||||
|
||||
|
@ -591,6 +669,9 @@ static Palette *rna_Main_palettes_new(Main *bmain, const char *name)
|
|||
|
||||
Palette *palette = BKE_palette_add(bmain, safe_name);
|
||||
id_us_min(&palette->id);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return (Palette *)palette;
|
||||
}
|
||||
|
||||
|
@ -622,6 +703,9 @@ static MovieClip *rna_Main_movieclip_load(Main *bmain,
|
|||
}
|
||||
|
||||
id_us_min((ID *)clip);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return clip;
|
||||
}
|
||||
|
||||
|
@ -630,7 +714,11 @@ static Mask *rna_Main_mask_new(Main *bmain, const char *name)
|
|||
char safe_name[MAX_ID_NAME - 2];
|
||||
rna_idname_validate(name, safe_name);
|
||||
|
||||
return BKE_mask_new(bmain, safe_name);
|
||||
Mask *mask = BKE_mask_new(bmain, safe_name);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
static FreestyleLineStyle *rna_Main_linestyles_new(Main *bmain, const char *name)
|
||||
|
@ -640,6 +728,9 @@ static FreestyleLineStyle *rna_Main_linestyles_new(Main *bmain, const char *name
|
|||
|
||||
FreestyleLineStyle *linestyle = BKE_linestyle_new(bmain, safe_name);
|
||||
id_us_min(&linestyle->id);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return linestyle;
|
||||
}
|
||||
|
||||
|
@ -653,6 +744,9 @@ static LightProbe *rna_Main_lightprobe_new(Main *bmain, const char *name, int ty
|
|||
BKE_lightprobe_type_set(probe, type);
|
||||
|
||||
id_us_min(&probe->id);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return probe;
|
||||
}
|
||||
|
||||
|
@ -663,6 +757,9 @@ static bGPdata *rna_Main_gpencils_new(Main *bmain, const char *name)
|
|||
|
||||
bGPdata *gpd = BKE_gpencil_data_addnew(bmain, safe_name);
|
||||
id_us_min(&gpd->id);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return gpd;
|
||||
}
|
||||
|
||||
|
@ -674,6 +771,9 @@ static Hair *rna_Main_hairs_new(Main *bmain, const char *name)
|
|||
|
||||
Hair *hair = BKE_hair_add(bmain, safe_name);
|
||||
id_us_min(&hair->id);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return hair;
|
||||
}
|
||||
# endif
|
||||
|
@ -686,6 +786,9 @@ static PointCloud *rna_Main_pointclouds_new(Main *bmain, const char *name)
|
|||
|
||||
PointCloud *pointcloud = BKE_pointcloud_add(bmain, safe_name);
|
||||
id_us_min(&pointcloud->id);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return pointcloud;
|
||||
}
|
||||
# endif
|
||||
|
@ -697,6 +800,9 @@ static Volume *rna_Main_volumes_new(Main *bmain, const char *name)
|
|||
|
||||
Volume *volume = BKE_volume_add(bmain, safe_name);
|
||||
id_us_min(&volume->id);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return volume;
|
||||
}
|
||||
|
||||
|
@ -708,6 +814,9 @@ static Simulation *rna_Main_simulations_new(Main *bmain, const char *name)
|
|||
|
||||
Simulation *simulation = BKE_simulation_add(bmain, safe_name);
|
||||
id_us_min(&simulation->id);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
|
||||
return simulation;
|
||||
}
|
||||
# endif
|
||||
|
|
|
@ -5900,8 +5900,7 @@ static void rna_def_modifier_triangulate(BlenderRNA *brna)
|
|||
prop = RNA_def_property(srna, "ngon_method", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "ngon_method");
|
||||
RNA_def_property_enum_items(prop, rna_enum_modifier_triangulate_ngon_method_items);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Polygon Method", "Method for splitting the polygons into triangles");
|
||||
RNA_def_property_ui_text(prop, "N-gon Method", "Method for splitting the n-gons into triangles");
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "min_vertices", PROP_INT, PROP_UNSIGNED);
|
||||
|
|
|
@ -3245,6 +3245,7 @@ static void rna_NodeGroup_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *
|
|||
}
|
||||
|
||||
ED_node_tag_update_nodetree(bmain, ntree, node);
|
||||
DEG_relations_tag_update(bmain);
|
||||
}
|
||||
|
||||
static void rna_NodeGroup_node_tree_set(PointerRNA *ptr,
|
||||
|
@ -8432,8 +8433,7 @@ static void def_geo_triangulate(StructRNA *srna)
|
|||
RNA_def_property_enum_sdna(prop, NULL, "custom2");
|
||||
RNA_def_property_enum_items(prop, rna_node_geometry_triangulate_ngon_method_items);
|
||||
RNA_def_property_enum_default(prop, GEO_NODE_TRIANGULATE_NGON_BEAUTY);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Polygon Method", "Method for splitting the polygons into triangles");
|
||||
RNA_def_property_ui_text(prop, "N-gon Method", "Method for splitting the n-gons into triangles");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
}
|
||||
|
||||
|
|
|
@ -135,7 +135,7 @@ static void rna_def_pointcloud(BlenderRNA *brna)
|
|||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "PointCloud", "ID");
|
||||
RNA_def_struct_ui_text(srna, "PointCloud", "Point cloud data-block");
|
||||
RNA_def_struct_ui_text(srna, "Point Cloud", "Point cloud data-block");
|
||||
RNA_def_struct_ui_icon(srna, ICON_POINTCLOUD_DATA);
|
||||
|
||||
/* geometry */
|
||||
|
|
|
@ -2821,6 +2821,7 @@ static void rna_def_view3d_cursor(BlenderRNA *brna)
|
|||
RNA_def_struct_sdna(srna, "View3DCursor");
|
||||
RNA_def_struct_path_func(srna, "rna_View3DCursor_path");
|
||||
RNA_def_struct_ui_text(srna, "3D Cursor", "");
|
||||
RNA_def_struct_ui_icon(srna, ICON_CURSOR);
|
||||
|
||||
prop = RNA_def_property(srna, "location", PROP_FLOAT, PROP_XYZ_LENGTH);
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
|
|
|
@ -420,10 +420,10 @@ void RNA_api_scene(StructRNA *srna)
|
|||
"Method for splitting the quads into triangles");
|
||||
RNA_def_enum(func,
|
||||
"ngon_method",
|
||||
rna_enum_modifier_triangulate_quad_method_items,
|
||||
rna_enum_modifier_triangulate_ngon_method_items,
|
||||
0,
|
||||
"Polygon Method",
|
||||
"Method for splitting the polygons into triangles");
|
||||
"N-gon Method",
|
||||
"Method for splitting the n-gons into triangles");
|
||||
|
||||
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
|
||||
# endif
|
||||
|
|
|
@ -754,6 +754,9 @@ void MOD_nodes_init(Main *bmain, NodesModifierData *nmd)
|
|||
bNode *group_input_node = nodeAddStaticNode(nullptr, ntree, NODE_GROUP_INPUT);
|
||||
bNode *group_output_node = nodeAddStaticNode(nullptr, ntree, NODE_GROUP_OUTPUT);
|
||||
|
||||
nodeSetSelected(group_input_node, false);
|
||||
nodeSetSelected(group_output_node, false);
|
||||
|
||||
group_input_node->locx = -200 - group_input_node->width;
|
||||
group_output_node->locx = 200;
|
||||
group_output_node->flag |= NODE_DO_OUTPUT;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
* \ingroup modifiers
|
||||
*/
|
||||
|
||||
#include "BLI_alloca.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_math_geom.h"
|
||||
#include "BLI_task.h"
|
||||
|
@ -160,7 +161,9 @@ typedef struct SDefDeformData {
|
|||
const SDefVert *const bind_verts;
|
||||
float (*const targetCos)[3];
|
||||
float (*const vertexCos)[3];
|
||||
float *const weights;
|
||||
const MDeformVert *const dvert;
|
||||
int const defgrp_index;
|
||||
bool const invert_vgroup;
|
||||
float const strength;
|
||||
} SDefDeformData;
|
||||
|
||||
|
@ -1191,7 +1194,17 @@ static void deformVert(void *__restrict userdata,
|
|||
const int num_binds = data->bind_verts[index].numbinds;
|
||||
float *const vertexCos = data->vertexCos[index];
|
||||
float norm[3], temp[3], offset[3];
|
||||
const float weight = (data->weights != NULL) ? data->weights[index] : 1.0f;
|
||||
|
||||
/* Retrieve the value of the weight vertex group if specified. */
|
||||
float weight = 1.0f;
|
||||
|
||||
if (data->dvert && data->defgrp_index != -1) {
|
||||
weight = BKE_defvert_find_weight(&data->dvert[index], data->defgrp_index);
|
||||
|
||||
if (data->invert_vgroup) {
|
||||
weight = 1.0f - weight;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if this vertex will be deformed. If it is not deformed we return and avoid
|
||||
* unnecessary calculations. */
|
||||
|
@ -1206,7 +1219,16 @@ static void deformVert(void *__restrict userdata,
|
|||
for (int j = 0; j < num_binds; j++) {
|
||||
max_verts = MAX2(max_verts, sdbind[j].numverts);
|
||||
}
|
||||
float(*coords_buffer)[3] = MEM_malloc_arrayN(max_verts, sizeof(*coords_buffer), __func__);
|
||||
|
||||
const bool big_buffer = max_verts > 256;
|
||||
float(*coords_buffer)[3];
|
||||
|
||||
if (UNLIKELY(big_buffer)) {
|
||||
coords_buffer = MEM_malloc_arrayN(max_verts, sizeof(*coords_buffer), __func__);
|
||||
}
|
||||
else {
|
||||
coords_buffer = BLI_array_alloca(coords_buffer, max_verts);
|
||||
}
|
||||
|
||||
for (int j = 0; j < num_binds; j++, sdbind++) {
|
||||
for (int k = 0; k < sdbind->numverts; k++) {
|
||||
|
@ -1216,28 +1238,32 @@ static void deformVert(void *__restrict userdata,
|
|||
normal_poly_v3(norm, coords_buffer, sdbind->numverts);
|
||||
zero_v3(temp);
|
||||
|
||||
/* ---------- looptri mode ---------- */
|
||||
if (sdbind->mode == MOD_SDEF_MODE_LOOPTRI) {
|
||||
madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[0]], sdbind->vert_weights[0]);
|
||||
madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[1]], sdbind->vert_weights[1]);
|
||||
madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[2]], sdbind->vert_weights[2]);
|
||||
}
|
||||
else {
|
||||
switch (sdbind->mode) {
|
||||
/* ---------- looptri mode ---------- */
|
||||
case MOD_SDEF_MODE_LOOPTRI: {
|
||||
madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[0]], sdbind->vert_weights[0]);
|
||||
madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[1]], sdbind->vert_weights[1]);
|
||||
madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[2]], sdbind->vert_weights[2]);
|
||||
break;
|
||||
}
|
||||
|
||||
/* ---------- ngon mode ---------- */
|
||||
if (sdbind->mode == MOD_SDEF_MODE_NGON) {
|
||||
case MOD_SDEF_MODE_NGON: {
|
||||
for (int k = 0; k < sdbind->numverts; k++) {
|
||||
madd_v3_v3fl(temp, coords_buffer[k], sdbind->vert_weights[k]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* ---------- centroid mode ---------- */
|
||||
else if (sdbind->mode == MOD_SDEF_MODE_CENTROID) {
|
||||
case MOD_SDEF_MODE_CENTROID: {
|
||||
float cent[3];
|
||||
mid_v3_v3_array(cent, coords_buffer, sdbind->numverts);
|
||||
|
||||
madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[0]], sdbind->vert_weights[0]);
|
||||
madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[1]], sdbind->vert_weights[1]);
|
||||
madd_v3_v3fl(temp, cent, sdbind->vert_weights[2]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1251,7 +1277,10 @@ static void deformVert(void *__restrict userdata,
|
|||
|
||||
/* Add the offset to start coord multiplied by the strength and weight values. */
|
||||
madd_v3_v3fl(vertexCos, offset, data->strength * weight);
|
||||
MEM_freeN(coords_buffer);
|
||||
|
||||
if (UNLIKELY(big_buffer)) {
|
||||
MEM_freeN(coords_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
static void surfacedeformModifier_do(ModifierData *md,
|
||||
|
@ -1332,33 +1361,16 @@ static void surfacedeformModifier_do(ModifierData *md,
|
|||
int defgrp_index;
|
||||
MDeformVert *dvert;
|
||||
MOD_get_vgroup(ob, mesh, smd->defgrp_name, &dvert, &defgrp_index);
|
||||
float *weights = NULL;
|
||||
const bool invert_group = (smd->flags & MOD_SDEF_INVERT_VGROUP) != 0;
|
||||
|
||||
if (defgrp_index != -1) {
|
||||
dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, mesh->totvert);
|
||||
/* If no vertices were ever added to an object's vgroup, dvert might be NULL. */
|
||||
if (dvert == NULL) {
|
||||
/* Add a valid data layer! */
|
||||
dvert = CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, mesh->totvert);
|
||||
}
|
||||
|
||||
if (dvert) {
|
||||
weights = MEM_calloc_arrayN((size_t)numverts, sizeof(*weights), __func__);
|
||||
MDeformVert *dv = dvert;
|
||||
for (uint i = 0; i < numverts; i++, dv++) {
|
||||
weights[i] = invert_group ? (1.0f - BKE_defvert_find_weight(dv, defgrp_index)) :
|
||||
BKE_defvert_find_weight(dv, defgrp_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
const bool invert_vgroup = (smd->flags & MOD_SDEF_INVERT_VGROUP) != 0;
|
||||
|
||||
/* Actual vertex location update starts here */
|
||||
SDefDeformData data = {
|
||||
.bind_verts = smd->verts,
|
||||
.targetCos = MEM_malloc_arrayN(tnumverts, sizeof(float[3]), "SDefTargetVertArray"),
|
||||
.vertexCos = vertexCos,
|
||||
.weights = weights,
|
||||
.dvert = dvert,
|
||||
.defgrp_index = defgrp_index,
|
||||
.invert_vgroup = invert_vgroup,
|
||||
.strength = smd->strength,
|
||||
};
|
||||
|
||||
|
@ -1372,8 +1384,6 @@ static void surfacedeformModifier_do(ModifierData *md,
|
|||
|
||||
MEM_freeN(data.targetCos);
|
||||
}
|
||||
|
||||
MEM_SAFE_FREE(weights);
|
||||
}
|
||||
|
||||
static void deformVerts(ModifierData *md,
|
||||
|
@ -1449,9 +1459,9 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
|
|||
col = uiLayoutColumn(layout, false);
|
||||
uiLayoutSetActive(col, !is_bound);
|
||||
uiItemR(col, ptr, "target", 0, NULL, ICON_NONE);
|
||||
|
||||
uiItemR(col, ptr, "falloff", 0, NULL, ICON_NONE);
|
||||
uiItemR(col, ptr, "strength", 0, NULL, ICON_NONE);
|
||||
|
||||
uiItemR(layout, ptr, "strength", 0, NULL, ICON_NONE);
|
||||
|
||||
modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", NULL);
|
||||
|
||||
|
|
|
@ -161,10 +161,11 @@ static void add_instances_from_geometry_component(InstancesComponent &instances,
|
|||
"rotation", domain, {0, 0, 0});
|
||||
Float3ReadAttribute scales = src_geometry.attribute_get_for_read<float3>(
|
||||
"scale", domain, {1, 1, 1});
|
||||
Int32ReadAttribute ids = src_geometry.attribute_get_for_read<int>("id", domain, -1);
|
||||
|
||||
for (const int i : IndexRange(domain_size)) {
|
||||
if (instances_data[i].has_value()) {
|
||||
instances.add_instance(*instances_data[i], positions[i], rotations[i], scales[i]);
|
||||
instances.add_instance(*instances_data[i], positions[i], rotations[i], scales[i], ids[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -195,10 +195,14 @@ void BPY_context_dict_clear_members_array(void **dict_p,
|
|||
|
||||
PyObject *dict = *dict_p;
|
||||
BLI_assert(PyDict_Check(dict));
|
||||
|
||||
/* Use #PyDict_Pop instead of #PyDict_DelItemString to avoid setting the exception,
|
||||
* while supported it's good to avoid for low level functions like this that run often. */
|
||||
for (uint i = 0; i < context_members_len; i++) {
|
||||
if (PyDict_DelItemString(dict, context_members[i])) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
PyObject *key = PyUnicode_FromString(context_members[i]);
|
||||
PyObject *item = _PyDict_Pop(dict, key, Py_None);
|
||||
Py_DECREF(key);
|
||||
Py_DECREF(item);
|
||||
}
|
||||
|
||||
if (use_gil) {
|
||||
|
@ -532,7 +536,7 @@ void BPY_DECREF(void *pyob_ptr)
|
|||
void BPY_DECREF_RNA_INVALIDATE(void *pyob_ptr)
|
||||
{
|
||||
const PyGILState_STATE gilstate = PyGILState_Ensure();
|
||||
const int do_invalidate = (Py_REFCNT((PyObject *)pyob_ptr) > 1);
|
||||
const bool do_invalidate = (Py_REFCNT((PyObject *)pyob_ptr) > 1);
|
||||
Py_DECREF((PyObject *)pyob_ptr);
|
||||
if (do_invalidate) {
|
||||
pyrna_invalidate(pyob_ptr);
|
||||
|
|
|
@ -204,7 +204,7 @@ void RE_engine_update_memory_stats(RenderEngine *engine, float mem_used, float m
|
|||
void RE_engine_report(RenderEngine *engine, int type, const char *msg);
|
||||
void RE_engine_set_error_message(RenderEngine *engine, const char *msg);
|
||||
|
||||
int RE_engine_render(struct Render *re, int do_all);
|
||||
bool RE_engine_render(struct Render *re, bool do_all);
|
||||
|
||||
bool RE_engine_is_external(const struct Render *re);
|
||||
|
||||
|
|
|
@ -803,23 +803,23 @@ static void engine_render_view_layer(Render *re,
|
|||
engine_depsgraph_free(engine);
|
||||
}
|
||||
|
||||
int RE_engine_render(Render *re, int do_all)
|
||||
bool RE_engine_render(Render *re, bool do_all)
|
||||
{
|
||||
RenderEngineType *type = RE_engines_find(re->r.engine);
|
||||
bool persistent_data = (re->r.mode & R_PERSISTENT_DATA) != 0;
|
||||
|
||||
/* verify if we can render */
|
||||
if (!type->render) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
if ((re->r.scemode & R_BUTS_PREVIEW) && !(type->flag & RE_USE_PREVIEW)) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
if (do_all && !(type->flag & RE_USE_POSTPROCESS)) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
if (!do_all && (type->flag & RE_USE_POSTPROCESS)) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Lock drawing in UI during data phase. */
|
||||
|
@ -859,7 +859,7 @@ int RE_engine_render(Render *re, int do_all)
|
|||
*/
|
||||
BKE_report(re->reports, RPT_ERROR, "Failed allocate render result, out of memory");
|
||||
G.is_break = true;
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* set render info */
|
||||
|
@ -977,7 +977,7 @@ int RE_engine_render(Render *re, int do_all)
|
|||
}
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
void RE_engine_update_render_passes(struct RenderEngine *engine,
|
||||
|
|
|
@ -1130,7 +1130,7 @@ void RE_AddObject(Render *UNUSED(re), Object *UNUSED(ob))
|
|||
static void do_render_3d(Render *re)
|
||||
{
|
||||
re->current_scene_update(re->suh, re->scene);
|
||||
RE_engine_render(re, 0);
|
||||
RE_engine_render(re, false);
|
||||
}
|
||||
|
||||
/* make sure disprect is not affected by the render border */
|
||||
|
@ -1599,7 +1599,7 @@ static void do_render_all_options(Render *re)
|
|||
BKE_image_all_free_anim_ibufs(re->main, re->r.cfra);
|
||||
SEQ_relations_free_all_anim_ibufs(re->scene, re->r.cfra);
|
||||
|
||||
if (RE_engine_render(re, 1)) {
|
||||
if (RE_engine_render(re, true)) {
|
||||
/* in this case external render overrides all */
|
||||
}
|
||||
else if (RE_seq_render_active(re->scene, &re->r)) {
|
||||
|
|
|
@ -133,7 +133,6 @@ Sequence *SEQ_sequence_alloc(ListBase *lb, int timeline_frame, int machine, int
|
|||
|
||||
seq->strip = seq_strip_alloc(type);
|
||||
seq->stereo3d_format = MEM_callocN(sizeof(Stereo3dFormat), "Sequence Stereo Format");
|
||||
seq->cache_flag = SEQ_CACHE_STORE_RAW | SEQ_CACHE_STORE_PREPROCESSED | SEQ_CACHE_STORE_COMPOSITE;
|
||||
|
||||
SEQ_relations_session_uuid_generate(seq);
|
||||
|
||||
|
@ -247,8 +246,7 @@ Editing *SEQ_editing_ensure(Scene *scene)
|
|||
ed->seqbasep = &ed->seqbase;
|
||||
ed->cache = NULL;
|
||||
ed->cache_flag = SEQ_CACHE_STORE_FINAL_OUT;
|
||||
ed->cache_flag |= SEQ_CACHE_VIEW_FINAL_OUT;
|
||||
ed->cache_flag |= SEQ_CACHE_VIEW_ENABLE;
|
||||
ed->cache_flag |= SEQ_CACHE_STORE_RAW;
|
||||
}
|
||||
|
||||
return scene->ed;
|
||||
|
|
Loading…
Reference in New Issue