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
path: root/intern
diff options
context:
space:
mode:
authorLukas Tönne <lukas.toenne@gmail.com>2015-03-21 22:22:25 +0300
committerLukas Tönne <lukas.toenne@gmail.com>2015-03-26 16:13:41 +0300
commit074281708829490e050089ae4683d1f1b8ec8392 (patch)
tree1cad6dbb5dc95b5a83707acf1a531b60c34a52a5 /intern
parentd1d98c23ee1915ff732db2a5672f04da69596db7 (diff)
Basic Alembic integration in the Cycles standalone.
This adds Alembic to the standalone application version of cycles. Files can be specified as XML or Alembic, or use automatic detection based on the filename extension. Currently the Alembic reader just dumps the file structure to stdout as a test.
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/app/CMakeLists.txt23
-rw-r--r--intern/cycles/app/cycles_alembic.cpp288
-rw-r--r--intern/cycles/app/cycles_alembic.h29
-rw-r--r--intern/cycles/app/cycles_standalone.cpp54
4 files changed, 392 insertions, 2 deletions
diff --git a/intern/cycles/app/CMakeLists.txt b/intern/cycles/app/CMakeLists.txt
index b000266cac2..b9a2abf1c9a 100644
--- a/intern/cycles/app/CMakeLists.txt
+++ b/intern/cycles/app/CMakeLists.txt
@@ -96,6 +96,12 @@ macro(cycles_target_link_libraries target)
${CMAKE_DL_LIBS}
${PLATFORM_LINKLIBS}
)
+ if(WITH_ALEMBIC)
+ target_link_libraries(
+ ${target}
+ ${ALEMBIC_LIBRARIES}
+ )
+ endif()
endmacro()
# Application build targets
@@ -106,6 +112,23 @@ if(WITH_CYCLES_STANDALONE)
cycles_xml.cpp
cycles_xml.h
)
+
+ if(WITH_ALEMBIC)
+ list(APPEND SRC
+ cycles_alembic.cpp
+ cycles_alembic.h
+ )
+ add_definitions(-DWITH_ALEMBIC)
+ include_directories(
+ SYSTEM
+ ${ALEMBIC_INCLUDE_DIRS}
+ )
+ endif()
+
+ if(WITH_HDF5)
+ add_definitions(-DWITH_HDF5)
+ endif()
+
add_executable(cycles ${SRC})
cycles_target_link_libraries(cycles)
diff --git a/intern/cycles/app/cycles_alembic.cpp b/intern/cycles/app/cycles_alembic.cpp
new file mode 100644
index 00000000000..c801dd43140
--- /dev/null
+++ b/intern/cycles/app/cycles_alembic.cpp
@@ -0,0 +1,288 @@
+/*
+ * Copyright 2015 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+
+#include <sstream>
+#include <algorithm>
+#include <iterator>
+
+#include <Alembic/AbcCoreOgawa/ReadWrite.h>
+#ifdef WITH_HDF5
+#include <Alembic/AbcCoreHDF5/ReadWrite.h>
+#endif
+#include <Alembic/Abc/IArchive.h>
+#include <Alembic/Abc/IObject.h>
+#include <Alembic/Abc/ISampleSelector.h>
+#include <Alembic/Abc/ICompoundProperty.h>
+#include <Alembic/Abc/IScalarProperty.h>
+#include <Alembic/Abc/IArrayProperty.h>
+#include <Alembic/Abc/ArchiveInfo.h>
+
+#include "camera.h"
+#include "film.h"
+#include "graph.h"
+#include "integrator.h"
+#include "light.h"
+#include "mesh.h"
+#include "nodes.h"
+#include "object.h"
+#include "shader.h"
+#include "scene.h"
+
+#include "subd_mesh.h"
+#include "subd_patch.h"
+#include "subd_split.h"
+
+#include "util_debug.h"
+#include "util_foreach.h"
+#include "util_path.h"
+#include "util_transform.h"
+#include "util_xml.h"
+
+#include "cycles_alembic.h"
+
+CCL_NAMESPACE_BEGIN
+
+using namespace Alembic;
+using namespace Abc;
+
+#define ABC_SAFE_CALL_BEGIN \
+ try {
+
+#define ABC_SAFE_CALL_END \
+ } \
+ catch (Alembic::Util::Exception e) { \
+ printf("%s", e.what()); \
+ }
+
+
+/* File */
+
+static const std::string g_sep(";");
+
+static void visitProperties(std::stringstream &ss, ICompoundProperty, std::string &);
+
+template <class PROP>
+static void visitSimpleArrayProperty(std::stringstream &ss, PROP iProp, const std::string &iIndent)
+{
+ std::string ptype = "ArrayProperty ";
+ size_t asize = 0;
+
+ AbcA::ArraySamplePtr samp;
+ index_t maxSamples = iProp.getNumSamples();
+ for (index_t i = 0 ; i < maxSamples; ++i) {
+ iProp.get(samp, ISampleSelector( i ));
+ asize = samp->size();
+ };
+
+ std::string mdstring = "interpretation=";
+ mdstring += iProp.getMetaData().get("interpretation");
+
+ std::stringstream dtype;
+ dtype << "datatype=";
+ dtype << iProp.getDataType();
+
+ std::stringstream asizestr;
+ asizestr << ";arraysize=";
+ asizestr << asize;
+
+ mdstring += g_sep;
+
+ mdstring += dtype.str();
+
+ mdstring += asizestr.str();
+
+ ss << iIndent << " " << ptype << "name=" << iProp.getName()
+ << g_sep << mdstring << g_sep << "numsamps="
+ << iProp.getNumSamples() << std::endl;
+}
+
+template <class PROP>
+static void visitSimpleScalarProperty(std::stringstream &ss, PROP iProp, const std::string &iIndent)
+{
+ std::string ptype = "ScalarProperty ";
+ size_t asize = 0;
+
+ const AbcA::DataType &dt = iProp.getDataType();
+ const Alembic::Util ::uint8_t extent = dt.getExtent();
+ Alembic::Util::Dimensions dims(extent);
+ AbcA::ArraySamplePtr samp = AbcA::AllocateArraySample( dt, dims );
+ index_t maxSamples = iProp.getNumSamples();
+ for (index_t i = 0 ; i < maxSamples; ++i) {
+ iProp.get(const_cast<void*>(samp->getData()), ISampleSelector( i ));
+ asize = samp->size();
+ };
+
+ std::string mdstring = "interpretation=";
+ mdstring += iProp.getMetaData().get("interpretation");
+
+ std::stringstream dtype;
+ dtype << "datatype=";
+ dtype << dt;
+
+ std::stringstream asizestr;
+ asizestr << ";arraysize=";
+ asizestr << asize;
+
+ mdstring += g_sep;
+
+ mdstring += dtype.str();
+
+ mdstring += asizestr.str();
+
+ ss << iIndent << " " << ptype << "name=" << iProp.getName()
+ << g_sep << mdstring << g_sep << "numsamps="
+ << iProp.getNumSamples() << std::endl;
+}
+
+static void visitCompoundProperty(std::stringstream &ss, ICompoundProperty iProp, std::string &ioIndent)
+{
+ std::string oldIndent = ioIndent;
+ ioIndent += " ";
+
+ std::string interp = "schema=";
+ interp += iProp.getMetaData().get("schema");
+
+ ss << ioIndent << "CompoundProperty " << "name=" << iProp.getName()
+ << g_sep << interp << std::endl;
+
+ visitProperties(ss, iProp, ioIndent);
+
+ ioIndent = oldIndent;
+}
+
+static void visitProperties(std::stringstream &ss, ICompoundProperty iParent, std::string &ioIndent )
+{
+ std::string oldIndent = ioIndent;
+ for (size_t i = 0 ; i < iParent.getNumProperties() ; i++) {
+ PropertyHeader header = iParent.getPropertyHeader(i);
+
+ if (header.isCompound()) {
+ visitCompoundProperty(ss, ICompoundProperty(iParent, header.getName()), ioIndent);
+ }
+ else if (header.isScalar()) {
+ visitSimpleScalarProperty(ss, IScalarProperty(iParent, header.getName()), ioIndent);
+ }
+ else {
+ assert(header.isArray());
+ visitSimpleArrayProperty(ss, IArrayProperty(iParent, header.getName()), ioIndent);
+ }
+ }
+
+ ioIndent = oldIndent;
+}
+
+static void visitObject(std::stringstream &ss, IObject iObj, std::string iIndent)
+{
+ // Object has a name, a full name, some meta data,
+ // and then it has a compound property full of properties.
+ std::string path = iObj.getFullName();
+
+ if (iObj.isInstanceRoot()) {
+ if (path != "/") {
+ ss << "Object " << "name=" << path
+ << " [Instance " << iObj.instanceSourcePath() << "]"
+ << std::endl;
+ }
+ }
+ else if (iObj.isInstanceDescendant()) {
+ /* skip non-root instances to avoid repetition */
+ return;
+ }
+ else {
+ if (path != "/") {
+ ss << "Object " << "name=" << path << std::endl;
+ }
+
+ // Get the properties.
+ ICompoundProperty props = iObj.getProperties();
+ visitProperties(ss, props, iIndent);
+
+ // now the child objects
+ for (size_t i = 0 ; i < iObj.getNumChildren() ; i++) {
+ visitObject(ss, IObject(iObj, iObj.getChildHeader(i).getName()), iIndent);
+ }
+ }
+}
+
+static std::string abc_archive_info(IArchive &archive)
+{
+ std::stringstream ss;
+
+ ss << "Alembic Archive Info for "
+ << Alembic::AbcCoreAbstract::GetLibraryVersion()
+ << std::endl;;
+
+ std::string appName;
+ std::string libraryVersionString;
+ Alembic::Util::uint32_t libraryVersion;
+ std::string whenWritten;
+ std::string userDescription;
+ GetArchiveInfo(archive,
+ appName,
+ libraryVersionString,
+ libraryVersion,
+ whenWritten,
+ userDescription);
+
+ if (appName != "") {
+ ss << " file written by: " << appName << std::endl;
+ ss << " using Alembic : " << libraryVersionString << std::endl;
+ ss << " written on : " << whenWritten << std::endl;
+ ss << " user description : " << userDescription << std::endl;
+ ss << std::endl;
+ }
+ else {
+// ss << argv[1] << std::endl;
+ ss << " (file doesn't have any ArchiveInfo)"
+ << std::endl;
+ ss << std::endl;
+ }
+
+ visitObject(ss, archive.getTop(), "");
+
+ return ss.str();
+}
+
+void abc_read_ogawa_file(Scene *scene, const char *filepath)
+{
+ IArchive archive;
+ ABC_SAFE_CALL_BEGIN
+ archive = IArchive(AbcCoreOgawa::ReadArchive(), filepath, Abc::ErrorHandler::kThrowPolicy);
+ ABC_SAFE_CALL_END
+
+ if (archive) {
+ printf("%s", abc_archive_info(archive).c_str());
+ }
+}
+
+void abc_read_hdf5_file(Scene *scene, const char *filepath)
+{
+#ifdef WITH_HDF5
+ IArchive archive;
+ ABC_SAFE_CALL_BEGIN
+ archive = IArchive(AbcCoreHDF5::ReadArchive(), filepath, Abc::ErrorHandler::kThrowPolicy);
+ ABC_SAFE_CALL_END
+
+ if (archive) {
+ printf(abc_archive_info(archive));
+ }
+#endif
+}
+
+CCL_NAMESPACE_END
+
diff --git a/intern/cycles/app/cycles_alembic.h b/intern/cycles/app/cycles_alembic.h
new file mode 100644
index 00000000000..761058bdb8c
--- /dev/null
+++ b/intern/cycles/app/cycles_alembic.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2015 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CYCLES_ALEMBIC_H__
+#define __CYCLES_ALEMBIC_H__
+
+CCL_NAMESPACE_BEGIN
+
+class Scene;
+
+void abc_read_ogawa_file(Scene *scene, const char *filepath);
+void abc_read_hdf5_file(Scene *scene, const char *filepath);
+
+CCL_NAMESPACE_END
+
+#endif /* __CYCLES_XML_H__ */
diff --git a/intern/cycles/app/cycles_standalone.cpp b/intern/cycles/app/cycles_standalone.cpp
index 42c339f56e5..28fecbf863c 100644
--- a/intern/cycles/app/cycles_standalone.cpp
+++ b/intern/cycles/app/cycles_standalone.cpp
@@ -37,13 +37,23 @@
#endif
#include "cycles_xml.h"
+#ifdef WITH_ALEMBIC
+#include "cycles_alembic.h"
+#endif
CCL_NAMESPACE_BEGIN
+enum FileType {
+ FILETYPE_XML = 0,
+ FILETYPE_ABC_HDF5,
+ FILETYPE_ABC_OGAWA,
+};
+
struct Options {
Session *session;
Scene *scene;
string filepath;
+ FileType filetype;
int width, height;
SceneParams scene_params;
SessionParams session_params;
@@ -120,8 +130,22 @@ static void scene_init()
{
options.scene = new Scene(options.scene_params, options.session_params.device);
- /* Read XML */
- xml_read_file(options.scene, options.filepath.c_str());
+ /* Read file */
+ switch (options.filetype) {
+ case FILETYPE_XML:
+ xml_read_file(options.scene, options.filepath.c_str());
+ break;
+#ifdef WITH_ALEMBIC
+ case FILETYPE_ABC_OGAWA:
+ abc_read_ogawa_file(options.scene, options.filepath.c_str());
+ break;
+ case FILETYPE_ABC_HDF5:
+ abc_read_hdf5_file(options.scene, options.filepath.c_str());
+ break;
+#endif
+ default:
+ return;
+ }
/* Camera width/height override? */
if (!(options.width == 0 || options.height == 0)) {
@@ -335,6 +359,16 @@ static void options_parse(int argc, const char **argv)
/* shading system */
string ssname = "svm";
+ /* input file type */
+ string filetypes = "auto, xml";
+#ifdef WITH_ALEMBIC
+ filetypes += ", alembic_ogawa";
+#ifdef WITH_HDF5
+ filetypes += ", alembic_hdf5";
+#endif
+#endif
+ string filetype = "auto";
+
/* parse options */
ArgParse ap;
bool help = false, debug = false;
@@ -350,6 +384,7 @@ static void options_parse(int argc, const char **argv)
"--quiet", &options.quiet, "In background mode, don't print progress messages",
"--samples %d", &options.session_params.samples, "Number of samples to render",
"--output %s", &options.session_params.output_path, "File path to write output image",
+ "--filetype %s", &filetype, ("File type: " + filetypes).c_str(),
"--threads %d", &options.session_params.threads, "CPU Rendering Threads",
"--width %d", &options.width, "Window width in pixel",
"--height %d", &options.height, "Window height in pixel",
@@ -394,6 +429,21 @@ static void options_parse(int argc, const char **argv)
else if(ssname == "svm")
options.scene_params.shadingsystem = SHADINGSYSTEM_SVM;
+ if(filetype == "auto") {
+ string extension = options.filepath.substr(options.filepath.find_last_of(".") + 1);
+
+ if (extension == "xml")
+ options.filetype = FILETYPE_XML;
+ else if (extension == "abc")
+ options.filetype = FILETYPE_ABC_OGAWA;
+ }
+ else if(filetype == "xml")
+ options.filetype = FILETYPE_XML;
+ else if(filetype == "alembic_ogawa")
+ options.filetype = FILETYPE_ABC_OGAWA;
+ else if(filetype == "alembic_hdf5")
+ options.filetype = FILETYPE_ABC_HDF5;
+
#ifndef WITH_CYCLES_STANDALONE_GUI
options.session_params.background = true;
#endif