54 {
SIMVERT_FACE,
"FACE", 0,
"Amount of Adjacent Faces",
""},
56 {
SIMVERT_EDGE,
"EDGE", 0,
"Amount of Connecting Edges",
""},
61 {
SIMEDGE_FACE,
"FACE", 0,
"Amount of Faces Around an Edge",
""},
154 const float thresh_radians = thresh * (
float)
M_PI;
157 int tot_faces_selected_all = 0;
158 uint objects_len = 0;
162 for (
uint ob_index = 0; ob_index < objects_len; ob_index++) {
163 Object *ob = objects[ob_index];
168 if (tot_faces_selected_all == 0) {
174 KDTree_1d *tree_1d =
NULL;
175 KDTree_3d *tree_3d =
NULL;
176 KDTree_4d *tree_4d =
NULL;
184 tree_1d = BLI_kdtree_1d_new(tot_faces_selected_all);
187 tree_3d = BLI_kdtree_3d_new(tot_faces_selected_all);
190 tree_4d = BLI_kdtree_4d_new(tot_faces_selected_all);
198 "Select similar face: facemap gset array");
203 for (
uint ob_index = 0; ob_index < objects_len; ob_index++) {
204 Object *ob = objects[ob_index];
209 int custom_data_offset = 0;
235 if (custom_data_offset == -1) {
238 gset_array[ob_index] =
BLI_gset_ptr_new(
"Select similar face: facemap gset");
260 BLI_kdtree_1d_insert(tree_1d, tree_index++, &
area);
265 BLI_kdtree_1d_insert(tree_1d, tree_index++, &perimeter);
273 BLI_kdtree_3d_insert(tree_3d, tree_index++,
normal);
279 BLI_kdtree_4d_insert(tree_4d, tree_index++, plane);
284 goto face_select_all;
298 goto face_select_all;
315 if (tree_1d !=
NULL) {
316 BLI_kdtree_1d_deduplicate(tree_1d);
317 BLI_kdtree_1d_balance(tree_1d);
319 if (tree_3d !=
NULL) {
320 BLI_kdtree_3d_deduplicate(tree_3d);
321 BLI_kdtree_3d_balance(tree_3d);
323 if (tree_4d !=
NULL) {
324 BLI_kdtree_4d_deduplicate(tree_4d);
325 BLI_kdtree_4d_balance(tree_4d);
328 for (
uint ob_index = 0; ob_index < objects_len; ob_index++) {
329 Object *ob = objects[ob_index];
332 bool changed =
false;
334 int custom_data_offset;
339 bool has_custom_data_layer =
false;
357 if (custom_data_offset == -1) {
371 const int num_sides = face->
len;
375 const int delta_i = num_sides - num_sides_iter;
421 KDTreeNearest_3d nearest;
422 if (BLI_kdtree_3d_find_nearest(tree_3d,
normal, &nearest) != -1) {
433 KDTreeNearest_4d nearest;
434 if (BLI_kdtree_4d_find_nearest(tree_4d, plane, &nearest) != -1) {
435 if (nearest.dist <= thresh) {
436 if ((
fabsf(plane[3] - nearest.co[3]) <= thresh) &&
437 (
angle_v3v3(plane, nearest.co) <= thresh_radians)) {
453 if (!has_custom_data_layer) {
469 GSET_ITER (gs_iter, gset_array[ob_index]) {
471 if (*face_map == *face_map_iter) {
491 .calc_looptri = false,
492 .calc_normals = false,
493 .is_destructive = false,
502 for (
uint ob_index = 0; ob_index < objects_len; ob_index++) {
503 Object *ob = objects[ob_index];
518 .calc_looptri = false,
519 .calc_normals = false,
520 .is_destructive = false,
526 BLI_kdtree_1d_free(tree_1d);
527 BLI_kdtree_3d_free(tree_3d);
528 BLI_kdtree_4d_free(tree_4d);
532 if (gset_array !=
NULL) {
533 for (
uint ob_index = 0; ob_index < objects_len; ob_index++) {
534 if (gset_array[ob_index] !=
NULL) {
569 if (
fabs(r_dir[2]) < FLT_EPSILON) {
570 if (
fabs(r_dir[1]) < FLT_EPSILON) {
571 if (r_dir[0] < 0.0f) {
575 else if (r_dir[1] < 0.0f) {
579 else if (r_dir[2] < 0.0f) {
627 const float thresh_radians = thresh * (
float)
M_PI + FLT_EPSILON;
629 int custom_data_type = -1;
631 int tot_edges_selected_all = 0;
632 uint objects_len = 0;
636 for (
uint ob_index = 0; ob_index < objects_len; ob_index++) {
637 Object *ob = objects[ob_index];
642 if (tot_edges_selected_all == 0) {
648 KDTree_1d *tree_1d =
NULL;
649 KDTree_3d *tree_3d =
NULL;
658 tree_1d = BLI_kdtree_1d_new(tot_edges_selected_all);
661 tree_3d = BLI_kdtree_3d_new(tot_edges_selected_all);
678 for (
uint ob_index = 0; ob_index < objects_len; ob_index++) {
679 Object *ob = objects[ob_index];
698 BLI_kdtree_1d_insert(tree_1d, tree_index++, (
float[1]){0.0f});
705 float ob_m3[3][3], ob_m3_inv[3][3];
721 BLI_kdtree_3d_insert(tree_3d, tree_index++, dir);
726 BLI_kdtree_1d_insert(tree_1d, tree_index++, &
length);
732 BLI_kdtree_1d_insert(tree_1d, tree_index++, &
angle);
738 goto edge_select_all;
743 goto edge_select_all;
756 goto edge_select_all;
763 &
bm->
edata, edge->head.data, custom_data_type);
764 BLI_kdtree_1d_insert(tree_1d, tree_index++, value);
774 if (tree_1d !=
NULL) {
775 BLI_kdtree_1d_deduplicate(tree_1d);
776 BLI_kdtree_1d_balance(tree_1d);
778 if (tree_3d !=
NULL) {
779 BLI_kdtree_3d_deduplicate(tree_3d);
780 BLI_kdtree_3d_balance(tree_3d);
783 for (
uint ob_index = 0; ob_index < objects_len; ob_index++) {
784 Object *ob = objects[ob_index];
787 bool changed =
false;
789 bool has_custom_data_layer =
false;
801 if (!has_custom_data_layer) {
812 float ob_m3[3][3], ob_m3_inv[3][3];
828 const int delta_i = num_faces - num_faces_iter;
842 KDTreeNearest_3d nearest;
843 if (BLI_kdtree_3d_find_nearest(tree_3d, dir, &nearest) != -1) {
881 if (!has_custom_data_layer) {
896 if (!has_custom_data_layer) {
902 &
bm->
edata, edge->head.data, custom_data_type);
921 .calc_looptri = false,
922 .calc_normals = false,
923 .is_destructive = false,
932 for (
uint ob_index = 0; ob_index < objects_len; ob_index++) {
933 Object *ob = objects[ob_index];
948 .calc_looptri = false,
949 .calc_normals = false,
950 .is_destructive = false,
956 BLI_kdtree_1d_free(tree_1d);
957 BLI_kdtree_3d_free(tree_3d);
978 const float thresh_radians = thresh * (
float)
M_PI + FLT_EPSILON;
981 int tot_verts_selected_all = 0;
982 uint objects_len = 0;
986 for (
uint ob_index = 0; ob_index < objects_len; ob_index++) {
987 Object *ob = objects[ob_index];
992 if (tot_verts_selected_all == 0) {
998 KDTree_3d *tree_3d =
NULL;
999 KDTree_1d *tree_1d =
NULL;
1004 tree_3d = BLI_kdtree_3d_new(tot_verts_selected_all);
1007 tree_1d = BLI_kdtree_1d_new(tot_verts_selected_all);
1018 int normal_tree_index = 0;
1019 int tree_1d_index = 0;
1020 for (
uint ob_index = 0; ob_index < objects_len; ob_index++) {
1021 Object *ob = objects[ob_index];
1024 int cd_dvert_offset = -1;
1026 int defbase_len = 0;
1036 if (cd_dvert_offset == -1) {
1040 if (defbase_len == 0) {
1047 BLI_kdtree_1d_insert(tree_1d, tree_1d_index++, (
float[1]){0.0f});
1070 BLI_kdtree_3d_insert(tree_3d, normal_tree_index++,
normal);
1077 for (
int i = 0; i < dvert->
totweight; i++, dw++) {
1088 BLI_kdtree_1d_insert(tree_1d, tree_1d_index++, value);
1119 if (tree_1d !=
NULL) {
1120 BLI_kdtree_1d_deduplicate(tree_1d);
1121 BLI_kdtree_1d_balance(tree_1d);
1123 if (tree_3d !=
NULL) {
1124 BLI_kdtree_3d_deduplicate(tree_3d);
1125 BLI_kdtree_3d_balance(tree_3d);
1129 for (
uint ob_index = 0; ob_index < objects_len; ob_index++) {
1130 Object *ob = objects[ob_index];
1133 bool changed =
false;
1134 bool has_crease_layer =
false;
1135 int cd_dvert_offset = -1;
1137 int defbase_len = 0;
1141 if (cd_dvert_offset == -1) {
1146 if (defbase_len == 0) {
1154 bool found_any =
false;
1159 if (vgroup_id != -1) {
1164 if (found_any ==
false) {
1171 if (!has_crease_layer) {
1193 const int delta_i = num_edges - num_edges_iter;
1206 const int delta_i = num_faces - num_faces_iter;
1222 KDTreeNearest_3d nearest;
1223 if (BLI_kdtree_3d_find_nearest(tree_3d,
normal, &nearest) != -1) {
1234 for (
int i = 0; i < dvert->
totweight; i++, dw++) {
1247 if (!has_crease_layer) {
1274 .calc_looptri = false,
1275 .calc_normals = false,
1276 .is_destructive = false,
1282 BLI_kdtree_1d_free(tree_1d);
1283 BLI_kdtree_3d_free(tree_3d);
1349 #ifdef WITH_FREESTYLE
1376 if (
STREQ(prop_id,
"compare")) {
1382 else if (
STREQ(prop_id,
"threshold")) {
1406 ot->
name =
"Select Similar";
1407 ot->
idname =
"MESH_OT_select_similar";
1408 ot->
description =
"Select similar vertices, edges or faces by property types";
1425 prop =
RNA_def_float(
ot->
srna,
"threshold", 0.0f, 0.0f, 1.0f,
"Threshold",
"", 0.0f, 1.0f);
typedef float(TangentPoint)[2]
struct Object * CTX_data_edit_object(const bContext *C)
struct ViewLayer * CTX_data_view_layer(const bContext *C)
struct View3D * CTX_wm_view3d(const bContext *C)
struct ToolSettings * CTX_data_tool_settings(const bContext *C)
CustomData interface, see also DNA_customdata_types.h.
bool CustomData_has_layer(const struct CustomData *data, int type)
void * CustomData_bmesh_get(const struct CustomData *data, void *block, int type)
int CustomData_get_offset(const struct CustomData *data, int type)
BMEditMesh * BKE_editmesh_from_object(struct Object *ob)
Return the BMEditMesh for a given object.
#define BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, v3d, r_len)
General operations, lookup, etc. for materials.
struct Material *** BKE_object_material_array_p(struct Object *ob)
void BKE_report(ReportList *reports, eReportType type, const char *message)
#define BLI_BITMAP_NEW(_num, _alloc_string)
#define BLI_BITMAP_TEST(_bitmap, _index)
#define BLI_BITMAP_ENABLE(_bitmap, _index)
GSet * BLI_gset_str_new(const char *info)
GSet * BLI_gset_ptr_new(const char *info)
unsigned int BLI_gset_len(const GSet *gs) ATTR_WARN_UNUSED_RESULT
#define GSET_ITER(gs_iter_, gset_)
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
BLI_INLINE void * BLI_gsetIterator_getKey(GSetIterator *gsi)
bool BLI_gset_add(GSet *gs, void *key)
A KD-tree for nearest neighbor search.
#define LISTBASE_FOREACH(type, var, list)
int BLI_findstringindex(const struct ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3])
void copy_m3_m4(float m1[3][3], const float m2[4][4])
bool invert_m4_m4(float R[4][4], const float A[4][4])
void mul_m4_v3(const float M[4][4], float r[3])
bool invert_m3_m3(float R[3][3], const float A[3][3])
void mul_transposed_mat3_m4_v3(const float M[4][4], float r[3])
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
void mul_v3_mat3_m4v3(float r[3], const float M[4][4], const float v[3])
float angle_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float normalize_v3(float r[3])
MINLINE float len_squared_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
float angle_normalized_v3v3(const float v1[3], const float v2[3]) ATTR_WARN_UNUSED_RESULT
#define POINTER_FROM_INT(i)
#define POINTER_AS_INT(i)
#define SCE_SELECT_VERTEX
void EDBM_update(struct Mesh *me, const struct EDBMUpdate_Params *params)
void EDBM_selectmode_flush(struct BMEditMesh *em)
bool ED_operator_editmesh(struct bContext *C)
bool ED_select_similar_compare_float_tree(const struct KDTree_1d *tree, float length, float thresh, eSimilarCmp compare)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
Read Guarded memory(de)allocation.
__forceinline const avxb select(const avxb &m, const avxb &t, const avxb &f)
#define BM_FACE_FIRST_LOOP(p)
#define BM_ELEM_CD_GET_VOID_P(ele, offset)
#define BM_elem_flag_test(ele, hflag)
#define BM_ITER_MESH(ele, iter, bm, itype)
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_face_select_set(BMesh *bm, BMFace *f, const bool select)
Select Face.
void BM_vert_select_set(BMesh *bm, BMVert *v, const bool select)
Select Vert.
void BM_edge_select_set(BMesh *bm, BMEdge *e, const bool select)
Select Edge.
float BM_face_calc_area_with_mat3(const BMFace *f, const float mat3[3][3])
float BM_face_calc_perimeter_with_mat3(const BMFace *f, const float mat3[3][3])
int BM_edge_face_count_at_most(const BMEdge *e, const int count_max)
int BM_vert_face_count(const BMVert *v)
int BM_edge_face_count(const BMEdge *e)
int BM_vert_edge_count(const BMVert *v)
float BM_edge_calc_face_angle_with_imat3(const BMEdge *e, const float imat3[3][3])
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
static int edbm_select_similar_exec(bContext *C, wmOperator *op)
static int mesh_select_similar_compare_int(const int delta, const int compare)
static int similar_edge_select_exec(bContext *C, wmOperator *op)
static int similar_vert_select_exec(bContext *C, wmOperator *op)
static const EnumPropertyItem prop_similar_types[]
static bool edge_data_value_set(BMEdge *edge, const int hflag, int *r_value)
static bool edbm_select_similar_poll_property(const bContext *UNUSED(C), wmOperator *op, const PropertyRNA *prop)
void MESH_OT_select_similar(wmOperatorType *ot)
static float edge_length_squared_worldspace_get(Object *ob, BMEdge *edge)
static int similar_face_select_exec(bContext *C, wmOperator *op)
static void face_to_plane(const Object *ob, BMFace *face, float r_plane[4])
static void edge_pos_direction_worldspace_get(Object *ob, BMEdge *edge, float *r_dir)
static const EnumPropertyItem prop_similar_compare_types[]
static const EnumPropertyItem * select_similar_type_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
static bool face_data_value_set(BMFace *face, const int hflag, int *r_value)
IconTextureDrawCall normal
void(* MEM_freeN)(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
ccl_device_inline float2 fabs(const float2 &a)
static void area(int d1, int d2, int e1, int e2, float weights[2])
T length(const vec_base< T, Size > &a)
float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
const char * RNA_property_identifier(const PropertyRNA *prop)
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
float RNA_float_get(PointerRNA *ptr, const char *name)
void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
void RNA_enum_item_end(EnumPropertyItem **items, int *totitem)
void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc)
void RNA_enum_items_add_value(EnumPropertyItem **items, int *totitem, const EnumPropertyItem *item, int value)
void RNA_def_property_ui_range(PropertyRNA *prop, double min, double max, double step, int precision)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
bool(* poll_property)(const struct bContext *C, struct wmOperator *op, const PropertyRNA *prop) ATTR_WARN_UNUSED_RESULT
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
struct ReportList * reports
int WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))