Merge branch 'master' into blender2.8
This commit is contained in:
commit
4233ccfb6c
|
@ -178,6 +178,10 @@ class DATA_PT_pose_library(ArmatureButtonsPanel, Panel):
|
|||
layout.template_ID(ob, "pose_library", new="poselib.new", unlink="poselib.unlink")
|
||||
|
||||
if poselib:
|
||||
# warning about poselib being in an invalid state
|
||||
if len(poselib.fcurves) > 0 and len(poselib.pose_markers) == 0:
|
||||
layout.label(icon='ERROR', text="Error: Potentially corrupt library, run 'Sanitize' operator to fix")
|
||||
|
||||
# list of poses in pose library
|
||||
row = layout.row()
|
||||
row.template_list("UI_UL_list", "pose_markers", poselib, "pose_markers",
|
||||
|
|
|
@ -139,6 +139,38 @@ AbcObjectReader::AbcObjectReader(const IObject &object, ImportSettings &settings
|
|||
else {
|
||||
m_object_name = m_data_name = parts[parts.size() - 1];
|
||||
}
|
||||
|
||||
determine_inherits_xform();
|
||||
}
|
||||
|
||||
/* Determine whether we can inherit our parent's XForm */
|
||||
void AbcObjectReader::determine_inherits_xform()
|
||||
{
|
||||
m_inherits_xform = false;
|
||||
|
||||
IXform ixform = xform();
|
||||
if (!ixform) {
|
||||
return;
|
||||
}
|
||||
|
||||
const IXformSchema & schema(ixform.getSchema());
|
||||
if (!schema.valid()) {
|
||||
std::cerr << "Alembic object " << ixform.getFullName()
|
||||
<< " has an invalid schema." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
m_inherits_xform = schema.getInheritsXforms();
|
||||
|
||||
IObject ixform_parent = ixform.getParent();
|
||||
if (!ixform_parent.getParent()) {
|
||||
/* The archive top object certainly is not a transform itself, so handle
|
||||
* it as "no parent". */
|
||||
m_inherits_xform = false;
|
||||
}
|
||||
else {
|
||||
m_inherits_xform = ixform_parent && m_inherits_xform;
|
||||
}
|
||||
}
|
||||
|
||||
AbcObjectReader::~AbcObjectReader()
|
||||
|
@ -285,32 +317,10 @@ void AbcObjectReader::read_matrix(float r_mat[4][4], const float time,
|
|||
return;
|
||||
}
|
||||
|
||||
bool has_alembic_parent;
|
||||
IObject ixform_parent = ixform.getParent();
|
||||
if (!ixform_parent.getParent()) {
|
||||
/* The archive top object certainly is not a transform itself, so handle
|
||||
* it as "no parent". */
|
||||
has_alembic_parent = false;
|
||||
}
|
||||
else {
|
||||
has_alembic_parent = ixform_parent && schema.getInheritsXforms();
|
||||
|
||||
if (has_alembic_parent && m_object->parent == NULL) {
|
||||
/* TODO Sybren: This happened in some files. I think I solved it,
|
||||
* but I'll leave this check in here anyway until we've tested it
|
||||
* more thoroughly. Better than crashing on a null parent anyway. */
|
||||
std::cerr << "Alembic object " << m_iobject.getFullName()
|
||||
<< " with transform " << ixform.getFullName()
|
||||
<< " has an Alembic parent but no parent Blender object."
|
||||
<< std::endl;
|
||||
has_alembic_parent = false;
|
||||
}
|
||||
}
|
||||
|
||||
const Imath::M44d matrix = get_matrix(schema, time);
|
||||
convert_matrix(matrix, m_object, r_mat);
|
||||
|
||||
if (has_alembic_parent) {
|
||||
if (m_inherits_xform) {
|
||||
/* In this case, the matrix in Alembic is in local coordinates, so
|
||||
* convert to world matrix. To prevent us from reading and accumulating
|
||||
* all parent matrices in the Alembic file, we assume that the Blender
|
||||
|
|
|
@ -143,6 +143,8 @@ protected:
|
|||
* modifiers and/or constraints. */
|
||||
int m_refcount;
|
||||
|
||||
bool m_inherits_xform;
|
||||
|
||||
public:
|
||||
AbcObjectReader *parent_reader;
|
||||
|
||||
|
@ -167,6 +169,7 @@ public:
|
|||
const std::string & name() const { return m_name; }
|
||||
const std::string & object_name() const { return m_object_name; }
|
||||
const std::string & data_name() const { return m_data_name; }
|
||||
bool inherits_xform() const { return m_inherits_xform; }
|
||||
|
||||
virtual bool valid() const = 0;
|
||||
virtual bool accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
|
||||
|
@ -194,6 +197,9 @@ public:
|
|||
|
||||
void read_matrix(float r_mat[4][4], const float time,
|
||||
const float scale, bool &is_constant);
|
||||
|
||||
protected:
|
||||
void determine_inherits_xform();
|
||||
};
|
||||
|
||||
Imath::M44d get_matrix(const Alembic::AbcGeom::IXformSchema &schema, const float time);
|
||||
|
|
|
@ -779,7 +779,7 @@ static void import_startjob(void *user_data, short *stop, short *do_update, floa
|
|||
const AbcObjectReader *parent_reader = reader->parent_reader;
|
||||
Object *ob = reader->object();
|
||||
|
||||
if (parent_reader == NULL) {
|
||||
if (parent_reader == NULL || !reader->inherits_xform()) {
|
||||
ob->parent = NULL;
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -329,7 +329,7 @@ static int poselib_sanitize_exec(bContext *C, wmOperator *op)
|
|||
/* add pose to poselib */
|
||||
marker = MEM_callocN(sizeof(TimeMarker), "ActionMarker");
|
||||
|
||||
BLI_strncpy(marker->name, "Pose", sizeof(marker->name));
|
||||
BLI_snprintf(marker->name, sizeof(marker->name), "F%d Pose", (int)ak->cfra);
|
||||
|
||||
marker->frame = (int)ak->cfra;
|
||||
marker->flag = -1;
|
||||
|
|
|
@ -767,6 +767,38 @@ static void rna_FModifierStepped_end_frame_range(PointerRNA *ptr, float *min, fl
|
|||
*max = MAXFRAMEF;
|
||||
}
|
||||
|
||||
static void rna_FModifierStepped_frame_start_set(PointerRNA *ptr, float value)
|
||||
{
|
||||
FModifier *fcm = (FModifier *)ptr->data;
|
||||
FMod_Stepped *data = fcm->data;
|
||||
|
||||
float prop_clamp_min = -FLT_MAX, prop_clamp_max = FLT_MAX, prop_soft_min, prop_soft_max;
|
||||
rna_FModifierStepped_start_frame_range(ptr, &prop_clamp_min, &prop_clamp_max, &prop_soft_min, &prop_soft_max);
|
||||
value = CLAMPIS(value, prop_clamp_min, prop_clamp_max);
|
||||
|
||||
/* Need to set both step-data's start/end and the start/end on the base-data,
|
||||
* or else Restrict-Range doesn't work due to RNA-property shadowing (T52009)
|
||||
*/
|
||||
data->start_frame = value;
|
||||
fcm->sfra = value;
|
||||
}
|
||||
|
||||
static void rna_FModifierStepped_frame_end_set(PointerRNA *ptr, float value)
|
||||
{
|
||||
FModifier *fcm = (FModifier *)ptr->data;
|
||||
FMod_Stepped *data = fcm->data;
|
||||
|
||||
float prop_clamp_min = -FLT_MAX, prop_clamp_max = FLT_MAX, prop_soft_min, prop_soft_max;
|
||||
rna_FModifierStepped_end_frame_range(ptr, &prop_clamp_min, &prop_clamp_max, &prop_soft_min, &prop_soft_max);
|
||||
value = CLAMPIS(value, prop_clamp_min, prop_clamp_max);
|
||||
|
||||
/* Need to set both step-data's start/end and the start/end on the base-data,
|
||||
* or else Restrict-Range doesn't work due to RNA-property shadowing (T52009)
|
||||
*/
|
||||
data->end_frame = value;
|
||||
fcm->efra = value;
|
||||
}
|
||||
|
||||
static BezTriple *rna_FKeyframe_points_insert(FCurve *fcu, float frame, float value, int keyframe_type, int flag)
|
||||
{
|
||||
int index = insert_vert_fcurve(fcu, frame, value, (char)keyframe_type, flag | INSERTKEY_NO_USERPREF);
|
||||
|
@ -1286,13 +1318,13 @@ static void rna_def_fmodifier_stepped(BlenderRNA *brna)
|
|||
|
||||
prop = RNA_def_property(srna, "frame_start", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "start_frame");
|
||||
RNA_def_property_float_funcs(prop, NULL, NULL, "rna_FModifierStepped_start_frame_range");
|
||||
RNA_def_property_float_funcs(prop, NULL, "rna_FModifierStepped_frame_start_set", "rna_FModifierStepped_start_frame_range");
|
||||
RNA_def_property_ui_text(prop, "Start Frame", "Frame that modifier's influence starts (if applicable)");
|
||||
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "frame_end", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "end_frame");
|
||||
RNA_def_property_float_funcs(prop, NULL, NULL, "rna_FModifierStepped_end_frame_range");
|
||||
RNA_def_property_float_funcs(prop, NULL, "rna_FModifierStepped_frame_end_set", "rna_FModifierStepped_end_frame_range");
|
||||
RNA_def_property_ui_text(prop, "End Frame", "Frame that modifier's influence ends (if applicable)");
|
||||
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
|
||||
}
|
||||
|
|
|
@ -658,7 +658,10 @@ static void rna_def_nlastrip(BlenderRNA *brna)
|
|||
prop = RNA_def_property(srna, "influence", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_range(prop, 0.0f, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Influence", "Amount the strip contributes to the current result");
|
||||
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update");
|
||||
/* XXX: Update temporarily disabled so that the property can be edited at all!
|
||||
* Even autokey only applies after the curves have been re-evaluated, causing the unkeyed values to be lost
|
||||
*/
|
||||
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, /*"rna_NlaStrip_update"*/ NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "strip_time", PROP_FLOAT, PROP_TIME);
|
||||
RNA_def_property_ui_text(prop, "Strip Time", "Frame of referenced Action to evaluate");
|
||||
|
|
|
@ -75,6 +75,39 @@ class SimpleImportTest(AbstractAlembicTest):
|
|||
self.assertEqual(objects['Cube_003'], objects['Cube_005'].parent)
|
||||
self.assertEqual(objects['Cube_003'], objects['Cube_006'].parent)
|
||||
|
||||
def test_inherit_or_not(self):
|
||||
res = bpy.ops.wm.alembic_import(
|
||||
filepath=str(self.testdir / "T52022-inheritance.abc"),
|
||||
as_background_job=False)
|
||||
self.assertEqual({'FINISHED'}, res)
|
||||
|
||||
# The objects should be linked to scene_collection in Blender 2.8,
|
||||
# and to scene in Blender 2.7x.
|
||||
objects = bpy.context.scene.objects
|
||||
|
||||
# ABC parent is top-level object, which translates to nothing in Blender
|
||||
self.assertIsNone(objects['locator1'].parent)
|
||||
|
||||
# ABC parent is locator1, but locator2 has "inherits Xforms" = false, which
|
||||
# translates to "no parent" in Blender.
|
||||
self.assertIsNone(objects['locator2'].parent)
|
||||
|
||||
# Shouldn't have inherited the ABC parent's transform.
|
||||
x, y, z = objects['locator2'].matrix_world.to_translation()
|
||||
self.assertAlmostEqual(0, x)
|
||||
self.assertAlmostEqual(0, y)
|
||||
self.assertAlmostEqual(2, z)
|
||||
|
||||
# ABC parent is inherited and translates to normal parent in Blender.
|
||||
self.assertEqual(objects['locator2'], objects['locatorShape2'].parent)
|
||||
|
||||
# Should have inherited its ABC parent's transform.
|
||||
x, y, z = objects['locatorShape2'].matrix_world.to_translation()
|
||||
self.assertAlmostEqual(0, x)
|
||||
self.assertAlmostEqual(0, y)
|
||||
self.assertAlmostEqual(2, z)
|
||||
|
||||
|
||||
def test_select_after_import(self):
|
||||
# Add a sphere, so that there is something in the scene, selected, and active,
|
||||
# before we do the Alembic import.
|
||||
|
|
Loading…
Reference in New Issue