Cycles Hair: add Generated texture coordinates for curves, so that procedural
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Thu, 3 Jan 2013 12:31:05 +0000 (12:31 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Thu, 3 Jan 2013 12:31:05 +0000 (12:31 +0000)
textures now work without having to add a UV map.

Also made UV and intercept attributes only export when needed by the shader.

intern/cycles/blender/blender_curves.cpp
intern/cycles/blender/blender_mesh.cpp
intern/cycles/blender/blender_util.h

index 2e9a32f15f2fefe282ccdca682473e19ef40d95c..9395fbb3e5d259dda0fad1f1804cec584e04e4e6 100644 (file)
@@ -16,6 +16,7 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
+#include "attribute.h"
 #include "mesh.h"
 #include "object.h"
 #include "scene.h"
 #include "blender_sync.h"
 #include "blender_util.h"
 
-#include "subd_mesh.h"
-#include "subd_patch.h"
-#include "subd_split.h"
-
 #include "util_foreach.h"
 
-#include "DNA_modifier_types.h"
-#include "DNA_particle_types.h"
-#include "DNA_meshdata_types.h"
-
 CCL_NAMESPACE_BEGIN
 
 /* Utilities */
@@ -650,7 +643,7 @@ void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int inter
        /* texture coords still needed */
 }
 
-void ExportCurveSegments(Mesh *mesh, ParticleCurveData *CData, int interpolation, int segments)
+void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CData, int interpolation, int segments)
 {
        int num_keys = 0;
        int num_curves = 0;
@@ -658,8 +651,12 @@ void ExportCurveSegments(Mesh *mesh, ParticleCurveData *CData, int interpolation
        if(!(mesh->curves.empty() && mesh->curve_keys.empty()))
                return;
 
-       Attribute *attr_uv = mesh->curve_attributes.add(ATTR_STD_UV);
-       Attribute *attr_intercept = mesh->curve_attributes.add(ATTR_STD_CURVE_INTERCEPT);
+       Attribute *attr_uv = NULL, *attr_intercept = NULL;
+       
+       if(mesh->need_attribute(scene, ATTR_STD_UV))
+               attr_uv = mesh->curve_attributes.add(ATTR_STD_UV);
+       if(mesh->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT))
+               attr_intercept = mesh->curve_attributes.add(ATTR_STD_CURVE_INTERCEPT);
 
        for( int sys = 0; sys < CData->psys_firstcurve.size() ; sys++) {
 
@@ -695,14 +692,16 @@ void ExportCurveSegments(Mesh *mesh, ParticleCurveData *CData, int interpolation
                                                radius =0.0f;
 
                                        mesh->add_curve_key(ickey_loc, radius);
-                                       attr_intercept->add(time);
+                                       if(attr_intercept)
+                                               attr_intercept->add(time);
 
                                        num_curve_keys++;
                                }
                        }
 
                        mesh->add_curve(num_keys, num_curve_keys, CData->psys_shader[sys]);
-                       attr_uv->add(CData->curve_uv[curve]);
+                       if(attr_uv)
+                               attr_uv->add(CData->curve_uv[curve]);
 
                        num_keys += num_curve_keys;
                        num_curves++;
@@ -871,7 +870,7 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool
                        ExportCurveTriangleGeometry(mesh, &CData, interpolation, use_smooth, resolution, segments);
        }
        else {
-               ExportCurveSegments(mesh, &CData, interpolation, segments);
+               ExportCurveSegments(scene, mesh, &CData, interpolation, segments);
                int ckey_num = mesh->curve_keys.size();
 
                /*export tangents or curve data? - not functional yet*/
@@ -886,6 +885,22 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool
                                data_tangent[ck] = tg;
                        }
                }
+
+               /* generated coordinates from first key. we should ideally get this from
+                * blender to handle deforming objects */
+               if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
+                       float3 loc, size;
+                       mesh_texture_space(b_mesh, loc, size);
+
+                       Attribute *attr_generated = mesh->curve_attributes.add(ATTR_STD_GENERATED);
+                       float3 *generated = attr_generated->data_float3();
+                       size_t i = 0;
+
+                       foreach(Mesh::Curve& curve, mesh->curves) {
+                               float3 co = mesh->curve_keys[curve.first_key].co;
+                               generated[i++] = co*size - loc;
+                       }
+               }
        }
 
        mesh->compute_bounds();
index 86f996320cb0a4d91789876a343feef5d3bb979a..1dd7800dfa41f742b33afb73416b77ef62bfd6ac 100644 (file)
@@ -328,14 +328,9 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
         * is available in the api. */
        if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
                Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED);
-               float3 loc = get_float3(b_mesh.texspace_location());
-               float3 size = get_float3(b_mesh.texspace_size());
 
-               if(size.x != 0.0f) size.x = 0.5f/size.x;
-               if(size.y != 0.0f) size.y = 0.5f/size.y;
-               if(size.z != 0.0f) size.z = 0.5f/size.z;
-
-               loc = loc*size - make_float3(0.5f, 0.5f, 0.5f);
+               float3 loc, size;
+               mesh_texture_space(b_mesh, loc, size);
 
                float3 *generated = attr->data_float3();
                size_t i = 0;
index fbcbe15ec5acfb130596f6c9a73064a341ebb660..88c988607944dc41d50c1d159ae098dd829454ec 100644 (file)
@@ -242,6 +242,20 @@ static inline string blender_absolute_path(BL::BlendData b_data, BL::ID b_id, co
        return path;
 }
 
+/* Texture Space */
+
+static inline void mesh_texture_space(BL::Mesh b_mesh, float3& loc, float3& size)
+{
+       loc = get_float3(b_mesh.texspace_location());
+       size = get_float3(b_mesh.texspace_size());
+
+       if(size.x != 0.0f) size.x = 0.5f/size.x;
+       if(size.y != 0.0f) size.y = 0.5f/size.y;
+       if(size.z != 0.0f) size.z = 0.5f/size.z;
+
+       loc = loc*size - make_float3(0.5f, 0.5f, 0.5f);
+}
+
 /* ID Map
  *
  * Utility class to keep in sync with blender data.