Geometry Nodes: new repeat zone #109164
|
@ -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",
|
||||
)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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'
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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,
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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" {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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_);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -7,6 +7,7 @@ set(INC
|
|||
../../blenkernel
|
||||
../../blenlib
|
||||
../../blenloader
|
||||
../../blentranslation
|
||||
../../gpu
|
||||
../../makesdna
|
||||
../../makesrna
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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")) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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). */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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*/)
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
/* makesdna ignores */
|
||||
/* `makesdna` ignores. */
|
||||
#ifdef DNA_DEPRECATED_ALLOW
|
||||
/* allow use of deprecated items */
|
||||
# define DNA_DEPRECATED
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue