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:
Diffstat (limited to 'intern/cycles/blender')
-rw-r--r--intern/cycles/blender/addon/engine.py3
-rw-r--r--intern/cycles/blender/addon/osl.py6
-rw-r--r--intern/cycles/blender/addon/properties.py51
-rw-r--r--intern/cycles/blender/addon/ui.py51
-rw-r--r--intern/cycles/blender/addon/version_update.py1
-rw-r--r--intern/cycles/blender/blender_mesh.cpp372
-rw-r--r--intern/cycles/blender/blender_object.cpp32
-rw-r--r--intern/cycles/blender/blender_shader.cpp13
-rw-r--r--intern/cycles/blender/blender_util.h29
9 files changed, 355 insertions, 203 deletions
diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py
index d4b7535b9ee..2c5365c9189 100644
--- a/intern/cycles/blender/addon/engine.py
+++ b/intern/cycles/blender/addon/engine.py
@@ -82,7 +82,6 @@ def init():
import bpy
import _cycles
import os.path
- import sys
# Workaround possibly buggy legacy drivers which crashes on the OpenCL
# device enumeration.
@@ -103,10 +102,12 @@ def init():
_cycles.init(path, user_path, bpy.app.background)
_parse_command_line()
+
def exit():
import _cycles
_cycles.exit()
+
def create(engine, data, scene, region=None, v3d=None, rv3d=None, preview_osl=False):
import bpy
import _cycles
diff --git a/intern/cycles/blender/addon/osl.py b/intern/cycles/blender/addon/osl.py
index f4aaaab5eab..19f2ecc9d1a 100644
--- a/intern/cycles/blender/addon/osl.py
+++ b/intern/cycles/blender/addon/osl.py
@@ -41,6 +41,8 @@ def update_script_node(node, report):
import shutil
import tempfile
+ oso_file_remove = False
+
if node.mode == 'EXTERNAL':
# compile external script file
script_path = bpy.path.abspath(node.filepath, library=node.id_data.library)
@@ -49,7 +51,6 @@ def update_script_node(node, report):
if script_ext == ".oso":
# it's a .oso file, no need to compile
ok, oso_path = True, script_path
- oso_file_remove = False
elif script_ext == ".osl":
# compile .osl file
ok, oso_path = osl_compile(script_path, report)
@@ -65,7 +66,6 @@ def update_script_node(node, report):
elif os.path.dirname(node.filepath) == "":
# module in search path
oso_path = node.filepath
- oso_file_remove = False
ok = True
else:
# unknown
@@ -88,12 +88,10 @@ def update_script_node(node, report):
osl_file.close()
ok, oso_path = osl_compile(osl_file.name, report)
- oso_file_remove = False
os.remove(osl_file.name)
else:
# compile text datablock from disk directly
ok, oso_path = osl_compile(osl_path, report)
- oso_file_remove = False
if ok:
# read bytecode
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 0b3dd552f62..8e82eac2b59 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -46,12 +46,6 @@ enum_displacement_methods = (
('BOTH', "Both", "Combination of displacement and bump mapping"),
)
-enum_subdivision_types = (
- ('NONE', "None", "No subdivision"),
- ('LINEAR', "Linear", "Use linear subdivision"),
- ('CATMULL_CLARK', "Catmull–Clark", "Use Catmull-Clark subdivision"),
- )
-
enum_bvh_types = (
('DYNAMIC_BVH', "Dynamic BVH", "Objects can be individually updated, at the cost of slower render time"),
('STATIC_BVH', "Static BVH", "Any object modification requires a complete BVH rebuild, but renders faster"),
@@ -781,6 +775,13 @@ class CyclesMaterialSettings(bpy.types.PropertyGroup):
default='LINEAR',
)
+ cls.displacement_method = EnumProperty(
+ name="Displacement Method",
+ description="Method to use for the displacement",
+ items=enum_displacement_methods,
+ default='BUMP',
+ )
+
@classmethod
def unregister(cls):
del bpy.types.Material.cycles
@@ -958,25 +959,6 @@ class CyclesMeshSettings(bpy.types.PropertyGroup):
type=cls,
)
- cls.displacement_method = EnumProperty(
- name="Displacement Method",
- description="Method to use for the displacement",
- items=enum_displacement_methods,
- default='BUMP',
- )
- cls.subdivision_type = EnumProperty(
- name="Subdivision Type",
- description="Type of subdivision to use",
- items=enum_subdivision_types,
- default='NONE',
- )
- cls.dicing_rate = FloatProperty(
- name="Dicing Rate",
- description="Multiplier for scene dicing rate",
- min=0.1, max=1000.0,
- default=1.0,
- )
-
@classmethod
def unregister(cls):
del bpy.types.Mesh.cycles
@@ -984,11 +966,9 @@ class CyclesMeshSettings(bpy.types.PropertyGroup):
del bpy.types.MetaBall.cycles
-class CyclesObjectBlurSettings(bpy.types.PropertyGroup):
-
+class CyclesObjectSettings(bpy.types.PropertyGroup):
@classmethod
def register(cls):
-
bpy.types.Object.cycles = PointerProperty(
name="Cycles Object Settings",
description="Cycles object settings",
@@ -1020,6 +1000,19 @@ class CyclesObjectBlurSettings(bpy.types.PropertyGroup):
default=False,
)
+ cls.use_adaptive_subdivision = BoolProperty(
+ name="Use Adaptive Subdivision",
+ description="Use adaptive render time subdivision",
+ default=False,
+ )
+
+ cls.dicing_rate = FloatProperty(
+ name="Dicing Rate",
+ description="Multiplier for scene dicing rate",
+ min=0.1, max=1000.0,
+ default=1.0,
+ )
+
@classmethod
def unregister(cls):
del bpy.types.Object.cycles
@@ -1136,6 +1129,7 @@ def register():
bpy.utils.register_class(CyclesWorldSettings)
bpy.utils.register_class(CyclesVisibilitySettings)
bpy.utils.register_class(CyclesMeshSettings)
+ bpy.utils.register_class(CyclesObjectSettings)
bpy.utils.register_class(CyclesCurveRenderSettings)
bpy.utils.register_class(CyclesCurveSettings)
@@ -1147,6 +1141,7 @@ def unregister():
bpy.utils.unregister_class(CyclesLampSettings)
bpy.utils.unregister_class(CyclesWorldSettings)
bpy.utils.unregister_class(CyclesMeshSettings)
+ bpy.utils.unregister_class(CyclesObjectSettings)
bpy.utils.unregister_class(CyclesVisibilitySettings)
bpy.utils.unregister_class(CyclesCurveRenderSettings)
bpy.utils.unregister_class(CyclesCurveSettings)
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 6656beb4478..52872d2b83f 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -674,48 +674,6 @@ class Cycles_PT_context_material(CyclesButtonsPanel, Panel):
split.separator()
-class Cycles_PT_mesh_displacement(CyclesButtonsPanel, Panel):
- bl_label = "Displacement"
- bl_context = "data"
-
- @classmethod
- def poll(cls, context):
- if CyclesButtonsPanel.poll(context):
- if context.mesh or context.curve or context.meta_ball:
- if context.scene.cycles.feature_set == 'EXPERIMENTAL':
- return True
-
- return False
-
- def draw(self, context):
- layout = self.layout
-
- mesh = context.mesh
- curve = context.curve
- mball = context.meta_ball
-
- if mesh:
- cdata = mesh.cycles
- elif curve:
- cdata = curve.cycles
- elif mball:
- cdata = mball.cycles
-
- split = layout.split()
-
- col = split.column()
- sub = col.column(align=True)
- sub.label(text="Displacement:")
- sub.prop(cdata, "displacement_method", text="")
-
- col = split.column()
- sub = col.column(align=True)
- sub.label(text="Subdivision:")
- sub.prop(cdata, "subdivision_type", text="")
-
- if cdata.subdivision_type != 'NONE':
- sub.prop(cdata, "dicing_rate")
-
class CyclesObject_PT_motion_blur(CyclesButtonsPanel, Panel):
bl_label = "Motion Blur"
bl_context = "object"
@@ -895,7 +853,7 @@ class CyclesLamp_PT_lamp(CyclesButtonsPanel, Panel):
lamp = context.lamp
clamp = lamp.cycles
- cscene = context.scene.cycles
+ # cscene = context.scene.cycles
layout.prop(lamp, "type", expand=True)
@@ -1115,7 +1073,7 @@ class CyclesWorld_PT_settings(CyclesButtonsPanel, Panel):
world = context.world
cworld = world.cycles
- cscene = context.scene.cycles
+ # cscene = context.scene.cycles
split = layout.split()
@@ -1227,6 +1185,11 @@ class CyclesMaterial_PT_settings(CyclesButtonsPanel, Panel):
col.prop(cmat, "sample_as_light", text="Multiple Importance")
col.prop(cmat, "use_transparent_shadow")
+ if context.scene.cycles.feature_set == 'EXPERIMENTAL':
+ col.separator()
+ col.label(text="Displacement:")
+ col.prop(cmat, "displacement_method", text="")
+
col = split.column()
col.label(text="Volume:")
sub = col.column()
diff --git a/intern/cycles/blender/addon/version_update.py b/intern/cycles/blender/addon/version_update.py
index 221b1437128..830723d6149 100644
--- a/intern/cycles/blender/addon/version_update.py
+++ b/intern/cycles/blender/addon/version_update.py
@@ -104,7 +104,6 @@ def vector_curve_node_remap(node):
"""
Remap values of vector curve node from normalized to absolute values
"""
- from mathutils import Vector
if node.bl_idname == 'ShaderNodeVectorCurve':
node.mapping.use_clip = False
for curve in node.mapping.curves:
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index ec11a893b5a..5d63aaa1415 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -24,7 +24,6 @@
#include "blender_session.h"
#include "blender_util.h"
-#include "subd_mesh.h"
#include "subd_patch.h"
#include "subd_split.h"
@@ -335,44 +334,71 @@ static void attr_create_vertex_color(Scene *scene,
Mesh *mesh,
BL::Mesh& b_mesh,
const vector<int>& nverts,
- const vector<int>& face_flags)
+ const vector<int>& face_flags,
+ bool subdivision)
{
- BL::Mesh::tessface_vertex_colors_iterator l;
- for(b_mesh.tessface_vertex_colors.begin(l); l != b_mesh.tessface_vertex_colors.end(); ++l) {
- if(!mesh->need_attribute(scene, ustring(l->name().c_str())))
- continue;
+ if(subdivision) {
+ BL::Mesh::vertex_colors_iterator l;
- Attribute *attr = mesh->attributes.add(
- ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CORNER_BYTE);
+ for(b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l) {
+ if(!mesh->need_attribute(scene, ustring(l->name().c_str())))
+ continue;
- BL::MeshColorLayer::data_iterator c;
- uchar4 *cdata = attr->data_uchar4();
- size_t i = 0;
+ Attribute *attr = mesh->subd_attributes.add(ustring(l->name().c_str()),
+ TypeDesc::TypeColor,
+ ATTR_ELEMENT_CORNER_BYTE);
- for(l->data.begin(c); c != l->data.end(); ++c, ++i) {
- int tri_a[3], tri_b[3];
- face_split_tri_indices(nverts[i], face_flags[i], tri_a, tri_b);
+ BL::Mesh::polygons_iterator p;
+ uchar4 *cdata = attr->data_uchar4();
- uchar4 colors[4];
- colors[0] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color1())));
- colors[1] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color2())));
- colors[2] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color3())));
- if(nverts[i] == 4) {
- colors[3] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color4())));
+ for(b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
+ int n = p->loop_total();
+ for(int i = 0; i < n; i++) {
+ float3 color = get_float3(l->data[p->loop_start() + i].color());
+ *(cdata++) = color_float_to_byte(color_srgb_to_scene_linear(color));
+ }
}
+ }
+ }
+ else {
+ BL::Mesh::tessface_vertex_colors_iterator l;
+ for(b_mesh.tessface_vertex_colors.begin(l); l != b_mesh.tessface_vertex_colors.end(); ++l) {
+ if(!mesh->need_attribute(scene, ustring(l->name().c_str())))
+ continue;
+
+ Attribute *attr = mesh->attributes.add(ustring(l->name().c_str()),
+ TypeDesc::TypeColor,
+ ATTR_ELEMENT_CORNER_BYTE);
+
+ BL::MeshColorLayer::data_iterator c;
+ uchar4 *cdata = attr->data_uchar4();
+ size_t i = 0;
+
+ for(l->data.begin(c); c != l->data.end(); ++c, ++i) {
+ int tri_a[3], tri_b[3];
+ face_split_tri_indices(nverts[i], face_flags[i], tri_a, tri_b);
+
+ uchar4 colors[4];
+ colors[0] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color1())));
+ colors[1] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color2())));
+ colors[2] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color3())));
+ if(nverts[i] == 4) {
+ colors[3] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color4())));
+ }
- cdata[0] = colors[tri_a[0]];
- cdata[1] = colors[tri_a[1]];
- cdata[2] = colors[tri_a[2]];
+ cdata[0] = colors[tri_a[0]];
+ cdata[1] = colors[tri_a[1]];
+ cdata[2] = colors[tri_a[2]];
- if(nverts[i] == 4) {
- cdata[3] = colors[tri_b[0]];
- cdata[4] = colors[tri_b[1]];
- cdata[5] = colors[tri_b[2]];
- cdata += 6;
+ if(nverts[i] == 4) {
+ cdata[3] = colors[tri_b[0]];
+ cdata[4] = colors[tri_b[1]];
+ cdata[5] = colors[tri_b[2]];
+ cdata += 6;
+ }
+ else
+ cdata += 3;
}
- else
- cdata += 3;
}
}
}
@@ -382,9 +408,45 @@ static void attr_create_uv_map(Scene *scene,
Mesh *mesh,
BL::Mesh& b_mesh,
const vector<int>& nverts,
- const vector<int>& face_flags)
+ const vector<int>& face_flags,
+ bool subdivision,
+ bool subdivide_uvs)
{
- if(b_mesh.tessface_uv_textures.length() != 0) {
+ if(subdivision) {
+ BL::Mesh::uv_layers_iterator l;
+ int i = 0;
+
+ for(b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l, ++i) {
+ bool active_render = b_mesh.uv_textures[i].active_render();
+ AttributeStandard std = (active_render)? ATTR_STD_UV: ATTR_STD_NONE;
+ ustring name = ustring(l->name().c_str());
+
+ /* UV map */
+ if(mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std)) {
+ Attribute *attr;
+
+ if(active_render)
+ attr = mesh->subd_attributes.add(std, name);
+ else
+ attr = mesh->subd_attributes.add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CORNER);
+
+ if(subdivide_uvs) {
+ attr->flags |= ATTR_SUBDIVIDED;
+ }
+
+ BL::Mesh::polygons_iterator p;
+ float3 *fdata = attr->data_float3();
+
+ for(b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
+ int n = p->loop_total();
+ for(int j = 0; j < n; j++) {
+ *(fdata++) = get_float3(l->data[p->loop_start() + j].uv());
+ }
+ }
+ }
+ }
+ }
+ else if(b_mesh.tessface_uv_textures.length() != 0) {
BL::Mesh::tessface_uv_textures_iterator l;
for(b_mesh.tessface_uv_textures.begin(l); l != b_mesh.tessface_uv_textures.end(); ++l) {
@@ -465,11 +527,13 @@ static void attr_create_uv_map(Scene *scene,
/* Create vertex pointiness attributes. */
static void attr_create_pointiness(Scene *scene,
Mesh *mesh,
- BL::Mesh& b_mesh)
+ BL::Mesh& b_mesh,
+ bool subdivision)
{
if(mesh->need_attribute(scene, ATTR_STD_POINTINESS)) {
const int numverts = b_mesh.vertices.length();
- Attribute *attr = mesh->attributes.add(ATTR_STD_POINTINESS);
+ AttributeSet& attributes = (subdivision)? mesh->subd_attributes: mesh->attributes;
+ Attribute *attr = attributes.add(ATTR_STD_POINTINESS);
float *data = attr->data_float();
int *counter = new int[numverts];
float *raw_data = new float[numverts];
@@ -532,30 +596,45 @@ static void attr_create_pointiness(Scene *scene,
static void create_mesh(Scene *scene,
Mesh *mesh,
BL::Mesh& b_mesh,
- const vector<Shader*>& used_shaders)
+ const vector<Shader*>& used_shaders,
+ bool subdivision=false,
+ bool subdivide_uvs=true)
{
/* count vertices and faces */
int numverts = b_mesh.vertices.length();
- int numfaces = b_mesh.tessfaces.length();
+ int numfaces = (!subdivision) ? b_mesh.tessfaces.length() : b_mesh.polygons.length();
int numtris = 0;
+ int numcorners = 0;
+ int numngons = 0;
bool use_loop_normals = b_mesh.use_auto_smooth();
BL::Mesh::vertices_iterator v;
BL::Mesh::tessfaces_iterator f;
+ BL::Mesh::polygons_iterator p;
- for(b_mesh.tessfaces.begin(f); f != b_mesh.tessfaces.end(); ++f) {
- int4 vi = get_int4(f->vertices_raw());
- numtris += (vi[3] == 0)? 1: 2;
+ if(!subdivision) {
+ for(b_mesh.tessfaces.begin(f); f != b_mesh.tessfaces.end(); ++f) {
+ int4 vi = get_int4(f->vertices_raw());
+ numtris += (vi[3] == 0)? 1: 2;
+ }
+ }
+ else {
+ for(b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
+ numngons += (p->loop_total() == 4)? 0: 1;
+ numcorners += p->loop_total();
+ }
}
/* allocate memory */
mesh->reserve_mesh(numverts, numtris);
+ mesh->reserve_subd_faces(numfaces, numngons, numcorners);
/* create vertex coordinates and normals */
for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v)
mesh->add_vertex(get_float3(v->co()));
- Attribute *attr_N = mesh->attributes.add(ATTR_STD_VERTEX_NORMAL);
+ AttributeSet& attributes = (subdivision)? mesh->subd_attributes: mesh->attributes;
+ Attribute *attr_N = attributes.add(ATTR_STD_VERTEX_NORMAL);
float3 *N = attr_N->data_float3();
for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++N)
@@ -564,7 +643,8 @@ static void create_mesh(Scene *scene,
/* create generated coordinates from undeformed coordinates */
if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
- Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED);
+ Attribute *attr = attributes.add(ATTR_STD_GENERATED);
+ attr->flags |= ATTR_SUBDIVIDED;
float3 loc, size;
mesh_texture_space(b_mesh, loc, size);
@@ -577,67 +657,103 @@ static void create_mesh(Scene *scene,
}
/* Create needed vertex attributes. */
- attr_create_pointiness(scene, mesh, b_mesh);
+ attr_create_pointiness(scene, mesh, b_mesh, subdivision);
/* create faces */
vector<int> nverts(numfaces);
vector<int> face_flags(numfaces, FACE_FLAG_NONE);
int fi = 0;
- for(b_mesh.tessfaces.begin(f); f != b_mesh.tessfaces.end(); ++f, ++fi) {
- int4 vi = get_int4(f->vertices_raw());
- int n = (vi[3] == 0)? 3: 4;
- int shader = clamp(f->material_index(), 0, used_shaders.size()-1);
- bool smooth = f->use_smooth() || use_loop_normals;
-
- /* split vertices if normal is different
- *
- * note all vertex attributes must have been set here so we can split
- * and copy attributes in split_vertex without remapping later */
- if(use_loop_normals) {
- BL::Array<float, 12> loop_normals = f->split_normals();
-
- for(int i = 0; i < n; i++) {
- float3 loop_N = make_float3(loop_normals[i * 3], loop_normals[i * 3 + 1], loop_normals[i * 3 + 2]);
-
- if(N[vi[i]] != loop_N) {
- int new_vi = mesh->split_vertex(vi[i]);
-
- /* set new normal and vertex index */
- N = attr_N->data_float3();
- N[new_vi] = loop_N;
- vi[i] = new_vi;
+ if(!subdivision) {
+ for(b_mesh.tessfaces.begin(f); f != b_mesh.tessfaces.end(); ++f, ++fi) {
+ int4 vi = get_int4(f->vertices_raw());
+ int n = (vi[3] == 0)? 3: 4;
+ int shader = clamp(f->material_index(), 0, used_shaders.size()-1);
+ bool smooth = f->use_smooth() || use_loop_normals;
+
+ /* split vertices if normal is different
+ *
+ * note all vertex attributes must have been set here so we can split
+ * and copy attributes in split_vertex without remapping later */
+ if(use_loop_normals) {
+ BL::Array<float, 12> loop_normals = f->split_normals();
+
+ for(int i = 0; i < n; i++) {
+ float3 loop_N = make_float3(loop_normals[i * 3], loop_normals[i * 3 + 1], loop_normals[i * 3 + 2]);
+
+ if(N[vi[i]] != loop_N) {
+ int new_vi = mesh->split_vertex(vi[i]);
+
+ /* set new normal and vertex index */
+ N = attr_N->data_float3();
+ N[new_vi] = loop_N;
+ vi[i] = new_vi;
+ }
}
}
- }
- /* create triangles */
- if(n == 4) {
- if(is_zero(cross(mesh->verts[vi[1]] - mesh->verts[vi[0]], mesh->verts[vi[2]] - mesh->verts[vi[0]])) ||
- is_zero(cross(mesh->verts[vi[2]] - mesh->verts[vi[0]], mesh->verts[vi[3]] - mesh->verts[vi[0]])))
- {
- // TODO(mai): order here is probably wrong
- mesh->add_triangle(vi[0], vi[1], vi[3], shader, smooth, true);
- mesh->add_triangle(vi[2], vi[3], vi[1], shader, smooth, true);
- face_flags[fi] |= FACE_FLAG_DIVIDE_24;
+ /* create triangles */
+ if(n == 4) {
+ if(is_zero(cross(mesh->verts[vi[1]] - mesh->verts[vi[0]], mesh->verts[vi[2]] - mesh->verts[vi[0]])) ||
+ is_zero(cross(mesh->verts[vi[2]] - mesh->verts[vi[0]], mesh->verts[vi[3]] - mesh->verts[vi[0]])))
+ {
+ mesh->add_triangle(vi[0], vi[1], vi[3], shader, smooth);
+ mesh->add_triangle(vi[2], vi[3], vi[1], shader, smooth);
+ face_flags[fi] |= FACE_FLAG_DIVIDE_24;
+ }
+ else {
+ mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth);
+ mesh->add_triangle(vi[0], vi[2], vi[3], shader, smooth);
+ face_flags[fi] |= FACE_FLAG_DIVIDE_13;
+ }
}
else {
- mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth, true);
- mesh->add_triangle(vi[0], vi[2], vi[3], shader, smooth, true);
- face_flags[fi] |= FACE_FLAG_DIVIDE_13;
+ mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth);
}
+
+ nverts[fi] = n;
}
- else
- mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth, false);
+ }
+ else {
+ vector<int> vi;
+
+ for(b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
+ int n = p->loop_total();
+ int shader = clamp(p->material_index(), 0, used_shaders.size()-1);
+ bool smooth = p->use_smooth() || use_loop_normals;
- nverts[fi] = n;
+ vi.reserve(n);
+ for(int i = 0; i < n; i++) {
+ vi[i] = b_mesh.loops[p->loop_start() + i].vertex_index();
+
+ /* split vertices if normal is different
+ *
+ * note all vertex attributes must have been set here so we can split
+ * and copy attributes in split_vertex without remapping later */
+ if(use_loop_normals) {
+ float3 loop_N = get_float3(b_mesh.loops[p->loop_start() + i].normal());
+
+ if(N[vi[i]] != loop_N) {
+ int new_vi = mesh->split_vertex(vi[i]);
+
+ /* set new normal and vertex index */
+ N = attr_N->data_float3();
+ N[new_vi] = loop_N;
+ vi[i] = new_vi;
+ }
+ }
+ }
+
+ /* create subd faces */
+ mesh->add_subd_face(&vi[0], n, shader, smooth);
+ }
}
/* Create all needed attributes.
* The calculate functions will check whether they're needed or not.
*/
- attr_create_vertex_color(scene, mesh, b_mesh, nverts, face_flags);
- attr_create_uv_map(scene, mesh, b_mesh, nverts, face_flags);
+ attr_create_vertex_color(scene, mesh, b_mesh, nverts, face_flags, subdivision);
+ attr_create_uv_map(scene, mesh, b_mesh, nverts, face_flags, subdivision, subdivide_uvs);
/* for volume objects, create a matrix to transform from object space to
* mesh texture space. this does not work with deformations but that can
@@ -657,16 +773,44 @@ static void create_subd_mesh(Scene *scene,
Mesh *mesh,
BL::Object& b_ob,
BL::Mesh& b_mesh,
- PointerRNA *cmesh,
const vector<Shader*>& used_shaders,
float dicing_rate,
int max_subdivisions)
{
- Mesh basemesh;
- create_mesh(scene, &basemesh, b_mesh, used_shaders);
+ BL::SubsurfModifier subsurf_mod(b_ob.modifiers[b_ob.modifiers.length()-1]);
+ bool subdivide_uvs = subsurf_mod.use_subsurf_uv();
+
+ create_mesh(scene, mesh, b_mesh, used_shaders, true, subdivide_uvs);
+
+ /* export creases */
+ size_t num_creases = 0;
+ BL::Mesh::edges_iterator e;
+
+ for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e) {
+ if(e->crease() != 0.0f) {
+ num_creases++;
+ }
+ }
+
+ mesh->subd_creases.resize(num_creases);
- SubdParams sdparams(mesh, 0, true, false);
- sdparams.dicing_rate = max(0.1f, RNA_float_get(cmesh, "dicing_rate") * dicing_rate);
+ Mesh::SubdEdgeCrease* crease = mesh->subd_creases.data();
+ for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e) {
+ if(e->crease() != 0.0f) {
+ crease->v[0] = e->vertices()[0];
+ crease->v[1] = e->vertices()[1];
+ crease->crease = e->crease();
+
+ crease++;
+ }
+ }
+
+ /* set subd params */
+ SubdParams sdparams(mesh);
+
+ PointerRNA cobj = RNA_pointer_get(&b_ob.ptr, "cycles");
+
+ sdparams.dicing_rate = max(0.1f, RNA_float_get(&cobj, "dicing_rate") * dicing_rate);
sdparams.max_level = max_subdivisions;
scene->camera->update();
@@ -675,7 +819,7 @@ static void create_subd_mesh(Scene *scene,
/* tesselate */
DiagSplit dsplit(sdparams);
- basemesh.tessellate(&dsplit);
+ mesh->tessellate(&dsplit);
}
/* Sync */
@@ -793,8 +937,6 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob,
mesh_synced.insert(mesh);
/* create derived mesh */
- PointerRNA cmesh = RNA_pointer_get(&b_ob_data.ptr, "cycles");
-
array<int> oldtriangle = mesh->triangles;
/* compares curve_keys rather than strands in order to handle quick hair
@@ -817,20 +959,41 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob,
b_ob.update_from_editmode();
bool need_undeformed = mesh->need_attribute(scene, ATTR_STD_GENERATED);
- BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview, need_undeformed);
+
+ mesh->subdivision_type = Mesh::SUBDIVISION_NONE;
+
+ PointerRNA cobj = RNA_pointer_get(&b_ob.ptr, "cycles");
+
+ if(cobj.data && b_ob.modifiers.length() > 0 && experimental) {
+ BL::Modifier mod = b_ob.modifiers[b_ob.modifiers.length()-1];
+ bool enabled = preview ? mod.show_viewport() : mod.show_render();
+
+ if(enabled && mod.type() == BL::Modifier::type_SUBSURF && RNA_int_get(&cobj, "use_adaptive_subdivision")) {
+ BL::SubsurfModifier subsurf(mod);
+
+ if(subsurf.subdivision_type() == BL::SubsurfModifier::subdivision_type_CATMULL_CLARK) {
+ mesh->subdivision_type = Mesh::SUBDIVISION_CATMULL_CLARK;
+ }
+ else {
+ mesh->subdivision_type = Mesh::SUBDIVISION_LINEAR;
+ }
+ }
+ }
+
+ BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview, need_undeformed, mesh->subdivision_type);
if(b_mesh) {
if(render_layer.use_surfaces && !hide_tris) {
- if(cmesh.data && experimental && RNA_enum_get(&cmesh, "subdivision_type"))
- create_subd_mesh(scene, mesh, b_ob, b_mesh, &cmesh, used_shaders,
+ if(mesh->subdivision_type != Mesh::SUBDIVISION_NONE)
+ create_subd_mesh(scene, mesh, b_ob, b_mesh, used_shaders,
dicing_rate, max_subdivisions);
else
- create_mesh(scene, mesh, b_mesh, used_shaders);
+ create_mesh(scene, mesh, b_mesh, used_shaders, false);
create_mesh_volume_attributes(scene, b_ob, mesh, b_scene.frame_current());
}
- if(render_layer.use_hair)
+ if(render_layer.use_hair && mesh->subdivision_type == Mesh::SUBDIVISION_NONE)
sync_curves(mesh, b_mesh, b_ob, false);
if(can_free_caches) {
@@ -843,21 +1006,6 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob,
}
mesh->geometry_flags = requested_geometry_flags;
- /* displacement method */
- if(cmesh.data) {
- const int method = get_enum(cmesh,
- "displacement_method",
- Mesh::DISPLACE_NUM_METHODS,
- Mesh::DISPLACE_BUMP);
-
- if(method == 0 || !experimental)
- mesh->displacement_method = Mesh::DISPLACE_BUMP;
- else if(method == 1)
- mesh->displacement_method = Mesh::DISPLACE_TRUE;
- else
- mesh->displacement_method = Mesh::DISPLACE_BOTH;
- }
-
/* fluid motion */
sync_mesh_fluid_motion(b_ob, scene, mesh);
@@ -957,7 +1105,7 @@ void BlenderSync::sync_mesh_motion(BL::Object& b_ob,
if(ccl::BKE_object_is_deform_modified(b_ob, b_scene, preview)) {
/* get derived mesh */
- b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview, false);
+ b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview, false, false);
}
if(!b_mesh) {
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 22a0b3988c8..f305e8e17cc 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -253,8 +253,18 @@ static bool object_boundbox_clip(Scene *scene,
boundbox[3 * i + 1],
boundbox[3 * i + 2]);
p = transform_point(&tfm, p);
- p = transform_perspective(&worldtondc, p);
- if(p.z >= -margin) {
+
+ float4 b = make_float4(p.x, p.y, p.z, 1.0f);
+ float4 c = make_float4(dot(worldtondc.x, b),
+ dot(worldtondc.y, b),
+ dot(worldtondc.z, b),
+ dot(worldtondc.w, b));
+ p = float4_to_float3(c / c.w);
+ if(c.z < 0.0f) {
+ p.x = 1.0f - p.x;
+ p.y = 1.0f - p.y;
+ }
+ if(c.z >= -margin) {
all_behind = false;
}
bb_min = min(bb_min, p);
@@ -319,16 +329,18 @@ Object *BlenderSync::sync_object(BL::Object& b_parent,
/* object transformation */
if(tfm != object->tfm) {
VLOG(1) << "Object " << b_ob.name() << " motion detected.";
- if(motion_time == -1.0f) {
- object->motion.pre = tfm;
- object->use_motion = true;
- }
- else if(motion_time == 1.0f) {
- object->motion.post = tfm;
+ if(motion_time == -1.0f || motion_time == 1.0f) {
object->use_motion = true;
}
}
+ if(motion_time == -1.0f) {
+ object->motion.pre = tfm;
+ }
+ else if(motion_time == 1.0f) {
+ object->motion.post = tfm;
+ }
+
/* mesh deformation */
if(object->mesh)
sync_mesh_motion(b_ob, object, motion_time);
@@ -385,8 +397,8 @@ Object *BlenderSync::sync_object(BL::Object& b_parent,
object->name = b_ob.name().c_str();
object->pass_id = b_ob.pass_index();
object->tfm = tfm;
- object->motion.pre = tfm;
- object->motion.post = tfm;
+ object->motion.pre = transform_empty();
+ object->motion.post = transform_empty();
object->use_motion = false;
/* motion blur */
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index 64559804ccb..534bc6cc897 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -64,6 +64,14 @@ static VolumeInterpolation get_volume_interpolation(PointerRNA& ptr)
VOLUME_INTERPOLATION_LINEAR);
}
+static DisplacementMethod get_displacement_method(PointerRNA& ptr)
+{
+ return (DisplacementMethod)get_enum(ptr,
+ "displacement_method",
+ DISPLACE_NUM_METHODS,
+ DISPLACE_BUMP);
+}
+
static int validate_enum_value(int value, int num_values, int default_value)
{
if(value >= num_values) {
@@ -837,8 +845,10 @@ static ShaderNode *add_node(Scene *scene,
}
}
- if(node)
+ if(node) {
+ node->name = b_node.name();
graph->add(node);
+ }
return node;
}
@@ -1180,6 +1190,7 @@ void BlenderSync::sync_materials(bool update_all)
shader->heterogeneous_volume = !get_boolean(cmat, "homogeneous_volume");
shader->volume_sampling_method = get_volume_sampling(cmat);
shader->volume_interpolation_method = get_volume_interpolation(cmat);
+ shader->displacement_method = (experimental) ? get_displacement_method(cmat) : DISPLACE_BUMP;
shader->set_graph(graph);
shader->tag_update(scene);
diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h
index 188d23d0c59..d5dbaba094b 100644
--- a/intern/cycles/blender/blender_util.h
+++ b/intern/cycles/blender/blender_util.h
@@ -45,14 +45,39 @@ static inline BL::Mesh object_to_mesh(BL::BlendData& data,
BL::Scene& scene,
bool apply_modifiers,
bool render,
- bool calc_undeformed)
+ bool calc_undeformed,
+ bool subdivision)
{
+ bool subsurf_mod_show_render;
+ bool subsurf_mod_show_viewport;
+
+ if(subdivision) {
+ BL::Modifier subsurf_mod = object.modifiers[object.modifiers.length()-1];
+
+ subsurf_mod_show_render = subsurf_mod.show_render();
+ subsurf_mod_show_viewport = subsurf_mod.show_render();
+
+ subsurf_mod.show_render(false);
+ subsurf_mod.show_viewport(false);
+
+ }
+
BL::Mesh me = data.meshes.new_from_object(scene, object, apply_modifiers, (render)? 2: 1, false, calc_undeformed);
+
+ if(subdivision) {
+ BL::Modifier subsurf_mod = object.modifiers[object.modifiers.length()-1];
+
+ subsurf_mod.show_render(subsurf_mod_show_render);
+ subsurf_mod.show_viewport(subsurf_mod_show_viewport);
+ }
+
if((bool)me) {
if(me.use_auto_smooth()) {
me.calc_normals_split();
}
- me.calc_tessface(true);
+ if(!subdivision) {
+ me.calc_tessface(true);
+ }
}
return me;
}