Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/depsgraph/CMakeLists.txt2
-rw-r--r--source/blender/depsgraph/DEG_depsgraph_build.h6
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_all_objects.cc80
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_all_objects.h44
-rw-r--r--source/blender/depsgraph/intern/depsgraph_build.cc10
-rw-r--r--source/blender/io/alembic/exporter/abc_export_capi.cc12
-rw-r--r--source/blender/io/alembic/exporter/abc_writer_abstract.cc16
-rw-r--r--source/blender/io/alembic/exporter/abc_writer_abstract.h5
-rw-r--r--source/blender/io/alembic/exporter/abc_writer_mesh.cc5
-rw-r--r--source/blender/io/alembic/exporter/abc_writer_transform.cc2
-rw-r--r--source/blender/io/common/intern/abstract_hierarchy_iterator.cc4
-rw-r--r--tests/python/alembic_export_tests.py70
12 files changed, 239 insertions, 17 deletions
diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt
index f9a6bde442d..e0916491edb 100644
--- a/source/blender/depsgraph/CMakeLists.txt
+++ b/source/blender/depsgraph/CMakeLists.txt
@@ -55,6 +55,7 @@ set(SRC
intern/builder/deg_builder_rna.cc
intern/builder/deg_builder_transitive.cc
intern/builder/pipeline.cc
+ intern/builder/pipeline_all_objects.cc
intern/builder/pipeline_compositor.cc
intern/builder/pipeline_from_ids.cc
intern/builder/pipeline_render.cc
@@ -116,6 +117,7 @@ set(SRC
intern/builder/deg_builder_rna.h
intern/builder/deg_builder_transitive.h
intern/builder/pipeline.h
+ intern/builder/pipeline_all_objects.h
intern/builder/pipeline_compositor.h
intern/builder/pipeline_from_ids.h
intern/builder/pipeline_render.h
diff --git a/source/blender/depsgraph/DEG_depsgraph_build.h b/source/blender/depsgraph/DEG_depsgraph_build.h
index 50f22b00028..dd52c97e03f 100644
--- a/source/blender/depsgraph/DEG_depsgraph_build.h
+++ b/source/blender/depsgraph/DEG_depsgraph_build.h
@@ -56,6 +56,12 @@ void DEG_graph_build_from_view_layer(struct Depsgraph *graph,
struct Scene *scene,
struct ViewLayer *view_layer);
+/* Build depsgraph for all objects (so also invisible ones) in the given view layer. */
+void DEG_graph_build_for_all_objects(struct Depsgraph *graph,
+ struct Main *bmain,
+ struct Scene *scene,
+ struct ViewLayer *view_layer);
+
/* Special version of builder which produces dependency graph suitable for the render pipeline.
* It will contain sequencer and compositor (if needed) and all their dependencies. */
void DEG_graph_build_for_render_pipeline(struct Depsgraph *graph,
diff --git a/source/blender/depsgraph/intern/builder/pipeline_all_objects.cc b/source/blender/depsgraph/intern/builder/pipeline_all_objects.cc
new file mode 100644
index 00000000000..c926ff7541a
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/pipeline_all_objects.cc
@@ -0,0 +1,80 @@
+/*
+ * 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) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "pipeline_all_objects.h"
+
+#include "intern/builder/deg_builder_nodes.h"
+#include "intern/builder/deg_builder_relations.h"
+#include "intern/depsgraph.h"
+
+#include "DNA_layer_types.h"
+
+namespace blender {
+namespace deg {
+
+namespace {
+
+class AllObjectsNodeBuilder : public DepsgraphNodeBuilder {
+ public:
+ AllObjectsNodeBuilder(Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache)
+ : DepsgraphNodeBuilder(bmain, graph, cache)
+ {
+ }
+
+ virtual bool need_pull_base_into_graph(Base * /*base*/) override
+ {
+ return true;
+ }
+};
+
+class AllObjectsRelationBuilder : public DepsgraphRelationBuilder {
+ public:
+ AllObjectsRelationBuilder(Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache)
+ : DepsgraphRelationBuilder(bmain, graph, cache)
+ {
+ }
+
+ virtual bool need_pull_base_into_graph(Base * /*base*/) override
+ {
+ return true;
+ }
+};
+
+} // namespace
+
+AllObjectsBuilderPipeline::AllObjectsBuilderPipeline(::Depsgraph *graph,
+ Main *bmain,
+ Scene *scene,
+ ViewLayer *view_layer)
+ : ViewLayerBuilderPipeline(graph, bmain, scene, view_layer)
+{
+}
+
+unique_ptr<DepsgraphNodeBuilder> AllObjectsBuilderPipeline::construct_node_builder()
+{
+ return std::make_unique<AllObjectsNodeBuilder>(bmain_, deg_graph_, &builder_cache_);
+}
+
+unique_ptr<DepsgraphRelationBuilder> AllObjectsBuilderPipeline::construct_relation_builder()
+{
+ return std::make_unique<AllObjectsRelationBuilder>(bmain_, deg_graph_, &builder_cache_);
+}
+
+} // namespace deg
+} // namespace blender
diff --git a/source/blender/depsgraph/intern/builder/pipeline_all_objects.h b/source/blender/depsgraph/intern/builder/pipeline_all_objects.h
new file mode 100644
index 00000000000..94f00ae840b
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/pipeline_all_objects.h
@@ -0,0 +1,44 @@
+/*
+ * 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) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#pragma once
+
+#include "pipeline_view_layer.h"
+
+namespace blender {
+namespace deg {
+
+/* Builds a dependency graph that contains all objects in the view layer.
+ * This is contrary to the regular ViewLayerBuilderPipeline, which is limited to visible objects
+ * (and their dependencies). */
+class AllObjectsBuilderPipeline : public ViewLayerBuilderPipeline {
+ public:
+ AllObjectsBuilderPipeline(::Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer);
+
+ protected:
+ virtual unique_ptr<DepsgraphNodeBuilder> construct_node_builder() override;
+ virtual unique_ptr<DepsgraphRelationBuilder> construct_relation_builder() override;
+};
+
+} // namespace deg
+} // namespace blender
diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc
index fb933cb38f3..230c59bd651 100644
--- a/source/blender/depsgraph/intern/depsgraph_build.cc
+++ b/source/blender/depsgraph/intern/depsgraph_build.cc
@@ -44,6 +44,7 @@
#include "DEG_depsgraph_debug.h"
#include "builder/deg_builder_relations.h"
+#include "builder/pipeline_all_objects.h"
#include "builder/pipeline_compositor.h"
#include "builder/pipeline_from_ids.h"
#include "builder/pipeline_render.h"
@@ -218,6 +219,15 @@ void DEG_graph_build_from_view_layer(Depsgraph *graph,
builder.build();
}
+void DEG_graph_build_for_all_objects(struct Depsgraph *graph,
+ struct Main *bmain,
+ struct Scene *scene,
+ struct ViewLayer *view_layer)
+{
+ deg::AllObjectsBuilderPipeline builder(graph, bmain, scene, view_layer);
+ builder.build();
+}
+
void DEG_graph_build_for_render_pipeline(Depsgraph *graph,
Main *bmain,
Scene *scene,
diff --git a/source/blender/io/alembic/exporter/abc_export_capi.cc b/source/blender/io/alembic/exporter/abc_export_capi.cc
index 8c5f3d89870..c4966a965eb 100644
--- a/source/blender/io/alembic/exporter/abc_export_capi.cc
+++ b/source/blender/io/alembic/exporter/abc_export_capi.cc
@@ -67,11 +67,17 @@ namespace io {
namespace alembic {
// Construct the depsgraph for exporting.
-static void build_depsgraph(Depsgraph *depsgraph, Main *bmain)
+static void build_depsgraph(Depsgraph *depsgraph, Main *bmain, const bool visible_objects_only)
{
Scene *scene = DEG_get_input_scene(depsgraph);
ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph);
- DEG_graph_build_from_view_layer(depsgraph, bmain, scene, view_layer);
+
+ if (visible_objects_only) {
+ DEG_graph_build_from_view_layer(depsgraph, bmain, scene, view_layer);
+ }
+ else {
+ DEG_graph_build_for_all_objects(depsgraph, bmain, scene, view_layer);
+ }
}
static void export_startjob(void *customdata,
@@ -91,7 +97,7 @@ static void export_startjob(void *customdata,
*progress = 0.0f;
*do_update = true;
- build_depsgraph(data->depsgraph, data->bmain);
+ build_depsgraph(data->depsgraph, data->bmain, data->params.visible_objects_only);
SubdivModifierDisabler subdiv_disabler(data->depsgraph);
if (!data->params.apply_subdiv) {
subdiv_disabler.disable_modifiers();
diff --git a/source/blender/io/alembic/exporter/abc_writer_abstract.cc b/source/blender/io/alembic/exporter/abc_writer_abstract.cc
index e43b394e27f..84527a12e85 100644
--- a/source/blender/io/alembic/exporter/abc_writer_abstract.cc
+++ b/source/blender/io/alembic/exporter/abc_writer_abstract.cc
@@ -25,6 +25,10 @@
#include "DNA_modifier_types.h"
+#include "DEG_depsgraph.h"
+
+#include <Alembic/AbcGeom/Visibility.h>
+
#include "CLG_log.h"
static CLG_LogRef LOG = {"io.alembic"};
@@ -96,6 +100,18 @@ void ABCAbstractWriter::update_bounding_box(Object *object)
bounding_box_.max.z = -bb->vec[0][1];
}
+void ABCAbstractWriter::write_visibility(const HierarchyContext &context)
+{
+ const bool is_visible = context.is_object_visible(DAG_EVAL_RENDER);
+ Alembic::Abc::OObject abc_object = get_alembic_object();
+
+ if (!abc_visibility_.valid()) {
+ abc_visibility_ = Alembic::AbcGeom::CreateVisibilityProperty(abc_object, timesample_index_);
+ }
+ abc_visibility_.set(is_visible ? Alembic::AbcGeom::kVisibilityVisible :
+ Alembic::AbcGeom::kVisibilityHidden);
+}
+
} // namespace alembic
} // namespace io
} // namespace blender
diff --git a/source/blender/io/alembic/exporter/abc_writer_abstract.h b/source/blender/io/alembic/exporter/abc_writer_abstract.h
index a83373a567a..f46409b7902 100644
--- a/source/blender/io/alembic/exporter/abc_writer_abstract.h
+++ b/source/blender/io/alembic/exporter/abc_writer_abstract.h
@@ -43,6 +43,9 @@ class ABCAbstractWriter : public AbstractHierarchyWriter {
uint32_t timesample_index_;
Imath::Box3d bounding_box_;
+ /* Visibility of this writer's data in Alembic. */
+ Alembic::Abc::OCharProperty abc_visibility_;
+
public:
explicit ABCAbstractWriter(const ABCWriterConstructorArgs &args);
virtual ~ABCAbstractWriter();
@@ -70,6 +73,8 @@ class ABCAbstractWriter : public AbstractHierarchyWriter {
virtual void do_write(HierarchyContext &context) = 0;
virtual void update_bounding_box(Object *object);
+
+ void write_visibility(const HierarchyContext &context);
};
} // namespace alembic
diff --git a/source/blender/io/alembic/exporter/abc_writer_mesh.cc b/source/blender/io/alembic/exporter/abc_writer_mesh.cc
index 5c005164bcc..517f0212712 100644
--- a/source/blender/io/alembic/exporter/abc_writer_mesh.cc
+++ b/source/blender/io/alembic/exporter/abc_writer_mesh.cc
@@ -159,7 +159,10 @@ ModifierData *ABCGenericMeshWriter::get_liquid_sim_modifier(Scene *scene, Object
bool ABCGenericMeshWriter::is_supported(const HierarchyContext *context) const
{
- return context->is_object_visible(DAG_EVAL_RENDER);
+ if (args_.export_params->visible_objects_only) {
+ return context->is_object_visible(DAG_EVAL_RENDER);
+ }
+ return true;
}
void ABCGenericMeshWriter::do_write(HierarchyContext &context)
diff --git a/source/blender/io/alembic/exporter/abc_writer_transform.cc b/source/blender/io/alembic/exporter/abc_writer_transform.cc
index 39af99c142c..7694066a13d 100644
--- a/source/blender/io/alembic/exporter/abc_writer_transform.cc
+++ b/source/blender/io/alembic/exporter/abc_writer_transform.cc
@@ -92,6 +92,8 @@ void ABCTransformWriter::do_write(HierarchyContext &context)
xform_sample.setMatrix(convert_matrix_datatype(parent_relative_matrix));
xform_sample.setInheritsXforms(true);
abc_xform_schema_.set(xform_sample);
+
+ write_visibility(context);
}
const OObject ABCTransformWriter::get_alembic_object() const
diff --git a/source/blender/io/common/intern/abstract_hierarchy_iterator.cc b/source/blender/io/common/intern/abstract_hierarchy_iterator.cc
index 93e7e677118..d825625cafc 100644
--- a/source/blender/io/common/intern/abstract_hierarchy_iterator.cc
+++ b/source/blender/io/common/intern/abstract_hierarchy_iterator.cc
@@ -80,7 +80,7 @@ void HierarchyContext::mark_as_not_instanced()
bool HierarchyContext::is_object_visible(const enum eEvaluationMode evaluation_mode) const
{
- bool is_dupli = duplicator != nullptr;
+ const bool is_dupli = duplicator != nullptr;
int base_flag;
if (is_dupli) {
@@ -92,7 +92,7 @@ bool HierarchyContext::is_object_visible(const enum eEvaluationMode evaluation_m
object->base_flag = duplicator->base_flag | BASE_FROM_DUPLI;
}
- int visibility = BKE_object_visibility(object, evaluation_mode);
+ const int visibility = BKE_object_visibility(object, evaluation_mode);
if (is_dupli) {
object->base_flag = base_flag;
diff --git a/tests/python/alembic_export_tests.py b/tests/python/alembic_export_tests.py
index 800e450776c..cacd2f2dd0e 100644
--- a/tests/python/alembic_export_tests.py
+++ b/tests/python/alembic_export_tests.py
@@ -32,6 +32,7 @@ import pathlib
import subprocess
import sys
import unittest
+from typing import Tuple
from modules.test_utils import (
with_tempdir,
@@ -59,19 +60,13 @@ class AbstractAlembicTest(AbstractBlenderRunnerTest):
# 'abcls' array notation, like "name[16]"
cls.abcls_array = re.compile(r'^(?P<name>[^\[]+)(\[(?P<arraysize>\d+)\])?$')
- def abcprop(self, filepath: pathlib.Path, proppath: str) -> dict:
- """Uses abcls to obtain compound property values from an Alembic object.
-
- A dict of subproperties is returned, where the values are Python values.
+ def abcls(self, *arguments) -> Tuple[int, str]:
+ """Uses abcls and return its output.
- The Python bindings for Alembic are old, and only compatible with Python 2.x,
- so that's why we can't use them here, and have to rely on other tooling.
+ :return: tuple (process exit status code, stdout)
"""
- import collections
- abcls = self.alembic_root / 'bin' / 'abcls'
-
- command = (str(abcls), '-vl', '%s%s' % (filepath, proppath))
+ command = (self.alembic_root / 'bin' / 'abcls', *arguments)
proc = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
timeout=30)
@@ -84,7 +79,25 @@ class AbstractAlembicTest(AbstractBlenderRunnerTest):
output = output.replace('\r\n', '\n').replace('\r', '\n')
if proc.returncode:
- raise AbcPropError('Error %d running %s:\n%s' % (proc.returncode, ' '.join(command), output))
+ str_command = " ".join(str(c) for c in command)
+ print(f'command {str_command} failed with status {proc.returncode}')
+
+ return (proc.returncode, output)
+
+ def abcprop(self, filepath: pathlib.Path, proppath: str) -> dict:
+ """Uses abcls to obtain compound property values from an Alembic object.
+
+ A dict of subproperties is returned, where the values are Python values.
+
+ The Python bindings for Alembic are old, and only compatible with Python 2.x,
+ so that's why we can't use them here, and have to rely on other tooling.
+ """
+ import collections
+
+ command = ('-vl', '%s%s' % (filepath, proppath))
+ returncode, output = self.abcls(*command)
+ if returncode:
+ raise AbcPropError('Error %d running abcls:\n%s' % (returncode, output))
# Mapping from value type to callable that can convert a string to Python values.
converters = {
@@ -536,6 +549,41 @@ class LongNamesExportTest(AbstractAlembicTest):
self.assertIn('.faceCounts', abcprop)
+class InvisibleObjectExportTest(AbstractAlembicTest):
+ """Export an object which is invisible.
+
+ This test only tests a small subset of the functionality that is required to
+ export invisible objects. It just tests that the visibility property is
+ written, and that it has the correct initial value. This is a limitation
+ caused by these tests relying on `abcls`.
+ """
+
+ @with_tempdir
+ def test_hierarchical_export(self, tempdir: pathlib.Path):
+ abc = tempdir / 'visibility.abc'
+ script = "import bpy; bpy.ops.wm.alembic_export(filepath='%s', start=1, end=2, " \
+ "renderable_only=False, visible_objects_only=False)" % abc.as_posix()
+ self.run_blender('visibility.blend', script)
+
+ def test(cube_name: str, expect_visible: bool):
+ returncode, output = self.abcls('-va', f'{abc}/{cube_name}')
+ if returncode:
+ self.fail(f"abcls failed: {output}")
+ output = output.strip()
+ self.assertEqual(f'Cube .xform visible {int(expect_visible)}', output)
+
+ # This cube is always visible.
+ test('VisibleCube', True)
+
+ # This cube is never visible, and thus will not be pulled into the
+ # depsgraph by the standard builder, only by the all-objects builder.
+ test('InvisibleCube', False)
+
+ # This cube has animated visibility, and thus will be pulled into the
+ # depsgraph by the standard builder as well as the all-objects builder.
+ test('InvisibleAnimatedCube', False)
+
+
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--blender', required=True)