diff options
author | Campbell Barton <ideasman42@gmail.com> | 2018-03-02 06:09:27 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2018-03-02 06:09:27 +0300 |
commit | 4913e47aa0107cbe1daf06e8020a60916ea883a3 (patch) | |
tree | 29cf5e0671027f74296d866cff0df66267bd09c8 | |
parent | b7016e69b3fff44d623f8413f9ebd4f7216a9b9b (diff) | |
parent | 7e4c23e4d7a3a27a49930824c822b679416724f6 (diff) |
Merge branch 'master' into blender2.8
-rw-r--r-- | source/blender/blenkernel/BKE_DerivedMesh.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_mesh.h | 39 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/constraint.c | 12 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/fcurve.c | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh.c | 19 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh_evaluate.c | 73 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_mesh.c | 16 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_mesh.h | 3 | ||||
-rw-r--r-- | source/blender/editors/util/numinput.c | 7 | ||||
-rw-r--r-- | source/blender/render/intern/source/external_engine.c | 3 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_files.c | 2 | ||||
-rwxr-xr-x | tests/python/alembic_tests.py | 59 | ||||
-rwxr-xr-x | tests/python/modules/test_utils.py | 97 |
13 files changed, 227 insertions, 113 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index c3cea6c883c..9d48ddb4f32 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -167,7 +167,7 @@ typedef enum DMDirtyFlag { DM_DIRTY_TESS_CDLAYERS = 1 << 0, /* One of the MCOL layers have been updated, force updating of GPUDrawObject's colors buffer. * This is necessary with modern, VBO draw code, as e.g. in vpaint mode me->mcol may be updated - * without actually rebuilding dm (hence by defautl keeping same GPUDrawObject, and same colors + * without actually rebuilding dm (hence by default keeping same GPUDrawObject, and same colors * buffer, which prevents update during a stroke!). */ DM_DIRTY_MCOL_UPDATE_DRAW = 1 << 1, diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 9ff842e36f1..19caf30a280 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -193,6 +193,17 @@ void BKE_mesh_calc_normals_looptri( const struct MLoop *mloop, const struct MLoopTri *looptri, int looptri_num, float (*r_tri_nors)[3]); +void BKE_mesh_loop_tangents_ex( + const struct MVert *mverts, const int numVerts, const struct MLoop *mloops, + float (*r_looptangent)[4], float (*loopnors)[3], const struct MLoopUV *loopuv, + const int numLoops, const struct MPoly *mpolys, const int numPolys, + struct ReportList *reports); +void BKE_mesh_loop_tangents( + struct Mesh *mesh, const char *uvmap, float (*r_looptangents)[4], struct ReportList *reports); +void BKE_mesh_loop_manifold_fan_around_vert_next( + const struct MLoop *mloops, const struct MPoly *mpolys, + const int *loop_to_poly, const int *e2lfan_curr, const uint mv_pivot_index, + const struct MLoop **r_mlfan_curr, int *r_mlfan_curr_index, int *r_mlfan_vert_index, int *r_mpfan_curr_index); void BKE_edges_sharp_from_angle_set( const struct MVert *mverts, const int numVerts, @@ -210,17 +221,38 @@ typedef struct MLoopNorSpace { float vec_ortho[3]; /* Third vector, orthogonal to vec_lnor and vec_ref. */ float ref_alpha; /* Reference angle, around vec_ortho, in ]0, pi] range (0.0 marks that space as invalid). */ float ref_beta; /* Reference angle, around vec_lnor, in ]0, 2pi] range (0.0 marks that space as invalid). */ - struct LinkNode *loops; /* All indices (uint_in_ptr) of loops using this lnor space (i.e. smooth fan of loops). */ + /* All loops using this lnor space (i.e. smooth fan of loops), + * as (depending on owning MLoopNorSpaceArrary.data_type): + * - Indices (uint_in_ptr), or + * - BMLoop pointers. */ + struct LinkNode *loops; + char flags; } MLoopNorSpace; /** + * MLoopNorSpace.flags + */ +enum { + MLNOR_SPACE_IS_SINGLE = 1 << 0, +}; + +/** * Collection of #MLoopNorSpace basic storage & pre-allocation. */ typedef struct MLoopNorSpaceArray { MLoopNorSpace **lspacearr; /* MLoop aligned array */ struct LinkNode *loops_pool; /* Allocated once, avoids to call BLI_linklist_prepend_arena() for each loop! */ + char data_type; /* Whether we store loop indices, or pointers to BMLoop. */ struct MemArena *mem; } MLoopNorSpaceArray; -void BKE_lnor_spacearr_init(MLoopNorSpaceArray *lnors_spacearr, const int numLoops); +/** + * MLoopNorSpaceArray.data_type + */ +enum { + MLNOR_SPACEARR_LOOP_INDEX = 0, + MLNOR_SPACEARR_BMLOOP_PTR = 1, +}; + +void BKE_lnor_spacearr_init(MLoopNorSpaceArray *lnors_spacearr, const int numLoops, const char data_type); void BKE_lnor_spacearr_clear(MLoopNorSpaceArray *lnors_spacearr); void BKE_lnor_spacearr_free(MLoopNorSpaceArray *lnors_spacearr); MLoopNorSpace *BKE_lnor_space_create(MLoopNorSpaceArray *lnors_spacearr); @@ -228,7 +260,8 @@ void BKE_lnor_space_define( MLoopNorSpace *lnor_space, const float lnor[3], float vec_ref[3], float vec_other[3], struct BLI_Stack *edge_vectors); void BKE_lnor_space_add_loop( - MLoopNorSpaceArray *lnors_spacearr, MLoopNorSpace *lnor_space, const int ml_index, const bool add_to_list); + MLoopNorSpaceArray *lnors_spacearr, MLoopNorSpace *lnor_space, + const int ml_index, void *bm_loop, const bool is_single); void BKE_lnor_space_custom_data_to_normal(MLoopNorSpace *lnor_space, const short clnor_data[2], float r_custom_lnor[3]); void BKE_lnor_space_custom_normal_to_data(MLoopNorSpace *lnor_space, const float custom_lnor[3], short r_clnor_data[2]); diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index b8dc7944a75..f0e60296119 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -1929,16 +1929,16 @@ static void samevolume_evaluate(bConstraint *con, bConstraintOb *cob, ListBase * /* apply scaling factor to the channels not being kept */ switch (data->flag) { case SAMEVOL_X: - mul_v3_fl(cob->matrix[1], fac); - mul_v3_fl(cob->matrix[2], fac); + mul_v3_fl(cob->matrix[1], fac / obsize[1]); + mul_v3_fl(cob->matrix[2], fac / obsize[2]); break; case SAMEVOL_Y: - mul_v3_fl(cob->matrix[0], fac); - mul_v3_fl(cob->matrix[2], fac); + mul_v3_fl(cob->matrix[0], fac / obsize[0]); + mul_v3_fl(cob->matrix[2], fac / obsize[2]); break; case SAMEVOL_Z: - mul_v3_fl(cob->matrix[0], fac); - mul_v3_fl(cob->matrix[1], fac); + mul_v3_fl(cob->matrix[0], fac / obsize[0]); + mul_v3_fl(cob->matrix[1], fac / obsize[1]); break; } } diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index d7e8c62375b..905f103250a 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -1590,11 +1590,9 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar) return 0.0f; } else if (dtar->transChan >= DTAR_TRANSCHAN_SCALEX) { - /* extract scale, and choose the right axis */ - float scale[3]; - - mat4_to_size(scale, mat); - return scale[dtar->transChan - DTAR_TRANSCHAN_SCALEX]; + /* Extract scale, and choose the right axis, + * inline 'mat4_to_size'. */ + return len_v3(mat[dtar->transChan - DTAR_TRANSCHAN_SCALEX]); } else if (dtar->transChan >= DTAR_TRANSCHAN_ROTX) { /* extract rotation as eulers (if needed) diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index d1b8920d612..9f346d10272 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -2205,6 +2205,8 @@ static int split_faces_prepare_new_verts( MLoop *ml = mloop; MLoopNorSpace **lnor_space = lnors_spacearr->lspacearr; + BLI_assert(lnors_spacearr->data_type == MLNOR_SPACEARR_LOOP_INDEX); + for (int loop_idx = 0; loop_idx < num_loops; loop_idx++, ml++, lnor_space++) { if (!BLI_BITMAP_TEST(done_loops, loop_idx)) { const int vert_idx = ml->v; @@ -2214,7 +2216,15 @@ static int split_faces_prepare_new_verts( BLI_assert(*lnor_space); - if ((*lnor_space)->loops) { + if ((*lnor_space)->flags & MLNOR_SPACE_IS_SINGLE) { + /* Single loop in this fan... */ + BLI_assert(GET_INT_FROM_POINTER((*lnor_space)->loops) == loop_idx); + BLI_BITMAP_ENABLE(done_loops, loop_idx); + if (vert_used) { + ml->v = new_vert_idx; + } + } + else { for (LinkNode *lnode = (*lnor_space)->loops; lnode; lnode = lnode->next) { const int ml_fan_idx = GET_INT_FROM_POINTER(lnode->link); BLI_BITMAP_ENABLE(done_loops, ml_fan_idx); @@ -2223,13 +2233,6 @@ static int split_faces_prepare_new_verts( } } } - else { - /* Single loop in this fan... */ - BLI_BITMAP_ENABLE(done_loops, loop_idx); - if (vert_used) { - ml->v = new_vert_idx; - } - } if (!vert_used) { BLI_BITMAP_ENABLE(verts_used, vert_idx); diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c index 92c47de5831..2a655752169 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.c +++ b/source/blender/blenkernel/intern/mesh_evaluate.c @@ -444,7 +444,7 @@ cleanup: MEM_freeN(fnors); } -void BKE_lnor_spacearr_init(MLoopNorSpaceArray *lnors_spacearr, const int numLoops) +void BKE_lnor_spacearr_init(MLoopNorSpaceArray *lnors_spacearr, const int numLoops, const char data_type) { if (!(lnors_spacearr->lspacearr && lnors_spacearr->loops_pool)) { MemArena *mem; @@ -456,6 +456,8 @@ void BKE_lnor_spacearr_init(MLoopNorSpaceArray *lnors_spacearr, const int numLoo lnors_spacearr->lspacearr = BLI_memarena_calloc(mem, sizeof(MLoopNorSpace *) * (size_t)numLoops); lnors_spacearr->loops_pool = BLI_memarena_alloc(mem, sizeof(LinkNode) * (size_t)numLoops); } + BLI_assert(ELEM(data_type, MLNOR_SPACEARR_BMLOOP_PTR, MLNOR_SPACEARR_LOOP_INDEX)); + lnors_spacearr->data_type = data_type; } void BKE_lnor_spacearr_clear(MLoopNorSpaceArray *lnors_spacearr) @@ -549,12 +551,32 @@ void BKE_lnor_space_define(MLoopNorSpace *lnor_space, const float lnor[3], } } -void BKE_lnor_space_add_loop(MLoopNorSpaceArray *lnors_spacearr, MLoopNorSpace *lnor_space, const int ml_index, - const bool do_add_loop) +/** + * Add a new given loop to given lnor_space. + * Depending on \a lnor_space->data_type, we expect \a bm_loop to be a pointer to BMLoop struct (in case of BMLOOP_PTR), + * or NULL (in case of LOOP_INDEX), loop index is then stored in pointer. + * If \a is_single is set, the BMLoop or loop index is directly stored in \a lnor_space->loops pointer (since there + * is only one loop in this fan), else it is added to the linked list of loops in the fan. + */ +void BKE_lnor_space_add_loop( + MLoopNorSpaceArray *lnors_spacearr, MLoopNorSpace *lnor_space, + const int ml_index, void *bm_loop, const bool is_single) { + BLI_assert((lnors_spacearr->data_type == MLNOR_SPACEARR_LOOP_INDEX && bm_loop == NULL) || + (lnors_spacearr->data_type == MLNOR_SPACEARR_BMLOOP_PTR && bm_loop != NULL)); + lnors_spacearr->lspacearr[ml_index] = lnor_space; - if (do_add_loop) { - BLI_linklist_prepend_nlink(&lnor_space->loops, SET_INT_IN_POINTER(ml_index), &lnors_spacearr->loops_pool[ml_index]); + if (bm_loop == NULL) { + bm_loop = SET_INT_IN_POINTER(ml_index); + } + if (is_single) { + BLI_assert(lnor_space->loops == NULL); + lnor_space->flags |= MLNOR_SPACE_IS_SINGLE; + lnor_space->loops = bm_loop; + } + else { + BLI_assert((lnor_space->flags & MLNOR_SPACE_IS_SINGLE) == 0); + BLI_linklist_prepend_nlink(&lnor_space->loops, bm_loop, &lnors_spacearr->loops_pool[ml_index]); } } @@ -841,7 +863,7 @@ void BKE_edges_sharp_from_angle_set( MEM_freeN(loop_to_poly); } -static void loop_manifold_fan_around_vert_next( +void BKE_mesh_loop_manifold_fan_around_vert_next( const MLoop *mloops, const MPoly *mpolys, const int *loop_to_poly, const int *e2lfan_curr, const uint mv_pivot_index, const MLoop **r_mlfan_curr, int *r_mlfan_curr_index, int *r_mlfan_vert_index, int *r_mpfan_curr_index) @@ -930,7 +952,7 @@ static void split_loop_nor_single_do(LoopSplitTaskDataCommon *common_data, LoopS BKE_lnor_space_define(lnor_space, *lnor, vec_curr, vec_prev, NULL); /* We know there is only one loop in this space, no need to create a linklist in this case... */ - BKE_lnor_space_add_loop(lnors_spacearr, lnor_space, ml_curr_index, false); + BKE_lnor_space_add_loop(lnors_spacearr, lnor_space, ml_curr_index, NULL, true); if (clnors_data) { BKE_lnor_space_custom_data_to_normal(lnor_space, clnors_data[ml_curr_index], *lnor); @@ -1063,7 +1085,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli if (lnors_spacearr) { /* Assign current lnor space to current 'vertex' loop. */ - BKE_lnor_space_add_loop(lnors_spacearr, lnor_space, mlfan_vert_index, true); + BKE_lnor_space_add_loop(lnors_spacearr, lnor_space, mlfan_vert_index, NULL, false); if (me_curr != me_org) { /* We store here all edges-normalized vectors processed. */ BLI_stack_push(edge_vectors, vec_curr); @@ -1081,7 +1103,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli copy_v3_v3(vec_prev, vec_curr); /* Find next loop of the smooth fan. */ - loop_manifold_fan_around_vert_next( + BKE_mesh_loop_manifold_fan_around_vert_next( mloops, mpolys, loop_to_poly, e2lfan_curr, mv_pivot_index, &mlfan_curr, &mlfan_curr_index, &mlfan_vert_index, &mpfan_curr_index); @@ -1218,7 +1240,7 @@ static bool loop_split_generator_check_cyclic_smooth_fan( while (true) { /* Find next loop of the smooth fan. */ - loop_manifold_fan_around_vert_next( + BKE_mesh_loop_manifold_fan_around_vert_next( mloops, mpolys, loop_to_poly, e2lfan_curr, mv_pivot_index, &mlfan_curr, &mlfan_curr_index, &mlfan_vert_index, &mpfan_curr_index); @@ -1475,7 +1497,7 @@ void BKE_mesh_normals_loop_split( r_lnors_spacearr = &_lnors_spacearr; } if (r_lnors_spacearr) { - BKE_lnor_spacearr_init(r_lnors_spacearr, numLoops); + BKE_lnor_spacearr_init(r_lnors_spacearr, numLoops, MLNOR_SPACEARR_LOOP_INDEX); } /* Init data common to all tasks. */ @@ -1589,6 +1611,8 @@ static void mesh_normals_loop_custom_set( } } + BLI_assert(lnors_spacearr.data_type == MLNOR_SPACEARR_LOOP_INDEX); + /* Now, check each current smooth fan (one lnor space per smooth fan!), and if all its matching custom lnors * are not (enough) equal, add sharp edges as needed. * This way, next time we run BKE_mesh_normals_loop_split(), we'll get lnor spacearr/smooth fans matching @@ -1612,7 +1636,7 @@ static void mesh_normals_loop_custom_set( if (!BLI_BITMAP_TEST(done_loops, i)) { /* Notes: - * * In case of mono-loop smooth fan, loops is NULL, so everything is fine (we have nothing to do). + * * In case of mono-loop smooth fan, we have nothing to do. * * Loops in this linklist are ordered (in reversed order compared to how they were discovered by * BKE_mesh_normals_loop_split(), but this is not a problem). Which means if we find a * mismatching clnor, we know all remaining loops will have to be in a new, different smooth fan/ @@ -1620,6 +1644,11 @@ static void mesh_normals_loop_custom_set( * * In smooth fan case, we compare each clnor against a ref one, to avoid small differences adding * up into a real big one in the end! */ + if (lnors_spacearr.lspacearr[i]->flags & MLNOR_SPACE_IS_SINGLE) { + BLI_BITMAP_ENABLE(done_loops, i); + continue; + } + LinkNode *loops = lnors_spacearr.lspacearr[i]->loops; MLoop *prev_ml = NULL; const float *org_nor = NULL; @@ -1667,9 +1696,6 @@ static void mesh_normals_loop_custom_set( medges[(prev_ml->e == mlp->e) ? prev_ml->e : ml->e].flag |= ME_SHARP; } } - - /* For single loops, where lnors_spacearr.lspacearr[i]->loops is NULL. */ - BLI_BITMAP_ENABLE(done_loops, i); } } @@ -1699,7 +1725,15 @@ static void mesh_normals_loop_custom_set( * computed 2D factors). */ LinkNode *loops = lnors_spacearr.lspacearr[i]->loops; - if (loops) { + if (lnors_spacearr.lspacearr[i]->flags & MLNOR_SPACE_IS_SINGLE) { + BLI_assert(GET_INT_FROM_POINTER(loops) == i); + const int nidx = use_vertices ? (int)mloops[i].v : i; + float *nor = r_custom_loopnors[nidx]; + + BKE_lnor_space_custom_normal_to_data(lnors_spacearr.lspacearr[i], nor, r_clnors_data[i]); + BLI_BITMAP_DISABLE(done_loops, i); + } + else { int nbr_nors = 0; float avg_nor[3]; short clnor_data_tmp[2], *clnor_data; @@ -1726,13 +1760,6 @@ static void mesh_normals_loop_custom_set( clnor_data[1] = clnor_data_tmp[1]; } } - else { - const int nidx = use_vertices ? (int)mloops[i].v : i; - float *nor = r_custom_loopnors[nidx]; - - BKE_lnor_space_custom_normal_to_data(lnors_spacearr.lspacearr[i], nor, r_clnors_data[i]); - BLI_BITMAP_DISABLE(done_loops, i); - } } } diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index d178b48ab60..9a927bd4701 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -597,9 +597,11 @@ static void bm_mesh_edges_sharp_tag( bm->elem_index_dirty &= ~BM_EDGE; } -/* Check whether gievn loop is part of an unknown-so-far cyclic smooth fan, or not. - * Needed because cyclic smooth fans have no obvious 'entry point', and yet we need to walk them once, and only once. */ -static bool bm_mesh_loop_check_cyclic_smooth_fan(BMLoop *l_curr) +/** + * Check whether given loop is part of an unknown-so-far cyclic smooth fan, or not. + * Needed because cyclic smooth fans have no obvious 'entry point', and yet we need to walk them once, and only once. + */ +bool BM_loop_check_cyclic_smooth_fan(BMLoop *l_curr) { BMLoop *lfan_pivot_next = l_curr; BMEdge *e_next = l_curr->e; @@ -665,7 +667,7 @@ static void bm_mesh_loops_calc_normals( r_lnors_spacearr = &_lnors_spacearr; } if (r_lnors_spacearr) { - BKE_lnor_spacearr_init(r_lnors_spacearr, bm->totloop); + BKE_lnor_spacearr_init(r_lnors_spacearr, bm->totloop, MLNOR_SPACEARR_BMLOOP_PTR); edge_vectors = BLI_stack_new(sizeof(float[3]), __func__); } @@ -700,7 +702,7 @@ static void bm_mesh_loops_calc_normals( * However, this would complicate the code, add more memory usage, and BM_vert_step_fan_loop() * is quite cheap in term of CPU cycles, so really think it's not worth it. */ if (BM_elem_flag_test(l_curr->e, BM_ELEM_TAG) && - (BM_elem_flag_test(l_curr, BM_ELEM_TAG) || !bm_mesh_loop_check_cyclic_smooth_fan(l_curr))) + (BM_elem_flag_test(l_curr, BM_ELEM_TAG) || !BM_loop_check_cyclic_smooth_fan(l_curr))) { } else if (!BM_elem_flag_test(l_curr->e, BM_ELEM_TAG) && @@ -734,7 +736,7 @@ static void bm_mesh_loops_calc_normals( BKE_lnor_space_define(lnor_space, r_lnos[l_curr_index], vec_curr, vec_prev, NULL); /* We know there is only one loop in this space, no need to create a linklist in this case... */ - BKE_lnor_space_add_loop(r_lnors_spacearr, lnor_space, l_curr_index, false); + BKE_lnor_space_add_loop(r_lnors_spacearr, lnor_space, l_curr_index, l_curr, true); if (has_clnors) { short (*clnor)[2] = clnors_data ? &clnors_data[l_curr_index] : @@ -853,7 +855,7 @@ static void bm_mesh_loops_calc_normals( if (r_lnors_spacearr) { /* Assign current lnor space to current 'vertex' loop. */ - BKE_lnor_space_add_loop(r_lnors_spacearr, lnor_space, lfan_pivot_index, true); + BKE_lnor_space_add_loop(r_lnors_spacearr, lnor_space, lfan_pivot_index, lfan_pivot, false); if (e_next != e_org) { /* We store here all edges-normalized vectors processed. */ BLI_stack_push(edge_vectors, vec_next); diff --git a/source/blender/bmesh/intern/bmesh_mesh.h b/source/blender/bmesh/intern/bmesh_mesh.h index 8326e82af00..10f024423aa 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.h +++ b/source/blender/bmesh/intern/bmesh_mesh.h @@ -52,6 +52,9 @@ void BM_loops_calc_normal_vcos( const bool use_split_normals, const float split_angle, float (*r_lnos)[3], struct MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2], const int cd_loop_clnors_offset); +bool BM_loop_check_cyclic_smooth_fan(BMLoop *l_curr); + + void BM_edges_sharp_from_angle_set(BMesh *bm, const float split_angle); void bmesh_edit_begin(BMesh *bm, const BMOpTypeFlag type_flag); diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c index 0f3240946fd..a139f0e3c87 100644 --- a/source/blender/editors/util/numinput.c +++ b/source/blender/editors/util/numinput.c @@ -478,9 +478,9 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event) /* At this point, our value has changed, try to interpret it with python (if str is not empty!). */ if (n->str[0]) { const float val_prev = n->val[idx]; + double val; #ifdef WITH_PYTHON Scene *sce = CTX_data_scene(C); - double val; char str_unit_convert[NUM_STR_REP_LEN * 6]; /* Should be more than enough! */ const char *default_unit = NULL; @@ -506,8 +506,9 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event) n->val_flag[idx] |= NUM_INVALID; } #else /* Very unlikely, but does not harm... */ - n->val[idx] = (float)atof(n->str); - (void)C; + val = atof(n->str); + n->val[idx] = (float)val; + UNUSED_VARS(C); #endif /* WITH_PYTHON */ if (n->val_flag[idx] & NUM_NEGATE) { diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index 9b384709f35..ebc4c704adf 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -1,11 +1,10 @@ /* - * ***** 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. + * 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 diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 4cdca043448..8c0f78a9824 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -497,6 +497,8 @@ static void wm_file_read_post(bContext *C, const bool is_startup_file, const boo BPY_python_reset(C); addons_loaded = true; } +#else + UNUSED_VARS(use_userdef); #endif /* WITH_PYTHON */ WM_operatortype_last_properties_clear_all(); diff --git a/tests/python/alembic_tests.py b/tests/python/alembic_tests.py index 96a68de9801..b9dc78a821f 100755 --- a/tests/python/alembic_tests.py +++ b/tests/python/alembic_tests.py @@ -28,37 +28,17 @@ import sys import tempfile import unittest +from modules.test_utils import (with_tempdir, + AbstractBlenderRunnerTest, + ) -def with_tempdir(wrapped): - """Creates a temporary directory for the function, cleaning up after it returns normally. - - When the wrapped function raises an exception, the contents of the temporary directory - remain available for manual inspection. - - The wrapped function is called with an extra positional argument containing - the pathlib.Path() of the temporary directory. - """ - - @functools.wraps(wrapped) - def decorator(*args, **kwargs): - dirname = tempfile.mkdtemp(prefix='blender-alembic-test') - try: - retval = wrapped(*args, pathlib.Path(dirname), **kwargs) - except: - print('Exception in %s, not cleaning up temporary directory %s' % (wrapped, dirname)) - raise - else: - shutil.rmtree(dirname) - return retval - - return decorator class AbcPropError(Exception): """Raised when AbstractAlembicTest.abcprop() finds an error.""" -class AbstractAlembicTest(unittest.TestCase): +class AbstractAlembicTest(AbstractBlenderRunnerTest): @classmethod def setUpClass(cls): import re @@ -74,37 +54,6 @@ class AbstractAlembicTest(unittest.TestCase): # 'abcls' array notation, like "name[16]" cls.abcls_array = re.compile(r'^(?P<name>[^\[]+)(\[(?P<arraysize>\d+)\])?$') - def run_blender(self, filepath: str, python_script: str, timeout: int=300) -> str: - """Runs Blender by opening a blendfile and executing a script. - - Returns Blender's stdout + stderr combined into one string. - - :param filepath: taken relative to self.testdir. - :param timeout: in seconds - """ - - blendfile = self.testdir / filepath - - command = ( - self.blender, - '--background', - '-noaudio', - '--factory-startup', - '--enable-autoexec', - str(blendfile), - '-E', 'CYCLES', - '--python-exit-code', '47', - '--python-expr', python_script, - ) - - proc = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, - timeout=timeout) - output = proc.stdout.decode('utf8') - if proc.returncode: - self.fail('Error %d running Blender:\n%s' % (proc.returncode, output)) - - return output - def abcprop(self, filepath: pathlib.Path, proppath: str) -> dict: """Uses abcls to obtain compound property values from an Alembic object. diff --git a/tests/python/modules/test_utils.py b/tests/python/modules/test_utils.py new file mode 100755 index 00000000000..489f36c913f --- /dev/null +++ b/tests/python/modules/test_utils.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python3 +# ##### 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. +# +# ##### END GPL LICENSE BLOCK ##### + +# <pep8 compliant> + +import argparse +import functools +import shutil +import pathlib +import re +import subprocess +import sys +import tempfile +import unittest + + +def with_tempdir(wrapped): + """Creates a temporary directory for the function, cleaning up after it returns normally. + + When the wrapped function raises an exception, the contents of the temporary directory + remain available for manual inspection. + + The wrapped function is called with an extra positional argument containing + the pathlib.Path() of the temporary directory. + """ + + @functools.wraps(wrapped) + def decorator(*args, **kwargs): + dirname = tempfile.mkdtemp(prefix='blender-alembic-test') + try: + retval = wrapped(*args, pathlib.Path(dirname), **kwargs) + except: + print('Exception in %s, not cleaning up temporary directory %s' % (wrapped, dirname)) + raise + else: + shutil.rmtree(dirname) + return retval + + return decorator + + +class AbstractBlenderRunnerTest(unittest.TestCase): + """Base class for all test suites which needs to run Blender""" + + @classmethod + def setUpClass(cls): + global args + cls.blender = args.blender + cls.testdir = pathlib.Path(args.testdir) + + def run_blender(self, filepath: str, python_script: str, timeout: int=300) -> str: + """Runs Blender by opening a blendfile and executing a script. + + Returns Blender's stdout + stderr combined into one string. + + :param filepath: taken relative to self.testdir. + :param timeout: in seconds + """ + + blendfile = self.testdir / filepath + + command = ( + self.blender, + '--background', + '-noaudio', + '--factory-startup', + '--enable-autoexec', + str(blendfile), + '-E', 'CYCLES', + '--python-exit-code', '47', + '--python-expr', python_script, + ) + + proc = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, + timeout=timeout) + output = proc.stdout.decode('utf8') + if proc.returncode: + self.fail('Error %d running Blender:\n%s' % (proc.returncode, output)) + + return output + |