BLI: Improve IndexMask::complement() performance #108331
@ -424,6 +424,7 @@ class NODE_MT_geometry_node_mesh_topology(Menu):
|
|||||||
|
|
||||||
def draw(self, _context):
|
def draw(self, _context):
|
||||||
layout = self.layout
|
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, "GeometryNodeCornersOfFace")
|
||||||
node_add_menu.add_node_type(layout, "GeometryNodeCornersOfVertex")
|
node_add_menu.add_node_type(layout, "GeometryNodeCornersOfVertex")
|
||||||
node_add_menu.add_node_type(layout, "GeometryNodeEdgesOfCorner")
|
node_add_menu.add_node_type(layout, "GeometryNodeEdgesOfCorner")
|
||||||
|
@ -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_clear(void);
|
||||||
void BKE_material_copybuf_free(void);
|
void BKE_material_copybuf_free(void);
|
||||||
void BKE_material_copybuf_copy(struct Main *bmain, struct Material *ma);
|
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);
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
|
@ -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_SIMULATION_OUTPUT 2101
|
||||||
#define GEO_NODE_INPUT_SIGNED_DISTANCE 2102
|
#define GEO_NODE_INPUT_SIGNED_DISTANCE 2102
|
||||||
#define GEO_NODE_SAMPLE_VOLUME 2103
|
#define GEO_NODE_SAMPLE_VOLUME 2103
|
||||||
|
#define GEO_NODE_MESH_TOPOLOGY_CORNERS_OF_EDGE 2104
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
|
@ -17,6 +17,8 @@ void BKE_simulation_data_update(struct Depsgraph *depsgraph,
|
|||||||
struct Scene *scene,
|
struct Scene *scene,
|
||||||
struct Simulation *simulation);
|
struct Simulation *simulation);
|
||||||
|
|
||||||
|
void BKE_simulation_reset_scene(Scene *scene);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -162,6 +162,8 @@ class ModifierSimulationCache {
|
|||||||
CacheState cache_state_ = CacheState::Valid;
|
CacheState cache_state_ = CacheState::Valid;
|
||||||
bool failed_finding_bake_ = false;
|
bool failed_finding_bake_ = false;
|
||||||
|
|
||||||
|
float last_fps_ = 0.0f;
|
||||||
|
|
||||||
void try_discover_bake(StringRefNull absolute_bake_dir);
|
void try_discover_bake(StringRefNull absolute_bake_dir);
|
||||||
|
|
||||||
bool has_state_at_frame(const SubFrame &frame) const;
|
bool has_state_at_frame(const SubFrame &frame) const;
|
||||||
|
@ -518,7 +518,7 @@ void BKE_collection_add_from_collection(Main *bmain,
|
|||||||
bool is_instantiated = false;
|
bool is_instantiated = false;
|
||||||
|
|
||||||
FOREACH_SCENE_COLLECTION_BEGIN (scene, collection) {
|
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_find_child(collection, collection_src))
|
||||||
{
|
{
|
||||||
collection_child_add(collection, collection_dst, 0, true);
|
collection_child_add(collection, collection_dst, 0, true);
|
||||||
|
@ -176,11 +176,9 @@ void legacy_gpencil_to_grease_pencil(Main &bmain, GreasePencil &grease_pencil, b
|
|||||||
{
|
{
|
||||||
using namespace blender::bke::greasepencil;
|
using namespace blender::bke::greasepencil;
|
||||||
|
|
||||||
int num_layers = 0;
|
|
||||||
int num_drawings = 0;
|
int num_drawings = 0;
|
||||||
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd.layers) {
|
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd.layers) {
|
||||||
num_drawings += BLI_listbase_count(&gpl->frames);
|
num_drawings += BLI_listbase_count(&gpl->frames);
|
||||||
num_layers++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
grease_pencil.drawing_array_size = num_drawings;
|
grease_pencil.drawing_array_size = num_drawings;
|
||||||
|
@ -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
|
/* Only remap new local ID's pointers, we don't want to force our new overrides onto our whole
|
||||||
* existing linked IDs usages. */
|
* existing linked IDs usages. */
|
||||||
if (success) {
|
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) {
|
if (id_hierarchy_root_reference != nullptr) {
|
||||||
id_hierarchy_root = id_hierarchy_root_reference->newid;
|
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
|
/* 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. */
|
* 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) {
|
if ((other_id->tag & LIB_TAG_DOIT) != 0 && other_id->lib != id_root_reference->lib) {
|
||||||
|
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);
|
BLI_linklist_prepend(&relinked_ids, other_id);
|
||||||
|
}
|
||||||
|
|
||||||
if (ID_IS_OVERRIDE_LIBRARY_REAL(other_id) &&
|
if (ID_IS_OVERRIDE_LIBRARY_REAL(other_id) &&
|
||||||
other_id->override_library->hierarchy_root == id_hierarchy_root)
|
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. */
|
* 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);
|
GSet *all_objects_in_scene = BKE_scene_objects_as_gset(scene, nullptr);
|
||||||
|
|
||||||
|
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
|
/* Instantiating the root collection or object should never be needed in resync case, since the
|
||||||
* old override would be remapped to the new one. */
|
* 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))
|
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)) {
|
switch (GS(id_root->name)) {
|
||||||
case ID_GR: {
|
case ID_GR: {
|
||||||
Object *ob_reference = id_instance_hint != nullptr && GS(id_instance_hint->name) == ID_OB ?
|
Object *ob_reference = id_instance_hint != nullptr && GS(id_instance_hint->name) == ID_OB ?
|
||||||
|
@ -72,118 +72,63 @@ void BKE_main_free(Main *mainvar)
|
|||||||
#if 1
|
#if 1
|
||||||
BKE_id_free_ex(mainvar, id, free_flag, false);
|
BKE_id_free_ex(mainvar, id, free_flag, false);
|
||||||
#else
|
#else
|
||||||
/* errors freeing ID's can be hard to track down,
|
/* Errors freeing ID's can be hard to track down,
|
||||||
* enable this so valgrind will give the line number in its error log */
|
* enable this so VALGRIND or ASAN will give the line number in its error log. */
|
||||||
switch (a) {
|
|
||||||
case 0:
|
# define CASE_ID_INDEX(id_index) \
|
||||||
BKE_id_free_ex(mainvar, id, free_flag, false);
|
case id_index: \
|
||||||
break;
|
BKE_id_free_ex(mainvar, id, free_flag, false); \
|
||||||
case 1:
|
break
|
||||||
BKE_id_free_ex(mainvar, id, free_flag, false);
|
|
||||||
break;
|
switch ((eID_Index)a) {
|
||||||
case 2:
|
CASE_ID_INDEX(INDEX_ID_LI);
|
||||||
BKE_id_free_ex(mainvar, id, free_flag, false);
|
CASE_ID_INDEX(INDEX_ID_IP);
|
||||||
break;
|
CASE_ID_INDEX(INDEX_ID_AC);
|
||||||
case 3:
|
CASE_ID_INDEX(INDEX_ID_GD_LEGACY);
|
||||||
BKE_id_free_ex(mainvar, id, free_flag, false);
|
CASE_ID_INDEX(INDEX_ID_NT);
|
||||||
break;
|
CASE_ID_INDEX(INDEX_ID_VF);
|
||||||
case 4:
|
CASE_ID_INDEX(INDEX_ID_TXT);
|
||||||
BKE_id_free_ex(mainvar, id, free_flag, false);
|
CASE_ID_INDEX(INDEX_ID_SO);
|
||||||
break;
|
CASE_ID_INDEX(INDEX_ID_MSK);
|
||||||
case 5:
|
CASE_ID_INDEX(INDEX_ID_IM);
|
||||||
BKE_id_free_ex(mainvar, id, free_flag, false);
|
CASE_ID_INDEX(INDEX_ID_MC);
|
||||||
break;
|
CASE_ID_INDEX(INDEX_ID_TE);
|
||||||
case 6:
|
CASE_ID_INDEX(INDEX_ID_MA);
|
||||||
BKE_id_free_ex(mainvar, id, free_flag, false);
|
CASE_ID_INDEX(INDEX_ID_LS);
|
||||||
break;
|
CASE_ID_INDEX(INDEX_ID_WO);
|
||||||
case 7:
|
CASE_ID_INDEX(INDEX_ID_CF);
|
||||||
BKE_id_free_ex(mainvar, id, free_flag, false);
|
CASE_ID_INDEX(INDEX_ID_SIM);
|
||||||
break;
|
CASE_ID_INDEX(INDEX_ID_PA);
|
||||||
case 8:
|
CASE_ID_INDEX(INDEX_ID_KE);
|
||||||
BKE_id_free_ex(mainvar, id, free_flag, false);
|
CASE_ID_INDEX(INDEX_ID_AR);
|
||||||
break;
|
CASE_ID_INDEX(INDEX_ID_ME);
|
||||||
case 9:
|
CASE_ID_INDEX(INDEX_ID_CU_LEGACY);
|
||||||
BKE_id_free_ex(mainvar, id, free_flag, false);
|
CASE_ID_INDEX(INDEX_ID_MB);
|
||||||
break;
|
CASE_ID_INDEX(INDEX_ID_CV);
|
||||||
case 10:
|
CASE_ID_INDEX(INDEX_ID_PT);
|
||||||
BKE_id_free_ex(mainvar, id, free_flag, false);
|
CASE_ID_INDEX(INDEX_ID_VO);
|
||||||
break;
|
CASE_ID_INDEX(INDEX_ID_LT);
|
||||||
case 11:
|
CASE_ID_INDEX(INDEX_ID_LA);
|
||||||
BKE_id_free_ex(mainvar, id, free_flag, false);
|
CASE_ID_INDEX(INDEX_ID_CA);
|
||||||
break;
|
CASE_ID_INDEX(INDEX_ID_SPK);
|
||||||
case 12:
|
CASE_ID_INDEX(INDEX_ID_LP);
|
||||||
BKE_id_free_ex(mainvar, id, free_flag, false);
|
CASE_ID_INDEX(INDEX_ID_OB);
|
||||||
break;
|
CASE_ID_INDEX(INDEX_ID_GR);
|
||||||
case 13:
|
CASE_ID_INDEX(INDEX_ID_PAL);
|
||||||
BKE_id_free_ex(mainvar, id, free_flag, false);
|
CASE_ID_INDEX(INDEX_ID_PC);
|
||||||
break;
|
CASE_ID_INDEX(INDEX_ID_BR);
|
||||||
case 14:
|
CASE_ID_INDEX(INDEX_ID_SCE);
|
||||||
BKE_id_free_ex(mainvar, id, free_flag, false);
|
CASE_ID_INDEX(INDEX_ID_SCR);
|
||||||
break;
|
CASE_ID_INDEX(INDEX_ID_WS);
|
||||||
case 15:
|
CASE_ID_INDEX(INDEX_ID_WM);
|
||||||
BKE_id_free_ex(mainvar, id, free_flag, false);
|
case INDEX_ID_NULL: {
|
||||||
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:
|
|
||||||
BLI_assert_unreachable();
|
BLI_assert_unreachable();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# undef CASE_ID_INDEX
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
BLI_listbase_clear(lb);
|
BLI_listbase_clear(lb);
|
||||||
|
@ -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).
|
* (the kind of data that would have to be copied).
|
||||||
*
|
*
|
||||||
* \note Keep in sync with #material_free_data.
|
* \note Keep in sync with #material_free_data.
|
||||||
|
* \note Doesn't handle animation data (`ma->adt`).
|
||||||
*/
|
*/
|
||||||
static void material_clear_data(ID *id)
|
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
|
/** \name Material Copy/Paste
|
||||||
* \note matcopybuf.nodetree does _NOT_ use ID's
|
*
|
||||||
* \todo matcopybuf.nodetree's node->id's are NOT validated, this will crash!
|
* 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 Material matcopybuf;
|
||||||
static short matcopied = 0;
|
static short matcopied = 0;
|
||||||
|
|
||||||
@ -1949,18 +1969,35 @@ void BKE_material_copybuf_clear(void)
|
|||||||
matcopied = 0;
|
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)
|
void BKE_material_copybuf_free(void)
|
||||||
{
|
{
|
||||||
BLI_assert(matcopybuf.id.icon_id == 0);
|
material_copybuf_assert_is_valid();
|
||||||
if (matcopybuf.nodetree) {
|
|
||||||
BLI_assert(!matcopybuf.nodetree->id.py_instance); /* Or call #BKE_libblock_free_data_py. */
|
|
||||||
}
|
|
||||||
material_free_data(&matcopybuf.id);
|
material_free_data(&matcopybuf.id);
|
||||||
matcopied = 0;
|
matcopied = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BKE_material_copybuf_copy(Main *bmain, Material *ma)
|
void BKE_material_copybuf_copy(Main *bmain, Material *ma)
|
||||||
{
|
{
|
||||||
|
material_copybuf_assert_is_valid();
|
||||||
|
|
||||||
if (matcopied) {
|
if (matcopied) {
|
||||||
BKE_material_copybuf_free();
|
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. */
|
/* Ensure dangling pointers are never copied back into a material. */
|
||||||
material_clear_data(&matcopybuf.id);
|
material_clear_data(&matcopybuf.id);
|
||||||
|
|
||||||
|
/* Unhandled by materials generic data functions. */
|
||||||
|
matcopybuf.adt = nullptr;
|
||||||
|
|
||||||
if (ma->nodetree != 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 = 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. */
|
/* TODO: Duplicate Engine Settings and set runtime to nullptr. */
|
||||||
matcopied = 1;
|
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) {
|
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);
|
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. */
|
/* Handles freeing nodes and and other run-time data (previews) for e.g. */
|
||||||
material_free_data(&ma->id);
|
material_free_data(&ma->id);
|
||||||
|
|
||||||
id = (ma->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 = blender::dna::shallow_copy(matcopybuf);
|
||||||
(ma->id) = id;
|
|
||||||
|
ma->id = backup.id;
|
||||||
|
ma->adt = backup.adt;
|
||||||
|
}
|
||||||
|
|
||||||
if (matcopybuf.nodetree != nullptr) {
|
if (matcopybuf.nodetree != nullptr) {
|
||||||
|
BLI_assert(matcopybuf.nodetree->adt == nullptr);
|
||||||
ma->nodetree = blender::bke::ntreeCopyTree_ex(matcopybuf.nodetree, bmain, false);
|
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,
|
/* Important to run this when the embedded tree if freed,
|
||||||
* otherwise the depsgraph holds a reference to the (now freed) `ma->nodetree`.
|
* 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);
|
DEG_relations_tag_update(bmain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
material_copybuf_assert_is_valid();
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** \} */
|
||||||
|
|
||||||
void BKE_material_eval(struct Depsgraph *depsgraph, Material *material)
|
void BKE_material_eval(struct Depsgraph *depsgraph, Material *material)
|
||||||
{
|
{
|
||||||
DEG_debug_print_eval(depsgraph, __func__, material->id.name, material);
|
DEG_debug_print_eval(depsgraph, __func__, material->id.name, material);
|
||||||
|
@ -279,7 +279,6 @@ class BMeshFairingContext : public FairingContext {
|
|||||||
|
|
||||||
/* This initializes both the bmloop and the vlmap for bmesh in a single loop. */
|
/* This initializes both the bmloop and the vlmap for bmesh in a single loop. */
|
||||||
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
|
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
|
||||||
int loop_count = 0;
|
|
||||||
const int vert_index = BM_elem_index_get(v);
|
const int vert_index = BM_elem_index_get(v);
|
||||||
vert_to_loop_offsets_[vert_index] = index_iter;
|
vert_to_loop_offsets_[vert_index] = index_iter;
|
||||||
BM_ITER_ELEM (l, &loop_iter, v, BM_LOOPS_OF_VERT) {
|
BM_ITER_ELEM (l, &loop_iter, v, BM_LOOPS_OF_VERT) {
|
||||||
@ -287,7 +286,6 @@ class BMeshFairingContext : public FairingContext {
|
|||||||
bmloop_[loop_index] = l;
|
bmloop_[loop_index] = l;
|
||||||
vert_to_loop_indices_[index_iter] = loop_index;
|
vert_to_loop_indices_[index_iter] = loop_index;
|
||||||
index_iter++;
|
index_iter++;
|
||||||
loop_count++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vert_to_loop_offsets_.last() = index_iter;
|
vert_to_loop_offsets_.last() = index_iter;
|
||||||
|
@ -430,12 +430,14 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
|
|||||||
if (j > src_poly.start()) {
|
if (j > src_poly.start()) {
|
||||||
mirrorj += result_polys[mirror_i].size() - (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]);
|
copy_v3_v3(loop_normals[mirrorj], loop_normals[j]);
|
||||||
mul_m4_v3(mtx_nor, loop_normals[mirrorj]);
|
mul_m4_v3(mtx_nor, loop_normals[mirrorj]);
|
||||||
|
|
||||||
const int space_index = lnors_spacearr.corner_space_indices[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],
|
blender::bke::mesh::lnor_space_custom_normal_to_data(&lnors_spacearr.spaces[space_index],
|
||||||
loop_normals[mirrorj],
|
orig_normal,
|
||||||
loop_normals[mirrorj],
|
loop_normals[mirrorj],
|
||||||
clnors[mirrorj]);
|
clnors[mirrorj]);
|
||||||
}
|
}
|
||||||
|
@ -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_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);
|
DEG_id_tag_update(&orig_me->id, ID_RECALC_GEOMETRY_ALL_MODES);
|
||||||
BKE_mesh_tessface_clear(orig_me);
|
BKE_mesh_tessface_clear(orig_me);
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "DNA_ID.h"
|
#include "DNA_ID.h"
|
||||||
#include "DNA_defaults.h"
|
#include "DNA_defaults.h"
|
||||||
|
#include "DNA_modifier_types.h"
|
||||||
#include "DNA_scene_types.h"
|
#include "DNA_scene_types.h"
|
||||||
#include "DNA_simulation_types.h"
|
#include "DNA_simulation_types.h"
|
||||||
|
|
||||||
@ -24,15 +25,18 @@
|
|||||||
|
|
||||||
#include "BKE_anim_data.h"
|
#include "BKE_anim_data.h"
|
||||||
#include "BKE_animsys.h"
|
#include "BKE_animsys.h"
|
||||||
|
#include "BKE_collection.h"
|
||||||
#include "BKE_customdata.h"
|
#include "BKE_customdata.h"
|
||||||
#include "BKE_idtype.h"
|
#include "BKE_idtype.h"
|
||||||
#include "BKE_lib_id.h"
|
#include "BKE_lib_id.h"
|
||||||
#include "BKE_lib_query.h"
|
#include "BKE_lib_query.h"
|
||||||
#include "BKE_lib_remap.h"
|
#include "BKE_lib_remap.h"
|
||||||
#include "BKE_main.h"
|
#include "BKE_main.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
#include "BKE_node.hh"
|
#include "BKE_node.hh"
|
||||||
#include "BKE_pointcache.h"
|
#include "BKE_pointcache.h"
|
||||||
#include "BKE_simulation.h"
|
#include "BKE_simulation.h"
|
||||||
|
#include "BKE_simulation_state.hh"
|
||||||
|
|
||||||
#include "NOD_geometry.h"
|
#include "NOD_geometry.h"
|
||||||
|
|
||||||
@ -181,3 +185,17 @@ void BKE_simulation_data_update(Depsgraph * /*depsgraph*/,
|
|||||||
Simulation * /*simulation*/)
|
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;
|
||||||
|
}
|
||||||
|
@ -2766,16 +2766,20 @@ void MATERIAL_OT_copy(wmOperatorType *ot)
|
|||||||
/** \name Material Paste Operator
|
/** \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 *>(
|
Material *ma = static_cast<Material *>(
|
||||||
CTX_data_pointer_get_type(C, "material", &RNA_Material).data);
|
CTX_data_pointer_get_type(C, "material", &RNA_Material).data);
|
||||||
|
|
||||||
if (ma == nullptr) {
|
if (ma == nullptr) {
|
||||||
|
BKE_report(op->reports, RPT_WARNING, "Cannot paste without a material");
|
||||||
return OPERATOR_CANCELLED;
|
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);
|
DEG_id_tag_update(&ma->id, ID_RECALC_COPY_ON_WRITE);
|
||||||
WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, ma);
|
WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, ma);
|
||||||
|
@ -548,11 +548,12 @@ static const EnumPropertyItem prop_lib_op_selection_set[] = {
|
|||||||
{0, nullptr, 0, nullptr, nullptr},
|
{0, nullptr, 0, nullptr, nullptr},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void outliner_do_libdata_operation_selection_set(bContext *C,
|
static bool outliner_do_libdata_operation_selection_set_element(
|
||||||
|
bContext *C,
|
||||||
ReportList *reports,
|
ReportList *reports,
|
||||||
Scene *scene,
|
Scene *scene,
|
||||||
SpaceOutliner *space_outliner,
|
TreeElement *element,
|
||||||
const ListBase &subtree,
|
TreeStoreElem *tselem,
|
||||||
const bool has_parent_selected,
|
const bool has_parent_selected,
|
||||||
outliner_operation_fn operation_fn,
|
outliner_operation_fn operation_fn,
|
||||||
eOutlinerLibOpSelectionSet selection_set,
|
eOutlinerLibOpSelectionSet selection_set,
|
||||||
@ -565,12 +566,7 @@ static void outliner_do_libdata_operation_selection_set(bContext *C,
|
|||||||
OUTLINER_LIB_LIB_SELECTIONSET_CONTENT,
|
OUTLINER_LIB_LIB_SELECTIONSET_CONTENT,
|
||||||
OUTLINER_LIB_LIB_SELECTIONSET_SELECTED_AND_CONTENT);
|
OUTLINER_LIB_LIB_SELECTIONSET_SELECTED_AND_CONTENT);
|
||||||
|
|
||||||
LISTBASE_FOREACH_MUTABLE (TreeElement *, element, &subtree) {
|
const bool is_selected = tselem->flag & TSE_SELECTED;
|
||||||
/* 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 ((is_selected && do_selected) || (has_parent_selected && do_content)) {
|
||||||
if (((tselem->type == TSE_SOME_ID) && (element->idcode != 0)) ||
|
if (((tselem->type == TSE_SOME_ID) && (element->idcode != 0)) ||
|
||||||
tselem->type == TSE_LAYER_COLLECTION)
|
tselem->type == TSE_LAYER_COLLECTION)
|
||||||
@ -579,6 +575,34 @@ static void outliner_do_libdata_operation_selection_set(bContext *C,
|
|||||||
operation_fn(C, reports, scene, element, tsep, tselem, user_data);
|
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,
|
||||||
|
SpaceOutliner *space_outliner,
|
||||||
|
const ListBase &subtree,
|
||||||
|
const bool has_parent_selected,
|
||||||
|
outliner_operation_fn operation_fn,
|
||||||
|
eOutlinerLibOpSelectionSet selection_set,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
LISTBASE_FOREACH_MUTABLE (TreeElement *, element, &subtree) {
|
||||||
|
/* Get needed data out in case element gets freed. */
|
||||||
|
TreeStoreElem *tselem = TREESTORE(element);
|
||||||
|
const ListBase subtree = element->subtree;
|
||||||
|
|
||||||
|
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
|
/* 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. */
|
* 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,
|
SpaceOutliner *space_outliner,
|
||||||
outliner_operation_fn operation_fn,
|
outliner_operation_fn operation_fn,
|
||||||
eOutlinerLibOpSelectionSet selection_set,
|
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,
|
outliner_do_libdata_operation_selection_set(C,
|
||||||
reports,
|
reports,
|
||||||
scene,
|
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)) {
|
if (!ID_IS_OVERRIDABLE_LIBRARY_HIERARCHY(id_root_reference)) {
|
||||||
BKE_reportf(reports,
|
if (ID_IS_LINKED(id_root_reference)) {
|
||||||
|
BKE_reportf(
|
||||||
|
reports,
|
||||||
RPT_WARNING,
|
RPT_WARNING,
|
||||||
"Could not create library override from data-block '%s', as it is not overridable",
|
"Could not create library override from data-block '%s', as it is not overridable",
|
||||||
id_root_reference->name);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BLI_assert(do_hierarchy);
|
BLI_assert(do_hierarchy);
|
||||||
UNUSED_VARS_NDEBUG(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);
|
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)) {
|
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,
|
space_outliner,
|
||||||
id_override_library_create_hierarchy_pre_process_fn,
|
id_override_library_create_hierarchy_pre_process_fn,
|
||||||
selection_set,
|
selection_set,
|
||||||
&override_data);
|
&override_data,
|
||||||
|
true);
|
||||||
|
|
||||||
id_override_library_create_hierarchy_process(C, op->reports, override_data);
|
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,
|
space_outliner,
|
||||||
id_override_library_reset_fn,
|
id_override_library_reset_fn,
|
||||||
selection_set,
|
selection_set,
|
||||||
&override_data);
|
&override_data,
|
||||||
|
false);
|
||||||
ED_undo_push(C, "Reset Overridden Data");
|
ED_undo_push(C, "Reset Overridden Data");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1832,7 +1900,8 @@ static int outliner_liboverride_operation_exec(bContext *C, wmOperator *op)
|
|||||||
space_outliner,
|
space_outliner,
|
||||||
id_override_library_clear_single_fn,
|
id_override_library_clear_single_fn,
|
||||||
selection_set,
|
selection_set,
|
||||||
nullptr);
|
nullptr,
|
||||||
|
false);
|
||||||
ED_undo_push(C, "Clear Overridden Data");
|
ED_undo_push(C, "Clear Overridden Data");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1846,7 +1915,8 @@ static int outliner_liboverride_operation_exec(bContext *C, wmOperator *op)
|
|||||||
space_outliner,
|
space_outliner,
|
||||||
id_override_library_resync_fn,
|
id_override_library_resync_fn,
|
||||||
OUTLINER_LIB_SELECTIONSET_SELECTED,
|
OUTLINER_LIB_SELECTIONSET_SELECTED,
|
||||||
&override_data);
|
&override_data,
|
||||||
|
false);
|
||||||
|
|
||||||
id_override_library_resync_hierarchy_process(C, op->reports, override_data);
|
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,
|
space_outliner,
|
||||||
id_override_library_resync_fn,
|
id_override_library_resync_fn,
|
||||||
OUTLINER_LIB_SELECTIONSET_SELECTED,
|
OUTLINER_LIB_SELECTIONSET_SELECTED,
|
||||||
&override_data);
|
&override_data,
|
||||||
|
false);
|
||||||
|
|
||||||
id_override_library_resync_hierarchy_process(C, op->reports, override_data);
|
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,
|
space_outliner,
|
||||||
id_override_library_delete_hierarchy_fn,
|
id_override_library_delete_hierarchy_fn,
|
||||||
OUTLINER_LIB_SELECTIONSET_SELECTED,
|
OUTLINER_LIB_SELECTIONSET_SELECTED,
|
||||||
&override_data);
|
&override_data,
|
||||||
|
false);
|
||||||
|
|
||||||
id_override_library_delete_hierarchy_process(C, op->reports, override_data);
|
id_override_library_delete_hierarchy_process(C, op->reports, override_data);
|
||||||
|
|
||||||
|
@ -22,16 +22,16 @@ set(INC_SYS
|
|||||||
)
|
)
|
||||||
|
|
||||||
set(SRC
|
set(SRC
|
||||||
uvedit_buttons.c
|
uvedit_buttons.cc
|
||||||
uvedit_clipboard.cc
|
uvedit_clipboard.cc
|
||||||
uvedit_clipboard_graph_iso.cc
|
uvedit_clipboard_graph_iso.cc
|
||||||
uvedit_draw.c
|
uvedit_draw.cc
|
||||||
uvedit_islands.cc
|
uvedit_islands.cc
|
||||||
uvedit_ops.c
|
uvedit_ops.cc
|
||||||
uvedit_path.c
|
uvedit_path.cc
|
||||||
uvedit_rip.c
|
uvedit_rip.cc
|
||||||
uvedit_select.c
|
uvedit_select.cc
|
||||||
uvedit_smart_stitch.c
|
uvedit_smart_stitch.cc
|
||||||
uvedit_unwrap_ops.cc
|
uvedit_unwrap_ops.cc
|
||||||
|
|
||||||
uvedit_clipboard_graph_iso.hh
|
uvedit_clipboard_graph_iso.hh
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
* \ingroup eduv
|
* \ingroup eduv
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <cstdio>
|
||||||
#include <string.h>
|
#include <cstring>
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
@ -198,7 +198,7 @@ static void uvedit_vertex_buttons(const bContext *C, uiBlock *block)
|
|||||||
MEM_freeN(objects);
|
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);
|
SpaceImage *sima = CTX_wm_space_image(C);
|
||||||
Scene *scene = CTX_data_scene(C);
|
Scene *scene = CTX_data_scene(C);
|
||||||
@ -238,7 +238,7 @@ static void do_uvedit_vertex(bContext *C, void *UNUSED(arg), int event)
|
|||||||
|
|
||||||
/* Panels */
|
/* 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);
|
SpaceImage *sima = CTX_wm_space_image(C);
|
||||||
if (sima->mode != SI_MODE_UV) {
|
if (sima->mode != SI_MODE_UV) {
|
||||||
@ -253,16 +253,15 @@ static void image_panel_uv(const bContext *C, Panel *panel)
|
|||||||
uiBlock *block;
|
uiBlock *block;
|
||||||
|
|
||||||
block = uiLayoutAbsoluteBlock(panel->layout);
|
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);
|
uvedit_vertex_buttons(C, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ED_uvedit_buttons_register(ARegionType *art)
|
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->idname, "IMAGE_PT_uv");
|
||||||
strcpy(pt->label, N_("UV Vertex")); /* XXX C panels unavailable through RNA bpy.types! */
|
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. */
|
/* Could be 'Item' matching 3D view, avoid new tab for two buttons. */
|
@ -237,7 +237,7 @@ static uint8_t select_next_v(uint8_t *left, uint8_t *bd)
|
|||||||
return min;
|
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;
|
uint8_t min_v = UINT8_MAX;
|
||||||
for (int i = 0; i < len; i++) {
|
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 min = UINT8_MAX;
|
||||||
uint8_t idx = UINT8_MAX;
|
uint8_t idx = UINT8_MAX;
|
||||||
|
@ -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)
|
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 (data->use_seams) {
|
||||||
if (BM_elem_flag_test(l_a->e, BM_ELEM_SEAM)) {
|
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);
|
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.offsets = uv_offsets;
|
||||||
user_data.use_seams = use_seams;
|
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]);
|
faces[j] = BM_face_at_index(bm, groups_array[faces_start + j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FaceIsland *island = static_cast<struct FaceIsland *>(
|
FaceIsland *island = static_cast<FaceIsland *>(MEM_callocN(sizeof(*island), __func__));
|
||||||
MEM_callocN(sizeof(*island), __func__));
|
|
||||||
island->faces = faces;
|
island->faces = faces;
|
||||||
island->faces_len = faces_len;
|
island->faces_len = faces_len;
|
||||||
island->offsets = uv_offsets;
|
island->offsets = uv_offsets;
|
||||||
|
@ -5,9 +5,9 @@
|
|||||||
* \ingroup eduv
|
* \ingroup eduv
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
#include <string.h>
|
#include <cstring>
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
@ -20,7 +20,6 @@
|
|||||||
#include "DNA_scene_types.h"
|
#include "DNA_scene_types.h"
|
||||||
#include "DNA_space_types.h"
|
#include "DNA_space_types.h"
|
||||||
|
|
||||||
#include "BLI_array.h"
|
|
||||||
#include "BLI_kdtree.h"
|
#include "BLI_kdtree.h"
|
||||||
#include "BLI_math.h"
|
#include "BLI_math.h"
|
||||||
#include "BLI_utildefines.h"
|
#include "BLI_utildefines.h"
|
||||||
@ -68,11 +67,11 @@ bool ED_uvedit_test(Object *obedit)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!obedit) {
|
if (!obedit) {
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obedit->type != OB_MESH) {
|
if (obedit->type != OB_MESH) {
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
em = BKE_editmesh_from_object(obedit);
|
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);
|
Object *ob = CTX_data_active_object(C);
|
||||||
|
|
||||||
if (ob && ob->type == OB_MESH) {
|
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;
|
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) :
|
Material *ma = DEG_is_evaluated_object(ob) ? BKE_object_material_get_eval(ob, mat_nr) :
|
||||||
BKE_object_material_get(ob, mat_nr);
|
BKE_object_material_get(ob, mat_nr);
|
||||||
bNodeTree *ntree = (ma && ma->use_nodes) ? ma->nodetree : NULL;
|
bNodeTree *ntree = (ma && ma->use_nodes) ? ma->nodetree : nullptr;
|
||||||
bNode *node = (ntree) ? nodeGetActiveTexture(ntree) : NULL;
|
bNode *node = (ntree) ? nodeGetActiveTexture(ntree) : nullptr;
|
||||||
|
|
||||||
if (node && is_image_texture_node(node)) {
|
if (node && is_image_texture_node(node)) {
|
||||||
if (r_ima) {
|
if (r_ima) {
|
||||||
@ -131,7 +130,7 @@ bool ED_object_get_active_image(Object *ob,
|
|||||||
*r_iuser = &((NodeTexEnvironment *)node->storage)->iuser;
|
*r_iuser = &((NodeTexEnvironment *)node->storage)->iuser;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*r_iuser = NULL;
|
*r_iuser = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (r_node) {
|
if (r_node) {
|
||||||
@ -144,10 +143,10 @@ bool ED_object_get_active_image(Object *ob,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (r_ima) {
|
if (r_ima) {
|
||||||
*r_ima = NULL;
|
*r_ima = nullptr;
|
||||||
}
|
}
|
||||||
if (r_iuser) {
|
if (r_iuser) {
|
||||||
*r_iuser = NULL;
|
*r_iuser = nullptr;
|
||||||
}
|
}
|
||||||
if (r_node) {
|
if (r_node) {
|
||||||
*r_node = 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)
|
void ED_object_assign_active_image(Main *bmain, Object *ob, int mat_nr, Image *ima)
|
||||||
{
|
{
|
||||||
Material *ma = BKE_object_material_get(ob, mat_nr);
|
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)) {
|
if (node && is_image_texture_node(node)) {
|
||||||
node->id = &ima->id;
|
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);
|
return (sel != 0);
|
||||||
}
|
}
|
||||||
@ -317,10 +316,10 @@ bool ED_uvedit_center_from_pivot_ex(SpaceImage *sima,
|
|||||||
case V3D_AROUND_CURSOR: {
|
case V3D_AROUND_CURSOR: {
|
||||||
copy_v2_v2(r_center, sima->cursor);
|
copy_v2_v2(r_center, sima->cursor);
|
||||||
changed = true;
|
changed = true;
|
||||||
if (r_has_select != NULL) {
|
if (r_has_select != nullptr) {
|
||||||
uint objects_len = 0;
|
uint objects_len = 0;
|
||||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
|
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);
|
*r_has_select = uvedit_select_is_any_selected_multi(scene, objects, objects_len);
|
||||||
MEM_freeN(objects);
|
MEM_freeN(objects);
|
||||||
}
|
}
|
||||||
@ -329,10 +328,10 @@ bool ED_uvedit_center_from_pivot_ex(SpaceImage *sima,
|
|||||||
default: {
|
default: {
|
||||||
uint objects_len = 0;
|
uint objects_len = 0;
|
||||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
|
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);
|
changed = ED_uvedit_center_multi(scene, objects, objects_len, r_center, mode);
|
||||||
MEM_freeN(objects);
|
MEM_freeN(objects);
|
||||||
if (r_has_select != NULL) {
|
if (r_has_select != nullptr) {
|
||||||
*r_has_select = changed;
|
*r_has_select = changed;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -344,7 +343,7 @@ bool ED_uvedit_center_from_pivot_ex(SpaceImage *sima,
|
|||||||
bool ED_uvedit_center_from_pivot(
|
bool ED_uvedit_center_from_pivot(
|
||||||
SpaceImage *sima, Scene *scene, ViewLayer *view_layer, float r_center[2], char mode)
|
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
|
/** \name Weld Align Operator
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
typedef enum eUVWeldAlign {
|
enum eUVWeldAlign {
|
||||||
UV_STRAIGHTEN,
|
UV_STRAIGHTEN,
|
||||||
UV_STRAIGHTEN_X,
|
UV_STRAIGHTEN_X,
|
||||||
UV_STRAIGHTEN_Y,
|
UV_STRAIGHTEN_Y,
|
||||||
@ -361,7 +360,7 @@ typedef enum eUVWeldAlign {
|
|||||||
UV_ALIGN_X,
|
UV_ALIGN_X,
|
||||||
UV_ALIGN_Y,
|
UV_ALIGN_Y,
|
||||||
UV_WELD,
|
UV_WELD,
|
||||||
} eUVWeldAlign;
|
};
|
||||||
|
|
||||||
static bool uvedit_uv_align_weld(Scene *scene,
|
static bool uvedit_uv_align_weld(Scene *scene,
|
||||||
BMesh *bm,
|
BMesh *bm,
|
||||||
@ -384,7 +383,7 @@ static bool uvedit_uv_align_weld(Scene *scene,
|
|||||||
if (!uvedit_uv_select_test(scene, l, offsets)) {
|
if (!uvedit_uv_select_test(scene, l, offsets)) {
|
||||||
continue;
|
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 (ELEM(tool, UV_ALIGN_X, UV_WELD)) {
|
||||||
if (luv[0] != cent[0]) {
|
if (luv[0] != cent[0]) {
|
||||||
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. */
|
/** Bitwise-or together, then choose loop with highest value. */
|
||||||
typedef enum eUVEndPointPrecedence {
|
enum eUVEndPointPrecedence {
|
||||||
UVEP_INVALID = 0,
|
UVEP_INVALID = 0,
|
||||||
UVEP_SELECTED = (1 << 0),
|
UVEP_SELECTED = (1 << 0),
|
||||||
UVEP_PINNED = (1 << 1), /* i.e. Pinned verts are preferred to selected. */
|
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)
|
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);
|
UvElementMap *element_map = BM_uv_element_map_create(bm, scene, true, false, true, true);
|
||||||
if (element_map == NULL) {
|
if (element_map == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -567,7 +567,7 @@ static void uv_weld_align(bContext *C, eUVWeldAlign tool)
|
|||||||
|
|
||||||
uint objects_len = 0;
|
uint objects_len = 0;
|
||||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
|
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) {
|
if (tool == UV_ALIGN_AUTO) {
|
||||||
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
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) {
|
if (changed) {
|
||||||
uvedit_live_unwrap_update(sima, scene, obedit);
|
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);
|
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)
|
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;
|
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"},
|
"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_X, "ALIGN_X", 0, "Align X", "Align UVs on X axis"},
|
||||||
{UV_ALIGN_Y, "ALIGN_Y", 0, "Align Y", "Align UVs on Y 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 */
|
/* identifiers */
|
||||||
@ -697,14 +697,14 @@ static int uv_remove_doubles_to_selected(bContext *C, wmOperator *op)
|
|||||||
|
|
||||||
uint objects_len = 0;
|
uint objects_len = 0;
|
||||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
|
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.
|
/* Maximum index of an objects[i]'s UVs in UV_arr.
|
||||||
* It helps find which UV in *mloopuv_arr belongs to which object. */
|
* It helps find which UV in *mloopuv_arr belongs to which object. */
|
||||||
uint *ob_mloopuv_max_idx = MEM_callocN(sizeof(uint) * objects_len,
|
uint *ob_mloopuv_max_idx = static_cast<uint *>(
|
||||||
"uv_remove_doubles_selected.ob_mloopuv_max_idx");
|
MEM_callocN(sizeof(uint) * objects_len, __func__));
|
||||||
|
|
||||||
/* Calculate max possible number of kdtree nodes. */
|
/* Calculate max possible number of kdtree nodes. */
|
||||||
int uv_maxlen = 0;
|
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);
|
KDTree_2d *tree = BLI_kdtree_2d_new(uv_maxlen);
|
||||||
|
|
||||||
int *duplicates = NULL;
|
blender::Vector<int> duplicates;
|
||||||
BLI_array_declare(duplicates);
|
blender::Vector<float *> mloopuv_arr;
|
||||||
|
|
||||||
float **mloopuv_arr = NULL;
|
|
||||||
BLI_array_declare(mloopuv_arr);
|
|
||||||
|
|
||||||
int mloopuv_count = 0; /* Also used for *duplicates count. */
|
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)) {
|
if (uvedit_uv_select_test(scene, l, offsets)) {
|
||||||
float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
|
float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
|
||||||
BLI_kdtree_2d_insert(tree, mloopuv_count, luv);
|
BLI_kdtree_2d_insert(tree, mloopuv_count, luv);
|
||||||
BLI_array_append(duplicates, -1);
|
duplicates.append(-1);
|
||||||
BLI_array_append(mloopuv_arr, luv);
|
mloopuv_arr.append(luv);
|
||||||
mloopuv_count++;
|
mloopuv_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -762,12 +759,13 @@ static int uv_remove_doubles_to_selected(bContext *C, wmOperator *op)
|
|||||||
}
|
}
|
||||||
|
|
||||||
BLI_kdtree_2d_balance(tree);
|
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) {
|
if (found_duplicates > 0) {
|
||||||
/* Calculate average uv for duplicates. */
|
/* Calculate average uv for duplicates. */
|
||||||
int *uv_duplicate_count = MEM_callocN(sizeof(int) * mloopuv_count,
|
int *uv_duplicate_count = static_cast<int *>(
|
||||||
"uv_remove_doubles_selected.uv_duplicate_count");
|
MEM_callocN(sizeof(int) * mloopuv_count, __func__));
|
||||||
for (int i = 0; i < mloopuv_count; i++) {
|
for (int i = 0; i < mloopuv_count; i++) {
|
||||||
if (duplicates[i] == -1) { /* If doesn't reference another */
|
if (duplicates[i] == -1) { /* If doesn't reference another */
|
||||||
uv_duplicate_count[i]++; /* self */
|
uv_duplicate_count[i]++; /* self */
|
||||||
@ -787,7 +785,7 @@ static int uv_remove_doubles_to_selected(bContext *C, wmOperator *op)
|
|||||||
continue;
|
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);
|
MEM_freeN(uv_duplicate_count);
|
||||||
|
|
||||||
@ -813,15 +811,13 @@ static int uv_remove_doubles_to_selected(bContext *C, wmOperator *op)
|
|||||||
if (changed[ob_index]) {
|
if (changed[ob_index]) {
|
||||||
Object *obedit = objects[ob_index];
|
Object *obedit = objects[ob_index];
|
||||||
uvedit_live_unwrap_update(sima, scene, obedit);
|
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);
|
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BLI_kdtree_2d_free(tree);
|
BLI_kdtree_2d_free(tree);
|
||||||
BLI_array_free(mloopuv_arr);
|
|
||||||
BLI_array_free(duplicates);
|
|
||||||
MEM_freeN(changed);
|
MEM_freeN(changed);
|
||||||
MEM_freeN(objects);
|
MEM_freeN(objects);
|
||||||
MEM_freeN(ob_mloopuv_max_idx);
|
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;
|
uint objects_len = 0;
|
||||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
|
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. */
|
/* Calculate max possible number of kdtree nodes. */
|
||||||
int uv_maxlen = 0;
|
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);
|
KDTree_2d *tree = BLI_kdtree_2d_new(uv_maxlen);
|
||||||
|
|
||||||
float **mloopuv_arr = NULL;
|
blender::Vector<float *> mloopuv_arr;
|
||||||
BLI_array_declare(mloopuv_arr);
|
|
||||||
|
|
||||||
int mloopuv_count = 0;
|
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)) {
|
if (!uvedit_uv_select_test(scene, l, offsets)) {
|
||||||
float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
|
float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
|
||||||
BLI_kdtree_2d_insert(tree, mloopuv_count, luv);
|
BLI_kdtree_2d_insert(tree, mloopuv_count, luv);
|
||||||
BLI_array_append(mloopuv_arr, luv);
|
mloopuv_arr.append(luv);
|
||||||
mloopuv_count++;
|
mloopuv_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -926,13 +921,12 @@ static int uv_remove_doubles_to_unselected(bContext *C, wmOperator *op)
|
|||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
uvedit_live_unwrap_update(sima, scene, obedit);
|
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);
|
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BLI_kdtree_2d_free(tree);
|
BLI_kdtree_2d_free(tree);
|
||||||
BLI_array_free(mloopuv_arr);
|
|
||||||
MEM_freeN(objects);
|
MEM_freeN(objects);
|
||||||
|
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
@ -968,8 +962,11 @@ static void UV_OT_remove_doubles(wmOperatorType *ot)
|
|||||||
"Maximum distance between welded vertices",
|
"Maximum distance between welded vertices",
|
||||||
0.0f,
|
0.0f,
|
||||||
1.0f);
|
1.0f);
|
||||||
RNA_def_boolean(
|
RNA_def_boolean(ot->srna,
|
||||||
ot->srna, "use_unselected", 0, "Unselected", "Merge selected to other unselected vertices");
|
"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
|
/** \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);
|
uv_weld_align(C, UV_WELD);
|
||||||
|
|
||||||
@ -1049,7 +1046,7 @@ static int uv_snap_cursor_exec(bContext *C, wmOperator *op)
|
|||||||
|
|
||||||
uint objects_len = 0;
|
uint objects_len = 0;
|
||||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
|
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);
|
changed = uv_snap_cursor_to_selection(scene, objects, objects_len, sima);
|
||||||
MEM_freeN(objects);
|
MEM_freeN(objects);
|
||||||
break;
|
break;
|
||||||
@ -1075,7 +1072,7 @@ static void UV_OT_snap_cursor(wmOperatorType *ot)
|
|||||||
{0, "PIXELS", 0, "Pixels", ""},
|
{0, "PIXELS", 0, "Pixels", ""},
|
||||||
{1, "SELECTED", 0, "Selected", ""},
|
{1, "SELECTED", 0, "Selected", ""},
|
||||||
{2, "ORIGIN", 0, "Origin", ""},
|
{2, "ORIGIN", 0, "Origin", ""},
|
||||||
{0, NULL, 0, NULL, NULL},
|
{0, nullptr, 0, nullptr, nullptr},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* identifiers */
|
/* identifiers */
|
||||||
@ -1199,7 +1196,7 @@ static bool uv_snap_uvs_to_adjacent_unselected(Scene *scene, Object *obedit)
|
|||||||
|
|
||||||
if (uv_tot) {
|
if (uv_tot) {
|
||||||
luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
|
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;
|
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);
|
const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
|
||||||
|
|
||||||
ED_space_image_get_size(sima, &width, &height);
|
ED_space_image_get_size(sima, &width, &height);
|
||||||
w = (float)width;
|
w = float(width);
|
||||||
h = (float)height;
|
h = float(height);
|
||||||
|
|
||||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||||
if (!uvedit_face_visible_test(scene, efa)) {
|
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;
|
uint objects_len = 0;
|
||||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
|
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) {
|
if (target == 2) {
|
||||||
float center[2];
|
float center[2];
|
||||||
@ -1296,7 +1293,7 @@ static int uv_snap_selection_exec(bContext *C, wmOperator *op)
|
|||||||
if (changed) {
|
if (changed) {
|
||||||
changed_multi = true;
|
changed_multi = true;
|
||||||
uvedit_live_unwrap_update(sima, scene, obedit);
|
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);
|
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", ""},
|
{1, "CURSOR", 0, "Cursor", ""},
|
||||||
{2, "CURSOR_OFFSET", 0, "Cursor (Offset)", ""},
|
{2, "CURSOR_OFFSET", 0, "Cursor (Offset)", ""},
|
||||||
{3, "ADJACENT_UNSELECTED", 0, "Adjacent Unselected", ""},
|
{3, "ADJACENT_UNSELECTED", 0, "Adjacent Unselected", ""},
|
||||||
{0, NULL, 0, NULL, NULL},
|
{0, nullptr, 0, nullptr, nullptr},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* identifiers */
|
/* identifiers */
|
||||||
@ -1349,7 +1346,7 @@ static int uv_pin_exec(bContext *C, wmOperator *op)
|
|||||||
|
|
||||||
uint objects_len = 0;
|
uint objects_len = 0;
|
||||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
|
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++) {
|
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
||||||
Object *obedit = objects[ob_index];
|
Object *obedit = objects[ob_index];
|
||||||
@ -1380,7 +1377,7 @@ static int uv_pin_exec(bContext *C, wmOperator *op)
|
|||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
|
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);
|
MEM_freeN(objects);
|
||||||
@ -1403,7 +1400,7 @@ static void UV_OT_pin(wmOperatorType *ot)
|
|||||||
|
|
||||||
/* properties */
|
/* properties */
|
||||||
RNA_def_boolean(
|
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;
|
uint objects_len = 0;
|
||||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
|
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++) {
|
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
||||||
Object *ob = objects[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 (ts->uv_flag & UV_SYNC_SELECTION) {
|
||||||
if (EDBM_mesh_hide(em, swap)) {
|
if (EDBM_mesh_hide(em, swap)) {
|
||||||
EDBM_update(ob->data,
|
Mesh *me = static_cast<Mesh *>(ob->data);
|
||||||
&(const struct EDBMUpdate_Params){
|
EDBMUpdate_Params params = {0};
|
||||||
.calc_looptri = true,
|
params.calc_looptri = true;
|
||||||
.calc_normals = false,
|
params.calc_normals = false;
|
||||||
.is_destructive = false,
|
params.is_destructive = false;
|
||||||
});
|
EDBM_update(me, ¶ms);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1569,7 +1566,7 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
|
|||||||
|
|
||||||
BM_select_history_validate(em->bm);
|
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);
|
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;
|
ot->poll = ED_operator_uvedit;
|
||||||
|
|
||||||
/* props */
|
/* 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;
|
uint objects_len = 0;
|
||||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
|
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++) {
|
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
||||||
Object *ob = objects[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 */
|
/* call the mesh function if we are in mesh sync sel */
|
||||||
if (ts->uv_flag & UV_SYNC_SELECTION) {
|
if (ts->uv_flag & UV_SYNC_SELECTION) {
|
||||||
if (EDBM_mesh_reveal(em, select)) {
|
if (EDBM_mesh_reveal(em, select)) {
|
||||||
EDBM_update(ob->data,
|
Mesh *me = static_cast<Mesh *>(ob->data);
|
||||||
&(const struct EDBMUpdate_Params){
|
EDBMUpdate_Params params = {0};
|
||||||
.calc_looptri = true,
|
params.calc_looptri = true;
|
||||||
.calc_normals = false,
|
params.calc_normals = false;
|
||||||
.is_destructive = false,
|
params.is_destructive = false;
|
||||||
});
|
EDBM_update(me, ¶ms);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1721,7 +1719,7 @@ static int uv_reveal_exec(bContext *C, wmOperator *op)
|
|||||||
/* re-select tagged faces */
|
/* re-select tagged faces */
|
||||||
BM_mesh_elem_hflag_enable_test(em->bm, BM_FACE, BM_ELEM_SELECT, true, false, BM_ELEM_TAG);
|
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);
|
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);
|
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);
|
bScreen *screen = CTX_wm_screen(C);
|
||||||
WM_msg_publish_rna_prop(mbus, &screen->id, sima, SpaceImageEditor, cursor_location);
|
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. */
|
/* Use pass-through to allow click-drag to transform the cursor. */
|
||||||
return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
|
return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
|
||||||
@ -1808,7 +1806,7 @@ static void UV_OT_cursor_set(wmOperatorType *ot)
|
|||||||
RNA_def_float_vector(ot->srna,
|
RNA_def_float_vector(ot->srna,
|
||||||
"location",
|
"location",
|
||||||
2,
|
2,
|
||||||
NULL,
|
nullptr,
|
||||||
-FLT_MAX,
|
-FLT_MAX,
|
||||||
FLT_MAX,
|
FLT_MAX,
|
||||||
"Location",
|
"Location",
|
||||||
@ -1833,7 +1831,7 @@ static int uv_seams_from_islands_exec(bContext *C, wmOperator *op)
|
|||||||
|
|
||||||
uint objects_len = 0;
|
uint objects_len = 0;
|
||||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
|
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++) {
|
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
||||||
Object *ob = objects[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->exec = uv_seams_from_islands_exec;
|
||||||
ot->poll = ED_operator_uvedit;
|
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_seams", true, "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_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;
|
uint objects_len = 0;
|
||||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
|
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;
|
bool changed = false;
|
||||||
|
|
||||||
@ -1980,7 +1978,7 @@ static int uv_mark_seam_exec(bContext *C, wmOperator *op)
|
|||||||
return OPERATOR_FINISHED;
|
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;
|
uiPopupMenu *pup;
|
||||||
uiLayout *layout;
|
uiLayout *layout;
|
@ -6,9 +6,9 @@
|
|||||||
* \note The logic in this file closely follows editmesh_path.c
|
* \note The logic in this file closely follows editmesh_path.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
#include <string.h>
|
#include <cstring>
|
||||||
|
|
||||||
#include "BLI_linklist.h"
|
#include "BLI_linklist.h"
|
||||||
#include "DNA_windowmanager_types.h"
|
#include "DNA_windowmanager_types.h"
|
||||||
@ -66,7 +66,7 @@ struct PathSelectParams {
|
|||||||
bool use_topology_distance;
|
bool use_topology_distance;
|
||||||
bool use_face_step;
|
bool use_face_step;
|
||||||
bool use_fill;
|
bool use_fill;
|
||||||
struct CheckerIntervalParams interval_params;
|
CheckerIntervalParams interval_params;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct UserData_UV {
|
struct UserData_UV {
|
||||||
@ -96,7 +96,7 @@ static void path_select_properties(wmOperatorType *ot)
|
|||||||
WM_operator_properties_checker_interval(ot, true);
|
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->track_active = false;
|
||||||
op_params->use_face_step = RNA_boolean_get(op->ptr, "use_face_step");
|
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 */
|
/* callbacks */
|
||||||
static bool verttag_filter_cb(BMLoop *l, void *user_data_v)
|
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);
|
return uvedit_face_visible_test(user_data->scene, l->f);
|
||||||
}
|
}
|
||||||
static bool verttag_test_cb(BMLoop *l, void *user_data_v)
|
static bool verttag_test_cb(BMLoop *l, void *user_data_v)
|
||||||
{
|
{
|
||||||
/* All connected loops are selected or we return false. */
|
/* 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 Scene *scene = user_data->scene;
|
||||||
const int cd_loop_uv_offset = user_data->offsets.uv;
|
const int cd_loop_uv_offset = user_data->offsets.uv;
|
||||||
const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
|
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)
|
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;
|
const Scene *scene = user_data->scene;
|
||||||
BMEditMesh *em = user_data->em;
|
BMEditMesh *em = user_data->em;
|
||||||
const uint cd_loop_uv_offset = user_data->offsets.uv;
|
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,
|
static int mouse_mesh_uv_shortest_path_vert(Scene *scene,
|
||||||
Object *obedit,
|
Object *obedit,
|
||||||
const struct PathSelectParams *op_params,
|
const PathSelectParams *op_params,
|
||||||
BMLoop *l_src,
|
BMLoop *l_src,
|
||||||
BMLoop *l_dst,
|
BMLoop *l_dst,
|
||||||
const float aspect_y,
|
const float aspect_y,
|
||||||
@ -169,20 +169,18 @@ static int mouse_mesh_uv_shortest_path_vert(Scene *scene,
|
|||||||
BMesh *bm = em->bm;
|
BMesh *bm = em->bm;
|
||||||
int flush = 0;
|
int flush = 0;
|
||||||
|
|
||||||
struct UserData_UV user_data = {
|
UserData_UV user_data = {};
|
||||||
.scene = scene,
|
user_data.scene = scene;
|
||||||
.em = em,
|
user_data.em = em;
|
||||||
.offsets = offsets,
|
user_data.offsets = offsets;
|
||||||
};
|
|
||||||
|
|
||||||
const struct BMCalcPathUVParams params = {
|
BMCalcPathUVParams params{};
|
||||||
.use_topology_distance = op_params->use_topology_distance,
|
params.use_topology_distance = op_params->use_topology_distance;
|
||||||
.use_step_face = op_params->use_face_step,
|
params.use_step_face = op_params->use_face_step;
|
||||||
.aspect_y = aspect_y,
|
params.aspect_y = aspect_y;
|
||||||
.cd_loop_uv_offset = offsets.uv,
|
params.cd_loop_uv_offset = offsets.uv;
|
||||||
};
|
|
||||||
|
|
||||||
LinkNode *path = NULL;
|
LinkNode *path = nullptr;
|
||||||
bool is_path_ordered = false;
|
bool is_path_ordered = false;
|
||||||
|
|
||||||
if (l_src != l_dst) {
|
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);
|
verttag_set_cb((BMLoop *)node->link, !all_set, &user_data);
|
||||||
if (is_path_ordered) {
|
if (is_path_ordered) {
|
||||||
l_dst_last = node->link;
|
l_dst_last = static_cast<BMLoop *>(node->link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while ((void)depth++, (node = node->next));
|
} while ((void)depth++, (node = node->next));
|
||||||
|
|
||||||
BLI_linklist_free(path, NULL);
|
BLI_linklist_free(path, nullptr);
|
||||||
flush = all_set ? -1 : 1;
|
flush = all_set ? -1 : 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -249,13 +247,13 @@ static int mouse_mesh_uv_shortest_path_vert(Scene *scene,
|
|||||||
/* callbacks */
|
/* callbacks */
|
||||||
static bool edgetag_filter_cb(BMLoop *l, void *user_data_v)
|
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);
|
return uvedit_face_visible_test(user_data->scene, l->f);
|
||||||
}
|
}
|
||||||
static bool edgetag_test_cb(BMLoop *l, void *user_data_v)
|
static bool edgetag_test_cb(BMLoop *l, void *user_data_v)
|
||||||
{
|
{
|
||||||
/* All connected loops (UV) are selected or we return false. */
|
/* 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;
|
const Scene *scene = user_data->scene;
|
||||||
BMIter iter;
|
BMIter iter;
|
||||||
BMLoop *l_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)
|
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;
|
const Scene *scene = user_data->scene;
|
||||||
BMEditMesh *em = user_data->em;
|
BMEditMesh *em = user_data->em;
|
||||||
uvedit_edge_select_set_with_sticky(scene, em, l, val, false, user_data->offsets);
|
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,
|
static int mouse_mesh_uv_shortest_path_edge(Scene *scene,
|
||||||
Object *obedit,
|
Object *obedit,
|
||||||
const struct PathSelectParams *op_params,
|
const PathSelectParams *op_params,
|
||||||
BMLoop *l_src,
|
BMLoop *l_src,
|
||||||
BMLoop *l_dst,
|
BMLoop *l_dst,
|
||||||
const float aspect_y,
|
const float aspect_y,
|
||||||
@ -290,20 +288,18 @@ static int mouse_mesh_uv_shortest_path_edge(Scene *scene,
|
|||||||
BMesh *bm = em->bm;
|
BMesh *bm = em->bm;
|
||||||
int flush = 0;
|
int flush = 0;
|
||||||
|
|
||||||
struct UserData_UV user_data = {
|
UserData_UV user_data = {};
|
||||||
.scene = scene,
|
user_data.scene = scene;
|
||||||
.em = em,
|
user_data.em = em;
|
||||||
.offsets = offsets,
|
user_data.offsets = offsets;
|
||||||
};
|
|
||||||
|
|
||||||
const struct BMCalcPathUVParams params = {
|
BMCalcPathUVParams params = {};
|
||||||
.use_topology_distance = op_params->use_topology_distance,
|
params.use_topology_distance = op_params->use_topology_distance;
|
||||||
.use_step_face = op_params->use_face_step,
|
params.use_step_face = op_params->use_face_step;
|
||||||
.aspect_y = aspect_y,
|
params.aspect_y = aspect_y;
|
||||||
.cd_loop_uv_offset = offsets.uv,
|
params.cd_loop_uv_offset = offsets.uv;
|
||||||
};
|
|
||||||
|
|
||||||
LinkNode *path = NULL;
|
LinkNode *path = nullptr;
|
||||||
bool is_path_ordered = false;
|
bool is_path_ordered = false;
|
||||||
|
|
||||||
if (l_src != l_dst) {
|
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);
|
edgetag_set_cb((BMLoop *)node->link, !all_set, &user_data);
|
||||||
if (is_path_ordered) {
|
if (is_path_ordered) {
|
||||||
l_dst_last = node->link;
|
l_dst_last = static_cast<BMLoop *>(node->link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while ((void)depth++, (node = node->next));
|
} while ((void)depth++, (node = node->next));
|
||||||
|
|
||||||
BLI_linklist_free(path, NULL);
|
BLI_linklist_free(path, nullptr);
|
||||||
flush = all_set ? -1 : 1;
|
flush = all_set ? -1 : 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -370,13 +366,13 @@ static int mouse_mesh_uv_shortest_path_edge(Scene *scene,
|
|||||||
/* callbacks */
|
/* callbacks */
|
||||||
static bool facetag_filter_cb(BMFace *f, void *user_data_v)
|
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);
|
return uvedit_face_visible_test(user_data->scene, f);
|
||||||
}
|
}
|
||||||
static bool facetag_test_cb(BMFace *f, void *user_data_v)
|
static bool facetag_test_cb(BMFace *f, void *user_data_v)
|
||||||
{
|
{
|
||||||
/* All connected loops are selected or we return false. */
|
/* 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 Scene *scene = user_data->scene;
|
||||||
BMIter iter;
|
BMIter iter;
|
||||||
BMLoop *l_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)
|
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;
|
const Scene *scene = user_data->scene;
|
||||||
BMEditMesh *em = user_data->em;
|
BMEditMesh *em = user_data->em;
|
||||||
uvedit_face_select_set_with_sticky(scene, em, f, val, false, user_data->offsets);
|
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,
|
static int mouse_mesh_uv_shortest_path_face(Scene *scene,
|
||||||
Object *obedit,
|
Object *obedit,
|
||||||
const struct PathSelectParams *op_params,
|
const PathSelectParams *op_params,
|
||||||
BMFace *f_src,
|
BMFace *f_src,
|
||||||
BMFace *f_dst,
|
BMFace *f_dst,
|
||||||
const float aspect_y,
|
const float aspect_y,
|
||||||
@ -407,20 +403,18 @@ static int mouse_mesh_uv_shortest_path_face(Scene *scene,
|
|||||||
BMesh *bm = em->bm;
|
BMesh *bm = em->bm;
|
||||||
int flush = 0;
|
int flush = 0;
|
||||||
|
|
||||||
struct UserData_UV user_data = {
|
UserData_UV user_data = {};
|
||||||
.scene = scene,
|
user_data.scene = scene;
|
||||||
.em = em,
|
user_data.em = em;
|
||||||
.offsets = offsets,
|
user_data.offsets = offsets;
|
||||||
};
|
|
||||||
|
|
||||||
const struct BMCalcPathUVParams params = {
|
BMCalcPathUVParams params = {};
|
||||||
.use_topology_distance = op_params->use_topology_distance,
|
params.use_topology_distance = op_params->use_topology_distance;
|
||||||
.use_step_face = op_params->use_face_step,
|
params.use_step_face = op_params->use_face_step;
|
||||||
.aspect_y = aspect_y,
|
params.aspect_y = aspect_y;
|
||||||
.cd_loop_uv_offset = offsets.uv,
|
params.cd_loop_uv_offset = offsets.uv;
|
||||||
};
|
|
||||||
|
|
||||||
LinkNode *path = NULL;
|
LinkNode *path = nullptr;
|
||||||
bool is_path_ordered = false;
|
bool is_path_ordered = false;
|
||||||
|
|
||||||
if (f_src != f_dst) {
|
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);
|
facetag_set_cb((BMFace *)node->link, !all_set, &user_data);
|
||||||
if (is_path_ordered) {
|
if (is_path_ordered) {
|
||||||
f_dst_last = node->link;
|
f_dst_last = static_cast<BMFace *>(node->link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while ((void)depth++, (node = node->next));
|
} while ((void)depth++, (node = node->next));
|
||||||
|
|
||||||
BLI_linklist_free(path, NULL);
|
BLI_linklist_free(path, nullptr);
|
||||||
flush = all_set ? -1 : 1;
|
flush = all_set ? -1 : 1;
|
||||||
}
|
}
|
||||||
else {
|
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,
|
static bool uv_shortest_path_pick_ex(Scene *scene,
|
||||||
Depsgraph *depsgraph,
|
Depsgraph *depsgraph,
|
||||||
Object *obedit,
|
Object *obedit,
|
||||||
const struct PathSelectParams *op_params,
|
const PathSelectParams *op_params,
|
||||||
BMElem *ele_src,
|
BMElem *ele_src,
|
||||||
BMElem *ele_dst,
|
BMElem *ele_dst,
|
||||||
const float aspect_y,
|
const float aspect_y,
|
||||||
@ -501,7 +495,7 @@ static bool uv_shortest_path_pick_ex(Scene *scene,
|
|||||||
bool ok = false;
|
bool ok = false;
|
||||||
int flush = 0;
|
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 */
|
/* pass */
|
||||||
}
|
}
|
||||||
else if (ele_src->head.htype == BM_FACE) {
|
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) {
|
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 {
|
else {
|
||||||
Object *obedit_eval = DEG_get_evaluated_object(depsgraph, obedit);
|
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. */
|
/* Only for region redraw. */
|
||||||
WM_main_add_notifier(NC_GEOM | ND_SELECT, obedit->data);
|
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);
|
return uv_shortest_path_pick_exec(C, op);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PathSelectParams op_params;
|
PathSelectParams op_params;
|
||||||
path_select_params_from_op(op, &op_params);
|
path_select_params_from_op(op, &op_params);
|
||||||
|
|
||||||
/* Set false if we support edge tagging. */
|
/* 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);
|
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||||
uint objects_len = 0;
|
uint objects_len = 0;
|
||||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
|
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];
|
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(®ion->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
|
UI_view2d_region_to_view(®ion->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. */
|
/* Detect the hit. */
|
||||||
UvNearestHit hit = uv_nearest_hit_init_max(®ion->v2d);
|
UvNearestHit hit = uv_nearest_hit_init_max(®ion->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) {
|
else if (uv_selectmode & UV_SELECT_EDGE) {
|
||||||
/* Edge selection. */
|
/* Edge selection. */
|
||||||
BMLoop *l_src = NULL;
|
BMLoop *l_src = nullptr;
|
||||||
if (ts->uv_flag & UV_SYNC_SELECTION) {
|
if (ts->uv_flag & UV_SYNC_SELECTION) {
|
||||||
BMEdge *e_src = BM_mesh_active_edge_get(bm);
|
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);
|
l_src = uv_find_nearest_loop_from_edge(scene, obedit, e_src, co);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
l_src = ED_uvedit_active_edge_loop_get(bm);
|
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) &&
|
if (!uvedit_uv_select_test(scene, l_src, offsets) &&
|
||||||
!uvedit_uv_select_test(scene, l_src->next, offsets))
|
!uvedit_uv_select_test(scene, l_src->next, offsets))
|
||||||
{
|
{
|
||||||
l_src = NULL;
|
l_src = nullptr;
|
||||||
}
|
}
|
||||||
ele_src = (BMElem *)l_src;
|
ele_src = (BMElem *)l_src;
|
||||||
}
|
}
|
||||||
@ -638,18 +633,18 @@ static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEve
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Vertex selection. */
|
/* Vertex selection. */
|
||||||
BMLoop *l_src = NULL;
|
BMLoop *l_src = nullptr;
|
||||||
if (ts->uv_flag & UV_SYNC_SELECTION) {
|
if (ts->uv_flag & UV_SYNC_SELECTION) {
|
||||||
BMVert *v_src = BM_mesh_active_vert_get(bm);
|
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);
|
l_src = uv_find_nearest_loop_from_vert(scene, obedit, v_src, co);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
l_src = ED_uvedit_active_vert_loop_get(bm);
|
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)) {
|
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);
|
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;
|
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. */
|
/* 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));
|
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);
|
path_select_params_from_op(op, &op_params);
|
||||||
op_params.track_active = true;
|
op_params.track_active = true;
|
||||||
|
|
||||||
@ -786,9 +781,9 @@ void UV_OT_shortest_path_pick(wmOperatorType *ot)
|
|||||||
|
|
||||||
/* use for redo */
|
/* use for redo */
|
||||||
prop = RNA_def_int(ot->srna, "object_index", -1, -1, INT_MAX, "", "", 0, INT_MAX);
|
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);
|
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);
|
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||||
uint objects_len = 0;
|
uint objects_len = 0;
|
||||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
|
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++) {
|
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
||||||
Object *obedit = objects[ob_index];
|
Object *obedit = objects[ob_index];
|
||||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
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);
|
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. */
|
/* Find 2x elements. */
|
||||||
{
|
{
|
||||||
BMElem **ele_array = NULL;
|
BMElem **ele_array = nullptr;
|
||||||
int ele_array_len = 0;
|
int ele_array_len = 0;
|
||||||
if (uv_selectmode & UV_SELECT_FACE) {
|
if (uv_selectmode & UV_SELECT_FACE) {
|
||||||
ele_array = (BMElem **)ED_uvedit_selected_faces(scene, bm, 3, &ele_array_len);
|
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) {
|
if (ele_src && ele_dst) {
|
||||||
struct PathSelectParams op_params;
|
PathSelectParams op_params;
|
||||||
path_select_params_from_op(op, &op_params);
|
path_select_params_from_op(op, &op_params);
|
||||||
|
|
||||||
uv_shortest_path_pick_ex(
|
uv_shortest_path_pick_ex(
|
@ -4,9 +4,9 @@
|
|||||||
* \ingroup eduv
|
* \ingroup eduv
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
#include <string.h>
|
#include <cstring>
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
@ -51,7 +51,7 @@
|
|||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
/** Unordered loop data, stored in #BMLoop.head.index. */
|
/** Unordered loop data, stored in #BMLoop.head.index. */
|
||||||
typedef struct ULData {
|
struct ULData {
|
||||||
/** When the specified UV edge is selected. */
|
/** When the specified UV edge is selected. */
|
||||||
uint is_select_edge : 1;
|
uint is_select_edge : 1;
|
||||||
/**
|
/**
|
||||||
@ -81,7 +81,7 @@ typedef struct ULData {
|
|||||||
* depending on the order of addition.
|
* depending on the order of addition.
|
||||||
*/
|
*/
|
||||||
uint side_was_swapped : 1;
|
uint side_was_swapped : 1;
|
||||||
} ULData;
|
};
|
||||||
|
|
||||||
/** Ensure this fits in an int (loop index). */
|
/** Ensure this fits in an int (loop index). */
|
||||||
BLI_STATIC_ASSERT(sizeof(ULData) <= sizeof(int), "");
|
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,
|
static BMLoop *bm_loop_find_other_radial_loop_with_visible_face(BMLoop *l_src,
|
||||||
const int cd_loop_uv_offset)
|
const int cd_loop_uv_offset)
|
||||||
{
|
{
|
||||||
BMLoop *l_other = NULL;
|
BMLoop *l_other = nullptr;
|
||||||
BMLoop *l_iter = l_src->radial_next;
|
BMLoop *l_iter = l_src->radial_next;
|
||||||
if (l_iter != l_src) {
|
if (l_iter != l_src) {
|
||||||
do {
|
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))
|
BM_loop_uv_share_edge_check(l_src, l_iter, cd_loop_uv_offset))
|
||||||
{
|
{
|
||||||
/* Check UVs are contiguous. */
|
/* Check UVs are contiguous. */
|
||||||
if (l_other == NULL) {
|
if (l_other == nullptr) {
|
||||||
l_other = l_iter;
|
l_other = l_iter;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Only use when there is a single alternative. */
|
/* Only use when there is a single alternative. */
|
||||||
l_other = NULL;
|
l_other = nullptr;
|
||||||
break;
|
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)
|
const int cd_loop_uv_offset)
|
||||||
{
|
{
|
||||||
BLI_assert(BM_vert_in_edge(l_src->e, v_src));
|
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;
|
BMLoop *l_iter = l_src->radial_next;
|
||||||
if (l_iter != l_src) {
|
if (l_iter != l_src) {
|
||||||
do {
|
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))
|
BM_loop_uv_share_edge_check(l_src, l_iter, cd_loop_uv_offset))
|
||||||
{
|
{
|
||||||
/* Check UVs are contiguous. */
|
/* Check UVs are contiguous. */
|
||||||
if (l_other == NULL) {
|
if (l_other == nullptr) {
|
||||||
l_other = l_iter;
|
l_other = l_iter;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Only use when there is a single alternative. */
|
/* Only use when there is a single alternative. */
|
||||||
l_other = NULL;
|
l_other = nullptr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while ((l_iter = l_iter->radial_next) != l_src);
|
} while ((l_iter = l_iter->radial_next) != l_src);
|
||||||
}
|
}
|
||||||
if (l_other != NULL) {
|
if (l_other != nullptr) {
|
||||||
if (l_other->v == v_src) {
|
if (l_other->v == v_src) {
|
||||||
/* do nothing. */
|
/* do nothing. */
|
||||||
}
|
}
|
||||||
@ -178,7 +178,7 @@ static BMLoop *bm_vert_step_fan_loop_uv(BMLoop *l, BMEdge **e_step, const int cd
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BLI_assert_unreachable();
|
BLI_assert_unreachable();
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
*e_step = l_next->e;
|
*e_step = l_next->e;
|
||||||
@ -279,10 +279,10 @@ static void bm_loop_calc_uv_angle_from_dir(BMLoop *l,
|
|||||||
/** \name UV Rip Single
|
/** \name UV Rip Single
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
typedef struct UVRipSingle {
|
struct UVRipSingle {
|
||||||
/** Walk around the selected UV point, store #BMLoop. */
|
/** Walk around the selected UV point, store #BMLoop. */
|
||||||
GSet *loops;
|
GSet *loops;
|
||||||
} UVRipSingle;
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle single loop, the following cases:
|
* 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 float aspect_y,
|
||||||
const int cd_loop_uv_offset)
|
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);
|
const float *co_center = BM_ELEM_CD_GET_FLOAT_P(l_init_orig, cd_loop_uv_offset);
|
||||||
rip->loops = BLI_gset_ptr_new(__func__);
|
rip->loops = BLI_gset_ptr_new(__func__);
|
||||||
|
|
||||||
/* Track the closest loop, start walking from this so in the event we have multiple
|
/* 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. */
|
* disconnected fans, we can rip away loops connected to this one. */
|
||||||
BMLoop *l_init = NULL;
|
BMLoop *l_init = nullptr;
|
||||||
BMLoop *l_init_edge = NULL;
|
BMLoop *l_init_edge = nullptr;
|
||||||
float corner_angle_best = FLT_MAX;
|
float corner_angle_best = FLT_MAX;
|
||||||
float edge_angle_best = FLT_MAX;
|
float edge_angle_best = FLT_MAX;
|
||||||
int edge_index_best = 0; /* -1 or +1 (never center). */
|
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;
|
BMEdge *e_prev = i ? l_init->e : l_init->prev->e;
|
||||||
BMLoop *l_iter = l_init;
|
BMLoop *l_iter = l_init;
|
||||||
while (((l_iter = bm_vert_step_fan_loop_uv(l_iter, &e_prev, cd_loop_uv_offset)) != 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;
|
uv_fan_count_contiguous += 1;
|
||||||
/* Keep. */
|
/* Keep. */
|
||||||
@ -393,7 +393,7 @@ static UVRipSingle *uv_rip_single_from_loop(BMLoop *l_init_orig,
|
|||||||
else {
|
else {
|
||||||
GSetIterator gs_iter;
|
GSetIterator gs_iter;
|
||||||
GSET_ITER (gs_iter, rip->loops) {
|
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;
|
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)
|
static void uv_rip_single_free(UVRipSingle *rip)
|
||||||
{
|
{
|
||||||
BLI_gset_free(rip->loops, NULL);
|
BLI_gset_free(rip->loops, nullptr);
|
||||||
MEM_freeN(rip);
|
MEM_freeN(rip);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -431,10 +431,10 @@ static void uv_rip_single_free(UVRipSingle *rip)
|
|||||||
/** \name UV Rip Loop Pairs
|
/** \name UV Rip Loop Pairs
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
typedef struct UVRipPairs {
|
struct UVRipPairs {
|
||||||
/** Walk along the UV selection, store #BMLoop. */
|
/** Walk along the UV selection, store #BMLoop. */
|
||||||
GSet *loops;
|
GSet *loops;
|
||||||
} UVRipPairs;
|
};
|
||||||
|
|
||||||
static void uv_rip_pairs_add(UVRipPairs *rip, BMLoop *l)
|
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(BLI_gset_haskey(rip->loops, l));
|
||||||
BLI_assert(ul->in_rip_pairs == true);
|
BLI_assert(ul->in_rip_pairs == true);
|
||||||
ul->in_rip_pairs = false;
|
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 float aspect_y,
|
||||||
const int cd_loop_uv_offset)
|
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__);
|
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,
|
/* 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;
|
UL(l_init)->in_stack = true;
|
||||||
|
|
||||||
BMLoop *l_step;
|
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;
|
int side = UL(l_step)->side;
|
||||||
UL(l_step)->in_stack = false;
|
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) {
|
if (UL(l_step)->is_select_edge) {
|
||||||
BMLoop *l_other = bm_loop_find_other_radial_loop_with_visible_face(l_step,
|
BMLoop *l_other = bm_loop_find_other_radial_loop_with_visible_face(l_step,
|
||||||
cd_loop_uv_offset);
|
cd_loop_uv_offset);
|
||||||
if (l_other != NULL) {
|
if (l_other != nullptr) {
|
||||||
if (!UL(l_other)->in_rip_pairs && !UL(l_other)->in_stack) {
|
if (!UL(l_other)->in_rip_pairs && !UL(l_other)->in_stack) {
|
||||||
BLI_SMALLSTACK_PUSH(stack, l_other);
|
BLI_SMALLSTACK_PUSH(stack, l_other);
|
||||||
UL(l_other)->in_stack = true;
|
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)
|
static void uv_rip_pairs_free(UVRipPairs *rip)
|
||||||
{
|
{
|
||||||
BLI_gset_free(rip->loops, NULL);
|
BLI_gset_free(rip->loops, nullptr);
|
||||||
MEM_freeN(rip);
|
MEM_freeN(rip);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -696,7 +696,7 @@ static bool uv_rip_pairs_calc_center_and_direction(UVRipPairs *rip,
|
|||||||
}
|
}
|
||||||
GSetIterator gs_iter;
|
GSetIterator gs_iter;
|
||||||
GSET_ITER (gs_iter, rip->loops) {
|
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;
|
int side = UL(l)->side;
|
||||||
const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
|
const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
|
||||||
add_v2_v2(r_center, luv);
|
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;
|
GSetIterator gs_iter;
|
||||||
GSET_ITER (gs_iter, rip->loops) {
|
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);
|
ULData *ul = UL(l_iter);
|
||||||
if (ul->side == side_from_cursor) {
|
if (ul->side == side_from_cursor) {
|
||||||
uvedit_uv_select_disable(scene, bm, l_iter, offsets);
|
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;
|
const int side_from_cursor = 0;
|
||||||
GSetIterator gs_iter;
|
GSetIterator gs_iter;
|
||||||
GSET_ITER (gs_iter, rip->loops) {
|
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);
|
ULData *ul = UL(l_iter);
|
||||||
if (ul->side == side_from_cursor) {
|
if (ul->side == side_from_cursor) {
|
||||||
uvedit_uv_select_disable(scene, bm, l_iter, offsets);
|
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;
|
uint objects_len = 0;
|
||||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
|
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++) {
|
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
||||||
Object *obedit = objects[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)) {
|
if (uv_rip_object(scene, obedit, co, aspect_y)) {
|
||||||
changed_multi = true;
|
changed_multi = true;
|
||||||
uvedit_live_unwrap_update(sima, scene, obedit);
|
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);
|
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -967,7 +967,7 @@ void UV_OT_rip(wmOperatorType *ot)
|
|||||||
ot->srna,
|
ot->srna,
|
||||||
"location",
|
"location",
|
||||||
2,
|
2,
|
||||||
NULL,
|
nullptr,
|
||||||
-FLT_MAX,
|
-FLT_MAX,
|
||||||
FLT_MAX,
|
FLT_MAX,
|
||||||
"Location",
|
"Location",
|
File diff suppressed because it is too large
Load Diff
@ -5,9 +5,9 @@
|
|||||||
* \ingroup eduv
|
* \ingroup eduv
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
#include <string.h>
|
#include <cstring>
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
@ -58,7 +58,7 @@
|
|||||||
/* ********************** smart stitch operator *********************** */
|
/* ********************** smart stitch operator *********************** */
|
||||||
|
|
||||||
/* object that stores display data for previewing before confirming stitching */
|
/* 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 */
|
/* here we'll store the preview triangle indices of the mesh */
|
||||||
float *preview_polys;
|
float *preview_polys;
|
||||||
/* uvs per polygon. */
|
/* uvs per polygon. */
|
||||||
@ -76,7 +76,7 @@ typedef struct StitchPreviewer {
|
|||||||
/* ...and here we'll store the static island triangles */
|
/* ...and here we'll store the static island triangles */
|
||||||
float *static_tris;
|
float *static_tris;
|
||||||
uint num_static_tris;
|
uint num_static_tris;
|
||||||
} StitchPreviewer;
|
};
|
||||||
|
|
||||||
struct IslandStitchData;
|
struct IslandStitchData;
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ struct IslandStitchData;
|
|||||||
* that will move and take the mean displacement/rotation and apply it to all
|
* that will move and take the mean displacement/rotation and apply it to all
|
||||||
* elements of the island except from the stitchable.
|
* 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 */
|
/* rotation can be used only for edges, for vertices there is no such notion */
|
||||||
float rotation;
|
float rotation;
|
||||||
float rotation_neg;
|
float rotation_neg;
|
||||||
@ -101,15 +101,15 @@ typedef struct IslandStitchData {
|
|||||||
char stitchableCandidate;
|
char stitchableCandidate;
|
||||||
/* if edge rotation is used, flag so that vertex rotation is not used */
|
/* if edge rotation is used, flag so that vertex rotation is not used */
|
||||||
bool use_edge_rotation;
|
bool use_edge_rotation;
|
||||||
} IslandStitchData;
|
};
|
||||||
|
|
||||||
/* just for averaging UVs */
|
/* just for averaging UVs */
|
||||||
typedef struct UVVertAverage {
|
struct UVVertAverage {
|
||||||
float uv[2];
|
float uv[2];
|
||||||
ushort count;
|
ushort count;
|
||||||
} UVVertAverage;
|
};
|
||||||
|
|
||||||
typedef struct UvEdge {
|
struct UvEdge {
|
||||||
/** index to uv buffer */
|
/** index to uv buffer */
|
||||||
uint uv1;
|
uint uv1;
|
||||||
uint uv2;
|
uint uv2;
|
||||||
@ -123,13 +123,13 @@ typedef struct UvEdge {
|
|||||||
UvElement *element;
|
UvElement *element;
|
||||||
/** next uv edge with the same exact vertices as this one.
|
/** next uv edge with the same exact vertices as this one.
|
||||||
* Calculated at startup to save time */
|
* Calculated at startup to save time */
|
||||||
struct UvEdge *next;
|
UvEdge *next;
|
||||||
/** point to first of common edges. Needed for iteration */
|
/** point to first of common edges. Needed for iteration */
|
||||||
struct UvEdge *first;
|
UvEdge *first;
|
||||||
} UvEdge;
|
};
|
||||||
|
|
||||||
/* stitch state object */
|
/* stitch state object */
|
||||||
typedef struct StitchState {
|
struct StitchState {
|
||||||
/** The `aspect[0] / aspect[1]`. */
|
/** The `aspect[0] / aspect[1]`. */
|
||||||
float aspect;
|
float aspect;
|
||||||
/* object for editmesh */
|
/* object for editmesh */
|
||||||
@ -165,10 +165,10 @@ typedef struct StitchState {
|
|||||||
uint *tris_per_island;
|
uint *tris_per_island;
|
||||||
/* preview data */
|
/* preview data */
|
||||||
StitchPreviewer *stitch_preview;
|
StitchPreviewer *stitch_preview;
|
||||||
} StitchState;
|
};
|
||||||
|
|
||||||
/* Stitch state container. */
|
/* Stitch state container. */
|
||||||
typedef struct StitchStateContainer {
|
struct StitchStateContainer {
|
||||||
/* clear seams of stitched edges after stitch */
|
/* clear seams of stitched edges after stitch */
|
||||||
bool clear_seams;
|
bool clear_seams;
|
||||||
/* use limit flag */
|
/* use limit flag */
|
||||||
@ -192,20 +192,22 @@ typedef struct StitchStateContainer {
|
|||||||
StitchState **states;
|
StitchState **states;
|
||||||
|
|
||||||
int active_object_index;
|
int active_object_index;
|
||||||
} StitchStateContainer;
|
};
|
||||||
|
|
||||||
typedef struct PreviewPosition {
|
struct PreviewPosition {
|
||||||
int data_position;
|
int data_position;
|
||||||
int polycount_position;
|
int polycount_position;
|
||||||
} PreviewPosition;
|
};
|
||||||
/*
|
/*
|
||||||
* defines for UvElement/UcEdge flags
|
* defines for UvElement/UcEdge flags
|
||||||
*/
|
*/
|
||||||
#define STITCH_SELECTED 1
|
enum {
|
||||||
#define STITCH_STITCHABLE 2
|
STITCH_SELECTED = 1,
|
||||||
#define STITCH_PROCESSED 4
|
STITCH_STITCHABLE = 2,
|
||||||
#define STITCH_BOUNDARY 8
|
STITCH_PROCESSED = 4,
|
||||||
#define STITCH_STITCHABLE_CANDIDATE 16
|
STITCH_BOUNDARY = 8,
|
||||||
|
STITCH_STITCHABLE_CANDIDATE = 16,
|
||||||
|
};
|
||||||
|
|
||||||
#define STITCH_NO_PREVIEW -1
|
#define STITCH_NO_PREVIEW -1
|
||||||
|
|
||||||
@ -215,34 +217,35 @@ enum StitchModes {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** #UvElement identification. */
|
/** #UvElement identification. */
|
||||||
typedef struct UvElementID {
|
struct UvElementID {
|
||||||
int faceIndex;
|
int faceIndex;
|
||||||
int elementIndex;
|
int elementIndex;
|
||||||
} UvElementID;
|
};
|
||||||
|
|
||||||
/** #StitchState initialization. */
|
/** #StitchState initialization. */
|
||||||
typedef struct StitchStateInit {
|
struct StitchStateInit {
|
||||||
int uv_selected_count;
|
int uv_selected_count;
|
||||||
UvElementID *to_select;
|
UvElementID *to_select;
|
||||||
} StitchStateInit;
|
};
|
||||||
|
|
||||||
/* constructor */
|
/* constructor */
|
||||||
static StitchPreviewer *stitch_preview_init(void)
|
static StitchPreviewer *stitch_preview_init()
|
||||||
{
|
{
|
||||||
StitchPreviewer *stitch_preview;
|
StitchPreviewer *stitch_preview;
|
||||||
|
|
||||||
stitch_preview = MEM_mallocN(sizeof(StitchPreviewer), "stitch_previewer");
|
stitch_preview = static_cast<StitchPreviewer *>(
|
||||||
stitch_preview->preview_polys = NULL;
|
MEM_mallocN(sizeof(StitchPreviewer), "stitch_previewer"));
|
||||||
stitch_preview->preview_stitchable = NULL;
|
stitch_preview->preview_polys = nullptr;
|
||||||
stitch_preview->preview_unstitchable = NULL;
|
stitch_preview->preview_stitchable = nullptr;
|
||||||
stitch_preview->uvs_per_polygon = NULL;
|
stitch_preview->preview_unstitchable = nullptr;
|
||||||
|
stitch_preview->uvs_per_polygon = nullptr;
|
||||||
|
|
||||||
stitch_preview->preview_uvs = 0;
|
stitch_preview->preview_uvs = 0;
|
||||||
stitch_preview->num_polys = 0;
|
stitch_preview->num_polys = 0;
|
||||||
stitch_preview->num_stitchable = 0;
|
stitch_preview->num_stitchable = 0;
|
||||||
stitch_preview->num_unstitchable = 0;
|
stitch_preview->num_unstitchable = 0;
|
||||||
|
|
||||||
stitch_preview->static_tris = NULL;
|
stitch_preview->static_tris = nullptr;
|
||||||
|
|
||||||
stitch_preview->num_static_tris = 0;
|
stitch_preview->num_static_tris = 0;
|
||||||
|
|
||||||
@ -315,7 +318,7 @@ static bool stitch_check_uvs_stitchable(const int cd_loop_uv_offset,
|
|||||||
float limit;
|
float limit;
|
||||||
|
|
||||||
if (element_iter == element) {
|
if (element_iter == element) {
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
limit = ssc->limit_dist;
|
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);
|
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) {
|
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,
|
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;
|
float limit;
|
||||||
|
|
||||||
if (edge_iter == edge) {
|
if (edge_iter == edge) {
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
limit = ssc->limit_dist;
|
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 &&
|
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)
|
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,
|
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) ||
|
if ((ssc->snap_islands && element->island == element_iter->island) ||
|
||||||
(!ssc->midpoints && 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);
|
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) ||
|
if ((ssc->snap_islands && edge->element->island == edge_iter->element->island) ||
|
||||||
(!ssc->midpoints && 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);
|
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;
|
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 == 0 ||
|
||||||
island_stitch_data[i].num_rot_elements_neg == 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 {
|
else {
|
||||||
rotation = (island_stitch_data[i].rotation * island_stitch_data[i].num_rot_elements +
|
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) /
|
island_stitch_data[i].num_rot_elements_neg) /
|
||||||
totelem;
|
totelem;
|
||||||
}
|
}
|
||||||
@ -628,9 +631,9 @@ static void state_delete(StitchState *state)
|
|||||||
MEM_freeN(state->edges);
|
MEM_freeN(state->edges);
|
||||||
}
|
}
|
||||||
stitch_preview_delete(state->stitch_preview);
|
stitch_preview_delete(state->stitch_preview);
|
||||||
state->stitch_preview = NULL;
|
state->stitch_preview = nullptr;
|
||||||
if (state->edge_hash) {
|
if (state->edge_hash) {
|
||||||
BLI_ghash_free(state->edge_hash, NULL, NULL);
|
BLI_ghash_free(state->edge_hash, nullptr, nullptr);
|
||||||
}
|
}
|
||||||
MEM_freeN(state);
|
MEM_freeN(state);
|
||||||
}
|
}
|
||||||
@ -673,7 +676,7 @@ static void stitch_uv_edge_generate_linked_edges(GHash *edge_hash, StitchState *
|
|||||||
edge->first = edge;
|
edge->first = edge;
|
||||||
|
|
||||||
for (; iter1; iter1 = iter1->next) {
|
for (; iter1; iter1 = iter1->next) {
|
||||||
UvElement *iter2 = NULL;
|
UvElement *iter2 = nullptr;
|
||||||
|
|
||||||
/* check to see if other vertex of edge belongs to same vertex as */
|
/* check to see if other vertex of edge belongs to same vertex as */
|
||||||
if (BM_elem_index_get(iter1->l->next->v) == elemindex2) {
|
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;
|
edgetmp.uv2 = index2;
|
||||||
|
|
||||||
/* get the edge from the hash */
|
/* 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 */
|
/* more iteration to make sure non-manifold case is handled nicely */
|
||||||
for (eiter = edge; eiter; eiter = eiter->next) {
|
for (eiter = edge; eiter; eiter = eiter->next) {
|
||||||
@ -944,38 +947,38 @@ static int stitch_process_data(StitchStateContainer *ssc,
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
StitchPreviewer *preview;
|
StitchPreviewer *preview;
|
||||||
IslandStitchData *island_stitch_data = NULL;
|
IslandStitchData *island_stitch_data = nullptr;
|
||||||
int previous_island = ssc->static_island;
|
int previous_island = ssc->static_island;
|
||||||
BMesh *bm = state->em->bm;
|
BMesh *bm = state->em->bm;
|
||||||
BMFace *efa;
|
BMFace *efa;
|
||||||
BMIter iter;
|
BMIter iter;
|
||||||
UVVertAverage *final_position = NULL;
|
UVVertAverage *final_position = nullptr;
|
||||||
bool is_active_state = (state == ssc->states[ssc->active_object_index]);
|
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);
|
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_PROP_FLOAT2);
|
||||||
|
|
||||||
char stitch_midpoints = ssc->midpoints;
|
char stitch_midpoints = ssc->midpoints;
|
||||||
/* Used to map UV indices to UV-average indices for selection. */
|
/* 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 */
|
/* per face preview position in preview buffer */
|
||||||
PreviewPosition *preview_position = NULL;
|
PreviewPosition *preview_position = nullptr;
|
||||||
|
|
||||||
/* cleanup previous preview */
|
/* cleanup previous preview */
|
||||||
stitch_preview_delete(state->stitch_preview);
|
stitch_preview_delete(state->stitch_preview);
|
||||||
preview = state->stitch_preview = stitch_preview_init();
|
preview = state->stitch_preview = stitch_preview_init();
|
||||||
if (preview == NULL) {
|
if (preview == nullptr) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
preview_position = MEM_mallocN(bm->totface * sizeof(*preview_position),
|
preview_position = static_cast<PreviewPosition *>(
|
||||||
"stitch_face_preview_position");
|
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 */
|
/* each face holds its position in the preview buffer in tmp. -1 is uninitialized */
|
||||||
for (i = 0; i < bm->totface; i++) {
|
for (i = 0; i < bm->totface; i++) {
|
||||||
preview_position[i].data_position = STITCH_NO_PREVIEW;
|
preview_position[i].data_position = STITCH_NO_PREVIEW;
|
||||||
}
|
}
|
||||||
|
|
||||||
island_stitch_data = MEM_callocN(sizeof(*island_stitch_data) * state->element_map->total_islands,
|
island_stitch_data = static_cast<IslandStitchData *>(MEM_callocN(
|
||||||
"stitch_island_data");
|
sizeof(*island_stitch_data) * state->element_map->total_islands, "stitch_island_data"));
|
||||||
if (!island_stitch_data) {
|
if (!island_stitch_data) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1144,14 +1147,14 @@ static int stitch_process_data(StitchStateContainer *ssc,
|
|||||||
uint buffer_index = 0;
|
uint buffer_index = 0;
|
||||||
|
|
||||||
/* initialize the preview buffers */
|
/* initialize the preview buffers */
|
||||||
preview->preview_polys = MEM_mallocN(sizeof(float[2]) * preview->preview_uvs,
|
preview->preview_polys = static_cast<float *>(
|
||||||
"tri_uv_stitch_prev");
|
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,
|
preview->uvs_per_polygon = static_cast<uint *>(
|
||||||
"tri_uv_stitch_prev");
|
MEM_mallocN(sizeof(*preview->uvs_per_polygon) * preview->num_polys, "tri_uv_stitch_prev"));
|
||||||
|
|
||||||
preview->static_tris = MEM_mallocN(
|
preview->static_tris = static_cast<float *>(
|
||||||
(sizeof(float[6]) * state->tris_per_island[ssc->static_island]),
|
MEM_mallocN((sizeof(float[6]) * state->tris_per_island[ssc->static_island]),
|
||||||
"static_island_preview_tris");
|
"static_island_preview_tris"));
|
||||||
|
|
||||||
preview->num_static_tris = state->tris_per_island[ssc->static_island];
|
preview->num_static_tris = state->tris_per_island[ssc->static_island];
|
||||||
/* will cause cancel and freeing of all data structures so OK */
|
/* 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) {
|
if (ssc->mode == STITCH_VERT) {
|
||||||
final_position = MEM_callocN(state->selection_size * sizeof(*final_position),
|
final_position = static_cast<UVVertAverage *>(
|
||||||
"stitch_uv_average");
|
MEM_callocN(state->selection_size * sizeof(*final_position), "stitch_uv_average"));
|
||||||
uvfinal_map = MEM_mallocN(state->element_map->total_uvs * sizeof(*uvfinal_map),
|
uvfinal_map = static_cast<uint *>(
|
||||||
"stitch_uv_final_map");
|
MEM_mallocN(state->element_map->total_uvs * sizeof(*uvfinal_map), "stitch_uv_final_map"));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
final_position = MEM_callocN(state->total_separate_uvs * sizeof(*final_position),
|
final_position = static_cast<UVVertAverage *>(
|
||||||
"stitch_uv_average");
|
MEM_callocN(state->total_separate_uvs * sizeof(*final_position), "stitch_uv_average"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* first pass, calculate final position for stitchable uvs of the static island */
|
/* first pass, calculate final position for stitchable uvs of the static island */
|
||||||
for (i = 0; i < state->selection_size; i++) {
|
for (i = 0; i < state->selection_size; i++) {
|
||||||
if (ssc->mode == STITCH_VERT) {
|
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) {
|
if (element->flag & STITCH_STITCHABLE) {
|
||||||
BMLoop *l = element->l;
|
BMLoop *l = element->l;
|
||||||
@ -1262,7 +1265,7 @@ static int stitch_process_data(StitchStateContainer *ssc,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
UvEdge *edge = state->selection_stack[i];
|
UvEdge *edge = static_cast<UvEdge *>(state->selection_stack[i]);
|
||||||
|
|
||||||
if (edge->flag & STITCH_STITCHABLE) {
|
if (edge->flag & STITCH_STITCHABLE) {
|
||||||
float *luv2, *luv1;
|
float *luv2, *luv1;
|
||||||
@ -1324,7 +1327,7 @@ static int stitch_process_data(StitchStateContainer *ssc,
|
|||||||
if (ssc->snap_islands) {
|
if (ssc->snap_islands) {
|
||||||
if (ssc->mode == STITCH_VERT) {
|
if (ssc->mode == STITCH_VERT) {
|
||||||
for (i = 0; i < state->selection_size; i++) {
|
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) {
|
if (element->flag & STITCH_STITCHABLE) {
|
||||||
BMLoop *l;
|
BMLoop *l;
|
||||||
@ -1374,7 +1377,7 @@ static int stitch_process_data(StitchStateContainer *ssc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < state->selection_size; i++) {
|
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 (!island_stitch_data[element->island].use_edge_rotation) {
|
||||||
if (element->flag & STITCH_STITCHABLE) {
|
if (element->flag & STITCH_STITCHABLE) {
|
||||||
stitch_island_calculate_vert_rotation(
|
stitch_island_calculate_vert_rotation(
|
||||||
@ -1406,11 +1409,11 @@ static int stitch_process_data(StitchStateContainer *ssc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < state->selection_size; i++) {
|
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) {
|
if (edge->flag & STITCH_STITCHABLE) {
|
||||||
stitch_island_calculate_edge_rotation(
|
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;
|
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 */
|
/* clear seams of stitched edges */
|
||||||
if (final && ssc->clear_seams) {
|
if (final && ssc->clear_seams) {
|
||||||
for (i = 0; i < state->selection_size; i++) {
|
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) {
|
if (edge->flag & STITCH_STITCHABLE) {
|
||||||
BM_elem_flag_disable(edge->element->l->e, BM_ELEM_SEAM);
|
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 */
|
/* third pass, propagate changes to coincident uvs */
|
||||||
for (i = 0; i < state->selection_size; i++) {
|
for (i = 0; i < state->selection_size; i++) {
|
||||||
if (ssc->mode == STITCH_VERT) {
|
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(
|
stitch_propagate_uv_final_position(
|
||||||
scene, element, i, preview_position, final_position, ssc, state, final);
|
scene, element, i, preview_position, final_position, ssc, state, final);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
UvEdge *edge = state->selection_stack[i];
|
UvEdge *edge = static_cast<UvEdge *>(state->selection_stack[i]);
|
||||||
|
|
||||||
stitch_propagate_uv_final_position(scene,
|
stitch_propagate_uv_final_position(scene,
|
||||||
state->uvs[edge->uv1],
|
state->uvs[edge->uv1],
|
||||||
@ -1489,22 +1492,22 @@ static int stitch_process_data_all(StitchStateContainer *ssc, Scene *scene, int
|
|||||||
/* Stitch hash initialization functions */
|
/* Stitch hash initialization functions */
|
||||||
static uint uv_edge_hash(const void *key)
|
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);
|
BLI_assert(edge->uv1 < edge->uv2);
|
||||||
return (BLI_ghashutil_uinthash(edge->uv2) + BLI_ghashutil_uinthash(edge->uv1));
|
return (BLI_ghashutil_uinthash(edge->uv2) + BLI_ghashutil_uinthash(edge->uv1));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool uv_edge_compare(const void *a, const void *b)
|
static bool uv_edge_compare(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
const UvEdge *edge1 = a;
|
const UvEdge *edge1 = static_cast<const UvEdge *>(a);
|
||||||
const UvEdge *edge2 = b;
|
const UvEdge *edge2 = static_cast<const UvEdge *>(b);
|
||||||
BLI_assert(edge1->uv1 < edge1->uv2);
|
BLI_assert(edge1->uv1 < edge1->uv2);
|
||||||
BLI_assert(edge2->uv1 < edge2->uv2);
|
BLI_assert(edge2->uv1 < edge2->uv2);
|
||||||
|
|
||||||
if ((edge1->uv1 == edge2->uv1) && (edge1->uv2 == edge2->uv2)) {
|
if ((edge1->uv1 == edge2->uv1) && (edge1->uv2 == edge2->uv2)) {
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* select all common edges */
|
/* 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) {
|
if (from_stitch_mode == STITCH_VERT) {
|
||||||
int i;
|
int i;
|
||||||
state->selection_stack = MEM_mallocN(state->total_separate_edges *
|
state->selection_stack = static_cast<void **>(
|
||||||
sizeof(*state->selection_stack),
|
MEM_mallocN(state->total_separate_edges * sizeof(*state->selection_stack),
|
||||||
"stitch_new_edge_selection_stack");
|
"stitch_new_edge_selection_stack"));
|
||||||
|
|
||||||
/* check if both elements of an edge are selected */
|
/* check if both elements of an edge are selected */
|
||||||
for (i = 0; i < state->total_separate_edges; i++) {
|
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 */
|
/* unselect selected uvelements */
|
||||||
for (i = 0; i < old_selection_size; i++) {
|
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;
|
element->flag &= ~STITCH_SELECTED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int i;
|
int i;
|
||||||
state->selection_stack = MEM_mallocN(state->total_separate_uvs *
|
state->selection_stack = static_cast<void **>(
|
||||||
sizeof(*state->selection_stack),
|
MEM_mallocN(state->total_separate_uvs * sizeof(*state->selection_stack),
|
||||||
"stitch_new_vert_selection_stack");
|
"stitch_new_vert_selection_stack"));
|
||||||
|
|
||||||
for (i = 0; i < old_selection_size; i++) {
|
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 *element1 = state->uvs[edge->uv1];
|
||||||
UvElement *element2 = state->uvs[edge->uv2];
|
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])
|
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_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR);
|
||||||
GPU_batch_uniform_4fv(batch, "color", col);
|
GPU_batch_uniform_4fv(batch, "color", col);
|
||||||
GPU_batch_draw(batch);
|
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
|
/* 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;
|
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);
|
UvElement *element2 = BM_uv_element_get(state->element_map, l->next);
|
||||||
|
|
||||||
if (!element1 || !element2) {
|
if (!element1 || !element2) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int uv1 = state->map[element1 - state->element_map->storage];
|
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;
|
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,
|
static StitchState *stitch_init(bContext *C,
|
||||||
@ -1842,7 +1845,7 @@ static StitchState *stitch_init(bContext *C,
|
|||||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||||
const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
|
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 */
|
/* initialize state */
|
||||||
state->obedit = obedit;
|
state->obedit = obedit;
|
||||||
@ -1857,7 +1860,7 @@ static StitchState *stitch_init(bContext *C,
|
|||||||
|
|
||||||
if (!state->element_map) {
|
if (!state->element_map) {
|
||||||
state_delete(state);
|
state_delete(state);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
state->aspect = ED_uvedit_get_aspect_y(obedit);
|
state->aspect = ED_uvedit_get_aspect_y(obedit);
|
||||||
@ -1866,21 +1869,24 @@ static StitchState *stitch_init(bContext *C,
|
|||||||
state->total_separate_uvs = unique_uvs;
|
state->total_separate_uvs = unique_uvs;
|
||||||
|
|
||||||
/* Allocate the unique uv buffers */
|
/* 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
|
/* 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.
|
* 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]}`. */
|
* 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->normals = static_cast<float *>(
|
||||||
state->map = map = MEM_mallocN(sizeof(*map) * state->element_map->total_uvs,
|
MEM_callocN(sizeof(*state->normals) * 2 * unique_uvs, "uv_stitch_normals"));
|
||||||
"uv_stitch_unique_map");
|
state->map = map = static_cast<int *>(
|
||||||
|
MEM_mallocN(sizeof(*map) * state->element_map->total_uvs, "uv_stitch_unique_map"));
|
||||||
/* Allocate the edge stack */
|
/* Allocate the edge stack */
|
||||||
edge_hash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "stitch_edge_hash");
|
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. */
|
BLI_assert(!state->stitch_preview); /* Paranoia. */
|
||||||
if (!state->uvs || !map || !edge_hash || !all_edges) {
|
if (!state->uvs || !map || !edge_hash || !all_edges) {
|
||||||
state_delete(state);
|
state_delete(state);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Index for the UvElements. */
|
/* Index for the UvElements. */
|
||||||
@ -1918,8 +1924,8 @@ static StitchState *stitch_init(bContext *C,
|
|||||||
int offset1 = map[itmp1];
|
int offset1 = map[itmp1];
|
||||||
int offset2 = map[itmp2];
|
int offset2 = map[itmp2];
|
||||||
|
|
||||||
all_edges[counter].next = NULL;
|
all_edges[counter].next = nullptr;
|
||||||
all_edges[counter].first = NULL;
|
all_edges[counter].first = nullptr;
|
||||||
all_edges[counter].flag = 0;
|
all_edges[counter].flag = 0;
|
||||||
all_edges[counter].element = element;
|
all_edges[counter].element = element;
|
||||||
/* Using an order policy, sort UVs according to address space.
|
/* 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;
|
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) {
|
if (edge) {
|
||||||
edge->flag = 0;
|
edge->flag = 0;
|
||||||
}
|
}
|
||||||
@ -1946,12 +1952,13 @@ static StitchState *stitch_init(bContext *C,
|
|||||||
}
|
}
|
||||||
|
|
||||||
total_edges = BLI_ghash_len(edge_hash);
|
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 */
|
/* I assume any system will be able to at least allocate an iterator :p */
|
||||||
if (!edges) {
|
if (!edges) {
|
||||||
state_delete(state);
|
state_delete(state);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
state->total_separate_edges = total_edges;
|
state->total_separate_edges = total_edges;
|
||||||
@ -1965,7 +1972,7 @@ static StitchState *stitch_init(bContext *C,
|
|||||||
/* cleanup temporary stuff */
|
/* cleanup temporary stuff */
|
||||||
MEM_freeN(all_edges);
|
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. */
|
/* 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");
|
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;
|
state->selection_size = 0;
|
||||||
|
|
||||||
/* Load old selection if redoing operator with different settings */
|
/* Load old selection if redoing operator with different settings */
|
||||||
if (state_init != NULL) {
|
if (state_init != nullptr) {
|
||||||
int faceIndex, elementIndex;
|
int faceIndex, elementIndex;
|
||||||
UvElement *element;
|
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);
|
BM_mesh_elem_table_ensure(em->bm, BM_FACE);
|
||||||
|
|
||||||
int selected_count = state_init->uv_selected_count;
|
int selected_count = state_init->uv_selected_count;
|
||||||
|
|
||||||
if (stored_mode == STITCH_VERT) {
|
if (stored_mode == STITCH_VERT) {
|
||||||
state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) *
|
state->selection_stack = static_cast<void **>(
|
||||||
state->total_separate_uvs,
|
MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_uvs,
|
||||||
"uv_stitch_selection_stack");
|
"uv_stitch_selection_stack"));
|
||||||
|
|
||||||
while (selected_count--) {
|
while (selected_count--) {
|
||||||
faceIndex = state_init->to_select[selected_count].faceIndex;
|
faceIndex = state_init->to_select[selected_count].faceIndex;
|
||||||
elementIndex = state_init->to_select[selected_count].elementIndex;
|
elementIndex = state_init->to_select[selected_count].elementIndex;
|
||||||
efa = BM_face_at_index(em->bm, faceIndex);
|
efa = BM_face_at_index(em->bm, faceIndex);
|
||||||
element = BM_uv_element_get(state->element_map,
|
element = BM_uv_element_get(
|
||||||
BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, elementIndex));
|
state->element_map,
|
||||||
|
static_cast<BMLoop *>(BM_iter_at_index(nullptr, BM_LOOPS_OF_FACE, efa, elementIndex)));
|
||||||
stitch_select_uv(element, state, 1);
|
stitch_select_uv(element, state, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) *
|
state->selection_stack = static_cast<void **>(
|
||||||
state->total_separate_edges,
|
MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_edges,
|
||||||
"uv_stitch_selection_stack");
|
"uv_stitch_selection_stack"));
|
||||||
|
|
||||||
while (selected_count--) {
|
while (selected_count--) {
|
||||||
UvEdge tmp_edge, *edge;
|
UvEdge tmp_edge, *edge;
|
||||||
@ -2034,13 +2042,15 @@ static StitchState *stitch_init(bContext *C,
|
|||||||
faceIndex = state_init->to_select[selected_count].faceIndex;
|
faceIndex = state_init->to_select[selected_count].faceIndex;
|
||||||
elementIndex = state_init->to_select[selected_count].elementIndex;
|
elementIndex = state_init->to_select[selected_count].elementIndex;
|
||||||
efa = BM_face_at_index(em->bm, faceIndex);
|
efa = BM_face_at_index(em->bm, faceIndex);
|
||||||
element = BM_uv_element_get(state->element_map,
|
element = BM_uv_element_get(
|
||||||
BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, elementIndex));
|
state->element_map,
|
||||||
|
static_cast<BMLoop *>(BM_iter_at_index(nullptr, BM_LOOPS_OF_FACE, efa, elementIndex)));
|
||||||
uv1 = map[element - state->element_map->storage];
|
uv1 = map[element - state->element_map->storage];
|
||||||
|
|
||||||
element = BM_uv_element_get(
|
element = BM_uv_element_get(
|
||||||
state->element_map,
|
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];
|
uv2 = map[element - state->element_map->storage];
|
||||||
|
|
||||||
if (uv1 < uv2) {
|
if (uv1 < uv2) {
|
||||||
@ -2052,7 +2062,7 @@ static StitchState *stitch_init(bContext *C,
|
|||||||
tmp_edge.uv2 = uv1;
|
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);
|
stitch_select_edge(edge, state, true);
|
||||||
}
|
}
|
||||||
@ -2065,9 +2075,9 @@ static StitchState *stitch_init(bContext *C,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (ssc->mode == STITCH_VERT) {
|
if (ssc->mode == STITCH_VERT) {
|
||||||
state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) *
|
state->selection_stack = static_cast<void **>(
|
||||||
state->total_separate_uvs,
|
MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_uvs,
|
||||||
"uv_stitch_selection_stack");
|
"uv_stitch_selection_stack"));
|
||||||
|
|
||||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||||
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
|
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
|
||||||
@ -2081,9 +2091,9 @@ static StitchState *stitch_init(bContext *C,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) *
|
state->selection_stack = static_cast<void **>(
|
||||||
state->total_separate_edges,
|
MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_edges,
|
||||||
"uv_stitch_selection_stack");
|
"uv_stitch_selection_stack"));
|
||||||
|
|
||||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||||
if (!(ts->uv_flag & UV_SYNC_SELECTION) &&
|
if (!(ts->uv_flag & UV_SYNC_SELECTION) &&
|
||||||
@ -2106,8 +2116,8 @@ static StitchState *stitch_init(bContext *C,
|
|||||||
|
|
||||||
/***** initialize static island preview data *****/
|
/***** initialize static island preview data *****/
|
||||||
|
|
||||||
state->tris_per_island = MEM_mallocN(
|
state->tris_per_island = static_cast<uint *>(MEM_mallocN(
|
||||||
sizeof(*state->tris_per_island) * state->element_map->total_islands, "stitch island tris");
|
sizeof(*state->tris_per_island) * state->element_map->total_islands, "stitch island tris"));
|
||||||
for (i = 0; i < state->element_map->total_islands; i++) {
|
for (i = 0; i < state->element_map->total_islands; i++) {
|
||||||
state->tris_per_island[i] = 0;
|
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,
|
state->island_is_stitchable = static_cast<bool *>(
|
||||||
"stitch I stops");
|
MEM_callocN(sizeof(bool) * state->element_map->total_islands, "stitch I stops"));
|
||||||
if (!state->island_is_stitchable) {
|
if (!state->island_is_stitchable) {
|
||||||
state_delete(state);
|
state_delete(state);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!stitch_process_data(ssc, state, scene, false)) {
|
if (!stitch_process_data(ssc, state, scene, false)) {
|
||||||
state_delete(state);
|
state_delete(state);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
@ -2194,7 +2204,7 @@ static int stitch_init_all(bContext *C, wmOperator *op)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
StitchStateContainer *ssc = MEM_callocN(sizeof(StitchStateContainer), "stitch collection");
|
StitchStateContainer *ssc = MEM_cnew<StitchStateContainer>("stitch collection");
|
||||||
|
|
||||||
op->customdata = ssc;
|
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->objects = static_cast<Object **>(
|
||||||
ssc->states = MEM_callocN(sizeof(StitchState *) * objects_len, "StitchState");
|
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;
|
ssc->objects_len = 0;
|
||||||
|
|
||||||
int *objs_selection_count = NULL;
|
int *objs_selection_count = nullptr;
|
||||||
UvElementID *selected_uvs_arr = NULL;
|
UvElementID *selected_uvs_arr = nullptr;
|
||||||
StitchStateInit *state_init = NULL;
|
StitchStateInit *state_init = nullptr;
|
||||||
|
|
||||||
if (RNA_struct_property_is_set(op->ptr, "selection") &&
|
if (RNA_struct_property_is_set(op->ptr, "selection") &&
|
||||||
RNA_struct_property_is_set(op->ptr, "objects_selection_count"))
|
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
|
/* Retrieve list of selected UVs, one list contains all selected UVs
|
||||||
* for all objects. */
|
* 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);
|
RNA_int_get_array(op->ptr, "objects_selection_count", objs_selection_count);
|
||||||
|
|
||||||
int total_selected = 0;
|
int total_selected = 0;
|
||||||
@ -2250,7 +2263,8 @@ static int stitch_init_all(bContext *C, wmOperator *op)
|
|||||||
total_selected += objs_selection_count[ob_index];
|
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;
|
int sel_idx = 0;
|
||||||
RNA_BEGIN (op->ptr, itemptr, "selection") {
|
RNA_BEGIN (op->ptr, itemptr, "selection") {
|
||||||
BLI_assert(sel_idx < total_selected);
|
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");
|
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;
|
state_init->to_select = selected_uvs_arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
||||||
Object *obedit = objects[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];
|
state_init->uv_selected_count = objs_selection_count[ob_index];
|
||||||
}
|
}
|
||||||
|
|
||||||
StitchState *stitch_state_ob = stitch_init(C, op, ssc, obedit, state_init);
|
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. */
|
/* Move pointer to beginning of next object's data. */
|
||||||
state_init->to_select += state_init->uv_selected_count;
|
state_init->to_select += state_init->uv_selected_count;
|
||||||
}
|
}
|
||||||
@ -2324,7 +2339,7 @@ static int stitch_init_all(bContext *C, wmOperator *op)
|
|||||||
return 1;
|
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)) {
|
if (!stitch_init_all(C, op)) {
|
||||||
return OPERATOR_CANCELLED;
|
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);
|
RNA_int_set(op->ptr, "static_island", ssc->static_island);
|
||||||
|
|
||||||
int *objs_selection_count = NULL;
|
int *objs_selection_count = nullptr;
|
||||||
objs_selection_count = MEM_mallocN(sizeof(int *) * ssc->objects_len,
|
objs_selection_count = static_cast<int *>(
|
||||||
"objects_selection_count");
|
MEM_mallocN(sizeof(int *) * ssc->objects_len, "objects_selection_count"));
|
||||||
|
|
||||||
/* Store selection for re-execution of stitch
|
/* Store selection for re-execution of stitch
|
||||||
* - Store all selected UVs in "selection"
|
* - Store all selected UVs in "selection"
|
||||||
@ -2390,7 +2405,7 @@ static void stitch_exit(bContext *C, wmOperator *op, int finished)
|
|||||||
UvElement *element;
|
UvElement *element;
|
||||||
|
|
||||||
if (ssc->mode == STITCH_VERT) {
|
if (ssc->mode == STITCH_VERT) {
|
||||||
element = state->selection_stack[i];
|
element = static_cast<UvElement *>(state->selection_stack[i]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
element = ((UvEdge *)state->selection_stack[i])->element;
|
element = ((UvEdge *)state->selection_stack[i])->element;
|
||||||
@ -2412,7 +2427,7 @@ static void stitch_exit(bContext *C, wmOperator *op, int finished)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (area) {
|
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);
|
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;
|
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);
|
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
state_delete_all(ssc);
|
state_delete_all(ssc);
|
||||||
|
|
||||||
op->customdata = NULL;
|
op->customdata = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stitch_cancel(bContext *C, wmOperator *op)
|
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 */
|
* the opposite stitchable vertex and the initial still gets deselected */
|
||||||
|
|
||||||
/* find StitchState from hit->ob */
|
/* find StitchState from hit->ob */
|
||||||
StitchState *state = NULL;
|
StitchState *state = nullptr;
|
||||||
for (uint ob_index = 0; ob_index < ssc->objects_len; ob_index++) {
|
for (uint ob_index = 0; ob_index < ssc->objects_len; ob_index++) {
|
||||||
if (hit.ob == ssc->objects[ob_index]) {
|
if (hit.ob == ssc->objects[ob_index]) {
|
||||||
state = ssc->states[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)) {
|
else if (uv_find_nearest_edge_multi(scene, ssc->objects, ssc->objects_len, co, 0.0f, &hit)) {
|
||||||
/* find StitchState from hit->ob */
|
/* find StitchState from hit->ob */
|
||||||
StitchState *state = NULL;
|
StitchState *state = nullptr;
|
||||||
for (uint ob_index = 0; ob_index < ssc->objects_len; ob_index++) {
|
for (uint ob_index = 0; ob_index < ssc->objects_len; ob_index++) {
|
||||||
if (hit.ob == ssc->objects[ob_index]) {
|
if (hit.ob == ssc->objects[ob_index]) {
|
||||||
state = ssc->states[ob_index];
|
state = ssc->states[ob_index];
|
||||||
@ -2510,7 +2525,7 @@ static StitchState *stitch_select(bContext *C,
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
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;
|
StitchStateContainer *ssc;
|
||||||
Scene *scene = CTX_data_scene(C);
|
Scene *scene = CTX_data_scene(C);
|
||||||
|
|
||||||
ssc = op->customdata;
|
ssc = static_cast<StitchStateContainer *>(op->customdata);
|
||||||
StitchState *active_state = ssc->states[ssc->active_object_index];
|
StitchState *active_state = ssc->states[ssc->active_object_index];
|
||||||
|
|
||||||
switch (event->type) {
|
switch (event->type) {
|
||||||
@ -2681,7 +2696,7 @@ void UV_OT_stitch(wmOperatorType *ot)
|
|||||||
static const EnumPropertyItem stitch_modes[] = {
|
static const EnumPropertyItem stitch_modes[] = {
|
||||||
{STITCH_VERT, "VERTEX", 0, "Vertex", ""},
|
{STITCH_VERT, "VERTEX", 0, "Vertex", ""},
|
||||||
{STITCH_EDGE, "EDGE", 0, "Edge", ""},
|
{STITCH_EDGE, "EDGE", 0, "Edge", ""},
|
||||||
{0, NULL, 0, NULL, NULL},
|
{0, nullptr, 0, nullptr, nullptr},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* identifiers */
|
/* identifiers */
|
||||||
@ -2699,10 +2714,10 @@ void UV_OT_stitch(wmOperatorType *ot)
|
|||||||
|
|
||||||
/* properties */
|
/* properties */
|
||||||
RNA_def_boolean(
|
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,
|
RNA_def_boolean(ot->srna,
|
||||||
"snap_islands",
|
"snap_islands",
|
||||||
1,
|
true,
|
||||||
"Snap Islands",
|
"Snap Islands",
|
||||||
"Snap islands together (on edge stitch mode, rotates the islands too)");
|
"Snap islands together (on edge stitch mode, rotates the islands too)");
|
||||||
|
|
||||||
@ -2735,10 +2750,10 @@ void UV_OT_stitch(wmOperatorType *ot)
|
|||||||
INT_MAX);
|
INT_MAX);
|
||||||
RNA_def_boolean(ot->srna,
|
RNA_def_boolean(ot->srna,
|
||||||
"midpoint_snap",
|
"midpoint_snap",
|
||||||
0,
|
false,
|
||||||
"Snap at Midpoint",
|
"Snap at Midpoint",
|
||||||
"UVs are stitched at midpoint instead of at static island");
|
"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,
|
RNA_def_enum(ot->srna,
|
||||||
"mode",
|
"mode",
|
||||||
stitch_modes,
|
stitch_modes,
|
||||||
@ -2761,7 +2776,7 @@ void UV_OT_stitch(wmOperatorType *ot)
|
|||||||
prop = RNA_def_int_array(ot->srna,
|
prop = RNA_def_int_array(ot->srna,
|
||||||
"objects_selection_count",
|
"objects_selection_count",
|
||||||
1,
|
1,
|
||||||
NULL,
|
nullptr,
|
||||||
0,
|
0,
|
||||||
INT_MAX,
|
INT_MAX,
|
||||||
"Objects Selection Count",
|
"Objects Selection Count",
|
@ -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)
|
static bool ED_uvedit_ensure_uvs(Object *obedit)
|
||||||
{
|
{
|
||||||
if (ED_uvedit_test(obedit)) {
|
if (ED_uvedit_test(obedit)) {
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
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. */
|
/* Happens when there are no faces. */
|
||||||
if (!ED_uvedit_test(obedit)) {
|
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);
|
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;
|
BMIter liter;
|
||||||
|
|
||||||
*r_uv = nullptr;
|
*r_uv = nullptr;
|
||||||
*r_pin = 0;
|
*r_pin = false;
|
||||||
*r_select = 1;
|
*r_select = true;
|
||||||
|
|
||||||
if (index == ORIGINDEX_NONE) {
|
if (index == ORIGINDEX_NONE) {
|
||||||
return;
|
return;
|
||||||
@ -1008,7 +1008,7 @@ void UV_OT_minimize_stretch(wmOperatorType *ot)
|
|||||||
/* properties */
|
/* properties */
|
||||||
RNA_def_boolean(ot->srna,
|
RNA_def_boolean(ot->srna,
|
||||||
"fill_holes",
|
"fill_holes",
|
||||||
1,
|
true,
|
||||||
"Fill Holes",
|
"Fill Holes",
|
||||||
"Virtually fill holes in mesh before unwrapping, to better avoid overlaps and "
|
"Virtually fill holes in mesh before unwrapping, to better avoid overlaps and "
|
||||||
"preserve symmetry");
|
"preserve symmetry");
|
||||||
@ -1205,7 +1205,7 @@ static void uvedit_pack_islands_multi(const Scene *scene,
|
|||||||
offsets);
|
offsets);
|
||||||
|
|
||||||
/* Remove from linked list and append to blender::Vector. */
|
/* 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);
|
BLI_remlink(&island_list, island);
|
||||||
const bool pinned = island_has_pins(scene, island, params);
|
const bool pinned = island_has_pins(scene, island, params);
|
||||||
if (ignore_pinned && pinned) {
|
if (ignore_pinned && pinned) {
|
||||||
@ -1838,8 +1838,10 @@ void ED_uvedit_live_unwrap_end(short cancel)
|
|||||||
#define POLAR_ZX 0
|
#define POLAR_ZX 0
|
||||||
#define POLAR_ZY 1
|
#define POLAR_ZY 1
|
||||||
|
|
||||||
#define PINCH 0
|
enum {
|
||||||
#define FAN 1
|
PINCH = 0,
|
||||||
|
FAN = 1,
|
||||||
|
};
|
||||||
|
|
||||||
static void uv_map_transform_calc_bounds(BMEditMesh *em, float r_min[3], float r_max[3])
|
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",
|
"Align",
|
||||||
"How to determine rotation around the pole");
|
"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_enum(ot->srna, "pole", pole_items, PINCH, "Pole", "How to handle faces at the poles");
|
||||||
RNA_def_boolean(
|
RNA_def_boolean(ot->srna,
|
||||||
ot->srna, "seam", 0, "Preserve Seams", "Separate projections by islands isolated by seams");
|
"seam",
|
||||||
|
false,
|
||||||
|
"Preserve Seams",
|
||||||
|
"Separate projections by islands isolated by seams");
|
||||||
|
|
||||||
if (radius) {
|
if (radius) {
|
||||||
RNA_def_float(ot->srna,
|
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,
|
RNA_def_boolean(ot->srna,
|
||||||
"correct_aspect",
|
"correct_aspect",
|
||||||
1,
|
true,
|
||||||
"Correct Aspect",
|
"Correct Aspect",
|
||||||
"Map UVs taking image aspect ratio into account");
|
"Map UVs taking image aspect ratio into account");
|
||||||
/* Optional, since not all unwrapping types need to be clipped. */
|
/* Optional, since not all unwrapping types need to be clipped. */
|
||||||
if (clip_to_bounds) {
|
if (clip_to_bounds) {
|
||||||
RNA_def_boolean(ot->srna,
|
RNA_def_boolean(ot->srna,
|
||||||
"clip_to_bounds",
|
"clip_to_bounds",
|
||||||
0,
|
false,
|
||||||
"Clip to Bounds",
|
"Clip to Bounds",
|
||||||
"Clip UV coordinates to bounds after unwrapping");
|
"Clip UV coordinates to bounds after unwrapping");
|
||||||
}
|
}
|
||||||
RNA_def_boolean(ot->srna,
|
RNA_def_boolean(ot->srna,
|
||||||
"scale_to_bounds",
|
"scale_to_bounds",
|
||||||
0,
|
false,
|
||||||
"Scale to Bounds",
|
"Scale to Bounds",
|
||||||
"Scale UV coordinates to bounds after unwrapping");
|
"Scale UV coordinates to bounds after unwrapping");
|
||||||
}
|
}
|
||||||
@ -2575,13 +2580,13 @@ void UV_OT_unwrap(wmOperatorType *ot)
|
|||||||
"being somewhat slower)");
|
"being somewhat slower)");
|
||||||
RNA_def_boolean(ot->srna,
|
RNA_def_boolean(ot->srna,
|
||||||
"fill_holes",
|
"fill_holes",
|
||||||
1,
|
true,
|
||||||
"Fill Holes",
|
"Fill Holes",
|
||||||
"Virtually fill holes in mesh before unwrapping, to better avoid overlaps and "
|
"Virtually fill holes in mesh before unwrapping, to better avoid overlaps and "
|
||||||
"preserve symmetry");
|
"preserve symmetry");
|
||||||
RNA_def_boolean(ot->srna,
|
RNA_def_boolean(ot->srna,
|
||||||
"correct_aspect",
|
"correct_aspect",
|
||||||
1,
|
true,
|
||||||
"Correct Aspect",
|
"Correct Aspect",
|
||||||
"Map UVs taking image aspect ratio into account");
|
"Map UVs taking image aspect ratio into account");
|
||||||
RNA_def_boolean(
|
RNA_def_boolean(
|
||||||
@ -3139,7 +3144,7 @@ static bool uv_from_view_poll(bContext *C)
|
|||||||
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
||||||
|
|
||||||
if (!ED_operator_uvmap(C)) {
|
if (!ED_operator_uvmap(C)) {
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (rv3d != nullptr);
|
return (rv3d != nullptr);
|
||||||
@ -3160,10 +3165,10 @@ void UV_OT_project_from_view(wmOperatorType *ot)
|
|||||||
ot->poll = uv_from_view_poll;
|
ot->poll = uv_from_view_poll;
|
||||||
|
|
||||||
/* properties */
|
/* 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,
|
RNA_def_boolean(ot->srna,
|
||||||
"camera_bounds",
|
"camera_bounds",
|
||||||
1,
|
true,
|
||||||
"Camera Bounds",
|
"Camera Bounds",
|
||||||
"Map UVs to the camera region taking resolution and aspect into account");
|
"Map UVs to the camera region taking resolution and aspect into account");
|
||||||
uv_map_clip_correct_properties(ot);
|
uv_map_clip_correct_properties(ot);
|
||||||
|
@ -307,25 +307,27 @@ bool imb_oiio_write(const WriteContext &ctx, const char *filepath, const ImageSp
|
|||||||
final_buf = std::move(orig_buf);
|
final_buf = std::move(orig_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ok = false;
|
bool write_ok = false;
|
||||||
|
bool close_ok = false;
|
||||||
if (ctx.flags & IB_mem) {
|
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);
|
ImBufMemWriter writer(ctx.ibuf);
|
||||||
|
|
||||||
imb_addencodedbufferImBuf(ctx.ibuf);
|
imb_addencodedbufferImBuf(ctx.ibuf);
|
||||||
out->set_ioproxy(&writer);
|
out->set_ioproxy(&writer);
|
||||||
if (out->open("", file_spec)) {
|
if (out->open("", file_spec)) {
|
||||||
ok = final_buf.write(out.get());
|
write_ok = final_buf.write(out.get());
|
||||||
|
close_ok = out->close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (out->open(filepath, file_spec)) {
|
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 write_ok && close_ok;
|
||||||
return ok;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteContext imb_create_write_context(const char *file_format,
|
WriteContext imb_create_write_context(const char *file_format,
|
||||||
|
@ -576,28 +576,61 @@ static const char *load_edge_element(PlyReadBuffer &file,
|
|||||||
return nullptr;
|
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> import_ply_data(PlyReadBuffer &file, PlyHeader &header)
|
||||||
{
|
{
|
||||||
std::unique_ptr<PlyData> data = std::make_unique<PlyData>();
|
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) {
|
for (const PlyElement &element : header.elements) {
|
||||||
const char *error = nullptr;
|
const char *error = nullptr;
|
||||||
if (element.name == "vertex") {
|
if (element.name == "vertex") {
|
||||||
error = load_vertex_element(file, header, element, data.get());
|
error = load_vertex_element(file, header, element, data.get());
|
||||||
|
got_vertex = true;
|
||||||
}
|
}
|
||||||
else if (element.name == "face") {
|
else if (element.name == "face") {
|
||||||
error = load_face_element(file, header, element, data.get());
|
error = load_face_element(file, header, element, data.get());
|
||||||
|
got_face = true;
|
||||||
}
|
}
|
||||||
else if (element.name == "tristrips") {
|
else if (element.name == "tristrips") {
|
||||||
error = load_tristrips_element(file, header, element, data.get());
|
error = load_tristrips_element(file, header, element, data.get());
|
||||||
|
got_tristrips = true;
|
||||||
}
|
}
|
||||||
else if (element.name == "edge") {
|
else if (element.name == "edge") {
|
||||||
error = load_edge_element(file, header, element, data.get());
|
error = load_edge_element(file, header, element, data.get());
|
||||||
|
got_edge = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
error = skip_element(file, header, element);
|
||||||
}
|
}
|
||||||
if (error != nullptr) {
|
if (error != nullptr) {
|
||||||
data->error = error;
|
data->error = error;
|
||||||
return data;
|
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;
|
return data;
|
||||||
|
@ -147,6 +147,22 @@ TEST_F(ply_import_test, PlyImportColorNotFull)
|
|||||||
import_and_check("color_not_full_b.ply", expect);
|
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)
|
TEST_F(ply_import_test, PlyImportDoubleXYZ)
|
||||||
{
|
{
|
||||||
Expectation expect = {4,
|
Expectation expect = {4,
|
||||||
|
@ -1192,7 +1192,7 @@ typedef enum IDRecalcFlag {
|
|||||||
* required to address all remaining relationship cases.
|
* required to address all remaining relationship cases.
|
||||||
* See e.g. how #BKE_library_unused_linked_data_set_tag is doing this.
|
* 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. */
|
/* Special case: Library, should never ever depend on any other type. */
|
||||||
INDEX_ID_LI = 0,
|
INDEX_ID_LI = 0,
|
||||||
|
|
||||||
@ -1273,8 +1273,9 @@ enum {
|
|||||||
|
|
||||||
/* Special values. */
|
/* Special values. */
|
||||||
INDEX_ID_NULL,
|
INDEX_ID_NULL,
|
||||||
INDEX_ID_MAX,
|
} eID_Index;
|
||||||
};
|
|
||||||
|
#define INDEX_ID_MAX (INDEX_ID_NULL + 1)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -712,6 +712,7 @@ static const EnumPropertyItem snap_to_items[] = {
|
|||||||
# include "BKE_pointcache.h"
|
# include "BKE_pointcache.h"
|
||||||
# include "BKE_scene.h"
|
# include "BKE_scene.h"
|
||||||
# include "BKE_screen.h"
|
# include "BKE_screen.h"
|
||||||
|
# include "BKE_simulation.h"
|
||||||
# include "BKE_unit.h"
|
# include "BKE_unit.h"
|
||||||
|
|
||||||
# include "NOD_composite.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,
|
* however, changes in FPS actually modifies an original skip length,
|
||||||
* so this we take care about here. */
|
* so this we take care about here. */
|
||||||
SEQ_sound_update_length(bmain, scene);
|
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)
|
static void rna_Scene_listener_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
|
||||||
|
@ -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_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_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_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_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_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")
|
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")
|
||||||
|
@ -130,6 +130,7 @@ set(SRC
|
|||||||
nodes/node_geo_mesh_to_points.cc
|
nodes/node_geo_mesh_to_points.cc
|
||||||
nodes/node_geo_mesh_to_sdf_volume.cc
|
nodes/node_geo_mesh_to_sdf_volume.cc
|
||||||
nodes/node_geo_mesh_to_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_face.cc
|
||||||
nodes/node_geo_mesh_topology_corners_of_vertex.cc
|
nodes/node_geo_mesh_topology_corners_of_vertex.cc
|
||||||
nodes/node_geo_mesh_topology_edges_of_corner.cc
|
nodes/node_geo_mesh_topology_edges_of_corner.cc
|
||||||
|
@ -114,6 +114,7 @@ void register_geometry_nodes()
|
|||||||
register_node_type_geo_mesh_to_points();
|
register_node_type_geo_mesh_to_points();
|
||||||
register_node_type_geo_mesh_to_sdf_volume();
|
register_node_type_geo_mesh_to_sdf_volume();
|
||||||
register_node_type_geo_mesh_to_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_face();
|
||||||
register_node_type_geo_mesh_topology_corners_of_vertex();
|
register_node_type_geo_mesh_topology_corners_of_vertex();
|
||||||
register_node_type_geo_mesh_topology_edges_of_corner();
|
register_node_type_geo_mesh_topology_edges_of_corner();
|
||||||
|
@ -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_points();
|
||||||
void register_node_type_geo_mesh_to_sdf_volume();
|
void register_node_type_geo_mesh_to_sdf_volume();
|
||||||
void register_node_type_geo_mesh_to_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_face();
|
||||||
void register_node_type_geo_mesh_topology_corners_of_vertex();
|
void register_node_type_geo_mesh_topology_corners_of_vertex();
|
||||||
void register_node_type_geo_mesh_topology_edges_of_corner();
|
void register_node_type_geo_mesh_topology_edges_of_corner();
|
||||||
|
@ -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::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_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::Int>("Next Vertex Index").reference_pass_all();
|
||||||
b.add_output<decl::Float>("Total Cost").field_source();
|
b.add_output<decl::Float>("Total Cost").reference_pass_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef std::pair<float, int> VertPriority;
|
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);
|
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
|
uint64_t hash() const override
|
||||||
{
|
{
|
||||||
return get_default_hash_2(end_selection_, cost_);
|
return get_default_hash_2(end_selection_, cost_);
|
||||||
|
@ -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);
|
||||||
|
}
|
@ -364,8 +364,7 @@ DO_INLINE void inverse_fmatrix(float to[3][3], float from[3][3])
|
|||||||
float d;
|
float d;
|
||||||
|
|
||||||
if ((d = det_fmatrix(from)) == 0) {
|
if ((d = det_fmatrix(from)) == 0) {
|
||||||
printf("can't build inverse");
|
// printf("can't build inverse");
|
||||||
exit(0);
|
|
||||||
}
|
}
|
||||||
for (i = 0; i < 3; i++) {
|
for (i = 0; i < 3; i++) {
|
||||||
for (j = 0; j < 3; j++) {
|
for (j = 0; j < 3; j++) {
|
||||||
|
@ -1507,7 +1507,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
printf("%s: no filepath argument given\n", __func__);
|
printf("%s: no filepath argument given\n", __func__);
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IMB_isanim(filepath)) {
|
if (IMB_isanim(filepath)) {
|
||||||
@ -1522,7 +1522,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
|
|||||||
}
|
}
|
||||||
else if (!IMB_ispic(filepath)) {
|
else if (!IMB_ispic(filepath)) {
|
||||||
printf("%s: '%s' not an image file\n", __func__, filepath);
|
printf("%s: '%s' not an image file\n", __func__, filepath);
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ibuf == NULL) {
|
if (ibuf == NULL) {
|
||||||
@ -1532,7 +1532,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
|
|||||||
|
|
||||||
if (ibuf == NULL) {
|
if (ibuf == NULL) {
|
||||||
printf("%s: '%s' couldn't open\n", __func__, filepath);
|
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. */
|
/* GHOST will have reported the back-ends that failed to load. */
|
||||||
fprintf(stderr, "GHOST: unable to initialize, exiting!\n");
|
fprintf(stderr, "GHOST: unable to initialize, exiting!\n");
|
||||||
/* This will leak memory, it's preferable to crashing. */
|
/* This will leak memory, it's preferable to crashing. */
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
GHOST_AddEventConsumer(g_WS.ghost_system, consumer);
|
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 delete */
|
||||||
else {
|
else {
|
||||||
printf("error: can't play this image type\n");
|
printf("error: can't play this image type\n");
|
||||||
exit(0);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ps.once) {
|
if (ps.once) {
|
||||||
|
@ -1677,7 +1677,7 @@ void wm_ghost_init(bContext *C)
|
|||||||
/* GHOST will have reported the back-ends that failed to load. */
|
/* GHOST will have reported the back-ends that failed to load. */
|
||||||
fprintf(stderr, "GHOST: unable to initialize, exiting!\n");
|
fprintf(stderr, "GHOST: unable to initialize, exiting!\n");
|
||||||
/* This will leak memory, it's preferable to crashing. */
|
/* This will leak memory, it's preferable to crashing. */
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
#if !(defined(WIN32) || defined(__APPLE__))
|
#if !(defined(WIN32) || defined(__APPLE__))
|
||||||
g_system_backend_id = GHOST_SystemBackend();
|
g_system_backend_id = GHOST_SystemBackend();
|
||||||
|
@ -543,7 +543,7 @@ static int arg_handle_print_version(int UNUSED(argc),
|
|||||||
void *UNUSED(data))
|
void *UNUSED(data))
|
||||||
{
|
{
|
||||||
print_version_full();
|
print_version_full();
|
||||||
exit(0);
|
exit(EXIT_SUCCESS);
|
||||||
BLI_assert_unreachable();
|
BLI_assert_unreachable();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -816,7 +816,7 @@ static int arg_handle_print_help(int UNUSED(argc), const char **UNUSED(argv), vo
|
|||||||
|
|
||||||
print_help(ba, false);
|
print_help(ba, false);
|
||||||
|
|
||||||
exit(0);
|
exit(EXIT_SUCCESS);
|
||||||
BLI_assert_unreachable();
|
BLI_assert_unreachable();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1381,7 +1381,7 @@ static int arg_handle_env_system_set(int argc, const char **argv, void *UNUSED(d
|
|||||||
|
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
fprintf(stderr, "%s requires one argument\n", argv[0]);
|
fprintf(stderr, "%s requires one argument\n", argv[0]);
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
BLI_assert_unreachable();
|
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'). */
|
/* This function knows to skip this argument ('-a'). */
|
||||||
WM_main_playanim(argc, argv);
|
WM_main_playanim(argc, argv);
|
||||||
|
|
||||||
exit(0);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -2;
|
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));
|
BPY_CTX_SETUP(ok = BPY_run_filepath(C, filepath, NULL));
|
||||||
if (!ok && app_state.exit_code_on_error.python) {
|
if (!ok && app_state.exit_code_on_error.python) {
|
||||||
fprintf(stderr, "\nError: script failed, file: '%s', exiting.\n", argv[1]);
|
fprintf(stderr, "\nError: script failed, file: '%s', exiting.\n", argv[1]);
|
||||||
BPY_python_end();
|
WM_exit(C, app_state.exit_code_on_error.python);
|
||||||
exit(app_state.exit_code_on_error.python);
|
|
||||||
}
|
}
|
||||||
return 1;
|
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) {
|
if (!ok && app_state.exit_code_on_error.python) {
|
||||||
fprintf(stderr, "\nError: script failed, text: '%s', exiting.\n", argv[1]);
|
fprintf(stderr, "\nError: script failed, text: '%s', exiting.\n", argv[1]);
|
||||||
BPY_python_end();
|
WM_exit(C, app_state.exit_code_on_error.python);
|
||||||
exit(app_state.exit_code_on_error.python);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
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]));
|
BPY_CTX_SETUP(ok = BPY_run_string_exec(C, NULL, argv[1]));
|
||||||
if (!ok && app_state.exit_code_on_error.python) {
|
if (!ok && app_state.exit_code_on_error.python) {
|
||||||
fprintf(stderr, "\nError: script failed, expr: '%s', exiting.\n", argv[1]);
|
fprintf(stderr, "\nError: script failed, expr: '%s', exiting.\n", argv[1]);
|
||||||
BPY_python_end();
|
WM_exit(C, app_state.exit_code_on_error.python);
|
||||||
exit(app_state.exit_code_on_error.python);
|
|
||||||
}
|
}
|
||||||
return 1;
|
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);
|
BLI_args_add_case(ba, "-setaudio", 1, NULL, 0, CB(arg_handle_audio_set), NULL);
|
||||||
|
|
||||||
/* Pass: Processing Arguments. */
|
/* 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_pass_set(ba, ARG_PASS_FINAL);
|
||||||
BLI_args_add(ba, "-f", "--render-frame", CB(arg_handle_render_frame), C);
|
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);
|
BLI_args_add(ba, "-a", "--render-anim", CB(arg_handle_render_animation), C);
|
||||||
|
@ -67,7 +67,12 @@ enum {
|
|||||||
/** Currently use for audio devices. */
|
/** Currently use for audio devices. */
|
||||||
ARG_PASS_SETTINGS_FORCE = 4,
|
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,
|
ARG_PASS_FINAL = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -790,6 +790,28 @@ class edit_generators:
|
|||||||
|
|
||||||
return edits
|
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):
|
class remove_return_parens(EditGenerator):
|
||||||
"""
|
"""
|
||||||
Remove redundant parenthesis around return arguments:
|
Remove redundant parenthesis around return arguments:
|
||||||
|
Loading…
Reference in New Issue
Block a user