Cycles: experimental OSL ptex reading code.
authorBrecht Van Lommel <brechtvanlommel@gmail.com>
Thu, 28 Nov 2013 00:38:23 +0000 (01:38 +0100)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Thu, 28 Nov 2013 01:11:42 +0000 (02:11 +0100)
This code can't actually be enabled for building and is incomplete, but it's
here because we know we want to support this at some point and there's not much
reason to have it in a separate branch if a simple #ifdef can disable it.

intern/cycles/CMakeLists.txt
intern/cycles/kernel/osl/osl_services.cpp
intern/cycles/kernel/osl/osl_services.h
intern/cycles/render/nodes.cpp
intern/cycles/render/nodes.h
intern/cycles/util/util_string.cpp
intern/cycles/util/util_string.h

index 9b84f882046240332594a1e3ca5822922fae87af..44b0ba808cfe249d4be5956cc809761aa6861b40 100644 (file)
@@ -62,6 +62,10 @@ if(WITH_CYCLES_NETWORK)
        add_definitions(-DWITH_NETWORK)
 endif()
 
+if(WITH_CYCLES_PTEX)
+       add_definitions(-DWITH_PTEX)
+endif()
+
 if(WITH_CYCLES_OSL)
        add_definitions(-DWITH_OSL)
        add_definitions(-DOSL_STATIC_LIBRARY)
index 309f5ded96daa393b63687e31b7ad7d592d3dd65..d7d3301c0b0b1fac4a451f4b98f73dcfa964bee7 100644 (file)
 #include "kernel_camera.h"
 #include "kernel_shader.h"
 
+#ifdef WITH_PTEX
+#include <Ptexture.h>
+#endif
+
 CCL_NAMESPACE_BEGIN
 
 /* RenderServices implementation */
@@ -98,10 +102,18 @@ OSLRenderServices::OSLRenderServices()
 {
        kernel_globals = NULL;
        osl_ts = NULL;
+
+#ifdef WITH_PTEX
+       size_t maxmem = 16384 * 1024;
+       ptex_cache = PtexCache::create(0, maxmem);
+#endif
 }
 
 OSLRenderServices::~OSLRenderServices()
 {
+#ifdef WITH_PTEX
+       ptex_cache->release();
+#endif
 }
 
 void OSLRenderServices::thread_init(KernelGlobals *kernel_globals_, OSL::TextureSystem *osl_ts_)
@@ -776,6 +788,45 @@ bool OSLRenderServices::texture(ustring filename, TextureOpt &options,
        OSL::TextureSystem *ts = osl_ts;
        ShaderData *sd = (ShaderData *)(sg->renderstate);
        KernelGlobals *kg = sd->osl_globals;
+
+#ifdef WITH_PTEX
+       /* todo: this is just a quick hack, only works with particular files and options */
+       if(string_endswith(filename.string(), ".ptx")) {
+               float2 uv;
+               int faceid;
+
+               if(!primitive_ptex(kg, sd, &uv, &faceid))
+                       return false;
+
+               float u = uv.x;
+               float v = uv.y;
+               float dudx = 0.0f;
+               float dvdx = 0.0f;
+               float dudy = 0.0f;
+               float dvdy = 0.0f;
+
+               Ptex::String error;
+               PtexPtr<PtexTexture> r(ptex_cache->get(filename.c_str(), error));
+
+               if(!r) {
+                       //std::cerr << error.c_str() << std::endl;
+                       return false;
+               }
+
+               bool mipmaplerp = false;
+               float sharpness = 1.0f;
+               PtexFilter::Options opts(PtexFilter::f_bicubic, mipmaplerp, sharpness);
+               PtexPtr<PtexFilter> f(PtexFilter::getFilter(r, opts));
+
+               f->eval(result, options.firstchannel, options.nchannels, faceid, u, v, dudx, dvdx, dudy, dvdy);
+
+               for(int c = r->numChannels(); c < options.nchannels; c++)
+                       result[c] = result[0];
+
+               return true;
+       }
+#endif
+
        OSLThreadData *tdata = kg->osl_tdata;
        OIIO::TextureSystem::Perthread *thread_info = tdata->oiio_thread_info;
 
index f62895047b35d30cd2c8ed8ad567b77009c5cb05..21609621b1d82bd70a87d9334aeb1b0ad60cba1d 100644 (file)
 #include <OSL/oslexec.h>
 #include <OSL/oslclosure.h>
 
+#ifdef WITH_PTEX
+class PtexCache;
+#endif
+
 CCL_NAMESPACE_BEGIN
 
 class Object;
@@ -148,6 +152,9 @@ public:
 private:
        KernelGlobals *kernel_globals;
        OSL::TextureSystem *osl_ts;
+#ifdef WITH_PTEX
+       PtexCache *ptex_cache;
+#endif
 };
 
 CCL_NAMESPACE_END
index daf75c813966a23be3b9d65be791c33bd292f685..fcc92b641fd4b8258059999d24f907107b218eb0 100644 (file)
@@ -217,6 +217,21 @@ ShaderNode *ImageTextureNode::clone() const
        return node;
 }
 
+void ImageTextureNode::attributes(AttributeRequestSet *attributes)
+{
+#ifdef WITH_PTEX
+       /* todo: avoid loading other texture coordinates when using ptex,
+        * and hide texture coordinate socket in the UI */
+       if (string_endswith(filename, ".ptx")) {
+               /* ptex */
+               attributes->add(ATTR_STD_PTEX_FACE_ID);
+               attributes->add(ATTR_STD_PTEX_UV);
+       }
+#endif
+
+       ShaderNode::attributes(attributes);
+}
+
 void ImageTextureNode::compile(SVMCompiler& compiler)
 {
        ShaderInput *vector_in = input("Vector");
@@ -352,6 +367,19 @@ ShaderNode *EnvironmentTextureNode::clone() const
        return node;
 }
 
+void EnvironmentTextureNode::attributes(AttributeRequestSet *attributes)
+{
+#ifdef WITH_PTEX
+       if (string_endswith(filename, ".ptx")) {
+               /* ptex */
+               attributes->add(ATTR_STD_PTEX_FACE_ID);
+               attributes->add(ATTR_STD_PTEX_UV);
+       }
+#endif
+
+       ShaderNode::attributes(attributes);
+}
+
 void EnvironmentTextureNode::compile(SVMCompiler& compiler)
 {
        ShaderInput *vector_in = input("Vector");
index 430c37158f47e99b233dc1e973acaf0215001bbd..d7a110af83b75beb7832e9fda77c9c8df875d0e4 100644 (file)
@@ -66,6 +66,7 @@ public:
        SHADER_NODE_NO_CLONE_CLASS(ImageTextureNode)
        ~ImageTextureNode();
        ShaderNode *clone() const;
+       void attributes(AttributeRequestSet *attributes);
 
        ImageManager *image_manager;
        int slot;
@@ -87,6 +88,7 @@ public:
        SHADER_NODE_NO_CLONE_CLASS(EnvironmentTextureNode)
        ~EnvironmentTextureNode();
        ShaderNode *clone() const;
+       void attributes(AttributeRequestSet *attributes);
 
        ImageManager *image_manager;
        int slot;
index 53603c54da0f0c609631f6a8979f9c484be9db66..c4a81fc7190d68b3753f39319540783fd2d27b2d 100644 (file)
@@ -86,5 +86,15 @@ void string_split(vector<string>& tokens, const string& str, const string& separ
                        tokens.push_back(token);
 }
 
+bool string_endswith(const string& s, const char *end)
+{
+       size_t len = strlen(end);
+
+       if(len > s.size())
+               return 0;
+       else
+        return strncmp(s.c_str() + s.size() - len, end, len) == 0;
+}
+
 CCL_NAMESPACE_END
 
index ee9243407166541d47b05e5d7096bed828e5a555..2d63a075e71a9877d11d55167a9cbd804bb05413 100644 (file)
@@ -40,6 +40,7 @@ string string_printf(const char *format, ...) PRINTF_ATTRIBUTE;
 
 bool string_iequals(const string& a, const string& b);
 void string_split(vector<string>& tokens, const string& str, const string& separators = "\t ");
+bool string_endswith(const string& s, const char *end);
 
 CCL_NAMESPACE_END