UI: Asset Shelf (Experimental Feature) #104831
|
@ -0,0 +1,15 @@
|
|||
diff --git a/extern/vulkan_memory_allocator/vk_mem_alloc.h b/extern/vulkan_memory_allocator/vk_mem_alloc.h
|
||||
index 60f572038c0..63a9994ba46 100644
|
||||
--- a/extern/vulkan_memory_allocator/vk_mem_alloc.h
|
||||
+++ b/extern/vulkan_memory_allocator/vk_mem_alloc.h
|
||||
@@ -13371,8 +13371,8 @@ bool VmaDefragmentationContext_T::IncrementCounters(VkDeviceSize bytes)
|
||||
// Early return when max found
|
||||
if (++m_PassStats.allocationsMoved >= m_MaxPassAllocations || m_PassStats.bytesMoved >= m_MaxPassBytes)
|
||||
{
|
||||
- VMA_ASSERT(m_PassStats.allocationsMoved == m_MaxPassAllocations ||
|
||||
- m_PassStats.bytesMoved == m_MaxPassBytes && "Exceeded maximal pass threshold!");
|
||||
+ VMA_ASSERT((m_PassStats.allocationsMoved == m_MaxPassAllocations ||
|
||||
+ m_PassStats.bytesMoved == m_MaxPassBytes) && "Exceeded maximal pass threshold!");
|
||||
return true;
|
||||
}
|
||||
return false;
|
File diff suppressed because it is too large
Load Diff
|
@ -161,7 +161,10 @@ ccl_device_inline void osl_eval_nodes(KernelGlobals kg,
|
|||
/* shadeindex = */ 0);
|
||||
# endif
|
||||
|
||||
if (globals.Ci) {
|
||||
if constexpr (type == SHADER_TYPE_DISPLACEMENT) {
|
||||
sd->P = globals.P;
|
||||
}
|
||||
else if (globals.Ci) {
|
||||
flatten_closure_tree(kg, sd, path_flag, globals.Ci);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,10 @@
|
|||
#include "subd/patch_table.h"
|
||||
#include "subd/split.h"
|
||||
|
||||
#include "kernel/osl/globals.h"
|
||||
#ifdef WITH_OSL
|
||||
# include "kernel/osl/globals.h"
|
||||
# include "kernel/osl/services.h"
|
||||
#endif
|
||||
|
||||
#include "util/foreach.h"
|
||||
#include "util/log.h"
|
||||
|
@ -1671,6 +1674,7 @@ void GeometryManager::device_update_displacement_images(Device *device,
|
|||
TaskPool pool;
|
||||
ImageManager *image_manager = scene->image_manager;
|
||||
set<int> bump_images;
|
||||
bool has_osl_node = false;
|
||||
foreach (Geometry *geom, scene->geometry) {
|
||||
if (geom->is_modified()) {
|
||||
/* Geometry-level check for hair shadow transparency.
|
||||
|
@ -1690,6 +1694,9 @@ void GeometryManager::device_update_displacement_images(Device *device,
|
|||
continue;
|
||||
}
|
||||
foreach (ShaderNode *node, shader->graph->nodes) {
|
||||
if (node->special_type == SHADER_SPECIAL_TYPE_OSL) {
|
||||
has_osl_node = true;
|
||||
}
|
||||
if (node->special_type != SHADER_SPECIAL_TYPE_IMAGE_SLOT) {
|
||||
continue;
|
||||
}
|
||||
|
@ -1705,6 +1712,28 @@ void GeometryManager::device_update_displacement_images(Device *device,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WITH_OSL
|
||||
/* If any OSL node is used for displacement, it may reference a texture. But it's
|
||||
* unknown which ones, so have to load them all. */
|
||||
if (has_osl_node) {
|
||||
set<OSLRenderServices *> services_shared;
|
||||
device->foreach_device([&services_shared](Device *sub_device) {
|
||||
OSLGlobals *og = (OSLGlobals *)sub_device->get_cpu_osl_memory();
|
||||
services_shared.insert(og->services);
|
||||
});
|
||||
|
||||
for (OSLRenderServices *services : services_shared) {
|
||||
for (auto it = services->textures.begin(); it != services->textures.end(); ++it) {
|
||||
if (it->second->handle.get_manager() == image_manager) {
|
||||
const int slot = it->second->handle.svm_slot();
|
||||
bump_images.insert(slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
foreach (int slot, bump_images) {
|
||||
pool.push(function_bind(
|
||||
&ImageManager::device_update_slot, image_manager, device, scene, slot, &progress));
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit fe59d382b4fd2047920208fa92d39fc1361d9242
|
||||
Subproject commit 534bf3b76c3b5f3bcd21641f1d53c1062bedcdbe
|
|
@ -4421,6 +4421,11 @@ def km_weight_paint_vertex_selection(params):
|
|||
("view3d.select_lasso", {"type": params.action_mouse, "value": 'CLICK_DRAG', "shift": True, "ctrl": True},
|
||||
{"properties": [("mode", 'SUB')]}),
|
||||
("view3d.select_circle", {"type": 'C', "value": 'PRESS'}, None),
|
||||
("paint.vert_select_linked", {"type": 'L', "value": 'PRESS', "ctrl": True}, None),
|
||||
("paint.vert_select_linked_pick", {"type": 'L', "value": 'PRESS'},
|
||||
{"properties": [("select", True)]}),
|
||||
("paint.vert_select_linked_pick", {"type": 'L', "value": 'PRESS', "shift": True},
|
||||
{"properties": [("select", False)]}),
|
||||
])
|
||||
|
||||
return keymap
|
||||
|
@ -5048,7 +5053,7 @@ def km_sculpt(params):
|
|||
{"properties": [
|
||||
("target", "MASK"),
|
||||
("falloff_type", "GEODESIC"),
|
||||
("invert", True),
|
||||
("invert", False),
|
||||
("use_auto_mask", False),
|
||||
("use_mask_preserve", True),
|
||||
]}),
|
||||
|
|
|
@ -2972,6 +2972,11 @@ def km_weight_paint_vertex_selection(params):
|
|||
("paint.vert_select_hide", {"type": 'H', "value": 'PRESS', "shift": True},
|
||||
{"properties": [("unselected", True)]}),
|
||||
("paint.face_vert_reveal", {"type": 'H', "value": 'PRESS', "alt": True}, None),
|
||||
("paint.vert_select_linked", {"type": 'L', "value": 'PRESS', "ctrl": True}, None),
|
||||
("paint.vert_select_linked_pick", {"type": 'L', "value": 'PRESS'},
|
||||
{"properties": [("select", True)]}),
|
||||
("paint.vert_select_linked_pick", {"type": 'L', "value": 'PRESS', "shift": True},
|
||||
{"properties": [("select", False)]}),
|
||||
])
|
||||
|
||||
return keymap
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
from bpy.types import Panel
|
||||
from bpy.app.translations import contexts as i18n_contexts
|
||||
|
||||
|
||||
class ObjectConstraintPanel:
|
||||
|
@ -398,7 +397,7 @@ class ConstraintButtonsPanel:
|
|||
sub.prop(con, "invert_z", text="Z", toggle=True)
|
||||
row.label(icon='BLANK1')
|
||||
|
||||
layout.prop(con, "mix_mode", text="Mix", text_ctxt=i18n_contexts.constraint)
|
||||
layout.prop(con, "mix_mode", text="Mix")
|
||||
|
||||
self.space_template(layout, con)
|
||||
|
||||
|
@ -489,7 +488,7 @@ class ConstraintButtonsPanel:
|
|||
self.target_template(layout, con)
|
||||
|
||||
layout.prop(con, "remove_target_shear")
|
||||
layout.prop(con, "mix_mode", text="Mix", text_ctxt=i18n_contexts.constraint)
|
||||
layout.prop(con, "mix_mode", text="Mix")
|
||||
|
||||
self.space_template(layout, con)
|
||||
|
||||
|
@ -514,7 +513,7 @@ class ConstraintButtonsPanel:
|
|||
subsub.prop(con, "eval_time", text="")
|
||||
row.prop_decorator(con, "eval_time")
|
||||
|
||||
layout.prop(con, "mix_mode", text="Mix", text_ctxt=i18n_contexts.constraint)
|
||||
layout.prop(con, "mix_mode", text="Mix")
|
||||
|
||||
self.draw_influence(layout, con)
|
||||
|
||||
|
@ -1025,7 +1024,7 @@ class ConstraintButtonsSubPanel:
|
|||
col.prop(con, "to_min_z" + ext, text="Min")
|
||||
col.prop(con, "to_max_z" + ext, text="Max")
|
||||
|
||||
layout.prop(con, "mix_mode" + ext, text="Mix", text_ctxt=i18n_contexts.constraint)
|
||||
layout.prop(con, "mix_mode" + ext, text="Mix")
|
||||
|
||||
def draw_armature_bones(self, context):
|
||||
layout = self.layout
|
||||
|
|
|
@ -605,7 +605,7 @@ class USERPREF_PT_system_cycles_devices(SystemPanel, CenterAlignMixIn, Panel):
|
|||
|
||||
|
||||
class USERPREF_PT_system_gpu_backend(SystemPanel, CenterAlignMixIn, Panel):
|
||||
bl_label = "GPU Back end"
|
||||
bl_label = "GPU Backend"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, _context):
|
||||
|
|
|
@ -2038,6 +2038,7 @@ class VIEW3D_MT_select_paint_mask_vertex(Menu):
|
|||
layout.separator()
|
||||
|
||||
layout.operator("paint.vert_select_ungrouped", text="Ungrouped Vertices")
|
||||
layout.operator("paint.vert_select_linked", text="Select Linked")
|
||||
|
||||
|
||||
class VIEW3D_MT_select_edit_curves(Menu):
|
||||
|
@ -6195,14 +6196,15 @@ class VIEW3D_PT_shading_compositor(Panel):
|
|||
def draw(self, context):
|
||||
shading = context.space_data.shading
|
||||
|
||||
import sys
|
||||
is_macos = sys.platform == "darwin"
|
||||
import gpu
|
||||
is_supported = (gpu.capabilities.compute_shader_support_get()
|
||||
and gpu.capabilities.shader_image_load_store_support_get())
|
||||
|
||||
row = self.layout.row()
|
||||
row.active = not is_macos
|
||||
row.active = is_supported
|
||||
row.prop(shading, "use_compositor", expand=True)
|
||||
if is_macos and shading.use_compositor != "DISABLED":
|
||||
self.layout.label(text="Compositor not supported on MacOS", icon='ERROR')
|
||||
if shading.use_compositor != "DISABLED" and not is_supported:
|
||||
self.layout.label(text="Compositor not supported on this platform", icon='ERROR')
|
||||
|
||||
|
||||
class VIEW3D_PT_gizmo_display(Panel):
|
||||
|
|
|
@ -153,6 +153,14 @@ bool BKE_collection_object_remove(struct Main *bmain,
|
|||
struct Collection *collection,
|
||||
struct Object *object,
|
||||
bool free_us);
|
||||
/**
|
||||
* Replace one object with another in a collection (managing user counts).
|
||||
*/
|
||||
bool BKE_collection_object_replace(struct Main *bmain,
|
||||
struct Collection *collection,
|
||||
struct Object *ob_old,
|
||||
struct Object *ob_new);
|
||||
|
||||
/**
|
||||
* Move object from a collection into another
|
||||
*
|
||||
|
|
|
@ -128,17 +128,6 @@ class CurvesGeometry : public ::CurvesGeometry {
|
|||
CurvesGeometry &operator=(CurvesGeometry &&other);
|
||||
~CurvesGeometry();
|
||||
|
||||
static CurvesGeometry &wrap(::CurvesGeometry &dna_struct)
|
||||
{
|
||||
CurvesGeometry *geometry = reinterpret_cast<CurvesGeometry *>(&dna_struct);
|
||||
return *geometry;
|
||||
}
|
||||
static const CurvesGeometry &wrap(const ::CurvesGeometry &dna_struct)
|
||||
{
|
||||
const CurvesGeometry *geometry = reinterpret_cast<const CurvesGeometry *>(&dna_struct);
|
||||
return *geometry;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Accessors.
|
||||
*/
|
||||
|
@ -408,6 +397,8 @@ class CurvesGeometry : public ::CurvesGeometry {
|
|||
}
|
||||
};
|
||||
|
||||
static_assert(sizeof(blender::bke::CurvesGeometry) == sizeof(::CurvesGeometry));
|
||||
|
||||
/**
|
||||
* Used to propagate deformation data through modifier evaluation so that sculpt tools can work on
|
||||
* evaluated data.
|
||||
|
@ -966,3 +957,12 @@ struct CurvesSurfaceTransforms {
|
|||
};
|
||||
|
||||
} // namespace blender::bke
|
||||
|
||||
inline blender::bke::CurvesGeometry &CurvesGeometry::wrap()
|
||||
{
|
||||
return *reinterpret_cast<blender::bke::CurvesGeometry *>(this);
|
||||
}
|
||||
inline const blender::bke::CurvesGeometry &CurvesGeometry::wrap() const
|
||||
{
|
||||
return *reinterpret_cast<const blender::bke::CurvesGeometry *>(this);
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ static std::optional<blender::bke::MutableAttributeAccessor> get_attribute_acces
|
|||
}
|
||||
case ID_CV: {
|
||||
Curves &curves_id = reinterpret_cast<Curves &>(id);
|
||||
CurvesGeometry &curves = CurvesGeometry::wrap(curves_id.geometry);
|
||||
CurvesGeometry &curves = curves_id.geometry.wrap();
|
||||
return curves.attributes_for_write();
|
||||
}
|
||||
default: {
|
||||
|
|
|
@ -1214,6 +1214,28 @@ bool BKE_collection_object_remove(Main *bmain,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool BKE_collection_object_replace(Main *bmain,
|
||||
Collection *collection,
|
||||
Object *ob_old,
|
||||
Object *ob_new)
|
||||
{
|
||||
CollectionObject *cob = BLI_findptr(
|
||||
&collection->gobject, ob_old, offsetof(CollectionObject, ob));
|
||||
if (cob == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
id_us_min(&cob->ob->id);
|
||||
cob->ob = ob_new;
|
||||
id_us_plus(&cob->ob->id);
|
||||
|
||||
if (BKE_collection_is_in_scene(collection)) {
|
||||
BKE_main_collection_sync(bmain);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove object from all collections of scene
|
||||
* \param collection_skip: Don't remove base from this collection.
|
||||
|
|
|
@ -601,7 +601,7 @@ GeometryDeformation get_evaluated_curves_deformation(const Depsgraph &depsgraph,
|
|||
{
|
||||
BLI_assert(ob_orig.type == OB_CURVES);
|
||||
const Curves &curves_id_orig = *static_cast<const Curves *>(ob_orig.data);
|
||||
const CurvesGeometry &curves_orig = CurvesGeometry::wrap(curves_id_orig.geometry);
|
||||
const CurvesGeometry &curves_orig = curves_id_orig.geometry.wrap();
|
||||
const int points_num = curves_orig.points_num();
|
||||
|
||||
GeometryDeformation deformation;
|
||||
|
@ -643,7 +643,7 @@ GeometryDeformation get_evaluated_curves_deformation(const Depsgraph &depsgraph,
|
|||
if (curves_component_eval != nullptr) {
|
||||
const Curves *curves_id_eval = curves_component_eval->get_for_read();
|
||||
if (curves_id_eval != nullptr) {
|
||||
const CurvesGeometry &curves_eval = CurvesGeometry::wrap(curves_id_eval->geometry);
|
||||
const CurvesGeometry &curves_eval = curves_id_eval->geometry.wrap();
|
||||
if (curves_eval.points_num() == points_num) {
|
||||
deformation.positions = curves_eval.positions();
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ Curves *curve_legacy_to_curves(const Curve &curve_legacy, const ListBase &nurbs_
|
|||
const Vector<const Nurb *> src_curves(nurbs_list);
|
||||
|
||||
Curves *curves_id = curves_new_nomain(0, src_curves.size());
|
||||
CurvesGeometry &curves = CurvesGeometry::wrap(curves_id->geometry);
|
||||
CurvesGeometry &curves = curves_id->geometry.wrap();
|
||||
MutableAttributeAccessor curves_attributes = curves.attributes_for_write();
|
||||
|
||||
MutableSpan<int8_t> types = curves.curve_types_for_write();
|
||||
|
|
|
@ -70,8 +70,8 @@ static void curves_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, con
|
|||
const Curves *curves_src = (const Curves *)id_src;
|
||||
curves_dst->mat = static_cast<Material **>(MEM_dupallocN(curves_src->mat));
|
||||
|
||||
const bke::CurvesGeometry &src = bke::CurvesGeometry::wrap(curves_src->geometry);
|
||||
bke::CurvesGeometry &dst = bke::CurvesGeometry::wrap(curves_dst->geometry);
|
||||
const bke::CurvesGeometry &src = curves_src->geometry.wrap();
|
||||
bke::CurvesGeometry &dst = curves_dst->geometry.wrap();
|
||||
|
||||
/* We need special handling here because the generic ID management code has already done a
|
||||
* shallow copy from the source to the destination, and because the copy-on-write functionality
|
||||
|
@ -103,7 +103,7 @@ static void curves_free_data(ID *id)
|
|||
Curves *curves = (Curves *)id;
|
||||
BKE_animdata_free(&curves->id, false);
|
||||
|
||||
blender::bke::CurvesGeometry::wrap(curves->geometry).~CurvesGeometry();
|
||||
curves->geometry.wrap().~CurvesGeometry();
|
||||
|
||||
BKE_curves_batch_cache_free(curves);
|
||||
|
||||
|
@ -174,7 +174,7 @@ static void curves_blend_read_data(BlendDataReader *reader, ID *id)
|
|||
curves->geometry.runtime = MEM_new<blender::bke::CurvesGeometryRuntime>(__func__);
|
||||
|
||||
/* Recalculate curve type count cache that isn't saved in files. */
|
||||
blender::bke::CurvesGeometry::wrap(curves->geometry).update_curve_types();
|
||||
curves->geometry.wrap().update_curve_types();
|
||||
|
||||
/* Materials */
|
||||
BLO_read_pointer_array(reader, (void **)&curves->mat);
|
||||
|
@ -247,8 +247,7 @@ BoundBox *BKE_curves_boundbox_get(Object *ob)
|
|||
if (ob->runtime.bb == nullptr) {
|
||||
ob->runtime.bb = MEM_cnew<BoundBox>(__func__);
|
||||
|
||||
const blender::bke::CurvesGeometry &curves = blender::bke::CurvesGeometry::wrap(
|
||||
curves_id->geometry);
|
||||
const blender::bke::CurvesGeometry &curves = curves_id->geometry.wrap();
|
||||
|
||||
float3 min(FLT_MAX);
|
||||
float3 max(-FLT_MAX);
|
||||
|
@ -372,7 +371,7 @@ Curves *curves_new_nomain(const int points_num, const int curves_num)
|
|||
BLI_assert(points_num >= 0);
|
||||
BLI_assert(curves_num >= 0);
|
||||
Curves *curves_id = static_cast<Curves *>(BKE_id_new_nomain(ID_CV, nullptr));
|
||||
CurvesGeometry &curves = CurvesGeometry::wrap(curves_id->geometry);
|
||||
CurvesGeometry &curves = curves_id->geometry.wrap();
|
||||
curves.resize(points_num, curves_num);
|
||||
return curves_id;
|
||||
}
|
||||
|
@ -380,7 +379,7 @@ Curves *curves_new_nomain(const int points_num, const int curves_num)
|
|||
Curves *curves_new_nomain_single(const int points_num, const CurveType type)
|
||||
{
|
||||
Curves *curves_id = curves_new_nomain(points_num, 1);
|
||||
CurvesGeometry &curves = CurvesGeometry::wrap(curves_id->geometry);
|
||||
CurvesGeometry &curves = curves_id->geometry.wrap();
|
||||
curves.offsets_for_write().last() = points_num;
|
||||
curves.fill_curve_types(type);
|
||||
return curves_id;
|
||||
|
@ -389,7 +388,7 @@ Curves *curves_new_nomain_single(const int points_num, const CurveType type)
|
|||
Curves *curves_new_nomain(CurvesGeometry curves)
|
||||
{
|
||||
Curves *curves_id = static_cast<Curves *>(BKE_id_new_nomain(ID_CV, nullptr));
|
||||
bke::CurvesGeometry::wrap(curves_id->geometry) = std::move(curves);
|
||||
curves_id->geometry.wrap() = std::move(curves);
|
||||
return curves_id;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ void GeometryComponentEditData::remember_deformed_curve_positions_if_necessary(
|
|||
if (curves_id == nullptr) {
|
||||
return;
|
||||
}
|
||||
const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id->geometry);
|
||||
const bke::CurvesGeometry &curves = curves_id->geometry.wrap();
|
||||
const int points_num = curves.points_num();
|
||||
if (points_num != edit_component.curves_edit_hints_->curves_id_orig.geometry.point_num) {
|
||||
return;
|
||||
|
|
|
@ -55,7 +55,7 @@ GeometryFieldContext::GeometryFieldContext(const GeometryComponent &component,
|
|||
case GEO_COMPONENT_TYPE_CURVE: {
|
||||
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
|
||||
const Curves *curves = curve_component.get_for_read();
|
||||
geometry_ = curves ? &CurvesGeometry::wrap(curves->geometry) : nullptr;
|
||||
geometry_ = curves ? &curves->geometry.wrap() : nullptr;
|
||||
break;
|
||||
}
|
||||
case GEO_COMPONENT_TYPE_POINT_CLOUD: {
|
||||
|
@ -560,8 +560,7 @@ std::optional<eAttrDomain> try_detect_field_domain(const GeometryComponent &comp
|
|||
}
|
||||
else if (const auto *curves_field_input = dynamic_cast<const CurvesFieldInput *>(
|
||||
&field_input)) {
|
||||
if (!handle_domain(
|
||||
curves_field_input->preferred_domain(CurvesGeometry::wrap(curves->geometry)))) {
|
||||
if (!handle_domain(curves_field_input->preferred_domain(curves->geometry.wrap()))) {
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -227,7 +227,7 @@ bool GeometrySet::compute_boundbox_without_instances(float3 *r_min, float3 *r_ma
|
|||
have_minmax |= BKE_volume_min_max(volume, *r_min, *r_max);
|
||||
}
|
||||
if (const Curves *curves_id = this->get_curves_for_read()) {
|
||||
const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id->geometry);
|
||||
const bke::CurvesGeometry &curves = curves_id->geometry.wrap();
|
||||
have_minmax |= curves.bounds_min_max(*r_min, *r_max);
|
||||
}
|
||||
return have_minmax;
|
||||
|
|
|
@ -802,8 +802,7 @@ static Mesh *mesh_new_from_evaluated_curve_type_object(const Object *evaluated_o
|
|||
}
|
||||
if (const Curves *curves = get_evaluated_curves_from_object(evaluated_object)) {
|
||||
const blender::bke::AnonymousAttributePropagationInfo propagation_info;
|
||||
return blender::bke::curve_to_wire_mesh(blender::bke::CurvesGeometry::wrap(curves->geometry),
|
||||
propagation_info);
|
||||
return blender::bke::curve_to_wire_mesh(curves->geometry.wrap(), propagation_info);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -1228,12 +1228,19 @@ void BKE_mesh_legacy_face_set_from_generic(Mesh *mesh,
|
|||
blender::MutableSpan<CustomDataLayer> poly_layers)
|
||||
{
|
||||
using namespace blender;
|
||||
void *faceset_data = nullptr;
|
||||
for (CustomDataLayer &layer : poly_layers) {
|
||||
if (StringRef(layer.name) == ".sculpt_face_set") {
|
||||
layer.type = CD_SCULPT_FACE_SETS;
|
||||
faceset_data = layer.data;
|
||||
layer.data = nullptr;
|
||||
CustomData_free_layer_named(&mesh->pdata, ".sculpt_face_set", mesh->totpoly);
|
||||
break;
|
||||
}
|
||||
}
|
||||
CustomData_update_typemap(&mesh->pdata);
|
||||
if (faceset_data != nullptr) {
|
||||
CustomData_add_layer(
|
||||
&mesh->pdata, CD_SCULPT_FACE_SETS, CD_ASSIGN, faceset_data, mesh->totpoly);
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_mesh_legacy_face_set_to_generic(Mesh *mesh)
|
||||
|
@ -1242,13 +1249,19 @@ void BKE_mesh_legacy_face_set_to_generic(Mesh *mesh)
|
|||
if (mesh->attributes().contains(".sculpt_face_set")) {
|
||||
return;
|
||||
}
|
||||
for (CustomDataLayer &layer : MutableSpan(mesh->pdata.layers, mesh->pdata.totlayer)) {
|
||||
if (layer.type == CD_SCULPT_FACE_SETS) {
|
||||
BLI_strncpy(layer.name, ".sculpt_face_set", sizeof(layer.name));
|
||||
layer.type = CD_PROP_INT32;
|
||||
void *faceset_data = nullptr;
|
||||
for (const int i : IndexRange(mesh->pdata.totlayer)) {
|
||||
if (mesh->pdata.layers[i].type == CD_SCULPT_FACE_SETS) {
|
||||
faceset_data = mesh->pdata.layers[i].data;
|
||||
mesh->pdata.layers[i].data = nullptr;
|
||||
CustomData_free_layer(&mesh->pdata, CD_SCULPT_FACE_SETS, mesh->totpoly, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
CustomData_update_typemap(&mesh->pdata);
|
||||
if (faceset_data != nullptr) {
|
||||
CustomData_add_layer_named(
|
||||
&mesh->pdata, CD_PROP_INT32, CD_ASSIGN, faceset_data, mesh->totpoly, ".sculpt_face_set");
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -922,7 +922,11 @@ void ntreeBlendReadLib(BlendLibReader *reader, bNodeTree *ntree)
|
|||
* to match the static layout. */
|
||||
if (!BLO_read_lib_is_undo(reader)) {
|
||||
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
|
||||
node_verify_sockets(ntree, node, false);
|
||||
/* Don't update node groups here because they may depend on other node groups which are not
|
||||
* fully versioned yet and don't have `typeinfo` pointers set. */
|
||||
if (node->type != NODE_GROUP) {
|
||||
node_verify_sockets(ntree, node, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1075,7 +1079,7 @@ IDTypeInfo IDType_ID_NT = {
|
|||
|
||||
static void node_add_sockets_from_type(bNodeTree *ntree, bNode *node, bNodeType *ntype)
|
||||
{
|
||||
if (ntype->declare != nullptr) {
|
||||
if (ntype->declare || ntype->declare_dynamic) {
|
||||
node_verify_sockets(ntree, node, true);
|
||||
return;
|
||||
}
|
||||
|
@ -3587,31 +3591,43 @@ static void update_socket_declarations(ListBase *sockets,
|
|||
}
|
||||
}
|
||||
|
||||
static void reset_socket_declarations(ListBase *sockets)
|
||||
{
|
||||
LISTBASE_FOREACH (bNodeSocket *, socket, sockets) {
|
||||
socket->runtime->declaration = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void nodeSocketDeclarationsUpdate(bNode *node)
|
||||
{
|
||||
BLI_assert(node->runtime->declaration != nullptr);
|
||||
update_socket_declarations(&node->inputs, node->runtime->declaration->inputs);
|
||||
update_socket_declarations(&node->outputs, node->runtime->declaration->outputs);
|
||||
if (node->runtime->declaration->skip_updating_sockets) {
|
||||
reset_socket_declarations(&node->inputs);
|
||||
reset_socket_declarations(&node->outputs);
|
||||
}
|
||||
else {
|
||||
update_socket_declarations(&node->inputs, node->runtime->declaration->inputs);
|
||||
update_socket_declarations(&node->outputs, node->runtime->declaration->outputs);
|
||||
}
|
||||
}
|
||||
|
||||
bool nodeDeclarationEnsureOnOutdatedNode(bNodeTree * /*ntree*/, bNode *node)
|
||||
bool nodeDeclarationEnsureOnOutdatedNode(bNodeTree *ntree, bNode *node)
|
||||
{
|
||||
if (node->runtime->declaration != nullptr) {
|
||||
return false;
|
||||
}
|
||||
if (node->typeinfo->declare == nullptr) {
|
||||
return false;
|
||||
}
|
||||
if (node->typeinfo->declare_dynamic) {
|
||||
node->runtime->declaration = new blender::nodes::NodeDeclaration();
|
||||
blender::nodes::build_node_declaration(*node->typeinfo, *node->runtime->declaration);
|
||||
blender::nodes::build_node_declaration_dynamic(*ntree, *node, *node->runtime->declaration);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if (node->typeinfo->declare) {
|
||||
/* Declaration should have been created in #nodeRegisterType. */
|
||||
BLI_assert(node->typeinfo->fixed_declaration != nullptr);
|
||||
node->runtime->declaration = node->typeinfo->fixed_declaration;
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool nodeDeclarationEnsure(bNodeTree *ntree, bNode *node)
|
||||
|
|
|
@ -476,11 +476,12 @@ static const AVCodec *get_av1_encoder(
|
|||
const AVCodec *codec = NULL;
|
||||
switch (context->ffmpeg_preset) {
|
||||
case FFM_PRESET_BEST:
|
||||
/* Default to libaom-av1 for BEST preset due to it performing better than rav1e in terms of
|
||||
* video quality (VMAF scores). Fallback to rav1e if libaom-av1 isn't available. */
|
||||
codec = avcodec_find_encoder_by_name("libaom-av1");
|
||||
/* libaom-av1 may produce better VMAF-scoring videos in serveral cases, but there are cases
|
||||
* where using a different encoder is desireable, such as in T103849. */
|
||||
codec = avcodec_find_encoder_by_name("librav1e");
|
||||
if (!codec) {
|
||||
codec = avcodec_find_encoder_by_name("librav1e");
|
||||
/* Fallback to libaom-av1 if librav1e is not found. */
|
||||
codec = avcodec_find_encoder_by_name("libaom-av1");
|
||||
}
|
||||
break;
|
||||
case FFM_PRESET_REALTIME:
|
||||
|
|
|
@ -174,6 +174,18 @@ template<typename T, int Size> struct VecBase : public vec_struct_base<T, Size>
|
|||
}
|
||||
}
|
||||
|
||||
/** Swizzling. */
|
||||
|
||||
template<BLI_ENABLE_IF_VEC(Size, >= 3)> VecBase<T, 2> xy() const
|
||||
{
|
||||
return *reinterpret_cast<const VecBase<T, 2> *>(this);
|
||||
}
|
||||
|
||||
template<BLI_ENABLE_IF_VEC(Size, >= 4)> VecBase<T, 3> xyz() const
|
||||
{
|
||||
return *reinterpret_cast<const VecBase<T, 3> *>(this);
|
||||
}
|
||||
|
||||
#undef BLI_ENABLE_IF_VEC
|
||||
|
||||
/** Conversion from pointers (from C-style vectors). */
|
||||
|
|
|
@ -26,33 +26,33 @@ typedef NodeOperation SocketReader;
|
|||
class OpenCLDevice : public Device {
|
||||
private:
|
||||
/**
|
||||
* \brief opencl context
|
||||
* \brief OPENCL context
|
||||
*/
|
||||
cl_context context_;
|
||||
|
||||
/**
|
||||
* \brief opencl device
|
||||
* \brief OPENCL device
|
||||
*/
|
||||
cl_device_id device_;
|
||||
|
||||
/**
|
||||
* \brief opencl program
|
||||
* \brief OPENCL program
|
||||
*/
|
||||
cl_program program_;
|
||||
|
||||
/**
|
||||
* \brief opencl command queue
|
||||
* \brief OPENCL command queue
|
||||
*/
|
||||
cl_command_queue queue_;
|
||||
|
||||
/**
|
||||
* \brief opencl vendor ID
|
||||
* \brief OPENCL vendor ID
|
||||
*/
|
||||
cl_int vendor_id_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* \brief constructor with opencl device
|
||||
* \brief constructor with OPENCL device
|
||||
* \param context:
|
||||
* \param device:
|
||||
* \param program:
|
||||
|
|
|
@ -230,7 +230,7 @@ static void compositor_engine_draw(void *data)
|
|||
if (GPU_backend_get_type() == GPU_BACKEND_METAL) {
|
||||
/* NOTE(Metal): Isolate Compositor compute work in individual command buffer to improve
|
||||
* workload scheduling. When expensive compositor nodes are in the graph, these can stall out
|
||||
* the GPU for extended periods of time and suboptimally schedule work for execution. */
|
||||
* the GPU for extended periods of time and sub-optimally schedule work for execution. */
|
||||
GPU_flush();
|
||||
}
|
||||
else {
|
||||
|
@ -241,11 +241,11 @@ static void compositor_engine_draw(void *data)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Exceute Compositor render commands. */
|
||||
/* Execute Compositor render commands. */
|
||||
compositor_data->instance_data->draw();
|
||||
|
||||
#if defined(__APPLE__)
|
||||
/* NOTE(Metal): Following previous flush to break commmand stream, with compositor command
|
||||
/* NOTE(Metal): Following previous flush to break command stream, with compositor command
|
||||
* buffers potentially being heavy, we avoid issuing subsequent commands until compositor work
|
||||
* has completed. If subsequent work is prematurely queued up, the subsequent command buffers
|
||||
* will be blocked behind compositor work and may trigger a command buffer time-out error. As a
|
||||
|
|
|
@ -644,21 +644,24 @@ void OVERLAY_light_cache_populate(OVERLAY_Data *vedata, Object *ob)
|
|||
DRW_buffer_add_entry(cb->light_sun, color, &instdata);
|
||||
}
|
||||
else if (la->type == LA_SPOT) {
|
||||
/* Previous implementation was using the clipend distance as cone size.
|
||||
/* Previous implementation was using the clip-end distance as cone size.
|
||||
* We cannot do this anymore so we use a fixed size of 10. (see T72871) */
|
||||
const float3 scale_vec = {10.0f, 10.0f, 10.0f};
|
||||
rescale_m4(instdata.mat, scale_vec);
|
||||
/* For cycles and eevee the spot attenuation is
|
||||
* y = (1/(1 + x^2) - a)/((1 - a) b)
|
||||
/* For cycles and EEVEE the spot attenuation is:
|
||||
* `y = (1/sqrt(1 + x^2) - a)/((1 - a) b)`
|
||||
* x being the tangent of the angle between the light direction and the generatrix of the cone.
|
||||
* We solve the case where spot attenuation y = 1 and y = 0
|
||||
* root for y = 1 is (-1 - c) / c
|
||||
* root for y = 0 is (1 - a) / a
|
||||
* root for y = 1 is sqrt(1/c^2 - 1)
|
||||
* root for y = 0 is sqrt(1/a^2 - 1)
|
||||
* and use that to position the blend circle. */
|
||||
float a = cosf(la->spotsize * 0.5f);
|
||||
float b = la->spotblend;
|
||||
float c = a * b - a - b;
|
||||
float a2 = a * a;
|
||||
float c2 = c * c;
|
||||
/* Optimized version or root1 / root0 */
|
||||
instdata.spot_blend = sqrtf((-a - c * a) / (c - c * a));
|
||||
instdata.spot_blend = sqrtf((a2 - a2 * c2) / (c2 - a2 * c2));
|
||||
instdata.spot_cosine = a;
|
||||
/* HACK: We pack the area size in alpha color. This is decoded by the shader. */
|
||||
color[3] = -max_ff(la->radius, FLT_MIN);
|
||||
|
|
|
@ -33,7 +33,7 @@ void OVERLAY_sculpt_curves_cache_init(OVERLAY_Data *vedata)
|
|||
static bool everything_selected(const Curves &curves_id)
|
||||
{
|
||||
using namespace blender;
|
||||
const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry);
|
||||
const bke::CurvesGeometry &curves = curves_id.geometry.wrap();
|
||||
const VArray<bool> selection = curves.attributes().lookup_or_default<bool>(
|
||||
".selection", ATTR_DOMAIN_POINT, true);
|
||||
return selection.is_single() && selection.get_internal_single();
|
||||
|
|
|
@ -131,7 +131,7 @@ static void populate_cache_for_geometry(Object &object,
|
|||
}
|
||||
case OB_CURVES_LEGACY: {
|
||||
Curve *curve = static_cast<Curve *>(object.data);
|
||||
const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curve->curve_eval->geometry);
|
||||
const bke::CurvesGeometry &curves = curve->curve_eval->geometry.wrap();
|
||||
if (curves.attributes().contains(".viewer")) {
|
||||
GPUBatch *batch = DRW_cache_curve_edge_wire_viewer_attribute_get(&object);
|
||||
DRW_shgroup_uniform_float_copy(pd.viewer_attribute_curve_grp, "opacity", opacity);
|
||||
|
@ -141,7 +141,7 @@ static void populate_cache_for_geometry(Object &object,
|
|||
}
|
||||
case OB_CURVES: {
|
||||
Curves *curves_id = static_cast<Curves *>(object.data);
|
||||
const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id->geometry);
|
||||
const bke::CurvesGeometry &curves = curves_id->geometry.wrap();
|
||||
if (curves.attributes().contains(".viewer")) {
|
||||
bool is_point_domain;
|
||||
GPUVertBuf **texture = DRW_curves_texture_for_evaluated_attribute(
|
||||
|
|
|
@ -213,11 +213,10 @@ static CurveRenderData *curve_render_data_create(Curve *cu,
|
|||
|
||||
if (types & CU_DATATYPE_WIRE) {
|
||||
if (rdata->curve_eval != nullptr) {
|
||||
curve_eval_render_wire_verts_edges_len_get(
|
||||
blender::bke::CurvesGeometry::wrap(rdata->curve_eval->geometry),
|
||||
&rdata->wire.curve_len,
|
||||
&rdata->wire.vert_len,
|
||||
&rdata->wire.edge_len);
|
||||
curve_eval_render_wire_verts_edges_len_get(rdata->curve_eval->geometry.wrap(),
|
||||
&rdata->wire.curve_len,
|
||||
&rdata->wire.vert_len,
|
||||
&rdata->wire.edge_len);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -473,8 +472,7 @@ static void curve_create_curves_pos(CurveRenderData *rdata, GPUVertBuf *vbo_curv
|
|||
GPU_vertbuf_init_with_format(vbo_curves_pos, &format);
|
||||
GPU_vertbuf_data_alloc(vbo_curves_pos, vert_len);
|
||||
|
||||
const blender::bke::CurvesGeometry &curves = blender::bke::CurvesGeometry::wrap(
|
||||
rdata->curve_eval->geometry);
|
||||
const blender::bke::CurvesGeometry &curves = rdata->curve_eval->geometry.wrap();
|
||||
const Span<float3> positions = curves.evaluated_positions();
|
||||
GPU_vertbuf_attr_fill(vbo_curves_pos, attr_id.pos, positions.data());
|
||||
}
|
||||
|
@ -495,7 +493,7 @@ static void curve_create_attribute(CurveRenderData *rdata, GPUVertBuf *vbo_attr)
|
|||
GPU_vertbuf_init_with_format(vbo_attr, &format);
|
||||
GPU_vertbuf_data_alloc(vbo_attr, vert_len);
|
||||
|
||||
const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(rdata->curve_eval->geometry);
|
||||
const bke::CurvesGeometry &curves = rdata->curve_eval->geometry.wrap();
|
||||
curves.ensure_can_interpolate_to_evaluated();
|
||||
const VArraySpan<ColorGeometry4f> colors = curves.attributes().lookup<ColorGeometry4f>(
|
||||
".viewer", ATTR_DOMAIN_POINT);
|
||||
|
@ -519,7 +517,7 @@ static void curve_create_curves_lines(CurveRenderData *rdata, GPUIndexBuf *ibo_c
|
|||
GPUIndexBufBuilder elb;
|
||||
GPU_indexbuf_init_ex(&elb, GPU_PRIM_LINE_STRIP, index_len, vert_len);
|
||||
|
||||
const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(rdata->curve_eval->geometry);
|
||||
const bke::CurvesGeometry &curves = rdata->curve_eval->geometry.wrap();
|
||||
const OffsetIndices points_by_curve = curves.evaluated_points_by_curve();
|
||||
const VArray<bool> cyclic = curves.cyclic();
|
||||
|
||||
|
|
|
@ -237,7 +237,7 @@ static void curves_batch_cache_fill_segments_proc_pos(
|
|||
{
|
||||
using namespace blender;
|
||||
/* TODO: use hair radius layer if available. */
|
||||
const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry);
|
||||
const bke::CurvesGeometry &curves = curves_id.geometry.wrap();
|
||||
const OffsetIndices points_by_curve = curves.points_by_curve();
|
||||
const Span<float3> positions = curves.positions();
|
||||
|
||||
|
@ -305,7 +305,7 @@ static void curves_batch_cache_ensure_edit_points_pos(const Curves &curves_id,
|
|||
CurvesBatchCache &cache)
|
||||
{
|
||||
using namespace blender;
|
||||
const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry);
|
||||
const bke::CurvesGeometry &curves = curves_id.geometry.wrap();
|
||||
|
||||
static GPUVertFormat format_pos = {0};
|
||||
static uint pos;
|
||||
|
@ -324,7 +324,7 @@ static void curves_batch_cache_ensure_edit_points_data(const Curves &curves_id,
|
|||
CurvesBatchCache &cache)
|
||||
{
|
||||
using namespace blender;
|
||||
const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry);
|
||||
const bke::CurvesGeometry &curves = curves_id.geometry.wrap();
|
||||
|
||||
static GPUVertFormat format_data = {0};
|
||||
static uint color;
|
||||
|
@ -361,7 +361,7 @@ static void curves_batch_cache_ensure_edit_points_data(const Curves &curves_id,
|
|||
static void curves_batch_cache_ensure_edit_lines(const Curves &curves_id, CurvesBatchCache &cache)
|
||||
{
|
||||
using namespace blender;
|
||||
const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry);
|
||||
const bke::CurvesGeometry &curves = curves_id.geometry.wrap();
|
||||
|
||||
const int vert_len = curves.points_num();
|
||||
const int curve_len = curves.curves_num();
|
||||
|
@ -432,8 +432,7 @@ static void curves_batch_ensure_attribute(const Curves &curves,
|
|||
request.domain == ATTR_DOMAIN_POINT ? curves.geometry.point_num :
|
||||
curves.geometry.curve_num);
|
||||
|
||||
const bke::AttributeAccessor attributes =
|
||||
bke::CurvesGeometry::wrap(curves.geometry).attributes();
|
||||
const bke::AttributeAccessor attributes = curves.geometry.wrap().attributes();
|
||||
|
||||
/* TODO(@kevindietrich): float4 is used for scalar attributes as the implicit conversion done
|
||||
* by OpenGL to vec4 for a scalar `s` will produce a `vec4(s, 0, 0, 1)`. However, following
|
||||
|
@ -463,8 +462,7 @@ static void curves_batch_cache_fill_strands_data(const Curves &curves_id,
|
|||
GPUVertBufRaw &data_step,
|
||||
GPUVertBufRaw &seg_step)
|
||||
{
|
||||
const blender::bke::CurvesGeometry &curves = blender::bke::CurvesGeometry::wrap(
|
||||
curves_id.geometry);
|
||||
const blender::bke::CurvesGeometry &curves = curves_id.geometry.wrap();
|
||||
const blender::OffsetIndices points_by_curve = curves.points_by_curve();
|
||||
|
||||
for (const int i : IndexRange(curves.curves_num())) {
|
||||
|
@ -694,8 +692,7 @@ static void request_attribute(Curves &curves, const char *name)
|
|||
|
||||
DRW_Attributes attributes{};
|
||||
|
||||
blender::bke::CurvesGeometry &curves_geometry = blender::bke::CurvesGeometry::wrap(
|
||||
curves.geometry);
|
||||
blender::bke::CurvesGeometry &curves_geometry = curves.geometry.wrap();
|
||||
std::optional<blender::bke::AttributeMetaData> meta_data =
|
||||
curves_geometry.attributes().lookup_meta_data(name);
|
||||
if (!meta_data) {
|
||||
|
|
|
@ -327,8 +327,7 @@ DRWShadingGroup *DRW_shgroup_curves_create_sub(Object *object,
|
|||
|
||||
/* Use the radius of the root and tip of the first curve for now. This is a workaround that we
|
||||
* use for now because we can't use a per-point radius yet. */
|
||||
const blender::bke::CurvesGeometry &curves = blender::bke::CurvesGeometry::wrap(
|
||||
curves_id.geometry);
|
||||
const blender::bke::CurvesGeometry &curves = curves_id.geometry.wrap();
|
||||
if (curves.curves_num() >= 1) {
|
||||
blender::VArray<float> radii = curves.attributes().lookup_or_default(
|
||||
"radius", ATTR_DOMAIN_POINT, 0.005f);
|
||||
|
|
|
@ -929,7 +929,7 @@ static bool acf_group_setting_valid(bAnimContext *ac,
|
|||
return (ac->spacetype == SPACE_GRAPH);
|
||||
|
||||
case ACHANNEL_SETTING_ALWAYS_VISIBLE:
|
||||
return (ac->spacetype == SPACE_GRAPH);
|
||||
return ELEM(ac->spacetype, SPACE_ACTION, SPACE_GRAPH);
|
||||
|
||||
default: /* always supported */
|
||||
return true;
|
||||
|
@ -4434,7 +4434,7 @@ void ANIM_channel_draw(
|
|||
* - in Grease Pencil mode, color swatches for layer color
|
||||
*/
|
||||
if (ac->sl) {
|
||||
if ((ac->spacetype == SPACE_GRAPH) &&
|
||||
if (ELEM(ac->spacetype, SPACE_ACTION, SPACE_GRAPH) &&
|
||||
(acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE) ||
|
||||
acf->has_setting(ac, ale, ACHANNEL_SETTING_ALWAYS_VISIBLE))) {
|
||||
/* for F-Curves, draw color-preview of curve left to the visibility icon */
|
||||
|
@ -5177,7 +5177,7 @@ void ANIM_channel_draw_widgets(const bContext *C,
|
|||
* - in Grease Pencil mode, color swatches for layer color
|
||||
*/
|
||||
if (ac->sl) {
|
||||
if ((ac->spacetype == SPACE_GRAPH) &&
|
||||
if (ELEM(ac->spacetype, SPACE_ACTION, SPACE_GRAPH) &&
|
||||
(acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE) ||
|
||||
acf->has_setting(ac, ale, ACHANNEL_SETTING_ALWAYS_VISIBLE))) {
|
||||
/* Pin toggle. */
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
float (*ED_curves_point_normals_array_create(const Curves *curves_id))[3]
|
||||
{
|
||||
using namespace blender;
|
||||
const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id->geometry);
|
||||
const bke::CurvesGeometry &curves = curves_id->geometry.wrap();
|
||||
const int size = curves.points_num();
|
||||
|
||||
float3 *data = static_cast<float3 *>(MEM_malloc_arrayN(size, sizeof(float3), __func__));
|
||||
|
|
|
@ -238,7 +238,7 @@ static void try_convert_single_object(Object &curves_ob,
|
|||
return;
|
||||
}
|
||||
Curves &curves_id = *static_cast<Curves *>(curves_ob.data);
|
||||
CurvesGeometry &curves = CurvesGeometry::wrap(curves_id.geometry);
|
||||
CurvesGeometry &curves = curves_id.geometry.wrap();
|
||||
if (curves_id.surface == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
@ -521,7 +521,7 @@ static int curves_convert_from_particle_system_exec(bContext *C, wmOperator * /*
|
|||
Object *ob_new = BKE_object_add(&bmain, &scene, &view_layer, OB_CURVES, psys_eval->name);
|
||||
Curves *curves_id = static_cast<Curves *>(ob_new->data);
|
||||
BKE_object_apply_mat4(ob_new, ob_from_orig->object_to_world, true, false);
|
||||
bke::CurvesGeometry::wrap(curves_id->geometry) = particles_to_curves(*ob_from_eval, *psys_eval);
|
||||
curves_id->geometry.wrap() = particles_to_curves(*ob_from_eval, *psys_eval);
|
||||
|
||||
DEG_relations_tag_update(&bmain);
|
||||
WM_main_add_notifier(NC_OBJECT | ND_DRAW, nullptr);
|
||||
|
@ -562,7 +562,7 @@ static void snap_curves_to_surface_exec_object(Object &curves_ob,
|
|||
bool *r_missing_uvs)
|
||||
{
|
||||
Curves &curves_id = *static_cast<Curves *>(curves_ob.data);
|
||||
CurvesGeometry &curves = CurvesGeometry::wrap(curves_id.geometry);
|
||||
CurvesGeometry &curves = curves_id.geometry.wrap();
|
||||
|
||||
const Mesh &surface_mesh = *static_cast<const Mesh *>(surface_ob.data);
|
||||
const Span<float3> surface_positions = surface_mesh.vert_positions();
|
||||
|
@ -774,7 +774,7 @@ static int curves_set_selection_domain_exec(bContext *C, wmOperator *op)
|
|||
|
||||
curves_id->selection_domain = domain;
|
||||
|
||||
CurvesGeometry &curves = CurvesGeometry::wrap(curves_id->geometry);
|
||||
CurvesGeometry &curves = curves_id->geometry.wrap();
|
||||
bke::MutableAttributeAccessor attributes = curves.attributes_for_write();
|
||||
if (curves.points_num() == 0) {
|
||||
continue;
|
||||
|
@ -830,7 +830,7 @@ static void CURVES_OT_set_selection_domain(wmOperatorType *ot)
|
|||
static bool has_anything_selected(const Span<Curves *> curves_ids)
|
||||
{
|
||||
return std::any_of(curves_ids.begin(), curves_ids.end(), [](const Curves *curves_id) {
|
||||
return has_anything_selected(CurvesGeometry::wrap(curves_id->geometry));
|
||||
return has_anything_selected(curves_id->geometry.wrap());
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -846,9 +846,7 @@ static int select_all_exec(bContext *C, wmOperator *op)
|
|||
|
||||
for (Curves *curves_id : unique_curves) {
|
||||
/* (De)select all the curves. */
|
||||
select_all(CurvesGeometry::wrap(curves_id->geometry),
|
||||
eAttrDomain(curves_id->selection_domain),
|
||||
action);
|
||||
select_all(curves_id->geometry.wrap(), eAttrDomain(curves_id->selection_domain), action);
|
||||
|
||||
/* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic
|
||||
* attribute for now. */
|
||||
|
@ -881,7 +879,7 @@ static int select_random_exec(bContext *C, wmOperator *op)
|
|||
const float probability = RNA_float_get(op->ptr, "probability");
|
||||
|
||||
for (Curves *curves_id : unique_curves) {
|
||||
CurvesGeometry &curves = CurvesGeometry::wrap(curves_id->geometry);
|
||||
CurvesGeometry &curves = curves_id->geometry.wrap();
|
||||
select_random(curves, eAttrDomain(curves_id->selection_domain), uint32_t(seed), probability);
|
||||
|
||||
/* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic
|
||||
|
@ -952,7 +950,7 @@ static int select_end_exec(bContext *C, wmOperator *op)
|
|||
const int amount = RNA_int_get(op->ptr, "amount");
|
||||
|
||||
for (Curves *curves_id : unique_curves) {
|
||||
CurvesGeometry &curves = CurvesGeometry::wrap(curves_id->geometry);
|
||||
CurvesGeometry &curves = curves_id->geometry.wrap();
|
||||
select_ends(curves, eAttrDomain(curves_id->selection_domain), amount, end_points);
|
||||
|
||||
/* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic
|
||||
|
|
|
@ -52,7 +52,7 @@ static IndexMask retrieve_selected_curves(const bke::CurvesGeometry &curves,
|
|||
|
||||
IndexMask retrieve_selected_curves(const Curves &curves_id, Vector<int64_t> &r_indices)
|
||||
{
|
||||
const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry);
|
||||
const bke::CurvesGeometry &curves = curves_id.geometry.wrap();
|
||||
return retrieve_selected_curves(curves, r_indices);
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ IndexMask retrieve_selected_points(const bke::CurvesGeometry &curves, Vector<int
|
|||
|
||||
IndexMask retrieve_selected_points(const Curves &curves_id, Vector<int64_t> &r_indices)
|
||||
{
|
||||
const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry);
|
||||
const bke::CurvesGeometry &curves = curves_id.geometry.wrap();
|
||||
return retrieve_selected_points(curves, r_indices);
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ static bool step_encode(bContext *C, Main *bmain, UndoStep *us_p)
|
|||
StepObject &object = us->objects[i];
|
||||
|
||||
object.obedit_ref.ptr = ob;
|
||||
object.geometry = bke::CurvesGeometry::wrap(curves_id.geometry);
|
||||
object.geometry = curves_id.geometry.wrap();
|
||||
}
|
||||
});
|
||||
MEM_SAFE_FREE(objects);
|
||||
|
@ -86,7 +86,7 @@ static void step_decode(
|
|||
Curves &curves_id = *static_cast<Curves *>(object.obedit_ref.ptr->data);
|
||||
|
||||
/* Overwrite the curves geometry. */
|
||||
bke::CurvesGeometry::wrap(curves_id.geometry) = object.geometry;
|
||||
curves_id.geometry.wrap() = object.geometry;
|
||||
|
||||
DEG_id_tag_update(&curves_id.id, ID_RECALC_GEOMETRY);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
* 2D Gizmo
|
||||
*
|
||||
* \brief Rectangular gizmo acting as a 'cage' around its content.
|
||||
* \brief Rectangular or circular gizmo acting as a 'cage' around its content.
|
||||
* Interacting scales or translates the gizmo.
|
||||
*/
|
||||
|
||||
|
@ -41,6 +41,8 @@
|
|||
#include "../gizmo_library_intern.h"
|
||||
|
||||
#define GIZMO_MARGIN_OFFSET_SCALE 1.5f
|
||||
/* The same as in `draw_cache.c` */
|
||||
#define CIRCLE_RESOL 32
|
||||
|
||||
static bool gizmo_calc_rect_view_scale(const wmGizmo *gz, const float dims[2], float scale[2])
|
||||
{
|
||||
|
@ -345,7 +347,7 @@ static void cage2d_draw_box_interaction(const float color[4],
|
|||
}
|
||||
|
||||
case ED_GIZMO_CAGE2D_PART_TRANSLATE:
|
||||
if (draw_options & ED_GIZMO_CAGE2D_DRAW_FLAG_XFORM_CENTER_HANDLE) {
|
||||
if (draw_options & ED_GIZMO_CAGE_DRAW_FLAG_XFORM_CENTER_HANDLE) {
|
||||
ARRAY_SET_ITEMS(verts[0], -margin[0] / 2, -margin[1] / 2);
|
||||
ARRAY_SET_ITEMS(verts[1], margin[0] / 2, margin[1] / 2);
|
||||
ARRAY_SET_ITEMS(verts[2], -margin[0] / 2, margin[1] / 2);
|
||||
|
@ -472,12 +474,12 @@ static void imm_draw_point_aspect_2d(
|
|||
}
|
||||
}
|
||||
|
||||
static void cage2d_draw_circle_wire(const rctf *r,
|
||||
const float margin[2],
|
||||
const float color[3],
|
||||
const int transform_flag,
|
||||
const int draw_options,
|
||||
const float line_width)
|
||||
static void cage2d_draw_rect_wire(const rctf *r,
|
||||
const float margin[2],
|
||||
const float color[3],
|
||||
const int transform_flag,
|
||||
const int draw_options,
|
||||
const float line_width)
|
||||
{
|
||||
/* NOTE(Metal): Prefer using 3D coordinates with 3D shader input, even if rendering 2D gizmo's.
|
||||
*/
|
||||
|
@ -506,7 +508,7 @@ static void cage2d_draw_circle_wire(const rctf *r,
|
|||
immVertex3f(pos, r->xmin, r->ymin, 0.0f);
|
||||
immEnd();
|
||||
|
||||
if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE) {
|
||||
if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_ROTATE) {
|
||||
immBegin(GPU_PRIM_LINES, 4);
|
||||
immVertex3f(pos, BLI_rctf_cent_x(r), r->ymax, 0.0f);
|
||||
immVertex3f(pos, BLI_rctf_cent_x(r), r->ymax + margin[1], 0.0f);
|
||||
|
@ -516,8 +518,8 @@ static void cage2d_draw_circle_wire(const rctf *r,
|
|||
immEnd();
|
||||
}
|
||||
|
||||
if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE) {
|
||||
if (draw_options & ED_GIZMO_CAGE2D_DRAW_FLAG_XFORM_CENTER_HANDLE) {
|
||||
if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_TRANSLATE) {
|
||||
if (draw_options & ED_GIZMO_CAGE_DRAW_FLAG_XFORM_CENTER_HANDLE) {
|
||||
const float rad[2] = {margin[0] / 2, margin[1] / 2};
|
||||
const float center[2] = {BLI_rctf_cent_x(r), BLI_rctf_cent_y(r)};
|
||||
|
||||
|
@ -533,11 +535,31 @@ static void cage2d_draw_circle_wire(const rctf *r,
|
|||
immUnbindProgram();
|
||||
}
|
||||
|
||||
static void cage2d_draw_circle_handles(const rctf *r,
|
||||
const float margin[2],
|
||||
const float color[3],
|
||||
const int transform_flag,
|
||||
bool solid)
|
||||
static void cage2d_draw_circle_wire(const float color[3],
|
||||
const float size[2],
|
||||
const float margin,
|
||||
const float line_width)
|
||||
{
|
||||
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
||||
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
|
||||
immUniformColor3fv(color);
|
||||
|
||||
float viewport[4];
|
||||
GPU_viewport_size_get_f(viewport);
|
||||
immUniform2fv("viewportSize", &viewport[2]);
|
||||
immUniform1f("lineWidth", line_width * U.pixelsize + margin);
|
||||
|
||||
imm_draw_circle_wire_aspect_3d(pos, 0.0f, 0.0f, size[0], size[1], CIRCLE_RESOL);
|
||||
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
static void cage2d_draw_rect_handles(const rctf *r,
|
||||
const float margin[2],
|
||||
const float color[3],
|
||||
const int transform_flag,
|
||||
bool solid)
|
||||
{
|
||||
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
void (*circle_fn)(uint, float, float, float, float, int) = (solid) ?
|
||||
|
@ -557,7 +579,7 @@ static void cage2d_draw_circle_handles(const rctf *r,
|
|||
imm_draw_point_aspect_2d(pos, r->xmin, r->ymax, rad[0], rad[1], solid);
|
||||
}
|
||||
|
||||
if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE) {
|
||||
if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_ROTATE) {
|
||||
const float handle[2] = {
|
||||
BLI_rctf_cent_x(r),
|
||||
r->ymax + (margin[1] * GIZMO_MARGIN_OFFSET_SCALE),
|
||||
|
@ -609,39 +631,46 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz,
|
|||
if (select) {
|
||||
/* Expand for hot-spot. */
|
||||
const float size[2] = {size_real[0] + margin[0] / 2, size_real[1] + margin[1] / 2};
|
||||
if (draw_style == ED_GIZMO_CAGE2D_STYLE_CIRCLE) {
|
||||
/* Only scaling is needed for now. */
|
||||
GPU_select_load_id(select_id | ED_GIZMO_CAGE2D_PART_SCALE);
|
||||
cage2d_draw_circle_wire(
|
||||
gz->color, size_real, 0.5f * (margin[0] + margin[1]), gz->line_width);
|
||||
}
|
||||
else {
|
||||
if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_SCALE) {
|
||||
int scale_parts[] = {
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MIN_X,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MAX_X,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MIN_Y,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MAX_Y,
|
||||
|
||||
if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE) {
|
||||
int scale_parts[] = {
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MIN_X,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MAX_X,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MIN_Y,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MAX_Y,
|
||||
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MIN_Y,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MAX_Y,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MIN_Y,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MAX_Y,
|
||||
};
|
||||
for (int i = 0; i < ARRAY_SIZE(scale_parts); i++) {
|
||||
GPU_select_load_id(select_id | scale_parts[i]);
|
||||
cage2d_draw_box_interaction(
|
||||
gz->color, scale_parts[i], size, margin, gz->line_width, true, draw_options);
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MIN_Y,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MAX_Y,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MIN_Y,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MAX_Y,
|
||||
};
|
||||
for (int i = 0; i < ARRAY_SIZE(scale_parts); i++) {
|
||||
GPU_select_load_id(select_id | scale_parts[i]);
|
||||
cage2d_draw_box_interaction(
|
||||
gz->color, scale_parts[i], size, margin, gz->line_width, true, draw_options);
|
||||
}
|
||||
}
|
||||
if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_TRANSLATE) {
|
||||
const int transform_part = ED_GIZMO_CAGE2D_PART_TRANSLATE;
|
||||
GPU_select_load_id(select_id | transform_part);
|
||||
cage2d_draw_box_interaction(
|
||||
gz->color, transform_part, size, margin, gz->line_width, true, draw_options);
|
||||
}
|
||||
if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_ROTATE) {
|
||||
cage2d_draw_box_interaction(gz->color,
|
||||
ED_GIZMO_CAGE2D_PART_ROTATE,
|
||||
size_real,
|
||||
margin,
|
||||
gz->line_width,
|
||||
true,
|
||||
draw_options);
|
||||
}
|
||||
}
|
||||
if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE) {
|
||||
const int transform_part = ED_GIZMO_CAGE2D_PART_TRANSLATE;
|
||||
GPU_select_load_id(select_id | transform_part);
|
||||
cage2d_draw_box_interaction(
|
||||
gz->color, transform_part, size, margin, gz->line_width, true, draw_options);
|
||||
}
|
||||
if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE) {
|
||||
cage2d_draw_box_interaction(gz->color,
|
||||
ED_GIZMO_CAGE2D_PART_ROTATE,
|
||||
size_real,
|
||||
margin,
|
||||
gz->line_width,
|
||||
true,
|
||||
draw_options);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -665,7 +694,7 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz,
|
|||
if (gz->highlight_part == ED_GIZMO_CAGE2D_PART_TRANSLATE) {
|
||||
/* Only show if we're drawing the center handle
|
||||
* otherwise the entire rectangle is the hot-spot. */
|
||||
if (draw_options & ED_GIZMO_CAGE2D_DRAW_FLAG_XFORM_CENTER_HANDLE) {
|
||||
if (draw_options & ED_GIZMO_CAGE_DRAW_FLAG_XFORM_CENTER_HANDLE) {
|
||||
show = true;
|
||||
}
|
||||
}
|
||||
|
@ -678,7 +707,7 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz,
|
|||
gz->color, gz->highlight_part, size_real, margin, gz->line_width, false, draw_options);
|
||||
}
|
||||
|
||||
if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE) {
|
||||
if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_ROTATE) {
|
||||
cage2d_draw_box_interaction(gz->color,
|
||||
ED_GIZMO_CAGE2D_PART_ROTATE,
|
||||
size_real,
|
||||
|
@ -688,25 +717,31 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz,
|
|||
draw_options);
|
||||
}
|
||||
}
|
||||
else if (draw_style == ED_GIZMO_CAGE2D_STYLE_CIRCLE) {
|
||||
else {
|
||||
float color[4], black[3] = {0, 0, 0};
|
||||
gizmo_color_get(gz, highlight, color);
|
||||
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
|
||||
float outline_line_width = gz->line_width + 3.0f;
|
||||
cage2d_draw_circle_wire(&r, margin, black, transform_flag, draw_options, outline_line_width);
|
||||
cage2d_draw_circle_wire(&r, margin, color, transform_flag, draw_options, gz->line_width);
|
||||
|
||||
/* corner gizmos */
|
||||
cage2d_draw_circle_handles(&r, margin, color, transform_flag, true);
|
||||
cage2d_draw_circle_handles(&r, margin, (const float[3]){0, 0, 0}, transform_flag, false);
|
||||
if (draw_style == ED_GIZMO_CAGE2D_STYLE_RECTANGLE) {
|
||||
cage2d_draw_rect_wire(&r, margin, black, transform_flag, draw_options, outline_line_width);
|
||||
cage2d_draw_rect_wire(&r, margin, color, transform_flag, draw_options, gz->line_width);
|
||||
|
||||
/* corner gizmos */
|
||||
cage2d_draw_rect_handles(&r, margin, color, transform_flag, true);
|
||||
cage2d_draw_rect_handles(&r, margin, black, transform_flag, false);
|
||||
}
|
||||
else if (draw_style == ED_GIZMO_CAGE2D_STYLE_CIRCLE) {
|
||||
cage2d_draw_circle_wire(black, size_real, 0.0f, outline_line_width);
|
||||
cage2d_draw_circle_wire(color, size_real, 0.0f, gz->line_width);
|
||||
}
|
||||
else {
|
||||
BLI_assert(0);
|
||||
}
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
}
|
||||
else {
|
||||
BLI_assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
GPU_matrix_pop();
|
||||
|
@ -781,9 +816,9 @@ static int gizmo_cage2d_test_select(bContext *C, wmGizmo *gz, const int mval[2])
|
|||
const int transform_flag = RNA_enum_get(gz->ptr, "transform");
|
||||
const int draw_options = RNA_enum_get(gz->ptr, "draw_options");
|
||||
|
||||
if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE) {
|
||||
if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_TRANSLATE) {
|
||||
rctf r;
|
||||
if (draw_options & ED_GIZMO_CAGE2D_DRAW_FLAG_XFORM_CENTER_HANDLE) {
|
||||
if (draw_options & ED_GIZMO_CAGE_DRAW_FLAG_XFORM_CENTER_HANDLE) {
|
||||
r.xmin = -margin[0] / 2;
|
||||
r.ymin = -margin[1] / 2;
|
||||
r.xmax = margin[0] / 2;
|
||||
|
@ -802,8 +837,7 @@ static int gizmo_cage2d_test_select(bContext *C, wmGizmo *gz, const int mval[2])
|
|||
}
|
||||
|
||||
/* if gizmo does not have a scale intersection, don't do it */
|
||||
if (transform_flag &
|
||||
(ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE | ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE_UNIFORM)) {
|
||||
if (transform_flag & (ED_GIZMO_CAGE_XFORM_FLAG_SCALE | ED_GIZMO_CAGE_XFORM_FLAG_SCALE_UNIFORM)) {
|
||||
const rctf r_xmin = {
|
||||
.xmin = -size[0],
|
||||
.ymin = -size[1],
|
||||
|
@ -855,7 +889,7 @@ static int gizmo_cage2d_test_select(bContext *C, wmGizmo *gz, const int mval[2])
|
|||
}
|
||||
}
|
||||
|
||||
if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE) {
|
||||
if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_ROTATE) {
|
||||
/* Rotate:
|
||||
* (*) <-- hot spot is here!
|
||||
* +---+
|
||||
|
@ -1056,7 +1090,7 @@ static int gizmo_cage2d_modal(bContext *C,
|
|||
float pivot[2];
|
||||
bool constrain_axis[2] = {false};
|
||||
|
||||
if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE) {
|
||||
if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_TRANSLATE) {
|
||||
gizmo_rect_pivot_from_scale_part(gz->highlight_part, pivot, constrain_axis);
|
||||
}
|
||||
else {
|
||||
|
@ -1082,7 +1116,7 @@ static int gizmo_cage2d_modal(bContext *C,
|
|||
|
||||
scale[i] = 1.0f + ((delta_curr[i] - delta_orig[i]) / len_v3(data->orig_matrix_offset[i]));
|
||||
|
||||
if ((transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE_SIGNED) == 0) {
|
||||
if ((transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_SCALE_SIGNED) == 0) {
|
||||
if (sign != signum_i(scale[i])) {
|
||||
scale[i] = 0.0f;
|
||||
}
|
||||
|
@ -1090,7 +1124,7 @@ static int gizmo_cage2d_modal(bContext *C,
|
|||
}
|
||||
}
|
||||
|
||||
if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE_UNIFORM) {
|
||||
if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_SCALE_UNIFORM) {
|
||||
if (constrain_axis[0] == false && constrain_axis[1] == false) {
|
||||
scale[1] = scale[0] = (scale[1] + scale[0]) / 2.0f;
|
||||
}
|
||||
|
@ -1189,22 +1223,19 @@ static void GIZMO_GT_cage_2d(wmGizmoType *gzt)
|
|||
/* rna */
|
||||
static EnumPropertyItem rna_enum_draw_style[] = {
|
||||
{ED_GIZMO_CAGE2D_STYLE_BOX, "BOX", 0, "Box", ""},
|
||||
{ED_GIZMO_CAGE2D_STYLE_RECTANGLE, "RECTANGLE", 0, "Rectangle", ""},
|
||||
{ED_GIZMO_CAGE2D_STYLE_CIRCLE, "CIRCLE", 0, "Circle", ""},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
static EnumPropertyItem rna_enum_transform[] = {
|
||||
{ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE, "TRANSLATE", 0, "Move", ""},
|
||||
{ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE, "ROTATE", 0, "Rotate", ""},
|
||||
{ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE, "SCALE", 0, "Scale", ""},
|
||||
{ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE_UNIFORM, "SCALE_UNIFORM", 0, "Scale Uniform", ""},
|
||||
{ED_GIZMO_CAGE_XFORM_FLAG_TRANSLATE, "TRANSLATE", 0, "Move", ""},
|
||||
{ED_GIZMO_CAGE_XFORM_FLAG_ROTATE, "ROTATE", 0, "Rotate", ""},
|
||||
{ED_GIZMO_CAGE_XFORM_FLAG_SCALE, "SCALE", 0, "Scale", ""},
|
||||
{ED_GIZMO_CAGE_XFORM_FLAG_SCALE_UNIFORM, "SCALE_UNIFORM", 0, "Scale Uniform", ""},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
static EnumPropertyItem rna_enum_draw_options[] = {
|
||||
{ED_GIZMO_CAGE2D_DRAW_FLAG_XFORM_CENTER_HANDLE,
|
||||
"XFORM_CENTER_HANDLE",
|
||||
0,
|
||||
"Center Handle",
|
||||
""},
|
||||
{ED_GIZMO_CAGE_DRAW_FLAG_XFORM_CENTER_HANDLE, "XFORM_CENTER_HANDLE", 0, "Center Handle", ""},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
static float unit_v2[2] = {1.0f, 1.0f};
|
||||
|
@ -1214,13 +1245,13 @@ static void GIZMO_GT_cage_2d(wmGizmoType *gzt)
|
|||
RNA_def_enum(gzt->srna,
|
||||
"draw_style",
|
||||
rna_enum_draw_style,
|
||||
ED_GIZMO_CAGE2D_STYLE_CIRCLE,
|
||||
ED_GIZMO_CAGE2D_STYLE_RECTANGLE,
|
||||
"Draw Style",
|
||||
"");
|
||||
RNA_def_enum_flag(gzt->srna,
|
||||
"draw_options",
|
||||
rna_enum_draw_options,
|
||||
ED_GIZMO_CAGE2D_DRAW_FLAG_XFORM_CENTER_HANDLE,
|
||||
ED_GIZMO_CAGE_DRAW_FLAG_XFORM_CENTER_HANDLE,
|
||||
"Draw Options",
|
||||
"");
|
||||
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
*
|
||||
* \name Cage Gizmo
|
||||
*
|
||||
* 2D Gizmo
|
||||
* 3D Gizmo
|
||||
*
|
||||
* \brief Rectangular gizmo acting as a 'cage' around its content.
|
||||
* \brief Cuboid gizmo acting as a 'cage' around its content.
|
||||
* Interacting scales or translates the gizmo.
|
||||
*/
|
||||
|
||||
|
@ -111,7 +111,7 @@ static void gizmo_rect_pivot_from_scale_part(int part, float r_pt[3], bool r_con
|
|||
/* -------------------------------------------------------------------- */
|
||||
/** \name Box Draw Style
|
||||
*
|
||||
* Useful for 3D views, see: #ED_GIZMO_CAGE2D_STYLE_BOX
|
||||
* Useful for 3D views, see: #ED_GIZMO_CAGE3D_STYLE_BOX
|
||||
* \{ */
|
||||
|
||||
static void cage3d_draw_box_corners(const float r[3],
|
||||
|
@ -180,7 +180,7 @@ static void cage3d_draw_box_interaction(const RegionView3D *rv3d,
|
|||
/* -------------------------------------------------------------------- */
|
||||
/** \name Circle Draw Style
|
||||
*
|
||||
* Useful for 2D views, see: #ED_GIZMO_CAGE2D_STYLE_CIRCLE
|
||||
* Useful for 2D views, see: #ED_GIZMO_CAGE3D_STYLE_CIRCLE
|
||||
* \{ */
|
||||
|
||||
static void imm_draw_point_aspect_3d(uint pos, const float co[3], const float rad[3], bool solid)
|
||||
|
@ -213,8 +213,8 @@ static void cage3d_draw_circle_wire(const float r[3],
|
|||
imm_draw_cube_wire_3d(pos, (const float[3]){0}, r);
|
||||
|
||||
#if 0
|
||||
if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE) {
|
||||
if (draw_options & ED_GIZMO_CAGE2D_DRAW_FLAG_XFORM_CENTER_HANDLE) {
|
||||
if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_TRANSLATE) {
|
||||
if (draw_options & ED_GIZMO_CAGE_DRAW_FLAG_XFORM_CENTER_HANDLE) {
|
||||
const float rad[2] = {margin[0] / 2, margin[1] / 2};
|
||||
const float center[2] = {0.0f, 0.0f};
|
||||
|
||||
|
@ -316,7 +316,7 @@ static void gizmo_cage3d_draw_intern(
|
|||
const float size[3] = {UNPACK3(size_real)};
|
||||
#endif
|
||||
|
||||
if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE) {
|
||||
if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_SCALE) {
|
||||
for (int i = ED_GIZMO_CAGE3D_PART_SCALE_MIN_X_MIN_Y_MIN_Z;
|
||||
i <= ED_GIZMO_CAGE3D_PART_SCALE_MAX_X_MAX_Y_MAX_Z;
|
||||
i++) {
|
||||
|
@ -327,7 +327,7 @@ static void gizmo_cage3d_draw_intern(
|
|||
cage3d_draw_box_interaction(rv3d, matrix_final, gz->color, i, size, margin);
|
||||
}
|
||||
}
|
||||
if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE) {
|
||||
if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_TRANSLATE) {
|
||||
const int transform_part = ED_GIZMO_CAGE3D_PART_TRANSLATE;
|
||||
GPU_select_load_id(select_id | transform_part);
|
||||
cage3d_draw_box_interaction(rv3d, matrix_final, gz->color, transform_part, size, margin);
|
||||
|
@ -342,7 +342,7 @@ static void gizmo_cage3d_draw_intern(
|
|||
.ymax = size_real[1],
|
||||
};
|
||||
#endif
|
||||
if (draw_style == ED_GIZMO_CAGE2D_STYLE_BOX) {
|
||||
if (draw_style == ED_GIZMO_CAGE3D_STYLE_BOX) {
|
||||
float color[4], black[3] = {0, 0, 0};
|
||||
gizmo_color_get(gz, highlight, color);
|
||||
|
||||
|
@ -356,7 +356,7 @@ static void gizmo_cage3d_draw_intern(
|
|||
if (gz->highlight_part == ED_GIZMO_CAGE3D_PART_TRANSLATE) {
|
||||
/* Only show if we're drawing the center handle
|
||||
* otherwise the entire rectangle is the hot-spot. */
|
||||
if (draw_options & ED_GIZMO_CAGE2D_DRAW_FLAG_XFORM_CENTER_HANDLE) {
|
||||
if (draw_options & ED_GIZMO_CAGE_DRAW_FLAG_XFORM_CENTER_HANDLE) {
|
||||
show = true;
|
||||
}
|
||||
}
|
||||
|
@ -369,7 +369,7 @@ static void gizmo_cage3d_draw_intern(
|
|||
rv3d, matrix_final, gz->color, gz->highlight_part, size_real, margin);
|
||||
}
|
||||
}
|
||||
else if (draw_style == ED_GIZMO_CAGE2D_STYLE_CIRCLE) {
|
||||
else if (draw_style == ED_GIZMO_CAGE3D_STYLE_CIRCLE) {
|
||||
float color[4], black[3] = {0, 0, 0};
|
||||
gizmo_color_get(gz, highlight, color);
|
||||
|
||||
|
@ -515,7 +515,7 @@ static int gizmo_cage3d_modal(bContext *C,
|
|||
float pivot[3];
|
||||
bool constrain_axis[3] = {false};
|
||||
|
||||
if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE) {
|
||||
if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_TRANSLATE) {
|
||||
gizmo_rect_pivot_from_scale_part(gz->highlight_part, pivot, constrain_axis);
|
||||
}
|
||||
else {
|
||||
|
@ -542,7 +542,7 @@ static int gizmo_cage3d_modal(bContext *C,
|
|||
|
||||
scale[i] = 1.0f + ((delta_curr[i] - delta_orig[i]) / len_v3(data->orig_matrix_offset[i]));
|
||||
|
||||
if ((transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE_SIGNED) == 0) {
|
||||
if ((transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_SCALE_SIGNED) == 0) {
|
||||
if (sign != signum_i(scale[i])) {
|
||||
scale[i] = 0.0f;
|
||||
}
|
||||
|
@ -550,7 +550,7 @@ static int gizmo_cage3d_modal(bContext *C,
|
|||
}
|
||||
}
|
||||
|
||||
if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE_UNIFORM) {
|
||||
if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_SCALE_UNIFORM) {
|
||||
if (constrain_axis[0] == false && constrain_axis[1] == false) {
|
||||
scale[1] = scale[0] = (scale[1] + scale[0]) / 2.0f;
|
||||
}
|
||||
|
@ -647,22 +647,18 @@ static void GIZMO_GT_cage_3d(wmGizmoType *gzt)
|
|||
|
||||
/* rna */
|
||||
static EnumPropertyItem rna_enum_draw_style[] = {
|
||||
{ED_GIZMO_CAGE2D_STYLE_BOX, "BOX", 0, "Box", ""},
|
||||
{ED_GIZMO_CAGE2D_STYLE_CIRCLE, "CIRCLE", 0, "Circle", ""},
|
||||
{ED_GIZMO_CAGE3D_STYLE_BOX, "BOX", 0, "Box", ""},
|
||||
{ED_GIZMO_CAGE3D_STYLE_CIRCLE, "CIRCLE", 0, "Circle", ""},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
static EnumPropertyItem rna_enum_transform[] = {
|
||||
{ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE, "TRANSLATE", 0, "Move", ""},
|
||||
{ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE, "SCALE", 0, "Scale", ""},
|
||||
{ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE_UNIFORM, "SCALE_UNIFORM", 0, "Scale Uniform", ""},
|
||||
{ED_GIZMO_CAGE_XFORM_FLAG_TRANSLATE, "TRANSLATE", 0, "Move", ""},
|
||||
{ED_GIZMO_CAGE_XFORM_FLAG_SCALE, "SCALE", 0, "Scale", ""},
|
||||
{ED_GIZMO_CAGE_XFORM_FLAG_SCALE_UNIFORM, "SCALE_UNIFORM", 0, "Scale Uniform", ""},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
static EnumPropertyItem rna_enum_draw_options[] = {
|
||||
{ED_GIZMO_CAGE2D_DRAW_FLAG_XFORM_CENTER_HANDLE,
|
||||
"XFORM_CENTER_HANDLE",
|
||||
0,
|
||||
"Center Handle",
|
||||
""},
|
||||
{ED_GIZMO_CAGE_DRAW_FLAG_XFORM_CENTER_HANDLE, "XFORM_CENTER_HANDLE", 0, "Center Handle", ""},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
static float unit_v3[3] = {1.0f, 1.0f, 1.0f};
|
||||
|
@ -672,13 +668,13 @@ static void GIZMO_GT_cage_3d(wmGizmoType *gzt)
|
|||
RNA_def_enum(gzt->srna,
|
||||
"draw_style",
|
||||
rna_enum_draw_style,
|
||||
ED_GIZMO_CAGE2D_STYLE_CIRCLE,
|
||||
ED_GIZMO_CAGE3D_STYLE_CIRCLE,
|
||||
"Draw Style",
|
||||
"");
|
||||
RNA_def_enum_flag(gzt->srna,
|
||||
"draw_options",
|
||||
rna_enum_draw_options,
|
||||
ED_GIZMO_CAGE2D_DRAW_FLAG_XFORM_CENTER_HANDLE,
|
||||
ED_GIZMO_CAGE_DRAW_FLAG_XFORM_CENTER_HANDLE,
|
||||
"Draw Options",
|
||||
"");
|
||||
|
||||
|
|
|
@ -97,40 +97,52 @@ void ED_gizmo_arrow3d_set_range_fac(struct wmGizmo *gz, float range_fac);
|
|||
/* Cage Gizmo */
|
||||
|
||||
enum {
|
||||
ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE = (1 << 0), /* Translates */
|
||||
ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE = (1 << 1), /* Rotates */
|
||||
ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE = (1 << 2), /* Scales */
|
||||
ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE_UNIFORM = (1 << 3), /* Scales uniformly */
|
||||
ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE_SIGNED = (1 << 4), /* Negative scale allowed */
|
||||
ED_GIZMO_CAGE_XFORM_FLAG_TRANSLATE = (1 << 0), /* Translates */
|
||||
ED_GIZMO_CAGE_XFORM_FLAG_ROTATE = (1 << 1), /* Rotates */
|
||||
ED_GIZMO_CAGE_XFORM_FLAG_SCALE = (1 << 2), /* Scales */
|
||||
ED_GIZMO_CAGE_XFORM_FLAG_SCALE_UNIFORM = (1 << 3), /* Scales uniformly */
|
||||
ED_GIZMO_CAGE_XFORM_FLAG_SCALE_SIGNED = (1 << 4), /* Negative scale allowed */
|
||||
};
|
||||
|
||||
/* draw_style */
|
||||
enum {
|
||||
/** Display the hover region (edge or corner) of the underlying rectangle. */
|
||||
ED_GIZMO_CAGE2D_STYLE_BOX = 0,
|
||||
ED_GIZMO_CAGE2D_STYLE_CIRCLE = 1,
|
||||
/** Display a rectangular wire plus dots on four corners while hovering. */
|
||||
ED_GIZMO_CAGE2D_STYLE_RECTANGLE,
|
||||
/** Display a circular wire while hovering. */
|
||||
ED_GIZMO_CAGE2D_STYLE_CIRCLE,
|
||||
};
|
||||
|
||||
enum {
|
||||
ED_GIZMO_CAGE3D_STYLE_BOX = 0,
|
||||
ED_GIZMO_CAGE3D_STYLE_CIRCLE = 1,
|
||||
};
|
||||
|
||||
/* draw_options */
|
||||
enum {
|
||||
/** Draw a central handle (instead of having the entire area selectable)
|
||||
* Needed for large rectangles that we don't want to swallow all events. */
|
||||
ED_GIZMO_CAGE2D_DRAW_FLAG_XFORM_CENTER_HANDLE = (1 << 0),
|
||||
ED_GIZMO_CAGE_DRAW_FLAG_XFORM_CENTER_HANDLE = (1 << 0),
|
||||
};
|
||||
|
||||
/** #wmGizmo.highlight_part */
|
||||
enum {
|
||||
ED_GIZMO_CAGE2D_PART_TRANSLATE = 0,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MIN_X = 1,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MAX_X = 2,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MIN_Y = 3,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MAX_Y = 4,
|
||||
/* Corners */
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MIN_Y = 5,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MAX_Y = 6,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MIN_Y = 7,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MAX_Y = 8,
|
||||
|
||||
ED_GIZMO_CAGE2D_PART_ROTATE = 9,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE,
|
||||
/* Edges */
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MIN_X,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MAX_X,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MIN_Y,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MAX_Y,
|
||||
/* Corners */
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MIN_Y,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MAX_Y,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MIN_Y,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MAX_Y,
|
||||
|
||||
ED_GIZMO_CAGE2D_PART_ROTATE,
|
||||
};
|
||||
|
||||
/** #wmGizmo.highlight_part */
|
||||
|
|
|
@ -437,7 +437,13 @@ void paintvert_select_ungrouped(struct Object *ob, bool extend, bool flush_flags
|
|||
*/
|
||||
void paintvert_flush_flags(struct Object *ob);
|
||||
void paintvert_tag_select_update(struct bContext *C, struct Object *ob);
|
||||
|
||||
/* Select vertices that are connected to already selected vertices. */
|
||||
void paintvert_select_linked(struct bContext *C, struct Object *ob);
|
||||
/* Select vertices that are linked to the vertex under the given region space coordinates. */
|
||||
void paintvert_select_linked_pick(struct bContext *C,
|
||||
struct Object *ob,
|
||||
const int region_coordinates[2],
|
||||
bool select);
|
||||
void paintvert_hide(struct bContext *C, struct Object *ob, bool unselected);
|
||||
void paintvert_reveal(struct bContext *C, struct Object *ob, bool select);
|
||||
|
||||
|
|
|
@ -6,9 +6,11 @@
|
|||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_atomic_disjoint_set.hh"
|
||||
#include "BLI_bitmap.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_task.hh"
|
||||
|
||||
#include "IMB_imbuf.h"
|
||||
#include "IMB_imbuf_types.h"
|
||||
|
@ -536,6 +538,92 @@ void paintvert_flush_flags(Object *ob)
|
|||
BKE_mesh_batch_cache_dirty_tag(me, BKE_MESH_BATCH_DIRTY_ALL);
|
||||
}
|
||||
|
||||
static void paintvert_select_linked_vertices(bContext *C,
|
||||
Object *ob,
|
||||
const blender::Span<int> vertex_indices,
|
||||
const bool select)
|
||||
{
|
||||
using namespace blender;
|
||||
|
||||
Mesh *mesh = BKE_mesh_from_object(ob);
|
||||
if (mesh == nullptr || mesh->totpoly == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* AtomicDisjointSet is used to store connection information in vertex indices. */
|
||||
AtomicDisjointSet islands(mesh->totvert);
|
||||
const Span<MEdge> edges = mesh->edges();
|
||||
|
||||
/* By calling join() on the vertices of all edges, the AtomicDisjointSet contains information on
|
||||
* which parts of the mesh are connected. */
|
||||
threading::parallel_for(edges.index_range(), 1024, [&](const IndexRange range) {
|
||||
for (const MEdge &edge : edges.slice(range)) {
|
||||
islands.join(edge.v1, edge.v2);
|
||||
}
|
||||
});
|
||||
|
||||
bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
|
||||
bke::SpanAttributeWriter<bool> select_vert = attributes.lookup_or_add_for_write_span<bool>(
|
||||
".select_vert", ATTR_DOMAIN_POINT);
|
||||
|
||||
Set<int> selected_roots;
|
||||
|
||||
for (const int i : vertex_indices) {
|
||||
const int root = islands.find_root(i);
|
||||
selected_roots.add(root);
|
||||
}
|
||||
|
||||
threading::parallel_for(select_vert.span.index_range(), 1024, [&](const IndexRange range) {
|
||||
for (const int i : range) {
|
||||
const int root = islands.find_root(i);
|
||||
if (selected_roots.contains(root)) {
|
||||
select_vert.span[i] = select;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
select_vert.finish();
|
||||
|
||||
paintvert_flush_flags(ob);
|
||||
paintvert_tag_select_update(C, ob);
|
||||
}
|
||||
|
||||
void paintvert_select_linked_pick(bContext *C,
|
||||
Object *ob,
|
||||
const int region_coordinates[2],
|
||||
const bool select)
|
||||
{
|
||||
uint index = uint(-1);
|
||||
if (!ED_mesh_pick_vert(
|
||||
C, ob, region_coordinates, ED_MESH_PICK_DEFAULT_VERT_DIST, true, &index)) {
|
||||
return;
|
||||
}
|
||||
|
||||
paintvert_select_linked_vertices(C, ob, {int(index)}, select);
|
||||
}
|
||||
|
||||
void paintvert_select_linked(bContext *C, Object *ob)
|
||||
{
|
||||
Mesh *mesh = BKE_mesh_from_object(ob);
|
||||
if (mesh == nullptr || mesh->totpoly == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
blender::bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
|
||||
blender::bke::SpanAttributeWriter<bool> select_vert =
|
||||
attributes.lookup_or_add_for_write_span<bool>(".select_vert", ATTR_DOMAIN_POINT);
|
||||
|
||||
blender::Vector<int> indices;
|
||||
for (const int i : select_vert.span.index_range()) {
|
||||
if (!select_vert.span[i]) {
|
||||
continue;
|
||||
}
|
||||
indices.append(i);
|
||||
}
|
||||
select_vert.finish();
|
||||
paintvert_select_linked_vertices(C, ob, indices, true);
|
||||
}
|
||||
|
||||
void paintvert_tag_select_update(bContext *C, Object *ob)
|
||||
{
|
||||
DEG_id_tag_update(static_cast<ID *>(ob->data), ID_RECALC_COPY_ON_WRITE | ID_RECALC_SELECT);
|
||||
|
|
|
@ -245,8 +245,8 @@ static void gizmo_mesh_placement_setup(const bContext *C, wmGizmoGroup *gzgroup)
|
|||
|
||||
RNA_enum_set(ggd->cage->ptr,
|
||||
"transform",
|
||||
ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE | ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE |
|
||||
ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE_SIGNED);
|
||||
ED_GIZMO_CAGE_XFORM_FLAG_SCALE | ED_GIZMO_CAGE_XFORM_FLAG_TRANSLATE |
|
||||
ED_GIZMO_CAGE_XFORM_FLAG_SCALE_SIGNED);
|
||||
|
||||
WM_gizmo_set_flag(ggd->cage, WM_GIZMO_DRAW_VALUE, true);
|
||||
|
||||
|
|
|
@ -2048,7 +2048,7 @@ static int object_curves_random_add_exec(bContext *C, wmOperator *op)
|
|||
Object *object = ED_object_add_type(C, OB_CURVES, nullptr, loc, rot, false, local_view_bits);
|
||||
|
||||
Curves *curves_id = static_cast<Curves *>(object->data);
|
||||
bke::CurvesGeometry::wrap(curves_id->geometry) = ed::curves::primitive_random_sphere(500, 8);
|
||||
curves_id->geometry.wrap() = ed::curves::primitive_random_sphere(500, 8);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
@ -3091,8 +3091,7 @@ static int object_convert_exec(bContext *C, wmOperator *op)
|
|||
newob->data = new_curves;
|
||||
newob->type = OB_CURVES;
|
||||
|
||||
blender::bke::CurvesGeometry::wrap(
|
||||
new_curves->geometry) = blender::bke::CurvesGeometry::wrap(curves_eval->geometry);
|
||||
new_curves->geometry.wrap() = curves_eval->geometry.wrap();
|
||||
BKE_object_material_from_eval_data(bmain, newob, &curves_eval->id);
|
||||
|
||||
BKE_object_free_derived_caches(newob);
|
||||
|
@ -3392,8 +3391,7 @@ static int object_convert_exec(bContext *C, wmOperator *op)
|
|||
else if (const Curves *curves_eval = geometry.get_curves_for_read()) {
|
||||
bke::AnonymousAttributePropagationInfo propagation_info;
|
||||
propagation_info.propagate_all = false;
|
||||
Mesh *mesh = bke::curve_to_wire_mesh(bke::CurvesGeometry::wrap(curves_eval->geometry),
|
||||
propagation_info);
|
||||
Mesh *mesh = bke::curve_to_wire_mesh(curves_eval->geometry.wrap(), propagation_info);
|
||||
BKE_mesh_nomain_to_mesh(mesh, new_mesh, newob);
|
||||
BKE_object_material_from_eval_data(bmain, newob, &curves_eval->id);
|
||||
}
|
||||
|
|
|
@ -1075,13 +1075,10 @@ static bool modifier_apply_obdata(
|
|||
Curves &curves_eval = *geometry_set.get_curves_for_write();
|
||||
|
||||
/* Anonymous attributes shouldn't be available on the applied geometry. */
|
||||
blender::bke::CurvesGeometry::wrap(curves_eval.geometry)
|
||||
.attributes_for_write()
|
||||
.remove_anonymous();
|
||||
curves_eval.geometry.wrap().attributes_for_write().remove_anonymous();
|
||||
|
||||
/* Copy the relevant information to the original. */
|
||||
blender::bke::CurvesGeometry::wrap(curves.geometry) = std::move(
|
||||
blender::bke::CurvesGeometry::wrap(curves_eval.geometry));
|
||||
curves.geometry.wrap() = std::move(curves_eval.geometry.wrap());
|
||||
Main *bmain = DEG_get_bmain(depsgraph);
|
||||
BKE_object_material_from_eval_data(bmain, ob, &curves_eval.id);
|
||||
}
|
||||
|
|
|
@ -944,8 +944,8 @@ static int apply_objects_internal(bContext *C,
|
|||
}
|
||||
else if (ob->type == OB_CURVES) {
|
||||
Curves &curves = *static_cast<Curves *>(ob->data);
|
||||
blender::bke::CurvesGeometry::wrap(curves.geometry).transform(mat);
|
||||
blender::bke::CurvesGeometry::wrap(curves.geometry).calculate_bezier_auto_handles();
|
||||
curves.geometry.wrap().transform(mat);
|
||||
curves.geometry.wrap().calculate_bezier_auto_handles();
|
||||
}
|
||||
else if (ob->type == OB_POINTCLOUD) {
|
||||
PointCloud &pointcloud = *static_cast<PointCloud *>(ob->data);
|
||||
|
@ -1674,7 +1674,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
|
|||
else if (ob->type == OB_CURVES) {
|
||||
using namespace blender;
|
||||
Curves &curves_id = *static_cast<Curves *>(ob->data);
|
||||
bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry);
|
||||
bke::CurvesGeometry &curves = curves_id.geometry.wrap();
|
||||
if (ELEM(centermode, ORIGIN_TO_CENTER_OF_MASS_SURFACE, ORIGIN_TO_CENTER_OF_MASS_VOLUME) ||
|
||||
!ELEM(around, V3D_AROUND_CENTER_BOUNDS, V3D_AROUND_CENTER_MEDIAN)) {
|
||||
BKE_report(
|
||||
|
|
|
@ -117,7 +117,7 @@ struct AddOperationExecutor {
|
|||
curves_ob_orig_ = CTX_data_active_object(&C);
|
||||
|
||||
curves_id_orig_ = static_cast<Curves *>(curves_ob_orig_->data);
|
||||
curves_orig_ = &CurvesGeometry::wrap(curves_id_orig_->geometry);
|
||||
curves_orig_ = &curves_id_orig_->geometry.wrap();
|
||||
|
||||
if (curves_id_orig_->surface == nullptr || curves_id_orig_->surface->type != OB_MESH) {
|
||||
report_missing_surface(stroke_extension.reports);
|
||||
|
|
|
@ -177,7 +177,7 @@ std::optional<CurvesBrush3D> sample_curves_3d_brush(const Depsgraph &depsgraph,
|
|||
const float brush_radius_re)
|
||||
{
|
||||
const Curves &curves_id = *static_cast<Curves *>(curves_object.data);
|
||||
const CurvesGeometry &curves = CurvesGeometry::wrap(curves_id.geometry);
|
||||
const CurvesGeometry &curves = curves_id.geometry.wrap();
|
||||
Object *surface_object = curves_id.surface;
|
||||
Object *surface_object_eval = DEG_get_evaluated_object(&depsgraph, surface_object);
|
||||
|
||||
|
|
|
@ -117,7 +117,7 @@ struct CombOperationExecutor {
|
|||
|
||||
curves_ob_orig_ = CTX_data_active_object(&C);
|
||||
curves_id_orig_ = static_cast<Curves *>(curves_ob_orig_->data);
|
||||
curves_orig_ = &CurvesGeometry::wrap(curves_id_orig_->geometry);
|
||||
curves_orig_ = &curves_id_orig_->geometry.wrap();
|
||||
if (curves_orig_->curves_num() == 0) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ struct DeleteOperationExecutor {
|
|||
object_ = CTX_data_active_object(&C);
|
||||
|
||||
curves_id_ = static_cast<Curves *>(object_->data);
|
||||
curves_ = &CurvesGeometry::wrap(curves_id_->geometry);
|
||||
curves_ = &curves_id_->geometry.wrap();
|
||||
|
||||
selected_curve_indices_.clear();
|
||||
curve_selection_ = curves::retrieve_selected_curves(*curves_id_, selected_curve_indices_);
|
||||
|
|
|
@ -102,7 +102,7 @@ struct DensityAddOperationExecutor {
|
|||
self_ = &self;
|
||||
curves_ob_orig_ = CTX_data_active_object(&C);
|
||||
curves_id_orig_ = static_cast<Curves *>(curves_ob_orig_->data);
|
||||
curves_orig_ = &CurvesGeometry::wrap(curves_id_orig_->geometry);
|
||||
curves_orig_ = &curves_id_orig_->geometry.wrap();
|
||||
|
||||
if (stroke_extension.is_first) {
|
||||
self_->original_curve_num_ = curves_orig_->curves_num();
|
||||
|
@ -540,7 +540,7 @@ struct DensitySubtractOperationExecutor {
|
|||
object_ = CTX_data_active_object(&C);
|
||||
|
||||
curves_id_ = static_cast<Curves *>(object_->data);
|
||||
curves_ = &CurvesGeometry::wrap(curves_id_->geometry);
|
||||
curves_ = &curves_id_->geometry.wrap();
|
||||
if (curves_->curves_num() == 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -834,7 +834,7 @@ static bool use_add_density_mode(const BrushStrokeMode brush_mode,
|
|||
if (surface_ob_eval == nullptr) {
|
||||
return true;
|
||||
}
|
||||
const CurvesGeometry &curves = CurvesGeometry::wrap(curves_id_orig.geometry);
|
||||
const CurvesGeometry &curves = curves_id_orig.geometry.wrap();
|
||||
if (curves.curves_num() <= 1) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -278,7 +278,7 @@ struct CurvesEffectOperationExecutor {
|
|||
object_ = CTX_data_active_object(&C);
|
||||
|
||||
curves_id_ = static_cast<Curves *>(object_->data);
|
||||
curves_ = &CurvesGeometry::wrap(curves_id_->geometry);
|
||||
curves_ = &curves_id_->geometry.wrap();
|
||||
if (curves_->curves_num() == 0) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -362,7 +362,7 @@ static int select_random_exec(bContext *C, wmOperator *op)
|
|||
const auto next_bool_random_value = [&]() { return rng.get_float() <= probability; };
|
||||
|
||||
for (Curves *curves_id : unique_curves) {
|
||||
CurvesGeometry &curves = CurvesGeometry::wrap(curves_id->geometry);
|
||||
CurvesGeometry &curves = curves_id->geometry.wrap();
|
||||
const bool was_anything_selected = curves::has_anything_selected(curves);
|
||||
|
||||
bke::SpanAttributeWriter<float> attribute = float_selection_ensure(*curves_id);
|
||||
|
@ -581,7 +581,7 @@ static int select_grow_update(bContext *C, wmOperator *op, const float mouse_dif
|
|||
|
||||
for (std::unique_ptr<GrowOperatorDataPerCurve> &curve_op_data : op_data.per_curve) {
|
||||
Curves &curves_id = *curve_op_data->curves_id;
|
||||
CurvesGeometry &curves = CurvesGeometry::wrap(curves_id.geometry);
|
||||
CurvesGeometry &curves = curves_id.geometry.wrap();
|
||||
const float distance = curve_op_data->pixel_to_distance_factor * mouse_diff_x;
|
||||
|
||||
bke::SpanAttributeWriter<float> selection = float_selection_ensure(curves_id);
|
||||
|
@ -629,7 +629,7 @@ static void select_grow_invoke_per_curve(const Curves &curves_id,
|
|||
const RegionView3D &rv3d,
|
||||
GrowOperatorDataPerCurve &curve_op_data)
|
||||
{
|
||||
const CurvesGeometry &curves = CurvesGeometry::wrap(curves_id.geometry);
|
||||
const CurvesGeometry &curves = curves_id.geometry.wrap();
|
||||
const Span<float3> positions = curves.positions();
|
||||
|
||||
if (const bke::GAttributeReader original_selection = curves.attributes().lookup(".selection")) {
|
||||
|
@ -773,7 +773,7 @@ static int select_grow_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
|||
/* Undo operator by resetting the selection to the original value. */
|
||||
for (std::unique_ptr<GrowOperatorDataPerCurve> &curve_op_data : op_data.per_curve) {
|
||||
Curves &curves_id = *curve_op_data->curves_id;
|
||||
CurvesGeometry &curves = CurvesGeometry::wrap(curves_id.geometry);
|
||||
CurvesGeometry &curves = curves_id.geometry.wrap();
|
||||
bke::MutableAttributeAccessor attributes = curves.attributes_for_write();
|
||||
|
||||
attributes.remove(".selection");
|
||||
|
|
|
@ -90,7 +90,7 @@ struct PinchOperationExecutor {
|
|||
|
||||
object_ = CTX_data_active_object(&C);
|
||||
curves_id_ = static_cast<Curves *>(object_->data);
|
||||
curves_ = &CurvesGeometry::wrap(curves_id_->geometry);
|
||||
curves_ = &curves_id_->geometry.wrap();
|
||||
if (curves_->curves_num() == 0) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ struct PuffOperationExecutor {
|
|||
|
||||
object_ = CTX_data_active_object(&C);
|
||||
curves_id_ = static_cast<Curves *>(object_->data);
|
||||
curves_ = &CurvesGeometry::wrap(curves_id_->geometry);
|
||||
curves_ = &curves_id_->geometry.wrap();
|
||||
if (curves_->curves_num() == 0) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace blender::ed::sculpt_paint {
|
|||
bke::SpanAttributeWriter<float> float_selection_ensure(Curves &curves_id)
|
||||
{
|
||||
/* TODO: Use a generic attribute conversion utility instead of this function. */
|
||||
bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry);
|
||||
bke::CurvesGeometry &curves = curves_id.geometry.wrap();
|
||||
bke::MutableAttributeAccessor attributes = curves.attributes_for_write();
|
||||
|
||||
if (const auto meta_data = attributes.lookup_meta_data(".selection")) {
|
||||
|
|
|
@ -83,7 +83,7 @@ struct SelectionPaintOperationExecutor {
|
|||
object_ = CTX_data_active_object(&C);
|
||||
|
||||
curves_id_ = static_cast<Curves *>(object_->data);
|
||||
curves_ = &CurvesGeometry::wrap(curves_id_->geometry);
|
||||
curves_ = &curves_id_->geometry.wrap();
|
||||
if (curves_->curves_num() == 0) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -131,7 +131,7 @@ struct SlideOperationExecutor {
|
|||
|
||||
curves_ob_orig_ = CTX_data_active_object(&C);
|
||||
curves_id_orig_ = static_cast<Curves *>(curves_ob_orig_->data);
|
||||
curves_orig_ = &CurvesGeometry::wrap(curves_id_orig_->geometry);
|
||||
curves_orig_ = &curves_id_orig_->geometry.wrap();
|
||||
if (curves_id_orig_->surface == nullptr || curves_id_orig_->surface->type != OB_MESH) {
|
||||
report_missing_surface(stroke_extension.reports);
|
||||
return;
|
||||
|
|
|
@ -66,7 +66,7 @@ struct SmoothOperationExecutor {
|
|||
|
||||
object_ = CTX_data_active_object(&C);
|
||||
curves_id_ = static_cast<Curves *>(object_->data);
|
||||
curves_ = &CurvesGeometry::wrap(curves_id_->geometry);
|
||||
curves_ = &curves_id_->geometry.wrap();
|
||||
if (curves_->curves_num() == 0) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@ struct SnakeHookOperatorExecutor {
|
|||
falloff_shape_ = static_cast<eBrushFalloffShape>(brush_->falloff_shape);
|
||||
|
||||
curves_id_ = static_cast<Curves *>(object_->data);
|
||||
curves_ = &CurvesGeometry::wrap(curves_id_->geometry);
|
||||
curves_ = &curves_id_->geometry.wrap();
|
||||
if (curves_->curves_num() == 0) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -383,6 +383,8 @@ void PAINT_OT_face_vert_reveal(struct wmOperatorType *ot);
|
|||
void PAINT_OT_vert_select_all(struct wmOperatorType *ot);
|
||||
void PAINT_OT_vert_select_ungrouped(struct wmOperatorType *ot);
|
||||
void PAINT_OT_vert_select_hide(struct wmOperatorType *ot);
|
||||
void PAINT_OT_vert_select_linked(struct wmOperatorType *ot);
|
||||
void PAINT_OT_vert_select_linked_pick(struct wmOperatorType *ot);
|
||||
|
||||
bool vert_paint_poll(struct bContext *C);
|
||||
bool mask_paint_poll(struct bContext *C);
|
||||
|
|
|
@ -1457,6 +1457,8 @@ void ED_operatortypes_paint(void)
|
|||
WM_operatortype_append(PAINT_OT_vert_select_all);
|
||||
WM_operatortype_append(PAINT_OT_vert_select_ungrouped);
|
||||
WM_operatortype_append(PAINT_OT_vert_select_hide);
|
||||
WM_operatortype_append(PAINT_OT_vert_select_linked);
|
||||
WM_operatortype_append(PAINT_OT_vert_select_linked_pick);
|
||||
|
||||
/* vertex */
|
||||
WM_operatortype_append(PAINT_OT_vertex_paint_toggle);
|
||||
|
|
|
@ -733,6 +733,53 @@ void PAINT_OT_vert_select_ungrouped(wmOperatorType *ot)
|
|||
RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
|
||||
}
|
||||
|
||||
static int paintvert_select_linked_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
paintvert_select_linked(C, CTX_data_active_object(C));
|
||||
ED_region_tag_redraw(CTX_wm_region(C));
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void PAINT_OT_vert_select_linked(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Select Linked Vertices";
|
||||
ot->description = "Select linked vertices";
|
||||
ot->idname = "PAINT_OT_vert_select_linked";
|
||||
|
||||
ot->exec = paintvert_select_linked_exec;
|
||||
ot->poll = vert_paint_poll;
|
||||
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
static int paintvert_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
const bool select = RNA_boolean_get(op->ptr, "select");
|
||||
view3d_operator_needs_opengl(C);
|
||||
|
||||
paintvert_select_linked_pick(C, CTX_data_active_object(C), event->mval, select);
|
||||
ED_region_tag_redraw(CTX_wm_region(C));
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void PAINT_OT_vert_select_linked_pick(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Select Linked Vertices Pick";
|
||||
ot->description = "Select linked vertices under the cursor";
|
||||
ot->idname = "PAINT_OT_vert_select_linked_pick";
|
||||
|
||||
ot->invoke = paintvert_select_linked_pick_invoke;
|
||||
ot->poll = vert_paint_poll;
|
||||
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
RNA_def_boolean(ot->srna,
|
||||
"select",
|
||||
true,
|
||||
"Select",
|
||||
"Whether to select or deselect linked vertices under the cursor");
|
||||
}
|
||||
|
||||
static int face_select_hide_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
const bool unselected = RNA_boolean_get(op->ptr, "unselected");
|
||||
|
|
|
@ -517,11 +517,12 @@ static bool mask_expand_normal_floodfill_cb(
|
|||
static float *sculpt_expand_normal_falloff_create(Sculpt *sd,
|
||||
Object *ob,
|
||||
const PBVHVertRef v,
|
||||
const float edge_sensitivity)
|
||||
const float edge_sensitivity,
|
||||
const int blur_steps)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
const int totvert = SCULPT_vertex_count_get(ss);
|
||||
float *dists = static_cast<float *>(MEM_malloc_arrayN(totvert, sizeof(float), __func__));
|
||||
float *dists = static_cast<float *>(MEM_calloc_arrayN(totvert, sizeof(float), __func__));
|
||||
float *edge_factor = static_cast<float *>(MEM_callocN(sizeof(float) * totvert, __func__));
|
||||
for (int i = 0; i < totvert; i++) {
|
||||
edge_factor[i] = 1.0f;
|
||||
|
@ -540,7 +541,7 @@ static float *sculpt_expand_normal_falloff_create(Sculpt *sd,
|
|||
SCULPT_floodfill_execute(ss, &flood, mask_expand_normal_floodfill_cb, &fdata);
|
||||
SCULPT_floodfill_free(&flood);
|
||||
|
||||
for (int repeat = 0; repeat < 2; repeat++) {
|
||||
for (int repeat = 0; repeat < blur_steps; repeat++) {
|
||||
for (int i = 0; i < totvert; i++) {
|
||||
PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
|
||||
|
||||
|
@ -550,10 +551,17 @@ static float *sculpt_expand_normal_falloff_create(Sculpt *sd,
|
|||
avg += dists[ni.index];
|
||||
}
|
||||
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
|
||||
dists[i] = avg / ni.size;
|
||||
|
||||
if (ni.size > 0.0f) {
|
||||
dists[i] = avg / ni.size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < totvert; i++) {
|
||||
dists[i] = 1.0 - dists[i];
|
||||
}
|
||||
|
||||
MEM_SAFE_FREE(edge_factor);
|
||||
|
||||
return dists;
|
||||
|
@ -1049,7 +1057,11 @@ static void sculpt_expand_falloff_factors_from_vertex_and_symm_create(
|
|||
break;
|
||||
case SCULPT_EXPAND_FALLOFF_NORMALS:
|
||||
expand_cache->vert_falloff = sculpt_expand_normal_falloff_create(
|
||||
sd, ob, v, SCULPT_EXPAND_NORMALS_FALLOFF_EDGE_SENSITIVITY);
|
||||
sd,
|
||||
ob,
|
||||
v,
|
||||
SCULPT_EXPAND_NORMALS_FALLOFF_EDGE_SENSITIVITY,
|
||||
expand_cache->normal_falloff_blur_steps);
|
||||
break;
|
||||
case SCULPT_EXPAND_FALLOFF_SPHERICAL:
|
||||
expand_cache->vert_falloff = sculpt_expand_spherical_falloff_create(ob, v);
|
||||
|
@ -2066,6 +2078,7 @@ static void sculpt_expand_cache_initial_config_set(bContext *C,
|
|||
ExpandCache *expand_cache)
|
||||
{
|
||||
/* RNA properties. */
|
||||
expand_cache->normal_falloff_blur_steps = RNA_int_get(op->ptr, "normal_falloff_smooth");
|
||||
expand_cache->invert = RNA_boolean_get(op->ptr, "invert");
|
||||
expand_cache->preserve = RNA_boolean_get(op->ptr, "use_mask_preserve");
|
||||
expand_cache->auto_mask = RNA_boolean_get(op->ptr, "use_auto_mask");
|
||||
|
@ -2415,4 +2428,13 @@ void SCULPT_OT_expand(wmOperatorType *ot)
|
|||
false,
|
||||
"Auto Create",
|
||||
"Fill in mask if nothing is already masked");
|
||||
ot->prop = RNA_def_int(ot->srna,
|
||||
"normal_falloff_smooth",
|
||||
2,
|
||||
0,
|
||||
10,
|
||||
"Normal Smooth",
|
||||
"Blurring steps for normal falloff",
|
||||
0,
|
||||
10);
|
||||
}
|
||||
|
|
|
@ -1303,8 +1303,8 @@ static bool sculpt_face_set_edit_is_operation_valid(SculptSession *ss,
|
|||
|
||||
if (mode == SCULPT_FACE_SET_EDIT_DELETE_GEOMETRY) {
|
||||
if (BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS) {
|
||||
/* Modification of base mesh geometry requires special remapping of multires displacement,
|
||||
* which does not happen here.
|
||||
/* Modification of base mesh geometry requires special remapping of multi-resolution
|
||||
* displacement, which does not happen here.
|
||||
* Disable delete operation. It can be supported in the future by doing similar displacement
|
||||
* data remapping as what happens in the mesh edit mode. */
|
||||
return false;
|
||||
|
@ -1318,9 +1318,9 @@ static bool sculpt_face_set_edit_is_operation_valid(SculptSession *ss,
|
|||
|
||||
if (ELEM(mode, SCULPT_FACE_SET_EDIT_FAIR_POSITIONS, SCULPT_FACE_SET_EDIT_FAIR_TANGENCY)) {
|
||||
if (BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS) {
|
||||
/* TODO: Multires topology representation using grids and duplicates can't be used directly
|
||||
* by the fair algorithm. Multires topology needs to be exposed in a different way or
|
||||
* converted to a mesh for this operation. */
|
||||
/* TODO: Multi-resolution topology representation using grids and duplicates can't be used
|
||||
* directly by the fair algorithm. Multi-resolution topology needs to be exposed in a
|
||||
* different way or converted to a mesh for this operation. */
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -822,6 +822,7 @@ typedef struct ExpandCache {
|
|||
float (*original_colors)[4];
|
||||
|
||||
bool check_islands;
|
||||
int normal_falloff_blur_steps;
|
||||
} ExpandCache;
|
||||
/** \} */
|
||||
|
||||
|
|
|
@ -2984,7 +2984,7 @@ static int filelist_readjob_list_dir(FileListReadJob *job_params,
|
|||
entry->relpath = current_relpath_append(job_params, files[i].relname);
|
||||
entry->st = files[i].s;
|
||||
|
||||
BLI_path_join(full_path, FILE_MAX, root, entry->relpath);
|
||||
BLI_path_join(full_path, FILE_MAX, root, files[i].relname);
|
||||
char *target = full_path;
|
||||
|
||||
/* Set initial file type and attributes. */
|
||||
|
|
|
@ -389,10 +389,7 @@ static bool draw_fcurve_handles_check(SpaceGraph *sipo, FCurve *fcu)
|
|||
(fcu->flag & FCURVE_INT_VALUES) ||
|
||||
#endif
|
||||
/* group that curve belongs to is not editable */
|
||||
((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) ||
|
||||
/* Do not show handles if there is only 1 keyframe,
|
||||
* otherwise they all clump together in an ugly ball. */
|
||||
(fcu->totvert <= 1)) {
|
||||
((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -707,7 +704,7 @@ static void draw_fcurve_curve_samples(bAnimContext *ac,
|
|||
const uint shdr_pos,
|
||||
const bool draw_extrapolation)
|
||||
{
|
||||
if (!draw_extrapolation && fcu->totvert == 1) {
|
||||
if (!draw_extrapolation) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -820,7 +817,7 @@ static bool fcurve_can_use_simple_bezt_drawing(FCurve *fcu)
|
|||
static void draw_fcurve_curve_bezts(
|
||||
bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d, uint pos, const bool draw_extrapolation)
|
||||
{
|
||||
if (!draw_extrapolation && fcu->totvert == 1) {
|
||||
if (!draw_extrapolation) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -852,7 +849,7 @@ static void draw_fcurve_curve_bezts(
|
|||
|
||||
/* y-value depends on the interpolation */
|
||||
if ((fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT) || (prevbezt->ipo == BEZT_IPO_CONST) ||
|
||||
(fcu->totvert == 1)) {
|
||||
(prevbezt->ipo == BEZT_IPO_LIN && fcu->totvert == 1)) {
|
||||
/* just extend across the first keyframe's value */
|
||||
v1[1] = prevbezt->vec[1][1];
|
||||
}
|
||||
|
@ -971,7 +968,8 @@ static void draw_fcurve_curve_bezts(
|
|||
|
||||
/* y-value depends on the interpolation */
|
||||
if ((fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT) || (fcu->flag & FCURVE_INT_VALUES) ||
|
||||
(prevbezt->ipo == BEZT_IPO_CONST) || (fcu->totvert == 1)) {
|
||||
(prevbezt->ipo == BEZT_IPO_CONST) ||
|
||||
(prevbezt->ipo == BEZT_IPO_LIN && fcu->totvert == 1)) {
|
||||
/* based on last keyframe's value */
|
||||
v1[1] = prevbezt->vec[1][1];
|
||||
}
|
||||
|
|
|
@ -210,8 +210,8 @@ static void get_nearest_fcurve_verts_list(bAnimContext *ac, const int mval[2], L
|
|||
unit_scale,
|
||||
offset);
|
||||
|
||||
/* handles - only do them if they're visible */
|
||||
if (fcurve_handle_sel_check(sipo, bezt1) && (fcu->totvert > 1)) {
|
||||
/* Handles. */
|
||||
if (fcurve_handle_sel_check(sipo, bezt1)) {
|
||||
/* first handle only visible if previous segment had handles */
|
||||
if ((!prevbezt && (bezt1->ipo == BEZT_IPO_BEZ)) ||
|
||||
(prevbezt && (prevbezt->ipo == BEZT_IPO_BEZ))) {
|
||||
|
|
|
@ -117,7 +117,7 @@ static void WIDGETGROUP_node_transform_setup(const bContext * /*C*/, wmGizmoGrou
|
|||
|
||||
RNA_enum_set(wwrapper->gizmo->ptr,
|
||||
"transform",
|
||||
ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE | ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE_UNIFORM);
|
||||
ED_GIZMO_CAGE_XFORM_FLAG_TRANSLATE | ED_GIZMO_CAGE_XFORM_FLAG_SCALE_UNIFORM);
|
||||
|
||||
gzgroup->customdata = wwrapper;
|
||||
}
|
||||
|
@ -323,7 +323,7 @@ static void WIDGETGROUP_node_crop_setup(const bContext * /*C*/, wmGizmoGroup *gz
|
|||
|
||||
RNA_enum_set(crop_group->border->ptr,
|
||||
"transform",
|
||||
ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE | ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE);
|
||||
ED_GIZMO_CAGE_XFORM_FLAG_TRANSLATE | ED_GIZMO_CAGE_XFORM_FLAG_SCALE);
|
||||
|
||||
gzgroup->customdata = crop_group;
|
||||
}
|
||||
|
|
|
@ -3594,7 +3594,7 @@ static int sequencer_scene_frame_range_update_exec(bContext *C, wmOperator *UNUS
|
|||
static bool sequencer_scene_frame_range_update_poll(bContext *C)
|
||||
{
|
||||
Editing *ed = SEQ_editing_get(CTX_data_scene(C));
|
||||
return (ed->act_seq != NULL && (ed->act_seq->type & SEQ_TYPE_SCENE) != 0);
|
||||
return (ed != NULL && ed->act_seq != NULL && (ed->act_seq->type & SEQ_TYPE_SCENE) != 0);
|
||||
}
|
||||
|
||||
void SEQUENCER_OT_scene_frame_range_update(wmOperatorType *ot)
|
||||
|
|
|
@ -413,7 +413,7 @@ static void WIDGETGROUP_camera_view_setup(const bContext *UNUSED(C), wmGizmoGrou
|
|||
|
||||
RNA_enum_set(viewgroup->border->ptr,
|
||||
"transform",
|
||||
ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE | ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE);
|
||||
ED_GIZMO_CAGE_XFORM_FLAG_TRANSLATE | ED_GIZMO_CAGE_XFORM_FLAG_SCALE);
|
||||
/* Box style is more subtle in this case. */
|
||||
RNA_enum_set(viewgroup->border->ptr, "draw_style", ED_GIZMO_CAGE2D_STYLE_BOX);
|
||||
|
||||
|
@ -470,7 +470,7 @@ static void WIDGETGROUP_camera_view_refresh(const bContext *C, wmGizmoGroup *gzg
|
|||
|
||||
RNA_enum_set(viewgroup->border->ptr,
|
||||
"transform",
|
||||
ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE | ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE);
|
||||
ED_GIZMO_CAGE_XFORM_FLAG_TRANSLATE | ED_GIZMO_CAGE_XFORM_FLAG_SCALE);
|
||||
|
||||
if (rv3d->persp == RV3D_CAMOB) {
|
||||
viewgroup->state.edit_border = &scene->r.border;
|
||||
|
|
|
@ -120,7 +120,7 @@ static void WIDGETGROUP_empty_image_setup(const bContext *UNUSED(C), wmGizmoGrou
|
|||
__func__);
|
||||
igzgroup->gizmo = WM_gizmo_new("GIZMO_GT_cage_2d", gzgroup, NULL);
|
||||
wmGizmo *gz = igzgroup->gizmo;
|
||||
RNA_enum_set(gz->ptr, "transform", ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE);
|
||||
RNA_enum_set(gz->ptr, "transform", ED_GIZMO_CAGE_XFORM_FLAG_SCALE);
|
||||
|
||||
gzgroup->customdata = igzgroup;
|
||||
|
||||
|
@ -143,8 +143,8 @@ static void WIDGETGROUP_empty_image_refresh(const bContext *C, wmGizmoGroup *gzg
|
|||
|
||||
RNA_enum_set(gz->ptr,
|
||||
"transform",
|
||||
ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE | ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE |
|
||||
ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE_UNIFORM);
|
||||
ED_GIZMO_CAGE_XFORM_FLAG_TRANSLATE | ED_GIZMO_CAGE_XFORM_FLAG_SCALE |
|
||||
ED_GIZMO_CAGE_XFORM_FLAG_SCALE_UNIFORM);
|
||||
|
||||
igzgroup->state.ob = ob;
|
||||
|
||||
|
|
|
@ -179,7 +179,7 @@ static void WIDGETGROUP_light_area_setup(const bContext *UNUSED(C), wmGizmoGroup
|
|||
wmGizmoWrapper *wwrapper = MEM_mallocN(sizeof(wmGizmoWrapper), __func__);
|
||||
wwrapper->gizmo = WM_gizmo_new("GIZMO_GT_cage_2d", gzgroup, NULL);
|
||||
wmGizmo *gz = wwrapper->gizmo;
|
||||
RNA_enum_set(gz->ptr, "transform", ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE);
|
||||
RNA_enum_set(gz->ptr, "transform", ED_GIZMO_CAGE_XFORM_FLAG_SCALE);
|
||||
|
||||
gzgroup->customdata = wwrapper;
|
||||
|
||||
|
@ -201,9 +201,9 @@ static void WIDGETGROUP_light_area_refresh(const bContext *C, wmGizmoGroup *gzgr
|
|||
|
||||
copy_m4_m4(gz->matrix_basis, ob->object_to_world);
|
||||
|
||||
int flag = ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE;
|
||||
int flag = ED_GIZMO_CAGE_XFORM_FLAG_SCALE;
|
||||
if (ELEM(la->area_shape, LA_AREA_SQUARE, LA_AREA_DISK)) {
|
||||
flag |= ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE_UNIFORM;
|
||||
flag |= ED_GIZMO_CAGE_XFORM_FLAG_SCALE_UNIFORM;
|
||||
}
|
||||
RNA_enum_set(gz->ptr, "transform", flag);
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ static void createTransCurvesVerts(bContext * /*C*/, TransInfo *t)
|
|||
for (const int i : trans_data_contrainers.index_range()) {
|
||||
TransDataContainer &tc = trans_data_contrainers[i];
|
||||
Curves *curves_id = static_cast<Curves *>(tc.obedit->data);
|
||||
bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id->geometry);
|
||||
bke::CurvesGeometry &curves = curves_id->geometry.wrap();
|
||||
|
||||
selection_per_object[i] = ed::curves::retrieve_selected_points(curves,
|
||||
selected_indices_per_object[i]);
|
||||
|
@ -51,7 +51,7 @@ static void createTransCurvesVerts(bContext * /*C*/, TransInfo *t)
|
|||
continue;
|
||||
}
|
||||
Curves *curves_id = static_cast<Curves *>(tc.obedit->data);
|
||||
bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id->geometry);
|
||||
bke::CurvesGeometry &curves = curves_id->geometry.wrap();
|
||||
IndexMask selected_indices = selection_per_object[i];
|
||||
|
||||
float mtx[3][3], smtx[3][3];
|
||||
|
@ -82,7 +82,7 @@ static void recalcData_curves(TransInfo *t)
|
|||
Span<TransDataContainer> trans_data_contrainers(t->data_container, t->data_container_len);
|
||||
for (const TransDataContainer &tc : trans_data_contrainers) {
|
||||
Curves *curves_id = static_cast<Curves *>(tc.obedit->data);
|
||||
bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id->geometry);
|
||||
bke::CurvesGeometry &curves = curves_id->geometry.wrap();
|
||||
|
||||
curves.calculate_bezier_auto_handles();
|
||||
curves.tag_positions_changed();
|
||||
|
|
|
@ -210,8 +210,8 @@ static GizmoGroup2D *gizmogroup2d_init(wmGizmoGroup *gzgroup)
|
|||
|
||||
RNA_enum_set(ggd->cage->ptr,
|
||||
"transform",
|
||||
ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE | ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE |
|
||||
ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE);
|
||||
ED_GIZMO_CAGE_XFORM_FLAG_TRANSLATE | ED_GIZMO_CAGE_XFORM_FLAG_SCALE |
|
||||
ED_GIZMO_CAGE_XFORM_FLAG_ROTATE);
|
||||
|
||||
return ggd;
|
||||
}
|
||||
|
|
|
@ -2159,9 +2159,8 @@ static void WIDGETGROUP_xform_cage_setup(const bContext *UNUSED(C), wmGizmoGroup
|
|||
xgzgroup->gizmo = WM_gizmo_new_ptr(gzt_cage, gzgroup, NULL);
|
||||
wmGizmo *gz = xgzgroup->gizmo;
|
||||
|
||||
RNA_enum_set(gz->ptr,
|
||||
"transform",
|
||||
ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE | ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE);
|
||||
RNA_enum_set(
|
||||
gz->ptr, "transform", ED_GIZMO_CAGE_XFORM_FLAG_SCALE | ED_GIZMO_CAGE_XFORM_FLAG_TRANSLATE);
|
||||
|
||||
gz->color[0] = 1;
|
||||
gz->color_hi[0] = 1;
|
||||
|
|
|
@ -159,12 +159,14 @@ VolumeGrid *volume_grid_add_from_mesh(Volume *volume,
|
|||
interior_band_width,
|
||||
density);
|
||||
|
||||
/* Merge the generated grid. Should be cheap because grid has just been created. */
|
||||
grid->merge(*mesh_grid);
|
||||
if (mesh_grid != nullptr) {
|
||||
/* Merge the generated grid. Should be cheap because grid has just been created. */
|
||||
grid->merge(*mesh_grid);
|
||||
/* Change transform so that the index space is correctly transformed to object space. */
|
||||
grid->transform().postScale(voxel_size);
|
||||
}
|
||||
/* Set class to "Fog Volume". */
|
||||
grid->setGridClass(openvdb::GRID_FOG_VOLUME);
|
||||
/* Change transform so that the index space is correctly transformed to object space. */
|
||||
grid->transform().postScale(voxel_size);
|
||||
return c_grid;
|
||||
}
|
||||
} // namespace blender::geometry
|
||||
|
|
|
@ -1197,7 +1197,7 @@ static AllCurvesInfo preprocess_curves(const GeometrySet &geometry_set,
|
|||
for (const int curve_index : info.realize_info.index_range()) {
|
||||
RealizeCurveInfo &curve_info = info.realize_info[curve_index];
|
||||
const Curves *curves_id = info.order[curve_index];
|
||||
const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id->geometry);
|
||||
const bke::CurvesGeometry &curves = curves_id->geometry.wrap();
|
||||
curve_info.curves = curves_id;
|
||||
|
||||
/* Access attributes. */
|
||||
|
@ -1258,7 +1258,7 @@ static void execute_realize_curve_task(const RealizeInstancesOptions &options,
|
|||
{
|
||||
const RealizeCurveInfo &curves_info = *task.curve_info;
|
||||
const Curves &curves_id = *curves_info.curves;
|
||||
const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry);
|
||||
const bke::CurvesGeometry &curves = curves_id.geometry.wrap();
|
||||
|
||||
const IndexRange dst_point_range{task.start_indices.point, curves.points_num()};
|
||||
const IndexRange dst_curve_range{task.start_indices.curve, curves.curves_num()};
|
||||
|
@ -1347,7 +1347,7 @@ static void execute_realize_curve_tasks(const RealizeInstancesOptions &options,
|
|||
|
||||
/* Allocate new curves data-block. */
|
||||
Curves *dst_curves_id = bke::curves_new_nomain(points_num, curves_num);
|
||||
bke::CurvesGeometry &dst_curves = bke::CurvesGeometry::wrap(dst_curves_id->geometry);
|
||||
bke::CurvesGeometry &dst_curves = dst_curves_id->geometry.wrap();
|
||||
dst_curves.offsets_for_write().last() = points_num;
|
||||
CurveComponent &dst_component = r_realized_geometry.get_component_for_write<CurveComponent>();
|
||||
dst_component.replace(dst_curves_id);
|
||||
|
|
|
@ -260,6 +260,7 @@ static void empty_panel_draw(const bContext *UNUSED(C), Panel *panel)
|
|||
static void random_panel_draw(const bContext *UNUSED(C), Panel *panel)
|
||||
{
|
||||
uiLayout *layout = panel->layout;
|
||||
uiLayout *col;
|
||||
|
||||
PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, NULL);
|
||||
int mode = RNA_enum_get(ptr, "mode");
|
||||
|
@ -270,22 +271,24 @@ static void random_panel_draw(const bContext *UNUSED(C), Panel *panel)
|
|||
uiItemR(layout, ptr, "random_offset", 0, IFACE_("Offset"), ICON_NONE);
|
||||
uiItemR(layout, ptr, "random_rotation", 0, IFACE_("Rotation"), ICON_NONE);
|
||||
uiItemR(layout, ptr, "random_scale", 0, IFACE_("Scale"), ICON_NONE);
|
||||
|
||||
col = uiLayoutColumn(layout, true);
|
||||
switch (mode) {
|
||||
case GP_OFFSET_RANDOM:
|
||||
uiItemR(layout, ptr, "use_uniform_random_scale", 0, NULL, ICON_NONE);
|
||||
uiItemR(layout, ptr, "seed", 0, NULL, ICON_NONE);
|
||||
break;
|
||||
case GP_OFFSET_STROKE:
|
||||
uiItemR(layout, ptr, "stroke_step", 0, IFACE_("Stroke Step"), ICON_NONE);
|
||||
uiItemR(layout, ptr, "stroke_start_offset", 0, IFACE_("Offset"), ICON_NONE);
|
||||
uiItemR(col, ptr, "stroke_step", 0, IFACE_("Stroke Step"), ICON_NONE);
|
||||
uiItemR(col, ptr, "stroke_start_offset", 0, IFACE_("Offset"), ICON_NONE);
|
||||
break;
|
||||
case GP_OFFSET_MATERIAL:
|
||||
uiItemR(layout, ptr, "stroke_step", 0, IFACE_("Material Step"), ICON_NONE);
|
||||
uiItemR(layout, ptr, "stroke_start_offset", 0, IFACE_("Offset"), ICON_NONE);
|
||||
uiItemR(col, ptr, "stroke_step", 0, IFACE_("Material Step"), ICON_NONE);
|
||||
uiItemR(col, ptr, "stroke_start_offset", 0, IFACE_("Offset"), ICON_NONE);
|
||||
break;
|
||||
case GP_OFFSET_LAYER:
|
||||
uiItemR(layout, ptr, "stroke_step", 0, IFACE_("Layer Step"), ICON_NONE);
|
||||
uiItemR(layout, ptr, "stroke_start_offset", 0, IFACE_("Offset"), ICON_NONE);
|
||||
uiItemR(col, ptr, "stroke_step", 0, IFACE_("Layer Step"), ICON_NONE);
|
||||
uiItemR(col, ptr, "stroke_start_offset", 0, IFACE_("Offset"), ICON_NONE);
|
||||
break;
|
||||
}
|
||||
gpencil_modifier_panel_end(layout, ptr);
|
||||
|
|
|
@ -72,6 +72,8 @@ void imm_draw_circle_fill_aspect_2d(
|
|||
* Use this version when #GPUVertFormat has a vec3 position.
|
||||
*/
|
||||
void imm_draw_circle_wire_3d(uint pos, float x, float y, float radius, int nsegments);
|
||||
void imm_draw_circle_wire_aspect_3d(
|
||||
uint pos, float x, float y, float radius_x, float radius_y, int nsegments);
|
||||
void imm_draw_circle_dashed_3d(uint pos, float x, float y, float radius, int nsegments);
|
||||
void imm_draw_circle_fill_3d(uint pos, float x, float y, float radius, int nsegments);
|
||||
|
||||
|
|
|
@ -179,6 +179,7 @@ void imm_draw_circle_wire_aspect_2d(
|
|||
{
|
||||
imm_draw_circle(GPU_PRIM_LINE_LOOP, shdr_pos, x, y, radius_x, radius_y, nsegments);
|
||||
}
|
||||
|
||||
void imm_draw_circle_fill_aspect_2d(
|
||||
uint shdr_pos, float x, float y, float radius_x, float radius_y, int nsegments)
|
||||
{
|
||||
|
@ -329,19 +330,24 @@ void imm_draw_disk_partial_fill_3d(uint pos,
|
|||
GPU_PRIM_TRI_STRIP, pos, x, y, z, rad_inner, rad_outer, nsegments, start, sweep);
|
||||
}
|
||||
|
||||
static void imm_draw_circle_3D(
|
||||
GPUPrimType prim_type, uint pos, float x, float y, float radius, int nsegments)
|
||||
static void imm_draw_circle_3D(GPUPrimType prim_type,
|
||||
uint pos,
|
||||
float x,
|
||||
float y,
|
||||
float radius_x,
|
||||
float radius_y,
|
||||
int nsegments)
|
||||
{
|
||||
if (prim_type == GPU_PRIM_LINE_LOOP) {
|
||||
/* NOTE(Metal/AMD): For small primitives, line list more efficient than line strip. */
|
||||
immBegin(GPU_PRIM_LINES, nsegments * 2);
|
||||
|
||||
const float angle = (float)(2 * M_PI) / (float)nsegments;
|
||||
float xprev = cosf(-angle) * radius;
|
||||
float yprev = sinf(-angle) * radius;
|
||||
float xprev = cosf(-angle) * radius_x;
|
||||
float yprev = sinf(-angle) * radius_y;
|
||||
const float alpha = 2.0f * cosf(angle);
|
||||
|
||||
float xr = radius;
|
||||
float xr = radius_x;
|
||||
float yr = 0;
|
||||
|
||||
for (int i = 0; i < nsegments; i++) {
|
||||
|
@ -349,21 +355,23 @@ static void imm_draw_circle_3D(
|
|||
if (i) {
|
||||
immVertex3f(pos, x + xr, y + yr, 0.0f);
|
||||
}
|
||||
/* cos[(n + 1)a] = 2cos(a)cos(na) - cos[(n - 1)a]. */
|
||||
const float xnext = alpha * xr - xprev;
|
||||
/* sin[(n + 1)a] = 2cos(a)sin(na) - sin[(n - 1)a]. */
|
||||
const float ynext = alpha * yr - yprev;
|
||||
xprev = xr;
|
||||
yprev = yr;
|
||||
xr = xnext;
|
||||
yr = ynext;
|
||||
}
|
||||
immVertex3f(pos, x + radius, y, 0.0f);
|
||||
immVertex3f(pos, x + radius_x, y, 0.0f);
|
||||
immEnd();
|
||||
}
|
||||
else {
|
||||
immBegin(prim_type, nsegments);
|
||||
for (int i = 0; i < nsegments; i++) {
|
||||
float angle = (float)(2 * M_PI) * ((float)i / (float)nsegments);
|
||||
immVertex3f(pos, x + radius * cosf(angle), y + radius * sinf(angle), 0.0f);
|
||||
immVertex3f(pos, x + radius_x * cosf(angle), y + radius_y * sinf(angle), 0.0f);
|
||||
}
|
||||
immEnd();
|
||||
}
|
||||
|
@ -371,17 +379,23 @@ static void imm_draw_circle_3D(
|
|||
|
||||
void imm_draw_circle_wire_3d(uint pos, float x, float y, float radius, int nsegments)
|
||||
{
|
||||
imm_draw_circle_3D(GPU_PRIM_LINE_LOOP, pos, x, y, radius, nsegments);
|
||||
imm_draw_circle_3D(GPU_PRIM_LINE_LOOP, pos, x, y, radius, radius, nsegments);
|
||||
}
|
||||
|
||||
void imm_draw_circle_wire_aspect_3d(
|
||||
uint shdr_pos, float x, float y, float radius_x, float radius_y, int nsegments)
|
||||
{
|
||||
imm_draw_circle_3D(GPU_PRIM_LINE_LOOP, shdr_pos, x, y, radius_x, radius_y, nsegments);
|
||||
}
|
||||
|
||||
void imm_draw_circle_dashed_3d(uint pos, float x, float y, float radius, int nsegments)
|
||||
{
|
||||
imm_draw_circle_3D(GPU_PRIM_LINES, pos, x, y, radius, nsegments / 2);
|
||||
imm_draw_circle_3D(GPU_PRIM_LINES, pos, x, y, radius, radius, nsegments / 2);
|
||||
}
|
||||
|
||||
void imm_draw_circle_fill_3d(uint pos, float x, float y, float radius, int nsegments)
|
||||
{
|
||||
imm_draw_circle_3D(GPU_PRIM_TRI_FAN, pos, x, y, radius, nsegments);
|
||||
imm_draw_circle_3D(GPU_PRIM_TRI_FAN, pos, x, y, radius, radius, nsegments);
|
||||
}
|
||||
|
||||
void imm_draw_box_wire_2d(uint pos, float x1, float y1, float x2, float y2)
|
||||
|
|
|
@ -68,7 +68,6 @@ class ShaderInterface {
|
|||
|
||||
public:
|
||||
ShaderInterface();
|
||||
ShaderInterface(const shader::ShaderCreateInfo &info);
|
||||
virtual ~ShaderInterface();
|
||||
|
||||
void debug_print();
|
||||
|
|
|
@ -1202,7 +1202,7 @@ bool MTLContext::ensure_uniform_buffer_bindings(
|
|||
BLI_assert(buffer_index >= 0 && buffer_index < MTL_MAX_BUFFER_BINDINGS);
|
||||
|
||||
/* For compute, we must always re-bind the push constant block as other compute
|
||||
* operations may have assigned reources over the top, outside of the compiled
|
||||
* operations may have assigned resources over the top, outside of the compiled
|
||||
* compute shader path. */
|
||||
/* Bind push constant data. */
|
||||
BLI_assert(this->pipeline_state.active_shader->get_push_constant_data() != nullptr);
|
||||
|
|
|
@ -309,7 +309,7 @@ class MTLSafeFreeList {
|
|||
* Performs a lockless list insert. */
|
||||
void insert_buffer(gpu::MTLBuffer *buffer);
|
||||
|
||||
/* Whether we need ot start a new safe free list, or can carry on using the existing one. */
|
||||
/* Whether we need to start a new safe free list, or can carry on using the existing one. */
|
||||
bool should_flush();
|
||||
|
||||
/* Increments command buffer reference count. */
|
||||
|
|
|
@ -225,7 +225,7 @@ static void extract_and_replace_clipping_distances(std::string &vertex_source,
|
|||
continue;
|
||||
}
|
||||
|
||||
/* Extract ID betwen zero and 9. */
|
||||
/* Extract ID between zero and 9. */
|
||||
if ((*c >= '0') && (*c <= '9')) {
|
||||
char clip_distance_id = ((*c) - '0');
|
||||
auto found = std::find(
|
||||
|
@ -314,9 +314,9 @@ static void replace_matrix_constructors(std::string &str)
|
|||
|
||||
/* Replace matrix constructors with GLSL-compatible constructors for Metal.
|
||||
* Base matrix constructors e.g. mat3x3 do not have as many overload variants as GLSL.
|
||||
* To add compatibility, we declare custom constuctors e.g. MAT3x3 in mtl_shader_defines.msl.
|
||||
* To add compatibility, we declare custom constructors e.g. MAT3x3 in `mtl_shader_defines.msl`.
|
||||
* If the GLSL syntax matches, we map mat3x3(..) -> MAT3x3(..) and implement a custom
|
||||
* constructor. This supports both mat3(..) and mat3x3(..) style sytax.*/
|
||||
* constructor. This supports both mat3(..) and mat3x3(..) style syntax. */
|
||||
char *current_str_begin = &*str.begin();
|
||||
char *current_str_end = &*str.end();
|
||||
|
||||
|
@ -335,7 +335,7 @@ static void replace_matrix_constructors(std::string &str)
|
|||
continue;
|
||||
}
|
||||
|
||||
/* Possible multiple dimensional matrix constructor. Verify if next char is a dim*/
|
||||
/* Possible multiple dimensional matrix constructor. Verify if next char is a dim. */
|
||||
c++;
|
||||
if (*c == 'x') {
|
||||
c++;
|
||||
|
@ -601,7 +601,7 @@ void extract_shared_memory_blocks(MSLGeneratorInterface &msl_iface,
|
|||
new_shared_block.type_name = std::string(buf);
|
||||
|
||||
/* Read var-name.
|
||||
* Varname can either come right before the final semi-colon, or
|
||||
* `varname` can either come right before the final semi-colon, or
|
||||
* with following array syntax.
|
||||
* spaces may exist before closing symbol. */
|
||||
c = c_next_space + 1;
|
||||
|
@ -3017,7 +3017,7 @@ std::string MSLGeneratorInterface::generate_msl_fragment_output_population()
|
|||
|
||||
std::string MSLGeneratorInterface::generate_msl_texture_vars(ShaderStage shader_stage)
|
||||
{
|
||||
/* NOTE: Shader stage must be a singualr stage index. Compound stage is not valid for this
|
||||
/* NOTE: Shader stage must be a singular stage index. Compound stage is not valid for this
|
||||
* function. */
|
||||
BLI_assert(shader_stage == ShaderStage::VERTEX || shader_stage == ShaderStage::FRAGMENT ||
|
||||
shader_stage == ShaderStage::COMPUTE);
|
||||
|
|
|
@ -209,6 +209,48 @@ static void test_gpu_shader_compute_ibo()
|
|||
}
|
||||
GPU_TEST(gpu_shader_compute_ibo)
|
||||
|
||||
static void test_gpu_shader_compute_ssbo()
|
||||
{
|
||||
|
||||
if (!GPU_compute_shader_support()) {
|
||||
/* We can't test as a the platform does not support compute shaders. */
|
||||
std::cout << "Skipping compute shader test: platform not supported";
|
||||
return;
|
||||
}
|
||||
|
||||
static constexpr uint SIZE = 128;
|
||||
|
||||
/* Build compute shader. */
|
||||
GPUShader *shader = GPU_shader_create_from_info_name("gpu_compute_ibo_test");
|
||||
EXPECT_NE(shader, nullptr);
|
||||
GPU_shader_bind(shader);
|
||||
|
||||
/* Construct IBO. */
|
||||
GPUStorageBuf *ssbo = GPU_storagebuf_create_ex(
|
||||
SIZE * sizeof(uint32_t), nullptr, GPU_USAGE_DEVICE_ONLY, __func__);
|
||||
GPU_storagebuf_bind(ssbo, GPU_shader_get_ssbo(shader, "out_indices"));
|
||||
|
||||
/* Dispatch compute task. */
|
||||
GPU_compute_dispatch(shader, SIZE, 1, 1);
|
||||
|
||||
/* Check if compute has been done. */
|
||||
GPU_memory_barrier(GPU_BARRIER_SHADER_STORAGE);
|
||||
|
||||
/* Download the index buffer. */
|
||||
uint32_t data[SIZE];
|
||||
GPU_storagebuf_read(ssbo, data);
|
||||
for (int index = 0; index < SIZE; index++) {
|
||||
uint32_t expected = index;
|
||||
EXPECT_EQ(data[index], expected);
|
||||
}
|
||||
|
||||
/* Cleanup. */
|
||||
GPU_shader_unbind();
|
||||
GPU_storagebuf_free(ssbo);
|
||||
GPU_shader_free(shader);
|
||||
}
|
||||
GPU_TEST(gpu_shader_compute_ssbo)
|
||||
|
||||
static void test_gpu_shader_ssbo_binding()
|
||||
{
|
||||
if (!GPU_compute_shader_support()) {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
void main() {
|
||||
void main()
|
||||
{
|
||||
int index = int(gl_GlobalInvocationID.x);
|
||||
vec4 pos = vec4(gl_GlobalInvocationID.x);
|
||||
imageStore(img_output, index, pos);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
void main() {
|
||||
void main()
|
||||
{
|
||||
vec4 pixel = vec4(1.0, 0.5, 0.2, 1.0);
|
||||
imageStore(img_output, ivec2(gl_GlobalInvocationID.xy), pixel);
|
||||
}
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
void main () {
|
||||
void main()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
void main() {
|
||||
void main()
|
||||
{
|
||||
uint store_index = int(gl_GlobalInvocationID.x);
|
||||
out_indices[store_index] = store_index;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
void main() {
|
||||
void main()
|
||||
{
|
||||
uint index = gl_GlobalInvocationID.x;
|
||||
vec4 pos = vec4(gl_GlobalInvocationID.x);
|
||||
out_positions[index] = pos;
|
||||
|
|
|
@ -521,7 +521,9 @@ static char *glsl_patch_get()
|
|||
static std::string combine_sources(Span<const char *> sources)
|
||||
{
|
||||
char *sources_combined = BLI_string_join_arrayN((const char **)sources.data(), sources.size());
|
||||
return std::string(sources_combined);
|
||||
std::string result(sources_combined);
|
||||
MEM_freeN(sources_combined);
|
||||
return result;
|
||||
}
|
||||
|
||||
Vector<uint32_t> VKShader::compile_glsl_to_spirv(Span<const char *> sources,
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
* \ingroup bgpencil
|
||||
*/
|
||||
|
||||
#include "BLI_float4x4.hh"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
#include "BLI_math_matrix.hh"
|
||||
#include "BLI_path_util.h"
|
||||
#include "BLI_span.hh"
|
||||
|
||||
|
@ -78,13 +77,12 @@ void GpencilIO::prepare_camera_params(Scene *scene, const GpencilIOParams *ipara
|
|||
BKE_camera_params_compute_viewplane(¶ms, rd->xsch, rd->ysch, rd->xasp, rd->yasp);
|
||||
BKE_camera_params_compute_matrix(¶ms);
|
||||
|
||||
float viewmat[4][4];
|
||||
invert_m4_m4(viewmat, cam_ob->object_to_world);
|
||||
float4x4 viewmat = math::invert(float4x4(cam_ob->object_to_world));
|
||||
|
||||
mul_m4_m4m4(persmat_, params.winmat, viewmat);
|
||||
persmat_ = float4x4(params.winmat) * viewmat;
|
||||
}
|
||||
else {
|
||||
unit_m4(persmat_);
|
||||
persmat_ = float4x4::identity();
|
||||
}
|
||||
|
||||
winx_ = params_.region->winx;
|
||||
|
@ -131,8 +129,7 @@ void GpencilIO::create_object_list()
|
|||
Scene *scene = CTX_data_scene(params_.C);
|
||||
ViewLayer *view_layer = CTX_data_view_layer(params_.C);
|
||||
|
||||
float3 camera_z_axis;
|
||||
copy_v3_v3(camera_z_axis, rv3d_->viewinv[2]);
|
||||
float3 camera_z_axis = float3(rv3d_->viewinv[2]);
|
||||
ob_list_.clear();
|
||||
|
||||
BKE_view_layer_synced_ensure(scene, view_layer);
|
||||
|
@ -150,9 +147,11 @@ void GpencilIO::create_object_list()
|
|||
continue;
|
||||
}
|
||||
|
||||
float3 object_position = float3(object->object_to_world[3]);
|
||||
|
||||
/* Save z-depth from view to sort from back to front. */
|
||||
if (is_camera_) {
|
||||
float camera_z = dot_v3v3(camera_z_axis, object->object_to_world[3]);
|
||||
float camera_z = math::dot(camera_z_axis, object_position);
|
||||
ObjectZ obz = {camera_z, object};
|
||||
ob_list_.append(obz);
|
||||
}
|
||||
|
@ -160,10 +159,10 @@ void GpencilIO::create_object_list()
|
|||
float zdepth = 0;
|
||||
if (rv3d_) {
|
||||
if (rv3d_->is_persp) {
|
||||
zdepth = ED_view3d_calc_zfac(rv3d_, object->object_to_world[3]);
|
||||
zdepth = ED_view3d_calc_zfac(rv3d_, object_position);
|
||||
}
|
||||
else {
|
||||
zdepth = -dot_v3v3(rv3d_->viewinv[2], object->object_to_world[3]);
|
||||
zdepth = -math::dot(camera_z_axis, object_position);
|
||||
}
|
||||
ObjectZ obz = {zdepth * -1.0f, object};
|
||||
ob_list_.append(obz);
|
||||
|
@ -184,13 +183,13 @@ void GpencilIO::filepath_set(const char *filepath)
|
|||
|
||||
bool GpencilIO::gpencil_3D_point_to_screen_space(const float3 co, float2 &r_co)
|
||||
{
|
||||
float3 parent_co = diff_mat_ * co;
|
||||
float3 parent_co = math::transform_point(diff_mat_, co);
|
||||
float2 screen_co;
|
||||
eV3DProjTest test = (eV3DProjTest)(V3D_PROJ_RET_OK);
|
||||
if (ED_view3d_project_float_global(params_.region, parent_co, screen_co, test) ==
|
||||
V3D_PROJ_RET_OK) {
|
||||
if (!ELEM(V2D_IS_CLIPPED, screen_co[0], screen_co[1])) {
|
||||
copy_v2_v2(r_co, screen_co);
|
||||
r_co = screen_co;
|
||||
/* Invert X axis. */
|
||||
if (invert_axis_[0]) {
|
||||
r_co[0] = winx_ - r_co[0];
|
||||
|
@ -200,8 +199,8 @@ bool GpencilIO::gpencil_3D_point_to_screen_space(const float3 co, float2 &r_co)
|
|||
r_co[1] = winy_ - r_co[1];
|
||||
}
|
||||
/* Apply offset and scale. */
|
||||
sub_v2_v2(r_co, &offset_.x);
|
||||
mul_v2_fl(r_co, camera_ratio_);
|
||||
r_co -= offset_;
|
||||
r_co *= camera_ratio_;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -223,12 +222,10 @@ bool GpencilIO::gpencil_3D_point_to_screen_space(const float3 co, float2 &r_co)
|
|||
|
||||
float2 GpencilIO::gpencil_3D_point_to_render_space(const float3 co)
|
||||
{
|
||||
float3 parent_co = diff_mat_ * co;
|
||||
float3 parent_co = math::transform_point(diff_mat_, co);
|
||||
|
||||
float2 r_co;
|
||||
mul_v2_project_m4_v3(&r_co.x, persmat_, &parent_co.x);
|
||||
r_co.x = (r_co.x + 1.0f) / 2.0f * float(render_x_);
|
||||
r_co.y = (r_co.y + 1.0f) / 2.0f * float(render_y_);
|
||||
float2 r_co = float2(math::project_point(persmat_, parent_co));
|
||||
r_co = ((r_co + 1.0f) / 2.0f) * float2(render_x_, render_y_);
|
||||
|
||||
/* Invert X axis. */
|
||||
if (invert_axis_[0]) {
|
||||
|
@ -260,7 +257,7 @@ float GpencilIO::stroke_point_radius_get(bGPDlayer *gpl, bGPDstroke *gps)
|
|||
|
||||
/* Radius. */
|
||||
bGPDstroke *gps_perimeter = BKE_gpencil_stroke_perimeter_from_view(
|
||||
rv3d_->viewmat, gpd_, gpl, gps, 3, diff_mat_.values, 0.0f);
|
||||
rv3d_->viewmat, gpd_, gpl, gps, 3, diff_mat_.ptr(), 0.0f);
|
||||
|
||||
pt = &gps_perimeter->points[0];
|
||||
const float2 screen_ex = gpencil_3D_point_to_2D(&pt->x);
|
||||
|
@ -274,7 +271,7 @@ float GpencilIO::stroke_point_radius_get(bGPDlayer *gpl, bGPDstroke *gps)
|
|||
|
||||
void GpencilIO::prepare_layer_export_matrix(Object *ob, bGPDlayer *gpl)
|
||||
{
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph_, ob, gpl, diff_mat_.values);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph_, ob, gpl, diff_mat_.ptr());
|
||||
diff_mat_ = diff_mat_ * float4x4(gpl->layer_invmat);
|
||||
}
|
||||
|
||||
|
@ -283,23 +280,21 @@ void GpencilIO::prepare_stroke_export_colors(Object *ob, bGPDstroke *gps)
|
|||
MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, gps->mat_nr + 1);
|
||||
|
||||
/* Stroke color. */
|
||||
copy_v4_v4(stroke_color_, gp_style->stroke_rgba);
|
||||
avg_opacity_ = 0.0f;
|
||||
/* Get average vertex color and apply. */
|
||||
float avg_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
float4 avg_color = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
for (const bGPDspoint &pt : Span(gps->points, gps->totpoints)) {
|
||||
add_v4_v4(avg_color, pt.vert_color);
|
||||
avg_color += pt.vert_color;
|
||||
avg_opacity_ += pt.strength;
|
||||
}
|
||||
|
||||
mul_v4_v4fl(avg_color, avg_color, 1.0f / float(gps->totpoints));
|
||||
interp_v3_v3v3(stroke_color_, stroke_color_, avg_color, avg_color[3]);
|
||||
avg_color /= float(gps->totpoints);
|
||||
avg_opacity_ /= float(gps->totpoints);
|
||||
stroke_color_ = math::interpolate(float4(gp_style->stroke_rgba), avg_color, avg_color[3]);
|
||||
|
||||
/* Fill color. */
|
||||
copy_v4_v4(fill_color_, gp_style->fill_rgba);
|
||||
/* Apply vertex color for fill. */
|
||||
interp_v3_v3v3(fill_color_, fill_color_, gps->vert_color_fill, gps->vert_color_fill[3]);
|
||||
fill_color_ = math::interpolate(
|
||||
float4(gp_style->fill_rgba), float4(gps->vert_color_fill), gps->vert_color_fill[3]);
|
||||
}
|
||||
|
||||
float GpencilIO::stroke_average_opacity_get()
|
||||
|
@ -329,7 +324,7 @@ void GpencilIO::selected_objects_boundbox_calc()
|
|||
if (gpl->flag & GP_LAYER_HIDE) {
|
||||
continue;
|
||||
}
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph_, ob_eval, gpl, diff_mat_.values);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph_, ob_eval, gpl, diff_mat_.ptr());
|
||||
|
||||
bGPDframe *gpf = gpl->actframe;
|
||||
if (gpf == nullptr) {
|
||||
|
@ -341,15 +336,14 @@ void GpencilIO::selected_objects_boundbox_calc()
|
|||
continue;
|
||||
}
|
||||
for (const bGPDspoint &pt : MutableSpan(gps->points, gps->totpoints)) {
|
||||
const float2 screen_co = gpencil_3D_point_to_2D(&pt.x);
|
||||
minmax_v2v2_v2(min, max, screen_co);
|
||||
math::min_max(gpencil_3D_point_to_2D(&pt.x), min, max);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Add small gap. */
|
||||
add_v2_fl(min, gap * -1.0f);
|
||||
add_v2_fl(max, gap);
|
||||
min -= gap;
|
||||
max += gap;
|
||||
|
||||
select_boundbox_.xmin = min[0];
|
||||
select_boundbox_.ymin = min[1];
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* \ingroup bgpencil
|
||||
*/
|
||||
|
||||
#include "BLI_float4x4.hh"
|
||||
#include "BLI_math_matrix_types.hh"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
|
@ -67,7 +67,7 @@ class GpencilIO {
|
|||
|
||||
int cfra_;
|
||||
|
||||
float stroke_color_[4], fill_color_[4];
|
||||
float4 stroke_color_, fill_color_;
|
||||
|
||||
/* Geometry functions. */
|
||||
/** Convert to screen-space. */
|
||||
|
@ -104,7 +104,7 @@ class GpencilIO {
|
|||
rctf select_boundbox_;
|
||||
|
||||
/* Camera matrix. */
|
||||
float persmat_[4][4];
|
||||
float4x4 persmat_;
|
||||
};
|
||||
|
||||
} // namespace blender::io::gpencil
|
||||
|
|
|
@ -193,7 +193,7 @@ void GpencilExporterPDF::export_gpencil_layers()
|
|||
}
|
||||
else {
|
||||
bGPDstroke *gps_perimeter = BKE_gpencil_stroke_perimeter_from_view(
|
||||
rv3d_->viewmat, gpd_, gpl, gps_duplicate, 3, diff_mat_.values, 0.0f);
|
||||
rv3d_->viewmat, gpd_, gpl, gps_duplicate, 3, diff_mat_.ptr(), 0.0f);
|
||||
|
||||
/* Sample stroke. */
|
||||
if (params_.stroke_sample > 0.0f) {
|
||||
|
|
|
@ -219,7 +219,7 @@ void GpencilExporterSVG::export_gpencil_layers()
|
|||
}
|
||||
else {
|
||||
bGPDstroke *gps_perimeter = BKE_gpencil_stroke_perimeter_from_view(
|
||||
rv3d_->viewmat, gpd_, gpl, gps_duplicate, 3, diff_mat_.values, 0.0f);
|
||||
rv3d_->viewmat, gpd_, gpl, gps_duplicate, 3, diff_mat_.ptr(), 0.0f);
|
||||
|
||||
/* Sample stroke. */
|
||||
if (params_.stroke_sample > 0.0f) {
|
||||
|
|
|
@ -104,6 +104,12 @@ typedef struct IDPropertyUIDataString {
|
|||
/** For #IDP_UI_DATA_TYPE_ID. */
|
||||
typedef struct IDPropertyUIDataID {
|
||||
IDPropertyUIData base;
|
||||
/**
|
||||
* #ID_Type. This type type is not enforced. It is just a hint to the ui for what kind of ID is
|
||||
* expected. If this is zero, any id type is expected.
|
||||
*/
|
||||
short id_type;
|
||||
char _pad[6];
|
||||
} IDPropertyUIDataID;
|
||||
|
||||
typedef struct IDPropertyData {
|
||||
|
|
|
@ -17,6 +17,7 @@ extern "C" {
|
|||
|
||||
#ifdef __cplusplus
|
||||
namespace blender::bke {
|
||||
class CurvesGeometry;
|
||||
class CurvesGeometryRuntime;
|
||||
} // namespace blender::bke
|
||||
using CurvesGeometryRuntimeHandle = blender::bke::CurvesGeometryRuntime;
|
||||
|
@ -134,6 +135,11 @@ typedef struct CurvesGeometry {
|
|||
* Runtime data for curves, stored as a pointer to allow defining this as a C++ class.
|
||||
*/
|
||||
CurvesGeometryRuntimeHandle *runtime;
|
||||
|
||||
#ifdef __cplusplus
|
||||
blender::bke::CurvesGeometry &wrap();
|
||||
const blender::bke::CurvesGeometry &wrap() const;
|
||||
#endif
|
||||
} CurvesGeometry;
|
||||
|
||||
/**
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue