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/CMakeLists.txt1
-rw-r--r--intern/cycles/blender/addon/__init__.py6
-rw-r--r--intern/cycles/blender/addon/engine.py1
-rw-r--r--intern/cycles/blender/addon/presets.py17
-rw-r--r--intern/cycles/blender/addon/properties.py27
-rw-r--r--intern/cycles/blender/addon/ui.py25
-rw-r--r--intern/cycles/blender/addon/version_update.py44
-rw-r--r--intern/cycles/blender/blender_camera.cpp6
-rw-r--r--intern/cycles/blender/blender_curves.cpp49
-rw-r--r--intern/cycles/blender/blender_mesh.cpp88
-rw-r--r--intern/cycles/blender/blender_object.cpp2
-rw-r--r--intern/cycles/blender/blender_python.cpp11
-rw-r--r--intern/cycles/blender/blender_session.cpp53
-rw-r--r--intern/cycles/blender/blender_session.h3
-rw-r--r--intern/cycles/blender/blender_shader.cpp15
-rw-r--r--intern/cycles/blender/blender_sync.cpp8
16 files changed, 275 insertions, 81 deletions
diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt
index ad553fb1d62..e97ad2e71f5 100644
--- a/intern/cycles/blender/CMakeLists.txt
+++ b/intern/cycles/blender/CMakeLists.txt
@@ -44,6 +44,7 @@ set(ADDON_FILES
addon/presets.py
addon/properties.py
addon/ui.py
+ addon/version_update.py
)
add_definitions(${GL_DEFINITIONS})
diff --git a/intern/cycles/blender/addon/__init__.py b/intern/cycles/blender/addon/__init__.py
index 27d986900c8..d1d27df8dc3 100644
--- a/intern/cycles/blender/addon/__init__.py
+++ b/intern/cycles/blender/addon/__init__.py
@@ -31,7 +31,7 @@ bl_info = {
import bpy
from . import engine
-
+from . import version_update
class CyclesRender(bpy.types.RenderEngine):
bl_idname = 'CYCLES'
@@ -100,12 +100,16 @@ def register():
presets.register()
bpy.utils.register_module(__name__)
+ bpy.app.handlers.version_update.append(version_update.do_versions)
+
def unregister():
from . import ui
from . import properties
from . import presets
+ bpy.app.handlers.version_update.remove(version_update.do_versions)
+
ui.unregister()
properties.unregister()
presets.unregister()
diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py
index 21a92a29cfc..18235eca790 100644
--- a/intern/cycles/blender/addon/engine.py
+++ b/intern/cycles/blender/addon/engine.py
@@ -65,6 +65,7 @@ def bake(engine, obj, pass_type, pixel_array, num_pixels, depth, result):
if session is not None:
_cycles.bake(engine.session, obj.as_pointer(), pass_type, pixel_array.as_pointer(), num_pixels, depth, result.as_pointer())
+
def reset(engine, data, scene):
import _cycles
data = data.as_pointer()
diff --git a/intern/cycles/blender/addon/presets.py b/intern/cycles/blender/addon/presets.py
index 9991fdb8e3b..2ec65d7183a 100644
--- a/intern/cycles/blender/addon/presets.py
+++ b/intern/cycles/blender/addon/presets.py
@@ -33,12 +33,16 @@ class AddPresetIntegrator(AddPresetBase, Operator):
preset_values = [
"cycles.max_bounces",
"cycles.min_bounces",
- "cycles.no_caustics",
"cycles.diffuse_bounces",
"cycles.glossy_bounces",
"cycles.transmission_bounces",
+ "cycles.volume_bounces",
"cycles.transparent_min_bounces",
- "cycles.transparent_max_bounces"
+ "cycles.transparent_max_bounces",
+ "cycles.use_transparent_shadows",
+ "cycles.caustics_reflective",
+ "cycles.caustics_refractive",
+ "cycles.blur_glossy"
]
preset_subdir = "cycles/integrator"
@@ -66,10 +70,13 @@ class AddPresetSampling(AddPresetBase, Operator):
"cycles.mesh_light_samples",
"cycles.subsurface_samples",
"cycles.volume_samples",
- "cycles.no_caustics",
- "cycles.blur_glossy",
"cycles.use_square_samples",
- "cycles.progressive"
+ "cycles.progressive",
+ "cycles.seed",
+ "cycles.sample_clamp_direct",
+ "cycles.sample_clamp_indirect",
+ "cycles.sample_all_lights_direct",
+ "cycles.sample_all_lights_indirect",
]
preset_subdir = "cycles/sampling"
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index b4a1b10f8b4..0ac0e0f091e 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -259,11 +259,18 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
default=True,
)
- cls.no_caustics = BoolProperty(
- name="No Caustics",
- description="Leave out caustics, resulting in a darker image with less noise",
- default=False,
+ cls.caustics_reflective = BoolProperty(
+ name="Reflective Caustics",
+ description="Use reflective caustics, resulting in a brighter image (more noise but added realism)",
+ default=True,
+ )
+
+ cls.caustics_refractive = BoolProperty(
+ name="Refractive Caustics",
+ description="Use refractive caustics, resulting in a brighter image (more noise but added realism)",
+ default=True,
)
+
cls.blur_glossy = FloatProperty(
name="Filter Glossy",
description="Adaptively blur glossy shaders after blurry bounces, "
@@ -544,6 +551,13 @@ class CyclesCameraSettings(bpy.types.PropertyGroup):
subtype='ANGLE',
default=0,
)
+ cls.aperture_ratio = FloatProperty(
+ name="Aperture Ratio",
+ description="Distortion to simulate anamorphic lens bokeh",
+ min=0.01, soft_min=1.0, soft_max=2.0,
+ default=1.0,
+ precision=4,
+ )
cls.panorama_type = EnumProperty(
name="Panorama Type",
description="Distortion to use for the calculation",
@@ -724,6 +738,11 @@ class CyclesVisibilitySettings(bpy.types.PropertyGroup):
description="Object visibility for shadow rays",
default=True,
)
+ cls.scatter = BoolProperty(
+ name="Volume Scatter",
+ description="Object visibility for volume scatter rays",
+ default=True,
+ )
@classmethod
def unregister(cls):
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 35ae8ecb7c1..6e40c42fb2d 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -154,7 +154,7 @@ class CyclesRender_PT_sampling(CyclesButtonsPanel, Panel):
sub.prop(cscene, "subsurface_samples", text="Subsurface")
sub.prop(cscene, "volume_samples", text="Volume")
- if cscene.feature_set == 'EXPERIMENTAL' and use_cpu(context):
+ if use_cpu(context) or cscene.feature_set == 'EXPERIMENTAL':
layout.row().prop(cscene, "sampling_pattern", text="Pattern")
for rl in scene.render.layers:
@@ -210,7 +210,8 @@ class CyclesRender_PT_light_paths(CyclesButtonsPanel, Panel):
col.separator()
- col.prop(cscene, "no_caustics")
+ col.prop(cscene, "caustics_reflective")
+ col.prop(cscene, "caustics_refractive")
col.prop(cscene, "blur_glossy")
col = split.column()
@@ -468,6 +469,7 @@ class CyclesCamera_PT_dof(CyclesButtonsPanel, Panel):
sub = col.column(align=True)
sub.prop(ccam, "aperture_blades", text="Blades")
sub.prop(ccam, "aperture_rotation", text="Rotation")
+ sub.prop(ccam, "aperture_ratio", text="Ratio")
class Cycles_PT_context_material(CyclesButtonsPanel, Panel):
@@ -617,6 +619,7 @@ class CyclesObject_PT_ray_visibility(CyclesButtonsPanel, Panel):
flow.prop(visibility, "diffuse")
flow.prop(visibility, "glossy")
flow.prop(visibility, "transmission")
+ flow.prop(visibility, "scatter")
if ob.type != 'LAMP':
flow.prop(visibility, "shadow")
@@ -629,7 +632,8 @@ class CYCLES_OT_use_shading_nodes(Operator):
@classmethod
def poll(cls, context):
- return context.material or context.world or context.lamp
+ return (getattr(context, "material", False) or getattr(context, "world", False) or
+ getattr(context, "lamp", False))
def execute(self, context):
if context.material:
@@ -895,6 +899,7 @@ class CyclesWorld_PT_ray_visibility(CyclesButtonsPanel, Panel):
flow.prop(visibility, "diffuse")
flow.prop(visibility, "glossy")
flow.prop(visibility, "transmission")
+ flow.prop(visibility, "scatter")
class CyclesWorld_PT_settings(CyclesButtonsPanel, Panel):
@@ -928,7 +933,9 @@ class CyclesWorld_PT_settings(CyclesButtonsPanel, Panel):
col = split.column()
col.label(text="Volume:")
- col.prop(cworld, "volume_sampling", text="")
+ sub = col.column()
+ sub.active = use_cpu(context)
+ sub.prop(cworld, "volume_sampling", text="")
col.prop(cworld, "homogeneous_volume", text="Homogeneous")
@@ -1030,7 +1037,9 @@ class CyclesMaterial_PT_settings(CyclesButtonsPanel, Panel):
col = split.column()
col.label(text="Volume:")
- col.prop(cmat, "volume_sampling", text="")
+ sub = col.column()
+ sub.active = use_cpu(context)
+ sub.prop(cmat, "volume_sampling", text="")
col.prop(cmat, "homogeneous_volume", text="Homogeneous")
@@ -1244,13 +1253,13 @@ class CyclesRender_PT_bake(CyclesButtonsPanel, Panel):
scene = context.scene
cscene = scene.cycles
cbk = scene.render.bake
-
+
layout.operator("object.bake", icon='RENDER_STILL').type = cscene.bake_type
-
+
col = layout.column()
col.prop(cscene, "bake_type")
col.separator()
-
+
split = layout.split()
col = split.column()
diff --git a/intern/cycles/blender/addon/version_update.py b/intern/cycles/blender/addon/version_update.py
new file mode 100644
index 00000000000..6f9509e7d99
--- /dev/null
+++ b/intern/cycles/blender/addon/version_update.py
@@ -0,0 +1,44 @@
+#
+# Copyright 2011-2014 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
+#
+
+# <pep8 compliant>
+
+import bpy
+
+from bpy.app.handlers import persistent
+
+
+@persistent
+def do_versions(self):
+ # We don't modify startup file because it assumes to
+ # have all the default values only.
+ if not bpy.data.is_saved:
+ return
+
+ if bpy.data.version <= (2, 71, 0):
+ for scene in bpy.data.scenes:
+ cscene = scene.cycles
+ if not cscene.is_property_set("volume_bounces"):
+ cscene.volume_bounces = 1
+
+ for scene in bpy.data.scenes:
+ cscene = scene.cycles
+ if (cscene.get("no_caustics", False) and
+ not cscene.is_property_set("caustics_reflective") and
+ not cscene.is_property_set("caustics_refractive")):
+
+ cscene.caustics_reflective = False
+ cscene.caustics_refractive = False
diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp
index 1a85561c6d5..ce8c64c4819 100644
--- a/intern/cycles/blender/blender_camera.cpp
+++ b/intern/cycles/blender/blender_camera.cpp
@@ -46,6 +46,8 @@ struct BlenderCamera {
float2 pixelaspect;
+ float aperture_ratio;
+
PanoramaType panorama_type;
float fisheye_fov;
float fisheye_lens;
@@ -167,6 +169,7 @@ static void blender_camera_from_object(BlenderCamera *bcam, BL::Object b_ob, boo
bcam->apertureblades = RNA_int_get(&ccamera, "aperture_blades");
bcam->aperturerotation = RNA_float_get(&ccamera, "aperture_rotation");
bcam->focaldistance = blender_camera_focal_distance(b_ob, b_camera);
+ bcam->aperture_ratio = RNA_float_get(&ccamera, "aperture_ratio");
bcam->shift.x = b_camera.shift_x();
bcam->shift.y = b_camera.shift_y();
@@ -328,6 +331,9 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int
cam->fisheye_fov = bcam->fisheye_fov;
cam->fisheye_lens = bcam->fisheye_lens;
+ /* anamorphic lens bokeh */
+ cam->aperture_ratio = bcam->aperture_ratio;
+
/* perspective */
cam->fov = 2.0f * atanf((0.5f * sensor_size) / bcam->lens / aspectratio);
cam->focaldistance = bcam->focaldistance;
diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp
index 7b1a8ec0b15..8cfaea59a06 100644
--- a/intern/cycles/blender/blender_curves.cpp
+++ b/intern/cycles/blender/blender_curves.cpp
@@ -15,10 +15,11 @@
*/
#include "attribute.h"
+#include "camera.h"
+#include "curves.h"
#include "mesh.h"
#include "object.h"
#include "scene.h"
-#include "curves.h"
#include "blender_sync.h"
#include "blender_util.h"
@@ -39,7 +40,8 @@ bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Parti
bool ObtainCacheParticleVcol(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background, int vcol_num);
bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background);
void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CData);
-void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, float3 RotCam);
+void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData,
+ float3 RotCam, bool is_ortho);
void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int resolution);
void ExportCurveTriangleUV(Mesh *mesh, ParticleCurveData *CData, int vert_offset, int resol, float3 *uvdata);
void ExportCurveTriangleVcol(Mesh *mesh, ParticleCurveData *CData, int vert_offset, int resol, uchar4 *cdata);
@@ -328,7 +330,8 @@ static void set_resolution(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, BL::S
}
}
-void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, float3 RotCam)
+void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData,
+ float3 RotCam, bool is_ortho)
{
int vertexno = mesh->verts.size();
int vertexindex = vertexno;
@@ -362,7 +365,10 @@ void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, float3 RotC
float3 ickey_loc = CData->curvekey_co[CData->curve_firstkey[curve]];
float radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], 0.0f);
v1 = CData->curvekey_co[CData->curve_firstkey[curve] + 1] - CData->curvekey_co[CData->curve_firstkey[curve]];
- xbasis = normalize(cross(RotCam - ickey_loc,v1));
+ if(is_ortho)
+ xbasis = normalize(cross(RotCam, v1));
+ else
+ xbasis = normalize(cross(RotCam - ickey_loc, v1));
float3 ickey_loc_shfl = ickey_loc - radius * xbasis;
float3 ickey_loc_shfr = ickey_loc + radius * xbasis;
mesh->verts.push_back(ickey_loc_shfl);
@@ -386,7 +392,10 @@ void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, float3 RotC
if(CData->psys_closetip[sys] && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1))
radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], 0.0f, 0.95f);
- xbasis = normalize(cross(RotCam - ickey_loc,v1));
+ if(is_ortho)
+ xbasis = normalize(cross(RotCam, v1));
+ else
+ xbasis = normalize(cross(RotCam - ickey_loc, v1));
float3 ickey_loc_shfl = ickey_loc - radius * xbasis;
float3 ickey_loc_shfr = ickey_loc + radius * xbasis;
mesh->verts.push_back(ickey_loc_shfl);
@@ -858,20 +867,26 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool
ObtainCacheParticleData(mesh, &b_mesh, &b_ob, &CData, !preview);
- /* obtain camera parameters */
- BL::Object b_CamOb = b_scene.camera();
- float3 RotCam = make_float3(0.0f, 0.0f, 0.0f);
- if(b_CamOb) {
- Transform ctfm = get_transform(b_CamOb.matrix_world());
- Transform tfm = get_transform(b_ob.matrix_world());
- Transform itfm = transform_quick_inverse(tfm);
- RotCam = transform_point(&itfm, make_float3(ctfm.x.w, ctfm.y.w, ctfm.z.w));
- }
-
/* add hair geometry to mesh */
if(primitive == CURVE_TRIANGLES) {
- if(triangle_method == CURVE_CAMERA_TRIANGLES)
- ExportCurveTrianglePlanes(mesh, &CData, RotCam);
+ if(triangle_method == CURVE_CAMERA_TRIANGLES) {
+ /* obtain camera parameters */
+ float3 RotCam;
+ Camera *camera = scene->camera;
+ Transform &ctfm = camera->matrix;
+ if(camera->type == CAMERA_ORTHOGRAPHIC) {
+ RotCam = -make_float3(ctfm.x.z, ctfm.y.z, ctfm.z.z);
+ }
+ else {
+ Transform tfm = get_transform(b_ob.matrix_world());
+ Transform itfm = transform_quick_inverse(tfm);
+ RotCam = transform_point(&itfm, make_float3(ctfm.x.w,
+ ctfm.y.w,
+ ctfm.z.w));
+ }
+ bool is_ortho = camera->type == CAMERA_ORTHOGRAPHIC;
+ ExportCurveTrianglePlanes(mesh, &CData, RotCam, is_ortho);
+ }
else {
ExportCurveTriangleGeometry(mesh, &CData, resolution);
used_res = resolution;
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index e7c18c9706b..a5e4b7bd2ae 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -35,14 +35,14 @@ CCL_NAMESPACE_BEGIN
/* Tangent Space */
struct MikkUserData {
- MikkUserData(const BL::Mesh mesh_, const BL::MeshTextureFaceLayer layer_, int num_faces_)
+ MikkUserData(const BL::Mesh mesh_, BL::MeshTextureFaceLayer *layer_, int num_faces_)
: mesh(mesh_), layer(layer_), num_faces(num_faces_)
{
tangent.resize(num_faces*4);
}
BL::Mesh mesh;
- BL::MeshTextureFaceLayer layer;
+ BL::MeshTextureFaceLayer *layer;
int num_faces;
vector<float4> tangent;
};
@@ -78,26 +78,34 @@ static void mikk_get_position(const SMikkTSpaceContext *context, float P[3], con
static void mikk_get_texture_coordinate(const SMikkTSpaceContext *context, float uv[2], const int face_num, const int vert_num)
{
MikkUserData *userdata = (MikkUserData*)context->m_pUserData;
- BL::MeshTextureFace tf = userdata->layer.data[face_num];
- float3 tfuv;
-
- switch (vert_num) {
- case 0:
- tfuv = get_float3(tf.uv1());
- break;
- case 1:
- tfuv = get_float3(tf.uv2());
- break;
- case 2:
- tfuv = get_float3(tf.uv3());
- break;
- default:
- tfuv = get_float3(tf.uv4());
- break;
+ if(userdata->layer != NULL) {
+ BL::MeshTextureFace tf = userdata->layer->data[face_num];
+ float3 tfuv;
+
+ switch (vert_num) {
+ case 0:
+ tfuv = get_float3(tf.uv1());
+ break;
+ case 1:
+ tfuv = get_float3(tf.uv2());
+ break;
+ case 2:
+ tfuv = get_float3(tf.uv3());
+ break;
+ default:
+ tfuv = get_float3(tf.uv4());
+ break;
+ }
+
+ uv[0] = tfuv.x;
+ uv[1] = tfuv.y;
+ }
+ else {
+ int vert_idx = userdata->mesh.tessfaces[face_num].vertices()[vert_num];
+ float3 orco =
+ get_float3(userdata->mesh.vertices[vert_idx].undeformed_co());
+ map_to_sphere(&uv[0], &uv[1], orco[0], orco[1], orco[2]);
}
-
- uv[0] = tfuv.x;
- uv[1] = tfuv.y;
}
static void mikk_get_normal(const SMikkTSpaceContext *context, float N[3], const int face_num, const int vert_num)
@@ -127,7 +135,7 @@ static void mikk_set_tangent_space(const SMikkTSpaceContext *context, const floa
userdata->tangent[face*4 + vert] = make_float4(T[0], T[1], T[2], sign);
}
-static void mikk_compute_tangents(BL::Mesh b_mesh, BL::MeshTextureFaceLayer b_layer, Mesh *mesh, vector<int>& nverts, bool need_sign, bool active_render)
+static void mikk_compute_tangents(BL::Mesh b_mesh, BL::MeshTextureFaceLayer *b_layer, Mesh *mesh, vector<int>& nverts, bool need_sign, bool active_render)
{
/* setup userdata */
MikkUserData userdata(b_mesh, b_layer, nverts.size());
@@ -153,7 +161,11 @@ static void mikk_compute_tangents(BL::Mesh b_mesh, BL::MeshTextureFaceLayer b_la
/* create tangent attributes */
Attribute *attr;
- ustring name = ustring((string(b_layer.name().c_str()) + ".tangent").c_str());
+ ustring name;
+ if(b_layer != NULL)
+ name = ustring((string(b_layer->name().c_str()) + ".tangent").c_str());
+ else
+ name = ustring("orco.tangent");
if(active_render)
attr = mesh->attributes.add(ATTR_STD_UV_TANGENT, name);
@@ -167,7 +179,11 @@ static void mikk_compute_tangents(BL::Mesh b_mesh, BL::MeshTextureFaceLayer b_la
if(need_sign) {
Attribute *attr_sign;
- ustring name_sign = ustring((string(b_layer.name().c_str()) + ".tangent_sign").c_str());
+ ustring name_sign;
+ if(b_layer != NULL)
+ name_sign = ustring((string(b_layer->name().c_str()) + ".tangent_sign").c_str());
+ else
+ name_sign = ustring("orco.tangent_sign");
if(active_render)
attr_sign = mesh->attributes.add(ATTR_STD_UV_TANGENT_SIGN, name_sign);
@@ -371,7 +387,7 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
}
/* create uv map attributes */
- {
+ 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) {
@@ -416,10 +432,14 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
name = ustring((string(l->name().c_str()) + ".tangent_sign").c_str());
bool need_sign = (mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std));
- mikk_compute_tangents(b_mesh, *l, mesh, nverts, need_sign, active_render);
+ mikk_compute_tangents(b_mesh, &(*l), mesh, nverts, need_sign, active_render);
}
}
}
+ else if(mesh->need_attribute(scene, ATTR_STD_UV_TANGENT)) {
+ bool need_sign = mesh->need_attribute(scene, ATTR_STD_UV_TANGENT_SIGN);
+ mikk_compute_tangents(b_mesh, NULL, mesh, nverts, need_sign, true);
+ }
/* for volume objects, create a matrix to transform from object space to
* mesh texture space. this does not work with deformations but that can
@@ -505,15 +525,16 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tri
}
/* test if we need to sync */
+ bool use_mesh_geometry = render_layer.use_surfaces || render_layer.use_hair;
Mesh *mesh;
if(!mesh_map.sync(&mesh, key)) {
-
/* if transform was applied to mesh, need full update */
if(object_updated && mesh->transform_applied);
/* test if shaders changed, these can be object level so mesh
* does not get tagged for recalc */
else if(mesh->used_shaders != used_shaders);
+ else if(use_mesh_geometry != mesh->geometry_synced);
else {
/* even if not tagged for recalc, we may need to sync anyway
* because the shader needs different mesh attributes */
@@ -540,15 +561,21 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tri
vector<Mesh::Triangle> oldtriangle = mesh->triangles;
/* compares curve_keys rather than strands in order to handle quick hair
- * adjustsments in dynamic BVH - other methods could probably do this better*/
+ * adjustments in dynamic BVH - other methods could probably do this better*/
vector<float4> oldcurve_keys = mesh->curve_keys;
mesh->clear();
mesh->used_shaders = used_shaders;
mesh->name = ustring(b_ob_data.name().c_str());
- if(render_layer.use_surfaces || render_layer.use_hair) {
- if(preview)
+ if(use_mesh_geometry) {
+ /* mesh objects does have special handle in the dependency graph,
+ * they're ensured to have properly updated.
+ *
+ * updating meshes here will end up having derived mesh referencing
+ * freed data from the blender side.
+ */
+ if(preview && b_ob.type() != BL::Object::type_MESH)
b_ob.update_from_editmode();
bool need_undeformed = mesh->need_attribute(scene, ATTR_STD_GENERATED);
@@ -570,6 +597,7 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tri
/* free derived mesh */
b_data.meshes.remove(b_mesh);
}
+ mesh->geometry_synced = true;
}
/* displacement method */
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 94dec0b8244..1e07c5f9c96 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -82,6 +82,7 @@ static uint object_ray_visibility(BL::Object b_ob)
flag |= get_boolean(cvisibility, "glossy")? PATH_RAY_GLOSSY: 0;
flag |= get_boolean(cvisibility, "transmission")? PATH_RAY_TRANSMIT: 0;
flag |= get_boolean(cvisibility, "shadow")? PATH_RAY_SHADOW: 0;
+ flag |= get_boolean(cvisibility, "scatter")? PATH_RAY_VOLUME_SCATTER: 0;
return flag;
}
@@ -172,6 +173,7 @@ void BlenderSync::sync_light(BL::Object b_parent, int persistent_id[OBJECT_PERSI
light->use_diffuse = (visibility & PATH_RAY_DIFFUSE) != 0;
light->use_glossy = (visibility & PATH_RAY_GLOSSY) != 0;
light->use_transmission = (visibility & PATH_RAY_TRANSMIT) != 0;
+ light->use_scatter = (visibility & PATH_RAY_VOLUME_SCATTER) != 0;
/* tag */
light->tag_update(scene);
diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp
index 1d18f564e32..b756d6acdb2 100644
--- a/intern/cycles/blender/blender_python.cpp
+++ b/intern/cycles/blender/blender_python.cpp
@@ -179,7 +179,7 @@ static PyObject *bake_func(PyObject *self, PyObject *args)
python_thread_state_save(&session->python_thread_state);
- session->bake(b_object, pass_type, b_bake_pixel, num_pixels, depth, (float *)b_result);
+ session->bake(b_object, pass_type, b_bake_pixel, (size_t)num_pixels, depth, (float *)b_result);
python_thread_state_restore(&session->python_thread_state);
@@ -363,7 +363,12 @@ static PyObject *osl_update_node_func(PyObject *self, PyObject *args)
/* find socket socket */
BL::NodeSocket b_sock(PointerRNA_NULL);
if (param->isoutput) {
+#if OSL_LIBRARY_VERSION_CODE < 10500
b_sock = b_node.outputs[param->name];
+#else
+ b_sock = b_node.outputs[param->name.string()];
+#endif
+
/* remove if type no longer matches */
if(b_sock && b_sock.bl_idname() != socket_type) {
@@ -372,7 +377,11 @@ static PyObject *osl_update_node_func(PyObject *self, PyObject *args)
}
}
else {
+#if OSL_LIBRARY_VERSION_CODE < 10500
b_sock = b_node.inputs[param->name];
+#else
+ b_sock = b_node.inputs[param->name.string()];
+#endif
/* remove if type no longer matches */
if(b_sock && b_sock.bl_idname() != socket_type) {
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index 0f31e55d60d..4ff3d89f9f1 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -88,6 +88,7 @@ void BlenderSession::create_session()
{
SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
+ bool session_pause = BlenderSync::get_session_pause(b_scene, background);
/* reset status/progress */
last_status = "";
@@ -107,15 +108,17 @@ void BlenderSession::create_session()
session->scene = scene;
session->progress.set_update_callback(function_bind(&BlenderSession::tag_redraw, this));
session->progress.set_cancel_callback(function_bind(&BlenderSession::test_cancel, this));
- session->set_pause(BlenderSync::get_session_pause(b_scene, background));
+ session->set_pause(session_pause);
/* create sync */
sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress, session_params.device.type == DEVICE_CPU);
if(b_v3d) {
- /* full data sync */
- sync->sync_data(b_v3d, b_engine.camera_override(), &python_thread_state);
- sync->sync_view(b_v3d, b_rv3d, width, height);
+ if(session_pause == false) {
+ /* full data sync */
+ sync->sync_view(b_v3d, b_rv3d, width, height);
+ sync->sync_data(b_v3d, b_engine.camera_override(), &python_thread_state);
+ }
}
else {
/* for final render we will do full data sync per render layer, only
@@ -492,7 +495,7 @@ static void populate_bake_data(BakeData *data, BL::BakePixel pixel_array, const
}
}
-void BlenderSession::bake(BL::Object b_object, const string& pass_type, BL::BakePixel pixel_array, int num_pixels, int depth, float result[])
+void BlenderSession::bake(BL::Object b_object, const string& pass_type, BL::BakePixel pixel_array, const size_t num_pixels, const int depth, float result[])
{
ShaderEvalType shader_type = get_shader_type(pass_type);
size_t object_index = OBJECT_NONE;
@@ -526,6 +529,7 @@ void BlenderSession::bake(BL::Object b_object, const string& pass_type, BL::Bake
SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_scene, b_v3d, b_rv3d, scene->camera, width, height);
+ scene->bake_manager->set_shader_limit((size_t)b_engine.tile_x(), (size_t)b_engine.tile_y());
scene->bake_manager->set_baking(true);
/* set number of samples */
@@ -554,6 +558,8 @@ void BlenderSession::bake(BL::Object b_object, const string& pass_type, BL::Bake
session->reset(buffer_params, session_params.samples);
session->update_scene();
+ session->progress.set_update_callback(function_bind(&BlenderSession::update_bake_progress, this));
+
scene->bake_manager->bake(scene->device, &scene->dscene, scene, session->progress, shader_type, bake_data, result);
/* free all memory used (host and device), so we wouldn't leave render
@@ -625,6 +631,7 @@ void BlenderSession::synchronize()
/* on session/scene parameter changes, we recreate session entirely */
SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
+ bool session_pause = BlenderSync::get_session_pause(b_scene, background);
if(session->params.modified(session_params) ||
scene->params.modified(scene_params))
@@ -637,12 +644,18 @@ void BlenderSession::synchronize()
/* increase samples, but never decrease */
session->set_samples(session_params.samples);
- session->set_pause(BlenderSync::get_session_pause(b_scene, background));
+ session->set_pause(session_pause);
/* copy recalc flags, outside of mutex so we can decide to do the real
* synchronization at a later time to not block on running updates */
sync->sync_recalc();
+ /* don't do synchronization if on pause */
+ if(session_pause) {
+ tag_update();
+ return;
+ }
+
/* try to acquire mutex. if we don't want to or can't, come back later */
if(!session->ready_to_reset() || !session->scene->mutex.try_lock()) {
tag_update();
@@ -718,10 +731,12 @@ bool BlenderSession::draw(int w, int h)
if(reset) {
SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_scene, b_v3d, b_rv3d, scene->camera, width, height);
+ bool session_pause = BlenderSync::get_session_pause(b_scene, background);
- session->reset(buffer_params, session_params.samples);
-
- start_resize_time = 0.0;
+ if(session_pause == false) {
+ session->reset(buffer_params, session_params.samples);
+ start_resize_time = 0.0;
+ }
}
}
else {
@@ -765,6 +780,26 @@ void BlenderSession::get_progress(float& progress, double& total_time)
progress = 0.0;
}
+void BlenderSession::update_bake_progress()
+{
+ float progress;
+ int sample, samples_per_task, parts_total;
+
+ sample = session->progress.get_sample();
+ samples_per_task = scene->bake_manager->num_samples;
+ parts_total = scene->bake_manager->num_parts;
+
+ if(samples_per_task)
+ progress = ((float)sample / (float)(parts_total * samples_per_task));
+ else
+ progress = 0.0;
+
+ if(progress != last_progress) {
+ b_engine.update_progress(progress);
+ last_progress = progress;
+ }
+}
+
void BlenderSession::update_status_progress()
{
string timestatus, status, substatus;
diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h
index 0e44493d674..ac685118b3d 100644
--- a/intern/cycles/blender/blender_session.h
+++ b/intern/cycles/blender/blender_session.h
@@ -52,7 +52,7 @@ public:
/* offline render */
void render();
- void bake(BL::Object b_object, const string& pass_type, BL::BakePixel pixel_array, int num_pixels, int depth, float pixels[]);
+ void bake(BL::Object b_object, const string& pass_type, BL::BakePixel pixel_array, const size_t num_pixels, const int depth, float pixels[]);
void write_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, RenderTile& rtile);
void write_render_tile(RenderTile& rtile);
@@ -73,6 +73,7 @@ public:
void get_progress(float& progress, double& total_time);
void test_cancel();
void update_status_progress();
+ void update_bake_progress();
bool background;
Session *session;
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index 51d8a4da744..7752c1ce1bd 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -572,6 +572,13 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
image->animated = b_image_node.image_user().use_auto_refresh();
image->use_alpha = b_image.use_alpha();
+
+ /* TODO(sergey): Does not work properly when we change builtin type. */
+ if (b_image.is_updated()) {
+ scene->image_manager->tag_reload_image(image->filename,
+ image->builtin_data,
+ (InterpolationType)b_image_node.interpolation());
+ }
}
image->color_space = ImageTextureNode::color_space_enum[(int)b_image_node.color_space()];
image->projection = ImageTextureNode::projection_enum[(int)b_image_node.projection()];
@@ -602,6 +609,13 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
}
env->use_alpha = b_image.use_alpha();
+
+ /* TODO(sergey): Does not work properly when we change builtin type. */
+ if (b_image.is_updated()) {
+ scene->image_manager->tag_reload_image(env->filename,
+ env->builtin_data,
+ INTERPOLATION_LINEAR);
+ }
}
env->color_space = EnvironmentTextureNode::color_space_enum[(int)b_env_node.color_space()];
env->projection = EnvironmentTextureNode::projection_enum[(int)b_env_node.projection()];
@@ -1057,6 +1071,7 @@ void BlenderSync::sync_world(bool update_all)
visibility |= get_boolean(cvisibility, "diffuse")? PATH_RAY_DIFFUSE: 0;
visibility |= get_boolean(cvisibility, "glossy")? PATH_RAY_GLOSSY: 0;
visibility |= get_boolean(cvisibility, "transmission")? PATH_RAY_TRANSMIT: 0;
+ visibility |= get_boolean(cvisibility, "scatter")? PATH_RAY_VOLUME_SCATTER: 0;
background->visibility = visibility;
}
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index 19898bfa573..2ac90b34fd7 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -180,10 +180,12 @@ void BlenderSync::sync_integrator()
integrator->volume_max_steps = get_int(cscene, "volume_max_steps");
integrator->volume_step_size = get_float(cscene, "volume_step_size");
- integrator->no_caustics = get_boolean(cscene, "no_caustics");
+ integrator->caustics_reflective = get_boolean(cscene, "caustics_reflective");
+ integrator->caustics_refractive = get_boolean(cscene, "caustics_refractive");
integrator->filter_glossy = get_float(cscene, "blur_glossy");
integrator->seed = get_int(cscene, "seed");
+ integrator->sampling_pattern = (SamplingPattern)RNA_enum_get(&cscene, "sampling_pattern");
integrator->layer_flag = render_layer.layer;
@@ -231,10 +233,6 @@ void BlenderSync::sync_integrator()
integrator->subsurface_samples = subsurface_samples;
integrator->volume_samples = volume_samples;
}
-
-
- if(experimental)
- integrator->sampling_pattern = (SamplingPattern)RNA_enum_get(&cscene, "sampling_pattern");
if(integrator->modified(previntegrator))
integrator->tag_update(scene);