Geometry Nodes: new repeat zone #109164

Merged
Jacques Lucke merged 98 commits from JacquesLucke/blender:serial-loop into main 2023-07-11 22:36:17 +02:00
139 changed files with 3321 additions and 2750 deletions
Showing only changes of commit 78c31f532e - Show all commits

View File

@ -14,7 +14,10 @@ from bpy.props import (
PointerProperty,
StringProperty,
)
from bpy.app.translations import pgettext_iface as iface_
from bpy.app.translations import (
contexts as i18n_contexts,
pgettext_iface as iface_
)
from math import pi
@ -1105,6 +1108,7 @@ class CyclesMaterialSettings(bpy.types.PropertyGroup):
emission_sampling: EnumProperty(
name="Emission Sampling",
description="Sampling strategy for emissive surfaces",
translation_context=i18n_contexts.id_light,
items=enum_emission_sampling,
default="AUTO",
)

View File

@ -261,14 +261,17 @@ void *MEM_guarded_dupallocN(const void *vmemh)
#else
{
MemHead *nmemh;
char *name = malloc(strlen(memh->name) + 24);
const char name_prefix[] = "dupli_alloc ";
const size_t name_prefix_len = sizeof(name_prefix) - 1;
const size_t name_size = strlen(memh->name) + 1;
char *name = malloc(name_prefix_len + name_size);
memcpy(name, name_prefix, sizeof(name_prefix));
memcpy(name + name_prefix_len, memh->name, name_size);
if (LIKELY(memh->alignment == 0)) {
sprintf(name, "%s %s", "dupli_alloc", memh->name);
newp = MEM_guarded_mallocN(memh->len, name);
}
else {
sprintf(name, "%s %s", "dupli_alloc", memh->name);
newp = MEM_guarded_mallocN_aligned(memh->len, (size_t)memh->alignment, name);
}

View File

@ -45,15 +45,16 @@
<p>New features:</p>
<ul>
<li>Simulation Nodes</li>
<li>Cycles Hardware Raytracing on AMD and Intel graphics cards</li>
<li>New transparent Render Pass</li>
<li>Animation: A new Gaussian Smooth operator for keyframe data was added.</li>
</ul>
<p>Enhancements:</p>
<ul>
<li> PLY I/O:About 4x-20x faster export, 8x-30x faster import</li>
<li>Improved UV packing</li>
<li>Python API: Custom script directories</li>
<li>USD Curves/Hair export</li>
<li>Major improvements to the resyncing process of Library Overrides</li>
<li>Major improvements to the Library Overrides resyncing process</li>
</ul>
</description>
</release>

View File

@ -34,6 +34,7 @@ https://github.com/AcademySoftwareFoundation/MaterialX
https://software.intel.com/en-us/oneapi/onetbb
** OpenCL Wrangler; version 27a6867 -- https://github.com/OpenCLWrangler/clew
** OpenImageDenoise; version 1.4.3 -- https://www.openimagedenoise.org/
** OpenSSL; version 3.0.9 -- https://www.openssl.org/
** OpenXR SDK; version 1.0.17 -- https://khronos.org/openxr
** RangeTree; version 40ebed8aa209 -- https://github.com/ideasman42/rangetree-c
** SDL Extension Wrangler; version 15edf8e --
@ -269,6 +270,11 @@ limitations under the License.
Written by George van Venrooij
* For OpenImageDenoise see also this required NOTICE:
Copyright 2009-2020 Intel Corporation
* For OpenSSL see also this required NOTICE:
Copyright (c) 1998-2023 The OpenSSL Project Authors
Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
All rights reserved.
* For OpenXR SDK see also this required NOTICE:
Copyright (c) 2017-2020 The Khronos Group Inc.
Copyright (c) 2017-2019 Valve Corporation
@ -4270,129 +4276,6 @@ MIT Expat
------
** OpenSSL; version 3.1.1 -- https://www.openssl.org/
Copyright (c) 1998-2021 The OpenSSL Project
Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
OpenSSL License
---------------
/* ====================================================================
* Copyright (c) 1998-2019 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
Original SSLeay License
-----------------------
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
------
** Python; version 3.10.12 -- https://www.python.org
Copyright (c) 2001-2021 Python Software Foundation. All rights reserved.

View File

@ -391,7 +391,7 @@ class DATA_PT_camera_background_image(CameraButtonsPanel, Panel):
col.prop(bg, "rotation")
col.prop(bg, "scale")
col = box.column(heading="Flip")
col = box.column(heading="Flip", heading_ctxt=i18n_contexts.id_image)
col.prop(bg, "use_flip_x", text="X")
col.prop(bg, "use_flip_y", text="Y")

View File

@ -2,7 +2,7 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
import bpy
from bpy.types import Panel
from bpy.types import Panel, Menu
class DataButtonsPanel:
@ -32,6 +32,15 @@ class DATA_PT_context_grease_pencil(DataButtonsPanel, Panel):
layout.template_ID(space, "pin_id")
class GREASE_PENCIL_MT_grease_pencil_add_layer_extra(Menu):
bl_label = "Add Extra"
def draw(self, context):
layout = self.layout
layout.operator("grease_pencil.layer_group_add", text="Add Group")
class DATA_PT_grease_pencil_layers(DataButtonsPanel, Panel):
bl_label = "Layers"
@ -42,13 +51,17 @@ class DATA_PT_grease_pencil_layers(DataButtonsPanel, Panel):
row.template_grease_pencil_layer_tree()
col = row.column()
col.operator("grease_pencil.layer_add", icon='ADD', text="")
sub = col.column(align=True)
sub.operator("grease_pencil.layer_add", icon='ADD', text="")
sub.menu("GREASE_PENCIL_MT_grease_pencil_add_layer_extra", icon='DOWNARROW_HLT', text="")
col.operator("grease_pencil.layer_remove", icon='REMOVE', text="")
classes = (
DATA_PT_context_grease_pencil,
DATA_PT_grease_pencil_layers,
GREASE_PENCIL_MT_grease_pencil_add_layer_extra,
)
if __name__ == "__main__": # only for live edit.

View File

@ -1372,7 +1372,7 @@ class USERPREF_PT_file_paths_script_directories(FilePathsPanel, Panel):
row = path_col.row(align=True) # Padding
row.separator()
row.label(text="Path")
row.label(text="Path", text_ctxt=i18n_contexts.editor_filebrowser)
row.operator("preferences.script_directory_add", text="", icon='ADD', emboss=False)

View File

@ -5354,7 +5354,8 @@ class VIEW3D_MT_edit_gpencil_stroke(Menu):
layout.separator()
layout.operator_menu_enum("gpencil.stroke_join", "type", text="Join")
layout.operator_menu_enum("gpencil.stroke_join", "type", text="Join",
text_ctxt=i18n_contexts.id_gpencil)
layout.separator()
@ -7661,7 +7662,9 @@ class VIEW3D_MT_gpencil_edit_context_menu(Menu):
# Removal Operators
col.operator("gpencil.stroke_merge_by_distance").use_unselected = True
col.operator_menu_enum("gpencil.stroke_join", "type", text="Join")
col.operator_menu_enum("gpencil.stroke_join", "type", text="Join",
text_ctxt=i18n_contexts.id_gpencil)
col.operator("gpencil.stroke_split", text="Split")
col.operator("gpencil.stroke_separate", text="Separate").mode = 'STROKE'

View File

@ -3,6 +3,7 @@
# SPDX-License-Identifier: GPL-2.0-or-later
from bpy.types import Menu, Panel, UIList, WindowManager
from bpy.app.translations import contexts as i18n_contexts
from bl_ui.properties_grease_pencil_common import (
GreasePencilSculptAdvancedPanel,
GreasePencilDisplayPanel,
@ -1582,7 +1583,8 @@ class VIEW3D_PT_tools_grease_pencil_brush_advanced(View3DPanel, Panel):
elif brush.gpencil_tool == 'FILL':
row = col.row(align=True)
row.prop(gp_settings, "fill_draw_mode", text="Boundary")
row.prop(gp_settings, "fill_draw_mode", text="Boundary",
text_ctxt=i18n_contexts.id_gpencil)
row.prop(
gp_settings,
"show_fill_boundary",

View File

@ -78,7 +78,7 @@ typedef enum BVHCacheType {
BVHTREE_FROM_LOOSEVERTS,
BVHTREE_FROM_LOOSEEDGES,
BVHTREE_FROM_EM_VERTS,
BVHTREE_FROM_EM_LOOSEVERTS,
BVHTREE_FROM_EM_EDGES,
BVHTREE_FROM_EM_LOOPTRI,

View File

@ -61,8 +61,21 @@ class DrawingRuntime {
* Triangle cache for all the strokes in the drawing.
*/
mutable SharedCache<Vector<uint3>> triangles_cache;
};
StrokeCache stroke_cache;
class Drawing : public ::GreasePencilDrawing {
public:
Drawing();
Drawing(const Drawing &other);
~Drawing();
const bke::CurvesGeometry &strokes() const;
bke::CurvesGeometry &strokes_for_write();
/**
* The triangles for all the fills in the geometry.
*/
Span<uint3> triangles() const;
void tag_positions_changed();
};
class LayerGroup;
@ -194,6 +207,12 @@ class Layer : public ::GreasePencilLayer {
*/
LayerGroup &parent_group() const;
/**
* \returns the layer as a `TreeNode`.
*/
const TreeNode &as_node() const;
TreeNode &as_node();
/**
* \returns the frames mapping.
*/
@ -274,6 +293,12 @@ class LayerGroup : public ::GreasePencilLayerTreeGroup {
LayerGroup &add_group(LayerGroup *group);
LayerGroup &add_group(StringRefNull name);
/**
* Adds a layer group after \a link and returns it.
*/
LayerGroup &add_group_after(LayerGroup *group, TreeNode *link);
LayerGroup &add_group_after(StringRefNull name, TreeNode *link);
/**
* Adds a layer at the end of this group and returns it.
*/
@ -346,6 +371,15 @@ inline LayerGroup &Layer::parent_group() const
return this->base.parent->wrap();
}
inline const TreeNode &Layer::as_node() const
{
return *reinterpret_cast<const TreeNode *>(this);
}
inline TreeNode &Layer::as_node()
{
return *reinterpret_cast<TreeNode *>(this);
}
namespace convert {
void legacy_gpencil_frame_to_grease_pencil_drawing(const bGPDframe &gpf,
@ -362,14 +396,30 @@ class GreasePencilRuntime {
* Allocated and freed by the drawing code. See `DRW_grease_pencil_batch_cache_*` functions.
*/
void *batch_cache = nullptr;
bke::greasepencil::StrokeCache stroke_cache;
public:
GreasePencilRuntime() {}
~GreasePencilRuntime() {}
/**
* A buffer for a single stroke while drawing.
*/
Span<bke::greasepencil::StrokePoint> stroke_buffer() const;
bool has_stroke_buffer() const;
};
} // namespace blender::bke
inline blender::bke::greasepencil::Drawing &GreasePencilDrawing::wrap()
{
return *reinterpret_cast<blender::bke::greasepencil::Drawing *>(this);
}
inline const blender::bke::greasepencil::Drawing &GreasePencilDrawing::wrap() const
{
return *reinterpret_cast<const blender::bke::greasepencil::Drawing *>(this);
}
inline blender::bke::greasepencil::TreeNode &GreasePencilLayerTreeNode::wrap()
{
return *reinterpret_cast<blender::bke::greasepencil::TreeNode *>(this);

View File

@ -618,7 +618,7 @@ static void bvhtree_from_mesh_setup_data(BVHTree *tree,
r_data->nearest_callback = mesh_looptri_nearest_point;
r_data->raycast_callback = mesh_looptri_spherecast;
break;
case BVHTREE_FROM_EM_VERTS:
case BVHTREE_FROM_EM_LOOSEVERTS:
case BVHTREE_FROM_EM_EDGES:
case BVHTREE_FROM_EM_LOOPTRI:
case BVHTREE_MAX_ITEM:
@ -639,7 +639,7 @@ static void bvhtree_from_editmesh_setup_data(BVHTree *tree,
r_data->em = em;
switch (bvh_cache_type) {
case BVHTREE_FROM_EM_VERTS:
case BVHTREE_FROM_EM_LOOSEVERTS:
r_data->nearest_callback = nullptr;
r_data->raycast_callback = editmesh_verts_spherecast;
break;
@ -754,7 +754,7 @@ BVHTree *bvhtree_from_editmesh_verts_ex(BVHTreeFromEditMesh *data,
bvhtree_balance(tree, false);
if (data) {
bvhtree_from_editmesh_setup_data(tree, BVHTREE_FROM_EM_VERTS, em, data);
bvhtree_from_editmesh_setup_data(tree, BVHTREE_FROM_EM_LOOSEVERTS, em, data);
}
return tree;
@ -1223,7 +1223,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(BVHTreeFromMesh *data,
0.0f, tree_type, 6, positions, corner_verts.data(), looptris, {}, -1);
break;
}
case BVHTREE_FROM_EM_VERTS:
case BVHTREE_FROM_EM_LOOSEVERTS:
case BVHTREE_FROM_EM_EDGES:
case BVHTREE_FROM_EM_LOOPTRI:
case BVHTREE_MAX_ITEM:
@ -1253,6 +1253,25 @@ BVHTree *BKE_bvhtree_from_mesh_get(BVHTreeFromMesh *data,
return data->tree;
}
static BitVector<> bmverts_loose_map_get(BMesh *bm, int *r_bmvert_active_len)
{
BitVector<> bmvert_mask(bm->totvert);
int i, bmvert_loose_len = 0;
BMIter iter;
BMVert *v;
BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
if (v->e == nullptr) {
bmvert_mask[i].set();
bmvert_loose_len++;
}
}
*r_bmvert_active_len = bmvert_loose_len;
return bmvert_mask;
}
BVHTree *BKE_bvhtree_from_editmesh_get(BVHTreeFromEditMesh *data,
BMEditMesh *em,
const int tree_type,
@ -1275,9 +1294,13 @@ BVHTree *BKE_bvhtree_from_editmesh_get(BVHTreeFromEditMesh *data,
}
switch (bvh_cache_type) {
case BVHTREE_FROM_EM_VERTS:
data->tree = bvhtree_from_editmesh_verts_create_tree(0.0f, tree_type, 6, em, {}, -1);
case BVHTREE_FROM_EM_LOOSEVERTS: {
int mask_bits_act_len = -1;
const BitVector<> mask = bmverts_loose_map_get(em->bm, &mask_bits_act_len);
data->tree = bvhtree_from_editmesh_verts_create_tree(
0.0f, tree_type, 6, em, mask, mask_bits_act_len);
break;
}
case BVHTREE_FROM_EM_EDGES:
data->tree = bvhtree_from_editmesh_edges_create_tree(0.0f, tree_type, 6, em, {}, -1);
break;

View File

@ -3,6 +3,7 @@
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_array.hh"
#include "BLI_array_utils.hh"
#include "BLI_math_matrix.hh"
#include "BLI_set.hh"
#include "BLI_task.hh"
@ -364,12 +365,11 @@ static bool should_add_attribute_to_mesh(const AttributeAccessor &curve_attribut
return true;
}
static GSpan evaluated_attribute_if_necessary(const GVArray &src,
const CurvesGeometry &curves,
const std::array<int, CURVE_TYPES_NUM> &type_counts,
Vector<std::byte> &buffer)
static GSpan evaluate_attribute(const GVArray &src,
const CurvesGeometry &curves,
Vector<std::byte> &buffer)
{
if (type_counts[CURVE_TYPE_POLY] == curves.curves_num() && src.is_span()) {
if (curves.is_single_type(CURVE_TYPE_POLY) && src.is_span()) {
return src.get_internal_span();
}
buffer.reinitialize(curves.evaluated_points_num() * src.type().size());
@ -438,6 +438,51 @@ static void foreach_curve_combination(const CurvesInfo &info,
});
}
static void build_mesh_positions(const CurvesInfo &curves_info,
const ResultOffsets &offsets,
Vector<std::byte> &eval_buffer,
Mesh &mesh)
{
BLI_assert(!mesh.attributes().contains("position"));
const Span<float3> profile_positions = curves_info.profile.evaluated_positions();
const bool ignore_profile_position = profile_positions.size() == 1 &&
math::is_equal(profile_positions.first(), float3(0.0f));
if (ignore_profile_position) {
if (mesh.totvert == curves_info.main.points_num()) {
const GAttributeReader src = curves_info.main.attributes().lookup("position");
if (src.sharing_info && src.varray.is_span()) {
const AttributeInitShared init(src.varray.get_internal_span().data(), *src.sharing_info);
if (mesh.attributes_for_write().add<float3>("position", ATTR_DOMAIN_POINT, init)) {
return;
}
}
}
}
const Span<float3> main_positions = curves_info.main.evaluated_positions();
mesh.attributes_for_write().add<float3>("position", ATTR_DOMAIN_POINT, AttributeInitConstruct());
MutableSpan<float3> positions = mesh.vert_positions_for_write();
if (ignore_profile_position) {
array_utils::copy(main_positions, positions);
return;
}
const Span<float3> tangents = curves_info.main.evaluated_tangents();
const Span<float3> normals = curves_info.main.evaluated_normals();
Span<float> radii_eval = {};
if (const GVArray radii = *curves_info.main.attributes().lookup("radius", ATTR_DOMAIN_POINT)) {
radii_eval = evaluate_attribute(radii, curves_info.main, eval_buffer).typed<float>();
}
foreach_curve_combination(curves_info, offsets, [&](const CombinationInfo &info) {
fill_mesh_positions(info.main_points.size(),
info.profile_points.size(),
main_positions.slice(info.main_points),
profile_positions.slice(info.profile_points),
tangents.slice(info.main_points),
normals.slice(info.main_points),
radii_eval.is_empty() ? radii_eval : radii_eval.slice(info.main_points),
positions.slice(info.vert_range));
});
}
template<typename T>
static void copy_main_point_data_to_mesh_verts(const Span<T> src,
const int profile_point_num,
@ -475,16 +520,67 @@ static void copy_main_point_data_to_mesh_faces(const Span<T> src,
}
}
static bool try_sharing_point_data(const CurvesGeometry &main,
const AttributeIDRef &id,
const GAttributeReader &src,
MutableAttributeAccessor mesh_attributes)
{
if (mesh_attributes.domain_size(ATTR_DOMAIN_POINT) != main.points_num()) {
return false;
}
if (!src.sharing_info || !src.varray.is_span()) {
return false;
}
return mesh_attributes.add(
id,
ATTR_DOMAIN_POINT,
bke::cpp_type_to_custom_data_type(src.varray.type()),
AttributeInitShared(src.varray.get_internal_span().data(), *src.sharing_info));
}
static bool try_direct_evaluate_point_data(const CurvesGeometry &main,
const GAttributeReader &src,
GMutableSpan dst)
{
if (dst.size() != main.evaluated_points_num()) {
return false;
}
if (!src.varray.is_span()) {
return false;
}
main.interpolate_to_evaluated(src.varray.get_internal_span(), dst);
return true;
}
static void copy_main_point_domain_attribute_to_mesh(const CurvesInfo &curves_info,
const AttributeIDRef &id,
const ResultOffsets &offsets,
const eAttrDomain dst_domain,
const GSpan src_all,
GMutableSpan dst_all)
const GAttributeReader &src_attribute,
Vector<std::byte> &eval_buffer,
MutableAttributeAccessor mesh_attributes)
{
attribute_math::convert_to_static_type(src_all.type(), [&](auto dummy) {
if (dst_domain == ATTR_DOMAIN_POINT) {
if (try_sharing_point_data(curves_info.main, id, src_attribute, mesh_attributes)) {
return;
}
}
GSpanAttributeWriter dst_attribute = mesh_attributes.lookup_or_add_for_write_only_span(
id, dst_domain, bke::cpp_type_to_custom_data_type(src_attribute.varray.type()));
if (!dst_attribute) {
return;
}
if (dst_domain == ATTR_DOMAIN_POINT) {
if (try_direct_evaluate_point_data(curves_info.main, src_attribute, dst_attribute.span)) {
dst_attribute.finish();
return;
}
}
const GSpan src_all = evaluate_attribute(*src_attribute, curves_info.main, eval_buffer);
attribute_math::convert_to_static_type(src_attribute.varray.type(), [&](auto dummy) {
using T = decltype(dummy);
const Span<T> src = src_all.typed<T>();
MutableSpan<T> dst = dst_all.typed<T>();
MutableSpan<T> dst = dst_attribute.span.typed<T>();
switch (dst_domain) {
case ATTR_DOMAIN_POINT:
foreach_curve_combination(curves_info, offsets, [&](const CombinationInfo &info) {
@ -517,6 +613,7 @@ static void copy_main_point_domain_attribute_to_mesh(const CurvesInfo &curves_in
break;
}
});
dst_attribute.finish();
}
template<typename T>
@ -692,11 +789,14 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main,
return nullptr;
}
/* Add the position attribute later so it can be shared in some cases.*/
Mesh *mesh = BKE_mesh_new_nomain(
offsets.vert.last(), offsets.edge.last(), offsets.poly.last(), offsets.loop.last());
0, offsets.edge.last(), offsets.poly.last(), offsets.loop.last());
CustomData_free_layer_named(&mesh->vdata, "position", 0);
mesh->totvert = offsets.vert.last();
mesh->flag |= ME_AUTOSMOOTH;
mesh->smoothresh = DEG2RADF(180.0f);
MutableSpan<float3> positions = mesh->vert_positions_for_write();
MutableSpan<int2> edges = mesh->edges_for_write();
MutableSpan<int> poly_offsets = mesh->poly_offsets_for_write();
MutableSpan<int> corner_verts = mesh->corner_verts_for_write();
@ -736,36 +836,9 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main,
sharp_faces.finish();
}
const Span<float3> main_positions = main.evaluated_positions();
const Span<float3> tangents = main.evaluated_tangents();
const Span<float3> normals = main.evaluated_normals();
const Span<float3> profile_positions = profile.evaluated_positions();
Vector<std::byte> eval_buffer;
const AttributeAccessor main_attributes = main.attributes();
const AttributeAccessor profile_attributes = profile.attributes();
Span<float> radii = {};
if (main_attributes.contains("radius")) {
radii = evaluated_attribute_if_necessary(
*main_attributes.lookup_or_default<float>("radius", ATTR_DOMAIN_POINT, 1.0f),
main,
main.curve_type_counts(),
eval_buffer)
.typed<float>();
}
foreach_curve_combination(curves_info, offsets, [&](const CombinationInfo &info) {
fill_mesh_positions(info.main_points.size(),
info.profile_points.size(),
main_positions.slice(info.main_points),
profile_positions.slice(info.profile_points),
tangents.slice(info.main_points),
normals.slice(info.main_points),
radii.is_empty() ? radii : radii.slice(info.main_points),
positions.slice(info.vert_range));
});
build_mesh_positions(curves_info, offsets, eval_buffer, *mesh);
if (!offsets.any_single_point_main) {
/* If there are no single point curves, every combination will have at least loose edges. */
@ -800,44 +873,37 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main,
}
sharp_edges.finish();
Set<AttributeIDRef> main_attributes_set;
const AttributeAccessor main_attributes = main.attributes();
main_attributes.for_all([&](const AttributeIDRef &id, const AttributeMetaData meta_data) {
if (!should_add_attribute_to_mesh(
main_attributes, mesh_attributes, id, meta_data, propagation_info))
{
return true;
}
main_attributes_set.add_new(id);
const eAttrDomain src_domain = meta_data.domain;
const eCustomDataType type = meta_data.data_type;
const GVArray src = *main_attributes.lookup(id, src_domain, type);
const GAttributeReader src = main_attributes.lookup(id, src_domain, type);
const eAttrDomain dst_domain = get_attribute_domain_for_mesh(mesh_attributes, id);
GSpanAttributeWriter dst = mesh_attributes.lookup_or_add_for_write_only_span(
id, dst_domain, type);
if (!dst) {
return true;
}
if (src_domain == ATTR_DOMAIN_POINT) {
copy_main_point_domain_attribute_to_mesh(
curves_info,
offsets,
dst_domain,
evaluated_attribute_if_necessary(src, main, main.curve_type_counts(), eval_buffer),
dst.span);
curves_info, id, offsets, dst_domain, src, eval_buffer, mesh_attributes);
}
else if (src_domain == ATTR_DOMAIN_CURVE) {
copy_curve_domain_attribute_to_mesh(
offsets, offsets.main_indices, dst_domain, src, dst.span);
GSpanAttributeWriter dst = mesh_attributes.lookup_or_add_for_write_only_span(
id, dst_domain, type);
if (dst) {
copy_curve_domain_attribute_to_mesh(
offsets, offsets.main_indices, dst_domain, *src, dst.span);
}
dst.finish();
}
dst.finish();
return true;
});
const AttributeAccessor profile_attributes = profile.attributes();
profile_attributes.for_all([&](const AttributeIDRef &id, const AttributeMetaData meta_data) {
if (main_attributes.contains(id)) {
return true;
@ -859,12 +925,11 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main,
}
if (src_domain == ATTR_DOMAIN_POINT) {
copy_profile_point_domain_attribute_to_mesh(
curves_info,
offsets,
dst_domain,
evaluated_attribute_if_necessary(src, profile, profile.curve_type_counts(), eval_buffer),
dst.span);
copy_profile_point_domain_attribute_to_mesh(curves_info,
offsets,
dst_domain,
evaluate_attribute(src, profile, eval_buffer),
dst.span);
}
else if (src_domain == ATTR_DOMAIN_CURVE) {
copy_curve_domain_attribute_to_mesh(
@ -882,7 +947,7 @@ static CurvesGeometry get_curve_single_vert()
{
CurvesGeometry curves(1, 1);
curves.offsets_for_write().last() = 1;
curves.positions_for_write().fill(float3(0));
curves.positions_for_write().fill(float3(0.0f));
curves.fill_curve_types(CURVE_TYPE_POLY);
return curves;

View File

@ -82,16 +82,7 @@ static void grease_pencil_copy_data(Main * /*bmain*/,
const GreasePencilDrawing *src_drawing = reinterpret_cast<const GreasePencilDrawing *>(
src_drawing_base);
grease_pencil_dst->drawing_array[i] = reinterpret_cast<GreasePencilDrawingBase *>(
MEM_cnew<GreasePencilDrawing>(__func__));
GreasePencilDrawing *dst_drawing = reinterpret_cast<GreasePencilDrawing *>(
grease_pencil_dst->drawing_array[i]);
dst_drawing->base.type = src_drawing->base.type;
dst_drawing->base.flag = src_drawing->base.flag;
new (&dst_drawing->geometry) bke::CurvesGeometry(src_drawing->geometry.wrap());
dst_drawing->runtime = MEM_new<bke::greasepencil::DrawingRuntime>(__func__);
dst_drawing->runtime->triangles_cache = src_drawing->runtime->triangles_cache;
MEM_new<bke::greasepencil::Drawing>(__func__, src_drawing->wrap()));
break;
}
case GP_DRAWING_REFERENCE: {
@ -141,8 +132,7 @@ static void grease_pencil_foreach_id(ID *id, LibraryForeachIDData *data)
for (int i = 0; i < grease_pencil->material_array_num; i++) {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, grease_pencil->material_array[i], IDWALK_CB_USER);
}
for (int i = 0; i < grease_pencil->drawing_array_num; i++) {
GreasePencilDrawingBase *drawing_base = grease_pencil->drawing_array[i];
for (GreasePencilDrawingBase *drawing_base : grease_pencil->drawings()) {
if (drawing_base->type == GP_DRAWING_REFERENCE) {
GreasePencilDrawingReference *drawing_reference =
reinterpret_cast<GreasePencilDrawingReference *>(drawing_base);
@ -234,7 +224,7 @@ IDTypeInfo IDType_ID_GP = {
/*main_listbase_index*/ INDEX_ID_GP,
/*struct_size*/ sizeof(GreasePencil),
/*name*/ "GreasePencil",
/*name_plural*/ "grease_pencils_new",
/*name_plural*/ "grease_pencils_v3",
/*translation_context*/ BLT_I18NCONTEXT_ID_GPENCIL,
/*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE,
/*asset_type_info*/ nullptr,
@ -260,6 +250,102 @@ IDTypeInfo IDType_ID_GP = {
namespace blender::bke::greasepencil {
Drawing::Drawing()
{
this->base.type = GP_DRAWING;
this->base.flag = 0;
new (&this->geometry) bke::CurvesGeometry();
/* Initialize runtime data. */
this->runtime = MEM_new<bke::greasepencil::DrawingRuntime>(__func__);
}
Drawing::Drawing(const Drawing &other) : Drawing()
{
this->base.flag = other.base.flag;
new (&this->geometry) bke::CurvesGeometry(other.geometry.wrap());
this->runtime->triangles_cache = other.runtime->triangles_cache;
}
Drawing::~Drawing()
{
this->geometry.wrap().~CurvesGeometry();
MEM_delete(this->runtime);
this->runtime = nullptr;
}
Span<uint3> Drawing::triangles() const
{
this->runtime->triangles_cache.ensure([&](Vector<uint3> &r_data) {
MemArena *pf_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
const CurvesGeometry &curves = this->geometry.wrap();
const Span<float3> positions = curves.positions();
const OffsetIndices<int> points_by_curve = curves.points_by_curve();
int total_triangles = 0;
Array<int> tris_offests(curves.curves_num());
for (int curve_i : curves.curves_range()) {
IndexRange points = points_by_curve[curve_i];
if (points.size() > 2) {
tris_offests[curve_i] = total_triangles;
total_triangles += points.size() - 2;
}
}
r_data.resize(total_triangles);
/* TODO: use threading. */
for (const int curve_i : curves.curves_range()) {
const IndexRange points = points_by_curve[curve_i];
if (points.size() < 3) {
continue;
}
const int num_triangles = points.size() - 2;
MutableSpan<uint3> r_tris = r_data.as_mutable_span().slice(tris_offests[curve_i],
num_triangles);
float(*projverts)[2] = static_cast<float(*)[2]>(
BLI_memarena_alloc(pf_arena, sizeof(*projverts) * size_t(points.size())));
/* TODO: calculate axis_mat properly. */
float3x3 axis_mat;
axis_dominant_v3_to_m3(axis_mat.ptr(), float3(0.0f, -1.0f, 0.0f));
for (const int i : IndexRange(points.size())) {
mul_v2_m3v3(projverts[i], axis_mat.ptr(), positions[points[i]]);
}
BLI_polyfill_calc_arena(
projverts, points.size(), 0, reinterpret_cast<uint32_t(*)[3]>(r_tris.data()), pf_arena);
BLI_memarena_clear(pf_arena);
}
BLI_memarena_free(pf_arena);
});
return this->runtime->triangles_cache.data().as_span();
}
const bke::CurvesGeometry &Drawing::strokes() const
{
return this->geometry.wrap();
}
bke::CurvesGeometry &Drawing::strokes_for_write()
{
return this->geometry.wrap();
}
void Drawing::tag_positions_changed()
{
this->geometry.wrap().tag_positions_changed();
this->runtime->triangles_cache.tag_dirty();
}
TreeNode::TreeNode()
{
this->next = this->prev = nullptr;
@ -545,6 +631,23 @@ LayerGroup &LayerGroup::add_group(StringRefNull name)
return this->add_group(new_group);
}
LayerGroup &LayerGroup::add_group_after(LayerGroup *group, TreeNode *link)
{
BLI_assert(group != nullptr && link != nullptr);
BLI_insertlinkafter(&this->children,
reinterpret_cast<GreasePencilLayerTreeNode *>(link),
reinterpret_cast<GreasePencilLayerTreeNode *>(group));
group->base.parent = reinterpret_cast<GreasePencilLayerTreeGroup *>(this);
this->tag_nodes_cache_dirty();
return *group;
}
LayerGroup &LayerGroup::add_group_after(StringRefNull name, TreeNode *link)
{
LayerGroup *new_group = MEM_new<LayerGroup>(__func__, name);
return this->add_group_after(new_group, link);
}
Layer &LayerGroup::add_layer(Layer *layer)
{
BLI_assert(layer != nullptr);
@ -891,80 +994,18 @@ void BKE_grease_pencil_batch_cache_free(GreasePencil *grease_pencil)
/** \} */
/* ------------------------------------------------------------------- */
/** \name Grease Pencil Drawing API
/** \name Grease Pencil runtime API
* \{ */
blender::Span<blender::uint3> GreasePencilDrawing::triangles() const
bool blender::bke::GreasePencilRuntime::has_stroke_buffer() const
{
using namespace blender;
const bke::greasepencil::DrawingRuntime &runtime = *this->runtime;
runtime.triangles_cache.ensure([&](Vector<uint3> &r_data) {
MemArena *pf_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
const bke::CurvesGeometry &curves = this->geometry.wrap();
const Span<float3> positions = curves.positions();
const OffsetIndices<int> points_by_curve = curves.points_by_curve();
int total_triangles = 0;
Array<int> tris_offests(curves.curves_num());
for (int curve_i : curves.curves_range()) {
IndexRange points = points_by_curve[curve_i];
if (points.size() > 2) {
tris_offests[curve_i] = total_triangles;
total_triangles += points.size() - 2;
}
}
r_data.resize(total_triangles);
/* TODO: use threading. */
for (const int curve_i : curves.curves_range()) {
const IndexRange points = points_by_curve[curve_i];
if (points.size() < 3) {
continue;
}
const int num_trinagles = points.size() - 2;
MutableSpan<uint3> r_tris = r_data.as_mutable_span().slice(tris_offests[curve_i],
num_trinagles);
float(*projverts)[2] = static_cast<float(*)[2]>(
BLI_memarena_alloc(pf_arena, sizeof(*projverts) * size_t(points.size())));
/* TODO: calculate axis_mat properly. */
float3x3 axis_mat;
axis_dominant_v3_to_m3(axis_mat.ptr(), float3(0.0f, -1.0f, 0.0f));
for (const int i : IndexRange(points.size())) {
mul_v2_m3v3(projverts[i], axis_mat.ptr(), positions[points[i]]);
}
BLI_polyfill_calc_arena(
projverts, points.size(), 0, reinterpret_cast<uint32_t(*)[3]>(r_tris.data()), pf_arena);
BLI_memarena_clear(pf_arena);
}
BLI_memarena_free(pf_arena);
});
return this->runtime->triangles_cache.data().as_span();
return this->stroke_cache.points.size() > 0;
}
void GreasePencilDrawing::tag_positions_changed()
blender::Span<blender::bke::greasepencil::StrokePoint> blender::bke::GreasePencilRuntime::
stroke_buffer() const
{
this->geometry.wrap().tag_positions_changed();
this->runtime->triangles_cache.tag_dirty();
}
bool GreasePencilDrawing::has_stroke_buffer() const
{
return this->runtime->stroke_cache.points.size() > 0;
}
blender::Span<blender::bke::greasepencil::StrokePoint> GreasePencilDrawing::stroke_buffer() const
{
return this->runtime->stroke_cache.points.as_span();
return this->stroke_cache.points.as_span();
}
/** \} */
@ -1018,10 +1059,7 @@ void GreasePencil::add_empty_drawings(const int add_num)
prev_num);
for (const int i : new_drawings.index_range()) {
new_drawings[i] = reinterpret_cast<GreasePencilDrawingBase *>(
MEM_new<GreasePencilDrawing>(__func__));
GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(new_drawings[i]);
new (&drawing->geometry) bke::CurvesGeometry();
drawing->runtime = MEM_new<bke::greasepencil::DrawingRuntime>(__func__);
MEM_new<blender::bke::greasepencil::Drawing>(__func__));
}
/* TODO: Update drawing user counts. */
@ -1066,10 +1104,7 @@ void GreasePencil::remove_drawing(const int index_to_remove)
case GP_DRAWING: {
GreasePencilDrawing *drawing_to_remove = reinterpret_cast<GreasePencilDrawing *>(
drawing_base_to_remove);
drawing_to_remove->geometry.wrap().~CurvesGeometry();
MEM_delete(drawing_to_remove->runtime);
drawing_to_remove->runtime = nullptr;
MEM_freeN(drawing_to_remove);
MEM_delete(&drawing_to_remove->wrap());
break;
}
case GP_DRAWING_REFERENCE: {
@ -1100,10 +1135,11 @@ enum ForeachDrawingMode {
EDITABLE,
};
static void foreach_drawing_ex(GreasePencil &grease_pencil,
int frame,
ForeachDrawingMode mode,
blender::FunctionRef<void(int, GreasePencilDrawing &)> function)
static void foreach_drawing_ex(
GreasePencil &grease_pencil,
int frame,
ForeachDrawingMode mode,
blender::FunctionRef<void(int, blender::bke::greasepencil::Drawing &)> function)
{
using namespace blender::bke::greasepencil;
@ -1131,7 +1167,7 @@ static void foreach_drawing_ex(GreasePencil &grease_pencil,
GreasePencilDrawingBase *drawing_base = drawings[index];
if (drawing_base->type == GP_DRAWING) {
GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(drawing_base);
function(index, *drawing);
function(index, drawing->wrap());
}
else if (drawing_base->type == GP_DRAWING_REFERENCE) {
/* TODO */
@ -1140,13 +1176,13 @@ static void foreach_drawing_ex(GreasePencil &grease_pencil,
}
void GreasePencil::foreach_visible_drawing(
int frame, blender::FunctionRef<void(int, GreasePencilDrawing &)> function)
int frame, blender::FunctionRef<void(int, blender::bke::greasepencil::Drawing &)> function)
{
foreach_drawing_ex(*this, frame, VISIBLE, function);
}
void GreasePencil::foreach_editable_drawing(
int frame, blender::FunctionRef<void(int, GreasePencilDrawing &)> function)
int frame, blender::FunctionRef<void(int, blender::bke::greasepencil::Drawing &)> function)
{
foreach_drawing_ex(*this, frame, EDITABLE, function);
}
@ -1226,7 +1262,7 @@ static blender::VectorSet<blender::StringRefNull> get_node_names(GreasePencil &g
return names;
}
static bool check_unique_layer_cb(void *arg, const char *name)
static bool check_unique_node_cb(void *arg, const char *name)
{
using namespace blender;
VectorSet<StringRefNull> &names = *reinterpret_cast<VectorSet<StringRefNull> *>(arg);
@ -1235,7 +1271,12 @@ static bool check_unique_layer_cb(void *arg, const char *name)
static bool unique_layer_name(VectorSet<blender::StringRefNull> &names, char *name)
{
return BLI_uniquename_cb(check_unique_layer_cb, &names, "GP_Layer", '.', name, MAX_NAME);
return BLI_uniquename_cb(check_unique_node_cb, &names, "GP_Layer", '.', name, MAX_NAME);
}
static bool unique_layer_group_name(VectorSet<blender::StringRefNull> &names, char *name)
{
return BLI_uniquename_cb(check_unique_node_cb, &names, "GP_Group", '.', name, MAX_NAME);
}
blender::bke::greasepencil::Layer &GreasePencil::add_layer(
@ -1265,6 +1306,34 @@ blender::bke::greasepencil::Layer &GreasePencil::add_layer(const blender::String
return this->add_layer(this->root_group.wrap(), name);
}
blender::bke::greasepencil::LayerGroup &GreasePencil::add_layer_group(
blender::bke::greasepencil::LayerGroup &group, const blender::StringRefNull name)
{
using namespace blender;
VectorSet<StringRefNull> names = get_node_names(*this);
std::string unique_name(name.c_str());
unique_layer_group_name(names, unique_name.data());
return group.add_group(unique_name);
}
blender::bke::greasepencil::LayerGroup &GreasePencil::add_layer_group_after(
blender::bke::greasepencil::LayerGroup &group,
blender::bke::greasepencil::TreeNode *node,
const blender::StringRefNull name)
{
using namespace blender;
VectorSet<StringRefNull> names = get_node_names(*this);
std::string unique_name(name.c_str());
unique_layer_group_name(names, unique_name.data());
return group.add_group_after(unique_name, node);
}
blender::bke::greasepencil::LayerGroup &GreasePencil::add_layer_group(
const blender::StringRefNull name)
{
return this->add_layer_group(this->root_group.wrap(), name);
}
const blender::bke::greasepencil::Layer *GreasePencil::find_layer_by_name(
const blender::StringRefNull name) const
{
@ -1394,10 +1463,7 @@ void GreasePencil::free_drawing_array()
switch (drawing_base->type) {
case GP_DRAWING: {
GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(drawing_base);
drawing->geometry.wrap().~CurvesGeometry();
MEM_delete(drawing->runtime);
drawing->runtime = nullptr;
MEM_freeN(drawing);
MEM_delete(&drawing->wrap());
break;
}
case GP_DRAWING_REFERENCE: {

View File

@ -675,7 +675,7 @@ static void ptcache_dynamicpaint_error(const ID *UNUSED(owner_id),
static int ptcache_dynamicpaint_write(PTCacheFile *pf, void *dp_v)
{
DynamicPaintSurface *surface = (DynamicPaintSurface *)dp_v;
int cache_compress = 1;
int cache_compress = PTCACHE_COMPRESS_LZO;
/* version header */
ptcache_file_write(pf, DPAINT_CACHE_VERSION, 1, sizeof(char[4]));
@ -1560,7 +1560,7 @@ static int ptcache_file_compressed_write(
#ifdef WITH_LZO
out_len = LZO_OUT_LEN(in_len);
if (mode == 1) {
if (mode == PTCACHE_COMPRESS_LZO) {
LZO_HEAP_ALLOC(wrkmem, LZO1X_MEM_COMPRESS);
r = lzo1x_1_compress(in, (lzo_uint)in_len, out, (lzo_uint *)&out_len, wrkmem);
@ -1573,7 +1573,7 @@ static int ptcache_file_compressed_write(
}
#endif
#ifdef WITH_LZMA
if (mode == 2) {
if (mode == PTCACHE_COMPRESS_LZMA) {
r = LzmaCompress(out,
&out_len,

View File

@ -670,7 +670,7 @@ static bool do_versions_sequencer_init_retiming_tool_data(Sequence *seq, void *u
const int content_length = SEQ_time_strip_length_get(scene, seq);
SEQ_retiming_data_ensure(seq);
SEQ_retiming_data_ensure(scene, seq);
SeqRetimingHandle *handle = &seq->retiming_handles[seq->retiming_handle_num - 1];
handle->strip_frame_index = round_fl_to_int(content_length / seq->speed_factor);

View File

@ -651,8 +651,10 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
/* Post Process */
EEVEE_draw_effects(sldata, vedata);
/* XXX Seems to fix TDR issue with NVidia drivers on linux. */
GPU_finish();
/* NOTE(@fclem): Seems to fix TDR issue with NVidia drivers. */
if (GPU_type_matches_ex(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY, GPU_BACKEND_OPENGL)) {
GPU_finish();
}
/* Perform render step between samples to allow
* flushing of freed GPUBackend resources. */

View File

@ -401,7 +401,8 @@ void OVERLAY_image_empty_cache_populate(OVERLAY_Data *vedata, Object *ob)
}
/* Use the actual depth if we are doing depth tests to determine the distance to the object */
char depth_mode = DRW_state_is_depth() ? OB_EMPTY_IMAGE_DEPTH_DEFAULT : ob->empty_image_depth;
char depth_mode = DRW_state_is_depth() ? char(OB_EMPTY_IMAGE_DEPTH_DEFAULT) :
ob->empty_image_depth;
DRWPass *pass = nullptr;
if ((ob->dtx & OB_DRAW_IN_FRONT) != 0) {
/* Object In Front overrides image empty depth mode. */

View File

@ -189,6 +189,7 @@ BLI_INLINE int32_t pack_rotation_aspect_hardness(float rot, float asp, float har
static void grease_pencil_geom_batch_ensure(GreasePencil &grease_pencil, int cfra)
{
using namespace blender::bke::greasepencil;
BLI_assert(grease_pencil.runtime != nullptr);
GreasePencilBatchCache *cache = static_cast<GreasePencilBatchCache *>(
grease_pencil.runtime->batch_cache);
@ -202,10 +203,9 @@ static void grease_pencil_geom_batch_ensure(GreasePencil &grease_pencil, int cfr
BLI_assert(cache->geom_batch == nullptr);
/* Get the visible drawings. */
Vector<const GreasePencilDrawing *> drawings;
Vector<Drawing *> drawings;
grease_pencil.foreach_visible_drawing(
cfra,
[&](int /*drawing_index*/, GreasePencilDrawing &drawing) { drawings.append(&drawing); });
cfra, [&](int /*drawing_index*/, Drawing &drawing) { drawings.append(&drawing); });
/* First, count how many vertices and triangles are needed for the whole object. Also record the
* offsets into the curves for the vertices and triangles. */
@ -215,19 +215,13 @@ static void grease_pencil_geom_batch_ensure(GreasePencil &grease_pencil, int cfr
int v_offset = 0;
Vector<Array<int>> verts_start_offsets_per_visible_drawing;
Vector<Array<int>> tris_start_offsets_per_visible_drawing;
for (const int drawing_i : drawings.index_range()) {
const GreasePencilDrawing &drawing = *drawings[drawing_i];
const bke::CurvesGeometry &curves = drawing.geometry.wrap();
for (const Drawing *drawing : drawings) {
const bke::CurvesGeometry &curves = drawing->strokes();
const OffsetIndices<int> points_by_curve = curves.points_by_curve();
const VArray<bool> cyclic = curves.cyclic();
int verts_start_offsets_size = curves.curves_num();
int tris_start_offsets_size = curves.curves_num();
if (drawing.has_stroke_buffer()) {
verts_start_offsets_size++;
/* TODO: triangles for stroke buffer. */
// tris_start_offsets_size++;
}
Array<int> verts_start_offsets(verts_start_offsets_size);
Array<int> tris_start_offsets(tris_start_offsets_size);
@ -257,21 +251,19 @@ static void grease_pencil_geom_batch_ensure(GreasePencil &grease_pencil, int cfr
* vertex.*/
total_verts_num += curves.points_num() + num_cyclic + curves.curves_num() * 2;
total_triangles_num += (curves.points_num() + num_cyclic) * 2;
total_triangles_num += drawing.triangles().size();
if (drawing.has_stroke_buffer()) {
const int num_buffer_points = drawing.stroke_buffer().size();
total_verts_num += 1 + num_buffer_points + 1;
total_triangles_num += num_buffer_points * 2;
verts_start_offsets[curves.curves_range().size()] = v_offset;
/* TODO: triangles for stroke buffer. */
v_offset += 1 + num_buffer_points + 1;
}
total_triangles_num += drawing->triangles().size();
verts_start_offsets_per_visible_drawing.append(std::move(verts_start_offsets));
tris_start_offsets_per_visible_drawing.append(std::move(tris_start_offsets));
}
if (grease_pencil.runtime->has_stroke_buffer()) {
const int num_buffer_points = grease_pencil.runtime->stroke_buffer().size();
total_verts_num += 1 + num_buffer_points + 1;
total_triangles_num += num_buffer_points * 2;
/* TODO: triangles for stroke buffer. */
}
static GPUVertFormat format_edit_points_pos = {0};
if (format_edit_points_pos.attr_len == 0) {
GPU_vertformat_attr_add(&format_edit_points_pos, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
@ -317,8 +309,8 @@ static void grease_pencil_geom_batch_ensure(GreasePencil &grease_pencil, int cfr
/* Fill buffers with data. */
int drawing_start_offset = 0;
for (const int drawing_i : drawings.index_range()) {
const GreasePencilDrawing &drawing = *drawings[drawing_i];
const bke::CurvesGeometry &curves = drawing.geometry.wrap();
const Drawing &drawing = *drawings[drawing_i];
const bke::CurvesGeometry &curves = drawing.strokes();
const bke::AttributeAccessor attributes = curves.attributes();
const OffsetIndices<int> points_by_curve = curves.points_by_curve();
const Span<float3> positions = curves.positions();
@ -433,51 +425,51 @@ static void grease_pencil_geom_batch_ensure(GreasePencil &grease_pencil, int cfr
verts_slice.last().mat = -1;
}
});
}
if (drawing.has_stroke_buffer()) {
Span<bke::greasepencil::StrokePoint> points = drawing.stroke_buffer();
const int verts_start_offset = verts_start_offsets.last();
const int num_verts = 1 + points.size() + 1;
IndexRange verts_range = IndexRange(verts_start_offset, num_verts);
MutableSpan<GreasePencilStrokeVert> verts_slice = verts.slice(verts_range);
MutableSpan<GreasePencilColorVert> cols_slice = cols.slice(verts_range);
const int material_nr = drawing.runtime->stroke_cache.mat;
if (grease_pencil.runtime->has_stroke_buffer()) {
Span<bke::greasepencil::StrokePoint> points = grease_pencil.runtime->stroke_buffer();
const int verts_start_offset = v_offset;
const int num_verts = 1 + points.size() + 1;
IndexRange verts_range = IndexRange(verts_start_offset, num_verts);
MutableSpan<GreasePencilStrokeVert> verts_slice = verts.slice(verts_range);
MutableSpan<GreasePencilColorVert> cols_slice = cols.slice(verts_range);
const int material_nr = grease_pencil.runtime->stroke_cache.mat;
verts_slice.first().mat = -1;
for (const int i : IndexRange(points.size())) {
const int idx = i + 1;
GreasePencilStrokeVert &s_vert = verts_slice[idx];
GreasePencilColorVert &c_vert = cols_slice[idx];
const bke::greasepencil::StrokePoint &point = points[i];
verts_slice.first().mat = -1;
for (const int i : IndexRange(points.size())) {
const int idx = i + 1;
GreasePencilStrokeVert &s_vert = verts_slice[idx];
GreasePencilColorVert &c_vert = cols_slice[idx];
const bke::greasepencil::StrokePoint &point = points[i];
copy_v3_v3(s_vert.pos, point.position);
s_vert.radius = point.radius;
s_vert.opacity = point.opacity;
s_vert.point_id = verts_range[idx];
s_vert.stroke_id = verts_range.first();
s_vert.mat = material_nr;
copy_v3_v3(s_vert.pos, point.position);
s_vert.radius = point.radius;
s_vert.opacity = point.opacity;
s_vert.point_id = verts_range[idx];
s_vert.stroke_id = verts_range.first();
s_vert.mat = material_nr;
/* TODO */
s_vert.packed_asp_hard_rot = pack_rotation_aspect_hardness(0.0f, 1.0f, 1.0f);
/* TODO */
s_vert.u_stroke = 0;
/* TODO */
s_vert.uv_fill[0] = s_vert.uv_fill[1] = 0;
/* TODO */
s_vert.packed_asp_hard_rot = pack_rotation_aspect_hardness(0.0f, 1.0f, 1.0f);
/* TODO */
s_vert.u_stroke = 0;
/* TODO */
s_vert.uv_fill[0] = s_vert.uv_fill[1] = 0;
/* TODO */
copy_v4_v4(c_vert.vcol, float4(0.0f, 0.0f, 0.0f, 0.0f));
copy_v4_v4(c_vert.fcol, float4(0.0f, 0.0f, 0.0f, 0.0f));
/* TODO */
copy_v4_v4(c_vert.vcol, float4(0.0f, 0.0f, 0.0f, 0.0f));
copy_v4_v4(c_vert.fcol, float4(0.0f, 0.0f, 0.0f, 0.0f));
/* TODO */
c_vert.fcol[3] = (int(c_vert.fcol[3] * 10000.0f) * 10.0f) + 1.0f;
/* TODO */
c_vert.fcol[3] = (int(c_vert.fcol[3] * 10000.0f) * 10.0f) + 1.0f;
int v_mat = (verts_range[idx] << GP_VERTEX_ID_SHIFT) | GP_IS_STROKE_VERTEX_BIT;
GPU_indexbuf_add_tri_verts(&ibo, v_mat + 0, v_mat + 1, v_mat + 2);
GPU_indexbuf_add_tri_verts(&ibo, v_mat + 2, v_mat + 1, v_mat + 3);
}
verts_slice.last().mat = -1;
int v_mat = (verts_range[idx] << GP_VERTEX_ID_SHIFT) | GP_IS_STROKE_VERTEX_BIT;
GPU_indexbuf_add_tri_verts(&ibo, v_mat + 0, v_mat + 1, v_mat + 2);
GPU_indexbuf_add_tri_verts(&ibo, v_mat + 2, v_mat + 1, v_mat + 3);
}
verts_slice.last().mat = -1;
}
/* Mark last 2 verts as invalid. */

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup draw
@ -150,7 +152,7 @@ static Vector<SculptBatch> sculpt_batches_get_ex(
Vector<SculptBatch> sculpt_batches_get(Object *ob, SculptBatchFeature features)
{
PBVHAttrReq attrs[16] = {0};
PBVHAttrReq attrs[16] = {};
int attrs_len = 0;
/* NOTE: these are NOT #eCustomDataType, they are extended values, ASAN may warn about this. */
@ -203,7 +205,7 @@ Vector<SculptBatch> sculpt_batches_per_material_get(Object *ob,
DRW_mesh_get_attributes(ob, mesh, materials.data(), materials.size(), &draw_attrs, &cd_needed);
PBVHAttrReq attrs[16] = {0};
PBVHAttrReq attrs[16] = {};
int attrs_len = 0;
/* NOTE: these are NOT #eCustomDataType, they are extended values, ASAN may warn about this. */

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup draw

View File

@ -11,7 +11,7 @@
#pragma once
#define GPU_INFO_SIZE 512 /* IMA_MAX_RENDER_TEXT */
#define GPU_INFO_SIZE 512 /* IMA_MAX_RENDER_TEXT_SIZE */
#ifdef __cplusplus
extern "C" {

View File

@ -214,7 +214,7 @@ static void snap_cursor_init(SnapGizmo3D *snap_gizmo)
snap_gizmo->snap_state->draw_point = true;
snap_gizmo->snap_state->draw_plane = false;
rgba_float_to_uchar(snap_gizmo->snap_state->color_point, snap_gizmo->gizmo.color);
rgba_float_to_uchar(snap_gizmo->snap_state->target_color, snap_gizmo->gizmo.color);
snap_gizmo->snap_state->poll = snap_cursor_poll;
snap_gizmo->snap_state->poll_data = snap_gizmo;

View File

@ -4345,6 +4345,8 @@ void GPENCIL_OT_stroke_outline(wmOperatorType *ot)
/* properties */
ot->prop = RNA_def_enum(ot->srna, "view_mode", view_mode, GP_PERIMETER_VIEW, "View", "");
RNA_def_property_translation_context(ot->prop, BLT_I18NCONTEXT_EDITOR_VIEW3D);
RNA_def_enum(ot->srna,
"material_mode",
material_mode,

View File

@ -16,6 +16,8 @@
#include "RNA_access.h"
#include "RNA_define.h"
#include "DNA_scene_types.h"
#include "WM_api.h"
namespace blender::ed::greasepencil {
@ -24,21 +26,27 @@ static int grease_pencil_layer_add_exec(bContext *C, wmOperator *op)
{
using namespace blender::bke::greasepencil;
Object *object = CTX_data_active_object(C);
Scene *scene = CTX_data_scene(C);
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
int new_layer_name_length;
char *new_layer_name = RNA_string_get_alloc(
op->ptr, "new_layer_name", nullptr, 0, &new_layer_name_length);
grease_pencil.add_empty_drawings(1);
GreasePencilFrame frame{int(grease_pencil.drawings().size() - 1), 0, BEZT_KEYTYPE_KEYFRAME};
if (grease_pencil.has_active_layer()) {
LayerGroup &active_group = grease_pencil.get_active_layer()->parent_group();
Layer &new_layer = grease_pencil.add_layer_after(
active_group, grease_pencil.get_active_layer_for_write(), new_layer_name);
grease_pencil.set_active_layer(&new_layer);
new_layer.insert_frame(scene->r.cfra, frame);
}
else {
Layer &new_layer = grease_pencil.add_layer(new_layer_name);
grease_pencil.set_active_layer(&new_layer);
new_layer.insert_frame(scene->r.cfra, frame);
}
MEM_SAFE_FREE(new_layer_name);
@ -54,7 +62,7 @@ static void GREASE_PENCIL_OT_layer_add(wmOperatorType *ot)
/* identifiers */
ot->name = "Add New Layer";
ot->idname = "GREASE_PENCIL_OT_layer_add";
ot->description = "Add new a new Grease Pencil layer in the active object";
ot->description = "Add a new Grease Pencil layer in the active object";
/* callbacks */
ot->exec = grease_pencil_layer_add_exec;
@ -146,6 +154,8 @@ static int grease_pencil_layer_reorder_exec(bContext *C, wmOperator *op)
BLI_assert_unreachable();
}
MEM_SAFE_FREE(target_layer_name);
DEG_id_tag_update(&grease_pencil.id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, &grease_pencil);
@ -177,6 +187,57 @@ static void GREASE_PENCIL_OT_layer_reorder(wmOperatorType *ot)
ot->srna, "location", prop_layer_reorder_location, LAYER_REORDER_ABOVE, "Location", "");
}
static int grease_pencil_layer_group_add_exec(bContext *C, wmOperator *op)
{
using namespace blender::bke::greasepencil;
Object *object = CTX_data_active_object(C);
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
int new_layer_group_name_length;
char *new_layer_group_name = RNA_string_get_alloc(
op->ptr, "new_layer_group_name", nullptr, 0, &new_layer_group_name_length);
if (grease_pencil.has_active_layer()) {
LayerGroup &active_group = grease_pencil.get_active_layer()->parent_group();
grease_pencil.add_layer_group_after(active_group,
&grease_pencil.get_active_layer_for_write()->as_node(),
new_layer_group_name);
}
else {
grease_pencil.add_layer_group(new_layer_group_name);
}
MEM_SAFE_FREE(new_layer_group_name);
DEG_id_tag_update(&grease_pencil.id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, &grease_pencil);
return OPERATOR_FINISHED;
}
static void GREASE_PENCIL_OT_layer_group_add(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Add New Layer Group";
ot->idname = "GREASE_PENCIL_OT_layer_group_add";
ot->description = "Add a new Grease Pencil layer group in the active object";
/* callbacks */
ot->exec = grease_pencil_layer_group_add_exec;
ot->poll = active_grease_pencil_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
PropertyRNA *prop = RNA_def_string(ot->srna,
"new_layer_group_name",
"GP_Group",
INT16_MAX,
"Name",
"Name of the new layer group");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
ot->prop = prop;
}
} // namespace blender::ed::greasepencil
void ED_operatortypes_grease_pencil_layers(void)
@ -185,4 +246,6 @@ void ED_operatortypes_grease_pencil_layers(void)
WM_operatortype_append(GREASE_PENCIL_OT_layer_add);
WM_operatortype_append(GREASE_PENCIL_OT_layer_remove);
WM_operatortype_append(GREASE_PENCIL_OT_layer_reorder);
WM_operatortype_append(GREASE_PENCIL_OT_layer_group_add);
}

View File

@ -37,8 +37,8 @@ static int select_all_exec(bContext *C, wmOperator *op)
eAttrDomain selection_domain = ED_grease_pencil_selection_domain_get(C);
grease_pencil.foreach_editable_drawing(
scene->r.cfra, [&](int /*drawing_index*/, GreasePencilDrawing &drawing) {
blender::ed::curves::select_all(drawing.geometry.wrap(), selection_domain, action);
scene->r.cfra, [&](int /*drawing_index*/, blender::bke::greasepencil::Drawing &drawing) {
blender::ed::curves::select_all(drawing.strokes_for_write(), selection_domain, action);
});
/* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic
@ -70,8 +70,8 @@ static int select_more_exec(bContext *C, wmOperator * /*op*/)
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
grease_pencil.foreach_editable_drawing(
scene->r.cfra, [](int /*drawing_index*/, GreasePencilDrawing &drawing) {
blender::ed::curves::select_adjacent(drawing.geometry.wrap(), false);
scene->r.cfra, [](int /*drawing_index*/, blender::bke::greasepencil::Drawing &drawing) {
blender::ed::curves::select_adjacent(drawing.strokes_for_write(), false);
});
/* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic
@ -101,8 +101,8 @@ static int select_less_exec(bContext *C, wmOperator * /*op*/)
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
grease_pencil.foreach_editable_drawing(
scene->r.cfra, [](int /*drawing_index*/, GreasePencilDrawing &drawing) {
blender::ed::curves::select_adjacent(drawing.geometry.wrap(), true);
scene->r.cfra, [](int /*drawing_index*/, blender::bke::greasepencil::Drawing &drawing) {
blender::ed::curves::select_adjacent(drawing.strokes_for_write(), true);
});
/* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic
@ -132,8 +132,8 @@ static int select_linked_exec(bContext *C, wmOperator * /*op*/)
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
grease_pencil.foreach_editable_drawing(
scene->r.cfra, [](int /*drawing_index*/, GreasePencilDrawing &drawing) {
blender::ed::curves::select_linked(drawing.geometry.wrap());
scene->r.cfra, [](int /*drawing_index*/, blender::bke::greasepencil::Drawing &drawing) {
blender::ed::curves::select_linked(drawing.strokes_for_write());
});
/* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic
@ -166,8 +166,8 @@ static int select_random_exec(bContext *C, wmOperator *op)
eAttrDomain selection_domain = ED_grease_pencil_selection_domain_get(C);
grease_pencil.foreach_editable_drawing(
scene->r.cfra, [&](int drawing_index, GreasePencilDrawing &drawing) {
blender::ed::curves::select_random(drawing.geometry.wrap(),
scene->r.cfra, [&](int drawing_index, blender::bke::greasepencil::Drawing &drawing) {
blender::ed::curves::select_random(drawing.strokes_for_write(),
selection_domain,
blender::get_default_hash_2<int>(seed, drawing_index),
ratio);
@ -203,8 +203,8 @@ static int select_alternate_exec(bContext *C, wmOperator *op)
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
grease_pencil.foreach_editable_drawing(
scene->r.cfra, [&](int /*drawing_index*/, GreasePencilDrawing &drawing) {
blender::ed::curves::select_alternate(drawing.geometry.wrap(), deselect_ends);
scene->r.cfra, [&](int /*drawing_index*/, blender::bke::greasepencil::Drawing &drawing) {
blender::ed::curves::select_alternate(drawing.strokes_for_write(), deselect_ends);
});
/* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic
@ -242,8 +242,8 @@ static int select_ends_exec(bContext *C, wmOperator *op)
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
grease_pencil.foreach_editable_drawing(
scene->r.cfra, [&](int /*drawing_index*/, GreasePencilDrawing &drawing) {
bke::CurvesGeometry &curves = drawing.geometry.wrap();
scene->r.cfra, [&](int /*drawing_index*/, blender::bke::greasepencil::Drawing &drawing) {
bke::CurvesGeometry &curves = drawing.strokes_for_write();
IndexMaskMemory memory;
const IndexMask inverted_end_points_mask = ed::curves::end_points(

View File

@ -322,8 +322,8 @@ typedef struct V3DSnapCursorData {
typedef struct V3DSnapCursorState {
/* Setup. */
eV3DSnapCursor flag;
uchar color_line[4];
uchar color_point[4];
uchar source_color[4];
uchar target_color[4];
uchar color_box[4];
float *prevpoint;
float box_dimensions[3];
@ -348,13 +348,13 @@ void ED_view3d_cursor_snap_data_update(V3DSnapCursorState *state,
int y);
V3DSnapCursorData *ED_view3d_cursor_snap_data_get(void);
struct SnapObjectContext *ED_view3d_cursor_snap_context_ensure(struct Scene *scene);
void ED_view3d_cursor_snap_draw_util(struct RegionView3D *rv3d,
const float loc_prev[3],
const float loc_curr[3],
const float normal[3],
const uchar color_line[4],
const uchar color_point[4],
eSnapMode snap_elem_type);
void ED_view3d_cursor_snap_draw_util(RegionView3D *rv3d,
const float source_loc[3],
const float target_loc[3],
const float target_normal[3],
const uchar source_color[4],
const uchar target_color[4],
const eSnapMode target_type);
/* view3d_iterators.cc */

View File

@ -34,6 +34,7 @@ struct uiViewHandle;
struct uiViewItemHandle;
struct wmDrag;
void UI_but_func_set(uiBut *but, std::function<void(bContext &)> func);
void UI_but_func_pushed_state_set(uiBut *but, std::function<bool(const uiBut &)> func);
namespace blender::ui {

View File

@ -752,6 +752,12 @@ static bool ui_but_equals_old(const uiBut *but, const uiBut *oldbut)
if (but->func != oldbut->func) {
return false;
}
/* Compares the contained function pointers. Buttons with different apply functions can be
* considered to do different things, and as such do not equal each other. */
if (but->apply_func.target<void(bContext &)>() != oldbut->apply_func.target<void(bContext &)>())
{
return false;
}
if (but->funcN != oldbut->funcN) {
return false;
}
@ -6048,6 +6054,11 @@ void UI_but_func_set(uiBut *but, uiButHandleFunc func, void *arg1, void *arg2)
but->func_arg2 = arg2;
}
void UI_but_func_set(uiBut *but, std::function<void(bContext &)> func)
{
but->apply_func = std::move(func);
}
void UI_but_funcN_set(uiBut *but, uiButHandleNFunc funcN, void *argN, void *arg2)
{
if (but->func_argN) {

View File

@ -31,6 +31,7 @@
#include "ED_screen.h"
#include "UI_interface.h"
#include "UI_interface.hh"
#include "interface_intern.hh"
@ -276,15 +277,8 @@ static void menu_add_shortcut_cancel(bContext *C, void *arg1)
WM_keymap_remove_item(km, kmi);
}
static void popup_change_shortcut_func(bContext *C, void *arg1, void * /*arg2*/)
static void remove_shortcut_func(bContext *C, uiBut *but)
{
uiBut *but = (uiBut *)arg1;
UI_popup_block_invoke(C, menu_change_shortcut, but, nullptr);
}
static void remove_shortcut_func(bContext *C, void *arg1, void * /*arg2*/)
{
uiBut *but = (uiBut *)arg1;
IDProperty *prop;
const char *idname = shortcut_get_operator_property(C, but, &prop);
@ -305,12 +299,6 @@ static void remove_shortcut_func(bContext *C, void *arg1, void * /*arg2*/)
but_shortcut_name_func(C, but, 0);
}
static void popup_add_shortcut_func(bContext *C, void *arg1, void * /*arg2*/)
{
uiBut *but = (uiBut *)arg1;
UI_popup_block_ex(C, menu_add_shortcut, nullptr, menu_add_shortcut_cancel, but, nullptr);
}
static bool ui_but_is_user_menu_compatible(bContext *C, uiBut *but)
{
bool result = false;
@ -444,22 +432,6 @@ static void ui_but_user_menu_add(bContext *C, uiBut *but, bUserMenu *um)
}
}
static void popup_user_menu_add_or_replace_func(bContext *C, void *arg1, void * /*arg2*/)
{
uiBut *but = static_cast<uiBut *>(arg1);
bUserMenu *um = ED_screen_user_menu_ensure(C);
U.runtime.is_dirty = true;
ui_but_user_menu_add(C, but, um);
}
static void popup_user_menu_remove_func(bContext * /*C*/, void *arg1, void *arg2)
{
bUserMenu *um = static_cast<bUserMenu *>(arg1);
bUserMenuItem *umi = static_cast<bUserMenuItem *>(arg2);
U.runtime.is_dirty = true;
ED_screen_user_menu_item_remove(&um->items, umi);
}
static void ui_but_menu_add_path_operators(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop)
{
const PropertySubType subtype = RNA_property_subtype(prop);
@ -1043,8 +1015,10 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but, const wmEvent *ev
0,
0,
"");
UI_but_func_set(but2, popup_user_menu_remove_func, um, umi);
item_found = true;
UI_but_func_set(but2, [um, umi](bContext &) {
U.runtime.is_dirty = true;
ED_screen_user_menu_item_remove(&um->items, umi);
});
}
}
if (um_array) {
@ -1068,7 +1042,11 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but, const wmEvent *ev
0,
0,
"Add to a user defined context menu (stored in the user preferences)");
UI_but_func_set(but2, popup_user_menu_add_or_replace_func, but, nullptr);
UI_but_func_set(but2, [but](bContext &C) {
bUserMenu *um = ED_screen_user_menu_ensure(&C);
U.runtime.is_dirty = true;
ui_but_user_menu_add(&C, but, um);
});
}
uiItemS(layout);
@ -1117,7 +1095,9 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but, const wmEvent *ev
0,
0,
"");
UI_but_func_set(but2, popup_change_shortcut_func, but, nullptr);
UI_but_func_set(but2, [but](bContext &C) {
UI_popup_block_invoke(&C, menu_change_shortcut, but, nullptr);
});
}
else {
uiBut *but2 = uiDefIconTextBut(block,
@ -1155,7 +1135,7 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but, const wmEvent *ev
0,
0,
"");
UI_but_func_set(but2, remove_shortcut_func, but, nullptr);
UI_but_func_set(but2, [but](bContext &C) { remove_shortcut_func(&C, but); });
}
/* only show 'assign' if there's a suitable key map for it to go in */
else if (WM_keymap_guess_opname(C, idname)) {
@ -1175,7 +1155,9 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but, const wmEvent *ev
0,
0,
"");
UI_but_func_set(but2, popup_add_shortcut_func, but, nullptr);
UI_but_func_set(but2, [but](bContext &C) {
UI_popup_block_ex(&C, menu_add_shortcut, nullptr, menu_add_shortcut_cancel, but, nullptr);
});
}
shortcut_free_operator_property(prop);

View File

@ -471,6 +471,8 @@ struct uiAfterFunc {
uiButHandleFunc func;
void *func_arg1;
void *func_arg2;
/** C++ version of #func above, without need for void pointer arguments. */
std::function<void(bContext &)> apply_func;
uiButHandleNFunc funcN;
void *func_argN;
@ -752,7 +754,10 @@ static ListBase UIAfterFuncs = {nullptr, nullptr};
static uiAfterFunc *ui_afterfunc_new()
{
uiAfterFunc *after = MEM_cnew<uiAfterFunc>(__func__);
uiAfterFunc *after = MEM_new<uiAfterFunc>(__func__);
/* Safety asserts to check if members were 0 initialized properly. */
BLI_assert(after->next == nullptr && after->prev == nullptr);
BLI_assert(after->undostr[0] == '\0');
BLI_addtail(&UIAfterFuncs, after);
@ -809,8 +814,9 @@ static void popup_check(bContext *C, wmOperator *op)
*/
static bool ui_afterfunc_check(const uiBlock *block, const uiBut *but)
{
return (but->func || but->funcN || but->rename_func || but->optype || but->rnaprop ||
block->handle_func || (but->type == UI_BTYPE_BUT_MENU && block->butm_func) ||
return (but->func || but->apply_func || but->funcN || but->rename_func || but->optype ||
but->rnaprop || block->handle_func ||
(but->type == UI_BTYPE_BUT_MENU && block->butm_func) ||
(block->handle && block->handle->popup_op));
}
@ -839,6 +845,8 @@ static void ui_apply_but_func(bContext *C, uiBut *but)
after->func_arg1 = but->func_arg1;
after->func_arg2 = but->func_arg2;
after->apply_func = but->apply_func;
after->funcN = but->funcN;
after->func_argN = (but->func_argN) ? MEM_dupallocN(but->func_argN) : nullptr;
@ -1008,7 +1016,8 @@ static void ui_apply_but_funcs_after(bContext *C)
LISTBASE_FOREACH_MUTABLE (uiAfterFunc *, afterf, &funcs) {
uiAfterFunc after = *afterf; /* Copy to avoid memory leak on exit(). */
BLI_freelinkN(&funcs, afterf);
BLI_remlink(&funcs, afterf);
MEM_delete(afterf);
if (after.context) {
CTX_store_set(C, after.context);
@ -1050,6 +1059,9 @@ static void ui_apply_but_funcs_after(bContext *C)
if (after.func) {
after.func(C, after.func_arg1, after.func_arg2);
}
if (after.apply_func) {
after.apply_func(*C);
}
if (after.funcN) {
after.funcN(C, after.func_argN, after.func_arg2);
}

View File

@ -193,6 +193,11 @@ struct uiBut {
uiButHandleFunc func = nullptr;
void *func_arg1 = nullptr;
void *func_arg2 = nullptr;
/**
* C++ version of #func above. Allows storing arbitrary data in a type safe way, no void
* pointer arguments.
*/
std::function<void(bContext &)> apply_func;
uiButHandleNFunc funcN = nullptr;
void *func_argN = nullptr;

View File

@ -131,13 +131,8 @@ class CollectionViewItem : public BasicTreeViewItem {
return ICON_NONE;
}
static void link_state_toggle_cb(bContext * /*C*/,
void * /*collection_v*/,
void *collection_light_linking_v)
static void link_state_toggle(CollectionLightLinking &collection_light_linking)
{
CollectionLightLinking &collection_light_linking = *static_cast<CollectionLightLinking *>(
collection_light_linking_v);
switch (collection_light_linking.link_state) {
case COLLECTION_LIGHT_LINKING_STATE_INCLUDE:
collection_light_linking.link_state = COLLECTION_LIGHT_LINKING_STATE_EXCLUDE;
@ -178,7 +173,7 @@ class CollectionViewItem : public BasicTreeViewItem {
0.0f,
nullptr);
UI_but_func_set(button, link_state_toggle_cb, &collection_, &collection_light_linking_);
UI_but_func_set(button, [this](bContext &) { link_state_toggle(collection_light_linking_); });
}
void build_remove_button(uiLayout &row)

View File

@ -610,9 +610,8 @@ static void uilist_prepare(uiList *ui_list,
items->tot_items);
}
static void uilist_resize_update_cb(bContext *C, void *arg1, void * /*arg2*/)
static void uilist_resize_update(bContext *C, uiList *ui_list)
{
uiList *ui_list = static_cast<uiList *>(arg1);
uiListDyn *dyn_data = ui_list->dyn_data;
/* This way we get diff in number of additional items to show (positive) or hide (negative). */
@ -1148,7 +1147,7 @@ static void ui_template_list_layout_draw(const bContext *C,
0,
0,
"");
UI_but_func_set(but, uilist_resize_update_cb, ui_list, nullptr);
UI_but_func_set(but, [ui_list](bContext &C) { uilist_resize_update(&C, ui_list); });
}
UI_block_emboss_set(subblock, UI_EMBOSS);
@ -1205,7 +1204,7 @@ static void ui_template_list_layout_draw(const bContext *C,
0,
0,
"");
UI_but_func_set(but, uilist_resize_update_cb, ui_list, nullptr);
UI_but_func_set(but, [ui_list](bContext &C) { uilist_resize_update(&C, ui_list); });
}
UI_block_emboss_set(subblock, UI_EMBOSS);

View File

@ -407,7 +407,7 @@ static void make_renderinfo_string(const RenderStats *rs,
const Scene *scene,
const bool v3d_override,
const char *error,
char ret[IMA_MAX_RENDER_TEXT])
char ret[IMA_MAX_RENDER_TEXT_SIZE])
{
const char *info_space = " ";
const char *info_sep = "| ";
@ -514,13 +514,13 @@ static void make_renderinfo_string(const RenderStats *rs,
}
if (G.debug & G_DEBUG) {
if (BLI_string_len_array(ret_array, i) >= IMA_MAX_RENDER_TEXT) {
if (BLI_string_len_array(ret_array, i) >= IMA_MAX_RENDER_TEXT_SIZE) {
printf("WARNING! renderwin text beyond limit\n");
}
}
BLI_assert(i < int(BOUNDED_ARRAY_TYPE_SIZE<decltype(ret_array)>()));
BLI_string_join_array(ret, IMA_MAX_RENDER_TEXT, ret_array, i);
BLI_string_join_array(ret, IMA_MAX_RENDER_TEXT_SIZE, ret_array, i);
}
static void image_renderinfo_cb(void *rjv, RenderStats *rs)
@ -533,7 +533,7 @@ static void image_renderinfo_cb(void *rjv, RenderStats *rs)
if (rr) {
/* malloc OK here, stats_draw is not in tile threads */
if (rr->text == nullptr) {
rr->text = static_cast<char *>(MEM_callocN(IMA_MAX_RENDER_TEXT, "rendertext"));
rr->text = static_cast<char *>(MEM_callocN(IMA_MAX_RENDER_TEXT_SIZE, "rendertext"));
}
make_renderinfo_string(rs, rj->scene, rj->v3d_override, rr->error, rr->text);

View File

@ -3866,12 +3866,10 @@ int ED_region_snap_size_test(const ARegion *region)
/* Use a larger value because toggling scrollbars can jump in size. */
const int snap_match_threshold = 16;
if (region->type->snap_size != nullptr) {
return ((((region->sizex - region->type->snap_size(region, region->sizex, 0)) <=
snap_match_threshold)
<< 0) |
(((region->sizey - region->type->snap_size(region, region->sizey, 1)) <=
snap_match_threshold)
<< 1));
const int snap_size_x = region->type->snap_size(region, region->sizex, 0);
const int snap_size_y = region->type->snap_size(region, region->sizey, 1);
return (((abs(region->sizex - snap_size_x) <= snap_match_threshold) << 0) |
((abs(region->sizey - snap_size_y) <= snap_match_threshold) << 1));
}
return 0;
}

View File

@ -42,7 +42,6 @@ struct PaintOperationExecutor {
{
using namespace blender::bke;
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(&C);
Scene *scene = CTX_data_scene(&C);
ARegion *region = CTX_wm_region(&C);
Object *obact = CTX_data_active_object(&C);
Object *ob_eval = DEG_get_evaluated_object(depsgraph, obact);
@ -58,12 +57,6 @@ struct PaintOperationExecutor {
BLI_assert_unreachable();
// grease_pencil.runtime->set_active_layer_index(0);
}
const bke::greasepencil::Layer &active_layer = *grease_pencil.get_active_layer();
int index = active_layer.drawing_index_at(scene->r.cfra);
BLI_assert(index != -1);
GreasePencilDrawing &drawing = *reinterpret_cast<GreasePencilDrawing *>(
grease_pencil.drawings()[index]);
float4 plane{0.0f, -1.0f, 0.0f, 0.0f};
float3 proj_pos;
@ -72,7 +65,7 @@ struct PaintOperationExecutor {
bke::greasepencil::StrokePoint new_point{
proj_pos, stroke_extension.pressure * 100.0f, 1.0f, float4(1.0f)};
drawing.runtime->stroke_cache.points.append(std::move(new_point));
grease_pencil.runtime->stroke_cache.points.append(std::move(new_point));
BKE_grease_pencil_batch_cache_dirty_tag(&grease_pencil, BKE_GREASEPENCIL_BATCH_DIRTY_ALL);
}
@ -101,12 +94,11 @@ void PaintOperation::on_stroke_done(const bContext &C)
int index_eval = active_layer_eval.drawing_index_at(scene->r.cfra);
BLI_assert(index_orig != -1 && index_eval != -1);
GreasePencilDrawing &drawing_orig = *reinterpret_cast<GreasePencilDrawing *>(
grease_pencil_orig.drawings()[index_orig]);
GreasePencilDrawing &drawing_eval = *reinterpret_cast<GreasePencilDrawing *>(
grease_pencil_eval.drawings()[index_eval]);
bke::greasepencil::Drawing &drawing_orig =
reinterpret_cast<GreasePencilDrawing *>(grease_pencil_orig.drawings()[index_orig])->wrap();
const Span<bke::greasepencil::StrokePoint> stroke_points = drawing_eval.stroke_buffer();
const Span<bke::greasepencil::StrokePoint> stroke_points =
grease_pencil_eval.runtime->stroke_buffer();
CurvesGeometry &curves = drawing_orig.geometry.wrap();
int num_old_curves = curves.curves_num();
@ -162,7 +154,7 @@ void PaintOperation::on_stroke_done(const bContext &C)
return true;
});
drawing_eval.runtime->stroke_cache.clear();
grease_pencil_eval.runtime->stroke_cache.clear();
drawing_orig.tag_positions_changed();
radii.finish();

View File

@ -772,7 +772,11 @@ static void graph_panel_driverVar__singleProp(uiLayout *layout, ID *id, DriverVa
/* rna path */
col = uiLayoutColumn(layout, true);
uiLayoutSetRedAlert(col, (dtar->flag & DTAR_FLAG_INVALID));
uiTemplatePathBuilder(col, &dtar_ptr, "data_path", &root_ptr, IFACE_("Path"));
uiTemplatePathBuilder(col,
&dtar_ptr,
"data_path",
&root_ptr,
CTX_IFACE_(BLT_I18NCONTEXT_EDITOR_FILEBROWSER, "Path"));
}
}
@ -925,7 +929,8 @@ static void graph_panel_driverVar__contextProp(uiLayout *layout, ID *id, DriverV
{
uiLayout *col = uiLayoutColumn(layout, true);
uiLayoutSetRedAlert(col, (dtar->flag & DTAR_FLAG_INVALID));
uiTemplatePathBuilder(col, &dtar_ptr, "data_path", NULL, IFACE_("Path"));
uiTemplatePathBuilder(
col, &dtar_ptr, "data_path", NULL, CTX_IFACE_(BLT_I18NCONTEXT_EDITOR_FILEBROWSER, "Path"));
}
}

View File

@ -222,7 +222,7 @@ static void add_node_search_exec_fn(bContext *C, void *arg1, void *arg2)
}
node_deselect_all(node_tree);
Vector<bNode *> new_nodes = item->add_fn(*C, node_tree, storage.cursor);
item->add_fn(*C, node_tree, storage.cursor);
/* Ideally it would be possible to tag the node tree in some way so it updates only after the
* translate operation is finished, but normally moving nodes around doesn't cause updates. */

View File

@ -11,21 +11,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_anim_types.h"
#include "DNA_cachefile_types.h"
#include "DNA_camera_types.h"
#include "DNA_collection_types.h"
#include "DNA_curves_types.h"
#include "DNA_key_types.h"
#include "DNA_light_types.h"
#include "DNA_lightprobe_types.h"
#include "DNA_material_types.h"
#include "DNA_pointcloud_types.h"
#include "DNA_scene_types.h"
#include "DNA_simulation_types.h"
#include "DNA_speaker_types.h"
#include "DNA_volume_types.h"
#include "DNA_world_types.h"
#include "BLI_blenlib.h"
#include "BLI_fnmatch.h"
@ -229,118 +215,6 @@ static void outliner_add_line_styles(SpaceOutliner *space_outliner,
}
}
#endif
/* Can be inlined if necessary. */
static void outliner_add_id_contents(SpaceOutliner *space_outliner, TreeElement *te, ID *id)
{
/* expand specific data always */
switch (GS(id->name)) {
case ID_LI:
case ID_SCE:
case ID_ME:
case ID_CU_LEGACY:
case ID_MB:
case ID_TE:
case ID_LS:
case ID_GD_LEGACY:
case ID_GR:
case ID_AR:
case ID_OB:
BLI_assert_msg(0, "ID type expected to be expanded through new tree-element design");
break;
case ID_MA: {
Material *ma = (Material *)id;
if (outliner_animdata_test(ma->adt)) {
outliner_add_element(space_outliner, &te->subtree, ma, te, TSE_ANIM_DATA, 0);
}
break;
}
case ID_CA: {
Camera *ca = (Camera *)id;
if (outliner_animdata_test(ca->adt)) {
outliner_add_element(space_outliner, &te->subtree, ca, te, TSE_ANIM_DATA, 0);
}
break;
}
case ID_CF: {
CacheFile *cache_file = (CacheFile *)id;
if (outliner_animdata_test(cache_file->adt)) {
outliner_add_element(space_outliner, &te->subtree, cache_file, te, TSE_ANIM_DATA, 0);
}
break;
}
case ID_LA: {
Light *la = (Light *)id;
if (outliner_animdata_test(la->adt)) {
outliner_add_element(space_outliner, &te->subtree, la, te, TSE_ANIM_DATA, 0);
}
break;
}
case ID_SPK: {
Speaker *spk = (Speaker *)id;
if (outliner_animdata_test(spk->adt)) {
outliner_add_element(space_outliner, &te->subtree, spk, te, TSE_ANIM_DATA, 0);
}
break;
}
case ID_LP: {
LightProbe *prb = (LightProbe *)id;
if (outliner_animdata_test(prb->adt)) {
outliner_add_element(space_outliner, &te->subtree, prb, te, TSE_ANIM_DATA, 0);
}
break;
}
case ID_WO: {
World *wrld = (World *)id;
if (outliner_animdata_test(wrld->adt)) {
outliner_add_element(space_outliner, &te->subtree, wrld, te, TSE_ANIM_DATA, 0);
}
break;
}
case ID_KE: {
Key *key = (Key *)id;
if (outliner_animdata_test(key->adt)) {
outliner_add_element(space_outliner, &te->subtree, key, te, TSE_ANIM_DATA, 0);
}
break;
}
case ID_AC: {
/* XXX do we want to be exposing the F-Curves here? */
/* bAction *act = (bAction *)id; */
break;
}
case ID_CV: {
Curves *curves = (Curves *)id;
if (outliner_animdata_test(curves->adt)) {
outliner_add_element(space_outliner, &te->subtree, curves, te, TSE_ANIM_DATA, 0);
}
break;
}
case ID_PT: {
PointCloud *pointcloud = (PointCloud *)id;
if (outliner_animdata_test(pointcloud->adt)) {
outliner_add_element(space_outliner, &te->subtree, pointcloud, te, TSE_ANIM_DATA, 0);
}
break;
}
case ID_VO: {
Volume *volume = (Volume *)id;
if (outliner_animdata_test(volume->adt)) {
outliner_add_element(space_outliner, &te->subtree, volume, te, TSE_ANIM_DATA, 0);
}
break;
}
case ID_SIM: {
Simulation *simulation = (Simulation *)id;
if (outliner_animdata_test(simulation->adt)) {
outliner_add_element(space_outliner, &te->subtree, simulation, te, TSE_ANIM_DATA, 0);
}
break;
}
default:
break;
}
}
TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
ListBase *lb,
@ -450,15 +324,9 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
if (!expand) {
/* Pass */
}
else if (te->abstract_element && te->abstract_element->isExpandValid()) {
else if (te->abstract_element) {
tree_element_expand(*te->abstract_element, *space_outliner);
}
else if (type == TSE_SOME_ID) {
/* ID types not (fully) ported to new design yet. */
if (te->abstract_element->expandPoll(*space_outliner)) {
outliner_add_id_contents(space_outliner, te, id);
}
}
else if (ELEM(type,
TSE_ANIM_DATA,
TSE_DRIVER_BASE,

View File

@ -48,15 +48,6 @@ class AbstractTreeElement {
return true;
}
/**
* Just while transitioning to the new tree-element design: Some types are only partially ported,
* and the expanding isn't done yet.
*/
virtual bool isExpandValid() const
{
return true;
}
TreeElement &getLegacyElement()
{
return legacy_te_;

View File

@ -12,6 +12,7 @@
#include "BLI_listbase_wrapper.hh"
#include "BLI_utildefines.h"
#include "BKE_anim_data.h"
#include "BKE_lib_override.h"
#include "BLT_translation.h"
@ -124,6 +125,15 @@ bool TreeElementID::expandPoll(const SpaceOutliner &space_outliner) const
return (tsepar == nullptr || tsepar->type != TSE_ID_BASE || space_outliner.filter_id_type);
}
void TreeElementID::expand(SpaceOutliner &space_outliner) const
{
/* Not all IDs support animation data. Will be null then. */
const AnimData *anim_data = BKE_animdata_from_id(&id_);
if (anim_data) {
expand_animation_data(space_outliner, anim_data);
}
}
void TreeElementID::expand_animation_data(SpaceOutliner &space_outliner,
const AnimData *anim_data) const
{

View File

@ -28,14 +28,7 @@ class TreeElementID : public AbstractTreeElement {
bool expandPoll(const SpaceOutliner &) const override;
/**
* Expanding not implemented for all types yet. Once it is, this can be set to true or
* `AbstractTreeElement::expandValid()` can be removed altogether.
*/
bool isExpandValid() const override
{
return false;
}
void expand(SpaceOutliner &) const override;
ID &get_ID()
{

View File

@ -48,11 +48,6 @@ void TreeElementIDArmature::expand(SpaceOutliner &space_outliner) const
}
}
bool TreeElementIDArmature::isExpandValid() const
{
return true;
}
void TreeElementIDArmature::expandEditBones(SpaceOutliner &space_outiner) const
{
int a = 0;

View File

@ -23,7 +23,6 @@ class TreeElementIDArmature final : public TreeElementID {
TreeElementIDArmature(TreeElement &legacy_te, bArmature &arm);
void expand(SpaceOutliner &) const override;
bool isExpandValid() const override;
private:
void expandEditBones(SpaceOutliner &) const;

View File

@ -21,11 +21,6 @@ TreeElementIDCollection::TreeElementIDCollection(TreeElement &legacy_te, Collect
{
}
bool TreeElementIDCollection::isExpandValid() const
{
return true;
}
void TreeElementIDCollection::expand(SpaceOutliner &space_outliner) const
{
/* Don't expand for instances, creates too many elements. */

View File

@ -19,7 +19,6 @@ class TreeElementIDCollection final : public TreeElementID {
TreeElementIDCollection(TreeElement &legacy_te, Collection &collection);
void expand(SpaceOutliner &) const override;
bool isExpandValid() const override;
};
} // namespace blender::ed::outliner

View File

@ -21,11 +21,6 @@ TreeElementIDCurve::TreeElementIDCurve(TreeElement &legacy_te, Curve &curve)
{
}
bool TreeElementIDCurve::isExpandValid() const
{
return true;
}
void TreeElementIDCurve::expand(SpaceOutliner &space_outliner) const
{
expand_animation_data(space_outliner, curve_.adt);

View File

@ -19,7 +19,6 @@ class TreeElementIDCurve final : public TreeElementID {
TreeElementIDCurve(TreeElement &legacy_te, Curve &curve);
void expand(SpaceOutliner &) const override;
bool isExpandValid() const override;
private:
void expandMaterials(SpaceOutliner &) const;

View File

@ -31,11 +31,6 @@ void TreeElementIDGPLegacy::expand(SpaceOutliner &space_outliner) const
expandLayers(space_outliner);
}
bool TreeElementIDGPLegacy::isExpandValid() const
{
return true;
}
void TreeElementIDGPLegacy::expandLayers(SpaceOutliner &space_outliner) const
{
int index = 0;

View File

@ -19,7 +19,6 @@ class TreeElementIDGPLegacy final : public TreeElementID {
TreeElementIDGPLegacy(TreeElement &legacy_te, bGPdata &gpd);
void expand(SpaceOutliner &) const override;
bool isExpandValid() const override;
private:
void expandLayers(SpaceOutliner &) const;

View File

@ -23,11 +23,6 @@ TreeElementIDLibrary::TreeElementIDLibrary(TreeElement &legacy_te, Library &libr
legacy_te.name = library.filepath;
}
bool TreeElementIDLibrary::isExpandValid() const
{
return true;
}
StringRefNull TreeElementIDLibrary::getWarning() const
{
Library &library = reinterpret_cast<Library &>(id_);

View File

@ -18,8 +18,6 @@ class TreeElementIDLibrary final : public TreeElementID {
public:
TreeElementIDLibrary(TreeElement &legacy_te, Library &library);
bool isExpandValid() const override;
blender::StringRefNull getWarning() const override;
};

View File

@ -31,11 +31,6 @@ void TreeElementIDLineStyle::expand(SpaceOutliner &space_outliner) const
expandTextures(space_outliner);
}
bool TreeElementIDLineStyle::isExpandValid() const
{
return true;
}
void TreeElementIDLineStyle::expandTextures(SpaceOutliner &space_outliner) const
{
for (int a = 0; a < MAX_MTEX; a++) {

View File

@ -21,7 +21,6 @@ class TreeElementIDLineStyle final : public TreeElementID {
TreeElementIDLineStyle(TreeElement &legacy_te, FreestyleLineStyle &linestyle);
void expand(SpaceOutliner &) const override;
bool isExpandValid() const override;
private:
void expandTextures(SpaceOutliner &) const;

View File

@ -21,11 +21,6 @@ TreeElementIDMesh::TreeElementIDMesh(TreeElement &legacy_te_, Mesh &mesh)
{
}
bool TreeElementIDMesh::isExpandValid() const
{
return true;
}
void TreeElementIDMesh::expand(SpaceOutliner &space_outliner) const
{
expand_animation_data(space_outliner, mesh_.adt);

View File

@ -19,7 +19,6 @@ class TreeElementIDMesh final : public TreeElementID {
TreeElementIDMesh(TreeElement &legacy_te_, Mesh &mesh);
void expand(SpaceOutliner &) const override;
bool isExpandValid() const override;
private:
void expandKey(SpaceOutliner &) const;

View File

@ -21,11 +21,6 @@ TreeElementIDMetaBall::TreeElementIDMetaBall(TreeElement &legacy_te, MetaBall &m
{
}
bool TreeElementIDMetaBall::isExpandValid() const
{
return true;
}
void TreeElementIDMetaBall::expand(SpaceOutliner &space_outliner) const
{
expand_animation_data(space_outliner, metaball_.adt);

View File

@ -21,7 +21,6 @@ class TreeElementIDMetaBall final : public TreeElementID {
TreeElementIDMetaBall(TreeElement &legacy_te, MetaBall &metaball);
void expand(SpaceOutliner &) const override;
bool isExpandValid() const override;
private:
void expandMaterials(SpaceOutliner &) const;

View File

@ -51,11 +51,6 @@ void TreeElementIDObject::expand(SpaceOutliner &space_outliner) const
expandDuplicatedGroup(space_outliner);
}
bool TreeElementIDObject::isExpandValid() const
{
return true;
}
void TreeElementIDObject::expandData(SpaceOutliner &space_outliner) const
{
outliner_add_element(

View File

@ -19,7 +19,6 @@ class TreeElementIDObject final : public TreeElementID {
TreeElementIDObject(TreeElement &legacy_te, Object &object);
void expand(SpaceOutliner &) const override;
bool isExpandValid() const override;
private:
void expandData(SpaceOutliner &) const;

View File

@ -21,11 +21,6 @@ TreeElementIDScene::TreeElementIDScene(TreeElement &legacy_te, Scene &scene)
{
}
bool TreeElementIDScene::isExpandValid() const
{
return true;
}
void TreeElementIDScene::expand(SpaceOutliner &space_outliner) const
{
expandViewLayers(space_outliner);

View File

@ -19,7 +19,6 @@ class TreeElementIDScene final : public TreeElementID {
TreeElementIDScene(TreeElement &legacy_te, Scene &scene);
void expand(SpaceOutliner &) const override;
bool isExpandValid() const override;
private:
void expandViewLayers(SpaceOutliner &) const;

View File

@ -21,11 +21,6 @@ TreeElementIDTexture::TreeElementIDTexture(TreeElement &legacy_te, Tex &texture)
{
}
bool TreeElementIDTexture::isExpandValid() const
{
return true;
}
void TreeElementIDTexture::expand(SpaceOutliner &space_outliner) const
{
expand_animation_data(space_outliner, texture_.adt);

View File

@ -19,7 +19,6 @@ class TreeElementIDTexture final : public TreeElementID {
TreeElementIDTexture(TreeElement &legacy_te, Tex &texture);
void expand(SpaceOutliner &) const override;
bool isExpandValid() const override;
private:
void expandImage(SpaceOutliner &) const;

View File

@ -44,11 +44,6 @@ TreeElementRNACommon::TreeElementRNACommon(TreeElement &legacy_te, PointerRNA &r
}
}
bool TreeElementRNACommon::isExpandValid() const
{
return true;
}
bool TreeElementRNACommon::isRNAValid() const
{
return rna_ptr_.data != nullptr;

View File

@ -28,7 +28,6 @@ class TreeElementRNACommon : public AbstractTreeElement {
public:
TreeElementRNACommon(TreeElement &legacy_te, PointerRNA &rna_ptr);
bool isExpandValid() const override;
bool expandPoll(const SpaceOutliner &) const override;
const PointerRNA &getPointerRNA() const;

View File

@ -7,6 +7,7 @@ set(INC
../../blenkernel
../../blenlib
../../blenloader
../../blentranslation
../../gpu
../../makesdna
../../makesrna

View File

@ -15,6 +15,8 @@
#include "BKE_context.h"
#include "BKE_report.h"
#include "BLT_translation.h"
#include "WM_api.h"
#include "WM_types.h"
#include "wm_event_system.h"
@ -50,6 +52,8 @@ static int run_pyfile_exec(bContext *C, wmOperator *op)
void SCRIPT_OT_python_file_run(wmOperatorType *ot)
{
PropertyRNA *prop;
/* identifiers */
ot->name = "Run Python File";
ot->description = "Run Python file";
@ -61,7 +65,8 @@ void SCRIPT_OT_python_file_run(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
RNA_def_string_file_path(ot->srna, "filepath", NULL, FILE_MAX, "Path", "");
prop = RNA_def_string_file_path(ot->srna, "filepath", NULL, FILE_MAX, "Path", "");
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_EDITOR_FILEBROWSER);
}
#ifdef WITH_PYTHON

View File

@ -429,7 +429,7 @@ static void gizmo_retime_handle_draw(const bContext *C, wmGizmo *gz)
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
Sequence *seq = active_seq_from_context(C);
SEQ_retiming_data_ensure(seq);
SEQ_retiming_data_ensure(CTX_data_scene(C), seq);
MutableSpan handles = SEQ_retiming_handles_get(seq);
for (const SeqRetimingHandle &handle : handles) {
@ -454,7 +454,7 @@ static int gizmo_retime_handle_test_select(bContext *C, wmGizmo *gz, const int m
gizmo->mouse_over_seq = nullptr;
Sequence *seq = active_seq_from_context(C);
SEQ_retiming_data_ensure(seq);
SEQ_retiming_data_ensure(scene, seq);
const SeqRetimingHandle *handle = mouse_over_handle_get(
scene, seq, UI_view2d_fromcontext(C), mval);
const int handle_index = SEQ_retiming_handle_index_get(seq, handle);
@ -531,7 +531,7 @@ static int gizmo_retime_remove_test_select(bContext *C, wmGizmo *gz, const int m
Scene *scene = CTX_data_scene(C);
Sequence *seq = active_seq_from_context(C);
SEQ_retiming_data_ensure(seq);
SEQ_retiming_data_ensure(scene, seq);
const SeqRetimingHandle *handle = mouse_over_handle_get(
scene, seq, UI_view2d_fromcontext(C), mval);
const int handle_index = SEQ_retiming_handle_index_get(seq, handle);
@ -690,7 +690,7 @@ static void gizmo_retime_speed_set_draw(const bContext *C, wmGizmo * /* gz */)
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
Sequence *seq = active_seq_from_context(C);
SEQ_retiming_data_ensure(seq);
SEQ_retiming_data_ensure(CTX_data_scene(C), seq);
MutableSpan handles = SEQ_retiming_handles_get(seq);
for (const SeqRetimingHandle &handle : handles) {
@ -711,7 +711,7 @@ static int gizmo_retime_speed_set_test_select(bContext *C, wmGizmo *gz, const in
const View2D *v2d = UI_view2d_fromcontext(C);
Sequence *seq = active_seq_from_context(C);
SEQ_retiming_data_ensure(seq);
SEQ_retiming_data_ensure(scene, seq);
for (const SeqRetimingHandle &handle : SEQ_retiming_handles_get(seq)) {
if (SEQ_retiming_handle_is_transition_type(&handle)) {

View File

@ -325,7 +325,7 @@ static int sequesequencer_retiming_handle_add_exec(bContext *C, wmOperator *op)
const Editing *ed = SEQ_editing_get(scene);
Sequence *seq = ed->act_seq;
SEQ_retiming_data_ensure(seq);
SEQ_retiming_data_ensure(scene, seq);
float timeline_frame;
if (RNA_struct_property_is_set(op->ptr, "timeline_frame")) {

View File

@ -79,8 +79,8 @@ typedef struct SnapCursorDataIntern {
static SnapCursorDataIntern g_data_intern = {
.state_default = {.flag = V3D_SNAPCURSOR_SNAP_EDIT_GEOM_FINAL,
.color_point = {255, 255, 255, 255},
.color_line = {255, 255, 255, 128},
.target_color = {255, 255, 255, 255},
.source_color = {255, 255, 255, 128},
.color_box = {255, 255, 255, 128},
.box_dimensions = {1.0f, 1.0f, 1.0f},
.draw_point = true}};
@ -367,14 +367,14 @@ static void cursor_box_draw(const float dimensions[3], uchar color[4])
}
void ED_view3d_cursor_snap_draw_util(RegionView3D *rv3d,
const float loc_prev[3],
const float loc_curr[3],
const float normal[3],
const uchar color_line[4],
const uchar color_point[4],
const eSnapMode snap_elem_type)
const float source_loc[3],
const float target_loc[3],
const float target_normal[3],
const uchar source_color[4],
const uchar target_color[4],
const eSnapMode target_type)
{
if (!loc_prev && !loc_curr) {
if (!source_loc && !target_loc) {
return;
}
@ -388,20 +388,23 @@ void ED_view3d_cursor_snap_draw_util(RegionView3D *rv3d,
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
if (loc_curr) {
immUniformColor4ubv(color_point);
imm_drawcircball(loc_curr, ED_view3d_pixel_size(rv3d, loc_curr) * radius, view_inv, pos);
if (target_loc) {
immUniformColor4ubv(target_color);
imm_drawcircball(target_loc, ED_view3d_pixel_size(rv3d, target_loc) * radius, view_inv, pos);
/* draw normal if needed */
if (normal) {
if (target_normal) {
immBegin(GPU_PRIM_LINES, 2);
immVertex3fv(pos, loc_curr);
immVertex3f(pos, loc_curr[0] + normal[0], loc_curr[1] + normal[1], loc_curr[2] + normal[2]);
immVertex3fv(pos, target_loc);
immVertex3f(pos,
target_loc[0] + target_normal[0],
target_loc[1] + target_normal[1],
target_loc[2] + target_normal[2]);
immEnd();
}
}
if (loc_prev) {
if (source_loc) {
/* Draw an "X" indicating where the previous snap point is.
* This is useful for indicating perpendicular snap. */
@ -411,7 +414,7 @@ void ED_view3d_cursor_snap_draw_util(RegionView3D *rv3d,
/* Multiply by 0.75f so that the final size of the "X" is close to that of
* the circle.
* (A closer value is 0.7071f, but we don't need to be exact here). */
float x_size = 0.75f * radius * ED_view3d_pixel_size(rv3d, loc_prev);
float x_size = 0.75f * radius * ED_view3d_pixel_size(rv3d, source_loc);
mul_v3_v3fl(vx, view_inv[0], x_size);
mul_v3_v3fl(vy, view_inv[1], x_size);
@ -421,12 +424,12 @@ void ED_view3d_cursor_snap_draw_util(RegionView3D *rv3d,
negate_v3_v3(v3, v1);
negate_v3_v3(v4, v2);
add_v3_v3(v1, loc_prev);
add_v3_v3(v2, loc_prev);
add_v3_v3(v3, loc_prev);
add_v3_v3(v4, loc_prev);
add_v3_v3(v1, source_loc);
add_v3_v3(v2, source_loc);
add_v3_v3(v3, source_loc);
add_v3_v3(v4, source_loc);
immUniformColor4ubv(color_line);
immUniformColor4ubv(source_color);
immBegin(GPU_PRIM_LINES, 4);
immVertex3fv(pos, v3);
immVertex3fv(pos, v1);
@ -434,7 +437,7 @@ void ED_view3d_cursor_snap_draw_util(RegionView3D *rv3d,
immVertex3fv(pos, v2);
immEnd();
if (loc_curr && (snap_elem_type & SCE_SNAP_TO_EDGE_PERPENDICULAR)) {
if (target_loc && (target_type & SCE_SNAP_TO_EDGE_PERPENDICULAR)) {
/* Dashed line. */
immUnbindProgram();
@ -444,11 +447,11 @@ void ED_view3d_cursor_snap_draw_util(RegionView3D *rv3d,
immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
immUniform1f("dash_width", 6.0f * U.pixelsize);
immUniform1f("udash_factor", 1.0f / 4.0f);
immUniformColor4ubv(color_line);
immUniformColor4ubv(source_color);
immBegin(GPU_PRIM_LINES, 2);
immVertex3fv(pos, loc_prev);
immVertex3fv(pos, loc_curr);
immVertex3fv(pos, source_loc);
immVertex3fv(pos, target_loc);
immEnd();
}
}
@ -883,8 +886,8 @@ static void v3d_cursor_snap_draw_fn(bContext *C, int x, int y, void *UNUSED(cust
prev_point,
snap_data->loc,
NULL,
state->color_line,
state->color_point,
state->source_color,
state->target_color,
snap_data->snap_elem);
}

View File

@ -1768,7 +1768,7 @@ static int vieworbit_exec(bContext *C, wmOperator *op)
/* support for switching to the opposite view (even when in locked views) */
view_opposite = (fabsf(angle) == float(M_PI)) ? ED_view3d_axis_view_opposite(rv3d->view) :
RV3D_VIEW_USER;
char(RV3D_VIEW_USER);
orbitdir = RNA_enum_get(op->ptr, "type");
if ((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ROTATION) && (view_opposite == RV3D_VIEW_USER)) {

View File

@ -1188,14 +1188,14 @@ static bool do_lasso_select_grease_pencil(ViewContext *vc,
bool changed = false;
grease_pencil.foreach_editable_drawing(
vc->scene->r.cfra, [&](int drawing_index, GreasePencilDrawing &drawing) {
vc->scene->r.cfra, [&](int drawing_index, blender::bke::greasepencil::Drawing &drawing) {
bke::crazyspace::GeometryDeformation deformation =
bke::crazyspace::get_evaluated_grease_pencil_drawing_deformation(
ob_eval, *vc->obedit, drawing_index);
changed = ed::curves::select_lasso(
*vc,
drawing.geometry.wrap(),
drawing.strokes_for_write(),
deformation.positions,
selection_domain,
Span<int2>(reinterpret_cast<const int2 *>(mcoords), mcoords_len),
@ -3143,7 +3143,7 @@ static bool ed_curves_select_pick(bContext &C, const int mval[2], const SelectPi
}
struct ClosestGreasePencilDrawing {
GreasePencilDrawing *drawing = nullptr;
blender::bke::greasepencil::Drawing *drawing = nullptr;
blender::ed::curves::FindClosestData elem = {};
};
@ -3165,13 +3165,13 @@ static bool ed_grease_pencil_select_pick(bContext *C,
/* Collect editable drawings. */
const Object *ob_eval = DEG_get_evaluated_object(vc.depsgraph, const_cast<Object *>(vc.obedit));
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(vc.obedit->data);
Vector<GreasePencilDrawing *> drawings;
Vector<blender::bke::greasepencil::Drawing *> drawings;
Vector<int> drawing_indices;
grease_pencil.foreach_editable_drawing(vc.scene->r.cfra,
[&](int drawing_index, GreasePencilDrawing &drawing) {
drawings.append(&drawing);
drawing_indices.append(drawing_index);
});
grease_pencil.foreach_editable_drawing(
vc.scene->r.cfra, [&](int drawing_index, blender::bke::greasepencil::Drawing &drawing) {
drawings.append(&drawing);
drawing_indices.append(drawing_index);
});
/* Get selection domain from tool settings. */
const eAttrDomain selection_domain = ED_grease_pencil_selection_domain_get(C);
@ -3190,7 +3190,7 @@ static bool ed_grease_pencil_select_pick(bContext *C,
std::optional<ed::curves::FindClosestData> new_closest_elem =
ed::curves::closest_elem_find_screen_space(vc,
*vc.obedit,
drawings[i]->geometry.wrap(),
drawings[i]->strokes_for_write(),
deformation.positions,
selection_domain,
mval,
@ -3234,7 +3234,7 @@ static bool ed_grease_pencil_select_pick(bContext *C,
}
bke::GSpanAttributeWriter selection = ed::curves::ensure_selection_attribute(
closest.drawing->geometry.wrap(), selection_domain, CD_PROP_BOOL);
closest.drawing->strokes_for_write(), selection_domain, CD_PROP_BOOL);
ed::curves::apply_selection_operation_at_index(
selection.span, closest.elem.index, params.sel_op);
selection.finish();
@ -4194,12 +4194,16 @@ static bool do_grease_pencil_box_select(ViewContext *vc, const rcti *rect, const
bool changed = false;
grease_pencil.foreach_editable_drawing(
scene->r.cfra, [&](int drawing_index, GreasePencilDrawing &drawing) {
scene->r.cfra, [&](int drawing_index, blender::bke::greasepencil::Drawing &drawing) {
bke::crazyspace::GeometryDeformation deformation =
bke::crazyspace::get_evaluated_grease_pencil_drawing_deformation(
ob_eval, *vc->obedit, drawing_index);
changed |= ed::curves::select_box(
*vc, drawing.geometry.wrap(), deformation.positions, selection_domain, *rect, sel_op);
changed |= ed::curves::select_box(*vc,
drawing.strokes_for_write(),
deformation.positions,
selection_domain,
*rect,
sel_op);
});
if (changed) {

View File

@ -302,7 +302,7 @@ typedef struct TransSnap {
short face_nearest_steps;
eTSnap status;
/* Snapped Element Type (currently for objects only). */
eSnapMode snapElem;
eSnapMode target_type;
/** snapping from this point (in global-space). */
float snap_source[3];
/** to this point (in global-space). */

View File

@ -399,11 +399,11 @@ static void applyAxisConstraintVec(const TransInfo *t,
if (transform_snap_is_active(t)) {
if (validSnap(t)) {
is_snap_to_edge = (t->tsnap.snapElem & SCE_SNAP_TO_EDGE) != 0;
is_snap_to_face = (t->tsnap.snapElem & SCE_SNAP_TO_FACE) != 0;
is_snap_to_edge = (t->tsnap.target_type & SCE_SNAP_TO_EDGE) != 0;
is_snap_to_face = (t->tsnap.target_type & SCE_SNAP_TO_FACE) != 0;
is_snap_to_point = !is_snap_to_edge && !is_snap_to_face;
}
else if (t->tsnap.snapElem & SCE_SNAP_TO_GRID) {
else if (t->tsnap.target_type & SCE_SNAP_TO_GRID) {
is_snap_to_point = true;
}
}

View File

@ -1294,11 +1294,11 @@ static void edge_slide_snap_apply(TransInfo *t, float *value)
side_index = t_snap >= t_mid;
}
if (t->tsnap.snapElem & (SCE_SNAP_TO_EDGE | SCE_SNAP_TO_FACE)) {
if (t->tsnap.target_type & (SCE_SNAP_TO_EDGE | SCE_SNAP_TO_FACE)) {
float co_dir[3];
sub_v3_v3v3(co_dir, co_dest[side_index], co_orig);
normalize_v3(co_dir);
if (t->tsnap.snapElem & SCE_SNAP_TO_EDGE) {
if (t->tsnap.target_type & SCE_SNAP_TO_EDGE) {
transform_constraint_snap_axis_to_edge(t, co_dir, dvec);
}
else {

View File

@ -75,7 +75,6 @@ static void snapsource_confirm(TransInfo *t)
getSnapPoint(t, t->tsnap.snap_source);
t->tsnap.snap_source_fn = NULL;
t->tsnap.status |= SNAP_SOURCE_FOUND;
t->flag |= T_DRAW_SNAP_SOURCE;
struct SnapSouceCustomData *customdata = t->custom.mode.data;
t->tsnap.mode = customdata->snap_mode_confirm;
@ -152,6 +151,9 @@ static void snapsource_transform_fn(TransInfo *t, const int UNUSED(mval[2]))
BLI_assert(t->modifiers & MOD_EDIT_SNAP_SOURCE);
t->tsnap.snap_target_fn(t, NULL);
if (t->tsnap.status & SNAP_MULTI_POINTS) {
getSnapPoint(t, t->tsnap.snap_source);
}
t->redraw |= TREDRAW_SOFT;
}
@ -184,6 +186,7 @@ void transform_mode_snap_source_init(TransInfo *t, wmOperator *UNUSED(op))
}
t->mode_info = &TransMode_snapsource;
t->flag |= T_DRAW_SNAP_SOURCE;
t->tsnap.target_operation = SCE_SNAP_TARGET_ALL;
t->tsnap.status &= ~SNAP_SOURCE_FOUND;
@ -194,7 +197,7 @@ void transform_mode_snap_source_init(TransInfo *t, wmOperator *UNUSED(op))
if ((t->tsnap.mode & ~(SCE_SNAP_TO_INCREMENT | SCE_SNAP_TO_GRID)) == 0) {
/* Initialize snap modes for geometry. */
t->tsnap.mode &= ~(SCE_SNAP_TO_INCREMENT | SCE_SNAP_TO_GRID);
t->tsnap.mode |= SCE_SNAP_TO_GEOM;
t->tsnap.mode |= SCE_SNAP_TO_GEOM & ~SCE_SNAP_TO_EDGE_PERPENDICULAR;
if (!(customdata->snap_mode_confirm & SCE_SNAP_TO_EDGE_PERPENDICULAR)) {
customdata->snap_mode_confirm = t->tsnap.mode;

View File

@ -384,7 +384,7 @@ static void translate_snap_grid_apply(TransInfo *t,
float in[3];
if (t->con.mode & CON_APPLY) {
BLI_assert(t->tsnap.snapElem == SCE_SNAP_TO_NONE);
BLI_assert(t->tsnap.target_type == SCE_SNAP_TO_NONE);
t->con.applyVec(t, NULL, NULL, loc, in);
}
else {
@ -429,7 +429,7 @@ static bool translate_snap_grid(TransInfo *t, float *val)
}
translate_snap_grid_apply(t, t->idx_max, grid_dist, val, val);
t->tsnap.snapElem = SCE_SNAP_TO_GRID;
t->tsnap.target_type = SCE_SNAP_TO_GRID;
return true;
}
@ -627,7 +627,7 @@ static void applyTranslation(TransInfo *t, const int UNUSED(mval[2]))
/* Test for mixed snap with grid. */
float snap_dist_sq = FLT_MAX;
if (t->tsnap.snapElem != SCE_SNAP_TO_NONE) {
if (t->tsnap.target_type != SCE_SNAP_TO_NONE) {
snap_dist_sq = len_squared_v3v3(t->values, global_dir);
}
if ((snap_dist_sq == FLT_MAX) || (len_squared_v3v3(global_dir, incr_dir) < snap_dist_sq)) {

View File

@ -539,11 +539,11 @@ static void vert_slide_snap_apply(TransInfo *t, float *value)
getSnapPoint(t, dvec);
sub_v3_v3(dvec, t->tsnap.snap_source);
if (t->tsnap.snapElem & (SCE_SNAP_TO_EDGE | SCE_SNAP_TO_FACE)) {
if (t->tsnap.target_type & (SCE_SNAP_TO_EDGE | SCE_SNAP_TO_FACE)) {
float co_dir[3];
sub_v3_v3v3(co_dir, co_curr_3d, co_orig_3d);
normalize_v3(co_dir);
if (t->tsnap.snapElem & SCE_SNAP_TO_EDGE) {
if (t->tsnap.target_type & SCE_SNAP_TO_EDGE) {
transform_constraint_snap_axis_to_edge(t, co_dir, dvec);
}
else {

View File

@ -174,7 +174,8 @@ void drawSnapping(const bContext *C, TransInfo *t)
return;
}
const bool draw_source = (t->tsnap.status & SNAP_SOURCE_FOUND) && (t->flag & T_DRAW_SNAP_SOURCE);
const bool draw_source = (t->flag & T_DRAW_SNAP_SOURCE) &&
(t->tsnap.status & (SNAP_SOURCE_FOUND | SNAP_MULTI_POINTS));
const bool draw_target = (t->tsnap.status & (SNAP_TARGET_FOUND | SNAP_MULTI_POINTS));
if (!(draw_source || draw_target)) {
@ -197,9 +198,9 @@ void drawSnapping(const bContext *C, TransInfo *t)
}
if (t->spacetype == SPACE_VIEW3D) {
const float *loc_cur = nullptr;
const float *loc_prev = nullptr;
const float *normal = nullptr;
const float *source_loc = nullptr;
const float *target_loc = nullptr;
const float *target_normal = nullptr;
GPU_depth_test(GPU_DEPTH_NONE);
@ -233,19 +234,19 @@ void drawSnapping(const bContext *C, TransInfo *t)
/* draw normal if needed */
if (usingSnappingNormal(t) && validSnappingNormal(t)) {
normal = t->tsnap.snapNormal;
target_normal = t->tsnap.snapNormal;
}
if (draw_source) {
loc_prev = t->tsnap.snap_source;
source_loc = t->tsnap.snap_source;
}
if (t->tsnap.status & SNAP_TARGET_FOUND) {
loc_cur = t->tsnap.snap_target;
target_loc = t->tsnap.snap_target;
}
ED_view3d_cursor_snap_draw_util(
rv3d, loc_prev, loc_cur, normal, col, activeCol, t->tsnap.snapElem);
rv3d, source_loc, target_loc, target_normal, col, activeCol, t->tsnap.target_type);
GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
}
@ -543,7 +544,7 @@ void transform_snap_mixed_apply(TransInfo *t, float *vec)
void resetSnapping(TransInfo *t)
{
t->tsnap.status = SNAP_RESETTED;
t->tsnap.snapElem = SCE_SNAP_TO_NONE;
t->tsnap.target_type = SCE_SNAP_TO_NONE;
t->tsnap.mode = SCE_SNAP_TO_NONE;
t->tsnap.target_operation = SCE_SNAP_TARGET_ALL;
t->tsnap.source_operation = SCE_SNAP_SOURCE_CLOSEST;
@ -1123,7 +1124,7 @@ static void snap_target_view3d_fn(TransInfo *t, float * /*vec*/)
t->tsnap.status &= ~SNAP_TARGET_FOUND;
}
t->tsnap.snapElem = snap_elem;
t->tsnap.target_type = snap_elem;
}
static void snap_target_uv_fn(TransInfo *t, float * /*vec*/)

View File

@ -96,19 +96,11 @@ static bool test_projected_edge_dist(const DistProjectedAABBPrecalc *precalc,
return test_projected_vert_dist(precalc, clip_plane, clip_plane_len, is_persp, near_co, nearest);
}
Nearest2dUserData::Nearest2dUserData(SnapObjectContext *sctx,
Object *ob_eval,
const ID *id_eval,
const float4x4 &obmat)
SnapData::SnapData(SnapObjectContext *sctx, const float4x4 &obmat)
: nearest_precalc(),
obmat_(obmat),
is_persp(sctx->runtime.rv3d ? sctx->runtime.rv3d->is_persp : false),
use_backface_culling(sctx->runtime.params.use_backface_culling),
/* To register the result. */
sctx_(sctx),
ob_(ob_eval),
id_(id_eval),
obmat_(obmat)
use_backface_culling(sctx->runtime.params.use_backface_culling)
{
if (sctx->runtime.rv3d) {
this->pmat_local = float4x4(sctx->runtime.rv3d->persmat) * obmat;
@ -125,32 +117,8 @@ Nearest2dUserData::Nearest2dUserData(SnapObjectContext *sctx,
copy_v3_fl3(this->nearest_point.no, 0.0f, 0.0f, 1.0f);
}
Nearest2dUserData::~Nearest2dUserData()
void SnapData::clip_planes_enable(SnapObjectContext *sctx, bool skip_occlusion_plane)
{
if (this->nearest_point.index == -2) {
return;
}
SnapObjectContext *sctx = this->sctx_;
copy_v3_v3(sctx->ret.loc, this->nearest_point.co);
copy_v3_v3(sctx->ret.no, this->nearest_point.no);
sctx->ret.index = this->nearest_point.index;
copy_m4_m4(sctx->ret.obmat, this->obmat_.ptr());
sctx->ret.ob = this->ob_;
sctx->ret.data = this->id_;
sctx->ret.dist_px_sq = this->nearest_point.dist_sq;
/* Global space. */
mul_m4_v3(this->obmat_.ptr(), sctx->ret.loc);
mul_mat3_m4_v3(this->obmat_.ptr(), sctx->ret.no);
normalize_v3(sctx->ret.no);
}
void Nearest2dUserData::clip_planes_enable(bool skip_occlusion_plane)
{
SnapObjectContext *sctx = this->sctx_;
float(*clip_planes)[4] = sctx->runtime.clip_plane;
int clip_plane_len = sctx->runtime.clip_plane_len;
@ -168,7 +136,7 @@ void Nearest2dUserData::clip_planes_enable(bool skip_occlusion_plane)
BLI_assert(this->clip_planes.size() == clip_plane_len);
}
bool Nearest2dUserData::snap_boundbox(const float3 &min, const float3 &max)
bool SnapData::snap_boundbox(const float3 &min, const float3 &max)
{
/* In vertex and edges you need to get the pixel distance from ray to BoundBox,
* see: #46099, #46816 */
@ -194,7 +162,7 @@ bool Nearest2dUserData::snap_boundbox(const float3 &min, const float3 &max)
return true;
}
bool Nearest2dUserData::snap_point(const float3 &co, int index)
bool SnapData::snap_point(const float3 &co, int index)
{
if (test_projected_vert_dist(&this->nearest_precalc,
reinterpret_cast<const float(*)[4]>(this->clip_planes.data()),
@ -209,7 +177,7 @@ bool Nearest2dUserData::snap_point(const float3 &co, int index)
return false;
}
bool Nearest2dUserData::snap_edge(const float3 &va, const float3 &vb, int edge_index)
bool SnapData::snap_edge(const float3 &va, const float3 &vb, int edge_index)
{
if (test_projected_edge_dist(&this->nearest_precalc,
reinterpret_cast<const float(*)[4]>(this->clip_planes.data()),
@ -226,10 +194,11 @@ bool Nearest2dUserData::snap_edge(const float3 &va, const float3 &vb, int edge_i
return false;
}
eSnapMode Nearest2dUserData::snap_edge_points(int edge_index, float dist_px_sq_orig)
eSnapMode SnapData::snap_edge_points_impl(SnapObjectContext *sctx,
int edge_index,
float dist_px_sq_orig)
{
eSnapMode elem = SCE_SNAP_TO_EDGE;
SnapObjectContext *sctx = this->sctx_;
int vindex[2];
this->get_edge_verts_index(edge_index, vindex);
@ -251,7 +220,8 @@ eSnapMode Nearest2dUserData::snap_edge_points(int edge_index, float dist_px_sq_o
this->nearest_point.dist_sq = dist_px_sq_orig;
eSnapMode snap_to = sctx->runtime.snap_to_flag;
int e_mode_len = ((snap_to & SCE_SNAP_TO_EDGE) != 0) + ((snap_to & SCE_SNAP_TO_VERTEX) != 0) +
int e_mode_len = ((snap_to & SCE_SNAP_TO_EDGE) != 0) +
((snap_to & SCE_SNAP_TO_EDGE_ENDPOINT) != 0) +
((snap_to & SCE_SNAP_TO_EDGE_MIDPOINT) != 0);
float range = 1.0f / (2 * e_mode_len - 1);
@ -287,12 +257,12 @@ eSnapMode Nearest2dUserData::snap_edge_points(int edge_index, float dist_px_sq_o
}
/* Leave this one for last so it doesn't change the normal. */
if (snap_to & SCE_SNAP_TO_VERTEX) {
if (snap_to & SCE_SNAP_TO_EDGE_ENDPOINT) {
if (lambda < (range) || (1.0f - range) < lambda) {
int v_id = lambda < 0.5f ? 0 : 1;
if (this->snap_point(v_pair[v_id], v_id)) {
elem = SCE_SNAP_TO_VERTEX;
elem = SCE_SNAP_TO_EDGE_ENDPOINT;
this->copy_vert_no(vindex[v_id], this->nearest_point.no);
}
}
@ -302,6 +272,29 @@ eSnapMode Nearest2dUserData::snap_edge_points(int edge_index, float dist_px_sq_o
return elem;
}
void SnapData::register_result(SnapObjectContext *sctx, Object *ob_eval, const ID *id_eval)
{
BLI_assert(this->nearest_point.index != -2);
copy_v3_v3(sctx->ret.loc, this->nearest_point.co);
copy_v3_v3(sctx->ret.no, this->nearest_point.no);
sctx->ret.index = this->nearest_point.index;
copy_m4_m4(sctx->ret.obmat, this->obmat_.ptr());
sctx->ret.ob = ob_eval;
sctx->ret.data = id_eval;
sctx->ret.dist_px_sq = this->nearest_point.dist_sq;
/* Global space. */
mul_m4_v3(this->obmat_.ptr(), sctx->ret.loc);
mul_mat3_m4_v3(this->obmat_.ptr(), sctx->ret.no);
normalize_v3(sctx->ret.no);
#if DEBUG
/* Make sure this is only called once. */
this->nearest_point.index = -2;
#endif
}
/* -------------------------------------------------------------------- */
/** \name Utilities
* \{ */
@ -609,11 +602,6 @@ static bool raycastObjects(SnapObjectContext *sctx)
/** \name Surface Snap Functions
* \{ */
struct NearestWorldObjUserData {
const float *init_co;
const float *curr_co;
};
static void nearest_world_tree_co(BVHTree *tree,
BVHTree_NearestPointCallback nearest_cb,
void *treedata,
@ -772,7 +760,7 @@ void cb_snap_vert(void *userdata,
const int clip_plane_len,
BVHTreeNearest *nearest)
{
Nearest2dUserData *data = static_cast<Nearest2dUserData *>(userdata);
SnapData *data = static_cast<SnapData *>(userdata);
const float *co;
data->get_vert_co(index, &co);
@ -790,7 +778,7 @@ void cb_snap_edge(void *userdata,
const int clip_plane_len,
BVHTreeNearest *nearest)
{
Nearest2dUserData *data = static_cast<Nearest2dUserData *>(userdata);
SnapData *data = static_cast<SnapData *>(userdata);
int vindex[2];
data->get_edge_verts_index(index, vindex);
@ -866,16 +854,16 @@ eSnapMode snap_object_center(SnapObjectContext *sctx,
}
/* For now only vertex supported. */
if ((snap_to_flag & SCE_SNAP_TO_VERTEX) == 0) {
if ((snap_to_flag & SCE_SNAP_TO_POINT) == 0) {
return SCE_SNAP_TO_NONE;
}
Nearest2dUserData nearest2d(
sctx, ob_eval, static_cast<const ID *>(ob_eval->data), float4x4(obmat));
SnapData nearest2d(sctx, float4x4(obmat));
nearest2d.clip_planes_enable();
nearest2d.clip_planes_enable(sctx);
if (nearest2d.snap_point(float3(0.0f))) {
nearest2d.register_result(sctx, ob_eval, static_cast<const ID *>(ob_eval->data));
return SCE_SNAP_TO_VERTEX;
}
@ -1353,16 +1341,11 @@ eSnapMode ED_transform_snap_object_project_view3d_ex(SnapObjectContext *sctx,
}
}
if (snap_to_flag & (SCE_SNAP_TO_VERTEX | SCE_SNAP_TO_EDGE | SCE_SNAP_TO_EDGE_MIDPOINT |
SCE_SNAP_TO_EDGE_PERPENDICULAR))
{
if (snap_to_flag & (SCE_SNAP_TO_POINT | SNAP_TO_EDGE_ELEMENTS)) {
eSnapMode elem_test, elem = SCE_SNAP_TO_NONE;
/* First snap to edge instead of middle or perpendicular. */
sctx->runtime.snap_to_flag &= (SCE_SNAP_TO_VERTEX | SCE_SNAP_TO_EDGE);
if (snap_to_flag & (SCE_SNAP_TO_EDGE_MIDPOINT | SCE_SNAP_TO_EDGE_PERPENDICULAR)) {
sctx->runtime.snap_to_flag |= SCE_SNAP_TO_EDGE;
}
/* Remove what has already been computed. */
sctx->runtime.snap_to_flag &= ~(SCE_SNAP_TO_FACE | SCE_SNAP_INDIVIDUAL_NEAREST);
/* By convention we only snap to the original elements of a curve. */
if (has_hit && sctx->ret.ob->type != OB_CURVES_LEGACY) {
@ -1398,11 +1381,7 @@ eSnapMode ED_transform_snap_object_project_view3d_ex(SnapObjectContext *sctx,
elem = elem_test;
}
if ((elem == SCE_SNAP_TO_EDGE) &&
(snap_to_flag &
(SCE_SNAP_TO_VERTEX | SCE_SNAP_TO_EDGE_MIDPOINT | SCE_SNAP_TO_EDGE_PERPENDICULAR)))
{
sctx->runtime.snap_to_flag = snap_to_flag;
if ((elem == SCE_SNAP_TO_EDGE) && (snap_to_flag & SNAP_TO_EDGE_ELEMENTS)) {
elem = snap_edge_points(sctx, square_f(*dist_px));
}

View File

@ -10,12 +10,16 @@
#define MAX_CLIPPLANE_LEN 3
struct SnapData_EditMesh;
#define SNAP_TO_EDGE_ELEMENTS \
(SCE_SNAP_TO_EDGE | SCE_SNAP_TO_EDGE_ENDPOINT | SCE_SNAP_TO_EDGE_MIDPOINT | \
SCE_SNAP_TO_EDGE_PERPENDICULAR)
struct SnapCache_EditMesh;
struct SnapObjectContext {
struct Scene *scene;
blender::Map<const BMEditMesh *, std::unique_ptr<SnapData_EditMesh>> editmesh_caches;
blender::Map<const BMEditMesh *, std::unique_ptr<SnapCache_EditMesh>> editmesh_caches;
/* Filter data, returns true to check this value */
struct {
@ -92,12 +96,13 @@ struct RayCastAll_Data {
ListBase *hit_list;
};
class Nearest2dUserData {
class SnapData {
public:
/* Read-only. */
DistProjectedAABBPrecalc nearest_precalc;
blender::Vector<blender::float4, MAX_CLIPPLANE_LEN> clip_planes;
blender::float4x4 pmat_local;
blender::float4x4 obmat_;
const bool is_persp;
const bool use_backface_culling;
@ -106,31 +111,21 @@ class Nearest2dUserData {
public:
/* Constructor. */
Nearest2dUserData(SnapObjectContext *sctx,
Object *ob_eval,
const ID *id_eval,
const blender::float4x4 &obmat = blender::float4x4::identity());
SnapData(SnapObjectContext *sctx,
const blender::float4x4 &obmat = blender::float4x4::identity());
/* Destructor. */
~Nearest2dUserData();
void clip_planes_enable(bool skip_occlusion_plane = false);
void clip_planes_enable(SnapObjectContext *sctx, bool skip_occlusion_plane = false);
bool snap_boundbox(const blender::float3 &min, const blender::float3 &max);
bool snap_point(const blender::float3 &co, int index = -1);
bool snap_edge(const blender::float3 &va, const blender::float3 &vb, int edge_index = -1);
eSnapMode snap_edge_points(int edge_index, float dist_px_sq_orig);
eSnapMode snap_edge_points_impl(SnapObjectContext *sctx, int edge_index, float dist_px_sq_orig);
void register_result(SnapObjectContext *sctx, Object *ob_eval, const ID *id_eval);
virtual void get_vert_co(const int /*index*/, const float ** /*r_co*/){};
virtual void get_edge_verts_index(const int /*index*/, int /*r_v_index*/[2]){};
virtual void get_tri_verts_index(const int /*index*/, int /*r_v_index*/[3]){};
virtual void get_tri_edges_index(const int /*index*/, int /*r_e_index*/[3]){};
virtual void copy_vert_no(const int /*index*/, float /*r_no*/[3]){};
protected:
SnapObjectContext *sctx_;
Object *ob_;
const ID *id_;
const blender::float4x4 &obmat_;
};
/* transform_snap_object.cc */
@ -185,8 +180,8 @@ eSnapMode snapCurve(SnapObjectContext *sctx, Object *ob_eval, const float obmat[
/* transform_snap_object_editmesh.cc */
struct SnapData_EditMesh {
/* Verts, Edges. */
struct SnapCache_EditMesh {
/* Loose Verts, Edges. */
BVHTree *bvhtree[2];
bool cached[2];
@ -198,7 +193,7 @@ struct SnapData_EditMesh {
void clear();
~SnapData_EditMesh()
~SnapCache_EditMesh()
{
this->clear();
}

View File

@ -34,7 +34,7 @@ eSnapMode snapArmature(SnapObjectContext *sctx,
bArmature *arm = static_cast<bArmature *>(ob_eval->data);
Nearest2dUserData nearest2d(sctx, ob_eval, &arm->id, float4x4(obmat));
SnapData nearest2d(sctx, float4x4(obmat));
const bool is_editmode = arm->edbo != nullptr;
@ -45,7 +45,7 @@ eSnapMode snapArmature(SnapObjectContext *sctx,
}
}
nearest2d.clip_planes_enable();
nearest2d.clip_planes_enable(sctx);
const float *head_vec = nullptr, *tail_vec = nullptr;
@ -100,11 +100,11 @@ eSnapMode snapArmature(SnapObjectContext *sctx,
nearest2d.nearest_point.index = -2;
}
if (sctx->runtime.snap_to_flag & SCE_SNAP_TO_VERTEX) {
if (sctx->runtime.snap_to_flag & SCE_SNAP_TO_EDGE_ENDPOINT) {
float dist_px_sq_edge = nearest2d.nearest_point.dist_sq;
nearest2d.nearest_point.dist_sq = sctx->ret.dist_px_sq;
if (nearest2d.snap_point(head_vec) || nearest2d.snap_point(tail_vec)) {
retval = SCE_SNAP_TO_VERTEX;
retval = SCE_SNAP_TO_EDGE_ENDPOINT;
}
else if (retval) {
nearest2d.nearest_point.dist_sq = dist_px_sq_edge;
@ -112,5 +112,8 @@ eSnapMode snapArmature(SnapObjectContext *sctx,
}
}
if (retval) {
nearest2d.register_result(sctx, ob_eval, &arm->id);
}
return retval;
}

View File

@ -25,7 +25,7 @@ eSnapMode snapCamera(SnapObjectContext *sctx,
{
eSnapMode retval = SCE_SNAP_TO_NONE;
if (!(sctx->runtime.snap_to_flag & SCE_SNAP_TO_VERTEX)) {
if (!(sctx->runtime.snap_to_flag & SCE_SNAP_TO_POINT)) {
return retval;
}
@ -44,8 +44,8 @@ eSnapMode snapCamera(SnapObjectContext *sctx,
BKE_tracking_get_camera_object_matrix(object, orig_camera_mat);
invert_m4_m4(orig_camera_imat, orig_camera_mat);
Nearest2dUserData nearest2d(sctx, object, static_cast<const ID *>(object->data));
nearest2d.clip_planes_enable();
SnapData nearest2d(sctx);
nearest2d.clip_planes_enable(sctx);
MovieTracking *tracking = &clip->tracking;
LISTBASE_FOREACH (MovieTrackingObject *, tracking_object, &tracking->objects) {
@ -77,10 +77,13 @@ eSnapMode snapCamera(SnapObjectContext *sctx,
mul_m4_v3(vertex_obmat, bundle_pos);
if (nearest2d.snap_point(bundle_pos)) {
retval = SCE_SNAP_TO_VERTEX;
retval = SCE_SNAP_TO_POINT;
}
}
}
return SCE_SNAP_TO_NONE;
if (retval) {
nearest2d.register_result(sctx, object, static_cast<const ID *>(object->data));
}
return retval;
}

View File

@ -27,13 +27,13 @@ eSnapMode snapCurve(SnapObjectContext *sctx, Object *ob_eval, const float obmat[
bool has_snap = false;
/* Only vertex snapping mode (eg control points and handles) supported for now). */
if ((sctx->runtime.snap_to_flag & SCE_SNAP_TO_VERTEX) == 0) {
if ((sctx->runtime.snap_to_flag & SCE_SNAP_TO_POINT) == 0) {
return SCE_SNAP_TO_NONE;
}
Curve *cu = static_cast<Curve *>(ob_eval->data);
Nearest2dUserData nearest2d(sctx, ob_eval, &cu->id, float4x4(obmat));
SnapData nearest2d(sctx, float4x4(obmat));
const bool use_obedit = BKE_object_is_in_editmode(ob_eval);
@ -45,69 +45,70 @@ eSnapMode snapCurve(SnapObjectContext *sctx, Object *ob_eval, const float obmat[
}
}
nearest2d.clip_planes_enable(true);
nearest2d.clip_planes_enable(sctx, true);
bool skip_selected = (sctx->runtime.params.snap_target_select & SCE_SNAP_TARGET_NOT_SELECTED) !=
0;
LISTBASE_FOREACH (Nurb *, nu, (use_obedit ? &cu->editnurb->nurbs : &cu->nurb)) {
for (int u = 0; u < nu->pntsu; u++) {
if (sctx->runtime.snap_to_flag & SCE_SNAP_TO_VERTEX) {
if (use_obedit) {
if (nu->bezt) {
if (nu->bezt[u].hide) {
/* Skip hidden. */
continue;
}
bool is_selected = (nu->bezt[u].f2 & SELECT) != 0;
if (is_selected && skip_selected) {
continue;
}
has_snap |= nearest2d.snap_point(nu->bezt[u].vec[1]);
/* Don't snap if handle is selected (moving),
* or if it is aligning to a moving handle. */
bool is_selected_h1 = (nu->bezt[u].f1 & SELECT) != 0;
bool is_selected_h2 = (nu->bezt[u].f3 & SELECT) != 0;
bool is_autoalign_h1 = (nu->bezt[u].h1 & HD_ALIGN) != 0;
bool is_autoalign_h2 = (nu->bezt[u].h2 & HD_ALIGN) != 0;
if (!skip_selected || !(is_selected_h1 || (is_autoalign_h1 && is_selected_h2))) {
has_snap |= nearest2d.snap_point(nu->bezt[u].vec[0]);
}
if (!skip_selected || !(is_selected_h2 || (is_autoalign_h2 && is_selected_h1))) {
has_snap |= nearest2d.snap_point(nu->bezt[u].vec[2]);
}
if (use_obedit) {
if (nu->bezt) {
if (nu->bezt[u].hide) {
/* Skip hidden. */
continue;
}
else {
if (nu->bp[u].hide) {
/* Skip hidden. */
continue;
}
bool is_selected = (nu->bp[u].f1 & SELECT) != 0;
if (is_selected && skip_selected) {
continue;
}
bool is_selected = (nu->bezt[u].f2 & SELECT) != 0;
if (is_selected && skip_selected) {
continue;
}
has_snap |= nearest2d.snap_point(nu->bezt[u].vec[1]);
has_snap |= nearest2d.snap_point(nu->bp[u].vec);
/* Don't snap if handle is selected (moving),
* or if it is aligning to a moving handle. */
bool is_selected_h1 = (nu->bezt[u].f1 & SELECT) != 0;
bool is_selected_h2 = (nu->bezt[u].f3 & SELECT) != 0;
bool is_autoalign_h1 = (nu->bezt[u].h1 & HD_ALIGN) != 0;
bool is_autoalign_h2 = (nu->bezt[u].h2 & HD_ALIGN) != 0;
if (!skip_selected || !(is_selected_h1 || (is_autoalign_h1 && is_selected_h2))) {
has_snap |= nearest2d.snap_point(nu->bezt[u].vec[0]);
}
if (!skip_selected || !(is_selected_h2 || (is_autoalign_h2 && is_selected_h1))) {
has_snap |= nearest2d.snap_point(nu->bezt[u].vec[2]);
}
}
else {
/* Curve is not visible outside editmode if nurb length less than two. */
if (nu->pntsu > 1) {
if (nu->bezt) {
has_snap |= nearest2d.snap_point(nu->bezt[u].vec[1]);
}
else {
has_snap |= nearest2d.snap_point(nu->bp[u].vec);
}
if (nu->bp[u].hide) {
/* Skip hidden. */
continue;
}
bool is_selected = (nu->bp[u].f1 & SELECT) != 0;
if (is_selected && skip_selected) {
continue;
}
has_snap |= nearest2d.snap_point(nu->bp[u].vec);
}
}
else {
/* Curve is not visible outside editmode if nurb length less than two. */
if (nu->pntsu > 1) {
if (nu->bezt) {
has_snap |= nearest2d.snap_point(nu->bezt[u].vec[1]);
}
else {
has_snap |= nearest2d.snap_point(nu->bp[u].vec);
}
}
}
}
}
return has_snap ? SCE_SNAP_TO_VERTEX : SCE_SNAP_TO_NONE;
if (has_snap) {
nearest2d.register_result(sctx, ob_eval, &cu->id);
return SCE_SNAP_TO_VERTEX;
}
return SCE_SNAP_TO_NONE;
}

View File

@ -27,7 +27,7 @@ using namespace blender;
/** \name Snap Object Data
* \{ */
void SnapData_EditMesh::clear()
void SnapCache_EditMesh::clear()
{
for (int i = 0; i < ARRAY_SIZE(this->bvhtree); i++) {
if (!this->cached[i]) {
@ -77,46 +77,48 @@ static blender::bke::MeshRuntime *snap_object_data_editmesh_runtime_get(Object *
return ((Mesh *)ob_eval->data)->runtime;
}
static SnapData_EditMesh *snap_object_data_editmesh_get(SnapObjectContext *sctx,
Object *ob_eval,
BMEditMesh *em,
const bool create)
static SnapCache_EditMesh *snap_object_data_editmesh_get(SnapObjectContext *sctx,
Object *ob_eval,
BMEditMesh *em,
const bool create)
{
SnapData_EditMesh *sod = nullptr;
SnapCache_EditMesh *em_cache = nullptr;
bool init = false;
if (std::unique_ptr<SnapData_EditMesh> *sod_p = sctx->editmesh_caches.lookup_ptr(em)) {
sod = sod_p->get();
if (std::unique_ptr<SnapCache_EditMesh> *em_cache_p = sctx->editmesh_caches.lookup_ptr(em)) {
em_cache = em_cache_p->get();
bool is_dirty = false;
/* Check if the geometry has changed. */
if (sod->treedata_editmesh.em != em) {
if (em_cache->treedata_editmesh.em != em) {
is_dirty = true;
}
else if (sod->mesh_runtime) {
if (sod->mesh_runtime != snap_object_data_editmesh_runtime_get(ob_eval)) {
else if (em_cache->mesh_runtime) {
if (em_cache->mesh_runtime != snap_object_data_editmesh_runtime_get(ob_eval)) {
if (G.moving) {
/* WORKAROUND: avoid updating while transforming. */
BLI_assert(!sod->treedata_editmesh.cached && !sod->cached[0] && !sod->cached[1]);
sod->mesh_runtime = snap_object_data_editmesh_runtime_get(ob_eval);
BLI_assert(!em_cache->treedata_editmesh.cached && !em_cache->cached[0] &&
!em_cache->cached[1]);
em_cache->mesh_runtime = snap_object_data_editmesh_runtime_get(ob_eval);
}
else {
is_dirty = true;
}
}
else if (sod->treedata_editmesh.tree && sod->treedata_editmesh.cached &&
!bvhcache_has_tree(sod->mesh_runtime->bvh_cache, sod->treedata_editmesh.tree))
else if (em_cache->treedata_editmesh.tree && em_cache->treedata_editmesh.cached &&
!bvhcache_has_tree(em_cache->mesh_runtime->bvh_cache,
em_cache->treedata_editmesh.tree))
{
/* The tree is owned by the EditMesh and may have been freed since we last used! */
is_dirty = true;
}
else if (sod->bvhtree[0] && sod->cached[0] &&
!bvhcache_has_tree(sod->mesh_runtime->bvh_cache, sod->bvhtree[0]))
else if (em_cache->bvhtree[0] && em_cache->cached[0] &&
!bvhcache_has_tree(em_cache->mesh_runtime->bvh_cache, em_cache->bvhtree[0]))
{
/* The tree is owned by the EditMesh and may have been freed since we last used! */
is_dirty = true;
}
else if (sod->bvhtree[1] && sod->cached[1] &&
!bvhcache_has_tree(sod->mesh_runtime->bvh_cache, sod->bvhtree[1]))
else if (em_cache->bvhtree[1] && em_cache->cached[1] &&
!bvhcache_has_tree(em_cache->mesh_runtime->bvh_cache, em_cache->bvhtree[1]))
{
/* The tree is owned by the EditMesh and may have been freed since we last used! */
is_dirty = true;
@ -124,14 +126,14 @@ static SnapData_EditMesh *snap_object_data_editmesh_get(SnapObjectContext *sctx,
}
if (is_dirty) {
sod->clear();
em_cache->clear();
init = true;
}
}
else if (create) {
std::unique_ptr<SnapData_EditMesh> sod_ptr = std::make_unique<SnapData_EditMesh>();
sod = sod_ptr.get();
sctx->editmesh_caches.add_new(em, std::move(sod_ptr));
std::unique_ptr<SnapCache_EditMesh> em_cache_ptr = std::make_unique<SnapCache_EditMesh>();
em_cache = em_cache_ptr.get();
sctx->editmesh_caches.add_new(em, std::move(em_cache_ptr));
init = true;
}
@ -139,22 +141,22 @@ static SnapData_EditMesh *snap_object_data_editmesh_get(SnapObjectContext *sctx,
/* Operators only update the editmesh looptris of the original mesh. */
BLI_assert(em == BKE_editmesh_from_object(DEG_get_original_object(ob_eval)));
sod->treedata_editmesh.em = em;
sod->mesh_runtime = snap_object_data_editmesh_runtime_get(ob_eval);
snap_editmesh_minmax(sctx, em->bm, sod->min, sod->max);
em_cache->treedata_editmesh.em = em;
em_cache->mesh_runtime = snap_object_data_editmesh_runtime_get(ob_eval);
snap_editmesh_minmax(sctx, em->bm, em_cache->min, em_cache->max);
}
return sod;
return em_cache;
}
static BVHTreeFromEditMesh *snap_object_data_editmesh_treedata_get(SnapData_EditMesh *sod,
static BVHTreeFromEditMesh *snap_object_data_editmesh_treedata_get(SnapCache_EditMesh *em_cache,
SnapObjectContext *sctx,
BMEditMesh *em)
{
BVHTreeFromEditMesh *treedata = &sod->treedata_editmesh;
BVHTreeFromEditMesh *treedata = &em_cache->treedata_editmesh;
if (treedata->tree == nullptr) {
em = sod->treedata_editmesh.em;
em = em_cache->treedata_editmesh.em;
if (sctx->callbacks.edit_mesh.test_face_fn) {
BMesh *bm = em->bm;
@ -177,8 +179,8 @@ static BVHTreeFromEditMesh *snap_object_data_editmesh_treedata_get(SnapData_Edit
4,
BVHTREE_FROM_EM_LOOPTRI,
/* WORKAROUND: avoid updating while transforming. */
G.moving ? nullptr : &sod->mesh_runtime->bvh_cache,
&sod->mesh_runtime->eval_mutex);
G.moving ? nullptr : &em_cache->mesh_runtime->bvh_cache,
&em_cache->mesh_runtime->eval_mutex);
}
}
if (treedata->tree == nullptr) {
@ -210,18 +212,18 @@ static eSnapMode editmesh_snap_mode_supported(BMEditMesh *em)
return snap_mode_supported;
}
static SnapData_EditMesh *editmesh_snapdata_init(SnapObjectContext *sctx,
Object *ob_eval,
eSnapMode snap_to_flag)
static SnapCache_EditMesh *editmesh_snapdata_init(SnapObjectContext *sctx,
Object *ob_eval,
eSnapMode snap_to_flag)
{
BMEditMesh *em = BKE_editmesh_from_object(ob_eval);
if (em == nullptr) {
return nullptr;
}
SnapData_EditMesh *sod = snap_object_data_editmesh_get(sctx, ob_eval, em, false);
if (sod != nullptr) {
return sod;
SnapCache_EditMesh *em_cache = snap_object_data_editmesh_get(sctx, ob_eval, em, false);
if (em_cache != nullptr) {
return em_cache;
}
eSnapMode snap_mode_used = snap_to_flag & editmesh_snap_mode_supported(em);
@ -268,7 +270,7 @@ static void editmesh_looptri_raycast_backface_culling_cb(void *userdata,
}
}
static bool raycastEditMesh(SnapData_EditMesh *sod,
static bool raycastEditMesh(SnapCache_EditMesh *em_cache,
SnapObjectContext *sctx,
BMEditMesh *em,
const float obmat[4][4],
@ -299,7 +301,7 @@ static bool raycastEditMesh(SnapData_EditMesh *sod,
/* was BKE_boundbox_ray_hit_check, see: cf6ca226fa58 */
if (!isect_ray_aabb_v3_simple(
ray_start_local, ray_normal_local, sod->min, sod->max, &len_diff, nullptr))
ray_start_local, ray_normal_local, em_cache->min, em_cache->max, &len_diff, nullptr))
{
return retval;
}
@ -315,7 +317,7 @@ static bool raycastEditMesh(SnapData_EditMesh *sod,
len_diff = 0.0f;
}
BVHTreeFromEditMesh *treedata = snap_object_data_editmesh_treedata_get(sod, sctx, em);
BVHTreeFromEditMesh *treedata = snap_object_data_editmesh_treedata_get(em_cache, sctx, em);
if (treedata == nullptr) {
return retval;
}
@ -370,7 +372,7 @@ static bool raycastEditMesh(SnapData_EditMesh *sod,
sctx->ret.ray_depth_max = hit.dist;
em = sod->treedata_editmesh.em;
em = em_cache->treedata_editmesh.em;
sctx->ret.index = BM_elem_index_get(em->looptris[hit.index][0]->f);
retval = true;
@ -385,12 +387,12 @@ static bool raycastEditMesh(SnapData_EditMesh *sod,
/** \name Surface Snap Functions
* \{ */
static bool nearest_world_editmesh(SnapData_EditMesh *sod,
static bool nearest_world_editmesh(SnapCache_EditMesh *em_cache,
SnapObjectContext *sctx,
BMEditMesh *em,
const float (*obmat)[4])
{
BVHTreeFromEditMesh *treedata = snap_object_data_editmesh_treedata_get(sod, sctx, em);
BVHTreeFromEditMesh *treedata = snap_object_data_editmesh_treedata_get(em_cache, sctx, em);
if (treedata == nullptr) {
return false;
}
@ -404,15 +406,12 @@ static bool nearest_world_editmesh(SnapData_EditMesh *sod,
/** \name Subclass for Snapping to Edges or Points of an EditMesh
* \{ */
class Nearest2dUserData_EditMesh : public Nearest2dUserData {
class SnapData_EditMesh : public SnapData {
public:
BMesh *bm;
Nearest2dUserData_EditMesh(SnapObjectContext *sctx,
Object *ob_eval,
BMesh *bm,
const float4x4 &obmat)
: Nearest2dUserData(sctx, ob_eval, nullptr, obmat), bm(bm){};
SnapData_EditMesh(SnapObjectContext *sctx, BMesh *bm, const float4x4 &obmat)
: SnapData(sctx, obmat), bm(bm){};
void get_vert_co(const int index, const float **r_co)
{
@ -450,8 +449,8 @@ eSnapMode snap_polygon_editmesh(SnapObjectContext *sctx,
eSnapMode elem = SCE_SNAP_TO_NONE;
BMEditMesh *em = BKE_editmesh_from_object(ob_eval);
Nearest2dUserData_EditMesh nearest2d(sctx, ob_eval, em->bm, float4x4(obmat));
nearest2d.clip_planes_enable();
SnapData_EditMesh nearest2d(sctx, em->bm, float4x4(obmat));
nearest2d.clip_planes_enable(sctx);
BVHTreeNearest nearest{};
nearest.index = -1;
@ -475,7 +474,7 @@ eSnapMode snap_polygon_editmesh(SnapObjectContext *sctx,
} while ((l_iter = l_iter->next) != l_first);
}
else {
elem = SCE_SNAP_TO_VERTEX;
elem = SCE_SNAP_TO_EDGE_ENDPOINT;
BM_mesh_elem_index_ensure(em->bm, BM_VERT);
BM_mesh_elem_table_ensure(em->bm, BM_VERT);
do {
@ -490,6 +489,7 @@ eSnapMode snap_polygon_editmesh(SnapObjectContext *sctx,
if (nearest.index != -1) {
nearest2d.nearest_point = nearest;
nearest2d.register_result(sctx, ob_eval, nullptr);
return elem;
}
@ -504,11 +504,15 @@ eSnapMode snap_edge_points_editmesh(SnapObjectContext *sctx,
int edge)
{
BMEditMesh *em = BKE_editmesh_from_object(ob_eval);
Nearest2dUserData_EditMesh nearest2d(sctx, ob_eval, em->bm, float4x4(obmat));
return nearest2d.snap_edge_points(edge, dist_pex_sq_orig);
SnapData_EditMesh nearest2d(sctx, em->bm, float4x4(obmat));
eSnapMode elem = nearest2d.snap_edge_points_impl(sctx, edge, dist_pex_sq_orig);
if (nearest2d.nearest_point.index != -2) {
nearest2d.register_result(sctx, ob_eval, nullptr);
}
return elem;
}
static eSnapMode snapEditMesh(SnapData_EditMesh *sod,
static eSnapMode snapEditMesh(SnapCache_EditMesh *em_cache,
SnapObjectContext *sctx,
Object *ob_eval,
BMEditMesh *em,
@ -517,26 +521,30 @@ static eSnapMode snapEditMesh(SnapData_EditMesh *sod,
{
BLI_assert(snap_to_flag != SCE_SNAP_TO_FACE);
Nearest2dUserData_EditMesh nearest2d(sctx, ob_eval, em->bm, float4x4(obmat));
SnapData_EditMesh nearest2d(sctx, em->bm, float4x4(obmat));
/* Was BKE_boundbox_ray_hit_check, see: cf6ca226fa58. */
if (!nearest2d.snap_boundbox(sod->min, sod->max)) {
if (!nearest2d.snap_boundbox(em_cache->min, em_cache->max)) {
return SCE_SNAP_TO_NONE;
}
if (snap_to_flag & SCE_SNAP_TO_VERTEX) {
if (snap_to_flag & SCE_SNAP_TO_POINT) {
BVHTreeFromEditMesh treedata{};
treedata.tree = sod->bvhtree[0];
treedata.tree = em_cache->bvhtree[0];
if (treedata.tree == nullptr) {
if (sctx->callbacks.edit_mesh.test_vert_fn) {
auto test_looseverts_fn = [](BMElem *elem, void *user_data) {
SnapObjectContext *sctx_ = static_cast<SnapObjectContext *>(user_data);
BMVert *v = reinterpret_cast<BMVert *>(elem);
if (v->e) {
return false;
}
return sctx_->callbacks.edit_mesh.test_vert_fn(v, sctx_->callbacks.edit_mesh.user_data);
};
blender::BitVector<> verts_mask(em->bm->totvert);
const int verts_num_active = BM_iter_mesh_bitmap_from_filter(
BM_VERTS_OF_MESH,
em->bm,
verts_mask,
(bool (*)(BMElem *, void *))sctx->callbacks.edit_mesh.test_vert_fn,
sctx->callbacks.edit_mesh.user_data);
BM_VERTS_OF_MESH, em->bm, verts_mask, test_looseverts_fn, sctx);
bvhtree_from_editmesh_verts_ex(&treedata, em, verts_mask, verts_num_active, 0.0f, 2, 6);
}
@ -544,19 +552,19 @@ static eSnapMode snapEditMesh(SnapData_EditMesh *sod,
BKE_bvhtree_from_editmesh_get(&treedata,
em,
2,
BVHTREE_FROM_EM_VERTS,
BVHTREE_FROM_EM_LOOSEVERTS,
/* WORKAROUND: avoid updating while transforming. */
G.moving ? nullptr : &sod->mesh_runtime->bvh_cache,
&sod->mesh_runtime->eval_mutex);
G.moving ? nullptr : &em_cache->mesh_runtime->bvh_cache,
&em_cache->mesh_runtime->eval_mutex);
}
sod->bvhtree[0] = treedata.tree;
sod->cached[0] = treedata.cached;
em_cache->bvhtree[0] = treedata.tree;
em_cache->cached[0] = treedata.cached;
}
}
if (snap_to_flag & SCE_SNAP_TO_EDGE) {
if (snap_to_flag & SNAP_TO_EDGE_ELEMENTS) {
BVHTreeFromEditMesh treedata{};
treedata.tree = sod->bvhtree[1];
treedata.tree = em_cache->bvhtree[1];
if (treedata.tree == nullptr) {
if (sctx->callbacks.edit_mesh.test_edge_fn) {
@ -576,26 +584,26 @@ static eSnapMode snapEditMesh(SnapData_EditMesh *sod,
2,
BVHTREE_FROM_EM_EDGES,
/* WORKAROUND: avoid updating while transforming. */
G.moving ? nullptr : &sod->mesh_runtime->bvh_cache,
&sod->mesh_runtime->eval_mutex);
G.moving ? nullptr : &em_cache->mesh_runtime->bvh_cache,
&em_cache->mesh_runtime->eval_mutex);
}
sod->bvhtree[1] = treedata.tree;
sod->cached[1] = treedata.cached;
em_cache->bvhtree[1] = treedata.tree;
em_cache->cached[1] = treedata.cached;
}
}
nearest2d.clip_planes_enable();
nearest2d.clip_planes_enable(sctx);
BVHTreeNearest nearest{};
nearest.index = -1;
nearest.dist_sq = sctx->ret.dist_px_sq;
eSnapMode elem = SCE_SNAP_TO_VERTEX;
eSnapMode elem = SCE_SNAP_TO_POINT;
if (sod->bvhtree[0] && (snap_to_flag & SCE_SNAP_TO_VERTEX)) {
if (em_cache->bvhtree[0] && (snap_to_flag & SCE_SNAP_TO_POINT)) {
BM_mesh_elem_table_ensure(em->bm, BM_VERT);
BM_mesh_elem_index_ensure(em->bm, BM_VERT);
BLI_bvhtree_find_nearest_projected(sod->bvhtree[0],
BLI_bvhtree_find_nearest_projected(em_cache->bvhtree[0],
nearest2d.pmat_local.ptr(),
sctx->runtime.win_size,
sctx->runtime.mval,
@ -606,12 +614,12 @@ static eSnapMode snapEditMesh(SnapData_EditMesh *sod,
&nearest2d);
}
if (sod->bvhtree[1] && (snap_to_flag & SCE_SNAP_TO_EDGE)) {
if (em_cache->bvhtree[1] && (snap_to_flag & SNAP_TO_EDGE_ELEMENTS)) {
int last_index = nearest.index;
nearest.index = -1;
BM_mesh_elem_table_ensure(em->bm, BM_EDGE | BM_VERT);
BM_mesh_elem_index_ensure(em->bm, BM_EDGE | BM_VERT);
BLI_bvhtree_find_nearest_projected(sod->bvhtree[1],
BLI_bvhtree_find_nearest_projected(em_cache->bvhtree[1],
nearest2d.pmat_local.ptr(),
sctx->runtime.win_size,
sctx->runtime.mval,
@ -631,6 +639,7 @@ static eSnapMode snapEditMesh(SnapData_EditMesh *sod,
if (nearest.index != -1) {
nearest2d.nearest_point = nearest;
nearest2d.register_result(sctx, ob_eval, nullptr);
return elem;
}
@ -648,31 +657,29 @@ eSnapMode snap_object_editmesh(SnapObjectContext *sctx,
{
eSnapMode elem = SCE_SNAP_TO_NONE;
SnapData_EditMesh *sod = editmesh_snapdata_init(sctx, ob_eval, snap_to_flag);
if (sod == nullptr) {
SnapCache_EditMesh *em_cache = editmesh_snapdata_init(sctx, ob_eval, snap_to_flag);
if (em_cache == nullptr) {
return elem;
}
BMEditMesh *em = sod->treedata_editmesh.em;
BMEditMesh *em = em_cache->treedata_editmesh.em;
eSnapMode snap_mode_used = snap_to_flag & editmesh_snap_mode_supported(em);
if (snap_mode_used & (SCE_SNAP_TO_EDGE | SCE_SNAP_TO_EDGE_MIDPOINT |
SCE_SNAP_TO_EDGE_PERPENDICULAR | SCE_SNAP_TO_VERTEX))
{
elem = snapEditMesh(sod, sctx, ob_eval, em, obmat, snap_to_flag);
if (snap_mode_used & (SNAP_TO_EDGE_ELEMENTS | SCE_SNAP_TO_POINT)) {
elem = snapEditMesh(em_cache, sctx, ob_eval, em, obmat, snap_to_flag);
if (elem) {
return elem;
}
}
if (snap_mode_used & SCE_SNAP_TO_FACE) {
if (raycastEditMesh(sod, sctx, em, obmat, sctx->runtime.object_index++)) {
if (raycastEditMesh(em_cache, sctx, em, obmat, sctx->runtime.object_index++)) {
return SCE_SNAP_TO_FACE;
}
}
if (snap_mode_used & SCE_SNAP_INDIVIDUAL_NEAREST) {
if (nearest_world_editmesh(sod, sctx, em, obmat)) {
if (nearest_world_editmesh(em_cache, sctx, em, obmat)) {
return SCE_SNAP_INDIVIDUAL_NEAREST;
}
}

View File

@ -239,7 +239,7 @@ static bool nearest_world_mesh(SnapObjectContext *sctx,
/** \name Subclass for Snapping to Edges or Points of a Mesh
* \{ */
class Nearest2dUserData_Mesh : public Nearest2dUserData {
class SnapData_Mesh : public SnapData {
public:
const float3 *vert_positions;
const float3 *vert_normals;
@ -248,13 +248,9 @@ class Nearest2dUserData_Mesh : public Nearest2dUserData {
const int *corner_edges;
const MLoopTri *looptris;
Nearest2dUserData_Mesh(SnapObjectContext *sctx,
Object *ob_eval,
const ID *id_eval,
const float4x4 &obmat)
: Nearest2dUserData(sctx, ob_eval, id_eval, obmat)
SnapData_Mesh(SnapObjectContext *sctx, const Mesh *mesh_eval, const float4x4 &obmat)
: SnapData(sctx, obmat)
{
const Mesh *mesh_eval = reinterpret_cast<const Mesh *>(id_eval);
this->vert_positions = mesh_eval->vert_positions().data();
this->vert_normals = mesh_eval->vert_normals().data();
this->edges = mesh_eval->edges().data();
@ -316,7 +312,7 @@ static void cb_snap_edge_verts(void *userdata,
const int clip_plane_len,
BVHTreeNearest *nearest)
{
Nearest2dUserData_Mesh *data = static_cast<Nearest2dUserData_Mesh *>(userdata);
SnapData_Mesh *data = static_cast<SnapData_Mesh *>(userdata);
int vindex[2];
data->get_edge_verts_index(index, vindex);
@ -336,7 +332,7 @@ static void cb_snap_tri_verts(void *userdata,
const int clip_plane_len,
BVHTreeNearest *nearest)
{
Nearest2dUserData_Mesh *data = static_cast<Nearest2dUserData_Mesh *>(userdata);
SnapData_Mesh *data = static_cast<SnapData_Mesh *>(userdata);
int vindex[3];
data->get_tri_verts_index(index, vindex);
@ -367,7 +363,7 @@ static void cb_snap_tri_edges(void *userdata,
const int clip_plane_len,
BVHTreeNearest *nearest)
{
Nearest2dUserData_Mesh *data = static_cast<Nearest2dUserData_Mesh *>(userdata);
SnapData_Mesh *data = static_cast<SnapData_Mesh *>(userdata);
if (data->use_backface_culling) {
int vindex[3];
@ -412,8 +408,8 @@ eSnapMode snap_polygon_mesh(SnapObjectContext *sctx,
const Mesh *mesh_eval = reinterpret_cast<const Mesh *>(id);
Nearest2dUserData_Mesh nearest2d(sctx, ob_eval, id, float4x4(obmat));
nearest2d.clip_planes_enable();
SnapData_Mesh nearest2d(sctx, mesh_eval, float4x4(obmat));
nearest2d.clip_planes_enable(sctx);
BVHTreeNearest nearest{};
nearest.index = -1;
@ -449,6 +445,7 @@ eSnapMode snap_polygon_mesh(SnapObjectContext *sctx,
if (nearest.index != -1) {
nearest2d.nearest_point = nearest;
nearest2d.register_result(sctx, ob_eval, id);
return elem;
}
@ -462,8 +459,12 @@ eSnapMode snap_edge_points_mesh(SnapObjectContext *sctx,
float dist_pex_sq_orig,
int edge)
{
Nearest2dUserData_Mesh nearest2d(sctx, ob_eval, id, float4x4(obmat));
return nearest2d.snap_edge_points(edge, dist_pex_sq_orig);
SnapData_Mesh nearest2d(sctx, reinterpret_cast<const Mesh *>(id), float4x4(obmat));
eSnapMode elem = nearest2d.snap_edge_points_impl(sctx, edge, dist_pex_sq_orig);
if (nearest2d.nearest_point.index != -2) {
nearest2d.register_result(sctx, ob_eval, id);
}
return elem;
}
static eSnapMode snapMesh(SnapObjectContext *sctx,
@ -476,11 +477,11 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
if (me_eval->totvert == 0) {
return SCE_SNAP_TO_NONE;
}
if (me_eval->totedge == 0 && !(sctx->runtime.snap_to_flag & SCE_SNAP_TO_VERTEX)) {
if (me_eval->totedge == 0 && !(sctx->runtime.snap_to_flag & SCE_SNAP_TO_POINT)) {
return SCE_SNAP_TO_NONE;
}
Nearest2dUserData_Mesh nearest2d(sctx, ob_eval, &me_eval->id, float4x4(obmat));
SnapData_Mesh nearest2d(sctx, me_eval, float4x4(obmat));
if (ob_eval->data == me_eval) {
const BoundBox *bb = BKE_mesh_boundbox_get(ob_eval);
@ -495,22 +496,22 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
BVHTree *bvhtree[2] = {nullptr};
bvhtree[0] = BKE_bvhtree_from_mesh_get(&treedata_dummy, me_eval, BVHTREE_FROM_LOOSEEDGES, 2);
BLI_assert(treedata_dummy.cached);
if (sctx->runtime.snap_to_flag & SCE_SNAP_TO_VERTEX) {
if (sctx->runtime.snap_to_flag & SCE_SNAP_TO_POINT) {
bvhtree[1] = BKE_bvhtree_from_mesh_get(&treedata_dummy, me_eval, BVHTREE_FROM_LOOSEVERTS, 2);
BLI_assert(treedata_dummy.cached);
}
nearest2d.clip_planes_enable();
nearest2d.clip_planes_enable(sctx);
BVHTreeNearest nearest{};
nearest.index = -1;
nearest.dist_sq = sctx->ret.dist_px_sq;
int last_index = nearest.index;
eSnapMode elem = SCE_SNAP_TO_VERTEX;
eSnapMode elem = SCE_SNAP_TO_POINT;
if (bvhtree[1]) {
BLI_assert(sctx->runtime.snap_to_flag & SCE_SNAP_TO_VERTEX);
BLI_assert(sctx->runtime.snap_to_flag & SCE_SNAP_TO_POINT);
/* snap to loose verts */
BLI_bvhtree_find_nearest_projected(bvhtree[1],
nearest2d.pmat_local.ptr(),
@ -525,7 +526,7 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
last_index = nearest.index;
}
if (sctx->runtime.snap_to_flag & SCE_SNAP_TO_EDGE) {
if (sctx->runtime.snap_to_flag & (SNAP_TO_EDGE_ELEMENTS & ~SCE_SNAP_TO_EDGE_ENDPOINT)) {
if (bvhtree[0]) {
/* Snap to loose edges. */
BLI_bvhtree_find_nearest_projected(
@ -559,7 +560,7 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
}
}
else {
BLI_assert(sctx->runtime.snap_to_flag & SCE_SNAP_TO_VERTEX);
BLI_assert(sctx->runtime.snap_to_flag & SCE_SNAP_TO_EDGE_ENDPOINT);
if (bvhtree[0]) {
/* Snap to loose edge verts. */
BLI_bvhtree_find_nearest_projected(
@ -591,6 +592,7 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
if (nearest.index != -1) {
nearest2d.nearest_point = nearest;
nearest2d.register_result(sctx, ob_eval, &me_eval->id);
return elem;
}
@ -627,9 +629,7 @@ eSnapMode snap_object_mesh(SnapObjectContext *sctx,
const Mesh *mesh_eval = reinterpret_cast<const Mesh *>(id);
eSnapMode snap_mode_used = snap_to_flag & mesh_snap_mode_supported(mesh_eval);
if (snap_mode_used & (SCE_SNAP_TO_EDGE | SCE_SNAP_TO_EDGE_MIDPOINT |
SCE_SNAP_TO_EDGE_PERPENDICULAR | SCE_SNAP_TO_VERTEX))
{
if (snap_mode_used & (SNAP_TO_EDGE_ELEMENTS | SCE_SNAP_TO_POINT)) {
elem = snapMesh(sctx, ob_eval, mesh_eval, obmat, use_hide);
if (elem) {
return elem;

View File

@ -1555,7 +1555,6 @@ static int pack_islands_exec(bContext *C, wmOperator *op)
pack_islands_endjob(pid);
pack_islands_freejob(pid);
MEM_freeN(pid);
return OPERATOR_FINISHED;
}

View File

@ -1758,12 +1758,10 @@ static ExrHandle *imb_exr_begin_read_mem(IStream &file_stream,
static void exr_printf(const char *fmt, ...)
{
#if 0
char output[1024];
va_list args;
va_start(args, fmt);
std::vsprintf(output, fmt, args);
vprintf(fmt, args);
va_end(args);
printf("%s", output);
#else
(void)fmt;
#endif

View File

@ -45,17 +45,21 @@ typedef enum eBoidRuleType {
} eBoidRuleType;
/* boidrule->flag */
#define BOIDRULE_CURRENT (1 << 0)
#define BOIDRULE_IN_AIR (1 << 2)
#define BOIDRULE_ON_LAND (1 << 3)
enum {
BOIDRULE_CURRENT = 1 << 0,
BOIDRULE_IN_AIR = 1 << 2,
BOIDRULE_ON_LAND = 1 << 3,
};
typedef struct BoidRule {
struct BoidRule *next, *prev;
int type, flag;
char name[32];
} BoidRule;
#define BRULE_GOAL_AVOID_PREDICT (1 << 0)
#define BRULE_GOAL_AVOID_ARRIVE (1 << 1)
#define BRULE_GOAL_AVOID_SIGNAL (1 << 2)
enum {
BRULE_GOAL_AVOID_PREDICT = 1 << 0,
BRULE_GOAL_AVOID_ARRIVE = 1 << 1,
BRULE_GOAL_AVOID_SIGNAL = 1 << 2,
};
typedef struct BoidRuleGoalAvoid {
BoidRule rule;
struct Object *ob;
@ -65,8 +69,10 @@ typedef struct BoidRuleGoalAvoid {
/* signals */
int signal_id, channels;
} BoidRuleGoalAvoid;
#define BRULE_ACOLL_WITH_BOIDS (1 << 0)
#define BRULE_ACOLL_WITH_DEFLECTORS (1 << 1)
enum {
BRULE_ACOLL_WITH_BOIDS = 1 << 0,
BRULE_ACOLL_WITH_DEFLECTORS = 1 << 1,
};
typedef struct BoidRuleAvoidCollision {
BoidRule rule;
int options;
@ -200,10 +206,12 @@ typedef struct BoidSettings {
struct ListBase states;
} BoidSettings;
/* boidsettings->options */
#define BOID_ALLOW_FLIGHT (1 << 0)
#define BOID_ALLOW_LAND (1 << 1)
#define BOID_ALLOW_CLIMB (1 << 2)
/** #BoidSettings::options */
enum {
BOID_ALLOW_FLIGHT = 1 << 0,
BOID_ALLOW_LAND = 1 << 1,
BOID_ALLOW_CLIMB = 1 << 2,
};
/* boidrule->options */
//#define BOID_RULE_FOLLOW_LINE (1 << 0) /* follow leader */

View File

@ -30,7 +30,7 @@ struct Material;
struct Object;
struct VFont;
/* These two Lines with # tell makesdna this struct can be excluded. */
/* These two Lines with # tell `makesdna` this struct can be excluded. */
#
#
typedef struct BevPoint {
@ -42,7 +42,7 @@ typedef struct BevPoint {
short dupe_tag;
} BevPoint;
/* These two Lines with # tell makesdna this struct can be excluded. */
/* These two Lines with # tell `makesdna` this struct can be excluded. */
#
#
typedef struct BevList {
@ -170,7 +170,7 @@ typedef struct TextBox {
float x, y, w, h;
} TextBox;
/* These two Lines with # tell makesdna this struct can be excluded. */
/* These two Lines with # tell `makesdna` this struct can be excluded. */
#
#
typedef struct EditNurb {
@ -611,7 +611,7 @@ enum {
#define KEY_CU_EASE 3
/* indicates point has been seen during surface duplication */
#define SURF_SEEN 4
#define SURF_SEEN (1 << 2)
#ifdef __cplusplus
}

View File

@ -10,7 +10,7 @@
#pragma once
/* makesdna ignores */
/* `makesdna` ignores. */
#ifdef DNA_DEPRECATED_ALLOW
/* allow use of deprecated items */
# define DNA_DEPRECATED

View File

@ -16,45 +16,56 @@ extern "C" {
/* Don't forget, new effects also in `writefile.c` for DNA! */
#define PAF_MAXMULT 4
/** #PartEff::flag. */
enum {
// PAF_UNUSED_0 = 1 << 0, /* DEPRECATED, dirty. */
PAF_BSPLINE = 1 << 1,
PAF_STATIC = 1 << 2,
PAF_FACE = 1 << 3,
PAF_ANIMATED = 1 << 4,
/** Show particles before they're emitted. */
PAF_UNBORN = 1 << 5,
/** Emit only from faces. */
PAF_OFACE = 1 << 6,
/** show emitter (don't hide actual mesh). */
PAF_SHOWE = 1 << 7,
/** True random emit from faces (not just ordered jitter). */
PAF_TRAND = 1 << 8,
/** even distribution in face emission based on face areas. */
PAF_EDISTR = 1 << 9,
/** Show particles after they've died. */
PAF_DIED = 1 << 11,
};
/* paf->flag (keep bit 0 free for compatibility). */
#define PAF_BSPLINE 2
#define PAF_STATIC 4
#define PAF_FACE 8
#define PAF_ANIMATED 16
/* show particles before they're emitted. */
#define PAF_UNBORN 32
/* Emit only from faces. */
#define PAF_OFACE 64
/* show emitter (don't hide actual mesh). */
#define PAF_SHOWE 128
/* true random emit from faces (not just ordered jitter). */
#define PAF_TRAND 256
/* even distribution in face emission based on face areas. */
#define PAF_EDISTR 512
/* Show particles after they've died. */
#define PAF_DIED 2048
/** #PartEff::flag2, for pos/neg #PartEff::flag2neg. */
enum {
PAF_TEXTIME = 1, /* Texture timing. */
};
/* `paf->flag2` for pos/neg `paf->flag2neg`. */
#define PAF_TEXTIME 1 /* Texture timing. */
/** #PartEff::type. */
enum {
EFF_BUILD = 0,
EFF_PARTICLE = 1,
EFF_WAVE = 2,
};
/* eff->type */
#define EFF_BUILD 0
#define EFF_PARTICLE 1
#define EFF_WAVE 2
/** #PartEff::flag. */
enum {
EFF_SELECT = 1,
};
/* eff->flag */
#define EFF_SELECT 1
/** #PartEff::stype. */
enum {
PAF_NORMAL = 0,
PAF_VECT = 1,
};
/* paf->stype */
#define PAF_NORMAL 0
#define PAF_VECT 1
/* paf->texmap */
#define PAF_TEXINT 0
#define PAF_TEXRGB 1
#define PAF_TEXGRAD 2
/** #PartEff::texmap. */
enum {
PAF_TEXINT = 0,
PAF_TEXRGB = 1,
PAF_TEXGRAD = 2,
};
typedef struct Effect {
struct Effect *next, *prev;

View File

@ -20,7 +20,7 @@ extern "C" {
/**
* DNAstr contains the prebuilt SDNA structure defining the layouts of the types
* used by this version of Blender. It is defined in a file dna.c, which is
* generated by the makesdna program during the build process (see makesdna.c).
* generated by the `makesdna` program during the build process (see `makesdna.c`).
*/
extern const unsigned char DNAstr[];
/** Length of DNAstr. */

View File

@ -23,6 +23,7 @@ class GreasePencilRuntime;
class GreasePencilDrawingRuntime;
namespace greasepencil {
class DrawingRuntime;
class Drawing;
class TreeNode;
class Layer;
class LayerRuntime;
@ -107,16 +108,8 @@ typedef struct GreasePencilDrawing {
*/
GreasePencilDrawingRuntimeHandle *runtime;
#ifdef __cplusplus
/**
* The triangles for all the fills in the geometry.
*/
blender::Span<blender::uint3> triangles() const;
void tag_positions_changed();
/**
* A buffer for a single stroke while drawing.
*/
blender::Span<blender::bke::greasepencil::StrokePoint> stroke_buffer() const;
bool has_stroke_buffer() const;
blender::bke::greasepencil::Drawing &wrap();
const blender::bke::greasepencil::Drawing &wrap() const;
#endif
} GreasePencilDrawing;
@ -457,6 +450,14 @@ typedef struct GreasePencil {
blender::bke::greasepencil::Layer *layer,
blender::StringRefNull name);
blender::bke::greasepencil::LayerGroup &add_layer_group(
blender::bke::greasepencil::LayerGroup &group, blender::StringRefNull name);
blender::bke::greasepencil::LayerGroup &add_layer_group(blender::StringRefNull name);
blender::bke::greasepencil::LayerGroup &add_layer_group_after(
blender::bke::greasepencil::LayerGroup &group,
blender::bke::greasepencil::TreeNode *node,
blender::StringRefNull name);
const blender::bke::greasepencil::Layer *find_layer_by_name(blender::StringRefNull name) const;
blender::bke::greasepencil::Layer *find_layer_by_name(blender::StringRefNull name);
@ -467,10 +468,10 @@ typedef struct GreasePencil {
void add_empty_drawings(int add_num);
void remove_drawing(int index);
void foreach_visible_drawing(int frame,
blender::FunctionRef<void(int, GreasePencilDrawing &)> function);
void foreach_editable_drawing(int frame,
blender::FunctionRef<void(int, GreasePencilDrawing &)> function);
void foreach_visible_drawing(
int frame, blender::FunctionRef<void(int, blender::bke::greasepencil::Drawing &)> function);
void foreach_editable_drawing(
int frame, blender::FunctionRef<void(int, blender::bke::greasepencil::Drawing &)> function);
std::optional<blender::Bounds<blender::float3>> bounds_min_max() const;

View File

@ -104,13 +104,15 @@ typedef struct ImageTile {
char label[64];
} ImageTile;
/* iuser->flag */
#define IMA_ANIM_ALWAYS (1 << 0)
/* #define IMA_UNUSED_1 (1 << 1) */
/* #define IMA_UNUSED_2 (1 << 2) */
#define IMA_NEED_FRAME_RECALC (1 << 3)
#define IMA_SHOW_STEREO (1 << 4)
/* #define IMA_UNUSED_5 (1 << 5) */
/** #ImageUser::flag */
enum {
IMA_ANIM_ALWAYS = 1 << 0,
// IMA_UNUSED_1 = 1 << 1,
// IMA_UNUSED_2 = 1 << 2,
IMA_NEED_FRAME_RECALC = 1 << 3,
IMA_SHOW_STEREO = 1 << 4,
// IMA_UNUSED_5 = 1 << 5,
};
/* Used to get the correct gpu texture from an Image datablock. */
typedef enum eGPUTextureTarget {
@ -271,8 +273,8 @@ enum {
IMA_GENTYPE_GRID_COLOR = 2,
};
/* render */
#define IMA_MAX_RENDER_TEXT (1 << 9)
/** Size of allocated string #RenderResult::text. */
#define IMA_MAX_RENDER_TEXT_SIZE 512
/** #Image.gen_flag */
enum {

View File

@ -73,11 +73,13 @@ typedef struct Lattice {
/* ***************** LATTICE ********************* */
/* flag */
#define LT_GRID 1
#define LT_OUTSIDE 2
/** #Lattice::flag */
enum {
LT_GRID = 1 << 0,
LT_OUTSIDE = 1 << 1,
#define LT_DS_EXPAND 4
LT_DS_EXPAND = 1 << 2,
};
#define LT_ACTBP_NONE -1

View File

@ -88,60 +88,73 @@ typedef struct Light {
/* **************** LIGHT ********************* */
/* flag */
#define LA_DS_EXPAND (1 << 0)
/* NOTE: this must have the same value as MA_DS_SHOW_TEXS,
* otherwise anim-editors will not read correctly
*/
#define LA_DS_SHOW_TEXS (1 << 2)
/** #Light::flag */
enum {
LA_DS_EXPAND = 1 << 0,
/**
* NOTE: this must have the same value as #MA_DS_SHOW_TEXS,
* otherwise anim-editors will not read correctly.
*/
LA_DS_SHOW_TEXS = 1 << 2,
};
/* type */
#define LA_LOCAL 0
#define LA_SUN 1
#define LA_SPOT 2
/* #define LA_HEMI 3 */ /* not used anymore */
#define LA_AREA 4
/** #Light::type */
enum {
LA_LOCAL = 0,
LA_SUN = 1,
LA_SPOT = 2,
// LA_HEMI = 3, /* Deprecated. */
LA_AREA = 4,
};
/* mode */
#define LA_SHADOW (1 << 0)
/* #define LA_HALO (1 << 1) */ /* not used anymore */
/* #define LA_LAYER (1 << 2) */ /* not used anymore */
/* #define LA_QUAD (1 << 3) */ /* not used anymore */
/* #define LA_NEG (1 << 4) */ /* not used anymore */
/* #define LA_ONLYSHADOW(1 << 5) */ /* not used anymore */
/* #define LA_SPHERE (1 << 6) */ /* not used anymore */
#define LA_SQUARE (1 << 7)
/* #define LA_TEXTURE (1 << 8) */ /* not used anymore */
/* #define LA_OSATEX (1 << 9) */ /* not used anymore */
/* #define LA_DEEP_SHADOW (1 << 10) */ /* not used anywhere */
/* #define LA_NO_DIFF (1 << 11) */ /* not used anywhere */
/* #define LA_NO_SPEC (1 << 12) */ /* not used anywhere */
/* #define LA_SHAD_RAY (1 << 13) */ /* not used anywhere - cleaned */
/* YAFRAY: light shadow-buffer flag, soft-light. */
/* Since it is used with LOCAL light, can't use LA_SHAD */
/* #define LA_YF_SOFT (1 << 14) */ /* not used anymore */
/* #define LA_LAYER_SHADOW (1 << 15) */ /* not used anymore */
/* #define LA_SHAD_TEX (1 << 16) */ /* not used anymore */
#define LA_SHOW_CONE (1 << 17)
/* #define LA_SHOW_SHADOW_BOX (1 << 18) */
#define LA_SHAD_CONTACT (1 << 19)
#define LA_CUSTOM_ATTENUATION (1 << 20)
/** #Light::mode */
enum {
LA_SHADOW = 1 << 0,
// LA_HALO = 1 << 1, /* Deprecated. .*/
// LA_LAYER = 1 << 2, /* Deprecated. */
// LA_QUAD = 1 << 3, /* Deprecated. */
// LA_NEG = 1 << 4, /* Deprecated. */
// LA_ONLYSHADOW = 1 << 5, /* Deprecated. */
// LA_SPHERE = 1 << 6, /* Deprecated. */
LA_SQUARE = 1 << 7,
// LA_TEXTURE = 1 << 8, /* Deprecated. */
// LA_OSATEX = 1 << 9, /* Deprecated. */
// LA_DEEP_SHADOW = 1 << 10, /* Deprecated. */
// LA_NO_DIFF = 1 << 11, /* Deprecated. */
// LA_NO_SPEC = 1 << 12, /* Deprecated. */
LA_SHAD_RAY = 1 << 13, /* Deprecated, cleaned. */
/**
* YAFRAY: light shadow-buffer flag, soft-light.
* Since it is used with LOCAL light, can't use LA_SHAD.
* */
// LA_YF_SOFT = 1 << 14, /* Deprecated. */
// LA_LAYER_SHADOW = 1 << 15, /* Deprecated. */
// LA_SHAD_TEX = 1 << 16, /* Deprecated. */
LA_SHOW_CONE = 1 << 17,
// LA_SHOW_SHADOW_BOX = 1 << 18,
LA_SHAD_CONTACT = 1 << 19,
LA_CUSTOM_ATTENUATION = 1 << 20,
};
/* falloff_type */
#define LA_FALLOFF_CONSTANT 0
#define LA_FALLOFF_INVLINEAR 1
#define LA_FALLOFF_INVSQUARE 2
#define LA_FALLOFF_CURVE 3
#define LA_FALLOFF_SLIDERS 4
#define LA_FALLOFF_INVCOEFFICIENTS 5
/** #Light::falloff_type */
enum {
LA_FALLOFF_CONSTANT = 0,
LA_FALLOFF_INVLINEAR = 1,
LA_FALLOFF_INVSQUARE = 2,
LA_FALLOFF_CURVE = 3,
LA_FALLOFF_SLIDERS = 4,
LA_FALLOFF_INVCOEFFICIENTS = 5,
};
/* area shape */
#define LA_AREA_SQUARE 0
#define LA_AREA_RECT 1
/* #define LA_AREA_CUBE 2 */ /* UNUSED */
/* #define LA_AREA_BOX 3 */ /* UNUSED */
#define LA_AREA_DISK 4
#define LA_AREA_ELLIPSE 5
/** #Light::area_shape */
enum {
LA_AREA_SQUARE = 0,
LA_AREA_RECT = 1,
// LA_AREA_CUBE = 2, /* Deprecated. */
// LA_AREA_BOX = 3, /* Deprecated. */
LA_AREA_DISK = 4,
LA_AREA_ELLIPSE = 5,
};
#ifdef __cplusplus
}

View File

@ -42,55 +42,67 @@ typedef struct LineStyleModifier {
int blend;
} LineStyleModifier;
/* LineStyleModifier::type */
#define LS_MODIFIER_ALONG_STROKE 1
#define LS_MODIFIER_DISTANCE_FROM_CAMERA 2
#define LS_MODIFIER_DISTANCE_FROM_OBJECT 3
#define LS_MODIFIER_MATERIAL 4
#define LS_MODIFIER_SAMPLING 5
#define LS_MODIFIER_BEZIER_CURVE 6
#define LS_MODIFIER_SINUS_DISPLACEMENT 7
#define LS_MODIFIER_SPATIAL_NOISE 8
#define LS_MODIFIER_PERLIN_NOISE_1D 9
#define LS_MODIFIER_PERLIN_NOISE_2D 10
#define LS_MODIFIER_BACKBONE_STRETCHER 11
#define LS_MODIFIER_TIP_REMOVER 12
#define LS_MODIFIER_CALLIGRAPHY 13
#define LS_MODIFIER_POLYGONIZATION 14
#define LS_MODIFIER_GUIDING_LINES 15
#define LS_MODIFIER_BLUEPRINT 16
#define LS_MODIFIER_2D_OFFSET 17
#define LS_MODIFIER_2D_TRANSFORM 18
#define LS_MODIFIER_TANGENT 19
#define LS_MODIFIER_NOISE 20
#define LS_MODIFIER_CREASE_ANGLE 21
#define LS_MODIFIER_SIMPLIFICATION 22
#define LS_MODIFIER_CURVATURE_3D 23
#define LS_MODIFIER_NUM 24
/** #LineStyleModifier::type */
enum {
LS_MODIFIER_ALONG_STROKE = 1,
LS_MODIFIER_DISTANCE_FROM_CAMERA = 2,
LS_MODIFIER_DISTANCE_FROM_OBJECT = 3,
LS_MODIFIER_MATERIAL = 4,
LS_MODIFIER_SAMPLING = 5,
LS_MODIFIER_BEZIER_CURVE = 6,
LS_MODIFIER_SINUS_DISPLACEMENT = 7,
LS_MODIFIER_SPATIAL_NOISE = 8,
LS_MODIFIER_PERLIN_NOISE_1D = 9,
LS_MODIFIER_PERLIN_NOISE_2D = 10,
LS_MODIFIER_BACKBONE_STRETCHER = 11,
LS_MODIFIER_TIP_REMOVER = 12,
LS_MODIFIER_CALLIGRAPHY = 13,
LS_MODIFIER_POLYGONIZATION = 14,
LS_MODIFIER_GUIDING_LINES = 15,
LS_MODIFIER_BLUEPRINT = 16,
LS_MODIFIER_2D_OFFSET = 17,
LS_MODIFIER_2D_TRANSFORM = 18,
LS_MODIFIER_TANGENT = 19,
LS_MODIFIER_NOISE = 20,
LS_MODIFIER_CREASE_ANGLE = 21,
LS_MODIFIER_SIMPLIFICATION = 22,
LS_MODIFIER_CURVATURE_3D = 23,
LS_MODIFIER_NUM = 24,
};
/* LineStyleModifier::flags */
#define LS_MODIFIER_ENABLED 1
#define LS_MODIFIER_EXPANDED 2
/** #LineStyleModifier::flags */
enum {
LS_MODIFIER_ENABLED = 1,
LS_MODIFIER_EXPANDED = 2,
};
/* flags (for color) */
#define LS_MODIFIER_USE_RAMP 1
/** Flags (for color) */
enum {
LS_MODIFIER_USE_RAMP = 1,
};
/* flags (for alpha & thickness) */
#define LS_MODIFIER_USE_CURVE 1
#define LS_MODIFIER_INVERT 2
/** Flags (for alpha & thickness) */
enum {
LS_MODIFIER_USE_CURVE = 1,
LS_MODIFIER_INVERT = 2,
};
/* flags (for asymmetric thickness application) */
#define LS_THICKNESS_ASYMMETRIC 1
/** Flags (for asymmetric thickness application). */
enum {
LS_THICKNESS_ASYMMETRIC = 1,
};
/* blend (for alpha & thickness) */
#define LS_VALUE_BLEND 0
#define LS_VALUE_ADD 1
#define LS_VALUE_MULT 2
#define LS_VALUE_SUB 3
#define LS_VALUE_DIV 4
#define LS_VALUE_DIFF 5
#define LS_VALUE_MIN 6
#define LS_VALUE_MAX 7
/** Blend (for alpha & thickness). */
enum {
LS_VALUE_BLEND = 0,
LS_VALUE_ADD = 1,
LS_VALUE_MULT = 2,
LS_VALUE_SUB = 3,
LS_VALUE_DIV = 4,
LS_VALUE_DIFF = 5,
LS_VALUE_MIN = 6,
LS_VALUE_MAX = 7,
};
/* Along Stroke modifiers */
@ -331,21 +343,23 @@ typedef struct LineStyleThicknessModifier_Tangent {
/* Material modifiers */
/* mat_attr */
#define LS_MODIFIER_MATERIAL_DIFF 1
#define LS_MODIFIER_MATERIAL_DIFF_R 2
#define LS_MODIFIER_MATERIAL_DIFF_G 3
#define LS_MODIFIER_MATERIAL_DIFF_B 4
#define LS_MODIFIER_MATERIAL_SPEC 5
#define LS_MODIFIER_MATERIAL_SPEC_R 6
#define LS_MODIFIER_MATERIAL_SPEC_G 7
#define LS_MODIFIER_MATERIAL_SPEC_B 8
#define LS_MODIFIER_MATERIAL_SPEC_HARD 9
#define LS_MODIFIER_MATERIAL_ALPHA 10
#define LS_MODIFIER_MATERIAL_LINE 11
#define LS_MODIFIER_MATERIAL_LINE_R 12
#define LS_MODIFIER_MATERIAL_LINE_G 13
#define LS_MODIFIER_MATERIAL_LINE_B 14
#define LS_MODIFIER_MATERIAL_LINE_A 15
enum {
LS_MODIFIER_MATERIAL_DIFF = 1,
LS_MODIFIER_MATERIAL_DIFF_R = 2,
LS_MODIFIER_MATERIAL_DIFF_G = 3,
LS_MODIFIER_MATERIAL_DIFF_B = 4,
LS_MODIFIER_MATERIAL_SPEC = 5,
LS_MODIFIER_MATERIAL_SPEC_R = 6,
LS_MODIFIER_MATERIAL_SPEC_G = 7,
LS_MODIFIER_MATERIAL_SPEC_B = 8,
LS_MODIFIER_MATERIAL_SPEC_HARD = 9,
LS_MODIFIER_MATERIAL_ALPHA = 10,
LS_MODIFIER_MATERIAL_LINE = 11,
LS_MODIFIER_MATERIAL_LINE_R = 12,
LS_MODIFIER_MATERIAL_LINE_G = 13,
LS_MODIFIER_MATERIAL_LINE_B = 14,
LS_MODIFIER_MATERIAL_LINE_A = 15,
};
typedef struct LineStyleColorModifier_Material {
DNA_DEFINE_CXX_METHODS(LineStyleColorModifier_Material)
@ -407,9 +421,11 @@ typedef struct LineStyleGeometryModifier_SinusDisplacement {
char _pad[4];
} LineStyleGeometryModifier_SinusDisplacement;
/* LineStyleGeometryModifier_SpatialNoise::flags */
#define LS_MODIFIER_SPATIAL_NOISE_SMOOTH 1
#define LS_MODIFIER_SPATIAL_NOISE_PURERANDOM 2
/** #LineStyleGeometryModifier_SpatialNoise::flags */
enum {
LS_MODIFIER_SPATIAL_NOISE_SMOOTH = 1,
LS_MODIFIER_SPATIAL_NOISE_PURERANDOM = 2,
};
typedef struct LineStyleGeometryModifier_SpatialNoise {
DNA_DEFINE_CXX_METHODS(LineStyleGeometryModifier_SpatialNoise)
@ -483,10 +499,12 @@ typedef struct LineStyleGeometryModifier_GuidingLines {
char _pad[4];
} LineStyleGeometryModifier_GuidingLines;
/* LineStyleGeometryModifier_BluePrintLines::shape */
#define LS_MODIFIER_BLUEPRINT_CIRCLES 1
#define LS_MODIFIER_BLUEPRINT_ELLIPSES 2
#define LS_MODIFIER_BLUEPRINT_SQUARES 4
/** #LineStyleGeometryModifier_BluePrintLines::shape */
enum {
LS_MODIFIER_BLUEPRINT_CIRCLES = 1,
LS_MODIFIER_BLUEPRINT_ELLIPSES = 2,
LS_MODIFIER_BLUEPRINT_SQUARES = 4,
};
typedef struct LineStyleGeometryModifier_Blueprint {
DNA_DEFINE_CXX_METHODS(LineStyleGeometryModifier_Blueprint)
@ -510,12 +528,14 @@ typedef struct LineStyleGeometryModifier_2DOffset {
float x, y;
} LineStyleGeometryModifier_2DOffset;
/* LineStyleGeometryModifier_2DTransform::pivot */
#define LS_MODIFIER_2D_TRANSFORM_PIVOT_CENTER 1
#define LS_MODIFIER_2D_TRANSFORM_PIVOT_START 2
#define LS_MODIFIER_2D_TRANSFORM_PIVOT_END 3
#define LS_MODIFIER_2D_TRANSFORM_PIVOT_PARAM 4
#define LS_MODIFIER_2D_TRANSFORM_PIVOT_ABSOLUTE 5
/** #LineStyleGeometryModifier_2DTransform::pivot */
enum {
LS_MODIFIER_2D_TRANSFORM_PIVOT_CENTER = 1,
LS_MODIFIER_2D_TRANSFORM_PIVOT_START = 2,
LS_MODIFIER_2D_TRANSFORM_PIVOT_END = 3,
LS_MODIFIER_2D_TRANSFORM_PIVOT_PARAM = 4,
LS_MODIFIER_2D_TRANSFORM_PIVOT_ABSOLUTE = 5,
};
typedef struct LineStyleGeometryModifier_2DTransform {
DNA_DEFINE_CXX_METHODS(LineStyleGeometryModifier_2DTransform)
@ -553,59 +573,74 @@ typedef struct LineStyleThicknessModifier_Calligraphy {
char _pad[4];
} LineStyleThicknessModifier_Calligraphy;
/* FreestyleLineStyle::panel */
#define LS_PANEL_STROKES 1
#define LS_PANEL_COLOR 2
#define LS_PANEL_ALPHA 3
#define LS_PANEL_THICKNESS 4
#define LS_PANEL_GEOMETRY 5
#define LS_PANEL_TEXTURE 6
#define LS_PANEL_MISC 7
/** #FreestyleLineStyle::panel */
enum {
LS_PANEL_STROKES = 1,
LS_PANEL_COLOR = 2,
LS_PANEL_ALPHA = 3,
LS_PANEL_THICKNESS = 4,
LS_PANEL_GEOMETRY = 5,
LS_PANEL_TEXTURE = 6,
LS_PANEL_MISC = 7,
};
/* FreestyleLineStyle::flag */
#define LS_DS_EXPAND (1 << 0) /* for animation editors */
#define LS_SAME_OBJECT (1 << 1)
#define LS_DASHED_LINE (1 << 2)
#define LS_MATERIAL_BOUNDARY (1 << 3)
#define LS_MIN_2D_LENGTH (1 << 4)
#define LS_MAX_2D_LENGTH (1 << 5)
#define LS_NO_CHAINING (1 << 6)
#define LS_MIN_2D_ANGLE (1 << 7)
#define LS_MAX_2D_ANGLE (1 << 8)
#define LS_SPLIT_LENGTH (1 << 9)
#define LS_SPLIT_PATTERN (1 << 10)
#define LS_NO_SORTING (1 << 11)
#define LS_REVERSE_ORDER (1 << 12) /* for sorting */
#define LS_TEXTURE (1 << 13)
#define LS_CHAIN_COUNT (1 << 14)
/** #FreestyleLineStyle::flag */
enum {
LS_DS_EXPAND = 1 << 0, /* for animation editors */
LS_SAME_OBJECT = 1 << 1,
LS_DASHED_LINE = 1 << 2,
LS_MATERIAL_BOUNDARY = 1 << 3,
LS_MIN_2D_LENGTH = 1 << 4,
LS_MAX_2D_LENGTH = 1 << 5,
LS_NO_CHAINING = 1 << 6,
LS_MIN_2D_ANGLE = 1 << 7,
LS_MAX_2D_ANGLE = 1 << 8,
LS_SPLIT_LENGTH = 1 << 9,
LS_SPLIT_PATTERN = 1 << 10,
LS_NO_SORTING = 1 << 11,
LS_REVERSE_ORDER = 1 << 12, /* for sorting */
LS_TEXTURE = 1 << 13,
LS_CHAIN_COUNT = 1 << 14,
};
/* FreestyleLineStyle::chaining */
#define LS_CHAINING_PLAIN 1
#define LS_CHAINING_SKETCHY 2
/** #FreestyleLineStyle::chaining */
enum {
LS_CHAINING_PLAIN = 1,
LS_CHAINING_SKETCHY = 2,
};
/* FreestyleLineStyle::caps */
#define LS_CAPS_BUTT 1
#define LS_CAPS_ROUND 2
#define LS_CAPS_SQUARE 3
/** #FreestyleLineStyle::caps */
enum {
LS_CAPS_BUTT = 1,
LS_CAPS_ROUND = 2,
LS_CAPS_SQUARE = 3,
};
/* FreestyleLineStyle::thickness_position */
#define LS_THICKNESS_CENTER 1
#define LS_THICKNESS_INSIDE 2
#define LS_THICKNESS_OUTSIDE 3
#define LS_THICKNESS_RELATIVE 4 /* thickness_ratio is used */
/** #FreestyleLineStyle::thickness_position */
enum {
LS_THICKNESS_CENTER = 1,
LS_THICKNESS_INSIDE = 2,
LS_THICKNESS_OUTSIDE = 3,
/** Thickness_ratio is used. */
LS_THICKNESS_RELATIVE = 4,
};
/* FreestyleLineStyle::sort_key */
#define LS_SORT_KEY_DISTANCE_FROM_CAMERA 1
#define LS_SORT_KEY_2D_LENGTH 2
#define LS_SORT_KEY_PROJECTED_X 3
#define LS_SORT_KEY_PROJECTED_Y 4
/** #FreestyleLineStyle::sort_key */
enum {
LS_SORT_KEY_DISTANCE_FROM_CAMERA = 1,
LS_SORT_KEY_2D_LENGTH = 2,
LS_SORT_KEY_PROJECTED_X = 3,
LS_SORT_KEY_PROJECTED_Y = 4,
};
/* FreestyleLineStyle::integration_type */
#define LS_INTEGRATION_MEAN 1
#define LS_INTEGRATION_MIN 2
#define LS_INTEGRATION_MAX 3
#define LS_INTEGRATION_FIRST 4
#define LS_INTEGRATION_LAST 5
/** #FreestyleLineStyle::integration_type */
enum {
LS_INTEGRATION_MEAN = 1,
LS_INTEGRATION_MIN = 2,
LS_INTEGRATION_MAX = 3,
LS_INTEGRATION_FIRST = 4,
LS_INTEGRATION_LAST = 5,
};
typedef struct FreestyleLineStyle {
DNA_DEFINE_CXX_METHODS(FreestyleLineStyle)

Some files were not shown because too many files have changed in this diff Show More