Merge branch 'master' into blender2.8

This commit is contained in:
Campbell Barton 2017-08-27 16:35:51 +10:00
commit ca9801bd42
8 changed files with 160 additions and 73 deletions

View File

@ -55,6 +55,8 @@ void BLI_rcti_do_minmax_v(struct rcti *rect, const int xy[2]);
void BLI_rctf_do_minmax_v(struct rctf *rect, const float xy[2]);
void BLI_rctf_transform_pt_v(const rctf *dst, const rctf *src, float xy_dst[2], const float xy_src[2]);
void BLI_rctf_transform_calc_m4_pivot_min_ex(const rctf *dst, const rctf *src, float matrix[4][4], uint x, uint y);
void BLI_rctf_transform_calc_m4_pivot_min(const rctf *dst, const rctf *src, float matrix[4][4]);
void BLI_rctf_translate(struct rctf *rect, float x, float y);
void BLI_rcti_translate(struct rcti *rect, int x, int y);

View File

@ -32,6 +32,7 @@
* A minimalist lib for functions doing stuff with rectangle structs.
*/
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
@ -41,6 +42,9 @@
#include "DNA_vec_types.h"
#include "BLI_rect.h"
/* avoid including BLI_math */
static void unit_m4(float m[4][4]);
/**
* Determine if a rect is empty. An empty
* rect is one with a zero (or negative)
@ -405,6 +409,31 @@ void BLI_rctf_transform_pt_v(const rctf *dst, const rctf *src, float xy_dst[2],
xy_dst[1] = dst->ymin + ((dst->ymax - dst->ymin) * xy_dst[1]);
}
/**
* Calculate a 4x4 matrix representing the transformation between two rectangles.
*
* \note Multiplying a vector by this matrix does *not* give the same value as #BLI_rctf_transform_pt_v.
*/
void BLI_rctf_transform_calc_m4_pivot_min_ex(
const rctf *dst, const rctf *src, float matrix[4][4],
uint x, uint y)
{
BLI_assert(x < 3 && y < 3);
unit_m4(matrix);
matrix[x][x] = BLI_rctf_size_x(src) / BLI_rctf_size_x(dst);
matrix[y][y] = BLI_rctf_size_y(src) / BLI_rctf_size_y(dst);
matrix[3][x] = (src->xmin - dst->xmin) * matrix[x][x];
matrix[3][y] = (src->ymin - dst->ymin) * matrix[y][y];
}
void BLI_rctf_transform_calc_m4_pivot_min(
const rctf *dst, const rctf *src, float matrix[4][4])
{
BLI_rctf_transform_calc_m4_pivot_min_ex(dst, src, matrix, 0, 1);
}
void BLI_rcti_translate(rcti *rect, int x, int y)
{
rect->xmin += x;
@ -763,3 +792,12 @@ void BLI_rctf_rotate_expand(rctf *dst, const rctf *src, const float angle)
#undef ROTATE_SINCOS
/** \} */
static void unit_m4(float m[4][4])
{
m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0f;
m[0][1] = m[0][2] = m[0][3] = 0.0f;
m[1][0] = m[1][2] = m[1][3] = 0.0f;
m[2][0] = m[2][1] = m[2][3] = 0.0f;
m[3][0] = m[3][1] = m[3][2] = 0.0f;
}

View File

@ -183,6 +183,11 @@ static BMFace *bm_face_create_from_mpoly(
/**
* \brief Mesh -> BMesh
* \param bm: The mesh to write into, while this is typically a newly created BMesh,
* merging into existing data is supported.
* Note the custom-data layout isn't used.
* If more comprehensive merging is needed we should move this into a separate function
* since this should be kept fast for edit-mode switching and storing undo steps.
*
* \warning This function doesn't calculate face normals.
*/
@ -190,6 +195,9 @@ void BM_mesh_bm_from_me(
BMesh *bm, Mesh *me,
const struct BMeshFromMeshParams *params)
{
const bool is_new =
!(bm->totvert ||
(bm->vdata.totlayer || bm->edata.totlayer || bm->pdata.totlayer || bm->ldata.totlayer));
MVert *mvert;
MEdge *medge;
MLoop *mloop;
@ -199,17 +207,10 @@ void BM_mesh_bm_from_me(
BMEdge *e, **etable = NULL;
BMFace *f, **ftable = NULL;
float (*keyco)[3] = NULL;
int totloops, i, j;
/* free custom data */
/* this isnt needed in most cases but do just incase */
CustomData_free(&bm->vdata, bm->totvert);
CustomData_free(&bm->edata, bm->totedge);
CustomData_free(&bm->ldata, bm->totloop);
CustomData_free(&bm->pdata, bm->totface);
int totloops, i;
if (!me || !me->totvert) {
if (me) { /*no verts? still copy customdata layout*/
if (me && is_new) { /*no verts? still copy customdata layout*/
CustomData_copy(&me->vdata, &bm->vdata, CD_MASK_BMESH, CD_ASSIGN, 0);
CustomData_copy(&me->edata, &bm->edata, CD_MASK_BMESH, CD_ASSIGN, 0);
CustomData_copy(&me->ldata, &bm->ldata, CD_MASK_BMESH, CD_ASSIGN, 0);
@ -223,12 +224,20 @@ void BM_mesh_bm_from_me(
return; /* sanity check */
}
vtable = MEM_mallocN(sizeof(BMVert **) * me->totvert, __func__);
if (is_new) {
CustomData_copy(&me->vdata, &bm->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
CustomData_copy(&me->edata, &bm->edata, CD_MASK_BMESH, CD_CALLOC, 0);
CustomData_copy(&me->ldata, &bm->ldata, CD_MASK_BMESH, CD_CALLOC, 0);
CustomData_copy(&me->pdata, &bm->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
}
CustomData_copy(&me->vdata, &bm->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
CustomData_copy(&me->edata, &bm->edata, CD_MASK_BMESH, CD_CALLOC, 0);
CustomData_copy(&me->ldata, &bm->ldata, CD_MASK_BMESH, CD_CALLOC, 0);
CustomData_copy(&me->pdata, &bm->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
/* -------------------------------------------------------------------- */
/* Shape Key */
int tot_shape_keys = me->key ? BLI_listbase_count(&me->key->block) : 0;
if (is_new == false) {
tot_shape_keys = min_ii(tot_shape_keys, CustomData_number_of_layers(&bm->vdata, CD_SHAPEKEY));
}
const float (**shape_key_table)[3] = tot_shape_keys ? BLI_array_alloca(shape_key_table, tot_shape_keys) : NULL;
if ((params->active_shapekey != 0) && (me->key != NULL)) {
actkey = BLI_findlink(&me->key->block, params->active_shapekey - 1);
@ -237,63 +246,68 @@ void BM_mesh_bm_from_me(
actkey = NULL;
}
const int tot_shape_keys = me->key ? BLI_listbase_count(&me->key->block) : 0;
const float (**shape_key_table)[3] = tot_shape_keys ? BLI_array_alloca(shape_key_table, tot_shape_keys) : NULL;
if (tot_shape_keys || params->add_key_index) {
CustomData_add_layer(&bm->vdata, CD_SHAPE_KEYINDEX, CD_ASSIGN, NULL, 0);
if (is_new) {
if (tot_shape_keys || params->add_key_index) {
CustomData_add_layer(&bm->vdata, CD_SHAPE_KEYINDEX, CD_ASSIGN, NULL, 0);
}
}
if (tot_shape_keys) {
/* check if we need to generate unique ids for the shapekeys.
* this also exists in the file reading code, but is here for
* a sanity check */
if (!me->key->uidgen) {
fprintf(stderr,
"%s had to generate shape key uid's in a situation we shouldn't need to! "
"(bmesh internal error)\n",
__func__);
if (is_new) {
/* check if we need to generate unique ids for the shapekeys.
* this also exists in the file reading code, but is here for
* a sanity check */
if (!me->key->uidgen) {
fprintf(stderr,
"%s had to generate shape key uid's in a situation we shouldn't need to! "
"(bmesh internal error)\n",
__func__);
me->key->uidgen = 1;
for (block = me->key->block.first; block; block = block->next) {
block->uid = me->key->uidgen++;
me->key->uidgen = 1;
for (block = me->key->block.first; block; block = block->next) {
block->uid = me->key->uidgen++;
}
}
}
if (actkey && actkey->totelem == me->totvert) {
keyco = actkey->data;
bm->shapenr = params->active_shapekey;
keyco = params->use_shapekey ? actkey->data : NULL;
if (is_new) {
bm->shapenr = params->active_shapekey;
}
}
for (i = 0, block = me->key->block.first; block; block = block->next, i++) {
CustomData_add_layer_named(&bm->vdata, CD_SHAPEKEY,
CD_ASSIGN, NULL, 0, block->name);
j = CustomData_get_layer_index_n(&bm->vdata, CD_SHAPEKEY, i);
bm->vdata.layers[j].uid = block->uid;
for (i = 0, block = me->key->block.first; i < tot_shape_keys; block = block->next, i++) {
if (is_new) {
CustomData_add_layer_named(&bm->vdata, CD_SHAPEKEY,
CD_ASSIGN, NULL, 0, block->name);
int j = CustomData_get_layer_index_n(&bm->vdata, CD_SHAPEKEY, i);
bm->vdata.layers[j].uid = block->uid;
}
shape_key_table[i] = (const float (*)[3])block->data;
}
}
CustomData_bmesh_init_pool(&bm->vdata, me->totvert, BM_VERT);
CustomData_bmesh_init_pool(&bm->edata, me->totedge, BM_EDGE);
CustomData_bmesh_init_pool(&bm->ldata, me->totloop, BM_LOOP);
CustomData_bmesh_init_pool(&bm->pdata, me->totpoly, BM_FACE);
if (is_new) {
CustomData_bmesh_init_pool(&bm->vdata, me->totvert, BM_VERT);
CustomData_bmesh_init_pool(&bm->edata, me->totedge, BM_EDGE);
CustomData_bmesh_init_pool(&bm->ldata, me->totloop, BM_LOOP);
CustomData_bmesh_init_pool(&bm->pdata, me->totpoly, BM_FACE);
BM_mesh_cd_flag_apply(bm, me->cd_flag);
BM_mesh_cd_flag_apply(bm, me->cd_flag);
}
const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
const int cd_shape_key_offset = me->key ? CustomData_get_offset(&bm->vdata, CD_SHAPEKEY) : -1;
const int cd_shape_keyindex_offset = (tot_shape_keys || params->add_key_index) ?
const int cd_shape_keyindex_offset = is_new && (tot_shape_keys || params->add_key_index) ?
CustomData_get_offset(&bm->vdata, CD_SHAPE_KEYINDEX) : -1;
vtable = MEM_mallocN(sizeof(BMVert **) * me->totvert, __func__);
for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) {
v = vtable[i] = BM_vert_create(
bm, keyco && params->use_shapekey ? keyco[i] : mvert->co, NULL,
BM_CREATE_SKIP_CD);
v = vtable[i] = BM_vert_create(bm, keyco ? keyco[i] : mvert->co, NULL, BM_CREATE_SKIP_CD);
BM_elem_index_set(v, i); /* set_ok */
/* transfer flag */
@ -317,13 +331,14 @@ void BM_mesh_bm_from_me(
/* set shapekey data */
if (tot_shape_keys) {
float (*co_dst)[3] = BM_ELEM_CD_GET_VOID_P(v, cd_shape_key_offset);
for (j = 0; j < tot_shape_keys; j++, co_dst++) {
for (int j = 0; j < tot_shape_keys; j++, co_dst++) {
copy_v3_v3(*co_dst, shape_key_table[j][i]);
}
}
}
bm->elem_index_dirty &= ~BM_VERT; /* added in order, clear dirty flag */
if (is_new) {
bm->elem_index_dirty &= ~BM_VERT; /* added in order, clear dirty flag */
}
etable = MEM_mallocN(sizeof(BMEdge **) * me->totedge, __func__);
@ -347,8 +362,14 @@ void BM_mesh_bm_from_me(
if (cd_edge_crease_offset != -1) BM_ELEM_CD_SET_FLOAT(e, cd_edge_crease_offset, (float)medge->crease / 255.0f);
}
if (is_new) {
bm->elem_index_dirty &= ~BM_EDGE; /* added in order, clear dirty flag */
}
bm->elem_index_dirty &= ~BM_EDGE; /* added in order, clear dirty flag */
/* only needed for selection. */
if (me->mselect && me->totselect != 0) {
ftable = MEM_mallocN(sizeof(BMFace **) * me->totpoly, __func__);
}
mloop = me->mloop;
mp = me->mpoly;
@ -358,6 +379,9 @@ void BM_mesh_bm_from_me(
f = bm_face_create_from_mpoly(mp, mloop + mp->loopstart,
bm, vtable, etable);
if (ftable != NULL) {
ftable[i] = f;
}
if (UNLIKELY(f == NULL)) {
printf("%s: Warning! Bad face in mesh"
@ -380,7 +404,7 @@ void BM_mesh_bm_from_me(
f->mat_nr = mp->mat_nr;
if (i == me->act_face) bm->act_face = f;
j = mp->loopstart;
int j = mp->loopstart;
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
/* don't use 'j' since we may have skipped some faces, hence some loops. */
@ -397,8 +421,9 @@ void BM_mesh_bm_from_me(
BM_face_normal_update(f);
}
}
bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP); /* added in order, clear dirty flag */
if (is_new) {
bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP); /* added in order, clear dirty flag */
}
/* -------------------------------------------------------------------- */
/* MSelect clears the array elements (avoid adding multiple times).
@ -407,11 +432,6 @@ void BM_mesh_bm_from_me(
*/
if (me->mselect && me->totselect != 0) {
if (ftable == NULL) {
ftable = MEM_mallocN(sizeof(BMFace **) * bm->totface, __func__);
BM_iter_as_array(bm, BM_FACES_OF_MESH, NULL, (void **)ftable, bm->totface);
}
MSelect *msel;
for (i = 0, msel = me->mselect; i < me->totselect; i++, msel++) {
BMElem **ele_p;

View File

@ -12,6 +12,8 @@ extern "C" {
#include "MEM_guardedalloc.h"
}
#include "stubs/bf_intern_eigen_stubs.h"
/* -------------------------------------------------------------------- */
/* Helper Functions */

View File

@ -4,6 +4,8 @@
#include "BLI_math.h"
#include "stubs/bf_intern_eigen_stubs.h"
TEST(math_geom, DistToLine2DSimple)
{
float p[2] = {5.0f, 1.0f},

View File

@ -27,6 +27,8 @@ extern "C" {
#endif
}
#include "stubs/bf_intern_eigen_stubs.h"
static void polyfill_to_obj(
const char *id,
const float poly[][2], const unsigned int poly_tot,

View File

@ -34,25 +34,28 @@ include_directories(${INC})
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PLATFORM_LINKFLAGS}")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${PLATFORM_LINKFLAGS_DEBUG}")
if(WIN32)
set(BLI_path_util_extra_libs "bf_blenlib;bf_intern_utfconv;extern_wcwidth;${ZLIB_LIBRARIES}")
else()
set(BLI_path_util_extra_libs "bf_blenlib;extern_wcwidth;${ZLIB_LIBRARIES}")
endif()
BLENDER_TEST(BLI_array_store "bf_blenlib")
BLENDER_TEST(BLI_array_utils "bf_blenlib")
BLENDER_TEST(BLI_kdopbvh "bf_blenlib;bf_intern_eigen")
BLENDER_TEST(BLI_stack "bf_blenlib")
BLENDER_TEST(BLI_math_color "bf_blenlib")
BLENDER_TEST(BLI_math_geom "bf_blenlib;bf_intern_eigen")
BLENDER_TEST(BLI_ghash "bf_blenlib")
BLENDER_TEST(BLI_hash_mm2a "bf_blenlib")
BLENDER_TEST(BLI_kdopbvh "bf_blenlib")
BLENDER_TEST(BLI_listbase "bf_blenlib")
BLENDER_TEST(BLI_math_base "bf_blenlib")
BLENDER_TEST(BLI_math_color "bf_blenlib")
BLENDER_TEST(BLI_math_geom "bf_blenlib")
BLENDER_TEST(BLI_memiter "bf_blenlib")
BLENDER_TEST(BLI_path_util "${BLI_path_util_extra_libs}")
BLENDER_TEST(BLI_polyfill2d "bf_blenlib")
BLENDER_TEST(BLI_stack "bf_blenlib")
BLENDER_TEST(BLI_string "bf_blenlib")
BLENDER_TEST(BLI_string_utf8 "bf_blenlib")
if(WIN32)
BLENDER_TEST(BLI_path_util "bf_blenlib;bf_intern_utfconv;extern_wcwidth;${ZLIB_LIBRARIES}")
else()
BLENDER_TEST(BLI_path_util "bf_blenlib;extern_wcwidth;${ZLIB_LIBRARIES}")
endif()
BLENDER_TEST(BLI_polyfill2d "bf_blenlib;bf_intern_eigen")
BLENDER_TEST(BLI_listbase "bf_blenlib")
BLENDER_TEST(BLI_hash_mm2a "bf_blenlib")
BLENDER_TEST(BLI_ghash "bf_blenlib")
BLENDER_TEST_PERFORMANCE(BLI_ghash_performance "bf_blenlib")
unset(BLI_path_util_extra_libs)

View File

@ -0,0 +1,18 @@
/* Apache License, Version 2.0 */
extern "C" {
bool EIG_self_adjoint_eigen_solve(const int size, const float *matrix, float *r_eigen_values, float *r_eigen_vectors)
{
BLI_assert(0);
UNUSED_VARS(size, matrix, r_eigen_values, r_eigen_vectors);
return false;
}
void EIG_svd_square_matrix(const int size, const float *matrix, float *r_U, float *r_S, float *r_V)
{
BLI_assert(0);
UNUSED_VARS(size, matrix, r_U, r_S, r_V);
}
}