Blender V4.3
editmesh_rip.cc File Reference
#include "MEM_guardedalloc.h"
#include "DNA_object_types.h"
#include "BLI_math_geom.h"
#include "BLI_math_vector.h"
#include "BLI_math_vector.hh"
#include "BLI_span.hh"
#include "BLI_vector.hh"
#include "BKE_context.hh"
#include "BKE_editmesh.hh"
#include "BKE_layer.hh"
#include "BKE_report.hh"
#include "BLT_translation.hh"
#include "RNA_access.hh"
#include "RNA_define.hh"
#include "WM_types.hh"
#include "ED_mesh.hh"
#include "ED_transform.hh"
#include "ED_view3d.hh"
#include "bmesh.hh"
#include "bmesh_tools.hh"
#include "mesh_intern.hh"

Go to the source code of this file.

Classes

struct  EdgeLoopPair
 
struct  UnorderedLoopPair
 

Functions

Rip Far-Side De-Select
static BMEdgeedbm_ripsel_edge_uid_step (BMEdge *e_orig, BMVert **v_prev)
 
static BMVertedbm_ripsel_edloop_pair_start_vert (BMEdge *e)
 
static void edbm_ripsel_deselect_helper (BMesh *bm, const Span< EdgeLoopPair > eloop_pairs, ARegion *region, const blender::float4x4 &projectMat, const float fmval[2])
 
Rip Vertex Implementation
static int edbm_rip_invoke__vert (bContext *C, const wmEvent *event, Object *obedit, bool do_fill)
 
Rip Edge Implementation
static int edbm_rip_invoke__edge (bContext *C, const wmEvent *event, Object *obedit, bool do_fill)
 
Rip Operator
static int edbm_rip_invoke (bContext *C, wmOperator *op, const wmEvent *event)
 
void MESH_OT_rip (wmOperatorType *ot)
 

Local Utilities

#define INSET_DEFAULT   0.00001f
 
static float edbm_rip_edgedist_squared (ARegion *region, const blender::float4x4 &mat, const float co1[3], const float co2[3], const float mvalf[2], const float inset)
 
static void edbm_calc_loop_co (BMLoop *l, float l_mid_co[3])
 
static float edbm_rip_edge_side_measure (BMEdge *e, BMLoop *e_l, ARegion *region, const blender::float4x4 &projectMat, const float fmval[2])
 

Rip Selection Handling (advanced rip-select <tt>ripsel</tt> functions)

#define IS_VISIT_POSSIBLE(e)   (BM_edge_is_manifold(e) && BM_elem_flag_test(e, BM_ELEM_TAG))
 
#define IS_VISIT_DONE(e)   ((e)->l && (BM_elem_index_get((e)->l) != INVALID_UID))
 
#define INVALID_UID   INT_MIN
 
static BMEdgeedbm_ripsel_edge_mark_step (BMVert *v, const int uid)
 
static Vector< EdgeLoopPairedbm_ripsel_looptag_helper (BMesh *bm)
 

Rip Face-Fill code

enum  { ULP_FLIP_0 = (1 << 0) , ULP_FLIP_1 = (1 << 1) }
 
static UnorderedLoopPairedbm_tagged_loop_pairs_to_fill (BMesh *bm)
 
static void edbm_tagged_loop_pairs_do_fill_faces (BMesh *bm, UnorderedLoopPair *uloop_pairs)
 

Macro Definition Documentation

◆ INSET_DEFAULT

#define INSET_DEFAULT   0.00001f

helper to find edge for edge_rip,

Parameters
insetis used so we get some useful distance when comparing multiple edges that meet at the same point and would result in the same distance.

Definition at line 56 of file editmesh_rip.cc.

Referenced by edbm_rip_invoke__vert().

◆ INVALID_UID

#define INVALID_UID   INT_MIN

Definition at line 201 of file editmesh_rip.cc.

Referenced by edbm_ripsel_looptag_helper().

◆ IS_VISIT_DONE

#define IS_VISIT_DONE ( e)    ((e)->l && (BM_elem_index_get((e)->l) != INVALID_UID))

Definition at line 200 of file editmesh_rip.cc.

Referenced by edbm_ripsel_edge_mark_step(), and edbm_ripsel_looptag_helper().

◆ IS_VISIT_POSSIBLE

#define IS_VISIT_POSSIBLE ( e)    (BM_edge_is_manifold(e) && BM_elem_flag_test(e, BM_ELEM_TAG))

How rip selection works:

Firstly - rip is basically edge split with side-selection & grab. Things would be much more simple if we didn't have to worry about side selection

The method used for checking the side of selection is as follows...

  • First tag all rip-able edges.
  • Build a contiguous edge list by looping over tagged edges and following each one's tagged siblings in both directions.
    • The loops are not stored in an array. Instead both loops on either side of each edge has its index values set to count down from the last edge. This way once we have the 'last' edge it's very easy to walk down the connected edge loops. The reason for using loops like this is because when the edges are split we don't know which face user gets the newly created edge (it's as good as random so we can't assume new edges will be on one side). After splitting, it's very simple to walk along boundary loops since each only has one edge from a single side.
  • The end loop pairs are stored in an array however to support multiple edge-selection-islands, so you can rip multiple selections at once.
  • * Execute the split *
  • For each EdgeLoopPair walk down both sides of the split using the loops and measure which is facing the mouse.
  • Deselect the edge loop facing away.

Limitation! This currently works very poorly with intersecting edge islands (verts with more than 2 tagged edges). This is nice to do but for now not essential.

  • campbell.

Definition at line 199 of file editmesh_rip.cc.

Referenced by edbm_ripsel_edge_mark_step(), and edbm_ripsel_looptag_helper().

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
ULP_FLIP_0 
ULP_FLIP_1 

Definition at line 402 of file editmesh_rip.cc.

Function Documentation

◆ edbm_calc_loop_co()

static void edbm_calc_loop_co ( BMLoop * l,
float l_mid_co[3] )
static

Calculates a point along the loop tangent which can be used to measure against edges.

Definition at line 100 of file editmesh_rip.cc.

References add_v3_v3(), BM_edge_calc_length(), BM_loop_calc_face_tangent(), BMVert::co, BMLoop::e, l, mul_v3_fl(), BMLoop::prev, and BMLoop::v.

Referenced by edbm_rip_invoke__vert().

◆ edbm_rip_edge_side_measure()

◆ edbm_rip_edgedist_squared()

static float edbm_rip_edgedist_squared ( ARegion * region,
const blender::float4x4 & mat,
const float co1[3],
const float co2[3],
const float mvalf[2],
const float inset )
static

◆ edbm_rip_invoke()

◆ edbm_rip_invoke__edge()

◆ edbm_rip_invoke__vert()

static int edbm_rip_invoke__vert ( bContext * C,
const wmEvent * event,
Object * obedit,
bool do_fill )
static

◆ edbm_ripsel_deselect_helper()

static void edbm_ripsel_deselect_helper ( BMesh * bm,
const Span< EdgeLoopPair > eloop_pairs,
ARegion * region,
const blender::float4x4 & projectMat,
const float fmval[2] )
static

◆ edbm_ripsel_edge_mark_step()

static BMEdge * edbm_ripsel_edge_mark_step ( BMVert * v,
const int uid )
static

◆ edbm_ripsel_edge_uid_step()

static BMEdge * edbm_ripsel_edge_uid_step ( BMEdge * e_orig,
BMVert ** v_prev )
static

◆ edbm_ripsel_edloop_pair_start_vert()

static BMVert * edbm_ripsel_edloop_pair_start_vert ( BMEdge * e)
static

Definition at line 343 of file editmesh_rip.cc.

References e, and edbm_ripsel_edge_uid_step().

Referenced by edbm_ripsel_deselect_helper().

◆ edbm_ripsel_looptag_helper()

◆ edbm_tagged_loop_pairs_do_fill_faces()

◆ edbm_tagged_loop_pairs_to_fill()

◆ MESH_OT_rip()