Blender V4.3
uvedit_rip.cc File Reference
#include <cmath>
#include <cstdlib>
#include <cstring>
#include "MEM_guardedalloc.h"
#include "BLI_ghash.h"
#include "BLI_linklist_stack.h"
#include "BLI_math_vector.h"
#include "BLI_utildefines.h"
#include "DNA_image_types.h"
#include "DNA_mesh_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_space_types.h"
#include "BKE_context.hh"
#include "BKE_customdata.hh"
#include "BKE_editmesh.hh"
#include "BKE_layer.hh"
#include "BKE_mesh_types.hh"
#include "BKE_report.hh"
#include "DEG_depsgraph.hh"
#include "ED_screen.hh"
#include "ED_transform.hh"
#include "ED_uvedit.hh"
#include "RNA_access.hh"
#include "RNA_define.hh"
#include "WM_api.hh"
#include "WM_types.hh"
#include "UI_view2d.hh"
#include "uvedit_intern.hh"

Go to the source code of this file.

Classes

struct  ULData
 
struct  UVRipSingle
 
struct  UVRipPairs
 

Macros

#define UV_SET_SIDE_AND_REMOVE_FROM_RAIL(loop, side_value)
 

Functions

UV Loop Rip Data Struct
 BLI_STATIC_ASSERT (sizeof(ULData)<=sizeof(int), "")
 
BLI_INLINE ULDataUL (BMLoop *l)
 
UV Utilities
static BMLoopbm_loop_find_other_radial_loop_with_visible_face (BMLoop *l_src, const int cd_loop_uv_offset)
 
static BMLoopbm_loop_find_other_fan_loop_with_visible_face (BMLoop *l_src, BMVert *v_src, const int cd_loop_uv_offset)
 
static BMLoopbm_vert_step_fan_loop_uv (BMLoop *l, BMEdge **e_step, const int cd_loop_uv_offset)
 
static void bm_loop_uv_select_single_vert_validate (BMLoop *l_init, const int cd_loop_uv_offset)
 
static void bm_loop_calc_uv_angle_from_dir (BMLoop *l, const float dir[2], const float aspect_y, const int cd_loop_uv_offset, float *r_corner_angle, float *r_edge_angle, int *r_edge_index)
 
UV Rip Single
static UVRipSingleuv_rip_single_from_loop (BMLoop *l_init_orig, const float co[2], const float aspect_y, const int cd_loop_uv_offset)
 
static void uv_rip_single_free (UVRipSingle *rip)
 
UV Rip Loop Pairs
static void uv_rip_pairs_add (UVRipPairs *rip, BMLoop *l)
 
static void uv_rip_pairs_remove (UVRipPairs *rip, BMLoop *l)
 
static float uv_rip_pairs_calc_uv_angle (BMLoop *l_init, uint side, const float aspect_y, const int cd_loop_uv_offset)
 
static int uv_rip_pairs_loop_count_on_side (BMLoop *l_init, uint side, const int cd_loop_uv_offset)
 
static bool uv_rip_pairs_loop_change_sides_test (BMLoop *l_switch, BMLoop *l_target, const float aspect_y, const int cd_loop_uv_offset)
 
static UVRipPairsuv_rip_pairs_from_loop (BMLoop *l_init, const float aspect_y, const int cd_loop_uv_offset)
 
static void uv_rip_pairs_free (UVRipPairs *rip)
 
static bool uv_rip_pairs_calc_center_and_direction (UVRipPairs *rip, const int cd_loop_uv_offset, float r_center[2], float r_dir_side[2][2])
 
UV Rip Main Function
static bool uv_rip_object (Scene *scene, Object *obedit, const float co[2], const float aspect_y)
 
UV Rip Operator
static int uv_rip_exec (bContext *C, wmOperator *op)
 
static int uv_rip_invoke (bContext *C, wmOperator *op, const wmEvent *event)
 
void UV_OT_rip (wmOperatorType *ot)
 

Macro Definition Documentation

◆ UV_SET_SIDE_AND_REMOVE_FROM_RAIL

#define UV_SET_SIDE_AND_REMOVE_FROM_RAIL ( loop,
side_value )
Value:
{ \
BLI_assert(UL(loop)->side_was_swapped == false); \
BLI_assert(UL(loop)->side != side_value); \
if (!UL(loop)->in_stack) { \
BLI_SMALLSTACK_PUSH(stack, loop); \
UL(loop)->in_stack = true; \
} \
if (UL(loop)->in_rip_pairs) { \
uv_rip_pairs_remove(rip, loop); \
} \
UL(loop)->side = side_value; \
UL(loop)->side_was_swapped = true; \
}
BLI_INLINE ULData * UL(BMLoop *l)
Definition uvedit_rip.cc:92

Referenced by uv_rip_pairs_from_loop().

Function Documentation

◆ BLI_STATIC_ASSERT()

BLI_STATIC_ASSERT ( sizeof(ULData)<=sizeof(int) ,
""  )

Ensure this fits in an int (loop index).

◆ bm_loop_calc_uv_angle_from_dir()

static void bm_loop_calc_uv_angle_from_dir ( BMLoop * l,
const float dir[2],
const float aspect_y,
const int cd_loop_uv_offset,
float * r_corner_angle,
float * r_edge_angle,
int * r_edge_index )
static

The corner return values calculate the angle between both loops, the edge values pick the closest to the either edge (ignoring the center).

Parameters
dirDirection to calculate the angle to (normalized and aspect corrected).

Definition at line 225 of file uvedit_rip.cc.

References angle_v2v2(), BM_ELEM_CD_GET_FLOAT_P, BM_face_uv_calc_cross(), BMLoop::f, l, negate_v2(), BMLoop::next, normalize_v2(), BMLoop::prev, and sub_v2_v2v2().

Referenced by uv_rip_single_from_loop().

◆ bm_loop_find_other_fan_loop_with_visible_face()

static BMLoop * bm_loop_find_other_fan_loop_with_visible_face ( BMLoop * l_src,
BMVert * v_src,
const int cd_loop_uv_offset )
static

◆ bm_loop_find_other_radial_loop_with_visible_face()

static BMLoop * bm_loop_find_other_radial_loop_with_visible_face ( BMLoop * l_src,
const int cd_loop_uv_offset )
static

◆ bm_loop_uv_select_single_vert_validate()

static void bm_loop_uv_select_single_vert_validate ( BMLoop * l_init,
const int cd_loop_uv_offset )
static

◆ bm_vert_step_fan_loop_uv()

static BMLoop * bm_vert_step_fan_loop_uv ( BMLoop * l,
BMEdge ** e_step,
const int cd_loop_uv_offset )
static

◆ UL()

◆ UV_OT_rip()

◆ uv_rip_exec()

◆ uv_rip_invoke()

static int uv_rip_invoke ( bContext * C,
wmOperator * op,
const wmEvent * event )
static

◆ uv_rip_object()

◆ uv_rip_pairs_add()

static void uv_rip_pairs_add ( UVRipPairs * rip,
BMLoop * l )
static

◆ uv_rip_pairs_calc_center_and_direction()

static bool uv_rip_pairs_calc_center_and_direction ( UVRipPairs * rip,
const int cd_loop_uv_offset,
float r_center[2],
float r_dir_side[2][2] )
static

This is an approximation, it's easily good enough for our purpose.

Definition at line 689 of file uvedit_rip.cc.

References add_v2_v2(), BLI_gset_len(), BLI_gsetIterator_getKey(), BM_ELEM_CD_GET_FLOAT_P, GSET_ITER, ULData::is_select_edge, l, UVRipPairs::loops, mul_v2_fl(), BMLoop::next, normalize_v2(), BMLoop::prev, ULData::side, sub_v2_v2v2(), UL(), and zero_v2().

Referenced by uv_rip_object().

◆ uv_rip_pairs_calc_uv_angle()

static float uv_rip_pairs_calc_uv_angle ( BMLoop * l_init,
uint side,
const float aspect_y,
const int cd_loop_uv_offset )
static
Note
While this isn't especially efficient, this is only needed for rip-pairs end-points (only two per contiguous selection loop).

Definition at line 464 of file uvedit_rip.cc.

References angle_v2v2(), BM_ELEM_CD_GET_FLOAT_P, BM_ITER_ELEM, BM_LOOPS_OF_VERT, equals_v2v2(), l, LIKELY, BMLoop::next, BMLoop::prev, sub_v2_v2v2(), UL(), and BMLoop::v.

Referenced by uv_rip_pairs_loop_change_sides_test().

◆ uv_rip_pairs_free()

static void uv_rip_pairs_free ( UVRipPairs * rip)
static

Definition at line 680 of file uvedit_rip.cc.

References BLI_gset_free(), UVRipPairs::loops, and MEM_freeN().

Referenced by uv_rip_object().

◆ uv_rip_pairs_from_loop()

static UVRipPairs * uv_rip_pairs_from_loop ( BMLoop * l_init,
const float aspect_y,
const int cd_loop_uv_offset )
static

Create 2x sides of a UV rip-pairs, the result is unordered, supporting non-contiguous rails.

Parameters
l_initA loop on a boundary which can be used to initialize flood-filling. This will always be added to the first side. Other loops will be added to the second side.
Note
We could have more than two sides, however in practice this almost never happens.

Definition at line 558 of file uvedit_rip.cc.

References BLI_assert, BLI_gset_ptr_new(), BLI_SMALLSTACK_DECLARE, BLI_SMALLSTACK_POP, BLI_SMALLSTACK_PUSH, BM_edge_uv_share_vert_check(), BM_elem_flag_test, BM_ELEM_TAG, bm_loop_find_other_radial_loop_with_visible_face(), BMLoop::e, BMLoop::f, ULData::in_stack, UVRipPairs::loops, BMLoop::next, BMLoop::prev, BMLoop::radial_next, ULData::side, UL(), uv_rip_pairs_add(), uv_rip_pairs_loop_change_sides_test(), UV_SET_SIDE_AND_REMOVE_FROM_RAIL, and BMLoop::v.

Referenced by uv_rip_object().

◆ uv_rip_pairs_loop_change_sides_test()

static bool uv_rip_pairs_loop_change_sides_test ( BMLoop * l_switch,
BMLoop * l_target,
const float aspect_y,
const int cd_loop_uv_offset )
static

◆ uv_rip_pairs_loop_count_on_side()

static int uv_rip_pairs_loop_count_on_side ( BMLoop * l_init,
uint side,
const int cd_loop_uv_offset )
static

◆ uv_rip_pairs_remove()

static void uv_rip_pairs_remove ( UVRipPairs * rip,
BMLoop * l )
static

◆ uv_rip_single_free()

static void uv_rip_single_free ( UVRipSingle * rip)
static

Definition at line 425 of file uvedit_rip.cc.

References BLI_gset_free(), UVRipSingle::loops, and MEM_freeN().

Referenced by uv_rip_object().

◆ uv_rip_single_from_loop()

static UVRipSingle * uv_rip_single_from_loop ( BMLoop * l_init_orig,
const float co[2],
const float aspect_y,
const int cd_loop_uv_offset )
static

Handle single loop, the following cases:

  • An isolated fan, without a shared UV edge to other fans which share the same coordinate, in this case we just need to pick the closest fan to co.
  • In the case of contiguous loops (part of the same fan). Rip away the loops connected to the closest edge.
  • In the case of 2 contiguous loops. Rip the closest loop away.
Note
This matches the behavior of edit-mesh rip tool.

Definition at line 304 of file uvedit_rip.cc.

References BLI_assert, BLI_gset_add(), BLI_gset_ptr_new(), BLI_gsetIterator_getKey(), BM_ELEM_CD_GET_FLOAT_P, BM_elem_flag_test, BM_ELEM_TAG, BM_ITER_ELEM, bm_loop_calc_uv_angle_from_dir(), BM_loop_uv_share_edge_check(), BM_LOOPS_OF_VERT, bm_vert_step_fan_loop_uv(), BMLoop::e, equals_v2v2(), BMLoop::f, FLT_MAX, GSET_ITER, ULData::is_select_vert_single, l, UVRipSingle::loops, min_ff(), BMLoop::next, normalize_v2(), BMLoop::prev, BMLoop::radial_next, ULData::side, sub_v2_v2v2(), UL(), UNLIKELY, and BMLoop::v.

Referenced by uv_rip_object().