BLI: Improve IndexMask::complement() performance #108331

Merged
Hans Goudey merged 15 commits from HooglyBoogly/blender:index-mask-complement-performance into main 2023-05-31 17:11:11 +02:00
44 changed files with 1244 additions and 779 deletions
Showing only changes of commit fde54ae1a9 - Show all commits

View File

@ -424,6 +424,7 @@ class NODE_MT_geometry_node_mesh_topology(Menu):
def draw(self, _context):
layout = self.layout
node_add_menu.add_node_type(layout, "GeometryNodeCornersOfEdge")
node_add_menu.add_node_type(layout, "GeometryNodeCornersOfFace")
node_add_menu.add_node_type(layout, "GeometryNodeCornersOfVertex")
node_add_menu.add_node_type(layout, "GeometryNodeEdgesOfCorner")

View File

@ -180,7 +180,10 @@ void ramp_blend(int type, float r_col[3], float fac, const float col[3]);
void BKE_material_copybuf_clear(void);
void BKE_material_copybuf_free(void);
void BKE_material_copybuf_copy(struct Main *bmain, struct Material *ma);
void BKE_material_copybuf_paste(struct Main *bmain, struct Material *ma);
/**
* \return true when the material was modified.
*/
bool BKE_material_copybuf_paste(struct Main *bmain, struct Material *ma);
/** \} */

View File

@ -1308,6 +1308,7 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i
#define GEO_NODE_SIMULATION_OUTPUT 2101
#define GEO_NODE_INPUT_SIGNED_DISTANCE 2102
#define GEO_NODE_SAMPLE_VOLUME 2103
#define GEO_NODE_MESH_TOPOLOGY_CORNERS_OF_EDGE 2104
/** \} */

View File

@ -17,6 +17,8 @@ void BKE_simulation_data_update(struct Depsgraph *depsgraph,
struct Scene *scene,
struct Simulation *simulation);
void BKE_simulation_reset_scene(Scene *scene);
#ifdef __cplusplus
}
#endif

View File

@ -162,6 +162,8 @@ class ModifierSimulationCache {
CacheState cache_state_ = CacheState::Valid;
bool failed_finding_bake_ = false;
float last_fps_ = 0.0f;
void try_discover_bake(StringRefNull absolute_bake_dir);
bool has_state_at_frame(const SubFrame &frame) const;

View File

@ -518,7 +518,7 @@ void BKE_collection_add_from_collection(Main *bmain,
bool is_instantiated = false;
FOREACH_SCENE_COLLECTION_BEGIN (scene, collection) {
if (!ID_IS_LINKED(collection) && !ID_IS_OVERRIDABLE_LIBRARY(collection) &&
if (!ID_IS_LINKED(collection) && !ID_IS_OVERRIDE_LIBRARY(collection) &&
collection_find_child(collection, collection_src))
{
collection_child_add(collection, collection_dst, 0, true);

View File

@ -176,11 +176,9 @@ void legacy_gpencil_to_grease_pencil(Main &bmain, GreasePencil &grease_pencil, b
{
using namespace blender::bke::greasepencil;
int num_layers = 0;
int num_drawings = 0;
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd.layers) {
num_drawings += BLI_listbase_count(&gpl->frames);
num_layers++;
}
grease_pencil.drawing_array_size = num_drawings;

View File

@ -589,6 +589,11 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain,
/* Only remap new local ID's pointers, we don't want to force our new overrides onto our whole
* existing linked IDs usages. */
if (success) {
/* If a valid liboverride hierarchy root was given, only remap non-liboverride data and
* liboverrides belonging to that hierarchy. Avoids having other liboverride hierarchies of
* the same reference data also remapped to the newly created liboverride. */
const bool do_remap_liboverride_hierarchy_only = (id_hierarchy_root != nullptr && !do_no_main);
if (id_hierarchy_root_reference != nullptr) {
id_hierarchy_root = id_hierarchy_root_reference->newid;
}
@ -625,7 +630,18 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain,
/* If other ID is a linked one, but not from the same library as our reference, then we
* consider we should also relink it, as part of recursive resync. */
if ((other_id->tag & LIB_TAG_DOIT) != 0 && other_id->lib != id_root_reference->lib) {
BLI_linklist_prepend(&relinked_ids, other_id);
ID *owner_id;
BKE_lib_override_library_get(bmain, other_id, nullptr, &owner_id);
/* When the root of the current liboverride hierarchy is known, only remap liboverrides if
* they belong to that hierarchy. */
if (!do_remap_liboverride_hierarchy_only ||
(!ID_IS_OVERRIDE_LIBRARY_REAL(owner_id) ||
owner_id->override_library->hierarchy_root == id_hierarchy_root))
{
BLI_linklist_prepend(&relinked_ids, other_id);
}
if (ID_IS_OVERRIDE_LIBRARY_REAL(other_id) &&
other_id->override_library->hierarchy_root == id_hierarchy_root)
{
@ -1264,11 +1280,25 @@ static void lib_override_library_create_post_process(Main *bmain,
* won't have a base, but are still considered as instanced from our point of view. */
GSet *all_objects_in_scene = BKE_scene_objects_as_gset(scene, nullptr);
/* Instantiating the root collection or object should never be needed in resync case, since the
* old override would be remapped to the new one. */
if (!is_resync && id_root != nullptr && id_root->newid != nullptr &&
(!ID_IS_LINKED(id_root->newid) || id_root->newid->lib == owner_library))
if (is_resync || id_root == nullptr || id_root->newid == nullptr) {
/* Instantiating the root collection or object should never be needed in resync case, since the
* old override would be remapped to the new one. */
}
else if (ID_IS_LINKED(id_root->newid) && id_root->newid->lib != owner_library) {
/* No instantiation in case the root override is linked data, unless it is part of the given
* owner library.
*
* NOTE: that last case should never happen actually in current code? Since non-NULL owner
* library should only happen in case of recursive resync, which is already excluded by the
* previous condition. */
}
else if ((id_root->newid->override_library->flag & LIBOVERRIDE_FLAG_NO_HIERARCHY) == 0 &&
id_root->newid->override_library->hierarchy_root != id_root->newid)
{
/* No instantiation in case this is not a hierarchy root, as it can be assumed already handled
* as part of hierarchy processing. */
}
else {
switch (GS(id_root->name)) {
case ID_GR: {
Object *ob_reference = id_instance_hint != nullptr && GS(id_instance_hint->name) == ID_OB ?

View File

@ -72,118 +72,63 @@ void BKE_main_free(Main *mainvar)
#if 1
BKE_id_free_ex(mainvar, id, free_flag, false);
#else
/* errors freeing ID's can be hard to track down,
* enable this so valgrind will give the line number in its error log */
switch (a) {
case 0:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 1:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 2:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 3:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 4:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 5:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 6:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 7:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 8:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 9:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 10:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 11:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 12:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 13:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 14:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 15:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 16:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 17:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 18:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 19:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 20:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 21:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 22:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 23:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 24:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 25:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 26:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 27:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 28:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 29:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 30:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 31:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 32:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 33:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
case 34:
BKE_id_free_ex(mainvar, id, free_flag, false);
break;
default:
/* Errors freeing ID's can be hard to track down,
* enable this so VALGRIND or ASAN will give the line number in its error log. */
# define CASE_ID_INDEX(id_index) \
case id_index: \
BKE_id_free_ex(mainvar, id, free_flag, false); \
break
switch ((eID_Index)a) {
CASE_ID_INDEX(INDEX_ID_LI);
CASE_ID_INDEX(INDEX_ID_IP);
CASE_ID_INDEX(INDEX_ID_AC);
CASE_ID_INDEX(INDEX_ID_GD_LEGACY);
CASE_ID_INDEX(INDEX_ID_NT);
CASE_ID_INDEX(INDEX_ID_VF);
CASE_ID_INDEX(INDEX_ID_TXT);
CASE_ID_INDEX(INDEX_ID_SO);
CASE_ID_INDEX(INDEX_ID_MSK);
CASE_ID_INDEX(INDEX_ID_IM);
CASE_ID_INDEX(INDEX_ID_MC);
CASE_ID_INDEX(INDEX_ID_TE);
CASE_ID_INDEX(INDEX_ID_MA);
CASE_ID_INDEX(INDEX_ID_LS);
CASE_ID_INDEX(INDEX_ID_WO);
CASE_ID_INDEX(INDEX_ID_CF);
CASE_ID_INDEX(INDEX_ID_SIM);
CASE_ID_INDEX(INDEX_ID_PA);
CASE_ID_INDEX(INDEX_ID_KE);
CASE_ID_INDEX(INDEX_ID_AR);
CASE_ID_INDEX(INDEX_ID_ME);
CASE_ID_INDEX(INDEX_ID_CU_LEGACY);
CASE_ID_INDEX(INDEX_ID_MB);
CASE_ID_INDEX(INDEX_ID_CV);
CASE_ID_INDEX(INDEX_ID_PT);
CASE_ID_INDEX(INDEX_ID_VO);
CASE_ID_INDEX(INDEX_ID_LT);
CASE_ID_INDEX(INDEX_ID_LA);
CASE_ID_INDEX(INDEX_ID_CA);
CASE_ID_INDEX(INDEX_ID_SPK);
CASE_ID_INDEX(INDEX_ID_LP);
CASE_ID_INDEX(INDEX_ID_OB);
CASE_ID_INDEX(INDEX_ID_GR);
CASE_ID_INDEX(INDEX_ID_PAL);
CASE_ID_INDEX(INDEX_ID_PC);
CASE_ID_INDEX(INDEX_ID_BR);
CASE_ID_INDEX(INDEX_ID_SCE);
CASE_ID_INDEX(INDEX_ID_SCR);
CASE_ID_INDEX(INDEX_ID_WS);
CASE_ID_INDEX(INDEX_ID_WM);
case INDEX_ID_NULL: {
BLI_assert_unreachable();
break;
}
}
# undef CASE_ID_INDEX
#endif
}
BLI_listbase_clear(lb);

View File

@ -140,6 +140,7 @@ static void material_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const
* (the kind of data that would have to be copied).
*
* \note Keep in sync with #material_free_data.
* \note Doesn't handle animation data (`ma->adt`).
*/
static void material_clear_data(ID *id)
{
@ -1932,11 +1933,30 @@ void ramp_blend(int type, float r_col[3], const float fac, const float col[3])
}
}
/**
* \brief copy/paste buffer, if we had a proper py api that would be better
* \note matcopybuf.nodetree does _NOT_ use ID's
* \todo matcopybuf.nodetree's node->id's are NOT validated, this will crash!
*/
/* -------------------------------------------------------------------- */
/** \name Material Copy/Paste
*
* As materials may reference other data, the clipboard only stores a subset of all possible data.
* The material and it's node-tree are stored and nothing else.
* Notably the following variables are *not* part of the clipboard.
*
* - The #ID (name, fake-user, custom-properties .. etc).
* - Animation data (#Material::adt, #bNodeTree::adt).
* - Texture paint slots (#Material::texpaintslot)
* as this is cache and references other ID's.
* - Grease pencil style (#Material::gp_style)
* could be supported but ID's and pointers would need to be handled carefully.
*
* When pasting, some data in the destination material is left as-is:
* - The #ID.
* - Animation data, with the exception that pasting a material without a node-tree
* will clear the existing materials node-tree & its animation.
* Note that applying existing animation to the pasted material might not make sense
* and may reference data-paths that don't resolve (depending on the kind of material).
* The user might need to clear the animation in this case.
*
* \{ */
static Material matcopybuf;
static short matcopied = 0;
@ -1949,18 +1969,35 @@ void BKE_material_copybuf_clear(void)
matcopied = 0;
}
/**
* Some members should *never* be set, ensure this is always the case.
* Call at the beginning & end of functions that manipulate the clipboard.
*/
static void material_copybuf_assert_is_valid()
{
BLI_assert(!matcopybuf.id.icon_id);
BLI_assert(!matcopybuf.id.py_instance);
BLI_assert(!matcopybuf.adt);
BLI_assert(!matcopybuf.preview);
if (matcopybuf.nodetree) {
BLI_assert(!matcopybuf.nodetree->id.py_instance);
BLI_assert(!matcopybuf.nodetree->adt);
BLI_assert(!matcopybuf.nodetree->owner_id);
}
}
void BKE_material_copybuf_free(void)
{
BLI_assert(matcopybuf.id.icon_id == 0);
if (matcopybuf.nodetree) {
BLI_assert(!matcopybuf.nodetree->id.py_instance); /* Or call #BKE_libblock_free_data_py. */
}
material_copybuf_assert_is_valid();
material_free_data(&matcopybuf.id);
matcopied = 0;
}
void BKE_material_copybuf_copy(Main *bmain, Material *ma)
{
material_copybuf_assert_is_valid();
if (matcopied) {
BKE_material_copybuf_free();
}
@ -1974,43 +2011,92 @@ void BKE_material_copybuf_copy(Main *bmain, Material *ma)
/* Ensure dangling pointers are never copied back into a material. */
material_clear_data(&matcopybuf.id);
/* Unhandled by materials generic data functions. */
matcopybuf.adt = nullptr;
if (ma->nodetree != nullptr) {
/* Never copy animation data. */
struct {
AnimData *adt;
} backup;
backup.adt = ma->nodetree->adt;
ma->nodetree->adt = nullptr;
matcopybuf.nodetree = blender::bke::ntreeCopyTree_ex(ma->nodetree, bmain, false);
matcopybuf.nodetree->owner_id = nullptr;
ma->nodetree->adt = backup.adt;
}
/* TODO: Duplicate Engine Settings and set runtime to nullptr. */
matcopied = 1;
material_copybuf_assert_is_valid();
}
void BKE_material_copybuf_paste(Main *bmain, Material *ma)
bool BKE_material_copybuf_paste(Main *bmain, Material *ma)
{
ID id;
material_copybuf_assert_is_valid();
if (matcopied == 0) {
return;
return false;
}
/* `matcopybuf` never has animation data, no need to check. */
const bool has_animdata = (ma->adt != nullptr || (ma->nodetree && ma->nodetree->adt));
const bool has_node_tree = (ma->nodetree || matcopybuf.nodetree);
AnimData *backup_nodetree_adt = nullptr;
if (ma->nodetree && matcopybuf.nodetree) {
/* Keep data to apply back to the new node-tree. */
std::swap(backup_nodetree_adt, ma->nodetree->adt);
}
/* Handles freeing nodes and and other run-time data (previews) for e.g. */
material_free_data(&ma->id);
id = (ma->id);
*ma = blender::dna::shallow_copy(matcopybuf);
(ma->id) = id;
/* Copy from `matcopybuf` preserving some members.
* NOTE: animation data isn't stored in the clipboard, any existing animation will be left as-is.
* Any undesired animation will have to be manually cleared by the user. */
{
struct {
ID id;
AnimData *adt;
} backup;
backup.id = ma->id;
backup.adt = ma->adt;
*ma = blender::dna::shallow_copy(matcopybuf);
ma->id = backup.id;
ma->adt = backup.adt;
}
if (matcopybuf.nodetree != nullptr) {
BLI_assert(matcopybuf.nodetree->adt == nullptr);
ma->nodetree = blender::bke::ntreeCopyTree_ex(matcopybuf.nodetree, bmain, false);
ma->nodetree->owner_id = &ma->id;
/* Restore animation pointer (if set). */
BLI_assert(ma->nodetree->adt == nullptr);
ma->nodetree->adt = backup_nodetree_adt;
}
if (has_node_tree) {
if (has_node_tree || has_animdata) {
/* Important to run this when the embedded tree if freed,
* otherwise the depsgraph holds a reference to the (now freed) `ma->nodetree`.
* Also run this when a new node-tree is set to ensure it's accounted for. */
* Also run this when a new node-tree is set to ensure it's accounted for.
* This also applies to animation data which is likely to be stored in the depsgraph. */
DEG_relations_tag_update(bmain);
}
material_copybuf_assert_is_valid();
return true;
}
/** \} */
void BKE_material_eval(struct Depsgraph *depsgraph, Material *material)
{
DEG_debug_print_eval(depsgraph, __func__, material->id.name, material);

View File

@ -279,7 +279,6 @@ class BMeshFairingContext : public FairingContext {
/* This initializes both the bmloop and the vlmap for bmesh in a single loop. */
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
int loop_count = 0;
const int vert_index = BM_elem_index_get(v);
vert_to_loop_offsets_[vert_index] = index_iter;
BM_ITER_ELEM (l, &loop_iter, v, BM_LOOPS_OF_VERT) {
@ -287,7 +286,6 @@ class BMeshFairingContext : public FairingContext {
bmloop_[loop_index] = l;
vert_to_loop_indices_[index_iter] = loop_index;
index_iter++;
loop_count++;
}
}
vert_to_loop_offsets_.last() = index_iter;

View File

@ -430,12 +430,14 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
if (j > src_poly.start()) {
mirrorj += result_polys[mirror_i].size() - (j - src_poly.start());
}
const blender::float3 orig_normal = loop_normals[mirrorj];
copy_v3_v3(loop_normals[mirrorj], loop_normals[j]);
mul_m4_v3(mtx_nor, loop_normals[mirrorj]);
const int space_index = lnors_spacearr.corner_space_indices[mirrorj];
blender::bke::mesh::lnor_space_custom_normal_to_data(&lnors_spacearr.spaces[space_index],
loop_normals[mirrorj],
orig_normal,
loop_normals[mirrorj],
clnors[mirrorj]);
}

View File

@ -1933,6 +1933,7 @@ void BKE_sculpt_color_layer_create_if_needed(Object *object)
}
BKE_id_attributes_active_color_set(&orig_me->id, unique_name);
BKE_id_attributes_default_color_set(&orig_me->id, unique_name);
DEG_id_tag_update(&orig_me->id, ID_RECALC_GEOMETRY_ALL_MODES);
BKE_mesh_tessface_clear(orig_me);

View File

@ -10,6 +10,7 @@
#include "DNA_ID.h"
#include "DNA_defaults.h"
#include "DNA_modifier_types.h"
#include "DNA_scene_types.h"
#include "DNA_simulation_types.h"
@ -24,15 +25,18 @@
#include "BKE_anim_data.h"
#include "BKE_animsys.h"
#include "BKE_collection.h"
#include "BKE_customdata.h"
#include "BKE_idtype.h"
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
#include "BKE_lib_remap.h"
#include "BKE_main.h"
#include "BKE_modifier.h"
#include "BKE_node.hh"
#include "BKE_pointcache.h"
#include "BKE_simulation.h"
#include "BKE_simulation_state.hh"
#include "NOD_geometry.h"
@ -181,3 +185,17 @@ void BKE_simulation_data_update(Depsgraph * /*depsgraph*/,
Simulation * /*simulation*/)
{
}
void BKE_simulation_reset_scene(Scene *scene)
{
FOREACH_SCENE_OBJECT_BEGIN (scene, ob) {
LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
if (md->type != eModifierType_Nodes) {
continue;
}
NodesModifierData *nmd = (NodesModifierData *)md;
nmd->simulation_cache->reset();
}
}
FOREACH_SCENE_OBJECT_END;
}

View File

@ -2766,16 +2766,20 @@ void MATERIAL_OT_copy(wmOperatorType *ot)
/** \name Material Paste Operator
* \{ */
static int paste_material_exec(bContext *C, wmOperator * /*op*/)
static int paste_material_exec(bContext *C, wmOperator *op)
{
Material *ma = static_cast<Material *>(
CTX_data_pointer_get_type(C, "material", &RNA_Material).data);
if (ma == nullptr) {
BKE_report(op->reports, RPT_WARNING, "Cannot paste without a material");
return OPERATOR_CANCELLED;
}
BKE_material_copybuf_paste(CTX_data_main(C), ma);
if (!BKE_material_copybuf_paste(CTX_data_main(C), ma)) {
BKE_report(op->reports, RPT_WARNING, "No material in the internal clipboard to paste");
return OPERATOR_CANCELLED;
}
DEG_id_tag_update(&ma->id, ID_RECALC_COPY_ON_WRITE);
WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, ma);

View File

@ -548,6 +548,36 @@ static const EnumPropertyItem prop_lib_op_selection_set[] = {
{0, nullptr, 0, nullptr, nullptr},
};
static bool outliner_do_libdata_operation_selection_set_element(
bContext *C,
ReportList *reports,
Scene *scene,
TreeElement *element,
TreeStoreElem *tselem,
const bool has_parent_selected,
outliner_operation_fn operation_fn,
eOutlinerLibOpSelectionSet selection_set,
void *user_data)
{
const bool do_selected = ELEM(selection_set,
OUTLINER_LIB_SELECTIONSET_SELECTED,
OUTLINER_LIB_LIB_SELECTIONSET_SELECTED_AND_CONTENT);
const bool do_content = ELEM(selection_set,
OUTLINER_LIB_LIB_SELECTIONSET_CONTENT,
OUTLINER_LIB_LIB_SELECTIONSET_SELECTED_AND_CONTENT);
const bool is_selected = tselem->flag & TSE_SELECTED;
if ((is_selected && do_selected) || (has_parent_selected && do_content)) {
if (((tselem->type == TSE_SOME_ID) && (element->idcode != 0)) ||
tselem->type == TSE_LAYER_COLLECTION)
{
TreeStoreElem *tsep = element->parent ? TREESTORE(element->parent) : nullptr;
operation_fn(C, reports, scene, element, tsep, tselem, user_data);
}
}
return is_selected;
}
static void outliner_do_libdata_operation_selection_set(bContext *C,
ReportList *reports,
Scene *scene,
@ -558,27 +588,21 @@ static void outliner_do_libdata_operation_selection_set(bContext *C,
eOutlinerLibOpSelectionSet selection_set,
void *user_data)
{
const bool do_selected = ELEM(selection_set,
OUTLINER_LIB_SELECTIONSET_SELECTED,
OUTLINER_LIB_LIB_SELECTIONSET_SELECTED_AND_CONTENT);
const bool do_content = ELEM(selection_set,
OUTLINER_LIB_LIB_SELECTIONSET_CONTENT,
OUTLINER_LIB_LIB_SELECTIONSET_SELECTED_AND_CONTENT);
LISTBASE_FOREACH_MUTABLE (TreeElement *, element, &subtree) {
/* Get needed data out in case element gets freed. */
TreeStoreElem *tselem = TREESTORE(element);
const ListBase subtree = element->subtree;
bool is_selected = tselem->flag & TSE_SELECTED;
if ((is_selected && do_selected) || (has_parent_selected && do_content)) {
if (((tselem->type == TSE_SOME_ID) && (element->idcode != 0)) ||
tselem->type == TSE_LAYER_COLLECTION)
{
TreeStoreElem *tsep = element->parent ? TREESTORE(element->parent) : nullptr;
operation_fn(C, reports, scene, element, tsep, tselem, user_data);
}
}
const bool is_selected = outliner_do_libdata_operation_selection_set_element(
C,
reports,
scene,
element,
tselem,
has_parent_selected,
operation_fn,
selection_set,
user_data);
/* Don't access element from now on, it may be freed. Note that the open/collapsed state may
* also have been changed in the visitor callback. */
@ -600,8 +624,40 @@ static void outliner_do_libdata_operation_selection_set(bContext *C,
SpaceOutliner *space_outliner,
outliner_operation_fn operation_fn,
eOutlinerLibOpSelectionSet selection_set,
void *user_data)
void *user_data,
const bool do_active_element_first)
{
if (do_active_element_first) {
TreeElement *active_element = outliner_find_element_with_flag(&space_outliner->tree,
TSE_ACTIVE);
if (active_element != nullptr) {
TreeStoreElem *tselem = TREESTORE(active_element);
const ListBase subtree = active_element->subtree;
const bool is_selected = outliner_do_libdata_operation_selection_set_element(C,
reports,
scene,
active_element,
tselem,
false,
operation_fn,
selection_set,
user_data);
/* Don't access element from now on, it may be freed. Note that the open/collapsed state may
* also have been changed in the visitor callback. */
outliner_do_libdata_operation_selection_set(C,
reports,
scene,
space_outliner,
subtree,
is_selected,
operation_fn,
selection_set,
user_data);
}
}
outliner_do_libdata_operation_selection_set(C,
reports,
scene,
@ -1046,16 +1102,26 @@ static void id_override_library_create_hierarchy_pre_process_fn(bContext *C,
}
if (!ID_IS_OVERRIDABLE_LIBRARY_HIERARCHY(id_root_reference)) {
BKE_reportf(reports,
RPT_WARNING,
"Could not create library override from data-block '%s', as it is not overridable",
id_root_reference->name);
if (ID_IS_LINKED(id_root_reference)) {
BKE_reportf(
reports,
RPT_WARNING,
"Could not create library override from data-block '%s', as it is not overridable",
id_root_reference->name);
}
/* Else it's a local ID, do not bother reporting this, as it gets annoyingly noisy then when
* operated e.g. on a hierarchy of liboverrides. */
return;
}
BLI_assert(do_hierarchy);
UNUSED_VARS_NDEBUG(do_hierarchy);
/* Only process a given ID once. Otherwise, all kind of weird things can happen if e.g. a
* selected sub-collection is part of more than one override hierarchies. */
if (data->selected_id_uid.contains(id_root_reference->session_uuid)) {
return;
}
data->selected_id_uid.add(id_root_reference->session_uuid);
if (ID_IS_OVERRIDE_LIBRARY_REAL(id_root_reference) && !ID_IS_LINKED(id_root_reference)) {
@ -1806,7 +1872,8 @@ static int outliner_liboverride_operation_exec(bContext *C, wmOperator *op)
space_outliner,
id_override_library_create_hierarchy_pre_process_fn,
selection_set,
&override_data);
&override_data,
true);
id_override_library_create_hierarchy_process(C, op->reports, override_data);
@ -1821,7 +1888,8 @@ static int outliner_liboverride_operation_exec(bContext *C, wmOperator *op)
space_outliner,
id_override_library_reset_fn,
selection_set,
&override_data);
&override_data,
false);
ED_undo_push(C, "Reset Overridden Data");
break;
}
@ -1832,7 +1900,8 @@ static int outliner_liboverride_operation_exec(bContext *C, wmOperator *op)
space_outliner,
id_override_library_clear_single_fn,
selection_set,
nullptr);
nullptr,
false);
ED_undo_push(C, "Clear Overridden Data");
break;
}
@ -1846,7 +1915,8 @@ static int outliner_liboverride_operation_exec(bContext *C, wmOperator *op)
space_outliner,
id_override_library_resync_fn,
OUTLINER_LIB_SELECTIONSET_SELECTED,
&override_data);
&override_data,
false);
id_override_library_resync_hierarchy_process(C, op->reports, override_data);
@ -1863,7 +1933,8 @@ static int outliner_liboverride_operation_exec(bContext *C, wmOperator *op)
space_outliner,
id_override_library_resync_fn,
OUTLINER_LIB_SELECTIONSET_SELECTED,
&override_data);
&override_data,
false);
id_override_library_resync_hierarchy_process(C, op->reports, override_data);
@ -1879,7 +1950,8 @@ static int outliner_liboverride_operation_exec(bContext *C, wmOperator *op)
space_outliner,
id_override_library_delete_hierarchy_fn,
OUTLINER_LIB_SELECTIONSET_SELECTED,
&override_data);
&override_data,
false);
id_override_library_delete_hierarchy_process(C, op->reports, override_data);

View File

@ -22,16 +22,16 @@ set(INC_SYS
)
set(SRC
uvedit_buttons.c
uvedit_buttons.cc
uvedit_clipboard.cc
uvedit_clipboard_graph_iso.cc
uvedit_draw.c
uvedit_draw.cc
uvedit_islands.cc
uvedit_ops.c
uvedit_path.c
uvedit_rip.c
uvedit_select.c
uvedit_smart_stitch.c
uvedit_ops.cc
uvedit_path.cc
uvedit_rip.cc
uvedit_select.cc
uvedit_smart_stitch.cc
uvedit_unwrap_ops.cc
uvedit_clipboard_graph_iso.hh

View File

@ -5,8 +5,8 @@
* \ingroup eduv
*/
#include <stdio.h>
#include <string.h>
#include <cstdio>
#include <cstring>
#include "MEM_guardedalloc.h"
@ -198,7 +198,7 @@ static void uvedit_vertex_buttons(const bContext *C, uiBlock *block)
MEM_freeN(objects);
}
static void do_uvedit_vertex(bContext *C, void *UNUSED(arg), int event)
static void do_uvedit_vertex(bContext *C, void * /*arg*/, int event)
{
SpaceImage *sima = CTX_wm_space_image(C);
Scene *scene = CTX_data_scene(C);
@ -238,7 +238,7 @@ static void do_uvedit_vertex(bContext *C, void *UNUSED(arg), int event)
/* Panels */
static bool image_panel_uv_poll(const bContext *C, PanelType *UNUSED(pt))
static bool image_panel_uv_poll(const bContext *C, PanelType * /*pt*/)
{
SpaceImage *sima = CTX_wm_space_image(C);
if (sima->mode != SI_MODE_UV) {
@ -253,16 +253,15 @@ static void image_panel_uv(const bContext *C, Panel *panel)
uiBlock *block;
block = uiLayoutAbsoluteBlock(panel->layout);
UI_block_func_handle_set(block, do_uvedit_vertex, NULL);
UI_block_func_handle_set(block, do_uvedit_vertex, nullptr);
uvedit_vertex_buttons(C, block);
}
void ED_uvedit_buttons_register(ARegionType *art)
{
PanelType *pt;
PanelType *pt = MEM_cnew<PanelType>(__func__);
pt = MEM_callocN(sizeof(PanelType), "spacetype image panel uv");
strcpy(pt->idname, "IMAGE_PT_uv");
strcpy(pt->label, N_("UV Vertex")); /* XXX C panels unavailable through RNA bpy.types! */
/* Could be 'Item' matching 3D view, avoid new tab for two buttons. */

View File

@ -237,7 +237,7 @@ static uint8_t select_next_v(uint8_t *left, uint8_t *bd)
return min;
}
static uint8_t find_min_value(uint8_t *arr, uint8_t start_idx, uint8_t len)
static uint8_t find_min_value(const uint8_t *arr, uint8_t start_idx, uint8_t len)
{
uint8_t min_v = UINT8_MAX;
for (int i = 0; i < len; i++) {
@ -290,7 +290,7 @@ static void select_bidomain(
}
}
static uint8_t select_next_w(uint8_t *right, uint8_t *bd)
static uint8_t select_next_w(const uint8_t *right, uint8_t *bd)
{
uint8_t min = UINT8_MAX;
uint8_t idx = UINT8_MAX;

View File

@ -65,7 +65,7 @@ struct SharedUVLoopData {
static bool bm_loop_uv_shared_edge_check(const BMLoop *l_a, const BMLoop *l_b, void *user_data)
{
const struct SharedUVLoopData *data = static_cast<const struct SharedUVLoopData *>(user_data);
const SharedUVLoopData *data = static_cast<const SharedUVLoopData *>(user_data);
if (data->use_seams) {
if (BM_elem_flag_test(l_a->e, BM_ELEM_SEAM)) {
@ -131,7 +131,7 @@ int bm_mesh_calc_uv_islands(const Scene *scene,
BM_elem_flag_set(f, BM_ELEM_TAG, face_affected);
}
struct SharedUVLoopData user_data = {{0}};
SharedUVLoopData user_data = {{0}};
user_data.offsets = uv_offsets;
user_data.use_seams = use_seams;
@ -156,8 +156,7 @@ int bm_mesh_calc_uv_islands(const Scene *scene,
faces[j] = BM_face_at_index(bm, groups_array[faces_start + j]);
}
struct FaceIsland *island = static_cast<struct FaceIsland *>(
MEM_callocN(sizeof(*island), __func__));
FaceIsland *island = static_cast<FaceIsland *>(MEM_callocN(sizeof(*island), __func__));
island->faces = faces;
island->faces_len = faces_len;
island->offsets = uv_offsets;

View File

@ -5,9 +5,9 @@
* \ingroup eduv
*/
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include "MEM_guardedalloc.h"
@ -20,7 +20,6 @@
#include "DNA_scene_types.h"
#include "DNA_space_types.h"
#include "BLI_array.h"
#include "BLI_kdtree.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
@ -68,11 +67,11 @@ bool ED_uvedit_test(Object *obedit)
int ret;
if (!obedit) {
return 0;
return false;
}
if (obedit->type != OB_MESH) {
return 0;
return false;
}
em = BKE_editmesh_from_object(obedit);
@ -86,9 +85,9 @@ static int UNUSED_FUNCTION(ED_operator_uvmap_mesh)(bContext *C)
Object *ob = CTX_data_active_object(C);
if (ob && ob->type == OB_MESH) {
Mesh *me = ob->data;
Mesh *me = static_cast<Mesh *>(ob->data);
if (CustomData_get_layer(&me->ldata, CD_PROP_FLOAT2) != NULL) {
if (CustomData_get_layer(&me->ldata, CD_PROP_FLOAT2) != nullptr) {
return 1;
}
}
@ -116,8 +115,8 @@ bool ED_object_get_active_image(Object *ob,
{
Material *ma = DEG_is_evaluated_object(ob) ? BKE_object_material_get_eval(ob, mat_nr) :
BKE_object_material_get(ob, mat_nr);
bNodeTree *ntree = (ma && ma->use_nodes) ? ma->nodetree : NULL;
bNode *node = (ntree) ? nodeGetActiveTexture(ntree) : NULL;
bNodeTree *ntree = (ma && ma->use_nodes) ? ma->nodetree : nullptr;
bNode *node = (ntree) ? nodeGetActiveTexture(ntree) : nullptr;
if (node && is_image_texture_node(node)) {
if (r_ima) {
@ -131,7 +130,7 @@ bool ED_object_get_active_image(Object *ob,
*r_iuser = &((NodeTexEnvironment *)node->storage)->iuser;
}
else {
*r_iuser = NULL;
*r_iuser = nullptr;
}
}
if (r_node) {
@ -144,10 +143,10 @@ bool ED_object_get_active_image(Object *ob,
}
if (r_ima) {
*r_ima = NULL;
*r_ima = nullptr;
}
if (r_iuser) {
*r_iuser = NULL;
*r_iuser = nullptr;
}
if (r_node) {
*r_node = node;
@ -162,11 +161,11 @@ bool ED_object_get_active_image(Object *ob,
void ED_object_assign_active_image(Main *bmain, Object *ob, int mat_nr, Image *ima)
{
Material *ma = BKE_object_material_get(ob, mat_nr);
bNode *node = (ma && ma->use_nodes) ? nodeGetActiveTexture(ma->nodetree) : NULL;
bNode *node = (ma && ma->use_nodes) ? nodeGetActiveTexture(ma->nodetree) : nullptr;
if (node && is_image_texture_node(node)) {
node->id = &ima->id;
ED_node_tree_propagate_change(NULL, bmain, ma->nodetree);
ED_node_tree_propagate_change(nullptr, bmain, ma->nodetree);
}
}
@ -279,7 +278,7 @@ static bool ED_uvedit_median_multi(const Scene *scene,
}
}
mul_v2_fl(co, 1.0f / (float)sel);
mul_v2_fl(co, 1.0f / float(sel));
return (sel != 0);
}
@ -317,10 +316,10 @@ bool ED_uvedit_center_from_pivot_ex(SpaceImage *sima,
case V3D_AROUND_CURSOR: {
copy_v2_v2(r_center, sima->cursor);
changed = true;
if (r_has_select != NULL) {
if (r_has_select != nullptr) {
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
scene, view_layer, ((View3D *)NULL), &objects_len);
scene, view_layer, ((View3D *)nullptr), &objects_len);
*r_has_select = uvedit_select_is_any_selected_multi(scene, objects, objects_len);
MEM_freeN(objects);
}
@ -329,10 +328,10 @@ bool ED_uvedit_center_from_pivot_ex(SpaceImage *sima,
default: {
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
scene, view_layer, ((View3D *)NULL), &objects_len);
scene, view_layer, ((View3D *)nullptr), &objects_len);
changed = ED_uvedit_center_multi(scene, objects, objects_len, r_center, mode);
MEM_freeN(objects);
if (r_has_select != NULL) {
if (r_has_select != nullptr) {
*r_has_select = changed;
}
break;
@ -344,7 +343,7 @@ bool ED_uvedit_center_from_pivot_ex(SpaceImage *sima,
bool ED_uvedit_center_from_pivot(
SpaceImage *sima, Scene *scene, ViewLayer *view_layer, float r_center[2], char mode)
{
return ED_uvedit_center_from_pivot_ex(sima, scene, view_layer, r_center, mode, NULL);
return ED_uvedit_center_from_pivot_ex(sima, scene, view_layer, r_center, mode, nullptr);
}
/** \} */
@ -353,7 +352,7 @@ bool ED_uvedit_center_from_pivot(
/** \name Weld Align Operator
* \{ */
typedef enum eUVWeldAlign {
enum eUVWeldAlign {
UV_STRAIGHTEN,
UV_STRAIGHTEN_X,
UV_STRAIGHTEN_Y,
@ -361,7 +360,7 @@ typedef enum eUVWeldAlign {
UV_ALIGN_X,
UV_ALIGN_Y,
UV_WELD,
} eUVWeldAlign;
};
static bool uvedit_uv_align_weld(Scene *scene,
BMesh *bm,
@ -384,7 +383,7 @@ static bool uvedit_uv_align_weld(Scene *scene,
if (!uvedit_uv_select_test(scene, l, offsets)) {
continue;
}
float *luv = BM_ELEM_CD_GET_VOID_P(l, offsets.uv);
float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
if (ELEM(tool, UV_ALIGN_X, UV_WELD)) {
if (luv[0] != cent[0]) {
luv[0] = cent[0];
@ -403,11 +402,12 @@ static bool uvedit_uv_align_weld(Scene *scene,
}
/** Bitwise-or together, then choose loop with highest value. */
typedef enum eUVEndPointPrecedence {
enum eUVEndPointPrecedence {
UVEP_INVALID = 0,
UVEP_SELECTED = (1 << 0),
UVEP_PINNED = (1 << 1), /* i.e. Pinned verts are preferred to selected. */
} eUVEndPointPrecedence;
};
ENUM_OPERATORS(eUVEndPointPrecedence, UVEP_PINNED);
static eUVEndPointPrecedence uvedit_line_update_get_precedence(const bool pinned)
{
@ -538,7 +538,7 @@ static bool uvedit_uv_straighten(Scene *scene, BMesh *bm, eUVWeldAlign tool)
}
UvElementMap *element_map = BM_uv_element_map_create(bm, scene, true, false, true, true);
if (element_map == NULL) {
if (element_map == nullptr) {
return false;
}
@ -567,7 +567,7 @@ static void uv_weld_align(bContext *C, eUVWeldAlign tool)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
scene, view_layer, ((View3D *)NULL), &objects_len);
scene, view_layer, ((View3D *)nullptr), &objects_len);
if (tool == UV_ALIGN_AUTO) {
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
@ -621,7 +621,7 @@ static void uv_weld_align(bContext *C, eUVWeldAlign tool)
if (changed) {
uvedit_live_unwrap_update(sima, scene, obedit);
DEG_id_tag_update(obedit->data, 0);
DEG_id_tag_update(static_cast<ID *>(obedit->data), 0);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
}
}
@ -631,7 +631,7 @@ static void uv_weld_align(bContext *C, eUVWeldAlign tool)
static int uv_align_exec(bContext *C, wmOperator *op)
{
uv_weld_align(C, RNA_enum_get(op->ptr, "axis"));
uv_weld_align(C, eUVWeldAlign(RNA_enum_get(op->ptr, "axis")));
return OPERATOR_FINISHED;
}
@ -661,7 +661,7 @@ static void UV_OT_align(wmOperatorType *ot)
"Automatically choose the axis on which there is most alignment already"},
{UV_ALIGN_X, "ALIGN_X", 0, "Align X", "Align UVs on X axis"},
{UV_ALIGN_Y, "ALIGN_Y", 0, "Align Y", "Align UVs on Y axis"},
{0, NULL, 0, NULL, NULL},
{0, nullptr, 0, nullptr, nullptr},
};
/* identifiers */
@ -697,14 +697,14 @@ static int uv_remove_doubles_to_selected(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
scene, view_layer, ((View3D *)NULL), &objects_len);
scene, view_layer, ((View3D *)nullptr), &objects_len);
bool *changed = MEM_callocN(sizeof(bool) * objects_len, "uv_remove_doubles_selected.changed");
bool *changed = static_cast<bool *>(MEM_callocN(sizeof(bool) * objects_len, __func__));
/* Maximum index of an objects[i]'s UVs in UV_arr.
* It helps find which UV in *mloopuv_arr belongs to which object. */
uint *ob_mloopuv_max_idx = MEM_callocN(sizeof(uint) * objects_len,
"uv_remove_doubles_selected.ob_mloopuv_max_idx");
uint *ob_mloopuv_max_idx = static_cast<uint *>(
MEM_callocN(sizeof(uint) * objects_len, __func__));
/* Calculate max possible number of kdtree nodes. */
int uv_maxlen = 0;
@ -721,11 +721,8 @@ static int uv_remove_doubles_to_selected(bContext *C, wmOperator *op)
KDTree_2d *tree = BLI_kdtree_2d_new(uv_maxlen);
int *duplicates = NULL;
BLI_array_declare(duplicates);
float **mloopuv_arr = NULL;
BLI_array_declare(mloopuv_arr);
blender::Vector<int> duplicates;
blender::Vector<float *> mloopuv_arr;
int mloopuv_count = 0; /* Also used for *duplicates count. */
@ -751,8 +748,8 @@ static int uv_remove_doubles_to_selected(bContext *C, wmOperator *op)
if (uvedit_uv_select_test(scene, l, offsets)) {
float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
BLI_kdtree_2d_insert(tree, mloopuv_count, luv);
BLI_array_append(duplicates, -1);
BLI_array_append(mloopuv_arr, luv);
duplicates.append(-1);
mloopuv_arr.append(luv);
mloopuv_count++;
}
}
@ -762,12 +759,13 @@ static int uv_remove_doubles_to_selected(bContext *C, wmOperator *op)
}
BLI_kdtree_2d_balance(tree);
int found_duplicates = BLI_kdtree_2d_calc_duplicates_fast(tree, threshold, false, duplicates);
int found_duplicates = BLI_kdtree_2d_calc_duplicates_fast(
tree, threshold, false, duplicates.data());
if (found_duplicates > 0) {
/* Calculate average uv for duplicates. */
int *uv_duplicate_count = MEM_callocN(sizeof(int) * mloopuv_count,
"uv_remove_doubles_selected.uv_duplicate_count");
int *uv_duplicate_count = static_cast<int *>(
MEM_callocN(sizeof(int) * mloopuv_count, __func__));
for (int i = 0; i < mloopuv_count; i++) {
if (duplicates[i] == -1) { /* If doesn't reference another */
uv_duplicate_count[i]++; /* self */
@ -787,7 +785,7 @@ static int uv_remove_doubles_to_selected(bContext *C, wmOperator *op)
continue;
}
mul_v2_fl(mloopuv_arr[i], 1.0f / (float)uv_duplicate_count[i]);
mul_v2_fl(mloopuv_arr[i], 1.0f / float(uv_duplicate_count[i]));
}
MEM_freeN(uv_duplicate_count);
@ -813,15 +811,13 @@ static int uv_remove_doubles_to_selected(bContext *C, wmOperator *op)
if (changed[ob_index]) {
Object *obedit = objects[ob_index];
uvedit_live_unwrap_update(sima, scene, obedit);
DEG_id_tag_update(obedit->data, 0);
DEG_id_tag_update(static_cast<ID *>(obedit->data), 0);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
}
}
}
BLI_kdtree_2d_free(tree);
BLI_array_free(mloopuv_arr);
BLI_array_free(duplicates);
MEM_freeN(changed);
MEM_freeN(objects);
MEM_freeN(ob_mloopuv_max_idx);
@ -841,7 +837,7 @@ static int uv_remove_doubles_to_unselected(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
scene, view_layer, ((View3D *)NULL), &objects_len);
scene, view_layer, ((View3D *)nullptr), &objects_len);
/* Calculate max possible number of kdtree nodes. */
int uv_maxlen = 0;
@ -853,8 +849,7 @@ static int uv_remove_doubles_to_unselected(bContext *C, wmOperator *op)
KDTree_2d *tree = BLI_kdtree_2d_new(uv_maxlen);
float **mloopuv_arr = NULL;
BLI_array_declare(mloopuv_arr);
blender::Vector<float *> mloopuv_arr;
int mloopuv_count = 0;
@ -881,7 +876,7 @@ static int uv_remove_doubles_to_unselected(bContext *C, wmOperator *op)
if (!uvedit_uv_select_test(scene, l, offsets)) {
float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
BLI_kdtree_2d_insert(tree, mloopuv_count, luv);
BLI_array_append(mloopuv_arr, luv);
mloopuv_arr.append(luv);
mloopuv_count++;
}
}
@ -926,13 +921,12 @@ static int uv_remove_doubles_to_unselected(bContext *C, wmOperator *op)
if (changed) {
uvedit_live_unwrap_update(sima, scene, obedit);
DEG_id_tag_update(obedit->data, 0);
DEG_id_tag_update(static_cast<ID *>(obedit->data), 0);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
}
}
BLI_kdtree_2d_free(tree);
BLI_array_free(mloopuv_arr);
MEM_freeN(objects);
return OPERATOR_FINISHED;
@ -968,8 +962,11 @@ static void UV_OT_remove_doubles(wmOperatorType *ot)
"Maximum distance between welded vertices",
0.0f,
1.0f);
RNA_def_boolean(
ot->srna, "use_unselected", 0, "Unselected", "Merge selected to other unselected vertices");
RNA_def_boolean(ot->srna,
"use_unselected",
false,
"Unselected",
"Merge selected to other unselected vertices");
}
/** \} */
@ -978,7 +975,7 @@ static void UV_OT_remove_doubles(wmOperatorType *ot)
/** \name Weld Near Operator
* \{ */
static int uv_weld_exec(bContext *C, wmOperator *UNUSED(op))
static int uv_weld_exec(bContext *C, wmOperator * /*op*/)
{
uv_weld_align(C, UV_WELD);
@ -1049,7 +1046,7 @@ static int uv_snap_cursor_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
scene, view_layer, ((View3D *)NULL), &objects_len);
scene, view_layer, ((View3D *)nullptr), &objects_len);
changed = uv_snap_cursor_to_selection(scene, objects, objects_len, sima);
MEM_freeN(objects);
break;
@ -1075,7 +1072,7 @@ static void UV_OT_snap_cursor(wmOperatorType *ot)
{0, "PIXELS", 0, "Pixels", ""},
{1, "SELECTED", 0, "Selected", ""},
{2, "ORIGIN", 0, "Origin", ""},
{0, NULL, 0, NULL, NULL},
{0, nullptr, 0, nullptr, nullptr},
};
/* identifiers */
@ -1199,7 +1196,7 @@ static bool uv_snap_uvs_to_adjacent_unselected(Scene *scene, Object *obedit)
if (uv_tot) {
luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
mul_v2_v2fl(luv, uv, 1.0f / (float)uv_tot);
mul_v2_v2fl(luv, uv, 1.0f / float(uv_tot));
changed = true;
}
}
@ -1224,8 +1221,8 @@ static bool uv_snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit
const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
ED_space_image_get_size(sima, &width, &height);
w = (float)width;
h = (float)height;
w = float(width);
h = float(height);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (!uvedit_face_visible_test(scene, efa)) {
@ -1257,7 +1254,7 @@ static int uv_snap_selection_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
scene, view_layer, ((View3D *)NULL), &objects_len);
scene, view_layer, ((View3D *)nullptr), &objects_len);
if (target == 2) {
float center[2];
@ -1296,7 +1293,7 @@ static int uv_snap_selection_exec(bContext *C, wmOperator *op)
if (changed) {
changed_multi = true;
uvedit_live_unwrap_update(sima, scene, obedit);
DEG_id_tag_update(obedit->data, 0);
DEG_id_tag_update(static_cast<ID *>(obedit->data), 0);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
}
}
@ -1312,7 +1309,7 @@ static void UV_OT_snap_selected(wmOperatorType *ot)
{1, "CURSOR", 0, "Cursor", ""},
{2, "CURSOR_OFFSET", 0, "Cursor (Offset)", ""},
{3, "ADJACENT_UNSELECTED", 0, "Adjacent Unselected", ""},
{0, NULL, 0, NULL, NULL},
{0, nullptr, 0, nullptr, nullptr},
};
/* identifiers */
@ -1349,7 +1346,7 @@ static int uv_pin_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
scene, view_layer, ((View3D *)NULL), &objects_len);
scene, view_layer, ((View3D *)nullptr), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@ -1380,7 +1377,7 @@ static int uv_pin_exec(bContext *C, wmOperator *op)
if (changed) {
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
DEG_id_tag_update(obedit->data, ID_RECALC_COPY_ON_WRITE);
DEG_id_tag_update(static_cast<ID *>(obedit->data), ID_RECALC_COPY_ON_WRITE);
}
}
MEM_freeN(objects);
@ -1403,7 +1400,7 @@ static void UV_OT_pin(wmOperatorType *ot)
/* properties */
RNA_def_boolean(
ot->srna, "clear", 0, "Clear", "Clear pinning for the selection instead of setting it");
ot->srna, "clear", false, "Clear", "Clear pinning for the selection instead of setting it");
}
/** \} */
@ -1444,7 +1441,7 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
scene, view_layer, ((View3D *)NULL), &objects_len);
scene, view_layer, ((View3D *)nullptr), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
@ -1460,12 +1457,12 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
if (ts->uv_flag & UV_SYNC_SELECTION) {
if (EDBM_mesh_hide(em, swap)) {
EDBM_update(ob->data,
&(const struct EDBMUpdate_Params){
.calc_looptri = true,
.calc_normals = false,
.is_destructive = false,
});
Mesh *me = static_cast<Mesh *>(ob->data);
EDBMUpdate_Params params = {0};
params.calc_looptri = true;
params.calc_normals = false;
params.is_destructive = false;
EDBM_update(me, &params);
}
continue;
}
@ -1569,7 +1566,7 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
BM_select_history_validate(em->bm);
DEG_id_tag_update(ob->data, ID_RECALC_SELECT);
DEG_id_tag_update(static_cast<ID *>(ob->data), ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data);
}
@ -1594,7 +1591,8 @@ static void UV_OT_hide(wmOperatorType *ot)
ot->poll = ED_operator_uvedit;
/* props */
RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected");
RNA_def_boolean(
ot->srna, "unselected", false, "Unselected", "Hide unselected rather than selected");
}
/** \} */
@ -1614,7 +1612,7 @@ static int uv_reveal_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
scene, view_layer, ((View3D *)NULL), &objects_len);
scene, view_layer, ((View3D *)nullptr), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
@ -1636,12 +1634,12 @@ static int uv_reveal_exec(bContext *C, wmOperator *op)
/* call the mesh function if we are in mesh sync sel */
if (ts->uv_flag & UV_SYNC_SELECTION) {
if (EDBM_mesh_reveal(em, select)) {
EDBM_update(ob->data,
&(const struct EDBMUpdate_Params){
.calc_looptri = true,
.calc_normals = false,
.is_destructive = false,
});
Mesh *me = static_cast<Mesh *>(ob->data);
EDBMUpdate_Params params = {0};
params.calc_looptri = true;
params.calc_normals = false;
params.is_destructive = false;
EDBM_update(me, &params);
}
continue;
}
@ -1721,7 +1719,7 @@ static int uv_reveal_exec(bContext *C, wmOperator *op)
/* re-select tagged faces */
BM_mesh_elem_hflag_enable_test(em->bm, BM_FACE, BM_ELEM_SELECT, true, false, BM_ELEM_TAG);
DEG_id_tag_update(ob->data, ID_RECALC_SELECT);
DEG_id_tag_update(static_cast<ID *>(ob->data), ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data);
}
@ -1762,12 +1760,12 @@ static int uv_set_2d_cursor_exec(bContext *C, wmOperator *op)
RNA_float_get_array(op->ptr, "location", sima->cursor);
{
struct wmMsgBus *mbus = CTX_wm_message_bus(C);
wmMsgBus *mbus = CTX_wm_message_bus(C);
bScreen *screen = CTX_wm_screen(C);
WM_msg_publish_rna_prop(mbus, &screen->id, sima, SpaceImageEditor, cursor_location);
}
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_IMAGE, NULL);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_IMAGE, nullptr);
/* Use pass-through to allow click-drag to transform the cursor. */
return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
@ -1808,7 +1806,7 @@ static void UV_OT_cursor_set(wmOperatorType *ot)
RNA_def_float_vector(ot->srna,
"location",
2,
NULL,
nullptr,
-FLT_MAX,
FLT_MAX,
"Location",
@ -1833,7 +1831,7 @@ static int uv_seams_from_islands_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
scene, view_layer, ((View3D *)NULL), &objects_len);
scene, view_layer, ((View3D *)nullptr), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
@ -1913,8 +1911,8 @@ static void UV_OT_seams_from_islands(wmOperatorType *ot)
ot->exec = uv_seams_from_islands_exec;
ot->poll = ED_operator_uvedit;
RNA_def_boolean(ot->srna, "mark_seams", 1, "Mark Seams", "Mark boundary edges as seams");
RNA_def_boolean(ot->srna, "mark_sharp", 0, "Mark Sharp", "Mark boundary edges as sharp");
RNA_def_boolean(ot->srna, "mark_seams", true, "Mark Seams", "Mark boundary edges as seams");
RNA_def_boolean(ot->srna, "mark_sharp", false, "Mark Sharp", "Mark boundary edges as sharp");
}
/** \} */
@ -1938,7 +1936,7 @@ static int uv_mark_seam_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
scene, view_layer, ((View3D *)NULL), &objects_len);
scene, view_layer, ((View3D *)nullptr), &objects_len);
bool changed = false;
@ -1980,7 +1978,7 @@ static int uv_mark_seam_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
static int uv_mark_seam_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
static int uv_mark_seam_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
uiPopupMenu *pup;
uiLayout *layout;

View File

@ -6,9 +6,9 @@
* \note The logic in this file closely follows editmesh_path.c
*/
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include "BLI_linklist.h"
#include "DNA_windowmanager_types.h"
@ -66,7 +66,7 @@ struct PathSelectParams {
bool use_topology_distance;
bool use_face_step;
bool use_fill;
struct CheckerIntervalParams interval_params;
CheckerIntervalParams interval_params;
};
struct UserData_UV {
@ -96,7 +96,7 @@ static void path_select_properties(wmOperatorType *ot)
WM_operator_properties_checker_interval(ot, true);
}
static void path_select_params_from_op(wmOperator *op, struct PathSelectParams *op_params)
static void path_select_params_from_op(wmOperator *op, PathSelectParams *op_params)
{
op_params->track_active = false;
op_params->use_face_step = RNA_boolean_get(op->ptr, "use_face_step");
@ -114,13 +114,13 @@ static void path_select_params_from_op(wmOperator *op, struct PathSelectParams *
/* callbacks */
static bool verttag_filter_cb(BMLoop *l, void *user_data_v)
{
struct UserData_UV *user_data = user_data_v;
UserData_UV *user_data = static_cast<UserData_UV *>(user_data_v);
return uvedit_face_visible_test(user_data->scene, l->f);
}
static bool verttag_test_cb(BMLoop *l, void *user_data_v)
{
/* All connected loops are selected or we return false. */
struct UserData_UV *user_data = user_data_v;
UserData_UV *user_data = static_cast<UserData_UV *>(user_data_v);
const Scene *scene = user_data->scene;
const int cd_loop_uv_offset = user_data->offsets.uv;
const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
@ -140,7 +140,7 @@ static bool verttag_test_cb(BMLoop *l, void *user_data_v)
}
static void verttag_set_cb(BMLoop *l, bool val, void *user_data_v)
{
struct UserData_UV *user_data = user_data_v;
UserData_UV *user_data = static_cast<UserData_UV *>(user_data_v);
const Scene *scene = user_data->scene;
BMEditMesh *em = user_data->em;
const uint cd_loop_uv_offset = user_data->offsets.uv;
@ -159,7 +159,7 @@ static void verttag_set_cb(BMLoop *l, bool val, void *user_data_v)
static int mouse_mesh_uv_shortest_path_vert(Scene *scene,
Object *obedit,
const struct PathSelectParams *op_params,
const PathSelectParams *op_params,
BMLoop *l_src,
BMLoop *l_dst,
const float aspect_y,
@ -169,20 +169,18 @@ static int mouse_mesh_uv_shortest_path_vert(Scene *scene,
BMesh *bm = em->bm;
int flush = 0;
struct UserData_UV user_data = {
.scene = scene,
.em = em,
.offsets = offsets,
};
UserData_UV user_data = {};
user_data.scene = scene;
user_data.em = em;
user_data.offsets = offsets;
const struct BMCalcPathUVParams params = {
.use_topology_distance = op_params->use_topology_distance,
.use_step_face = op_params->use_face_step,
.aspect_y = aspect_y,
.cd_loop_uv_offset = offsets.uv,
};
BMCalcPathUVParams params{};
params.use_topology_distance = op_params->use_topology_distance;
params.use_step_face = op_params->use_face_step;
params.aspect_y = aspect_y;
params.cd_loop_uv_offset = offsets.uv;
LinkNode *path = NULL;
LinkNode *path = nullptr;
bool is_path_ordered = false;
if (l_src != l_dst) {
@ -221,12 +219,12 @@ static int mouse_mesh_uv_shortest_path_vert(Scene *scene,
{
verttag_set_cb((BMLoop *)node->link, !all_set, &user_data);
if (is_path_ordered) {
l_dst_last = node->link;
l_dst_last = static_cast<BMLoop *>(node->link);
}
}
} while ((void)depth++, (node = node->next));
BLI_linklist_free(path, NULL);
BLI_linklist_free(path, nullptr);
flush = all_set ? -1 : 1;
}
else {
@ -249,13 +247,13 @@ static int mouse_mesh_uv_shortest_path_vert(Scene *scene,
/* callbacks */
static bool edgetag_filter_cb(BMLoop *l, void *user_data_v)
{
struct UserData_UV *user_data = user_data_v;
UserData_UV *user_data = static_cast<UserData_UV *>(user_data_v);
return uvedit_face_visible_test(user_data->scene, l->f);
}
static bool edgetag_test_cb(BMLoop *l, void *user_data_v)
{
/* All connected loops (UV) are selected or we return false. */
struct UserData_UV *user_data = user_data_v;
UserData_UV *user_data = static_cast<UserData_UV *>(user_data_v);
const Scene *scene = user_data->scene;
BMIter iter;
BMLoop *l_iter;
@ -272,7 +270,7 @@ static bool edgetag_test_cb(BMLoop *l, void *user_data_v)
}
static void edgetag_set_cb(BMLoop *l, bool val, void *user_data_v)
{
struct UserData_UV *user_data = user_data_v;
UserData_UV *user_data = static_cast<UserData_UV *>(user_data_v);
const Scene *scene = user_data->scene;
BMEditMesh *em = user_data->em;
uvedit_edge_select_set_with_sticky(scene, em, l, val, false, user_data->offsets);
@ -280,7 +278,7 @@ static void edgetag_set_cb(BMLoop *l, bool val, void *user_data_v)
static int mouse_mesh_uv_shortest_path_edge(Scene *scene,
Object *obedit,
const struct PathSelectParams *op_params,
const PathSelectParams *op_params,
BMLoop *l_src,
BMLoop *l_dst,
const float aspect_y,
@ -290,20 +288,18 @@ static int mouse_mesh_uv_shortest_path_edge(Scene *scene,
BMesh *bm = em->bm;
int flush = 0;
struct UserData_UV user_data = {
.scene = scene,
.em = em,
.offsets = offsets,
};
UserData_UV user_data = {};
user_data.scene = scene;
user_data.em = em;
user_data.offsets = offsets;
const struct BMCalcPathUVParams params = {
.use_topology_distance = op_params->use_topology_distance,
.use_step_face = op_params->use_face_step,
.aspect_y = aspect_y,
.cd_loop_uv_offset = offsets.uv,
};
BMCalcPathUVParams params = {};
params.use_topology_distance = op_params->use_topology_distance;
params.use_step_face = op_params->use_face_step;
params.aspect_y = aspect_y;
params.cd_loop_uv_offset = offsets.uv;
LinkNode *path = NULL;
LinkNode *path = nullptr;
bool is_path_ordered = false;
if (l_src != l_dst) {
@ -342,12 +338,12 @@ static int mouse_mesh_uv_shortest_path_edge(Scene *scene,
{
edgetag_set_cb((BMLoop *)node->link, !all_set, &user_data);
if (is_path_ordered) {
l_dst_last = node->link;
l_dst_last = static_cast<BMLoop *>(node->link);
}
}
} while ((void)depth++, (node = node->next));
BLI_linklist_free(path, NULL);
BLI_linklist_free(path, nullptr);
flush = all_set ? -1 : 1;
}
else {
@ -370,13 +366,13 @@ static int mouse_mesh_uv_shortest_path_edge(Scene *scene,
/* callbacks */
static bool facetag_filter_cb(BMFace *f, void *user_data_v)
{
struct UserData_UV *user_data = user_data_v;
UserData_UV *user_data = static_cast<UserData_UV *>(user_data_v);
return uvedit_face_visible_test(user_data->scene, f);
}
static bool facetag_test_cb(BMFace *f, void *user_data_v)
{
/* All connected loops are selected or we return false. */
struct UserData_UV *user_data = user_data_v;
UserData_UV *user_data = static_cast<UserData_UV *>(user_data_v);
const Scene *scene = user_data->scene;
BMIter iter;
BMLoop *l_iter;
@ -389,7 +385,7 @@ static bool facetag_test_cb(BMFace *f, void *user_data_v)
}
static void facetag_set_cb(BMFace *f, bool val, void *user_data_v)
{
struct UserData_UV *user_data = user_data_v;
UserData_UV *user_data = static_cast<UserData_UV *>(user_data_v);
const Scene *scene = user_data->scene;
BMEditMesh *em = user_data->em;
uvedit_face_select_set_with_sticky(scene, em, f, val, false, user_data->offsets);
@ -397,7 +393,7 @@ static void facetag_set_cb(BMFace *f, bool val, void *user_data_v)
static int mouse_mesh_uv_shortest_path_face(Scene *scene,
Object *obedit,
const struct PathSelectParams *op_params,
const PathSelectParams *op_params,
BMFace *f_src,
BMFace *f_dst,
const float aspect_y,
@ -407,20 +403,18 @@ static int mouse_mesh_uv_shortest_path_face(Scene *scene,
BMesh *bm = em->bm;
int flush = 0;
struct UserData_UV user_data = {
.scene = scene,
.em = em,
.offsets = offsets,
};
UserData_UV user_data = {};
user_data.scene = scene;
user_data.em = em;
user_data.offsets = offsets;
const struct BMCalcPathUVParams params = {
.use_topology_distance = op_params->use_topology_distance,
.use_step_face = op_params->use_face_step,
.aspect_y = aspect_y,
.cd_loop_uv_offset = offsets.uv,
};
BMCalcPathUVParams params = {};
params.use_topology_distance = op_params->use_topology_distance;
params.use_step_face = op_params->use_face_step;
params.aspect_y = aspect_y;
params.cd_loop_uv_offset = offsets.uv;
LinkNode *path = NULL;
LinkNode *path = nullptr;
bool is_path_ordered = false;
if (f_src != f_dst) {
@ -459,12 +453,12 @@ static int mouse_mesh_uv_shortest_path_face(Scene *scene,
{
facetag_set_cb((BMFace *)node->link, !all_set, &user_data);
if (is_path_ordered) {
f_dst_last = node->link;
f_dst_last = static_cast<BMFace *>(node->link);
}
}
} while ((void)depth++, (node = node->next));
BLI_linklist_free(path, NULL);
BLI_linklist_free(path, nullptr);
flush = all_set ? -1 : 1;
}
else {
@ -490,7 +484,7 @@ static int uv_shortest_path_pick_exec(bContext *C, wmOperator *op);
static bool uv_shortest_path_pick_ex(Scene *scene,
Depsgraph *depsgraph,
Object *obedit,
const struct PathSelectParams *op_params,
const PathSelectParams *op_params,
BMElem *ele_src,
BMElem *ele_dst,
const float aspect_y,
@ -501,7 +495,7 @@ static bool uv_shortest_path_pick_ex(Scene *scene,
bool ok = false;
int flush = 0;
if (ELEM(NULL, ele_src, ele_dst) || (ele_src->head.htype != ele_dst->head.htype)) {
if (ELEM(nullptr, ele_src, ele_dst) || (ele_src->head.htype != ele_dst->head.htype)) {
/* pass */
}
else if (ele_src->head.htype == BM_FACE) {
@ -534,11 +528,12 @@ static bool uv_shortest_path_pick_ex(Scene *scene,
}
if (ts->uv_flag & UV_SYNC_SELECTION) {
DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
DEG_id_tag_update(static_cast<ID *>(obedit->data), ID_RECALC_SELECT);
}
else {
Object *obedit_eval = DEG_get_evaluated_object(depsgraph, obedit);
BKE_mesh_batch_cache_dirty_tag(obedit_eval->data, BKE_MESH_BATCH_DIRTY_UVEDIT_SELECT);
BKE_mesh_batch_cache_dirty_tag(static_cast<Mesh *>(obedit_eval->data),
BKE_MESH_BATCH_DIRTY_UVEDIT_SELECT);
}
/* Only for region redraw. */
WM_main_add_notifier(NC_GEOM | ND_SELECT, obedit->data);
@ -558,7 +553,7 @@ static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEve
return uv_shortest_path_pick_exec(C, op);
}
struct PathSelectParams op_params;
PathSelectParams op_params;
path_select_params_from_op(op, &op_params);
/* Set false if we support edge tagging. */
@ -568,7 +563,7 @@ static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEve
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
scene, view_layer, NULL, &objects_len);
scene, view_layer, nullptr, &objects_len);
float co[2];
@ -576,7 +571,7 @@ static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEve
UI_view2d_region_to_view(&region->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
BMElem *ele_src = NULL, *ele_dst = NULL;
BMElem *ele_src = nullptr, *ele_dst = nullptr;
/* Detect the hit. */
UvNearestHit hit = uv_nearest_hit_init_max(&region->v2d);
@ -615,20 +610,20 @@ static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEve
}
else if (uv_selectmode & UV_SELECT_EDGE) {
/* Edge selection. */
BMLoop *l_src = NULL;
BMLoop *l_src = nullptr;
if (ts->uv_flag & UV_SYNC_SELECTION) {
BMEdge *e_src = BM_mesh_active_edge_get(bm);
if (e_src != NULL) {
if (e_src != nullptr) {
l_src = uv_find_nearest_loop_from_edge(scene, obedit, e_src, co);
}
}
else {
l_src = ED_uvedit_active_edge_loop_get(bm);
if (l_src != NULL) {
if (l_src != nullptr) {
if (!uvedit_uv_select_test(scene, l_src, offsets) &&
!uvedit_uv_select_test(scene, l_src->next, offsets))
{
l_src = NULL;
l_src = nullptr;
}
ele_src = (BMElem *)l_src;
}
@ -638,18 +633,18 @@ static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEve
}
else {
/* Vertex selection. */
BMLoop *l_src = NULL;
BMLoop *l_src = nullptr;
if (ts->uv_flag & UV_SYNC_SELECTION) {
BMVert *v_src = BM_mesh_active_vert_get(bm);
if (v_src != NULL) {
if (v_src != nullptr) {
l_src = uv_find_nearest_loop_from_vert(scene, obedit, v_src, co);
}
}
else {
l_src = ED_uvedit_active_vert_loop_get(bm);
if (l_src != NULL) {
if (l_src != nullptr) {
if (!uvedit_uv_select_test(scene, l_src, offsets)) {
l_src = NULL;
l_src = nullptr;
}
}
}
@ -705,7 +700,7 @@ static int uv_shortest_path_pick_exec(bContext *C, wmOperator *op)
}
Object *obedit = ED_object_in_mode_from_index(scene, view_layer, OB_MODE_EDIT, object_index);
if (obedit == NULL) {
if (obedit == nullptr) {
return OPERATOR_CANCELLED;
}
@ -751,7 +746,7 @@ static int uv_shortest_path_pick_exec(bContext *C, wmOperator *op)
/* Always use the active object, not `obedit` as the active defines the UV display. */
const float aspect_y = ED_uvedit_get_aspect_y(CTX_data_edit_object(C));
struct PathSelectParams op_params;
PathSelectParams op_params;
path_select_params_from_op(op, &op_params);
op_params.track_active = true;
@ -786,9 +781,9 @@ void UV_OT_shortest_path_pick(wmOperatorType *ot)
/* use for redo */
prop = RNA_def_int(ot->srna, "object_index", -1, -1, INT_MAX, "", "", 0, INT_MAX);
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
RNA_def_property_flag(prop, PropertyFlag(PROP_HIDDEN | PROP_SKIP_SAVE));
prop = RNA_def_int(ot->srna, "index", -1, -1, INT_MAX, "", "", 0, INT_MAX);
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
RNA_def_property_flag(prop, PropertyFlag(PROP_HIDDEN | PROP_SKIP_SAVE));
}
/** \} */
@ -809,7 +804,7 @@ static int uv_shortest_path_select_exec(bContext *C, wmOperator *op)
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
scene, view_layer, NULL, &objects_len);
scene, view_layer, nullptr, &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@ -817,11 +812,11 @@ static int uv_shortest_path_select_exec(bContext *C, wmOperator *op)
const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
BMElem *ele_src = NULL, *ele_dst = NULL;
BMElem *ele_src = nullptr, *ele_dst = nullptr;
/* Find 2x elements. */
{
BMElem **ele_array = NULL;
BMElem **ele_array = nullptr;
int ele_array_len = 0;
if (uv_selectmode & UV_SELECT_FACE) {
ele_array = (BMElem **)ED_uvedit_selected_faces(scene, bm, 3, &ele_array_len);
@ -841,7 +836,7 @@ static int uv_shortest_path_select_exec(bContext *C, wmOperator *op)
}
if (ele_src && ele_dst) {
struct PathSelectParams op_params;
PathSelectParams op_params;
path_select_params_from_op(op, &op_params);
uv_shortest_path_pick_ex(

View File

@ -4,9 +4,9 @@
* \ingroup eduv
*/
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include "MEM_guardedalloc.h"
@ -51,7 +51,7 @@
* \{ */
/** Unordered loop data, stored in #BMLoop.head.index. */
typedef struct ULData {
struct ULData {
/** When the specified UV edge is selected. */
uint is_select_edge : 1;
/**
@ -81,7 +81,7 @@ typedef struct ULData {
* depending on the order of addition.
*/
uint side_was_swapped : 1;
} ULData;
};
/** Ensure this fits in an int (loop index). */
BLI_STATIC_ASSERT(sizeof(ULData) <= sizeof(int), "");
@ -100,7 +100,7 @@ BLI_INLINE ULData *UL(BMLoop *l)
static BMLoop *bm_loop_find_other_radial_loop_with_visible_face(BMLoop *l_src,
const int cd_loop_uv_offset)
{
BMLoop *l_other = NULL;
BMLoop *l_other = nullptr;
BMLoop *l_iter = l_src->radial_next;
if (l_iter != l_src) {
do {
@ -108,12 +108,12 @@ static BMLoop *bm_loop_find_other_radial_loop_with_visible_face(BMLoop *l_src,
BM_loop_uv_share_edge_check(l_src, l_iter, cd_loop_uv_offset))
{
/* Check UVs are contiguous. */
if (l_other == NULL) {
if (l_other == nullptr) {
l_other = l_iter;
}
else {
/* Only use when there is a single alternative. */
l_other = NULL;
l_other = nullptr;
break;
}
}
@ -127,7 +127,7 @@ static BMLoop *bm_loop_find_other_fan_loop_with_visible_face(BMLoop *l_src,
const int cd_loop_uv_offset)
{
BLI_assert(BM_vert_in_edge(l_src->e, v_src));
BMLoop *l_other = NULL;
BMLoop *l_other = nullptr;
BMLoop *l_iter = l_src->radial_next;
if (l_iter != l_src) {
do {
@ -135,18 +135,18 @@ static BMLoop *bm_loop_find_other_fan_loop_with_visible_face(BMLoop *l_src,
BM_loop_uv_share_edge_check(l_src, l_iter, cd_loop_uv_offset))
{
/* Check UVs are contiguous. */
if (l_other == NULL) {
if (l_other == nullptr) {
l_other = l_iter;
}
else {
/* Only use when there is a single alternative. */
l_other = NULL;
l_other = nullptr;
break;
}
}
} while ((l_iter = l_iter->radial_next) != l_src);
}
if (l_other != NULL) {
if (l_other != nullptr) {
if (l_other->v == v_src) {
/* do nothing. */
}
@ -178,7 +178,7 @@ static BMLoop *bm_vert_step_fan_loop_uv(BMLoop *l, BMEdge **e_step, const int cd
}
else {
BLI_assert_unreachable();
return NULL;
return nullptr;
}
*e_step = l_next->e;
@ -279,10 +279,10 @@ static void bm_loop_calc_uv_angle_from_dir(BMLoop *l,
/** \name UV Rip Single
* \{ */
typedef struct UVRipSingle {
struct UVRipSingle {
/** Walk around the selected UV point, store #BMLoop. */
GSet *loops;
} UVRipSingle;
};
/**
* Handle single loop, the following cases:
@ -303,14 +303,14 @@ static UVRipSingle *uv_rip_single_from_loop(BMLoop *l_init_orig,
const float aspect_y,
const int cd_loop_uv_offset)
{
UVRipSingle *rip = MEM_callocN(sizeof(*rip), __func__);
UVRipSingle *rip = MEM_cnew<UVRipSingle>(__func__);
const float *co_center = BM_ELEM_CD_GET_FLOAT_P(l_init_orig, cd_loop_uv_offset);
rip->loops = BLI_gset_ptr_new(__func__);
/* Track the closest loop, start walking from this so in the event we have multiple
* disconnected fans, we can rip away loops connected to this one. */
BMLoop *l_init = NULL;
BMLoop *l_init_edge = NULL;
BMLoop *l_init = nullptr;
BMLoop *l_init_edge = nullptr;
float corner_angle_best = FLT_MAX;
float edge_angle_best = FLT_MAX;
int edge_index_best = 0; /* -1 or +1 (never center). */
@ -373,7 +373,7 @@ static UVRipSingle *uv_rip_single_from_loop(BMLoop *l_init_orig,
BMEdge *e_prev = i ? l_init->e : l_init->prev->e;
BMLoop *l_iter = l_init;
while (((l_iter = bm_vert_step_fan_loop_uv(l_iter, &e_prev, cd_loop_uv_offset)) != l_init) &&
(l_iter != NULL) && (UL(l_iter)->side == 0))
(l_iter != nullptr) && (UL(l_iter)->side == 0))
{
uv_fan_count_contiguous += 1;
/* Keep. */
@ -393,7 +393,7 @@ static UVRipSingle *uv_rip_single_from_loop(BMLoop *l_init_orig,
else {
GSetIterator gs_iter;
GSET_ITER (gs_iter, rip->loops) {
BMLoop *l = BLI_gsetIterator_getKey(&gs_iter);
BMLoop *l = static_cast<BMLoop *>(BLI_gsetIterator_getKey(&gs_iter));
UL(l)->side = 0;
}
@ -421,7 +421,7 @@ static UVRipSingle *uv_rip_single_from_loop(BMLoop *l_init_orig,
static void uv_rip_single_free(UVRipSingle *rip)
{
BLI_gset_free(rip->loops, NULL);
BLI_gset_free(rip->loops, nullptr);
MEM_freeN(rip);
}
@ -431,10 +431,10 @@ static void uv_rip_single_free(UVRipSingle *rip)
/** \name UV Rip Loop Pairs
* \{ */
typedef struct UVRipPairs {
struct UVRipPairs {
/** Walk along the UV selection, store #BMLoop. */
GSet *loops;
} UVRipPairs;
};
static void uv_rip_pairs_add(UVRipPairs *rip, BMLoop *l)
{
@ -451,7 +451,7 @@ static void uv_rip_pairs_remove(UVRipPairs *rip, BMLoop *l)
BLI_assert(BLI_gset_haskey(rip->loops, l));
BLI_assert(ul->in_rip_pairs == true);
ul->in_rip_pairs = false;
BLI_gset_remove(rip->loops, l, NULL);
BLI_gset_remove(rip->loops, l, nullptr);
}
/**
@ -556,7 +556,7 @@ static UVRipPairs *uv_rip_pairs_from_loop(BMLoop *l_init,
const float aspect_y,
const int cd_loop_uv_offset)
{
UVRipPairs *rip = MEM_callocN(sizeof(*rip), __func__);
UVRipPairs *rip = MEM_cnew<UVRipPairs>(__func__);
rip->loops = BLI_gset_ptr_new(__func__);
/* We can rely on this stack being small, as we're walking down two sides of an edge loop,
@ -587,7 +587,7 @@ static UVRipPairs *uv_rip_pairs_from_loop(BMLoop *l_init,
UL(l_init)->in_stack = true;
BMLoop *l_step;
while ((l_step = BLI_SMALLSTACK_POP(stack))) {
while ((l_step = static_cast<BMLoop *>(BLI_SMALLSTACK_POP(stack)))) {
int side = UL(l_step)->side;
UL(l_step)->in_stack = false;
@ -599,7 +599,7 @@ static UVRipPairs *uv_rip_pairs_from_loop(BMLoop *l_init,
if (UL(l_step)->is_select_edge) {
BMLoop *l_other = bm_loop_find_other_radial_loop_with_visible_face(l_step,
cd_loop_uv_offset);
if (l_other != NULL) {
if (l_other != nullptr) {
if (!UL(l_other)->in_rip_pairs && !UL(l_other)->in_stack) {
BLI_SMALLSTACK_PUSH(stack, l_other);
UL(l_other)->in_stack = true;
@ -675,7 +675,7 @@ static UVRipPairs *uv_rip_pairs_from_loop(BMLoop *l_init,
static void uv_rip_pairs_free(UVRipPairs *rip)
{
BLI_gset_free(rip->loops, NULL);
BLI_gset_free(rip->loops, nullptr);
MEM_freeN(rip);
}
@ -696,7 +696,7 @@ static bool uv_rip_pairs_calc_center_and_direction(UVRipPairs *rip,
}
GSetIterator gs_iter;
GSET_ITER (gs_iter, rip->loops) {
BMLoop *l = BLI_gsetIterator_getKey(&gs_iter);
BMLoop *l = static_cast<BMLoop *>(BLI_gsetIterator_getKey(&gs_iter));
int side = UL(l)->side;
const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
add_v2_v2(r_center, luv);
@ -849,7 +849,7 @@ static bool uv_rip_object(Scene *scene, Object *obedit, const float co[2], const
}
GSetIterator gs_iter;
GSET_ITER (gs_iter, rip->loops) {
BMLoop *l_iter = BLI_gsetIterator_getKey(&gs_iter);
BMLoop *l_iter = static_cast<BMLoop *>(BLI_gsetIterator_getKey(&gs_iter));
ULData *ul = UL(l_iter);
if (ul->side == side_from_cursor) {
uvedit_uv_select_disable(scene, bm, l_iter, offsets);
@ -867,7 +867,7 @@ static bool uv_rip_object(Scene *scene, Object *obedit, const float co[2], const
const int side_from_cursor = 0;
GSetIterator gs_iter;
GSET_ITER (gs_iter, rip->loops) {
BMLoop *l_iter = BLI_gsetIterator_getKey(&gs_iter);
BMLoop *l_iter = static_cast<BMLoop *>(BLI_gsetIterator_getKey(&gs_iter));
ULData *ul = UL(l_iter);
if (ul->side == side_from_cursor) {
uvedit_uv_select_disable(scene, bm, l_iter, offsets);
@ -914,7 +914,7 @@ static int uv_rip_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
scene, view_layer, ((View3D *)NULL), &objects_len);
scene, view_layer, ((View3D *)nullptr), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@ -922,7 +922,7 @@ static int uv_rip_exec(bContext *C, wmOperator *op)
if (uv_rip_object(scene, obedit, co, aspect_y)) {
changed_multi = true;
uvedit_live_unwrap_update(sima, scene, obedit);
DEG_id_tag_update(obedit->data, 0);
DEG_id_tag_update(static_cast<ID *>(obedit->data), 0);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
}
}
@ -967,7 +967,7 @@ void UV_OT_rip(wmOperatorType *ot)
ot->srna,
"location",
2,
NULL,
nullptr,
-FLT_MAX,
FLT_MAX,
"Location",

View File

@ -5,9 +5,9 @@
* \ingroup eduv
*/
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include "MEM_guardedalloc.h"
@ -58,7 +58,7 @@
/* ********************** smart stitch operator *********************** */
/* object that stores display data for previewing before confirming stitching */
typedef struct StitchPreviewer {
struct StitchPreviewer {
/* here we'll store the preview triangle indices of the mesh */
float *preview_polys;
/* uvs per polygon. */
@ -76,7 +76,7 @@ typedef struct StitchPreviewer {
/* ...and here we'll store the static island triangles */
float *static_tris;
uint num_static_tris;
} StitchPreviewer;
};
struct IslandStitchData;
@ -85,7 +85,7 @@ struct IslandStitchData;
* that will move and take the mean displacement/rotation and apply it to all
* elements of the island except from the stitchable.
*/
typedef struct IslandStitchData {
struct IslandStitchData {
/* rotation can be used only for edges, for vertices there is no such notion */
float rotation;
float rotation_neg;
@ -101,15 +101,15 @@ typedef struct IslandStitchData {
char stitchableCandidate;
/* if edge rotation is used, flag so that vertex rotation is not used */
bool use_edge_rotation;
} IslandStitchData;
};
/* just for averaging UVs */
typedef struct UVVertAverage {
struct UVVertAverage {
float uv[2];
ushort count;
} UVVertAverage;
};
typedef struct UvEdge {
struct UvEdge {
/** index to uv buffer */
uint uv1;
uint uv2;
@ -123,13 +123,13 @@ typedef struct UvEdge {
UvElement *element;
/** next uv edge with the same exact vertices as this one.
* Calculated at startup to save time */
struct UvEdge *next;
UvEdge *next;
/** point to first of common edges. Needed for iteration */
struct UvEdge *first;
} UvEdge;
UvEdge *first;
};
/* stitch state object */
typedef struct StitchState {
struct StitchState {
/** The `aspect[0] / aspect[1]`. */
float aspect;
/* object for editmesh */
@ -165,10 +165,10 @@ typedef struct StitchState {
uint *tris_per_island;
/* preview data */
StitchPreviewer *stitch_preview;
} StitchState;
};
/* Stitch state container. */
typedef struct StitchStateContainer {
struct StitchStateContainer {
/* clear seams of stitched edges after stitch */
bool clear_seams;
/* use limit flag */
@ -192,20 +192,22 @@ typedef struct StitchStateContainer {
StitchState **states;
int active_object_index;
} StitchStateContainer;
};
typedef struct PreviewPosition {
struct PreviewPosition {
int data_position;
int polycount_position;
} PreviewPosition;
};
/*
* defines for UvElement/UcEdge flags
*/
#define STITCH_SELECTED 1
#define STITCH_STITCHABLE 2
#define STITCH_PROCESSED 4
#define STITCH_BOUNDARY 8
#define STITCH_STITCHABLE_CANDIDATE 16
enum {
STITCH_SELECTED = 1,
STITCH_STITCHABLE = 2,
STITCH_PROCESSED = 4,
STITCH_BOUNDARY = 8,
STITCH_STITCHABLE_CANDIDATE = 16,
};
#define STITCH_NO_PREVIEW -1
@ -215,34 +217,35 @@ enum StitchModes {
};
/** #UvElement identification. */
typedef struct UvElementID {
struct UvElementID {
int faceIndex;
int elementIndex;
} UvElementID;
};
/** #StitchState initialization. */
typedef struct StitchStateInit {
struct StitchStateInit {
int uv_selected_count;
UvElementID *to_select;
} StitchStateInit;
};
/* constructor */
static StitchPreviewer *stitch_preview_init(void)
static StitchPreviewer *stitch_preview_init()
{
StitchPreviewer *stitch_preview;
stitch_preview = MEM_mallocN(sizeof(StitchPreviewer), "stitch_previewer");
stitch_preview->preview_polys = NULL;
stitch_preview->preview_stitchable = NULL;
stitch_preview->preview_unstitchable = NULL;
stitch_preview->uvs_per_polygon = NULL;
stitch_preview = static_cast<StitchPreviewer *>(
MEM_mallocN(sizeof(StitchPreviewer), "stitch_previewer"));
stitch_preview->preview_polys = nullptr;
stitch_preview->preview_stitchable = nullptr;
stitch_preview->preview_unstitchable = nullptr;
stitch_preview->uvs_per_polygon = nullptr;
stitch_preview->preview_uvs = 0;
stitch_preview->num_polys = 0;
stitch_preview->num_stitchable = 0;
stitch_preview->num_unstitchable = 0;
stitch_preview->static_tris = NULL;
stitch_preview->static_tris = nullptr;
stitch_preview->num_static_tris = 0;
@ -315,7 +318,7 @@ static bool stitch_check_uvs_stitchable(const int cd_loop_uv_offset,
float limit;
if (element_iter == element) {
return 0;
return false;
}
limit = ssc->limit_dist;
@ -329,11 +332,11 @@ static bool stitch_check_uvs_stitchable(const int cd_loop_uv_offset,
float *luv_iter = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
if (fabsf(luv[0] - luv_iter[0]) < limit && fabsf(luv[1] - luv_iter[1]) < limit) {
return 1;
return true;
}
return 0;
return false;
}
return 1;
return true;
}
static bool stitch_check_edges_stitchable(const int cd_loop_uv_offset,
@ -345,7 +348,7 @@ static bool stitch_check_edges_stitchable(const int cd_loop_uv_offset,
float limit;
if (edge_iter == edge) {
return 0;
return false;
}
limit = ssc->limit_dist;
@ -360,11 +363,11 @@ static bool stitch_check_edges_stitchable(const int cd_loop_uv_offset,
if (fabsf(luv_orig1[0] - luv_iter1[0]) < limit && fabsf(luv_orig1[1] - luv_iter1[1]) < limit &&
fabsf(luv_orig2[0] - luv_iter2[0]) < limit && fabsf(luv_orig2[1] - luv_iter2[1]) < limit)
{
return 1;
return true;
}
return 0;
return false;
}
return 1;
return true;
}
static bool stitch_check_uvs_state_stitchable(const int cd_loop_uv_offset,
@ -375,7 +378,7 @@ static bool stitch_check_uvs_state_stitchable(const int cd_loop_uv_offset,
if ((ssc->snap_islands && element->island == element_iter->island) ||
(!ssc->midpoints && element->island == element_iter->island))
{
return 0;
return false;
}
return stitch_check_uvs_stitchable(cd_loop_uv_offset, element, element_iter, ssc);
@ -390,7 +393,7 @@ static bool stitch_check_edges_state_stitchable(const int cd_loop_uv_offset,
if ((ssc->snap_islands && edge->element->island == edge_iter->element->island) ||
(!ssc->midpoints && edge->element->island == edge_iter->element->island))
{
return 0;
return false;
}
return stitch_check_edges_stitchable(cd_loop_uv_offset, edge, edge_iter, ssc, state);
@ -432,7 +435,7 @@ static void stitch_calculate_island_snapping(const int cd_loop_uv_offset,
}
island_stitch_data[i].medianPoint[1] /= state->aspect;
if ((island_stitch_data[i].rotation + island_stitch_data[i].rotation_neg < (float)M_PI_2) ||
if ((island_stitch_data[i].rotation + island_stitch_data[i].rotation_neg < float(M_PI_2)) ||
island_stitch_data[i].num_rot_elements == 0 ||
island_stitch_data[i].num_rot_elements_neg == 0)
{
@ -443,7 +446,7 @@ static void stitch_calculate_island_snapping(const int cd_loop_uv_offset,
}
else {
rotation = (island_stitch_data[i].rotation * island_stitch_data[i].num_rot_elements +
(2.0f * (float)M_PI - island_stitch_data[i].rotation_neg) *
(2.0f * float(M_PI) - island_stitch_data[i].rotation_neg) *
island_stitch_data[i].num_rot_elements_neg) /
totelem;
}
@ -628,9 +631,9 @@ static void state_delete(StitchState *state)
MEM_freeN(state->edges);
}
stitch_preview_delete(state->stitch_preview);
state->stitch_preview = NULL;
state->stitch_preview = nullptr;
if (state->edge_hash) {
BLI_ghash_free(state->edge_hash, NULL, NULL);
BLI_ghash_free(state->edge_hash, nullptr, nullptr);
}
MEM_freeN(state);
}
@ -673,7 +676,7 @@ static void stitch_uv_edge_generate_linked_edges(GHash *edge_hash, StitchState *
edge->first = edge;
for (; iter1; iter1 = iter1->next) {
UvElement *iter2 = NULL;
UvElement *iter2 = nullptr;
/* check to see if other vertex of edge belongs to same vertex as */
if (BM_elem_index_get(iter1->l->next->v) == elemindex2) {
@ -699,7 +702,7 @@ static void stitch_uv_edge_generate_linked_edges(GHash *edge_hash, StitchState *
edgetmp.uv2 = index2;
/* get the edge from the hash */
edge2 = BLI_ghash_lookup(edge_hash, &edgetmp);
edge2 = static_cast<UvEdge *>(BLI_ghash_lookup(edge_hash, &edgetmp));
/* more iteration to make sure non-manifold case is handled nicely */
for (eiter = edge; eiter; eiter = eiter->next) {
@ -944,38 +947,38 @@ static int stitch_process_data(StitchStateContainer *ssc,
{
int i;
StitchPreviewer *preview;
IslandStitchData *island_stitch_data = NULL;
IslandStitchData *island_stitch_data = nullptr;
int previous_island = ssc->static_island;
BMesh *bm = state->em->bm;
BMFace *efa;
BMIter iter;
UVVertAverage *final_position = NULL;
UVVertAverage *final_position = nullptr;
bool is_active_state = (state == ssc->states[ssc->active_object_index]);
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_PROP_FLOAT2);
char stitch_midpoints = ssc->midpoints;
/* Used to map UV indices to UV-average indices for selection. */
uint *uvfinal_map = NULL;
uint *uvfinal_map = nullptr;
/* per face preview position in preview buffer */
PreviewPosition *preview_position = NULL;
PreviewPosition *preview_position = nullptr;
/* cleanup previous preview */
stitch_preview_delete(state->stitch_preview);
preview = state->stitch_preview = stitch_preview_init();
if (preview == NULL) {
if (preview == nullptr) {
return 0;
}
preview_position = MEM_mallocN(bm->totface * sizeof(*preview_position),
"stitch_face_preview_position");
preview_position = static_cast<PreviewPosition *>(
MEM_mallocN(bm->totface * sizeof(*preview_position), "stitch_face_preview_position"));
/* each face holds its position in the preview buffer in tmp. -1 is uninitialized */
for (i = 0; i < bm->totface; i++) {
preview_position[i].data_position = STITCH_NO_PREVIEW;
}
island_stitch_data = MEM_callocN(sizeof(*island_stitch_data) * state->element_map->total_islands,
"stitch_island_data");
island_stitch_data = static_cast<IslandStitchData *>(MEM_callocN(
sizeof(*island_stitch_data) * state->element_map->total_islands, "stitch_island_data"));
if (!island_stitch_data) {
return 0;
}
@ -1144,14 +1147,14 @@ static int stitch_process_data(StitchStateContainer *ssc,
uint buffer_index = 0;
/* initialize the preview buffers */
preview->preview_polys = MEM_mallocN(sizeof(float[2]) * preview->preview_uvs,
"tri_uv_stitch_prev");
preview->uvs_per_polygon = MEM_mallocN(sizeof(*preview->uvs_per_polygon) * preview->num_polys,
"tri_uv_stitch_prev");
preview->preview_polys = static_cast<float *>(
MEM_mallocN(sizeof(float[2]) * preview->preview_uvs, "tri_uv_stitch_prev"));
preview->uvs_per_polygon = static_cast<uint *>(
MEM_mallocN(sizeof(*preview->uvs_per_polygon) * preview->num_polys, "tri_uv_stitch_prev"));
preview->static_tris = MEM_mallocN(
(sizeof(float[6]) * state->tris_per_island[ssc->static_island]),
"static_island_preview_tris");
preview->static_tris = static_cast<float *>(
MEM_mallocN((sizeof(float[6]) * state->tris_per_island[ssc->static_island]),
"static_island_preview_tris"));
preview->num_static_tris = state->tris_per_island[ssc->static_island];
/* will cause cancel and freeing of all data structures so OK */
@ -1208,20 +1211,20 @@ static int stitch_process_data(StitchStateContainer *ssc,
******************************************************/
if (ssc->mode == STITCH_VERT) {
final_position = MEM_callocN(state->selection_size * sizeof(*final_position),
"stitch_uv_average");
uvfinal_map = MEM_mallocN(state->element_map->total_uvs * sizeof(*uvfinal_map),
"stitch_uv_final_map");
final_position = static_cast<UVVertAverage *>(
MEM_callocN(state->selection_size * sizeof(*final_position), "stitch_uv_average"));
uvfinal_map = static_cast<uint *>(
MEM_mallocN(state->element_map->total_uvs * sizeof(*uvfinal_map), "stitch_uv_final_map"));
}
else {
final_position = MEM_callocN(state->total_separate_uvs * sizeof(*final_position),
"stitch_uv_average");
final_position = static_cast<UVVertAverage *>(
MEM_callocN(state->total_separate_uvs * sizeof(*final_position), "stitch_uv_average"));
}
/* first pass, calculate final position for stitchable uvs of the static island */
for (i = 0; i < state->selection_size; i++) {
if (ssc->mode == STITCH_VERT) {
UvElement *element = state->selection_stack[i];
UvElement *element = static_cast<UvElement *>(state->selection_stack[i]);
if (element->flag & STITCH_STITCHABLE) {
BMLoop *l = element->l;
@ -1262,7 +1265,7 @@ static int stitch_process_data(StitchStateContainer *ssc,
}
}
else {
UvEdge *edge = state->selection_stack[i];
UvEdge *edge = static_cast<UvEdge *>(state->selection_stack[i]);
if (edge->flag & STITCH_STITCHABLE) {
float *luv2, *luv1;
@ -1324,7 +1327,7 @@ static int stitch_process_data(StitchStateContainer *ssc,
if (ssc->snap_islands) {
if (ssc->mode == STITCH_VERT) {
for (i = 0; i < state->selection_size; i++) {
UvElement *element = state->selection_stack[i];
UvElement *element = static_cast<UvElement *>(state->selection_stack[i]);
if (element->flag & STITCH_STITCHABLE) {
BMLoop *l;
@ -1374,7 +1377,7 @@ static int stitch_process_data(StitchStateContainer *ssc,
}
for (i = 0; i < state->selection_size; i++) {
UvElement *element = state->selection_stack[i];
UvElement *element = static_cast<UvElement *>(state->selection_stack[i]);
if (!island_stitch_data[element->island].use_edge_rotation) {
if (element->flag & STITCH_STITCHABLE) {
stitch_island_calculate_vert_rotation(
@ -1406,11 +1409,11 @@ static int stitch_process_data(StitchStateContainer *ssc,
}
for (i = 0; i < state->selection_size; i++) {
UvEdge *edge = state->selection_stack[i];
UvEdge *edge = static_cast<UvEdge *>(state->selection_stack[i]);
if (edge->flag & STITCH_STITCHABLE) {
stitch_island_calculate_edge_rotation(
cd_loop_uv_offset, edge, ssc, state, final_position, NULL, island_stitch_data);
cd_loop_uv_offset, edge, ssc, state, final_position, nullptr, island_stitch_data);
island_stitch_data[state->uvs[edge->uv1]->island].use_edge_rotation = true;
}
}
@ -1418,7 +1421,7 @@ static int stitch_process_data(StitchStateContainer *ssc,
/* clear seams of stitched edges */
if (final && ssc->clear_seams) {
for (i = 0; i < state->selection_size; i++) {
UvEdge *edge = state->selection_stack[i];
UvEdge *edge = static_cast<UvEdge *>(state->selection_stack[i]);
if (edge->flag & STITCH_STITCHABLE) {
BM_elem_flag_disable(edge->element->l->e, BM_ELEM_SEAM);
}
@ -1430,13 +1433,13 @@ static int stitch_process_data(StitchStateContainer *ssc,
/* third pass, propagate changes to coincident uvs */
for (i = 0; i < state->selection_size; i++) {
if (ssc->mode == STITCH_VERT) {
UvElement *element = state->selection_stack[i];
UvElement *element = static_cast<UvElement *>(state->selection_stack[i]);
stitch_propagate_uv_final_position(
scene, element, i, preview_position, final_position, ssc, state, final);
}
else {
UvEdge *edge = state->selection_stack[i];
UvEdge *edge = static_cast<UvEdge *>(state->selection_stack[i]);
stitch_propagate_uv_final_position(scene,
state->uvs[edge->uv1],
@ -1489,22 +1492,22 @@ static int stitch_process_data_all(StitchStateContainer *ssc, Scene *scene, int
/* Stitch hash initialization functions */
static uint uv_edge_hash(const void *key)
{
const UvEdge *edge = key;
const UvEdge *edge = static_cast<const UvEdge *>(key);
BLI_assert(edge->uv1 < edge->uv2);
return (BLI_ghashutil_uinthash(edge->uv2) + BLI_ghashutil_uinthash(edge->uv1));
}
static bool uv_edge_compare(const void *a, const void *b)
{
const UvEdge *edge1 = a;
const UvEdge *edge2 = b;
const UvEdge *edge1 = static_cast<const UvEdge *>(a);
const UvEdge *edge2 = static_cast<const UvEdge *>(b);
BLI_assert(edge1->uv1 < edge1->uv2);
BLI_assert(edge2->uv1 < edge2->uv2);
if ((edge1->uv1 == edge2->uv1) && (edge1->uv2 == edge2->uv2)) {
return 0;
return false;
}
return 1;
return true;
}
/* select all common edges */
@ -1576,9 +1579,9 @@ static void stitch_set_selection_mode(StitchState *state, const char from_stitch
if (from_stitch_mode == STITCH_VERT) {
int i;
state->selection_stack = MEM_mallocN(state->total_separate_edges *
sizeof(*state->selection_stack),
"stitch_new_edge_selection_stack");
state->selection_stack = static_cast<void **>(
MEM_mallocN(state->total_separate_edges * sizeof(*state->selection_stack),
"stitch_new_edge_selection_stack"));
/* check if both elements of an edge are selected */
for (i = 0; i < state->total_separate_edges; i++) {
@ -1593,19 +1596,19 @@ static void stitch_set_selection_mode(StitchState *state, const char from_stitch
/* unselect selected uvelements */
for (i = 0; i < old_selection_size; i++) {
UvElement *element = old_selection_stack[i];
UvElement *element = static_cast<UvElement *>(old_selection_stack[i]);
element->flag &= ~STITCH_SELECTED;
}
}
else {
int i;
state->selection_stack = MEM_mallocN(state->total_separate_uvs *
sizeof(*state->selection_stack),
"stitch_new_vert_selection_stack");
state->selection_stack = static_cast<void **>(
MEM_mallocN(state->total_separate_uvs * sizeof(*state->selection_stack),
"stitch_new_vert_selection_stack"));
for (i = 0; i < old_selection_size; i++) {
UvEdge *edge = old_selection_stack[i];
UvEdge *edge = static_cast<UvEdge *>(old_selection_stack[i]);
UvElement *element1 = state->uvs[edge->uv1];
UvElement *element2 = state->uvs[edge->uv2];
@ -1657,7 +1660,7 @@ static void stitch_calculate_edge_normal(const int cd_loop_uv_offset,
*/
static void stitch_draw_vbo(GPUVertBuf *vbo, GPUPrimType prim_type, const float col[4])
{
GPUBatch *batch = GPU_batch_create_ex(prim_type, vbo, NULL, GPU_BATCH_OWNS_VBO);
GPUBatch *batch = GPU_batch_create_ex(prim_type, vbo, nullptr, GPU_BATCH_OWNS_VBO);
GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR);
GPU_batch_uniform_4fv(batch, "color", col);
GPU_batch_draw(batch);
@ -1666,7 +1669,7 @@ static void stitch_draw_vbo(GPUVertBuf *vbo, GPUPrimType prim_type, const float
/* TODO: make things prettier : store batches inside StitchPreviewer instead of the bare verts pos
*/
static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), void *arg)
static void stitch_draw(const bContext * /*C*/, ARegion * /*region*/, void *arg)
{
StitchStateContainer *ssc = (StitchStateContainer *)arg;
@ -1799,7 +1802,7 @@ static UvEdge *uv_edge_get(BMLoop *l, StitchState *state)
UvElement *element2 = BM_uv_element_get(state->element_map, l->next);
if (!element1 || !element2) {
return NULL;
return nullptr;
}
int uv1 = state->map[element1 - state->element_map->storage];
@ -1814,7 +1817,7 @@ static UvEdge *uv_edge_get(BMLoop *l, StitchState *state)
tmp_edge.uv2 = uv1;
}
return BLI_ghash_lookup(state->edge_hash, &tmp_edge);
return static_cast<UvEdge *>(BLI_ghash_lookup(state->edge_hash, &tmp_edge));
}
static StitchState *stitch_init(bContext *C,
@ -1842,7 +1845,7 @@ static StitchState *stitch_init(bContext *C,
BMEditMesh *em = BKE_editmesh_from_object(obedit);
const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
state = MEM_callocN(sizeof(StitchState), "stitch state obj");
state = MEM_cnew<StitchState>("stitch state obj");
/* initialize state */
state->obedit = obedit;
@ -1857,7 +1860,7 @@ static StitchState *stitch_init(bContext *C,
if (!state->element_map) {
state_delete(state);
return NULL;
return nullptr;
}
state->aspect = ED_uvedit_get_aspect_y(obedit);
@ -1866,21 +1869,24 @@ static StitchState *stitch_init(bContext *C,
state->total_separate_uvs = unique_uvs;
/* Allocate the unique uv buffers */
state->uvs = MEM_mallocN(sizeof(*state->uvs) * unique_uvs, "uv_stitch_unique_uvs");
state->uvs = static_cast<UvElement **>(
MEM_mallocN(sizeof(*state->uvs) * unique_uvs, "uv_stitch_unique_uvs"));
/* internal uvs need no normals but it is hard and slow to keep a map of
* normals only for boundary uvs, so allocating for all uvs.
* Times 2 because each `float[2]` is stored as `{n[2 * i], n[2*i + 1]}`. */
state->normals = MEM_callocN(sizeof(*state->normals) * 2 * unique_uvs, "uv_stitch_normals");
state->map = map = MEM_mallocN(sizeof(*map) * state->element_map->total_uvs,
"uv_stitch_unique_map");
state->normals = static_cast<float *>(
MEM_callocN(sizeof(*state->normals) * 2 * unique_uvs, "uv_stitch_normals"));
state->map = map = static_cast<int *>(
MEM_mallocN(sizeof(*map) * state->element_map->total_uvs, "uv_stitch_unique_map"));
/* Allocate the edge stack */
edge_hash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "stitch_edge_hash");
all_edges = MEM_mallocN(sizeof(*all_edges) * state->element_map->total_uvs, "ssc_edges");
all_edges = static_cast<UvEdge *>(
MEM_mallocN(sizeof(*all_edges) * state->element_map->total_uvs, "ssc_edges"));
BLI_assert(!state->stitch_preview); /* Paranoia. */
if (!state->uvs || !map || !edge_hash || !all_edges) {
state_delete(state);
return NULL;
return nullptr;
}
/* Index for the UvElements. */
@ -1918,8 +1924,8 @@ static StitchState *stitch_init(bContext *C,
int offset1 = map[itmp1];
int offset2 = map[itmp2];
all_edges[counter].next = NULL;
all_edges[counter].first = NULL;
all_edges[counter].next = nullptr;
all_edges[counter].first = nullptr;
all_edges[counter].flag = 0;
all_edges[counter].element = element;
/* Using an order policy, sort UVs according to address space.
@ -1933,7 +1939,7 @@ static StitchState *stitch_init(bContext *C,
all_edges[counter].uv2 = offset1;
}
edge = BLI_ghash_lookup(edge_hash, &all_edges[counter]);
edge = static_cast<UvEdge *>(BLI_ghash_lookup(edge_hash, &all_edges[counter]));
if (edge) {
edge->flag = 0;
}
@ -1946,12 +1952,13 @@ static StitchState *stitch_init(bContext *C,
}
total_edges = BLI_ghash_len(edge_hash);
state->edges = edges = MEM_mallocN(sizeof(*edges) * total_edges, "stitch_edges");
state->edges = edges = static_cast<UvEdge *>(
MEM_mallocN(sizeof(*edges) * total_edges, "stitch_edges"));
/* I assume any system will be able to at least allocate an iterator :p */
if (!edges) {
state_delete(state);
return NULL;
return nullptr;
}
state->total_separate_edges = total_edges;
@ -1965,7 +1972,7 @@ static StitchState *stitch_init(bContext *C,
/* cleanup temporary stuff */
MEM_freeN(all_edges);
BLI_ghash_free(edge_hash, NULL, NULL);
BLI_ghash_free(edge_hash, nullptr, nullptr);
/* Refill an edge hash to create edge connectivity data. */
state->edge_hash = edge_hash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "stitch_edge_hash");
@ -2000,33 +2007,34 @@ static StitchState *stitch_init(bContext *C,
state->selection_size = 0;
/* Load old selection if redoing operator with different settings */
if (state_init != NULL) {
if (state_init != nullptr) {
int faceIndex, elementIndex;
UvElement *element;
enum StitchModes stored_mode = RNA_enum_get(op->ptr, "stored_mode");
enum StitchModes stored_mode = StitchModes(RNA_enum_get(op->ptr, "stored_mode"));
BM_mesh_elem_table_ensure(em->bm, BM_FACE);
int selected_count = state_init->uv_selected_count;
if (stored_mode == STITCH_VERT) {
state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) *
state->total_separate_uvs,
"uv_stitch_selection_stack");
state->selection_stack = static_cast<void **>(
MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_uvs,
"uv_stitch_selection_stack"));
while (selected_count--) {
faceIndex = state_init->to_select[selected_count].faceIndex;
elementIndex = state_init->to_select[selected_count].elementIndex;
efa = BM_face_at_index(em->bm, faceIndex);
element = BM_uv_element_get(state->element_map,
BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, elementIndex));
element = BM_uv_element_get(
state->element_map,
static_cast<BMLoop *>(BM_iter_at_index(nullptr, BM_LOOPS_OF_FACE, efa, elementIndex)));
stitch_select_uv(element, state, 1);
}
}
else {
state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) *
state->total_separate_edges,
"uv_stitch_selection_stack");
state->selection_stack = static_cast<void **>(
MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_edges,
"uv_stitch_selection_stack"));
while (selected_count--) {
UvEdge tmp_edge, *edge;
@ -2034,13 +2042,15 @@ static StitchState *stitch_init(bContext *C,
faceIndex = state_init->to_select[selected_count].faceIndex;
elementIndex = state_init->to_select[selected_count].elementIndex;
efa = BM_face_at_index(em->bm, faceIndex);
element = BM_uv_element_get(state->element_map,
BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, elementIndex));
element = BM_uv_element_get(
state->element_map,
static_cast<BMLoop *>(BM_iter_at_index(nullptr, BM_LOOPS_OF_FACE, efa, elementIndex)));
uv1 = map[element - state->element_map->storage];
element = BM_uv_element_get(
state->element_map,
BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, (elementIndex + 1) % efa->len));
static_cast<BMLoop *>(
BM_iter_at_index(nullptr, BM_LOOPS_OF_FACE, efa, (elementIndex + 1) % efa->len)));
uv2 = map[element - state->element_map->storage];
if (uv1 < uv2) {
@ -2052,7 +2062,7 @@ static StitchState *stitch_init(bContext *C,
tmp_edge.uv2 = uv1;
}
edge = BLI_ghash_lookup(edge_hash, &tmp_edge);
edge = static_cast<UvEdge *>(BLI_ghash_lookup(edge_hash, &tmp_edge));
stitch_select_edge(edge, state, true);
}
@ -2065,9 +2075,9 @@ static StitchState *stitch_init(bContext *C,
}
else {
if (ssc->mode == STITCH_VERT) {
state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) *
state->total_separate_uvs,
"uv_stitch_selection_stack");
state->selection_stack = static_cast<void **>(
MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_uvs,
"uv_stitch_selection_stack"));
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
@ -2081,9 +2091,9 @@ static StitchState *stitch_init(bContext *C,
}
}
else {
state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) *
state->total_separate_edges,
"uv_stitch_selection_stack");
state->selection_stack = static_cast<void **>(
MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_edges,
"uv_stitch_selection_stack"));
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (!(ts->uv_flag & UV_SYNC_SELECTION) &&
@ -2106,8 +2116,8 @@ static StitchState *stitch_init(bContext *C,
/***** initialize static island preview data *****/
state->tris_per_island = MEM_mallocN(
sizeof(*state->tris_per_island) * state->element_map->total_islands, "stitch island tris");
state->tris_per_island = static_cast<uint *>(MEM_mallocN(
sizeof(*state->tris_per_island) * state->element_map->total_islands, "stitch island tris"));
for (i = 0; i < state->element_map->total_islands; i++) {
state->tris_per_island[i] = 0;
}
@ -2120,16 +2130,16 @@ static StitchState *stitch_init(bContext *C,
}
}
state->island_is_stitchable = MEM_callocN(sizeof(bool) * state->element_map->total_islands,
"stitch I stops");
state->island_is_stitchable = static_cast<bool *>(
MEM_callocN(sizeof(bool) * state->element_map->total_islands, "stitch I stops"));
if (!state->island_is_stitchable) {
state_delete(state);
return NULL;
return nullptr;
}
if (!stitch_process_data(ssc, state, scene, false)) {
state_delete(state);
return NULL;
return nullptr;
}
return state;
@ -2194,7 +2204,7 @@ static int stitch_init_all(bContext *C, wmOperator *op)
return 0;
}
StitchStateContainer *ssc = MEM_callocN(sizeof(StitchStateContainer), "stitch collection");
StitchStateContainer *ssc = MEM_cnew<StitchStateContainer>("stitch collection");
op->customdata = ssc;
@ -2228,13 +2238,15 @@ static int stitch_init_all(bContext *C, wmOperator *op)
}
}
ssc->objects = MEM_callocN(sizeof(Object *) * objects_len, "Object *ssc->objects");
ssc->states = MEM_callocN(sizeof(StitchState *) * objects_len, "StitchState");
ssc->objects = static_cast<Object **>(
MEM_callocN(sizeof(Object *) * objects_len, "Object *ssc->objects"));
ssc->states = static_cast<StitchState **>(
MEM_callocN(sizeof(StitchState *) * objects_len, "StitchState"));
ssc->objects_len = 0;
int *objs_selection_count = NULL;
UvElementID *selected_uvs_arr = NULL;
StitchStateInit *state_init = NULL;
int *objs_selection_count = nullptr;
UvElementID *selected_uvs_arr = nullptr;
StitchStateInit *state_init = nullptr;
if (RNA_struct_property_is_set(op->ptr, "selection") &&
RNA_struct_property_is_set(op->ptr, "objects_selection_count"))
@ -2242,7 +2254,8 @@ static int stitch_init_all(bContext *C, wmOperator *op)
/* Retrieve list of selected UVs, one list contains all selected UVs
* for all objects. */
objs_selection_count = MEM_mallocN(sizeof(int *) * objects_len, "objects_selection_count");
objs_selection_count = static_cast<int *>(
MEM_mallocN(sizeof(int *) * objects_len, "objects_selection_count"));
RNA_int_get_array(op->ptr, "objects_selection_count", objs_selection_count);
int total_selected = 0;
@ -2250,7 +2263,8 @@ static int stitch_init_all(bContext *C, wmOperator *op)
total_selected += objs_selection_count[ob_index];
}
selected_uvs_arr = MEM_callocN(sizeof(UvElementID) * total_selected, "selected_uvs_arr");
selected_uvs_arr = static_cast<UvElementID *>(
MEM_callocN(sizeof(UvElementID) * total_selected, "selected_uvs_arr"));
int sel_idx = 0;
RNA_BEGIN (op->ptr, itemptr, "selection") {
BLI_assert(sel_idx < total_selected);
@ -2262,20 +2276,21 @@ static int stitch_init_all(bContext *C, wmOperator *op)
RNA_collection_clear(op->ptr, "selection");
state_init = MEM_callocN(sizeof(StitchStateInit), "UV_init_selected");
state_init = static_cast<StitchStateInit *>(
MEM_callocN(sizeof(StitchStateInit), "UV_init_selected"));
state_init->to_select = selected_uvs_arr;
}
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
if (state_init != NULL) {
if (state_init != nullptr) {
state_init->uv_selected_count = objs_selection_count[ob_index];
}
StitchState *stitch_state_ob = stitch_init(C, op, ssc, obedit, state_init);
if (state_init != NULL) {
if (state_init != nullptr) {
/* Move pointer to beginning of next object's data. */
state_init->to_select += state_init->uv_selected_count;
}
@ -2324,7 +2339,7 @@ static int stitch_init_all(bContext *C, wmOperator *op)
return 1;
}
static int stitch_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
static int stitch_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
if (!stitch_init_all(C, op)) {
return OPERATOR_CANCELLED;
@ -2373,9 +2388,9 @@ static void stitch_exit(bContext *C, wmOperator *op, int finished)
RNA_int_set(op->ptr, "static_island", ssc->static_island);
int *objs_selection_count = NULL;
objs_selection_count = MEM_mallocN(sizeof(int *) * ssc->objects_len,
"objects_selection_count");
int *objs_selection_count = nullptr;
objs_selection_count = static_cast<int *>(
MEM_mallocN(sizeof(int *) * ssc->objects_len, "objects_selection_count"));
/* Store selection for re-execution of stitch
* - Store all selected UVs in "selection"
@ -2390,7 +2405,7 @@ static void stitch_exit(bContext *C, wmOperator *op, int finished)
UvElement *element;
if (ssc->mode == STITCH_VERT) {
element = state->selection_stack[i];
element = static_cast<UvElement *>(state->selection_stack[i]);
}
else {
element = ((UvEdge *)state->selection_stack[i])->element;
@ -2412,7 +2427,7 @@ static void stitch_exit(bContext *C, wmOperator *op, int finished)
}
if (area) {
ED_workspace_status_text(C, NULL);
ED_workspace_status_text(C, nullptr);
}
ED_region_draw_cb_exit(CTX_wm_region(C)->type, ssc->draw_handle);
@ -2429,13 +2444,13 @@ static void stitch_exit(bContext *C, wmOperator *op, int finished)
continue;
}
DEG_id_tag_update(obedit->data, 0);
DEG_id_tag_update(static_cast<ID *>(obedit->data), 0);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
}
state_delete_all(ssc);
op->customdata = NULL;
op->customdata = nullptr;
}
static void stitch_cancel(bContext *C, wmOperator *op)
@ -2477,7 +2492,7 @@ static StitchState *stitch_select(bContext *C,
* the opposite stitchable vertex and the initial still gets deselected */
/* find StitchState from hit->ob */
StitchState *state = NULL;
StitchState *state = nullptr;
for (uint ob_index = 0; ob_index < ssc->objects_len; ob_index++) {
if (hit.ob == ssc->objects[ob_index]) {
state = ssc->states[ob_index];
@ -2496,7 +2511,7 @@ static StitchState *stitch_select(bContext *C,
}
else if (uv_find_nearest_edge_multi(scene, ssc->objects, ssc->objects_len, co, 0.0f, &hit)) {
/* find StitchState from hit->ob */
StitchState *state = NULL;
StitchState *state = nullptr;
for (uint ob_index = 0; ob_index < ssc->objects_len; ob_index++) {
if (hit.ob == ssc->objects[ob_index]) {
state = ssc->states[ob_index];
@ -2510,7 +2525,7 @@ static StitchState *stitch_select(bContext *C,
return state;
}
return NULL;
return nullptr;
}
static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
@ -2518,7 +2533,7 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
StitchStateContainer *ssc;
Scene *scene = CTX_data_scene(C);
ssc = op->customdata;
ssc = static_cast<StitchStateContainer *>(op->customdata);
StitchState *active_state = ssc->states[ssc->active_object_index];
switch (event->type) {
@ -2681,7 +2696,7 @@ void UV_OT_stitch(wmOperatorType *ot)
static const EnumPropertyItem stitch_modes[] = {
{STITCH_VERT, "VERTEX", 0, "Vertex", ""},
{STITCH_EDGE, "EDGE", 0, "Edge", ""},
{0, NULL, 0, NULL, NULL},
{0, nullptr, 0, nullptr, nullptr},
};
/* identifiers */
@ -2699,10 +2714,10 @@ void UV_OT_stitch(wmOperatorType *ot)
/* properties */
RNA_def_boolean(
ot->srna, "use_limit", 0, "Use Limit", "Stitch UVs within a specified limit distance");
ot->srna, "use_limit", false, "Use Limit", "Stitch UVs within a specified limit distance");
RNA_def_boolean(ot->srna,
"snap_islands",
1,
true,
"Snap Islands",
"Snap islands together (on edge stitch mode, rotates the islands too)");
@ -2735,10 +2750,10 @@ void UV_OT_stitch(wmOperatorType *ot)
INT_MAX);
RNA_def_boolean(ot->srna,
"midpoint_snap",
0,
false,
"Snap at Midpoint",
"UVs are stitched at midpoint instead of at static island");
RNA_def_boolean(ot->srna, "clear_seams", 1, "Clear Seams", "Clear seams of stitched edges");
RNA_def_boolean(ot->srna, "clear_seams", true, "Clear Seams", "Clear seams of stitched edges");
RNA_def_enum(ot->srna,
"mode",
stitch_modes,
@ -2761,7 +2776,7 @@ void UV_OT_stitch(wmOperatorType *ot)
prop = RNA_def_int_array(ot->srna,
"objects_selection_count",
1,
NULL,
nullptr,
0,
INT_MAX,
"Objects Selection Count",

View File

@ -103,7 +103,7 @@ static void modifier_unwrap_state(Object *obedit, const Scene *scene, bool *r_us
static bool ED_uvedit_ensure_uvs(Object *obedit)
{
if (ED_uvedit_test(obedit)) {
return 1;
return true;
}
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@ -116,7 +116,7 @@ static bool ED_uvedit_ensure_uvs(Object *obedit)
/* Happens when there are no faces. */
if (!ED_uvedit_test(obedit)) {
return 0;
return false;
}
const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2);
@ -135,7 +135,7 @@ static bool ED_uvedit_ensure_uvs(Object *obedit)
}
}
return 1;
return true;
}
/** \} */
@ -547,8 +547,8 @@ static void texface_from_original_index(const Scene *scene,
BMIter liter;
*r_uv = nullptr;
*r_pin = 0;
*r_select = 1;
*r_pin = false;
*r_select = true;
if (index == ORIGINDEX_NONE) {
return;
@ -1008,7 +1008,7 @@ void UV_OT_minimize_stretch(wmOperatorType *ot)
/* properties */
RNA_def_boolean(ot->srna,
"fill_holes",
1,
true,
"Fill Holes",
"Virtually fill holes in mesh before unwrapping, to better avoid overlaps and "
"preserve symmetry");
@ -1205,7 +1205,7 @@ static void uvedit_pack_islands_multi(const Scene *scene,
offsets);
/* Remove from linked list and append to blender::Vector. */
LISTBASE_FOREACH_MUTABLE (struct FaceIsland *, island, &island_list) {
LISTBASE_FOREACH_MUTABLE (FaceIsland *, island, &island_list) {
BLI_remlink(&island_list, island);
const bool pinned = island_has_pins(scene, island, params);
if (ignore_pinned && pinned) {
@ -1838,8 +1838,10 @@ void ED_uvedit_live_unwrap_end(short cancel)
#define POLAR_ZX 0
#define POLAR_ZY 1
#define PINCH 0
#define FAN 1
enum {
PINCH = 0,
FAN = 1,
};
static void uv_map_transform_calc_bounds(BMEditMesh *em, float r_min[3], float r_max[3])
{
@ -2051,8 +2053,11 @@ static void uv_transform_properties(wmOperatorType *ot, int radius)
"Align",
"How to determine rotation around the pole");
RNA_def_enum(ot->srna, "pole", pole_items, PINCH, "Pole", "How to handle faces at the poles");
RNA_def_boolean(
ot->srna, "seam", 0, "Preserve Seams", "Separate projections by islands isolated by seams");
RNA_def_boolean(ot->srna,
"seam",
false,
"Preserve Seams",
"Separate projections by islands isolated by seams");
if (radius) {
RNA_def_float(ot->srna,
@ -2166,20 +2171,20 @@ static void uv_map_clip_correct_properties_ex(wmOperatorType *ot, bool clip_to_b
{
RNA_def_boolean(ot->srna,
"correct_aspect",
1,
true,
"Correct Aspect",
"Map UVs taking image aspect ratio into account");
/* Optional, since not all unwrapping types need to be clipped. */
if (clip_to_bounds) {
RNA_def_boolean(ot->srna,
"clip_to_bounds",
0,
false,
"Clip to Bounds",
"Clip UV coordinates to bounds after unwrapping");
}
RNA_def_boolean(ot->srna,
"scale_to_bounds",
0,
false,
"Scale to Bounds",
"Scale UV coordinates to bounds after unwrapping");
}
@ -2575,13 +2580,13 @@ void UV_OT_unwrap(wmOperatorType *ot)
"being somewhat slower)");
RNA_def_boolean(ot->srna,
"fill_holes",
1,
true,
"Fill Holes",
"Virtually fill holes in mesh before unwrapping, to better avoid overlaps and "
"preserve symmetry");
RNA_def_boolean(ot->srna,
"correct_aspect",
1,
true,
"Correct Aspect",
"Map UVs taking image aspect ratio into account");
RNA_def_boolean(
@ -3139,7 +3144,7 @@ static bool uv_from_view_poll(bContext *C)
RegionView3D *rv3d = CTX_wm_region_view3d(C);
if (!ED_operator_uvmap(C)) {
return 0;
return false;
}
return (rv3d != nullptr);
@ -3160,10 +3165,10 @@ void UV_OT_project_from_view(wmOperatorType *ot)
ot->poll = uv_from_view_poll;
/* properties */
RNA_def_boolean(ot->srna, "orthographic", 0, "Orthographic", "Use orthographic projection");
RNA_def_boolean(ot->srna, "orthographic", false, "Orthographic", "Use orthographic projection");
RNA_def_boolean(ot->srna,
"camera_bounds",
1,
true,
"Camera Bounds",
"Map UVs to the camera region taking resolution and aspect into account");
uv_map_clip_correct_properties(ot);

View File

@ -307,25 +307,27 @@ bool imb_oiio_write(const WriteContext &ctx, const char *filepath, const ImageSp
final_buf = std::move(orig_buf);
}
bool ok = false;
bool write_ok = false;
bool close_ok = false;
if (ctx.flags & IB_mem) {
/* This memory proxy must remain alive for the full duration of the write. */
/* This memory proxy must remain alive until the ImageOutput is finally closed. */
ImBufMemWriter writer(ctx.ibuf);
imb_addencodedbufferImBuf(ctx.ibuf);
out->set_ioproxy(&writer);
if (out->open("", file_spec)) {
ok = final_buf.write(out.get());
write_ok = final_buf.write(out.get());
close_ok = out->close();
}
}
else {
if (out->open(filepath, file_spec)) {
ok = final_buf.write(out.get());
write_ok = final_buf.write(out.get());
close_ok = out->close();
}
}
out->close();
return ok;
return write_ok && close_ok;
}
WriteContext imb_create_write_context(const char *file_format,

View File

@ -576,28 +576,61 @@ static const char *load_edge_element(PlyReadBuffer &file,
return nullptr;
}
static const char *skip_element(PlyReadBuffer &file,
const PlyHeader &header,
const PlyElement &element)
{
if (header.type == PlyFormatType::ASCII) {
for (int i = 0; i < element.count; i++) {
Span<char> line = file.read_line();
(void)line;
}
}
else {
Vector<uint8_t> scratch(64);
for (int i = 0; i < element.count; i++) {
for (const PlyProperty &prop : element.properties) {
skip_property(file, prop, scratch, header.type == PlyFormatType::BINARY_BE);
}
}
}
return nullptr;
}
std::unique_ptr<PlyData> import_ply_data(PlyReadBuffer &file, PlyHeader &header)
{
std::unique_ptr<PlyData> data = std::make_unique<PlyData>();
bool got_vertex = false, got_face = false, got_tristrips = false, got_edge = false;
for (const PlyElement &element : header.elements) {
const char *error = nullptr;
if (element.name == "vertex") {
error = load_vertex_element(file, header, element, data.get());
got_vertex = true;
}
else if (element.name == "face") {
error = load_face_element(file, header, element, data.get());
got_face = true;
}
else if (element.name == "tristrips") {
error = load_tristrips_element(file, header, element, data.get());
got_tristrips = true;
}
else if (element.name == "edge") {
error = load_edge_element(file, header, element, data.get());
got_edge = true;
}
else {
error = skip_element(file, header, element);
}
if (error != nullptr) {
data->error = error;
return data;
}
if (got_vertex && got_face && got_tristrips && got_edge) {
/* We have parsed all the elements we'd need, skip the rest. */
break;
}
}
return data;

View File

@ -147,6 +147,22 @@ TEST_F(ply_import_test, PlyImportColorNotFull)
import_and_check("color_not_full_b.ply", expect);
}
TEST_F(ply_import_test, PlyImportCustomDataElements)
{
Expectation expect = {600,
0,
0,
0,
0,
0,
float3(-0.78193f, 0.40659f, -1),
float3(-0.75537f, 1, -0.24777f),
float3(0, 0, 0),
float2(0, 0),
float4(0.31373f, 0, 0, 1)};
import_and_check("custom_data_elements.ply", expect);
}
TEST_F(ply_import_test, PlyImportDoubleXYZ)
{
Expectation expect = {4,

View File

@ -1192,7 +1192,7 @@ typedef enum IDRecalcFlag {
* required to address all remaining relationship cases.
* See e.g. how #BKE_library_unused_linked_data_set_tag is doing this.
*/
enum {
typedef enum eID_Index {
/* Special case: Library, should never ever depend on any other type. */
INDEX_ID_LI = 0,
@ -1273,8 +1273,9 @@ enum {
/* Special values. */
INDEX_ID_NULL,
INDEX_ID_MAX,
};
} eID_Index;
#define INDEX_ID_MAX (INDEX_ID_NULL + 1)
#ifdef __cplusplus
}

View File

@ -712,6 +712,7 @@ static const EnumPropertyItem snap_to_items[] = {
# include "BKE_pointcache.h"
# include "BKE_scene.h"
# include "BKE_screen.h"
# include "BKE_simulation.h"
# include "BKE_unit.h"
# include "NOD_composite.h"
@ -930,6 +931,8 @@ static void rna_Scene_fps_update(Main *bmain, Scene *UNUSED(active_scene), Point
* however, changes in FPS actually modifies an original skip length,
* so this we take care about here. */
SEQ_sound_update_length(bmain, scene);
/* Reset simulation states because new frame interval doesn't apply anymore. */
BKE_simulation_reset_scene(scene);
}
static void rna_Scene_listener_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)

View File

@ -374,6 +374,7 @@ DefNode(GeometryNode, GEO_NODE_MESH_TO_CURVE, 0, "MESH_TO_CURVE", MeshToCurve, "
DefNode(GeometryNode, GEO_NODE_MESH_TO_POINTS, def_geo_mesh_to_points, "MESH_TO_POINTS", MeshToPoints, "Mesh to Points", "Generate a point cloud from a mesh's vertices")
DefNode(GeometryNode, GEO_NODE_MESH_TO_SDF_VOLUME, def_geo_mesh_to_sdf_volume, "MESH_TO_SDF_VOLUME", MeshToSDFVolume, "Mesh to SDF Volume", "Create an SDF volume with the shape of the input mesh's surface")
DefNode(GeometryNode, GEO_NODE_MESH_TO_VOLUME, def_geo_mesh_to_volume, "MESH_TO_VOLUME", MeshToVolume, "Mesh to Volume", "Create a fog volume with the shape of the input mesh's surface")
DefNode(GeometryNode, GEO_NODE_MESH_TOPOLOGY_CORNERS_OF_EDGE, 0, "CORNERS_OF_EDGE", CornersOfEdge, "Corners of Edge", "Retrieve face corners connected to edges")
DefNode(GeometryNode, GEO_NODE_MESH_TOPOLOGY_CORNERS_OF_FACE, 0, "CORNERS_OF_FACE", CornersOfFace, "Corners of Face", "Retrieve corners that make up a face")
DefNode(GeometryNode, GEO_NODE_MESH_TOPOLOGY_CORNERS_OF_VERTEX, 0, "CORNERS_OF_VERTEX", CornersOfVertex, "Corners of Vertex", "Retrieve face corners connected to vertices")
DefNode(GeometryNode, GEO_NODE_MESH_TOPOLOGY_EDGES_OF_CORNER, 0, "EDGES_OF_CORNER", EdgesOfCorner, "Edges of Corner", "Retrieve the edges on both sides of a face corner")

View File

@ -130,6 +130,7 @@ set(SRC
nodes/node_geo_mesh_to_points.cc
nodes/node_geo_mesh_to_sdf_volume.cc
nodes/node_geo_mesh_to_volume.cc
nodes/node_geo_mesh_topology_corners_of_edge.cc
nodes/node_geo_mesh_topology_corners_of_face.cc
nodes/node_geo_mesh_topology_corners_of_vertex.cc
nodes/node_geo_mesh_topology_edges_of_corner.cc

View File

@ -114,6 +114,7 @@ void register_geometry_nodes()
register_node_type_geo_mesh_to_points();
register_node_type_geo_mesh_to_sdf_volume();
register_node_type_geo_mesh_to_volume();
register_node_type_geo_mesh_topology_corners_of_edge();
register_node_type_geo_mesh_topology_corners_of_face();
register_node_type_geo_mesh_topology_corners_of_vertex();
register_node_type_geo_mesh_topology_edges_of_corner();

View File

@ -111,6 +111,7 @@ void register_node_type_geo_mesh_to_curve();
void register_node_type_geo_mesh_to_points();
void register_node_type_geo_mesh_to_sdf_volume();
void register_node_type_geo_mesh_to_volume();
void register_node_type_geo_mesh_topology_corners_of_edge();
void register_node_type_geo_mesh_topology_corners_of_face();
void register_node_type_geo_mesh_topology_corners_of_vertex();
void register_node_type_geo_mesh_topology_edges_of_corner();

View File

@ -17,8 +17,8 @@ static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Bool>("End Vertex").default_value(false).hide_value().supports_field();
b.add_input<decl::Float>("Edge Cost").default_value(1.0f).hide_value().supports_field();
b.add_output<decl::Int>("Next Vertex Index").field_source();
b.add_output<decl::Float>("Total Cost").field_source();
b.add_output<decl::Int>("Next Vertex Index").reference_pass_all();
b.add_output<decl::Float>("Total Cost").reference_pass_all();
}
typedef std::pair<float, int> VertPriority;
@ -205,6 +205,12 @@ class ShortestEdgePathsCostFieldInput final : public bke::MeshFieldInput {
VArray<float>::ForContainer(std::move(cost)), ATTR_DOMAIN_POINT, domain);
}
void for_each_field_input_recursive(FunctionRef<void(const FieldInput &)> fn) const override
{
end_selection_.node().for_each_field_input_recursive(fn);
cost_.node().for_each_field_input_recursive(fn);
}
uint64_t hash() const override
{
return get_default_hash_2(end_selection_, cost_);

View File

@ -0,0 +1,197 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BKE_mesh.hh"
#include "BKE_mesh_mapping.h"
#include "BLI_task.hh"
#include "node_geometry_util.hh"
namespace blender::nodes::node_geo_mesh_topology_corners_of_edge_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Int>(N_("Edge Index"))
.implicit_field(implicit_field_inputs::index)
.description(
N_("The edge to retrieve data from. Defaults to the edge from the context"));
b.add_input<decl::Float>(N_("Weights"))
.supports_field()
.hide_value()
.description(
N_("Values that sort the corners attached to the edge"));
b.add_input<decl::Int>(N_("Sort Index"))
.min(0)
.supports_field()
.description(N_("Which of the sorted corners to output"));
b.add_output<decl::Int>(N_("Corner Index"))
.field_source_reference_all()
.description(N_("A corner of the input edge in its face's winding order, chosen by the sort index"));
b.add_output<decl::Int>(N_("Total"))
.field_source()
.reference_pass({0})
.description(N_("The number of faces or corners connected to each edge"));
}
class CornersOfEdgeInput final : public bke::MeshFieldInput {
const Field<int> edge_index_;
const Field<int> sort_index_;
const Field<float> sort_weight_;
public:
CornersOfEdgeInput(Field<int> edge_index, Field<int> sort_index, Field<float> sort_weight)
: bke::MeshFieldInput(CPPType::get<int>(), "Corner of Edge"),
edge_index_(std::move(edge_index)),
sort_index_(std::move(sort_index)),
sort_weight_(std::move(sort_weight))
{
category_ = Category::Generated;
}
GVArray get_varray_for_context(const Mesh &mesh,
const eAttrDomain domain,
const IndexMask &mask) const final
{
const IndexRange edge_range(mesh.totedge);
Array<int> map_offsets;
Array<int> map_indices;
const Span<int> corner_edges = mesh.corner_edges();
const GroupedSpan<int> edge_to_loop_map = bke::mesh::build_edge_to_loop_map(
mesh.corner_edges(), mesh.totedge, map_offsets, map_indices);
const bke::MeshFieldContext context{mesh, domain};
fn::FieldEvaluator evaluator{context, &mask};
evaluator.add(edge_index_);
evaluator.add(sort_index_);
evaluator.evaluate();
const VArray<int> edge_indices = evaluator.get_evaluated<int>(0);
const VArray<int> indices_in_sort = evaluator.get_evaluated<int>(1);
const bke::MeshFieldContext corner_context{mesh, ATTR_DOMAIN_CORNER};
fn::FieldEvaluator corner_evaluator{corner_context, corner_edges.size()};
corner_evaluator.add(sort_weight_);
corner_evaluator.evaluate();
const VArray<float> all_sort_weights = corner_evaluator.get_evaluated<float>(0);
const bool use_sorting = !all_sort_weights.is_single();
Array<int> corner_of_edge(mask.min_array_size());
mask.foreach_segment(GrainSize(1024), [&](const IndexMaskSegment segment) {
/* Reuse arrays to avoid allocation. */
Array<int64_t> corner_indices;
Array<float> sort_weights;
Array<int> sort_indices;
for (const int selection_i : segment) {
const int edge_i = edge_indices[selection_i];
const int index_in_sort = indices_in_sort[selection_i];
if (!edge_range.contains(edge_i)) {
corner_of_edge[selection_i] = 0;
continue;
}
const Span<int> corners = edge_to_loop_map[edge_i];
if (corners.is_empty()) {
corner_of_edge[selection_i] = 0;
continue;
}
const int index_in_sort_wrapped = mod_i(index_in_sort, corners.size());
if (use_sorting) {
/* Retrieve a compressed array of weights for each edge. */
sort_weights.reinitialize(corners.size());
IndexMaskMemory memory;
all_sort_weights.materialize_compressed(IndexMask::from_indices<int>(corners, memory),
sort_weights.as_mutable_span());
/* Sort a separate array of compressed indices corresponding to the compressed weights.
* This allows using `materialize_compressed` to avoid virtual function call overhead
* when accessing values in the sort weights. However, it means a separate array of
* indices within the compressed array is necessary for sorting. */
sort_indices.reinitialize(corners.size());
std::iota(sort_indices.begin(), sort_indices.end(), 0);
std::stable_sort(sort_indices.begin(), sort_indices.end(), [&](int a, int b) {
return sort_weights[a] < sort_weights[b];
});
corner_of_edge[selection_i] = corners[sort_indices[index_in_sort_wrapped]];
}
else {
corner_of_edge[selection_i] = corners[index_in_sort_wrapped];
}
}
});
return VArray<int>::ForContainer(std::move(corner_of_edge));
}
void for_each_field_input_recursive(FunctionRef<void(const FieldInput &)> fn) const override
{
edge_index_.node().for_each_field_input_recursive(fn);
sort_index_.node().for_each_field_input_recursive(fn);
sort_weight_.node().for_each_field_input_recursive(fn);
}
std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
{
return ATTR_DOMAIN_EDGE;
}
};
class CornersOfEdgeCountInput final : public bke::MeshFieldInput {
public:
CornersOfEdgeCountInput() : bke::MeshFieldInput(CPPType::get<int>(), "Edge Corner Count")
{
category_ = Category::Generated;
}
GVArray get_varray_for_context(const Mesh &mesh,
const eAttrDomain domain,
const IndexMask & /*mask*/) const final
{
if (domain != ATTR_DOMAIN_EDGE) {
return {};
}
const Span<int> corner_edges = mesh.corner_edges();
Array<int> counts(mesh.totedge, 0);
for (const int i : corner_edges.index_range()) {
counts[corner_edges[i]]++;
}
return VArray<int>::ForContainer(std::move(counts));
}
std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
{
return ATTR_DOMAIN_EDGE;
}
};
static void node_geo_exec(GeoNodeExecParams params)
{
const Field<int> edge_index = params.extract_input<Field<int>>("Edge Index");
if (params.output_is_required("Total")) {
params.set_output("Total",
Field<int>(std::make_shared<EvaluateAtIndexInput>(
edge_index,
Field<int>(std::make_shared<CornersOfEdgeCountInput>()),
ATTR_DOMAIN_EDGE)));
}
if (params.output_is_required("Corner Index")) {
params.set_output("Corner Index",
Field<int>(std::make_shared<CornersOfEdgeInput>(
edge_index,
params.extract_input<Field<int>>("Sort Index"),
params.extract_input<Field<float>>("Weights"))));
}
}
} // namespace blender::nodes::node_geo_mesh_topology_corners_of_edge_cc
void register_node_type_geo_mesh_topology_corners_of_edge()
{
namespace file_ns = blender::nodes::node_geo_mesh_topology_corners_of_edge_cc;
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_MESH_TOPOLOGY_CORNERS_OF_EDGE, "Corners of Edge", NODE_CLASS_INPUT);
ntype.geometry_node_execute = file_ns::node_geo_exec;
ntype.declare = file_ns::node_declare;
nodeRegisterType(&ntype);
}

View File

@ -364,8 +364,7 @@ DO_INLINE void inverse_fmatrix(float to[3][3], float from[3][3])
float d;
if ((d = det_fmatrix(from)) == 0) {
printf("can't build inverse");
exit(0);
// printf("can't build inverse");
}
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {

View File

@ -1507,7 +1507,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
}
else {
printf("%s: no filepath argument given\n", __func__);
exit(1);
exit(EXIT_FAILURE);
}
if (IMB_isanim(filepath)) {
@ -1522,7 +1522,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
}
else if (!IMB_ispic(filepath)) {
printf("%s: '%s' not an image file\n", __func__, filepath);
exit(1);
exit(EXIT_FAILURE);
}
if (ibuf == NULL) {
@ -1532,7 +1532,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
if (ibuf == NULL) {
printf("%s: '%s' couldn't open\n", __func__, filepath);
exit(1);
exit(EXIT_FAILURE);
}
{
@ -1547,7 +1547,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
/* GHOST will have reported the back-ends that failed to load. */
fprintf(stderr, "GHOST: unable to initialize, exiting!\n");
/* This will leak memory, it's preferable to crashing. */
exit(1);
exit(EXIT_FAILURE);
}
GHOST_AddEventConsumer(g_WS.ghost_system, consumer);
@ -1708,7 +1708,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
} /* else delete */
else {
printf("error: can't play this image type\n");
exit(0);
exit(EXIT_SUCCESS);
}
if (ps.once) {

View File

@ -1677,7 +1677,7 @@ void wm_ghost_init(bContext *C)
/* GHOST will have reported the back-ends that failed to load. */
fprintf(stderr, "GHOST: unable to initialize, exiting!\n");
/* This will leak memory, it's preferable to crashing. */
exit(1);
exit(EXIT_FAILURE);
}
#if !(defined(WIN32) || defined(__APPLE__))
g_system_backend_id = GHOST_SystemBackend();

View File

@ -543,7 +543,7 @@ static int arg_handle_print_version(int UNUSED(argc),
void *UNUSED(data))
{
print_version_full();
exit(0);
exit(EXIT_SUCCESS);
BLI_assert_unreachable();
return 0;
}
@ -816,7 +816,7 @@ static int arg_handle_print_help(int UNUSED(argc), const char **UNUSED(argv), vo
print_help(ba, false);
exit(0);
exit(EXIT_SUCCESS);
BLI_assert_unreachable();
return 0;
@ -1381,7 +1381,7 @@ static int arg_handle_env_system_set(int argc, const char **argv, void *UNUSED(d
if (argc < 2) {
fprintf(stderr, "%s requires one argument\n", argv[0]);
exit(1);
exit(EXIT_FAILURE);
BLI_assert_unreachable();
}
@ -1428,7 +1428,7 @@ static int arg_handle_playback_mode(int argc, const char **argv, void *UNUSED(da
/* This function knows to skip this argument ('-a'). */
WM_main_playanim(argc, argv);
exit(0);
exit(EXIT_SUCCESS);
}
return -2;
@ -2039,8 +2039,7 @@ static int arg_handle_python_file_run(int argc, const char **argv, void *data)
BPY_CTX_SETUP(ok = BPY_run_filepath(C, filepath, NULL));
if (!ok && app_state.exit_code_on_error.python) {
fprintf(stderr, "\nError: script failed, file: '%s', exiting.\n", argv[1]);
BPY_python_end();
exit(app_state.exit_code_on_error.python);
WM_exit(C, app_state.exit_code_on_error.python);
}
return 1;
}
@ -2079,8 +2078,7 @@ static int arg_handle_python_text_run(int argc, const char **argv, void *data)
if (!ok && app_state.exit_code_on_error.python) {
fprintf(stderr, "\nError: script failed, text: '%s', exiting.\n", argv[1]);
BPY_python_end();
exit(app_state.exit_code_on_error.python);
WM_exit(C, app_state.exit_code_on_error.python);
}
return 1;
@ -2109,8 +2107,7 @@ static int arg_handle_python_expr_run(int argc, const char **argv, void *data)
BPY_CTX_SETUP(ok = BPY_run_string_exec(C, NULL, argv[1]));
if (!ok && app_state.exit_code_on_error.python) {
fprintf(stderr, "\nError: script failed, expr: '%s', exiting.\n", argv[1]);
BPY_python_end();
exit(app_state.exit_code_on_error.python);
WM_exit(C, app_state.exit_code_on_error.python);
}
return 1;
}
@ -2549,6 +2546,8 @@ void main_args_setup(bContext *C, bArgs *ba, bool all)
BLI_args_add_case(ba, "-setaudio", 1, NULL, 0, CB(arg_handle_audio_set), NULL);
/* Pass: Processing Arguments. */
/* NOTE: Use #WM_exit for these callbacks, not `exit()`
* so temporary files are properly cleaned up. */
BLI_args_pass_set(ba, ARG_PASS_FINAL);
BLI_args_add(ba, "-f", "--render-frame", CB(arg_handle_render_frame), C);
BLI_args_add(ba, "-a", "--render-anim", CB(arg_handle_render_animation), C);

View File

@ -67,7 +67,12 @@ enum {
/** Currently use for audio devices. */
ARG_PASS_SETTINGS_FORCE = 4,
/** Actions & fall back to loading blend file. */
/**
* Actions & fall back to loading blend file.
*
* \note arguments in the final pass must use #WM_exit instead of `exit()` environment is
* properly shut-down (temporary directory deleted, etc).
*/
ARG_PASS_FINAL = 5,
};

View File

@ -790,6 +790,28 @@ class edit_generators:
return edits
class remove_struct_qualifier(EditGenerator):
"""
Remove redundant struct qualifiers:
Replace:
struct Foo
With:
Foo
"""
@staticmethod
def edit_list_from_file(_source: str, data: str, _shared_edit_data: Any) -> List[Edit]:
edits = []
# Remove `struct`
for match in re.finditer(r"\bstruct\b", data):
edits.append(Edit(
span=match.span(),
content=' ',
content_fail=' __ALWAYS_FAIL__ ',
))
return edits
class remove_return_parens(EditGenerator):
"""
Remove redundant parenthesis around return arguments: