forked from bartvdbraak/blender
sorting utility functions for simple cases - sorting pointers by float for example.
This commit is contained in:
parent
6cc3aec8bc
commit
7a38fe97fd
61
source/blender/blenlib/BLI_sort_utils.h
Normal file
61
source/blender/blenlib/BLI_sort_utils.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2013 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __BLI_SORT_UTILS_H__
|
||||
#define __BLI_SORT_UTILS_H__
|
||||
|
||||
/** \file BLI_sort_utils.h
|
||||
* \ingroup bli
|
||||
*/
|
||||
|
||||
/**
|
||||
* \note keep \a sort_value first,
|
||||
* so cmp functions can be reused.
|
||||
*/
|
||||
struct SortPointerByFloat {
|
||||
float sort_value;
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct SortIntByFloat {
|
||||
float sort_value;
|
||||
int data;
|
||||
};
|
||||
|
||||
struct SortPointerByInt {
|
||||
int sort_value;
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct SortIntByInt {
|
||||
int sort_value;
|
||||
int data;
|
||||
};
|
||||
|
||||
int BLI_sortutil_cmp_float(const void *a_, const void *b_);
|
||||
int BLI_sortutil_cmp_float_reverse(const void *a_, const void *b_);
|
||||
|
||||
int BLI_sortutil_cmp_int(const void *a_, const void *b_);
|
||||
int BLI_sortutil_cmp_int_reverse(const void *a_, const void *b_);
|
||||
|
||||
#endif /* __BLI_SORT_UTILS_H__ */
|
@ -87,6 +87,7 @@ set(SRC
|
||||
intern/scanfill.c
|
||||
intern/smallhash.c
|
||||
intern/sort.c
|
||||
intern/sort_utils.c
|
||||
intern/stack.c
|
||||
intern/storage.c
|
||||
intern/string.c
|
||||
@ -150,6 +151,7 @@ set(SRC
|
||||
BLI_scanfill.h
|
||||
BLI_smallhash.h
|
||||
BLI_sort.h
|
||||
BLI_sort_utils.h
|
||||
BLI_stack.h
|
||||
BLI_strict_flags.h
|
||||
BLI_string.h
|
||||
|
74
source/blender/blenlib/intern/sort_utils.c
Normal file
74
source/blender/blenlib/intern/sort_utils.c
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2013 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/blenlib/intern/sort_utils.c
|
||||
* \ingroup bli
|
||||
*
|
||||
* Utility functions for sorting common types.
|
||||
*/
|
||||
|
||||
#include "BLI_sort_utils.h" /* own include */
|
||||
|
||||
struct SortAnyByFloat {
|
||||
float sort_value;
|
||||
};
|
||||
|
||||
struct SortAnyByInt {
|
||||
int sort_value;
|
||||
};
|
||||
|
||||
int BLI_sortutil_cmp_float(const void *a_, const void *b_)
|
||||
{
|
||||
const struct SortAnyByFloat *a = a_;
|
||||
const struct SortAnyByFloat *b = b_;
|
||||
if (a->sort_value > b->sort_value) return 1;
|
||||
else if (a->sort_value < b->sort_value) return -1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
int BLI_sortutil_cmp_float_reverse(const void *a_, const void *b_)
|
||||
{
|
||||
const struct SortAnyByFloat *a = a_;
|
||||
const struct SortAnyByFloat *b = b_;
|
||||
if (a->sort_value < b->sort_value) return 1;
|
||||
else if (a->sort_value > b->sort_value) return -1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
int BLI_sortutil_cmp_int(const void *a_, const void *b_)
|
||||
{
|
||||
const struct SortAnyByInt *a = a_;
|
||||
const struct SortAnyByInt *b = b_;
|
||||
if (a->sort_value > b->sort_value) return 1;
|
||||
else if (a->sort_value < b->sort_value) return -1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
int BLI_sortutil_cmp_int_reverse(const void *a_, const void *b_)
|
||||
{
|
||||
const struct SortAnyByInt *a = a_;
|
||||
const struct SortAnyByInt *b = b_;
|
||||
if (a->sort_value < b->sort_value) return 1;
|
||||
else if (a->sort_value > b->sort_value) return -1;
|
||||
else return 0;
|
||||
}
|
@ -35,6 +35,7 @@
|
||||
|
||||
#include "BLI_alloca.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_sort_utils.h"
|
||||
|
||||
#include "BKE_customdata.h"
|
||||
|
||||
@ -358,20 +359,6 @@ BMFace *BM_face_create_ngon_verts(BMesh *bm, BMVert **vert_arr, const int len,
|
||||
f_example, create_flag);
|
||||
}
|
||||
|
||||
|
||||
typedef struct AngleIndexPair {
|
||||
float angle;
|
||||
int index;
|
||||
} AngleIndexPair;
|
||||
|
||||
static int angle_index_pair_cmp(const void *e1, const void *e2)
|
||||
{
|
||||
const AngleIndexPair *p1 = e1, *p2 = e2;
|
||||
if (p1->angle > p2->angle) return 1;
|
||||
else if (p1->angle < p2->angle) return -1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes an NGon from an un-ordered set of verts
|
||||
*
|
||||
@ -391,7 +378,7 @@ static int angle_index_pair_cmp(const void *e1, const void *e2)
|
||||
BMFace *BM_face_create_ngon_vcloud(BMesh *bm, BMVert **vert_arr, int len,
|
||||
const BMFace *f_example, const eBMCreateFlag create_flag)
|
||||
{
|
||||
AngleIndexPair *vang = BLI_array_alloca(vang, len);
|
||||
struct SortIntByFloat *vang = BLI_array_alloca(vang, len);
|
||||
BMVert **vert_arr_map = BLI_array_alloca(vert_arr_map, len);
|
||||
|
||||
BMFace *f;
|
||||
@ -488,18 +475,18 @@ BMFace *BM_face_create_ngon_vcloud(BMesh *bm, BMVert **vert_arr, int len,
|
||||
angle = -angle;
|
||||
}
|
||||
|
||||
vang[i].angle = angle;
|
||||
vang[i].index = i;
|
||||
vang[i].sort_value = angle;
|
||||
vang[i].data = i;
|
||||
}
|
||||
|
||||
/* sort by angle and magic! - we have our ngon */
|
||||
qsort(vang, len, sizeof(AngleIndexPair), angle_index_pair_cmp);
|
||||
qsort(vang, len, sizeof(*vang), BLI_sortutil_cmp_float);
|
||||
|
||||
/* --- */
|
||||
|
||||
/* create edges and find the winding (if faces are attached to any existing edges) */
|
||||
for (i = 0; i < len; i++) {
|
||||
vert_arr_map[i] = vert_arr[vang[i].index];
|
||||
vert_arr_map[i] = vert_arr[vang[i].data];
|
||||
}
|
||||
|
||||
f = BM_face_create_ngon_verts(bm, vert_arr_map, len, f_example, create_flag, true, true);
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "DNA_meshdata_types.h"
|
||||
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_sort_utils.h"
|
||||
|
||||
#include "BKE_customdata.h"
|
||||
|
||||
@ -181,10 +182,6 @@ static bool bm_edge_faces_cmp(BMesh *bm, BMEdge *e, const bool do_uv, const bool
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef struct JoinEdge {
|
||||
float weight;
|
||||
BMEdge *e;
|
||||
} JoinEdge;
|
||||
|
||||
#define EDGE_MARK 1
|
||||
#define EDGE_CHOSEN 2
|
||||
@ -192,14 +189,7 @@ typedef struct JoinEdge {
|
||||
#define FACE_MARK 1
|
||||
#define FACE_INPUT 2
|
||||
|
||||
static int fplcmp(const void *v1, const void *v2)
|
||||
{
|
||||
const JoinEdge *e1 = (JoinEdge *)v1, *e2 = (JoinEdge *)v2;
|
||||
|
||||
if (e1->weight > e2->weight) return 1;
|
||||
else if (e1->weight < e2->weight) return -1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
void bmo_join_triangles_exec(BMesh *bm, BMOperator *op)
|
||||
{
|
||||
@ -214,7 +204,8 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op)
|
||||
BMOIter siter;
|
||||
BMFace *f;
|
||||
BMEdge *e;
|
||||
JoinEdge *jedges = NULL;
|
||||
/* data: edge-to-join, sort_value: error weight */
|
||||
struct SortPointerByFloat *jedges;
|
||||
unsigned i, totedge;
|
||||
unsigned int totedge_tag = 0;
|
||||
|
||||
@ -271,19 +262,19 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op)
|
||||
|
||||
measure = measure_facepair(v1->co, v2->co, v3->co, v4->co, limit);
|
||||
if (measure < limit) {
|
||||
jedges[i].e = e;
|
||||
jedges[i].weight = measure;
|
||||
jedges[i].data = e;
|
||||
jedges[i].sort_value = measure;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
totedge = i;
|
||||
qsort(jedges, totedge, sizeof(JoinEdge), fplcmp);
|
||||
qsort(jedges, totedge, sizeof(*jedges), BLI_sortutil_cmp_float);
|
||||
|
||||
for (i = 0; i < totedge; i++) {
|
||||
BMFace *f_a, *f_b;
|
||||
|
||||
e = jedges[i].e;
|
||||
e = jedges[i].data;
|
||||
f_a = e->l->f;
|
||||
f_b = e->l->radial_next->f;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user