Merge branch 'master' into sculpt-dev

This commit is contained in:
Pablo Dobarro 2020-12-31 18:30:27 +01:00
commit e1b8577e41
6 changed files with 296 additions and 276 deletions

View File

@ -1911,6 +1911,7 @@ static void draw_seq_backdrop(View2D *v2d)
while (line_len--) {
immVertex2f(pos, v2d->cur.xmax, i);
immVertex2f(pos, v2d->cur.xmin, i);
i++;
}
immEnd();

View File

@ -3209,223 +3209,6 @@ void SEQUENCER_OT_set_range_to_strips(struct wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
/** \name Unused functions
* \{ */
#if 0
static void set_filter_seq(Scene *scene)
{
Sequence *seq;
Editing *ed = SEQ_editing_get(scene, false);
if (ed == NULL) {
return;
}
if (okee("Set Deinterlace") == 0) {
return;
}
SEQ_CURRENT_BEGIN (ed, seq) {
if (seq->flag & SELECT) {
if (seq->type == SEQ_TYPE_MOVIE) {
seq->flag |= SEQ_FILTERY;
SEQ_add_reload_new_file(bmain, scene, seq, false);
SEQ_time_update_sequence(scene, seq);
}
}
}
SEQ_CURRENT_END;
}
static void UNUSED_FUNCTION(seq_remap_paths)(Scene *scene)
{
Sequence *seq, *last_seq = SEQ_select_active_get(scene);
Editing *ed = SEQ_editing_get(scene, false);
char from[FILE_MAX], to[FILE_MAX], stripped[FILE_MAX];
if (last_seq == NULL) {
return;
}
BLI_strncpy(from, last_seq->strip->dir, sizeof(from));
/* XXX if (0 == sbutton(from, 0, sizeof(from) - 1, "From: "))
* return; */
BLI_strncpy(to, from, sizeof(to));
/* XXX if (0 == sbutton(to, 0, sizeof(to) - 1, "To: "))
* return; */
if (STREQ(to, from)) {
return;
}
SEQ_CURRENT_BEGIN (ed, seq) {
if (seq->flag & SELECT) {
if (STREQLEN(seq->strip->dir, from, strlen(from))) {
printf("found %s\n", seq->strip->dir);
/* Strip off the beginning. */
stripped[0] = 0;
BLI_strncpy(stripped, seq->strip->dir + strlen(from), FILE_MAX);
/* New path. */
BLI_snprintf(seq->strip->dir, sizeof(seq->strip->dir), "%s%s", to, stripped);
printf("new %s\n", seq->strip->dir);
}
}
}
SEQ_CURRENT_END;
}
static Sequence *sequence_find_parent(Scene *scene, Sequence *child)
{
Editing *ed = SEQ_editing_get(scene, false);
Sequence *parent = NULL;
Sequence *seq;
if (ed == NULL) {
return NULL;
}
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
if ((seq != child) && seq_is_parent(seq, child)) {
parent = seq;
break;
}
}
return parent;
}
static int seq_get_snaplimit(View2D *v2d)
{
/* fake mouse coords to get the snap value
* a bit lazy but its only done once pre transform */
float xmouse, ymouse, x;
int mval[2] = {24, 0}; /* 24 screen px snap */
UI_view2d_region_to_view(v2d, mval[0], mval[1], &xmouse, &ymouse);
x = xmouse;
mval[0] = 0;
UI_view2d_region_to_view(v2d, mval[0], mval[1], &xmouse, &ymouse);
return (int)(x - xmouse);
}
#endif
/** \} */
/* -------------------------------------------------------------------- */
/** \name Unused in current file
* \{ */
void seq_rectf(Sequence *seq, rctf *rect)
{
rect->xmin = seq->startdisp;
rect->xmax = seq->enddisp;
rect->ymin = seq->machine + SEQ_STRIP_OFSBOTTOM;
rect->ymax = seq->machine + SEQ_STRIP_OFSTOP;
}
Sequence *find_neighboring_sequence(Scene *scene, Sequence *test, int lr, int sel)
{
/* sel: 0==unselected, 1==selected, -1==don't care. */
Sequence *seq;
Editing *ed = SEQ_editing_get(scene, false);
if (ed == NULL) {
return NULL;
}
if (sel > 0) {
sel = SELECT;
}
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
if ((seq != test) && (test->machine == seq->machine) &&
((sel == -1) || (sel && (seq->flag & SELECT)) ||
(sel == 0 && (seq->flag & SELECT) == 0))) {
switch (lr) {
case SEQ_SIDE_LEFT:
if (test->startdisp == (seq->enddisp)) {
return seq;
}
break;
case SEQ_SIDE_RIGHT:
if (test->enddisp == (seq->startdisp)) {
return seq;
}
break;
}
}
}
return NULL;
}
Sequence *find_nearest_seq(Scene *scene, View2D *v2d, int *hand, const int mval[2])
{
Sequence *seq;
Editing *ed = SEQ_editing_get(scene, false);
float x, y;
float pixelx;
float handsize;
float displen;
*hand = SEQ_SIDE_NONE;
if (ed == NULL) {
return NULL;
}
pixelx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask);
UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y);
seq = ed->seqbasep->first;
while (seq) {
if (seq->machine == (int)y) {
/* Check for both normal strips, and strips that have been flipped horizontally. */
if (((seq->startdisp < seq->enddisp) && (seq->startdisp <= x && seq->enddisp >= x)) ||
((seq->startdisp > seq->enddisp) && (seq->startdisp >= x && seq->enddisp <= x))) {
if (SEQ_transform_sequence_can_be_translated(seq)) {
/* Clamp handles to defined size in pixel space. */
handsize = 2.0f * sequence_handle_size_get_clamped(seq, pixelx);
displen = (float)abs(seq->startdisp - seq->enddisp);
/* Don't even try to grab the handles of small strips. */
if (displen / pixelx > 16) {
/* Set the max value to handle to 1/3 of the total len when its
* less than 28. This is important because otherwise selecting
* handles happens even when you click in the middle. */
if ((displen / 3) < 30 * pixelx) {
handsize = displen / 3;
}
else {
CLAMP(handsize, 7 * pixelx, 30 * pixelx);
}
if (handsize + seq->startdisp >= x) {
*hand = SEQ_SIDE_LEFT;
}
else if (-handsize + seq->enddisp <= x) {
*hand = SEQ_SIDE_RIGHT;
}
}
}
return seq;
}
}
seq = seq->next;
}
return NULL;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Clear Strip Transform Operator
* \{ */

View File

@ -42,6 +42,7 @@
#include "SEQ_iterator.h"
#include "SEQ_select.h"
#include "SEQ_sequencer.h"
#include "SEQ_transform.h"
/* For menu, popup, icons, etc. */
@ -222,6 +223,109 @@ void ED_sequencer_select_sequence_single(Scene *scene, Sequence *seq, bool desel
recurs_sel_seq(seq);
}
void seq_rectf(Sequence *seq, rctf *rect)
{
rect->xmin = seq->startdisp;
rect->xmax = seq->enddisp;
rect->ymin = seq->machine + SEQ_STRIP_OFSBOTTOM;
rect->ymax = seq->machine + SEQ_STRIP_OFSTOP;
}
Sequence *find_neighboring_sequence(Scene *scene, Sequence *test, int lr, int sel)
{
/* sel: 0==unselected, 1==selected, -1==don't care. */
Sequence *seq;
Editing *ed = SEQ_editing_get(scene, false);
if (ed == NULL) {
return NULL;
}
if (sel > 0) {
sel = SELECT;
}
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
if ((seq != test) && (test->machine == seq->machine) &&
((sel == -1) || (sel && (seq->flag & SELECT)) ||
(sel == 0 && (seq->flag & SELECT) == 0))) {
switch (lr) {
case SEQ_SIDE_LEFT:
if (test->startdisp == (seq->enddisp)) {
return seq;
}
break;
case SEQ_SIDE_RIGHT:
if (test->enddisp == (seq->startdisp)) {
return seq;
}
break;
}
}
}
return NULL;
}
Sequence *find_nearest_seq(Scene *scene, View2D *v2d, int *hand, const int mval[2])
{
Sequence *seq;
Editing *ed = SEQ_editing_get(scene, false);
float x, y;
float pixelx;
float handsize;
float displen;
*hand = SEQ_SIDE_NONE;
if (ed == NULL) {
return NULL;
}
pixelx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask);
UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y);
seq = ed->seqbasep->first;
while (seq) {
if (seq->machine == (int)y) {
/* Check for both normal strips, and strips that have been flipped horizontally. */
if (((seq->startdisp < seq->enddisp) && (seq->startdisp <= x && seq->enddisp >= x)) ||
((seq->startdisp > seq->enddisp) && (seq->startdisp >= x && seq->enddisp <= x))) {
if (SEQ_transform_sequence_can_be_translated(seq)) {
/* Clamp handles to defined size in pixel space. */
handsize = 2.0f * sequence_handle_size_get_clamped(seq, pixelx);
displen = (float)abs(seq->startdisp - seq->enddisp);
/* Don't even try to grab the handles of small strips. */
if (displen / pixelx > 16) {
/* Set the max value to handle to 1/3 of the total len when its
* less than 28. This is important because otherwise selecting
* handles happens even when you click in the middle. */
if ((displen / 3) < 30 * pixelx) {
handsize = displen / 3;
}
else {
CLAMP(handsize, 7 * pixelx, 30 * pixelx);
}
if (handsize + seq->startdisp >= x) {
*hand = SEQ_SIDE_LEFT;
}
else if (-handsize + seq->enddisp <= x) {
*hand = SEQ_SIDE_RIGHT;
}
}
}
return seq;
}
}
seq = seq->next;
}
return NULL;
}
#if 0
static void select_neighbor_from_last(Scene *scene, int lr)
{

View File

@ -52,6 +52,74 @@
#include "rna_access_internal.h"
#include "rna_internal.h"
/**
* Find the actual ID owner of the given \a ptr #PointerRNA, in override sense, and generate the
* full rna path from it to given \a prop #PropertyRNA if \a rna_path is given.
*
* \note this is slightly different than 'generic' RNA 'id owner' as returned by
* #RNA_find_real_ID_and_path, since in overrides we also consider shape keys as embedded data, not
* only root node trees and master collections.
*/
static ID *rna_property_override_property_real_id_owner(Main *bmain,
PointerRNA *ptr,
PropertyRNA *prop,
char **r_rna_path)
{
ID *id = ptr->owner_id;
ID *owner_id = id;
const char *rna_path_prefix = NULL;
if (r_rna_path != NULL) {
*r_rna_path = NULL;
}
if (id == NULL) {
return NULL;
}
if (id->flag & (LIB_EMBEDDED_DATA | LIB_EMBEDDED_DATA_LIB_OVERRIDE)) {
/* XXX this is very bad band-aid code, but for now it will do.
* We should at least use a #define for those prop names.
* Ideally RNA as a whole should be aware of those PITA of embedded IDs, and have a way to
* retrieve their owner IDs and generate paths from those.
*/
switch (GS(id->name)) {
case ID_KE:
owner_id = ((Key *)id)->from;
rna_path_prefix = "shape_keys.";
break;
case ID_GR:
case ID_NT:
/* Master collections, Root node trees. */
owner_id = RNA_find_real_ID_and_path(bmain, id, &rna_path_prefix);
break;
default:
BLI_assert(0);
}
}
if (!ID_IS_OVERRIDE_LIBRARY_REAL(owner_id)) {
return NULL;
}
if (r_rna_path == NULL) {
return owner_id;
}
char *rna_path = RNA_path_from_ID_to_property(ptr, prop);
if (rna_path) {
*r_rna_path = rna_path;
if (rna_path_prefix != NULL) {
*r_rna_path = BLI_sprintfN("%s%s", rna_path_prefix, rna_path);
MEM_freeN(rna_path);
}
return owner_id;
}
return NULL;
}
int RNA_property_override_flag(PropertyRNA *prop)
{
return rna_ensure_property(prop)->flag_override;
@ -1115,61 +1183,6 @@ void RNA_struct_override_apply(Main *bmain,
#endif
}
static char *rna_property_override_property_real_id_owner(Main *bmain,
PointerRNA *ptr,
PropertyRNA *prop,
ID **r_id)
{
ID *id = ptr->owner_id;
ID *owner_id = id;
const char *rna_path_prefix = NULL;
*r_id = NULL;
if (id == NULL) {
return NULL;
}
if (id->flag & (LIB_EMBEDDED_DATA | LIB_EMBEDDED_DATA_LIB_OVERRIDE)) {
/* XXX this is very bad band-aid code, but for now it will do.
* We should at least use a #define for those prop names.
* Ideally RNA as a whole should be aware of those PITA of embedded IDs, and have a way to
* retrieve their owner IDs and generate paths from those.
*/
switch (GS(id->name)) {
case ID_KE:
owner_id = ((Key *)id)->from;
rna_path_prefix = "shape_keys.";
break;
case ID_GR:
case ID_NT:
/* Master collections, Root node trees. */
owner_id = RNA_find_real_ID_and_path(bmain, id, &rna_path_prefix);
break;
default:
BLI_assert(0);
}
}
if (!ID_IS_OVERRIDE_LIBRARY_REAL(owner_id)) {
return NULL;
}
char *rna_path = RNA_path_from_ID_to_property(ptr, prop);
if (rna_path) {
char *rna_path_full = rna_path;
if (rna_path_prefix != NULL) {
rna_path_full = BLI_sprintfN("%s%s", rna_path_prefix, rna_path);
MEM_freeN(rna_path);
}
*r_id = owner_id;
return rna_path_full;
}
return NULL;
}
IDOverrideLibraryProperty *RNA_property_override_property_find(Main *bmain,
PointerRNA *ptr,
PropertyRNA *prop,
@ -1177,8 +1190,8 @@ IDOverrideLibraryProperty *RNA_property_override_property_find(Main *bmain,
{
char *rna_path;
if ((rna_path = rna_property_override_property_real_id_owner(bmain, ptr, prop, r_owner_id)) !=
NULL) {
*r_owner_id = rna_property_override_property_real_id_owner(bmain, ptr, prop, &rna_path);
if (rna_path != NULL) {
IDOverrideLibraryProperty *op = BKE_lib_override_library_property_find(
(*r_owner_id)->override_library, rna_path);
MEM_freeN(rna_path);
@ -1192,14 +1205,14 @@ IDOverrideLibraryProperty *RNA_property_override_property_get(Main *bmain,
PropertyRNA *prop,
bool *r_created)
{
ID *id;
char *rna_path;
if (r_created != NULL) {
*r_created = false;
}
if ((rna_path = rna_property_override_property_real_id_owner(bmain, ptr, prop, &id)) != NULL) {
ID *id = rna_property_override_property_real_id_owner(bmain, ptr, prop, &rna_path);
if (rna_path != NULL) {
IDOverrideLibraryProperty *op = BKE_lib_override_library_property_get(
id->override_library, rna_path, r_created);
MEM_freeN(rna_path);

View File

@ -172,6 +172,14 @@ add_blender_test(
--python-text run_tests
)
add_blender_test(
curve_to_mesh
${TEST_SRC_DIR}/modeling/curve_to_mesh.blend
--python ${TEST_PYTHON_DIR}/curve_to_mesh.py
--
--run-all-tests
)
# ------------------------------------------------------------------------------
# MODIFIERS TESTS
add_blender_test(

View File

@ -0,0 +1,111 @@
# ##### 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 #####
# To run all tests, use
# BLENDER_VERBOSE=1 ./bin/blender ../lib/tests/modeling/curve_to_mesh.blend --python ../blender/tests/python/bl_curve_to_mesh.py -- --run-all-tests
# (that assumes the test is run from a build directory in the same directory as the source code)
import bpy
import os
import sys
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from modules.mesh_test import MeshTest, OperatorSpecObjectMode, RunTest
def main():
tests = [
MeshTest('2D Non Cyclic', 'test2DNonCyclic', 'expected2DNonCyclic',
[OperatorSpecObjectMode('convert', {'target': 'MESH'})]),
MeshTest('2D NURBS With Tail', 'test2DNURBSWithTail', 'expected2DNURBSWithTail',
[OperatorSpecObjectMode('convert', {'target': 'MESH'})]),
MeshTest('2D Shape With Hole', 'test2DShapeWithHole', 'expected2DShapeWithHole',
[OperatorSpecObjectMode('convert', {'target': 'MESH'})]),
MeshTest('2D Simple Lower Res', 'test2DSimpleLowerRes', 'expected2DSimpleLowerRes',
[OperatorSpecObjectMode('convert', {'target': 'MESH'})]),
MeshTest('2D Simple Low Res', 'test2DSimpleLowRes', 'expected2DSimpleLowRes',
[OperatorSpecObjectMode('convert', {'target': 'MESH'})]),
MeshTest('2D Square', 'test2DSquare', 'expected2DSquare',
[OperatorSpecObjectMode('convert', {'target': 'MESH'})]),
MeshTest('Bevel Back', 'testBevelBack', 'expectedBevelBack',
[OperatorSpecObjectMode('convert', {'target': 'MESH'})]),
MeshTest('Bevel Back Low Res', 'testBevelBackLowRes', 'expectedBevelBackLowRes',
[OperatorSpecObjectMode('convert', {'target': 'MESH'})]),
MeshTest('Bevel Extrude Back', 'testBevelExtrudeBack', 'expectedBevelExtrudeBack',
[OperatorSpecObjectMode('convert', {'target': 'MESH'})]),
MeshTest('Bevel Extrude Front', 'testBevelExtrudeFront', 'expectedBevelExtrudeFront',
[OperatorSpecObjectMode('convert', {'target': 'MESH'})]),
MeshTest('Bevel Extrude Full', 'testBevelExtrudeFull', 'expectedBevelExtrudeFull',
[OperatorSpecObjectMode('convert', {'target': 'MESH'})]),
MeshTest('Bevel Extrude Half', 'testBevelExtrudeHalf', 'expectedBevelExtrudeHalf',
[OperatorSpecObjectMode('convert', {'target': 'MESH'})]),
MeshTest('Bevel Front', 'testBevelFront', 'expectedBevelFront',
[OperatorSpecObjectMode('convert', {'target': 'MESH'})]),
MeshTest('Bevel Front Low Res', 'testBevelFrontLowRes', 'expectedBevelFrontLowRes',
[OperatorSpecObjectMode('convert', {'target': 'MESH'})]),
MeshTest('Bevel Full', 'testBevelFull', 'expectedBevelFull',
[OperatorSpecObjectMode('convert', {'target': 'MESH'})]),
MeshTest('Bevel Full Low Res', 'testBevelFullLowRes', 'expectedBevelFullLowRes',
[OperatorSpecObjectMode('convert', {'target': 'MESH'})]),
MeshTest('Bevel Half', 'testBevelHalf', 'expectedBevelHalf',
[OperatorSpecObjectMode('convert', {'target': 'MESH'})]),
MeshTest('Bevel Half Low Res', 'testBevelHalfLowRes', 'expectedBevelHalfLowRes',
[OperatorSpecObjectMode('convert', {'target': 'MESH'})]),
MeshTest('Caps None', 'testCapsNone', 'expectedCapsNone',
[OperatorSpecObjectMode('convert', {'target': 'MESH'})]),
MeshTest('Caps Object Bevel', 'testCapsObjectBevel', 'expectedCapsObjectBevel',
[OperatorSpecObjectMode('convert', {'target': 'MESH'})]),
MeshTest('Caps Profile Bevel', 'testCapsProfileBevel', 'expectedCapsProfileBevel',
[OperatorSpecObjectMode('convert', {'target': 'MESH'})]),
MeshTest('Caps Profile Bevel Half', 'testCapsProfileBevelHalf', 'expectedCapsProfileBevelHalf',
[OperatorSpecObjectMode('convert', {'target': 'MESH'})]),
MeshTest('Caps Profile Bevel Quarter', 'testCapsProfileBevelQuarter', 'expectedCapsProfileBevelQuarter',
[OperatorSpecObjectMode('convert', {'target': 'MESH'})]),
MeshTest('Caps Round Bevel', 'testCapsRoundBevel', 'expectedCapsRoundBevel',
[OperatorSpecObjectMode('convert', {'target': 'MESH'})]),
MeshTest('Caps Round Bevel Extrude', 'testCapsRoundBevelExtrude', 'expectedCapsRoundBevelExtrude',
[OperatorSpecObjectMode('convert', {'target': 'MESH'})]),
MeshTest('Caps Round Bevel Half', 'testCapsRoundBevelHalf', 'expectedCapsRoundBevelHalf',
[OperatorSpecObjectMode('convert', {'target': 'MESH'})]),
MeshTest('Caps Round Bevel Quarter', 'testCapsRoundBevelQuarter', 'expectedCapsRoundBevelQuarter',
[OperatorSpecObjectMode('convert', {'target': 'MESH'})]),
MeshTest('Extrude Back', 'testExtrudeBack', 'expectedExtrudeBack',
[OperatorSpecObjectMode('convert', {'target': 'MESH'})]),
MeshTest('Extrude Front', 'testExtrudeFront', 'expectedExtrudeFront',
[OperatorSpecObjectMode('convert', {'target': 'MESH'})]),
MeshTest('Extrude Full', 'testExtrudeFull', 'expectedExtrudeFull',
[OperatorSpecObjectMode('convert', {'target': 'MESH'})]),
MeshTest('Extrude Half', 'testExtrudeHalf', 'expectedExtrudeHalf',
[OperatorSpecObjectMode('convert', {'target': 'MESH'})]),
]
operator_test = RunTest(tests)
command = list(sys.argv)
for i, cmd in enumerate(command):
if cmd == "--run-all-tests":
operator_test.do_compare = True
operator_test.run_all_tests()
break
elif cmd == "--run-test":
name = command[i + 1]
operator_test.do_compare = False
operator_test.run_test(name)
break
if __name__ == "__main__":
main()