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/CCL_api.h2
-rw-r--r--intern/cycles/blender/CMakeLists.txt98
-rw-r--r--intern/cycles/blender/blender_camera.cpp1541
-rw-r--r--intern/cycles/blender/blender_curves.cpp1961
-rw-r--r--intern/cycles/blender/blender_device.cpp140
-rw-r--r--intern/cycles/blender/blender_device.h8
-rw-r--r--intern/cycles/blender/blender_logging.cpp6
-rw-r--r--intern/cycles/blender/blender_mesh.cpp2173
-rw-r--r--intern/cycles/blender/blender_object.cpp1169
-rw-r--r--intern/cycles/blender/blender_object_cull.cpp193
-rw-r--r--intern/cycles/blender/blender_object_cull.h37
-rw-r--r--intern/cycles/blender/blender_particles.cpp116
-rw-r--r--intern/cycles/blender/blender_python.cpp1594
-rw-r--r--intern/cycles/blender/blender_session.cpp2538
-rw-r--r--intern/cycles/blender/blender_session.h298
-rw-r--r--intern/cycles/blender/blender_shader.cpp2589
-rw-r--r--intern/cycles/blender/blender_sync.cpp1463
-rw-r--r--intern/cycles/blender/blender_sync.h330
-rw-r--r--intern/cycles/blender/blender_texture.cpp50
-rw-r--r--intern/cycles/blender/blender_texture.h10
-rw-r--r--intern/cycles/blender/blender_util.h1078
21 files changed, 8668 insertions, 8726 deletions
diff --git a/intern/cycles/blender/CCL_api.h b/intern/cycles/blender/CCL_api.h
index b9750ad0c53..233ffc8802c 100644
--- a/intern/cycles/blender/CCL_api.h
+++ b/intern/cycles/blender/CCL_api.h
@@ -33,4 +33,4 @@ void CCL_logging_verbosity_set(int verbosity);
}
#endif
-#endif /* __CCL_API_H__ */
+#endif /* __CCL_API_H__ */
diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt
index fc265a47a01..7354b1e615e 100644
--- a/intern/cycles/blender/CMakeLists.txt
+++ b/intern/cycles/blender/CMakeLists.txt
@@ -1,68 +1,68 @@
set(INC
- ..
- ../../glew-mx
- ../../guardedalloc
- ../../mikktspace
- ../../../source/blender/makesdna
- ../../../source/blender/makesrna
- ../../../source/blender/blenlib
- ${CMAKE_BINARY_DIR}/source/blender/makesrna/intern
+ ..
+ ../../glew-mx
+ ../../guardedalloc
+ ../../mikktspace
+ ../../../source/blender/makesdna
+ ../../../source/blender/makesrna
+ ../../../source/blender/blenlib
+ ${CMAKE_BINARY_DIR}/source/blender/makesrna/intern
)
set(INC_SYS
- ${PYTHON_INCLUDE_DIRS}
- ${GLEW_INCLUDE_DIR}
+ ${PYTHON_INCLUDE_DIRS}
+ ${GLEW_INCLUDE_DIR}
)
set(SRC
- blender_camera.cpp
- blender_device.cpp
- blender_mesh.cpp
- blender_object.cpp
- blender_object_cull.cpp
- blender_particles.cpp
- blender_curves.cpp
- blender_logging.cpp
- blender_python.cpp
- blender_session.cpp
- blender_shader.cpp
- blender_sync.cpp
- blender_texture.cpp
+ blender_camera.cpp
+ blender_device.cpp
+ blender_mesh.cpp
+ blender_object.cpp
+ blender_object_cull.cpp
+ blender_particles.cpp
+ blender_curves.cpp
+ blender_logging.cpp
+ blender_python.cpp
+ blender_session.cpp
+ blender_shader.cpp
+ blender_sync.cpp
+ blender_texture.cpp
- CCL_api.h
- blender_object_cull.h
- blender_sync.h
- blender_session.h
- blender_texture.h
- blender_util.h
+ CCL_api.h
+ blender_object_cull.h
+ blender_sync.h
+ blender_session.h
+ blender_texture.h
+ blender_util.h
)
set(LIB
- cycles_bvh
- cycles_device
- cycles_graph
- cycles_kernel
- cycles_render
- cycles_subd
- cycles_util
+ cycles_bvh
+ cycles_device
+ cycles_graph
+ cycles_kernel
+ cycles_render
+ cycles_subd
+ cycles_util
)
if(WITH_CYCLES_LOGGING)
- list(APPEND LIB
- extern_glog
- )
+ list(APPEND LIB
+ extern_glog
+ )
endif()
set(ADDON_FILES
- addon/__init__.py
- addon/engine.py
- addon/operators.py
- addon/osl.py
- addon/presets.py
- addon/properties.py
- addon/ui.py
- addon/version_update.py
+ addon/__init__.py
+ addon/engine.py
+ addon/operators.py
+ addon/osl.py
+ addon/presets.py
+ addon/properties.py
+ addon/ui.py
+ addon/version_update.py
)
add_definitions(${GL_DEFINITIONS})
@@ -72,14 +72,14 @@ if(WITH_CYCLES_DEVICE_OPENCL)
endif()
if(WITH_CYCLES_NETWORK)
- add_definitions(-DWITH_NETWORK)
+ add_definitions(-DWITH_NETWORK)
endif()
blender_add_lib(bf_intern_cycles "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
# avoid link failure with clang 3.4 debug
if(CMAKE_C_COMPILER_ID MATCHES "Clang" AND NOT ${CMAKE_C_COMPILER_VERSION} VERSION_LESS '3.4')
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -gline-tables-only")
+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -gline-tables-only")
endif()
add_dependencies(bf_intern_cycles bf_rna)
diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp
index 21efba4cdf0..b3bfaa992a9 100644
--- a/intern/cycles/blender/blender_camera.cpp
+++ b/intern/cycles/blender/blender_camera.cpp
@@ -28,875 +28,858 @@ CCL_NAMESPACE_BEGIN
* render camera to this, and from there convert to our native camera format. */
struct BlenderCamera {
- float nearclip;
- float farclip;
+ float nearclip;
+ float farclip;
- CameraType type;
- float ortho_scale;
+ CameraType type;
+ float ortho_scale;
- float lens;
- float shuttertime;
- Camera::MotionPosition motion_position;
- array<float> shutter_curve;
+ float lens;
+ float shuttertime;
+ Camera::MotionPosition motion_position;
+ array<float> shutter_curve;
- Camera::RollingShutterType rolling_shutter_type;
- float rolling_shutter_duration;
+ Camera::RollingShutterType rolling_shutter_type;
+ float rolling_shutter_duration;
- float aperturesize;
- uint apertureblades;
- float aperturerotation;
- float focaldistance;
+ float aperturesize;
+ uint apertureblades;
+ float aperturerotation;
+ float focaldistance;
- float2 shift;
- float2 offset;
- float zoom;
+ float2 shift;
+ float2 offset;
+ float zoom;
- float2 pixelaspect;
+ float2 pixelaspect;
- float aperture_ratio;
+ float aperture_ratio;
- PanoramaType panorama_type;
- float fisheye_fov;
- float fisheye_lens;
- float latitude_min;
- float latitude_max;
- float longitude_min;
- float longitude_max;
- bool use_spherical_stereo;
- float interocular_distance;
- float convergence_distance;
- bool use_pole_merge;
- float pole_merge_angle_from;
- float pole_merge_angle_to;
+ PanoramaType panorama_type;
+ float fisheye_fov;
+ float fisheye_lens;
+ float latitude_min;
+ float latitude_max;
+ float longitude_min;
+ float longitude_max;
+ bool use_spherical_stereo;
+ float interocular_distance;
+ float convergence_distance;
+ bool use_pole_merge;
+ float pole_merge_angle_from;
+ float pole_merge_angle_to;
- enum { AUTO, HORIZONTAL, VERTICAL } sensor_fit;
- float sensor_width;
- float sensor_height;
+ enum { AUTO, HORIZONTAL, VERTICAL } sensor_fit;
+ float sensor_width;
+ float sensor_height;
- int full_width;
- int full_height;
+ int full_width;
+ int full_height;
- BoundBox2D border;
- BoundBox2D pano_viewplane;
- BoundBox2D viewport_camera_border;
+ BoundBox2D border;
+ BoundBox2D pano_viewplane;
+ BoundBox2D viewport_camera_border;
- Transform matrix;
+ Transform matrix;
- float offscreen_dicing_scale;
+ float offscreen_dicing_scale;
- int motion_steps;
+ int motion_steps;
};
-static void blender_camera_init(BlenderCamera *bcam,
- BL::RenderSettings& b_render)
+static void blender_camera_init(BlenderCamera *bcam, BL::RenderSettings &b_render)
{
- memset((void *)bcam, 0, sizeof(BlenderCamera));
-
- bcam->type = CAMERA_PERSPECTIVE;
- bcam->zoom = 1.0f;
- bcam->pixelaspect = make_float2(1.0f, 1.0f);
- bcam->sensor_width = 36.0f;
- bcam->sensor_height = 24.0f;
- bcam->sensor_fit = BlenderCamera::AUTO;
- bcam->shuttertime = 1.0f;
- bcam->motion_position = Camera::MOTION_POSITION_CENTER;
- bcam->rolling_shutter_type = Camera::ROLLING_SHUTTER_NONE;
- bcam->rolling_shutter_duration = 0.1f;
- bcam->border.right = 1.0f;
- bcam->border.top = 1.0f;
- bcam->pano_viewplane.right = 1.0f;
- bcam->pano_viewplane.top = 1.0f;
- bcam->viewport_camera_border.right = 1.0f;
- bcam->viewport_camera_border.top = 1.0f;
- bcam->offscreen_dicing_scale = 1.0f;
-
- /* render resolution */
- bcam->full_width = render_resolution_x(b_render);
- bcam->full_height = render_resolution_y(b_render);
+ memset((void *)bcam, 0, sizeof(BlenderCamera));
+
+ bcam->type = CAMERA_PERSPECTIVE;
+ bcam->zoom = 1.0f;
+ bcam->pixelaspect = make_float2(1.0f, 1.0f);
+ bcam->sensor_width = 36.0f;
+ bcam->sensor_height = 24.0f;
+ bcam->sensor_fit = BlenderCamera::AUTO;
+ bcam->shuttertime = 1.0f;
+ bcam->motion_position = Camera::MOTION_POSITION_CENTER;
+ bcam->rolling_shutter_type = Camera::ROLLING_SHUTTER_NONE;
+ bcam->rolling_shutter_duration = 0.1f;
+ bcam->border.right = 1.0f;
+ bcam->border.top = 1.0f;
+ bcam->pano_viewplane.right = 1.0f;
+ bcam->pano_viewplane.top = 1.0f;
+ bcam->viewport_camera_border.right = 1.0f;
+ bcam->viewport_camera_border.top = 1.0f;
+ bcam->offscreen_dicing_scale = 1.0f;
+
+ /* render resolution */
+ bcam->full_width = render_resolution_x(b_render);
+ bcam->full_height = render_resolution_y(b_render);
}
-static float blender_camera_focal_distance(BL::RenderEngine& b_engine,
- BL::Object& b_ob,
- BL::Camera& b_camera,
+static float blender_camera_focal_distance(BL::RenderEngine &b_engine,
+ BL::Object &b_ob,
+ BL::Camera &b_camera,
BlenderCamera *bcam)
{
- BL::Object b_dof_object = b_camera.dof_object();
-
- if(!b_dof_object)
- return b_camera.dof_distance();
-
- /* for dof object, return distance along camera Z direction */
- BL::Array<float, 16> b_ob_matrix;
- b_engine.camera_model_matrix(b_ob, bcam->use_spherical_stereo, b_ob_matrix);
- Transform obmat = transform_clear_scale(get_transform(b_ob_matrix));
- Transform dofmat = get_transform(b_dof_object.matrix_world());
- float3 view_dir = normalize(transform_get_column(&obmat, 2));
- float3 dof_dir = transform_get_column(&obmat, 3) - transform_get_column(&dofmat, 3);
- return fabsf(dot(view_dir, dof_dir));
+ BL::Object b_dof_object = b_camera.dof_object();
+
+ if (!b_dof_object)
+ return b_camera.dof_distance();
+
+ /* for dof object, return distance along camera Z direction */
+ BL::Array<float, 16> b_ob_matrix;
+ b_engine.camera_model_matrix(b_ob, bcam->use_spherical_stereo, b_ob_matrix);
+ Transform obmat = transform_clear_scale(get_transform(b_ob_matrix));
+ Transform dofmat = get_transform(b_dof_object.matrix_world());
+ float3 view_dir = normalize(transform_get_column(&obmat, 2));
+ float3 dof_dir = transform_get_column(&obmat, 3) - transform_get_column(&dofmat, 3);
+ return fabsf(dot(view_dir, dof_dir));
}
static void blender_camera_from_object(BlenderCamera *bcam,
- BL::RenderEngine& b_engine,
- BL::Object& b_ob,
+ BL::RenderEngine &b_engine,
+ BL::Object &b_ob,
bool skip_panorama = false)
{
- BL::ID b_ob_data = b_ob.data();
-
- if(b_ob_data.is_a(&RNA_Camera)) {
- BL::Camera b_camera(b_ob_data);
- PointerRNA ccamera = RNA_pointer_get(&b_camera.ptr, "cycles");
-
- bcam->nearclip = b_camera.clip_start();
- bcam->farclip = b_camera.clip_end();
-
- switch(b_camera.type())
- {
- case BL::Camera::type_ORTHO:
- bcam->type = CAMERA_ORTHOGRAPHIC;
- break;
- case BL::Camera::type_PANO:
- if(!skip_panorama)
- bcam->type = CAMERA_PANORAMA;
- else
- bcam->type = CAMERA_PERSPECTIVE;
- break;
- case BL::Camera::type_PERSP:
- default:
- bcam->type = CAMERA_PERSPECTIVE;
- break;
- }
-
- bcam->panorama_type = (PanoramaType)get_enum(ccamera,
- "panorama_type",
- PANORAMA_NUM_TYPES,
- PANORAMA_EQUIRECTANGULAR);
-
- bcam->fisheye_fov = RNA_float_get(&ccamera, "fisheye_fov");
- bcam->fisheye_lens = RNA_float_get(&ccamera, "fisheye_lens");
- bcam->latitude_min = RNA_float_get(&ccamera, "latitude_min");
- bcam->latitude_max = RNA_float_get(&ccamera, "latitude_max");
- bcam->longitude_min = RNA_float_get(&ccamera, "longitude_min");
- bcam->longitude_max = RNA_float_get(&ccamera, "longitude_max");
-
- bcam->interocular_distance = b_camera.stereo().interocular_distance();
- if(b_camera.stereo().convergence_mode() == BL::CameraStereoData::convergence_mode_PARALLEL) {
- bcam->convergence_distance = FLT_MAX;
- }
- else {
- bcam->convergence_distance = b_camera.stereo().convergence_distance();
- }
- bcam->use_spherical_stereo = b_engine.use_spherical_stereo(b_ob);
-
- bcam->use_pole_merge = b_camera.stereo().use_pole_merge();
- bcam->pole_merge_angle_from = b_camera.stereo().pole_merge_angle_from();
- bcam->pole_merge_angle_to = b_camera.stereo().pole_merge_angle_to();
-
- bcam->ortho_scale = b_camera.ortho_scale();
-
- bcam->lens = b_camera.lens();
-
- /* allow f/stop number to change aperture_size but still
- * give manual control over aperture radius */
- int aperture_type = get_enum(ccamera, "aperture_type");
-
- if(aperture_type == 1) {
- float fstop = RNA_float_get(&ccamera, "aperture_fstop");
- fstop = max(fstop, 1e-5f);
-
- if(bcam->type == CAMERA_ORTHOGRAPHIC)
- bcam->aperturesize = 1.0f/(2.0f*fstop);
- else
- bcam->aperturesize = (bcam->lens*1e-3f)/(2.0f*fstop);
- }
- else
- bcam->aperturesize = RNA_float_get(&ccamera, "aperture_size");
-
- bcam->apertureblades = RNA_int_get(&ccamera, "aperture_blades");
- bcam->aperturerotation = RNA_float_get(&ccamera, "aperture_rotation");
- bcam->focaldistance = blender_camera_focal_distance(b_engine, b_ob, b_camera, bcam);
- bcam->aperture_ratio = RNA_float_get(&ccamera, "aperture_ratio");
-
- bcam->shift.x = b_engine.camera_shift_x(b_ob, bcam->use_spherical_stereo);
- bcam->shift.y = b_camera.shift_y();
-
- bcam->sensor_width = b_camera.sensor_width();
- bcam->sensor_height = b_camera.sensor_height();
-
- if(b_camera.sensor_fit() == BL::Camera::sensor_fit_AUTO)
- bcam->sensor_fit = BlenderCamera::AUTO;
- else if(b_camera.sensor_fit() == BL::Camera::sensor_fit_HORIZONTAL)
- bcam->sensor_fit = BlenderCamera::HORIZONTAL;
- else
- bcam->sensor_fit = BlenderCamera::VERTICAL;
- }
- else if(b_ob_data.is_a(&RNA_Light)) {
- /* Can also look through spot light. */
- BL::SpotLight b_light(b_ob_data);
- float lens = 16.0f / tanf(b_light.spot_size() * 0.5f);
- if (lens > 0.0f) {
- bcam->lens = lens;
- }
- }
-
- bcam->motion_steps = object_motion_steps(b_ob, b_ob);
+ BL::ID b_ob_data = b_ob.data();
+
+ if (b_ob_data.is_a(&RNA_Camera)) {
+ BL::Camera b_camera(b_ob_data);
+ PointerRNA ccamera = RNA_pointer_get(&b_camera.ptr, "cycles");
+
+ bcam->nearclip = b_camera.clip_start();
+ bcam->farclip = b_camera.clip_end();
+
+ switch (b_camera.type()) {
+ case BL::Camera::type_ORTHO:
+ bcam->type = CAMERA_ORTHOGRAPHIC;
+ break;
+ case BL::Camera::type_PANO:
+ if (!skip_panorama)
+ bcam->type = CAMERA_PANORAMA;
+ else
+ bcam->type = CAMERA_PERSPECTIVE;
+ break;
+ case BL::Camera::type_PERSP:
+ default:
+ bcam->type = CAMERA_PERSPECTIVE;
+ break;
+ }
+
+ bcam->panorama_type = (PanoramaType)get_enum(
+ ccamera, "panorama_type", PANORAMA_NUM_TYPES, PANORAMA_EQUIRECTANGULAR);
+
+ bcam->fisheye_fov = RNA_float_get(&ccamera, "fisheye_fov");
+ bcam->fisheye_lens = RNA_float_get(&ccamera, "fisheye_lens");
+ bcam->latitude_min = RNA_float_get(&ccamera, "latitude_min");
+ bcam->latitude_max = RNA_float_get(&ccamera, "latitude_max");
+ bcam->longitude_min = RNA_float_get(&ccamera, "longitude_min");
+ bcam->longitude_max = RNA_float_get(&ccamera, "longitude_max");
+
+ bcam->interocular_distance = b_camera.stereo().interocular_distance();
+ if (b_camera.stereo().convergence_mode() == BL::CameraStereoData::convergence_mode_PARALLEL) {
+ bcam->convergence_distance = FLT_MAX;
+ }
+ else {
+ bcam->convergence_distance = b_camera.stereo().convergence_distance();
+ }
+ bcam->use_spherical_stereo = b_engine.use_spherical_stereo(b_ob);
+
+ bcam->use_pole_merge = b_camera.stereo().use_pole_merge();
+ bcam->pole_merge_angle_from = b_camera.stereo().pole_merge_angle_from();
+ bcam->pole_merge_angle_to = b_camera.stereo().pole_merge_angle_to();
+
+ bcam->ortho_scale = b_camera.ortho_scale();
+
+ bcam->lens = b_camera.lens();
+
+ /* allow f/stop number to change aperture_size but still
+ * give manual control over aperture radius */
+ int aperture_type = get_enum(ccamera, "aperture_type");
+
+ if (aperture_type == 1) {
+ float fstop = RNA_float_get(&ccamera, "aperture_fstop");
+ fstop = max(fstop, 1e-5f);
+
+ if (bcam->type == CAMERA_ORTHOGRAPHIC)
+ bcam->aperturesize = 1.0f / (2.0f * fstop);
+ else
+ bcam->aperturesize = (bcam->lens * 1e-3f) / (2.0f * fstop);
+ }
+ else
+ bcam->aperturesize = RNA_float_get(&ccamera, "aperture_size");
+
+ bcam->apertureblades = RNA_int_get(&ccamera, "aperture_blades");
+ bcam->aperturerotation = RNA_float_get(&ccamera, "aperture_rotation");
+ bcam->focaldistance = blender_camera_focal_distance(b_engine, b_ob, b_camera, bcam);
+ bcam->aperture_ratio = RNA_float_get(&ccamera, "aperture_ratio");
+
+ bcam->shift.x = b_engine.camera_shift_x(b_ob, bcam->use_spherical_stereo);
+ bcam->shift.y = b_camera.shift_y();
+
+ bcam->sensor_width = b_camera.sensor_width();
+ bcam->sensor_height = b_camera.sensor_height();
+
+ if (b_camera.sensor_fit() == BL::Camera::sensor_fit_AUTO)
+ bcam->sensor_fit = BlenderCamera::AUTO;
+ else if (b_camera.sensor_fit() == BL::Camera::sensor_fit_HORIZONTAL)
+ bcam->sensor_fit = BlenderCamera::HORIZONTAL;
+ else
+ bcam->sensor_fit = BlenderCamera::VERTICAL;
+ }
+ else if (b_ob_data.is_a(&RNA_Light)) {
+ /* Can also look through spot light. */
+ BL::SpotLight b_light(b_ob_data);
+ float lens = 16.0f / tanf(b_light.spot_size() * 0.5f);
+ if (lens > 0.0f) {
+ bcam->lens = lens;
+ }
+ }
+
+ bcam->motion_steps = object_motion_steps(b_ob, b_ob);
}
-static Transform blender_camera_matrix(const Transform& tfm,
+static Transform blender_camera_matrix(const Transform &tfm,
const CameraType type,
const PanoramaType panorama_type)
{
- Transform result;
-
- if(type == CAMERA_PANORAMA) {
- if(panorama_type == PANORAMA_MIRRORBALL) {
- /* Mirror ball camera is looking into the negative Y direction
- * which matches texture mirror ball mapping.
- */
- result = tfm *
- make_transform(1.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f,
- 0.0f, 1.0f, 0.0f, 0.0f);
- }
- else {
- /* Make it so environment camera needs to be pointed in the direction
- * of the positive x-axis to match an environment texture, this way
- * it is looking at the center of the texture
- */
- result = tfm *
- make_transform( 0.0f, -1.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f,
- -1.0f, 0.0f, 0.0f, 0.0f);
- }
- }
- else {
- /* note the blender camera points along the negative z-axis */
- result = tfm * transform_scale(1.0f, 1.0f, -1.0f);
- }
-
- return transform_clear_scale(result);
+ Transform result;
+
+ if (type == CAMERA_PANORAMA) {
+ if (panorama_type == PANORAMA_MIRRORBALL) {
+ /* Mirror ball camera is looking into the negative Y direction
+ * which matches texture mirror ball mapping.
+ */
+ result = tfm * make_transform(
+ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
+ }
+ else {
+ /* Make it so environment camera needs to be pointed in the direction
+ * of the positive x-axis to match an environment texture, this way
+ * it is looking at the center of the texture
+ */
+ result = tfm * make_transform(
+ 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f);
+ }
+ }
+ else {
+ /* note the blender camera points along the negative z-axis */
+ result = tfm * transform_scale(1.0f, 1.0f, -1.0f);
+ }
+
+ return transform_clear_scale(result);
}
static void blender_camera_viewplane(BlenderCamera *bcam,
- int width, int height,
+ int width,
+ int height,
BoundBox2D *viewplane,
float *aspectratio,
float *sensor_size)
{
- /* dimensions */
- float xratio = (float)width*bcam->pixelaspect.x;
- float yratio = (float)height*bcam->pixelaspect.y;
-
- /* compute x/y aspect and ratio */
- float xaspect, yaspect;
- bool horizontal_fit;
-
- /* sensor fitting */
- if(bcam->sensor_fit == BlenderCamera::AUTO) {
- horizontal_fit = (xratio > yratio);
- if(sensor_size != NULL) {
- *sensor_size = bcam->sensor_width;
- }
- }
- else if(bcam->sensor_fit == BlenderCamera::HORIZONTAL) {
- horizontal_fit = true;
- if(sensor_size != NULL) {
- *sensor_size = bcam->sensor_width;
- }
- }
- else {
- horizontal_fit = false;
- if(sensor_size != NULL) {
- *sensor_size = bcam->sensor_height;
- }
- }
-
- if(horizontal_fit) {
- if(aspectratio != NULL) {
- *aspectratio = xratio/yratio;
- }
- xaspect = *aspectratio;
- yaspect = 1.0f;
- }
- else {
- if(aspectratio != NULL) {
- *aspectratio = yratio/xratio;
- }
- xaspect = 1.0f;
- yaspect = *aspectratio;
- }
-
- /* modify aspect for orthographic scale */
- if(bcam->type == CAMERA_ORTHOGRAPHIC) {
- xaspect = xaspect*bcam->ortho_scale/(*aspectratio*2.0f);
- yaspect = yaspect*bcam->ortho_scale/(*aspectratio*2.0f);
- if(aspectratio != NULL) {
- *aspectratio = bcam->ortho_scale/2.0f;
- }
- }
-
- if(bcam->type == CAMERA_PANORAMA) {
- /* set viewplane */
- if(viewplane != NULL) {
- *viewplane = bcam->pano_viewplane;
- }
- }
- else {
- /* set viewplane */
- if(viewplane != NULL) {
- viewplane->left = -xaspect;
- viewplane->right = xaspect;
- viewplane->bottom = -yaspect;
- viewplane->top = yaspect;
-
- /* zoom for 3d camera view */
- *viewplane = (*viewplane) * bcam->zoom;
-
- /* modify viewplane with camera shift and 3d camera view offset */
- float dx = 2.0f*(*aspectratio*bcam->shift.x + bcam->offset.x*xaspect*2.0f);
- float dy = 2.0f*(*aspectratio*bcam->shift.y + bcam->offset.y*yaspect*2.0f);
-
- viewplane->left += dx;
- viewplane->right += dx;
- viewplane->bottom += dy;
- viewplane->top += dy;
- }
- }
+ /* dimensions */
+ float xratio = (float)width * bcam->pixelaspect.x;
+ float yratio = (float)height * bcam->pixelaspect.y;
+
+ /* compute x/y aspect and ratio */
+ float xaspect, yaspect;
+ bool horizontal_fit;
+
+ /* sensor fitting */
+ if (bcam->sensor_fit == BlenderCamera::AUTO) {
+ horizontal_fit = (xratio > yratio);
+ if (sensor_size != NULL) {
+ *sensor_size = bcam->sensor_width;
+ }
+ }
+ else if (bcam->sensor_fit == BlenderCamera::HORIZONTAL) {
+ horizontal_fit = true;
+ if (sensor_size != NULL) {
+ *sensor_size = bcam->sensor_width;
+ }
+ }
+ else {
+ horizontal_fit = false;
+ if (sensor_size != NULL) {
+ *sensor_size = bcam->sensor_height;
+ }
+ }
+
+ if (horizontal_fit) {
+ if (aspectratio != NULL) {
+ *aspectratio = xratio / yratio;
+ }
+ xaspect = *aspectratio;
+ yaspect = 1.0f;
+ }
+ else {
+ if (aspectratio != NULL) {
+ *aspectratio = yratio / xratio;
+ }
+ xaspect = 1.0f;
+ yaspect = *aspectratio;
+ }
+
+ /* modify aspect for orthographic scale */
+ if (bcam->type == CAMERA_ORTHOGRAPHIC) {
+ xaspect = xaspect * bcam->ortho_scale / (*aspectratio * 2.0f);
+ yaspect = yaspect * bcam->ortho_scale / (*aspectratio * 2.0f);
+ if (aspectratio != NULL) {
+ *aspectratio = bcam->ortho_scale / 2.0f;
+ }
+ }
+
+ if (bcam->type == CAMERA_PANORAMA) {
+ /* set viewplane */
+ if (viewplane != NULL) {
+ *viewplane = bcam->pano_viewplane;
+ }
+ }
+ else {
+ /* set viewplane */
+ if (viewplane != NULL) {
+ viewplane->left = -xaspect;
+ viewplane->right = xaspect;
+ viewplane->bottom = -yaspect;
+ viewplane->top = yaspect;
+
+ /* zoom for 3d camera view */
+ *viewplane = (*viewplane) * bcam->zoom;
+
+ /* modify viewplane with camera shift and 3d camera view offset */
+ float dx = 2.0f * (*aspectratio * bcam->shift.x + bcam->offset.x * xaspect * 2.0f);
+ float dy = 2.0f * (*aspectratio * bcam->shift.y + bcam->offset.y * yaspect * 2.0f);
+
+ viewplane->left += dx;
+ viewplane->right += dx;
+ viewplane->bottom += dy;
+ viewplane->top += dy;
+ }
+ }
}
static void blender_camera_sync(Camera *cam,
BlenderCamera *bcam,
- int width, int height,
+ int width,
+ int height,
const char *viewname,
PointerRNA *cscene)
{
- /* copy camera to compare later */
- Camera prevcam = *cam;
- float aspectratio, sensor_size;
-
- /* viewplane */
- blender_camera_viewplane(bcam, width, height,
- &cam->viewplane, &aspectratio, &sensor_size);
-
- cam->width = bcam->full_width;
- cam->height = bcam->full_height;
-
- cam->full_width = width;
- cam->full_height = height;
-
- /* panorama sensor */
- if(bcam->type == CAMERA_PANORAMA && bcam->panorama_type == PANORAMA_FISHEYE_EQUISOLID) {
- float fit_xratio = (float)bcam->full_width*bcam->pixelaspect.x;
- float fit_yratio = (float)bcam->full_height*bcam->pixelaspect.y;
- bool horizontal_fit;
- float sensor_size;
-
- if(bcam->sensor_fit == BlenderCamera::AUTO) {
- horizontal_fit = (fit_xratio > fit_yratio);
- sensor_size = bcam->sensor_width;
- }
- else if(bcam->sensor_fit == BlenderCamera::HORIZONTAL) {
- horizontal_fit = true;
- sensor_size = bcam->sensor_width;
- }
- else { /* vertical */
- horizontal_fit = false;
- sensor_size = bcam->sensor_height;
- }
-
- if(horizontal_fit) {
- cam->sensorwidth = sensor_size;
- cam->sensorheight = sensor_size * fit_yratio / fit_xratio;
- }
- else {
- cam->sensorwidth = sensor_size * fit_xratio / fit_yratio;
- cam->sensorheight = sensor_size;
- }
- }
-
- /* clipping distances */
- cam->nearclip = bcam->nearclip;
- cam->farclip = bcam->farclip;
-
- /* type */
- cam->type = bcam->type;
-
- /* panorama */
- cam->panorama_type = bcam->panorama_type;
- cam->fisheye_fov = bcam->fisheye_fov;
- cam->fisheye_lens = bcam->fisheye_lens;
- cam->latitude_min = bcam->latitude_min;
- cam->latitude_max = bcam->latitude_max;
-
- cam->longitude_min = bcam->longitude_min;
- cam->longitude_max = bcam->longitude_max;
-
- /* panorama stereo */
- cam->interocular_distance = bcam->interocular_distance;
- cam->convergence_distance = bcam->convergence_distance;
- cam->use_spherical_stereo = bcam->use_spherical_stereo;
-
- if(cam->use_spherical_stereo) {
- if(strcmp(viewname, "left") == 0)
- cam->stereo_eye = Camera::STEREO_LEFT;
- else if(strcmp(viewname, "right") == 0)
- cam->stereo_eye = Camera::STEREO_RIGHT;
- else
- cam->stereo_eye = Camera::STEREO_NONE;
- }
-
- cam->use_pole_merge = bcam->use_pole_merge;
- cam->pole_merge_angle_from = bcam->pole_merge_angle_from;
- cam->pole_merge_angle_to = bcam->pole_merge_angle_to;
-
- /* 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;
- cam->aperturesize = bcam->aperturesize;
- cam->blades = bcam->apertureblades;
- cam->bladesrotation = bcam->aperturerotation;
-
- /* transform */
- cam->matrix = blender_camera_matrix(bcam->matrix,
- bcam->type,
- bcam->panorama_type);
- cam->motion.clear();
- cam->motion.resize(bcam->motion_steps, cam->matrix);
- cam->use_perspective_motion = false;
- cam->shuttertime = bcam->shuttertime;
- cam->fov_pre = cam->fov;
- cam->fov_post = cam->fov;
- cam->motion_position = bcam->motion_position;
-
- cam->rolling_shutter_type = bcam->rolling_shutter_type;
- cam->rolling_shutter_duration = bcam->rolling_shutter_duration;
-
- cam->shutter_curve = bcam->shutter_curve;
-
- /* border */
- cam->border = bcam->border;
- cam->viewport_camera_border = bcam->viewport_camera_border;
-
- bcam->offscreen_dicing_scale = RNA_float_get(cscene, "offscreen_dicing_scale");
- cam->offscreen_dicing_scale = bcam->offscreen_dicing_scale;
-
- /* set update flag */
- if(cam->modified(prevcam))
- cam->tag_update();
+ /* copy camera to compare later */
+ Camera prevcam = *cam;
+ float aspectratio, sensor_size;
+
+ /* viewplane */
+ blender_camera_viewplane(bcam, width, height, &cam->viewplane, &aspectratio, &sensor_size);
+
+ cam->width = bcam->full_width;
+ cam->height = bcam->full_height;
+
+ cam->full_width = width;
+ cam->full_height = height;
+
+ /* panorama sensor */
+ if (bcam->type == CAMERA_PANORAMA && bcam->panorama_type == PANORAMA_FISHEYE_EQUISOLID) {
+ float fit_xratio = (float)bcam->full_width * bcam->pixelaspect.x;
+ float fit_yratio = (float)bcam->full_height * bcam->pixelaspect.y;
+ bool horizontal_fit;
+ float sensor_size;
+
+ if (bcam->sensor_fit == BlenderCamera::AUTO) {
+ horizontal_fit = (fit_xratio > fit_yratio);
+ sensor_size = bcam->sensor_width;
+ }
+ else if (bcam->sensor_fit == BlenderCamera::HORIZONTAL) {
+ horizontal_fit = true;
+ sensor_size = bcam->sensor_width;
+ }
+ else { /* vertical */
+ horizontal_fit = false;
+ sensor_size = bcam->sensor_height;
+ }
+
+ if (horizontal_fit) {
+ cam->sensorwidth = sensor_size;
+ cam->sensorheight = sensor_size * fit_yratio / fit_xratio;
+ }
+ else {
+ cam->sensorwidth = sensor_size * fit_xratio / fit_yratio;
+ cam->sensorheight = sensor_size;
+ }
+ }
+
+ /* clipping distances */
+ cam->nearclip = bcam->nearclip;
+ cam->farclip = bcam->farclip;
+
+ /* type */
+ cam->type = bcam->type;
+
+ /* panorama */
+ cam->panorama_type = bcam->panorama_type;
+ cam->fisheye_fov = bcam->fisheye_fov;
+ cam->fisheye_lens = bcam->fisheye_lens;
+ cam->latitude_min = bcam->latitude_min;
+ cam->latitude_max = bcam->latitude_max;
+
+ cam->longitude_min = bcam->longitude_min;
+ cam->longitude_max = bcam->longitude_max;
+
+ /* panorama stereo */
+ cam->interocular_distance = bcam->interocular_distance;
+ cam->convergence_distance = bcam->convergence_distance;
+ cam->use_spherical_stereo = bcam->use_spherical_stereo;
+
+ if (cam->use_spherical_stereo) {
+ if (strcmp(viewname, "left") == 0)
+ cam->stereo_eye = Camera::STEREO_LEFT;
+ else if (strcmp(viewname, "right") == 0)
+ cam->stereo_eye = Camera::STEREO_RIGHT;
+ else
+ cam->stereo_eye = Camera::STEREO_NONE;
+ }
+
+ cam->use_pole_merge = bcam->use_pole_merge;
+ cam->pole_merge_angle_from = bcam->pole_merge_angle_from;
+ cam->pole_merge_angle_to = bcam->pole_merge_angle_to;
+
+ /* 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;
+ cam->aperturesize = bcam->aperturesize;
+ cam->blades = bcam->apertureblades;
+ cam->bladesrotation = bcam->aperturerotation;
+
+ /* transform */
+ cam->matrix = blender_camera_matrix(bcam->matrix, bcam->type, bcam->panorama_type);
+ cam->motion.clear();
+ cam->motion.resize(bcam->motion_steps, cam->matrix);
+ cam->use_perspective_motion = false;
+ cam->shuttertime = bcam->shuttertime;
+ cam->fov_pre = cam->fov;
+ cam->fov_post = cam->fov;
+ cam->motion_position = bcam->motion_position;
+
+ cam->rolling_shutter_type = bcam->rolling_shutter_type;
+ cam->rolling_shutter_duration = bcam->rolling_shutter_duration;
+
+ cam->shutter_curve = bcam->shutter_curve;
+
+ /* border */
+ cam->border = bcam->border;
+ cam->viewport_camera_border = bcam->viewport_camera_border;
+
+ bcam->offscreen_dicing_scale = RNA_float_get(cscene, "offscreen_dicing_scale");
+ cam->offscreen_dicing_scale = bcam->offscreen_dicing_scale;
+
+ /* set update flag */
+ if (cam->modified(prevcam))
+ cam->tag_update();
}
/* Sync Render Camera */
-void BlenderSync::sync_camera(BL::RenderSettings& b_render,
- BL::Object& b_override,
- int width, int height,
+void BlenderSync::sync_camera(BL::RenderSettings &b_render,
+ BL::Object &b_override,
+ int width,
+ int height,
const char *viewname)
{
- BlenderCamera bcam;
- blender_camera_init(&bcam, b_render);
-
- /* pixel aspect */
- bcam.pixelaspect.x = b_render.pixel_aspect_x();
- bcam.pixelaspect.y = b_render.pixel_aspect_y();
- bcam.shuttertime = b_render.motion_blur_shutter();
-
- BL::CurveMapping b_shutter_curve(b_render.motion_blur_shutter_curve());
- curvemapping_to_array(b_shutter_curve, bcam.shutter_curve, RAMP_TABLE_SIZE);
-
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
- bcam.motion_position =
- (Camera::MotionPosition)get_enum(cscene,
- "motion_blur_position",
- Camera::MOTION_NUM_POSITIONS,
- Camera::MOTION_POSITION_CENTER);
- bcam.rolling_shutter_type =
- (Camera::RollingShutterType)get_enum(cscene,
- "rolling_shutter_type",
- Camera::ROLLING_SHUTTER_NUM_TYPES,
- Camera::ROLLING_SHUTTER_NONE);
- bcam.rolling_shutter_duration = RNA_float_get(&cscene, "rolling_shutter_duration");
-
- /* border */
- if(b_render.use_border()) {
- bcam.border.left = b_render.border_min_x();
- bcam.border.right = b_render.border_max_x();
- bcam.border.bottom = b_render.border_min_y();
- bcam.border.top = b_render.border_max_y();
- }
-
- /* camera object */
- BL::Object b_ob = b_scene.camera();
-
- if(b_override)
- b_ob = b_override;
-
- if(b_ob) {
- BL::Array<float, 16> b_ob_matrix;
- blender_camera_from_object(&bcam, b_engine, b_ob);
- b_engine.camera_model_matrix(b_ob, bcam.use_spherical_stereo, b_ob_matrix);
- bcam.matrix = get_transform(b_ob_matrix);
- }
-
- /* sync */
- Camera *cam = scene->camera;
- blender_camera_sync(cam, &bcam, width, height, viewname, &cscene);
-
- /* dicing camera */
- b_ob = BL::Object(RNA_pointer_get(&cscene, "dicing_camera"));
- if(b_ob) {
- BL::Array<float, 16> b_ob_matrix;
- blender_camera_from_object(&bcam, b_engine, b_ob);
- b_engine.camera_model_matrix(b_ob, bcam.use_spherical_stereo, b_ob_matrix);
- bcam.matrix = get_transform(b_ob_matrix);
-
- blender_camera_sync(scene->dicing_camera, &bcam, width, height, viewname, &cscene);
- }
- else {
- *scene->dicing_camera = *cam;
- }
+ BlenderCamera bcam;
+ blender_camera_init(&bcam, b_render);
+
+ /* pixel aspect */
+ bcam.pixelaspect.x = b_render.pixel_aspect_x();
+ bcam.pixelaspect.y = b_render.pixel_aspect_y();
+ bcam.shuttertime = b_render.motion_blur_shutter();
+
+ BL::CurveMapping b_shutter_curve(b_render.motion_blur_shutter_curve());
+ curvemapping_to_array(b_shutter_curve, bcam.shutter_curve, RAMP_TABLE_SIZE);
+
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+ bcam.motion_position = (Camera::MotionPosition)get_enum(cscene,
+ "motion_blur_position",
+ Camera::MOTION_NUM_POSITIONS,
+ Camera::MOTION_POSITION_CENTER);
+ bcam.rolling_shutter_type = (Camera::RollingShutterType)get_enum(
+ cscene,
+ "rolling_shutter_type",
+ Camera::ROLLING_SHUTTER_NUM_TYPES,
+ Camera::ROLLING_SHUTTER_NONE);
+ bcam.rolling_shutter_duration = RNA_float_get(&cscene, "rolling_shutter_duration");
+
+ /* border */
+ if (b_render.use_border()) {
+ bcam.border.left = b_render.border_min_x();
+ bcam.border.right = b_render.border_max_x();
+ bcam.border.bottom = b_render.border_min_y();
+ bcam.border.top = b_render.border_max_y();
+ }
+
+ /* camera object */
+ BL::Object b_ob = b_scene.camera();
+
+ if (b_override)
+ b_ob = b_override;
+
+ if (b_ob) {
+ BL::Array<float, 16> b_ob_matrix;
+ blender_camera_from_object(&bcam, b_engine, b_ob);
+ b_engine.camera_model_matrix(b_ob, bcam.use_spherical_stereo, b_ob_matrix);
+ bcam.matrix = get_transform(b_ob_matrix);
+ }
+
+ /* sync */
+ Camera *cam = scene->camera;
+ blender_camera_sync(cam, &bcam, width, height, viewname, &cscene);
+
+ /* dicing camera */
+ b_ob = BL::Object(RNA_pointer_get(&cscene, "dicing_camera"));
+ if (b_ob) {
+ BL::Array<float, 16> b_ob_matrix;
+ blender_camera_from_object(&bcam, b_engine, b_ob);
+ b_engine.camera_model_matrix(b_ob, bcam.use_spherical_stereo, b_ob_matrix);
+ bcam.matrix = get_transform(b_ob_matrix);
+
+ blender_camera_sync(scene->dicing_camera, &bcam, width, height, viewname, &cscene);
+ }
+ else {
+ *scene->dicing_camera = *cam;
+ }
}
-void BlenderSync::sync_camera_motion(BL::RenderSettings& b_render,
- BL::Object& b_ob,
- int width, int height,
- float motion_time)
+void BlenderSync::sync_camera_motion(
+ BL::RenderSettings &b_render, BL::Object &b_ob, int width, int height, float motion_time)
{
- if(!b_ob)
- return;
-
- Camera *cam = scene->camera;
- BL::Array<float, 16> b_ob_matrix;
- b_engine.camera_model_matrix(b_ob, cam->use_spherical_stereo, b_ob_matrix);
- Transform tfm = get_transform(b_ob_matrix);
- tfm = blender_camera_matrix(tfm, cam->type, cam->panorama_type);
-
- if(motion_time == 0.0f) {
- /* When motion blur is not centered in frame, cam->matrix gets reset. */
- cam->matrix = tfm;
- }
-
- /* Set transform in motion array. */
- int motion_step = cam->motion_step(motion_time);
- if(motion_step >= 0) {
- cam->motion[motion_step] = tfm;
- }
-
- if(cam->type == CAMERA_PERSPECTIVE) {
- BlenderCamera bcam;
- float aspectratio, sensor_size;
- blender_camera_init(&bcam, b_render);
-
- /* TODO(sergey): Consider making it a part of blender_camera_init(). */
- bcam.pixelaspect.x = b_render.pixel_aspect_x();
- bcam.pixelaspect.y = b_render.pixel_aspect_y();
-
- blender_camera_from_object(&bcam, b_engine, b_ob);
- blender_camera_viewplane(&bcam,
- width, height,
- NULL,
- &aspectratio,
- &sensor_size);
- /* TODO(sergey): De-duplicate calculation with camera sync. */
- float fov = 2.0f * atanf((0.5f * sensor_size) / bcam.lens / aspectratio);
- if(fov != cam->fov) {
- VLOG(1) << "Camera " << b_ob.name() << " FOV change detected.";
- if(motion_time == 0.0f) {
- cam->fov = fov;
- }
- else if(motion_time == -1.0f) {
- cam->fov_pre = fov;
- cam->use_perspective_motion = true;
- }
- else if(motion_time == 1.0f) {
- cam->fov_post = fov;
- cam->use_perspective_motion = true;
- }
- }
- }
+ if (!b_ob)
+ return;
+
+ Camera *cam = scene->camera;
+ BL::Array<float, 16> b_ob_matrix;
+ b_engine.camera_model_matrix(b_ob, cam->use_spherical_stereo, b_ob_matrix);
+ Transform tfm = get_transform(b_ob_matrix);
+ tfm = blender_camera_matrix(tfm, cam->type, cam->panorama_type);
+
+ if (motion_time == 0.0f) {
+ /* When motion blur is not centered in frame, cam->matrix gets reset. */
+ cam->matrix = tfm;
+ }
+
+ /* Set transform in motion array. */
+ int motion_step = cam->motion_step(motion_time);
+ if (motion_step >= 0) {
+ cam->motion[motion_step] = tfm;
+ }
+
+ if (cam->type == CAMERA_PERSPECTIVE) {
+ BlenderCamera bcam;
+ float aspectratio, sensor_size;
+ blender_camera_init(&bcam, b_render);
+
+ /* TODO(sergey): Consider making it a part of blender_camera_init(). */
+ bcam.pixelaspect.x = b_render.pixel_aspect_x();
+ bcam.pixelaspect.y = b_render.pixel_aspect_y();
+
+ blender_camera_from_object(&bcam, b_engine, b_ob);
+ blender_camera_viewplane(&bcam, width, height, NULL, &aspectratio, &sensor_size);
+ /* TODO(sergey): De-duplicate calculation with camera sync. */
+ float fov = 2.0f * atanf((0.5f * sensor_size) / bcam.lens / aspectratio);
+ if (fov != cam->fov) {
+ VLOG(1) << "Camera " << b_ob.name() << " FOV change detected.";
+ if (motion_time == 0.0f) {
+ cam->fov = fov;
+ }
+ else if (motion_time == -1.0f) {
+ cam->fov_pre = fov;
+ cam->use_perspective_motion = true;
+ }
+ else if (motion_time == 1.0f) {
+ cam->fov_post = fov;
+ cam->use_perspective_motion = true;
+ }
+ }
+ }
}
/* Sync 3D View Camera */
-static void blender_camera_view_subset(BL::RenderEngine& b_engine,
- BL::RenderSettings& b_render,
- BL::Scene& b_scene,
- BL::Object& b_ob,
- BL::SpaceView3D& b_v3d,
- BL::RegionView3D& b_rv3d,
- int width, int height,
+static void blender_camera_view_subset(BL::RenderEngine &b_engine,
+ BL::RenderSettings &b_render,
+ BL::Scene &b_scene,
+ BL::Object &b_ob,
+ BL::SpaceView3D &b_v3d,
+ BL::RegionView3D &b_rv3d,
+ int width,
+ int height,
BoundBox2D *view_box,
BoundBox2D *cam_box);
static void blender_camera_from_view(BlenderCamera *bcam,
- BL::RenderEngine& b_engine,
- BL::Scene& b_scene,
- BL::SpaceView3D& b_v3d,
- BL::RegionView3D& b_rv3d,
- int width, int height,
+ BL::RenderEngine &b_engine,
+ BL::Scene &b_scene,
+ BL::SpaceView3D &b_v3d,
+ BL::RegionView3D &b_rv3d,
+ int width,
+ int height,
bool skip_panorama = false)
{
- /* 3d view parameters */
- bcam->nearclip = b_v3d.clip_start();
- bcam->farclip = b_v3d.clip_end();
- bcam->lens = b_v3d.lens();
- bcam->shuttertime = b_scene.render().motion_blur_shutter();
-
- BL::CurveMapping b_shutter_curve(b_scene.render().motion_blur_shutter_curve());
- curvemapping_to_array(b_shutter_curve, bcam->shutter_curve, RAMP_TABLE_SIZE);
-
- if(b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_CAMERA) {
- /* camera view */
- BL::Object b_ob = (b_v3d.use_local_camera())? b_v3d.camera(): b_scene.camera();
-
- if(b_ob) {
- blender_camera_from_object(bcam, b_engine, b_ob, skip_panorama);
-
- if(!skip_panorama && bcam->type == CAMERA_PANORAMA) {
- /* in panorama camera view, we map viewplane to camera border */
- BoundBox2D view_box, cam_box;
-
- BL::RenderSettings b_render_settings(b_scene.render());
- blender_camera_view_subset(b_engine,
- b_render_settings,
- b_scene,
- b_ob,
- b_v3d,
- b_rv3d,
- width, height,
- &view_box,
- &cam_box);
-
- bcam->pano_viewplane = view_box.make_relative_to(cam_box);
- }
- else {
- /* magic zoom formula */
- bcam->zoom = (float)b_rv3d.view_camera_zoom();
- bcam->zoom = (1.41421f + bcam->zoom/50.0f);
- bcam->zoom *= bcam->zoom;
- bcam->zoom = 2.0f/bcam->zoom;
-
- /* offset */
- bcam->offset = get_float2(b_rv3d.view_camera_offset());
- }
- }
- }
- else if(b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_ORTHO) {
- /* orthographic view */
- bcam->farclip *= 0.5f;
- bcam->nearclip = -bcam->farclip;
-
- float sensor_size;
- if(bcam->sensor_fit == BlenderCamera::VERTICAL)
- sensor_size = bcam->sensor_height;
- else
- sensor_size = bcam->sensor_width;
-
- bcam->type = CAMERA_ORTHOGRAPHIC;
- bcam->ortho_scale = b_rv3d.view_distance() * sensor_size / b_v3d.lens();
- }
-
- bcam->zoom *= 2.0f;
-
- /* 3d view transform */
- bcam->matrix = transform_inverse(get_transform(b_rv3d.view_matrix()));
+ /* 3d view parameters */
+ bcam->nearclip = b_v3d.clip_start();
+ bcam->farclip = b_v3d.clip_end();
+ bcam->lens = b_v3d.lens();
+ bcam->shuttertime = b_scene.render().motion_blur_shutter();
+
+ BL::CurveMapping b_shutter_curve(b_scene.render().motion_blur_shutter_curve());
+ curvemapping_to_array(b_shutter_curve, bcam->shutter_curve, RAMP_TABLE_SIZE);
+
+ if (b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_CAMERA) {
+ /* camera view */
+ BL::Object b_ob = (b_v3d.use_local_camera()) ? b_v3d.camera() : b_scene.camera();
+
+ if (b_ob) {
+ blender_camera_from_object(bcam, b_engine, b_ob, skip_panorama);
+
+ if (!skip_panorama && bcam->type == CAMERA_PANORAMA) {
+ /* in panorama camera view, we map viewplane to camera border */
+ BoundBox2D view_box, cam_box;
+
+ BL::RenderSettings b_render_settings(b_scene.render());
+ blender_camera_view_subset(b_engine,
+ b_render_settings,
+ b_scene,
+ b_ob,
+ b_v3d,
+ b_rv3d,
+ width,
+ height,
+ &view_box,
+ &cam_box);
+
+ bcam->pano_viewplane = view_box.make_relative_to(cam_box);
+ }
+ else {
+ /* magic zoom formula */
+ bcam->zoom = (float)b_rv3d.view_camera_zoom();
+ bcam->zoom = (1.41421f + bcam->zoom / 50.0f);
+ bcam->zoom *= bcam->zoom;
+ bcam->zoom = 2.0f / bcam->zoom;
+
+ /* offset */
+ bcam->offset = get_float2(b_rv3d.view_camera_offset());
+ }
+ }
+ }
+ else if (b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_ORTHO) {
+ /* orthographic view */
+ bcam->farclip *= 0.5f;
+ bcam->nearclip = -bcam->farclip;
+
+ float sensor_size;
+ if (bcam->sensor_fit == BlenderCamera::VERTICAL)
+ sensor_size = bcam->sensor_height;
+ else
+ sensor_size = bcam->sensor_width;
+
+ bcam->type = CAMERA_ORTHOGRAPHIC;
+ bcam->ortho_scale = b_rv3d.view_distance() * sensor_size / b_v3d.lens();
+ }
+
+ bcam->zoom *= 2.0f;
+
+ /* 3d view transform */
+ bcam->matrix = transform_inverse(get_transform(b_rv3d.view_matrix()));
}
-static void blender_camera_view_subset(BL::RenderEngine& b_engine,
- BL::RenderSettings& b_render,
- BL::Scene& b_scene,
- BL::Object& b_ob,
- BL::SpaceView3D& b_v3d,
- BL::RegionView3D& b_rv3d,
- int width, int height,
+static void blender_camera_view_subset(BL::RenderEngine &b_engine,
+ BL::RenderSettings &b_render,
+ BL::Scene &b_scene,
+ BL::Object &b_ob,
+ BL::SpaceView3D &b_v3d,
+ BL::RegionView3D &b_rv3d,
+ int width,
+ int height,
BoundBox2D *view_box,
BoundBox2D *cam_box)
{
- BoundBox2D cam, view;
- float view_aspect, cam_aspect, sensor_size;
+ BoundBox2D cam, view;
+ float view_aspect, cam_aspect, sensor_size;
- /* get viewport viewplane */
- BlenderCamera view_bcam;
- blender_camera_init(&view_bcam, b_render);
- blender_camera_from_view(&view_bcam, b_engine, b_scene, b_v3d, b_rv3d, width, height, true);
+ /* get viewport viewplane */
+ BlenderCamera view_bcam;
+ blender_camera_init(&view_bcam, b_render);
+ blender_camera_from_view(&view_bcam, b_engine, b_scene, b_v3d, b_rv3d, width, height, true);
- blender_camera_viewplane(&view_bcam, width, height,
- &view, &view_aspect, &sensor_size);
+ blender_camera_viewplane(&view_bcam, width, height, &view, &view_aspect, &sensor_size);
- /* get camera viewplane */
- BlenderCamera cam_bcam;
- blender_camera_init(&cam_bcam, b_render);
- blender_camera_from_object(&cam_bcam, b_engine, b_ob, true);
+ /* get camera viewplane */
+ BlenderCamera cam_bcam;
+ blender_camera_init(&cam_bcam, b_render);
+ blender_camera_from_object(&cam_bcam, b_engine, b_ob, true);
- blender_camera_viewplane(&cam_bcam, cam_bcam.full_width, cam_bcam.full_height,
- &cam, &cam_aspect, &sensor_size);
+ blender_camera_viewplane(
+ &cam_bcam, cam_bcam.full_width, cam_bcam.full_height, &cam, &cam_aspect, &sensor_size);
- /* return */
- *view_box = view * (1.0f/view_aspect);
- *cam_box = cam * (1.0f/cam_aspect);
+ /* return */
+ *view_box = view * (1.0f / view_aspect);
+ *cam_box = cam * (1.0f / cam_aspect);
}
-static void blender_camera_border_subset(BL::RenderEngine& b_engine,
- BL::RenderSettings& b_render,
- BL::Scene& b_scene,
- BL::SpaceView3D& b_v3d,
- BL::RegionView3D& b_rv3d,
- BL::Object& b_ob,
- int width, int height,
+static void blender_camera_border_subset(BL::RenderEngine &b_engine,
+ BL::RenderSettings &b_render,
+ BL::Scene &b_scene,
+ BL::SpaceView3D &b_v3d,
+ BL::RegionView3D &b_rv3d,
+ BL::Object &b_ob,
+ int width,
+ int height,
const BoundBox2D &border,
BoundBox2D *result)
{
- /* Determine camera viewport subset. */
- BoundBox2D view_box, cam_box;
- blender_camera_view_subset(b_engine, b_render, b_scene, b_ob, b_v3d, b_rv3d, width, height,
- &view_box, &cam_box);
-
- /* Determine viewport subset matching given border. */
- cam_box = cam_box.make_relative_to(view_box);
- *result = cam_box.subset(border);
+ /* Determine camera viewport subset. */
+ BoundBox2D view_box, cam_box;
+ blender_camera_view_subset(
+ b_engine, b_render, b_scene, b_ob, b_v3d, b_rv3d, width, height, &view_box, &cam_box);
+
+ /* Determine viewport subset matching given border. */
+ cam_box = cam_box.make_relative_to(view_box);
+ *result = cam_box.subset(border);
}
static void blender_camera_border(BlenderCamera *bcam,
- BL::RenderEngine& b_engine,
- BL::RenderSettings& b_render,
- BL::Scene& b_scene,
- BL::SpaceView3D& b_v3d,
- BL::RegionView3D& b_rv3d,
- int width, int height)
+ BL::RenderEngine &b_engine,
+ BL::RenderSettings &b_render,
+ BL::Scene &b_scene,
+ BL::SpaceView3D &b_v3d,
+ BL::RegionView3D &b_rv3d,
+ int width,
+ int height)
{
- bool is_camera_view;
-
- /* camera view? */
- is_camera_view = b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_CAMERA;
-
- if(!is_camera_view) {
- /* for non-camera view check whether render border is enabled for viewport
- * and if so use border from 3d viewport
- * assume viewport has got correctly clamped border already
- */
- if(b_v3d.use_render_border()) {
- bcam->border.left = b_v3d.render_border_min_x();
- bcam->border.right = b_v3d.render_border_max_x();
- bcam->border.bottom = b_v3d.render_border_min_y();
- bcam->border.top = b_v3d.render_border_max_y();
- }
- return;
- }
-
- BL::Object b_ob = (b_v3d.use_local_camera())? b_v3d.camera(): b_scene.camera();
-
- if(!b_ob)
- return;
-
- /* Determine camera border inside the viewport. */
- BoundBox2D full_border;
- blender_camera_border_subset(b_engine,
- b_render,
- b_scene,
- b_v3d,
- b_rv3d,
- b_ob,
- width, height,
- full_border,
- &bcam->viewport_camera_border);
-
- if(!b_render.use_border()) {
- return;
- }
-
- bcam->border.left = b_render.border_min_x();
- bcam->border.right = b_render.border_max_x();
- bcam->border.bottom = b_render.border_min_y();
- bcam->border.top = b_render.border_max_y();
-
- /* Determine viewport subset matching camera border. */
- blender_camera_border_subset(b_engine,
- b_render,
- b_scene,
- b_v3d,
- b_rv3d,
- b_ob,
- width, height,
- bcam->border,
- &bcam->border);
- bcam->border = bcam->border.clamp();
+ bool is_camera_view;
+
+ /* camera view? */
+ is_camera_view = b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_CAMERA;
+
+ if (!is_camera_view) {
+ /* for non-camera view check whether render border is enabled for viewport
+ * and if so use border from 3d viewport
+ * assume viewport has got correctly clamped border already
+ */
+ if (b_v3d.use_render_border()) {
+ bcam->border.left = b_v3d.render_border_min_x();
+ bcam->border.right = b_v3d.render_border_max_x();
+ bcam->border.bottom = b_v3d.render_border_min_y();
+ bcam->border.top = b_v3d.render_border_max_y();
+ }
+ return;
+ }
+
+ BL::Object b_ob = (b_v3d.use_local_camera()) ? b_v3d.camera() : b_scene.camera();
+
+ if (!b_ob)
+ return;
+
+ /* Determine camera border inside the viewport. */
+ BoundBox2D full_border;
+ blender_camera_border_subset(b_engine,
+ b_render,
+ b_scene,
+ b_v3d,
+ b_rv3d,
+ b_ob,
+ width,
+ height,
+ full_border,
+ &bcam->viewport_camera_border);
+
+ if (!b_render.use_border()) {
+ return;
+ }
+
+ bcam->border.left = b_render.border_min_x();
+ bcam->border.right = b_render.border_max_x();
+ bcam->border.bottom = b_render.border_min_y();
+ bcam->border.top = b_render.border_max_y();
+
+ /* Determine viewport subset matching camera border. */
+ blender_camera_border_subset(b_engine,
+ b_render,
+ b_scene,
+ b_v3d,
+ b_rv3d,
+ b_ob,
+ width,
+ height,
+ bcam->border,
+ &bcam->border);
+ bcam->border = bcam->border.clamp();
}
-void BlenderSync::sync_view(BL::SpaceView3D& b_v3d,
- BL::RegionView3D& b_rv3d,
- int width, int height)
+void BlenderSync::sync_view(BL::SpaceView3D &b_v3d,
+ BL::RegionView3D &b_rv3d,
+ int width,
+ int height)
{
- BlenderCamera bcam;
- BL::RenderSettings b_render_settings(b_scene.render());
- blender_camera_init(&bcam, b_render_settings);
- blender_camera_from_view(&bcam,
- b_engine,
- b_scene,
- b_v3d,
- b_rv3d,
- width, height);
- blender_camera_border(&bcam,
- b_engine,
- b_render_settings,
- b_scene,
- b_v3d,
- b_rv3d,
- width, height);
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
- blender_camera_sync(scene->camera, &bcam, width, height, "", &cscene);
-
- /* dicing camera */
- BL::Object b_ob = BL::Object(RNA_pointer_get(&cscene, "dicing_camera"));
- if(b_ob) {
- BL::Array<float, 16> b_ob_matrix;
- blender_camera_from_object(&bcam, b_engine, b_ob);
- b_engine.camera_model_matrix(b_ob, bcam.use_spherical_stereo, b_ob_matrix);
- bcam.matrix = get_transform(b_ob_matrix);
-
- blender_camera_sync(scene->dicing_camera, &bcam, width, height, "", &cscene);
- }
- else {
- *scene->dicing_camera = *scene->camera;
- }
+ BlenderCamera bcam;
+ BL::RenderSettings b_render_settings(b_scene.render());
+ blender_camera_init(&bcam, b_render_settings);
+ blender_camera_from_view(&bcam, b_engine, b_scene, b_v3d, b_rv3d, width, height);
+ blender_camera_border(&bcam, b_engine, b_render_settings, b_scene, b_v3d, b_rv3d, width, height);
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+ blender_camera_sync(scene->camera, &bcam, width, height, "", &cscene);
+
+ /* dicing camera */
+ BL::Object b_ob = BL::Object(RNA_pointer_get(&cscene, "dicing_camera"));
+ if (b_ob) {
+ BL::Array<float, 16> b_ob_matrix;
+ blender_camera_from_object(&bcam, b_engine, b_ob);
+ b_engine.camera_model_matrix(b_ob, bcam.use_spherical_stereo, b_ob_matrix);
+ bcam.matrix = get_transform(b_ob_matrix);
+
+ blender_camera_sync(scene->dicing_camera, &bcam, width, height, "", &cscene);
+ }
+ else {
+ *scene->dicing_camera = *scene->camera;
+ }
}
-BufferParams BlenderSync::get_buffer_params(BL::RenderSettings& b_render,
- BL::SpaceView3D& b_v3d,
- BL::RegionView3D& b_rv3d,
+BufferParams BlenderSync::get_buffer_params(BL::RenderSettings &b_render,
+ BL::SpaceView3D &b_v3d,
+ BL::RegionView3D &b_rv3d,
Camera *cam,
- int width, int height)
+ int width,
+ int height)
{
- BufferParams params;
- bool use_border = false;
-
- params.full_width = width;
- params.full_height = height;
-
- if(b_v3d && b_rv3d && b_rv3d.view_perspective() != BL::RegionView3D::view_perspective_CAMERA)
- use_border = b_v3d.use_render_border();
- else
- use_border = b_render.use_border();
-
- if(use_border) {
- /* border render */
- /* the viewport may offset the border outside the view */
- BoundBox2D border = cam->border.clamp();
- params.full_x = (int)(border.left * (float)width);
- params.full_y = (int)(border.bottom * (float)height);
- params.width = (int)(border.right * (float)width) - params.full_x;
- params.height = (int)(border.top * (float)height) - params.full_y;
-
- /* survive in case border goes out of view or becomes too small */
- params.width = max(params.width, 1);
- params.height = max(params.height, 1);
- }
- else {
- params.width = width;
- params.height = height;
- }
-
- return params;
+ BufferParams params;
+ bool use_border = false;
+
+ params.full_width = width;
+ params.full_height = height;
+
+ if (b_v3d && b_rv3d && b_rv3d.view_perspective() != BL::RegionView3D::view_perspective_CAMERA)
+ use_border = b_v3d.use_render_border();
+ else
+ use_border = b_render.use_border();
+
+ if (use_border) {
+ /* border render */
+ /* the viewport may offset the border outside the view */
+ BoundBox2D border = cam->border.clamp();
+ params.full_x = (int)(border.left * (float)width);
+ params.full_y = (int)(border.bottom * (float)height);
+ params.width = (int)(border.right * (float)width) - params.full_x;
+ params.height = (int)(border.top * (float)height) - params.full_y;
+
+ /* survive in case border goes out of view or becomes too small */
+ params.width = max(params.width, 1);
+ params.height = max(params.height, 1);
+ }
+ else {
+ params.width = width;
+ params.height = height;
+ }
+
+ return params;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp
index 602e63a3e47..d0375ceb79c 100644
--- a/intern/cycles/blender/blender_curves.cpp
+++ b/intern/cycles/blender/blender_curves.cpp
@@ -40,170 +40,165 @@ ParticleCurveData::~ParticleCurveData()
static void interp_weights(float t, float data[4])
{
- /* Cardinal curve interpolation */
- float t2 = t * t;
- float t3 = t2 * t;
- float fc = 0.71f;
-
- data[0] = -fc * t3 + 2.0f * fc * t2 - fc * t;
- data[1] = (2.0f - fc) * t3 + (fc - 3.0f) * t2 + 1.0f;
- data[2] = (fc - 2.0f) * t3 + (3.0f - 2.0f * fc) * t2 + fc * t;
- data[3] = fc * t3 - fc * t2;
+ /* Cardinal curve interpolation */
+ float t2 = t * t;
+ float t3 = t2 * t;
+ float fc = 0.71f;
+
+ data[0] = -fc * t3 + 2.0f * fc * t2 - fc * t;
+ data[1] = (2.0f - fc) * t3 + (fc - 3.0f) * t2 + 1.0f;
+ data[2] = (fc - 2.0f) * t3 + (3.0f - 2.0f * fc) * t2 + fc * t;
+ data[3] = fc * t3 - fc * t2;
}
-static void curveinterp_v3_v3v3v3v3(float3 *p,
- float3 *v1, float3 *v2, float3 *v3, float3 *v4,
- const float w[4])
+static void curveinterp_v3_v3v3v3v3(
+ float3 *p, float3 *v1, float3 *v2, float3 *v3, float3 *v4, const float w[4])
{
- p->x = v1->x * w[0] + v2->x * w[1] + v3->x * w[2] + v4->x * w[3];
- p->y = v1->y * w[0] + v2->y * w[1] + v3->y * w[2] + v4->y * w[3];
- p->z = v1->z * w[0] + v2->z * w[1] + v3->z * w[2] + v4->z * w[3];
+ p->x = v1->x * w[0] + v2->x * w[1] + v3->x * w[2] + v4->x * w[3];
+ p->y = v1->y * w[0] + v2->y * w[1] + v3->y * w[2] + v4->y * w[3];
+ p->z = v1->z * w[0] + v2->z * w[1] + v3->z * w[2] + v4->z * w[3];
}
static float shaperadius(float shape, float root, float tip, float time)
{
- assert(time >= 0.0f);
- assert(time <= 1.0f);
- float radius = 1.0f - time;
-
- if(shape != 0.0f) {
- if(shape < 0.0f)
- radius = powf(radius, 1.0f + shape);
- else
- radius = powf(radius, 1.0f / (1.0f - shape));
- }
- return (radius * (root - tip)) + tip;
+ assert(time >= 0.0f);
+ assert(time <= 1.0f);
+ float radius = 1.0f - time;
+
+ if (shape != 0.0f) {
+ if (shape < 0.0f)
+ radius = powf(radius, 1.0f + shape);
+ else
+ radius = powf(radius, 1.0f / (1.0f - shape));
+ }
+ return (radius * (root - tip)) + tip;
}
/* curve functions */
-static void InterpolateKeySegments(int seg,
- int segno,
- int key,
- int curve,
- float3 *keyloc,
- float *time,
- ParticleCurveData *CData)
+static void InterpolateKeySegments(
+ int seg, int segno, int key, int curve, float3 *keyloc, float *time, ParticleCurveData *CData)
{
- float3 ckey_loc1 = CData->curvekey_co[key];
- float3 ckey_loc2 = ckey_loc1;
- float3 ckey_loc3 = CData->curvekey_co[key+1];
- float3 ckey_loc4 = ckey_loc3;
+ float3 ckey_loc1 = CData->curvekey_co[key];
+ float3 ckey_loc2 = ckey_loc1;
+ float3 ckey_loc3 = CData->curvekey_co[key + 1];
+ float3 ckey_loc4 = ckey_loc3;
- if(key > CData->curve_firstkey[curve])
- ckey_loc1 = CData->curvekey_co[key - 1];
+ if (key > CData->curve_firstkey[curve])
+ ckey_loc1 = CData->curvekey_co[key - 1];
- if(key < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2)
- ckey_loc4 = CData->curvekey_co[key + 2];
+ if (key < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2)
+ ckey_loc4 = CData->curvekey_co[key + 2];
- float time1 = CData->curvekey_time[key]/CData->curve_length[curve];
- float time2 = CData->curvekey_time[key + 1]/CData->curve_length[curve];
+ float time1 = CData->curvekey_time[key] / CData->curve_length[curve];
+ float time2 = CData->curvekey_time[key + 1] / CData->curve_length[curve];
- float dfra = (time2 - time1) / (float)segno;
+ float dfra = (time2 - time1) / (float)segno;
- if(time)
- *time = (dfra * seg) + time1;
+ if (time)
+ *time = (dfra * seg) + time1;
- float t[4];
+ float t[4];
- interp_weights((float)seg / (float)segno, t);
+ interp_weights((float)seg / (float)segno, t);
- if(keyloc)
- curveinterp_v3_v3v3v3v3(keyloc, &ckey_loc1, &ckey_loc2, &ckey_loc3, &ckey_loc4, t);
+ if (keyloc)
+ curveinterp_v3_v3v3v3v3(keyloc, &ckey_loc1, &ckey_loc2, &ckey_loc3, &ckey_loc4, t);
}
-static bool ObtainCacheParticleData(Mesh *mesh,
- BL::Mesh *b_mesh,
- BL::Object *b_ob,
- ParticleCurveData *CData,
- bool background)
+static bool ObtainCacheParticleData(
+ Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background)
{
- int curvenum = 0;
- int keyno = 0;
-
- if(!(mesh && b_mesh && b_ob && CData))
- return false;
-
- Transform tfm = get_transform(b_ob->matrix_world());
- Transform itfm = transform_quick_inverse(tfm);
-
- BL::Object::modifiers_iterator b_mod;
- for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
- if((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (background ? b_mod->show_render() : b_mod->show_viewport())) {
- BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
- BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
- BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
-
- if((b_part.render_type() == BL::ParticleSettings::render_type_PATH) && (b_part.type() == BL::ParticleSettings::type_HAIR)) {
- int shader = clamp(b_part.material()-1, 0, mesh->used_shaders.size()-1);
- int display_step = background ? b_part.render_step() : b_part.display_step();
- int totparts = b_psys.particles.length();
- int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_part.display_percentage() / 100.0f);
- int totcurves = totchild;
-
- if(b_part.child_type() == 0 || totchild == 0)
- totcurves += totparts;
-
- if(totcurves == 0)
- continue;
-
- int ren_step = (1 << display_step) + 1;
- if(b_part.kink() == BL::ParticleSettings::kink_SPIRAL)
- ren_step += b_part.kink_extra_steps();
-
- CData->psys_firstcurve.push_back_slow(curvenum);
- CData->psys_curvenum.push_back_slow(totcurves);
- CData->psys_shader.push_back_slow(shader);
-
- float radius = b_part.radius_scale() * 0.5f;
-
- CData->psys_rootradius.push_back_slow(radius * b_part.root_radius());
- CData->psys_tipradius.push_back_slow(radius * b_part.tip_radius());
- CData->psys_shape.push_back_slow(b_part.shape());
- CData->psys_closetip.push_back_slow(b_part.use_close_tip());
-
- int pa_no = 0;
- if(!(b_part.child_type() == 0) && totchild != 0)
- pa_no = totparts;
-
- int num_add = (totparts+totchild - pa_no);
- CData->curve_firstkey.reserve(CData->curve_firstkey.size() + num_add);
- CData->curve_keynum.reserve(CData->curve_keynum.size() + num_add);
- CData->curve_length.reserve(CData->curve_length.size() + num_add);
- CData->curvekey_co.reserve(CData->curvekey_co.size() + num_add*ren_step);
- CData->curvekey_time.reserve(CData->curvekey_time.size() + num_add*ren_step);
-
- for(; pa_no < totparts+totchild; pa_no++) {
- int keynum = 0;
- CData->curve_firstkey.push_back_slow(keyno);
-
- float curve_length = 0.0f;
- float3 pcKey;
- for(int step_no = 0; step_no < ren_step; step_no++) {
- float nco[3];
- b_psys.co_hair(*b_ob, pa_no, step_no, nco);
- float3 cKey = make_float3(nco[0], nco[1], nco[2]);
- cKey = transform_point(&itfm, cKey);
- if(step_no > 0) {
- const float step_length = len(cKey - pcKey);
- curve_length += step_length;
- }
- CData->curvekey_co.push_back_slow(cKey);
- CData->curvekey_time.push_back_slow(curve_length);
- pcKey = cKey;
- keynum++;
- }
- keyno += keynum;
-
- CData->curve_keynum.push_back_slow(keynum);
- CData->curve_length.push_back_slow(curve_length);
- curvenum++;
- }
- }
- }
- }
-
- return true;
+ int curvenum = 0;
+ int keyno = 0;
+
+ if (!(mesh && b_mesh && b_ob && CData))
+ return false;
+
+ Transform tfm = get_transform(b_ob->matrix_world());
+ Transform itfm = transform_quick_inverse(tfm);
+
+ BL::Object::modifiers_iterator b_mod;
+ for (b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
+ if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) &&
+ (background ? b_mod->show_render() : b_mod->show_viewport())) {
+ BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
+ BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
+ BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
+
+ if ((b_part.render_type() == BL::ParticleSettings::render_type_PATH) &&
+ (b_part.type() == BL::ParticleSettings::type_HAIR)) {
+ int shader = clamp(b_part.material() - 1, 0, mesh->used_shaders.size() - 1);
+ int display_step = background ? b_part.render_step() : b_part.display_step();
+ int totparts = b_psys.particles.length();
+ int totchild = background ? b_psys.child_particles.length() :
+ (int)((float)b_psys.child_particles.length() *
+ (float)b_part.display_percentage() / 100.0f);
+ int totcurves = totchild;
+
+ if (b_part.child_type() == 0 || totchild == 0)
+ totcurves += totparts;
+
+ if (totcurves == 0)
+ continue;
+
+ int ren_step = (1 << display_step) + 1;
+ if (b_part.kink() == BL::ParticleSettings::kink_SPIRAL)
+ ren_step += b_part.kink_extra_steps();
+
+ CData->psys_firstcurve.push_back_slow(curvenum);
+ CData->psys_curvenum.push_back_slow(totcurves);
+ CData->psys_shader.push_back_slow(shader);
+
+ float radius = b_part.radius_scale() * 0.5f;
+
+ CData->psys_rootradius.push_back_slow(radius * b_part.root_radius());
+ CData->psys_tipradius.push_back_slow(radius * b_part.tip_radius());
+ CData->psys_shape.push_back_slow(b_part.shape());
+ CData->psys_closetip.push_back_slow(b_part.use_close_tip());
+
+ int pa_no = 0;
+ if (!(b_part.child_type() == 0) && totchild != 0)
+ pa_no = totparts;
+
+ int num_add = (totparts + totchild - pa_no);
+ CData->curve_firstkey.reserve(CData->curve_firstkey.size() + num_add);
+ CData->curve_keynum.reserve(CData->curve_keynum.size() + num_add);
+ CData->curve_length.reserve(CData->curve_length.size() + num_add);
+ CData->curvekey_co.reserve(CData->curvekey_co.size() + num_add * ren_step);
+ CData->curvekey_time.reserve(CData->curvekey_time.size() + num_add * ren_step);
+
+ for (; pa_no < totparts + totchild; pa_no++) {
+ int keynum = 0;
+ CData->curve_firstkey.push_back_slow(keyno);
+
+ float curve_length = 0.0f;
+ float3 pcKey;
+ for (int step_no = 0; step_no < ren_step; step_no++) {
+ float nco[3];
+ b_psys.co_hair(*b_ob, pa_no, step_no, nco);
+ float3 cKey = make_float3(nco[0], nco[1], nco[2]);
+ cKey = transform_point(&itfm, cKey);
+ if (step_no > 0) {
+ const float step_length = len(cKey - pcKey);
+ curve_length += step_length;
+ }
+ CData->curvekey_co.push_back_slow(cKey);
+ CData->curvekey_time.push_back_slow(curve_length);
+ pcKey = cKey;
+ keynum++;
+ }
+ keyno += keynum;
+
+ CData->curve_keynum.push_back_slow(keynum);
+ CData->curve_length.push_back_slow(curve_length);
+ curvenum++;
+ }
+ }
+ }
+ }
+
+ return true;
}
static bool ObtainCacheParticleUV(Mesh *mesh,
@@ -213,56 +208,60 @@ static bool ObtainCacheParticleUV(Mesh *mesh,
bool background,
int uv_num)
{
- if(!(mesh && b_mesh && b_ob && CData))
- return false;
-
- CData->curve_uv.clear();
-
- BL::Object::modifiers_iterator b_mod;
- for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
- if((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (background ? b_mod->show_render() : b_mod->show_viewport())) {
- BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
- BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
- BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
-
- if((b_part.render_type() == BL::ParticleSettings::render_type_PATH) && (b_part.type() == BL::ParticleSettings::type_HAIR)) {
- int totparts = b_psys.particles.length();
- int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_part.display_percentage() / 100.0f);
- int totcurves = totchild;
-
- if(b_part.child_type() == 0 || totchild == 0)
- totcurves += totparts;
-
- if(totcurves == 0)
- continue;
-
- int pa_no = 0;
- if(!(b_part.child_type() == 0) && totchild != 0)
- pa_no = totparts;
-
- int num_add = (totparts+totchild - pa_no);
- CData->curve_uv.reserve(CData->curve_uv.size() + num_add);
-
- BL::ParticleSystem::particles_iterator b_pa;
- b_psys.particles.begin(b_pa);
- for(; pa_no < totparts+totchild; pa_no++) {
- /* Add UVs */
- BL::Mesh::uv_layers_iterator l;
- b_mesh->uv_layers.begin(l);
-
- float2 uv = make_float2(0.0f, 0.0f);
- if(b_mesh->uv_layers.length())
- b_psys.uv_on_emitter(psmd, *b_pa, pa_no, uv_num, &uv.x);
- CData->curve_uv.push_back_slow(uv);
-
- if(pa_no < totparts && b_pa != b_psys.particles.end())
- ++b_pa;
- }
- }
- }
- }
-
- return true;
+ if (!(mesh && b_mesh && b_ob && CData))
+ return false;
+
+ CData->curve_uv.clear();
+
+ BL::Object::modifiers_iterator b_mod;
+ for (b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
+ if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) &&
+ (background ? b_mod->show_render() : b_mod->show_viewport())) {
+ BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
+ BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
+ BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
+
+ if ((b_part.render_type() == BL::ParticleSettings::render_type_PATH) &&
+ (b_part.type() == BL::ParticleSettings::type_HAIR)) {
+ int totparts = b_psys.particles.length();
+ int totchild = background ? b_psys.child_particles.length() :
+ (int)((float)b_psys.child_particles.length() *
+ (float)b_part.display_percentage() / 100.0f);
+ int totcurves = totchild;
+
+ if (b_part.child_type() == 0 || totchild == 0)
+ totcurves += totparts;
+
+ if (totcurves == 0)
+ continue;
+
+ int pa_no = 0;
+ if (!(b_part.child_type() == 0) && totchild != 0)
+ pa_no = totparts;
+
+ int num_add = (totparts + totchild - pa_no);
+ CData->curve_uv.reserve(CData->curve_uv.size() + num_add);
+
+ BL::ParticleSystem::particles_iterator b_pa;
+ b_psys.particles.begin(b_pa);
+ for (; pa_no < totparts + totchild; pa_no++) {
+ /* Add UVs */
+ BL::Mesh::uv_layers_iterator l;
+ b_mesh->uv_layers.begin(l);
+
+ float2 uv = make_float2(0.0f, 0.0f);
+ if (b_mesh->uv_layers.length())
+ b_psys.uv_on_emitter(psmd, *b_pa, pa_no, uv_num, &uv.x);
+ CData->curve_uv.push_back_slow(uv);
+
+ if (pa_no < totparts && b_pa != b_psys.particles.end())
+ ++b_pa;
+ }
+ }
+ }
+ }
+
+ return true;
}
static bool ObtainCacheParticleVcol(Mesh *mesh,
@@ -272,481 +271,542 @@ static bool ObtainCacheParticleVcol(Mesh *mesh,
bool background,
int vcol_num)
{
- if(!(mesh && b_mesh && b_ob && CData))
- return false;
-
- CData->curve_vcol.clear();
-
- BL::Object::modifiers_iterator b_mod;
- for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
- if((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (background ? b_mod->show_render() : b_mod->show_viewport())) {
- BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
- BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
- BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
-
- if((b_part.render_type() == BL::ParticleSettings::render_type_PATH) && (b_part.type() == BL::ParticleSettings::type_HAIR)) {
- int totparts = b_psys.particles.length();
- int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_part.display_percentage() / 100.0f);
- int totcurves = totchild;
-
- if(b_part.child_type() == 0 || totchild == 0)
- totcurves += totparts;
-
- if(totcurves == 0)
- continue;
-
- int pa_no = 0;
- if(!(b_part.child_type() == 0) && totchild != 0)
- pa_no = totparts;
-
- int num_add = (totparts+totchild - pa_no);
- CData->curve_vcol.reserve(CData->curve_vcol.size() + num_add);
-
- BL::ParticleSystem::particles_iterator b_pa;
- b_psys.particles.begin(b_pa);
- for(; pa_no < totparts+totchild; pa_no++) {
- /* Add vertex colors */
- BL::Mesh::vertex_colors_iterator l;
- b_mesh->vertex_colors.begin(l);
-
- float3 vcol = make_float3(0.0f, 0.0f, 0.0f);
- if(b_mesh->vertex_colors.length())
- b_psys.mcol_on_emitter(psmd, *b_pa, pa_no, vcol_num, &vcol.x);
- CData->curve_vcol.push_back_slow(vcol);
-
- if(pa_no < totparts && b_pa != b_psys.particles.end())
- ++b_pa;
- }
- }
- }
- }
-
- return true;
+ if (!(mesh && b_mesh && b_ob && CData))
+ return false;
+
+ CData->curve_vcol.clear();
+
+ BL::Object::modifiers_iterator b_mod;
+ for (b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
+ if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) &&
+ (background ? b_mod->show_render() : b_mod->show_viewport())) {
+ BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
+ BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
+ BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
+
+ if ((b_part.render_type() == BL::ParticleSettings::render_type_PATH) &&
+ (b_part.type() == BL::ParticleSettings::type_HAIR)) {
+ int totparts = b_psys.particles.length();
+ int totchild = background ? b_psys.child_particles.length() :
+ (int)((float)b_psys.child_particles.length() *
+ (float)b_part.display_percentage() / 100.0f);
+ int totcurves = totchild;
+
+ if (b_part.child_type() == 0 || totchild == 0)
+ totcurves += totparts;
+
+ if (totcurves == 0)
+ continue;
+
+ int pa_no = 0;
+ if (!(b_part.child_type() == 0) && totchild != 0)
+ pa_no = totparts;
+
+ int num_add = (totparts + totchild - pa_no);
+ CData->curve_vcol.reserve(CData->curve_vcol.size() + num_add);
+
+ BL::ParticleSystem::particles_iterator b_pa;
+ b_psys.particles.begin(b_pa);
+ for (; pa_no < totparts + totchild; pa_no++) {
+ /* Add vertex colors */
+ BL::Mesh::vertex_colors_iterator l;
+ b_mesh->vertex_colors.begin(l);
+
+ float3 vcol = make_float3(0.0f, 0.0f, 0.0f);
+ if (b_mesh->vertex_colors.length())
+ b_psys.mcol_on_emitter(psmd, *b_pa, pa_no, vcol_num, &vcol.x);
+ CData->curve_vcol.push_back_slow(vcol);
+
+ if (pa_no < totparts && b_pa != b_psys.particles.end())
+ ++b_pa;
+ }
+ }
+ }
+ }
+
+ return true;
}
-static void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData,
- float3 RotCam, bool is_ortho)
+static void ExportCurveTrianglePlanes(Mesh *mesh,
+ ParticleCurveData *CData,
+ float3 RotCam,
+ bool is_ortho)
{
- int vertexno = mesh->verts.size();
- int vertexindex = vertexno;
- int numverts = 0, numtris = 0;
-
- /* compute and reserve size of arrays */
- for(int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
- for(int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; curve++) {
- numverts += 2 + (CData->curve_keynum[curve] - 1)*2;
- numtris += (CData->curve_keynum[curve] - 1)*2;
- }
- }
-
- mesh->reserve_mesh(mesh->verts.size() + numverts, mesh->num_triangles() + numtris);
-
- /* actually export */
- for(int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
- for(int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; curve++) {
- float3 xbasis;
- float3 v1;
- float time = 0.0f;
- 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]];
- 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->add_vertex(ickey_loc_shfl);
- mesh->add_vertex(ickey_loc_shfr);
- vertexindex += 2;
-
- for(int curvekey = CData->curve_firstkey[curve] + 1; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve]; curvekey++) {
- ickey_loc = CData->curvekey_co[curvekey];
-
- if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)
- v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[max(curvekey - 1, CData->curve_firstkey[curve])];
- else
- v1 = CData->curvekey_co[curvekey + 1] - CData->curvekey_co[curvekey - 1];
-
- time = CData->curvekey_time[curvekey]/CData->curve_length[curve];
- radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time);
-
- if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)
- radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], 0.95f);
-
- 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);
-
- 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->add_vertex(ickey_loc_shfl);
- mesh->add_vertex(ickey_loc_shfr);
- mesh->add_triangle(vertexindex-2, vertexindex, vertexindex-1, CData->psys_shader[sys], true);
- mesh->add_triangle(vertexindex+1, vertexindex-1, vertexindex, CData->psys_shader[sys], true);
- vertexindex += 2;
- }
- }
- }
-
- mesh->resize_mesh(mesh->verts.size(), mesh->num_triangles());
- mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
- mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
- mesh->add_face_normals();
- mesh->add_vertex_normals();
- mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
-
- /* texture coords still needed */
+ int vertexno = mesh->verts.size();
+ int vertexindex = vertexno;
+ int numverts = 0, numtris = 0;
+
+ /* compute and reserve size of arrays */
+ for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
+ for (int curve = CData->psys_firstcurve[sys];
+ curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys];
+ curve++) {
+ numverts += 2 + (CData->curve_keynum[curve] - 1) * 2;
+ numtris += (CData->curve_keynum[curve] - 1) * 2;
+ }
+ }
+
+ mesh->reserve_mesh(mesh->verts.size() + numverts, mesh->num_triangles() + numtris);
+
+ /* actually export */
+ for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
+ for (int curve = CData->psys_firstcurve[sys];
+ curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys];
+ curve++) {
+ float3 xbasis;
+ float3 v1;
+ float time = 0.0f;
+ 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]];
+ 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->add_vertex(ickey_loc_shfl);
+ mesh->add_vertex(ickey_loc_shfr);
+ vertexindex += 2;
+
+ for (int curvekey = CData->curve_firstkey[curve] + 1;
+ curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve];
+ curvekey++) {
+ ickey_loc = CData->curvekey_co[curvekey];
+
+ if (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)
+ v1 = CData->curvekey_co[curvekey] -
+ CData->curvekey_co[max(curvekey - 1, CData->curve_firstkey[curve])];
+ else
+ v1 = CData->curvekey_co[curvekey + 1] - CData->curvekey_co[curvekey - 1];
+
+ time = CData->curvekey_time[curvekey] / CData->curve_length[curve];
+ radius = shaperadius(
+ CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time);
+
+ if (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)
+ radius = shaperadius(CData->psys_shape[sys],
+ CData->psys_rootradius[sys],
+ CData->psys_tipradius[sys],
+ 0.95f);
+
+ 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);
+
+ 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->add_vertex(ickey_loc_shfl);
+ mesh->add_vertex(ickey_loc_shfr);
+ mesh->add_triangle(
+ vertexindex - 2, vertexindex, vertexindex - 1, CData->psys_shader[sys], true);
+ mesh->add_triangle(
+ vertexindex + 1, vertexindex - 1, vertexindex, CData->psys_shader[sys], true);
+ vertexindex += 2;
+ }
+ }
+ }
+
+ mesh->resize_mesh(mesh->verts.size(), mesh->num_triangles());
+ mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
+ mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
+ mesh->add_face_normals();
+ mesh->add_vertex_normals();
+ mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
+
+ /* texture coords still needed */
}
-static void ExportCurveTriangleGeometry(Mesh *mesh,
- ParticleCurveData *CData,
- int resolution)
+static void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int resolution)
{
- int vertexno = mesh->verts.size();
- int vertexindex = vertexno;
- int numverts = 0, numtris = 0;
-
- /* compute and reserve size of arrays */
- for(int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
- for(int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; curve++) {
- numverts += (CData->curve_keynum[curve] - 1)*resolution + resolution;
- numtris += (CData->curve_keynum[curve] - 1)*2*resolution;
- }
- }
-
- mesh->reserve_mesh(mesh->verts.size() + numverts, mesh->num_triangles() + numtris);
-
- /* actually export */
- for(int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
- for(int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; curve++) {
- float3 firstxbasis = cross(make_float3(1.0f,0.0f,0.0f),CData->curvekey_co[CData->curve_firstkey[curve]+1] - CData->curvekey_co[CData->curve_firstkey[curve]]);
- if(!is_zero(firstxbasis))
- firstxbasis = normalize(firstxbasis);
- else
- firstxbasis = normalize(cross(make_float3(0.0f,1.0f,0.0f),CData->curvekey_co[CData->curve_firstkey[curve]+1] - CData->curvekey_co[CData->curve_firstkey[curve]]));
-
- for(int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) {
- float3 xbasis = firstxbasis;
- float3 v1;
- float3 v2;
-
- if(curvekey == CData->curve_firstkey[curve]) {
- v1 = CData->curvekey_co[min(curvekey+2,CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)] - CData->curvekey_co[curvekey+1];
- v2 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey];
- }
- else if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) {
- v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1];
- v2 = CData->curvekey_co[curvekey-1] - CData->curvekey_co[max(curvekey-2,CData->curve_firstkey[curve])];
- }
- else {
- v1 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey];
- v2 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1];
- }
-
- xbasis = cross(v1, v2);
-
- if(len_squared(xbasis) >= 0.05f * len_squared(v1) * len_squared(v2)) {
- firstxbasis = normalize(xbasis);
- break;
- }
- }
-
- for(int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) {
- int subv = 1;
- float3 xbasis;
- float3 ybasis;
- float3 v1;
- float3 v2;
-
- if(curvekey == CData->curve_firstkey[curve]) {
- subv = 0;
- v1 = CData->curvekey_co[min(curvekey+2,CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)] - CData->curvekey_co[curvekey+1];
- v2 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey];
- }
- else if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) {
- v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1];
- v2 = CData->curvekey_co[curvekey-1] - CData->curvekey_co[max(curvekey-2,CData->curve_firstkey[curve])];
- }
- else {
- v1 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey];
- v2 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1];
- }
-
- xbasis = cross(v1, v2);
-
- if(len_squared(xbasis) >= 0.05f * len_squared(v1) * len_squared(v2)) {
- xbasis = normalize(xbasis);
- firstxbasis = xbasis;
- }
- else
- xbasis = firstxbasis;
-
- ybasis = normalize(cross(xbasis, v2));
-
- for(; subv <= 1; subv++) {
- float3 ickey_loc = make_float3(0.0f,0.0f,0.0f);
- float time = 0.0f;
-
- InterpolateKeySegments(subv, 1, curvekey, curve, &ickey_loc, &time, CData);
-
- float radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time);
-
- if((curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2) && (subv == 1))
- radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], 0.95f);
-
- if(CData->psys_closetip[sys] && (subv == 1) && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2))
- radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], 0.0f, 0.95f);
-
- float angle = M_2PI_F / (float)resolution;
- for(int section = 0; section < resolution; section++) {
- float3 ickey_loc_shf = ickey_loc + radius * (cosf(angle * section) * xbasis + sinf(angle * section) * ybasis);
- mesh->add_vertex(ickey_loc_shf);
- }
-
- if(subv != 0) {
- for(int section = 0; section < resolution - 1; section++) {
- mesh->add_triangle(vertexindex - resolution + section, vertexindex + section, vertexindex - resolution + section + 1, CData->psys_shader[sys], true);
- mesh->add_triangle(vertexindex + section + 1, vertexindex - resolution + section + 1, vertexindex + section, CData->psys_shader[sys], true);
- }
- mesh->add_triangle(vertexindex-1, vertexindex + resolution - 1, vertexindex - resolution, CData->psys_shader[sys], true);
- mesh->add_triangle(vertexindex, vertexindex - resolution , vertexindex + resolution - 1, CData->psys_shader[sys], true);
- }
- vertexindex += resolution;
- }
- }
- }
- }
-
- mesh->resize_mesh(mesh->verts.size(), mesh->num_triangles());
- mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
- mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
- mesh->add_face_normals();
- mesh->add_vertex_normals();
- mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
-
- /* texture coords still needed */
+ int vertexno = mesh->verts.size();
+ int vertexindex = vertexno;
+ int numverts = 0, numtris = 0;
+
+ /* compute and reserve size of arrays */
+ for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
+ for (int curve = CData->psys_firstcurve[sys];
+ curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys];
+ curve++) {
+ numverts += (CData->curve_keynum[curve] - 1) * resolution + resolution;
+ numtris += (CData->curve_keynum[curve] - 1) * 2 * resolution;
+ }
+ }
+
+ mesh->reserve_mesh(mesh->verts.size() + numverts, mesh->num_triangles() + numtris);
+
+ /* actually export */
+ for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
+ for (int curve = CData->psys_firstcurve[sys];
+ curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys];
+ curve++) {
+ float3 firstxbasis = cross(make_float3(1.0f, 0.0f, 0.0f),
+ CData->curvekey_co[CData->curve_firstkey[curve] + 1] -
+ CData->curvekey_co[CData->curve_firstkey[curve]]);
+ if (!is_zero(firstxbasis))
+ firstxbasis = normalize(firstxbasis);
+ else
+ firstxbasis = normalize(cross(make_float3(0.0f, 1.0f, 0.0f),
+ CData->curvekey_co[CData->curve_firstkey[curve] + 1] -
+ CData->curvekey_co[CData->curve_firstkey[curve]]));
+
+ for (int curvekey = CData->curve_firstkey[curve];
+ curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1;
+ curvekey++) {
+ float3 xbasis = firstxbasis;
+ float3 v1;
+ float3 v2;
+
+ if (curvekey == CData->curve_firstkey[curve]) {
+ v1 = CData->curvekey_co[min(
+ curvekey + 2, CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)] -
+ CData->curvekey_co[curvekey + 1];
+ v2 = CData->curvekey_co[curvekey + 1] - CData->curvekey_co[curvekey];
+ }
+ else if (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) {
+ v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey - 1];
+ v2 = CData->curvekey_co[curvekey - 1] -
+ CData->curvekey_co[max(curvekey - 2, CData->curve_firstkey[curve])];
+ }
+ else {
+ v1 = CData->curvekey_co[curvekey + 1] - CData->curvekey_co[curvekey];
+ v2 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey - 1];
+ }
+
+ xbasis = cross(v1, v2);
+
+ if (len_squared(xbasis) >= 0.05f * len_squared(v1) * len_squared(v2)) {
+ firstxbasis = normalize(xbasis);
+ break;
+ }
+ }
+
+ for (int curvekey = CData->curve_firstkey[curve];
+ curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1;
+ curvekey++) {
+ int subv = 1;
+ float3 xbasis;
+ float3 ybasis;
+ float3 v1;
+ float3 v2;
+
+ if (curvekey == CData->curve_firstkey[curve]) {
+ subv = 0;
+ v1 = CData->curvekey_co[min(
+ curvekey + 2, CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)] -
+ CData->curvekey_co[curvekey + 1];
+ v2 = CData->curvekey_co[curvekey + 1] - CData->curvekey_co[curvekey];
+ }
+ else if (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) {
+ v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey - 1];
+ v2 = CData->curvekey_co[curvekey - 1] -
+ CData->curvekey_co[max(curvekey - 2, CData->curve_firstkey[curve])];
+ }
+ else {
+ v1 = CData->curvekey_co[curvekey + 1] - CData->curvekey_co[curvekey];
+ v2 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey - 1];
+ }
+
+ xbasis = cross(v1, v2);
+
+ if (len_squared(xbasis) >= 0.05f * len_squared(v1) * len_squared(v2)) {
+ xbasis = normalize(xbasis);
+ firstxbasis = xbasis;
+ }
+ else
+ xbasis = firstxbasis;
+
+ ybasis = normalize(cross(xbasis, v2));
+
+ for (; subv <= 1; subv++) {
+ float3 ickey_loc = make_float3(0.0f, 0.0f, 0.0f);
+ float time = 0.0f;
+
+ InterpolateKeySegments(subv, 1, curvekey, curve, &ickey_loc, &time, CData);
+
+ float radius = shaperadius(CData->psys_shape[sys],
+ CData->psys_rootradius[sys],
+ CData->psys_tipradius[sys],
+ time);
+
+ if ((curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2) &&
+ (subv == 1))
+ radius = shaperadius(CData->psys_shape[sys],
+ CData->psys_rootradius[sys],
+ CData->psys_tipradius[sys],
+ 0.95f);
+
+ if (CData->psys_closetip[sys] && (subv == 1) &&
+ (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2))
+ radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], 0.0f, 0.95f);
+
+ float angle = M_2PI_F / (float)resolution;
+ for (int section = 0; section < resolution; section++) {
+ float3 ickey_loc_shf = ickey_loc + radius * (cosf(angle * section) * xbasis +
+ sinf(angle * section) * ybasis);
+ mesh->add_vertex(ickey_loc_shf);
+ }
+
+ if (subv != 0) {
+ for (int section = 0; section < resolution - 1; section++) {
+ mesh->add_triangle(vertexindex - resolution + section,
+ vertexindex + section,
+ vertexindex - resolution + section + 1,
+ CData->psys_shader[sys],
+ true);
+ mesh->add_triangle(vertexindex + section + 1,
+ vertexindex - resolution + section + 1,
+ vertexindex + section,
+ CData->psys_shader[sys],
+ true);
+ }
+ mesh->add_triangle(vertexindex - 1,
+ vertexindex + resolution - 1,
+ vertexindex - resolution,
+ CData->psys_shader[sys],
+ true);
+ mesh->add_triangle(vertexindex,
+ vertexindex - resolution,
+ vertexindex + resolution - 1,
+ CData->psys_shader[sys],
+ true);
+ }
+ vertexindex += resolution;
+ }
+ }
+ }
+ }
+
+ mesh->resize_mesh(mesh->verts.size(), mesh->num_triangles());
+ mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
+ mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
+ mesh->add_face_normals();
+ mesh->add_vertex_normals();
+ mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
+
+ /* texture coords still needed */
}
static void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CData)
{
- int num_keys = 0;
- int num_curves = 0;
-
- if(mesh->num_curves())
- return;
-
- Attribute *attr_intercept = NULL;
- Attribute *attr_random = NULL;
-
- if(mesh->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT))
- attr_intercept = mesh->curve_attributes.add(ATTR_STD_CURVE_INTERCEPT);
- if(mesh->need_attribute(scene, ATTR_STD_CURVE_RANDOM))
- attr_random = mesh->curve_attributes.add(ATTR_STD_CURVE_RANDOM);
-
- /* compute and reserve size of arrays */
- for(int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
- for(int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; curve++) {
- num_keys += CData->curve_keynum[curve];
- num_curves++;
- }
- }
-
- if(num_curves > 0) {
- VLOG(1) << "Exporting curve segments for mesh " << mesh->name;
- }
-
- mesh->reserve_curves(mesh->num_curves() + num_curves, mesh->curve_keys.size() + num_keys);
-
- num_keys = 0;
- num_curves = 0;
-
- /* actually export */
- for(int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
- for(int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; curve++) {
- size_t num_curve_keys = 0;
-
- for(int curvekey = CData->curve_firstkey[curve];
- curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve];
- curvekey++)
- {
- const float3 ickey_loc = CData->curvekey_co[curvekey];
- const float curve_time = CData->curvekey_time[curvekey];
- const float curve_length = CData->curve_length[curve];
- const float time = (curve_length > 0.0f)
- ? curve_time / curve_length
- : 0.0f;
- float radius = shaperadius(CData->psys_shape[sys],
- CData->psys_rootradius[sys],
- CData->psys_tipradius[sys],
- time);
- if(CData->psys_closetip[sys] &&
- (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1))
- {
- radius = 0.0f;
- }
- mesh->add_curve_key(ickey_loc, radius);
- if(attr_intercept)
- attr_intercept->add(time);
-
- num_curve_keys++;
- }
-
- if(attr_random != NULL) {
- attr_random->add(hash_int_01(num_curves));
- }
-
- mesh->add_curve(num_keys, CData->psys_shader[sys]);
- num_keys += num_curve_keys;
- num_curves++;
- }
- }
-
- /* check allocation */
- if((mesh->curve_keys.size() != num_keys) || (mesh->num_curves() != num_curves)) {
- VLOG(1) << "Allocation failed, clearing data";
- mesh->clear();
- }
+ int num_keys = 0;
+ int num_curves = 0;
+
+ if (mesh->num_curves())
+ return;
+
+ Attribute *attr_intercept = NULL;
+ Attribute *attr_random = NULL;
+
+ if (mesh->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT))
+ attr_intercept = mesh->curve_attributes.add(ATTR_STD_CURVE_INTERCEPT);
+ if (mesh->need_attribute(scene, ATTR_STD_CURVE_RANDOM))
+ attr_random = mesh->curve_attributes.add(ATTR_STD_CURVE_RANDOM);
+
+ /* compute and reserve size of arrays */
+ for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
+ for (int curve = CData->psys_firstcurve[sys];
+ curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys];
+ curve++) {
+ num_keys += CData->curve_keynum[curve];
+ num_curves++;
+ }
+ }
+
+ if (num_curves > 0) {
+ VLOG(1) << "Exporting curve segments for mesh " << mesh->name;
+ }
+
+ mesh->reserve_curves(mesh->num_curves() + num_curves, mesh->curve_keys.size() + num_keys);
+
+ num_keys = 0;
+ num_curves = 0;
+
+ /* actually export */
+ for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
+ for (int curve = CData->psys_firstcurve[sys];
+ curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys];
+ curve++) {
+ size_t num_curve_keys = 0;
+
+ for (int curvekey = CData->curve_firstkey[curve];
+ curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve];
+ curvekey++) {
+ const float3 ickey_loc = CData->curvekey_co[curvekey];
+ const float curve_time = CData->curvekey_time[curvekey];
+ const float curve_length = CData->curve_length[curve];
+ const float time = (curve_length > 0.0f) ? curve_time / curve_length : 0.0f;
+ float radius = shaperadius(
+ CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time);
+ if (CData->psys_closetip[sys] &&
+ (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)) {
+ radius = 0.0f;
+ }
+ mesh->add_curve_key(ickey_loc, radius);
+ if (attr_intercept)
+ attr_intercept->add(time);
+
+ num_curve_keys++;
+ }
+
+ if (attr_random != NULL) {
+ attr_random->add(hash_int_01(num_curves));
+ }
+
+ mesh->add_curve(num_keys, CData->psys_shader[sys]);
+ num_keys += num_curve_keys;
+ num_curves++;
+ }
+ }
+
+ /* check allocation */
+ if ((mesh->curve_keys.size() != num_keys) || (mesh->num_curves() != num_curves)) {
+ VLOG(1) << "Allocation failed, clearing data";
+ mesh->clear();
+ }
}
static float4 CurveSegmentMotionCV(ParticleCurveData *CData, int sys, int curve, int curvekey)
{
- const float3 ickey_loc = CData->curvekey_co[curvekey];
- const float curve_time = CData->curvekey_time[curvekey];
- const float curve_length = CData->curve_length[curve];
- float time = (curve_length > 0.0f) ? curve_time / curve_length : 0.0f;
- float radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time);
-
- if(CData->psys_closetip[sys] && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1))
- radius = 0.0f;
-
- /* curve motion keys store both position and radius in float4 */
- float4 mP = float3_to_float4(ickey_loc);
- mP.w = radius;
- return mP;
+ const float3 ickey_loc = CData->curvekey_co[curvekey];
+ const float curve_time = CData->curvekey_time[curvekey];
+ const float curve_length = CData->curve_length[curve];
+ float time = (curve_length > 0.0f) ? curve_time / curve_length : 0.0f;
+ float radius = shaperadius(
+ CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time);
+
+ if (CData->psys_closetip[sys] &&
+ (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1))
+ radius = 0.0f;
+
+ /* curve motion keys store both position and radius in float4 */
+ float4 mP = float3_to_float4(ickey_loc);
+ mP.w = radius;
+ return mP;
}
static float4 LerpCurveSegmentMotionCV(ParticleCurveData *CData, int sys, int curve, float step)
{
- assert(step >= 0.0f);
- assert(step <= 1.0f);
- const int first_curve_key = CData->curve_firstkey[curve];
- const float curve_key_f = step * (CData->curve_keynum[curve] - 1);
- int curvekey = (int)floorf(curve_key_f);
- const float remainder = curve_key_f - curvekey;
- if(remainder == 0.0f) {
- return CurveSegmentMotionCV(CData, sys, curve, first_curve_key + curvekey);
- }
- int curvekey2 = curvekey + 1;
- if(curvekey2 >= (CData->curve_keynum[curve] - 1)) {
- curvekey2 = (CData->curve_keynum[curve] - 1);
- curvekey = curvekey2 - 1;
- }
- const float4 mP = CurveSegmentMotionCV(
- CData, sys, curve, first_curve_key + curvekey);
- const float4 mP2 = CurveSegmentMotionCV(
- CData, sys, curve, first_curve_key + curvekey2);
- return lerp(mP, mP2, remainder);
+ assert(step >= 0.0f);
+ assert(step <= 1.0f);
+ const int first_curve_key = CData->curve_firstkey[curve];
+ const float curve_key_f = step * (CData->curve_keynum[curve] - 1);
+ int curvekey = (int)floorf(curve_key_f);
+ const float remainder = curve_key_f - curvekey;
+ if (remainder == 0.0f) {
+ return CurveSegmentMotionCV(CData, sys, curve, first_curve_key + curvekey);
+ }
+ int curvekey2 = curvekey + 1;
+ if (curvekey2 >= (CData->curve_keynum[curve] - 1)) {
+ curvekey2 = (CData->curve_keynum[curve] - 1);
+ curvekey = curvekey2 - 1;
+ }
+ const float4 mP = CurveSegmentMotionCV(CData, sys, curve, first_curve_key + curvekey);
+ const float4 mP2 = CurveSegmentMotionCV(CData, sys, curve, first_curve_key + curvekey2);
+ return lerp(mP, mP2, remainder);
}
static void ExportCurveSegmentsMotion(Mesh *mesh, ParticleCurveData *CData, int motion_step)
{
- VLOG(1) << "Exporting curve motion segments for mesh " << mesh->name
- << ", motion step " << motion_step;
-
- /* find attribute */
- Attribute *attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
- bool new_attribute = false;
-
- /* add new attribute if it doesn't exist already */
- if(!attr_mP) {
- VLOG(1) << "Creating new motion vertex position attribute";
- attr_mP = mesh->curve_attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
- new_attribute = true;
- }
-
- /* export motion vectors for curve keys */
- size_t numkeys = mesh->curve_keys.size();
- float4 *mP = attr_mP->data_float4() + motion_step*numkeys;
- bool have_motion = false;
- int i = 0;
- int num_curves = 0;
-
- for(int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
- for(int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; curve++) {
- /* Curve lengths may not match! Curves can be clipped. */
- int curve_key_end = (num_curves+1 < (int)mesh->curve_first_key.size() ? mesh->curve_first_key[num_curves+1] : (int)mesh->curve_keys.size());
- const int num_center_curve_keys = curve_key_end - mesh->curve_first_key[num_curves];
- const int is_num_keys_different = CData->curve_keynum[curve] - num_center_curve_keys;
-
- if(!is_num_keys_different) {
- for(int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve]; curvekey++) {
- if(i < mesh->curve_keys.size()) {
- mP[i] = CurveSegmentMotionCV(CData, sys, curve, curvekey);
- if(!have_motion) {
- /* unlike mesh coordinates, these tend to be slightly different
- * between frames due to particle transforms into/out of object
- * space, so we use an epsilon to detect actual changes */
- float4 curve_key = float3_to_float4(mesh->curve_keys[i]);
- curve_key.w = mesh->curve_radius[i];
- if(len_squared(mP[i] - curve_key) > 1e-5f*1e-5f)
- have_motion = true;
- }
- }
- i++;
- }
- }
- else {
- /* Number of keys has changed. Genereate an interpolated version
- * to preserve motion blur. */
- const float step_size =
- num_center_curve_keys > 1
- ? 1.0f / (num_center_curve_keys - 1)
- : 0.0f;
- for(int step_index = 0;
- step_index < num_center_curve_keys;
- ++step_index)
- {
- const float step = step_index * step_size;
- mP[i] = LerpCurveSegmentMotionCV(CData, sys, curve, step);
- i++;
- }
- have_motion = true;
- }
- num_curves++;
- }
- }
-
- /* in case of new attribute, we verify if there really was any motion */
- if(new_attribute) {
- if(i != numkeys || !have_motion) {
- /* No motion or hair "topology" changed, remove attributes again. */
- if(i != numkeys) {
- VLOG(1) << "Hair topology changed, removing attribute.";
- }
- else {
- VLOG(1) << "No motion, removing attribute.";
- }
- mesh->curve_attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
- }
- else if(motion_step > 0) {
- VLOG(1) << "Filling in new motion vertex position for motion_step "
- << motion_step;
- /* motion, fill up previous steps that we might have skipped because
- * they had no motion, but we need them anyway now */
- for(int step = 0; step < motion_step; step++) {
- float4 *mP = attr_mP->data_float4() + step*numkeys;
-
- for(int key = 0; key < numkeys; key++) {
- mP[key] = float3_to_float4(mesh->curve_keys[key]);
- mP[key].w = mesh->curve_radius[key];
- }
- }
- }
- }
+ VLOG(1) << "Exporting curve motion segments for mesh " << mesh->name << ", motion step "
+ << motion_step;
+
+ /* find attribute */
+ Attribute *attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ bool new_attribute = false;
+
+ /* add new attribute if it doesn't exist already */
+ if (!attr_mP) {
+ VLOG(1) << "Creating new motion vertex position attribute";
+ attr_mP = mesh->curve_attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
+ new_attribute = true;
+ }
+
+ /* export motion vectors for curve keys */
+ size_t numkeys = mesh->curve_keys.size();
+ float4 *mP = attr_mP->data_float4() + motion_step * numkeys;
+ bool have_motion = false;
+ int i = 0;
+ int num_curves = 0;
+
+ for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
+ for (int curve = CData->psys_firstcurve[sys];
+ curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys];
+ curve++) {
+ /* Curve lengths may not match! Curves can be clipped. */
+ int curve_key_end = (num_curves + 1 < (int)mesh->curve_first_key.size() ?
+ mesh->curve_first_key[num_curves + 1] :
+ (int)mesh->curve_keys.size());
+ const int num_center_curve_keys = curve_key_end - mesh->curve_first_key[num_curves];
+ const int is_num_keys_different = CData->curve_keynum[curve] - num_center_curve_keys;
+
+ if (!is_num_keys_different) {
+ for (int curvekey = CData->curve_firstkey[curve];
+ curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve];
+ curvekey++) {
+ if (i < mesh->curve_keys.size()) {
+ mP[i] = CurveSegmentMotionCV(CData, sys, curve, curvekey);
+ if (!have_motion) {
+ /* unlike mesh coordinates, these tend to be slightly different
+ * between frames due to particle transforms into/out of object
+ * space, so we use an epsilon to detect actual changes */
+ float4 curve_key = float3_to_float4(mesh->curve_keys[i]);
+ curve_key.w = mesh->curve_radius[i];
+ if (len_squared(mP[i] - curve_key) > 1e-5f * 1e-5f)
+ have_motion = true;
+ }
+ }
+ i++;
+ }
+ }
+ else {
+ /* Number of keys has changed. Genereate an interpolated version
+ * to preserve motion blur. */
+ const float step_size = num_center_curve_keys > 1 ? 1.0f / (num_center_curve_keys - 1) :
+ 0.0f;
+ for (int step_index = 0; step_index < num_center_curve_keys; ++step_index) {
+ const float step = step_index * step_size;
+ mP[i] = LerpCurveSegmentMotionCV(CData, sys, curve, step);
+ i++;
+ }
+ have_motion = true;
+ }
+ num_curves++;
+ }
+ }
+
+ /* in case of new attribute, we verify if there really was any motion */
+ if (new_attribute) {
+ if (i != numkeys || !have_motion) {
+ /* No motion or hair "topology" changed, remove attributes again. */
+ if (i != numkeys) {
+ VLOG(1) << "Hair topology changed, removing attribute.";
+ }
+ else {
+ VLOG(1) << "No motion, removing attribute.";
+ }
+ mesh->curve_attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
+ }
+ else if (motion_step > 0) {
+ VLOG(1) << "Filling in new motion vertex position for motion_step " << motion_step;
+ /* motion, fill up previous steps that we might have skipped because
+ * they had no motion, but we need them anyway now */
+ for (int step = 0; step < motion_step; step++) {
+ float4 *mP = attr_mP->data_float4() + step * numkeys;
+
+ for (int key = 0; key < numkeys; key++) {
+ mP[key] = float3_to_float4(mesh->curve_keys[key]);
+ mP[key].w = mesh->curve_radius[key];
+ }
+ }
+ }
+ }
}
static void ExportCurveTriangleUV(ParticleCurveData *CData,
@@ -754,30 +814,34 @@ static void ExportCurveTriangleUV(ParticleCurveData *CData,
int resol,
float2 *uvdata)
{
- if(uvdata == NULL)
- return;
- int vertexindex = vert_offset;
-
- for(int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
- for(int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; curve++) {
- for(int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) {
- for(int section = 0; section < resol; section++) {
- uvdata[vertexindex] = CData->curve_uv[curve];
- vertexindex++;
- uvdata[vertexindex] = CData->curve_uv[curve];
- vertexindex++;
- uvdata[vertexindex] = CData->curve_uv[curve];
- vertexindex++;
- uvdata[vertexindex] = CData->curve_uv[curve];
- vertexindex++;
- uvdata[vertexindex] = CData->curve_uv[curve];
- vertexindex++;
- uvdata[vertexindex] = CData->curve_uv[curve];
- vertexindex++;
- }
- }
- }
- }
+ if (uvdata == NULL)
+ return;
+ int vertexindex = vert_offset;
+
+ for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
+ for (int curve = CData->psys_firstcurve[sys];
+ curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys];
+ curve++) {
+ for (int curvekey = CData->curve_firstkey[curve];
+ curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1;
+ curvekey++) {
+ for (int section = 0; section < resol; section++) {
+ uvdata[vertexindex] = CData->curve_uv[curve];
+ vertexindex++;
+ uvdata[vertexindex] = CData->curve_uv[curve];
+ vertexindex++;
+ uvdata[vertexindex] = CData->curve_uv[curve];
+ vertexindex++;
+ uvdata[vertexindex] = CData->curve_uv[curve];
+ vertexindex++;
+ uvdata[vertexindex] = CData->curve_uv[curve];
+ vertexindex++;
+ uvdata[vertexindex] = CData->curve_uv[curve];
+ vertexindex++;
+ }
+ }
+ }
+ }
}
static void ExportCurveTriangleVcol(ParticleCurveData *CData,
@@ -785,295 +849,296 @@ static void ExportCurveTriangleVcol(ParticleCurveData *CData,
int resol,
uchar4 *cdata)
{
- if(cdata == NULL)
- return;
-
- int vertexindex = vert_offset;
-
- for(int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
- for(int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; curve++) {
- for(int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) {
- for(int section = 0; section < resol; section++) {
- /* Encode vertex color using the sRGB curve. */
- cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear_v3(CData->curve_vcol[curve]));
- vertexindex++;
- cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear_v3(CData->curve_vcol[curve]));
- vertexindex++;
- cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear_v3(CData->curve_vcol[curve]));
- vertexindex++;
- cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear_v3(CData->curve_vcol[curve]));
- vertexindex++;
- cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear_v3(CData->curve_vcol[curve]));
- vertexindex++;
- cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear_v3(CData->curve_vcol[curve]));
- vertexindex++;
- }
- }
- }
- }
+ if (cdata == NULL)
+ return;
+
+ int vertexindex = vert_offset;
+
+ for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
+ for (int curve = CData->psys_firstcurve[sys];
+ curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys];
+ curve++) {
+ for (int curvekey = CData->curve_firstkey[curve];
+ curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1;
+ curvekey++) {
+ for (int section = 0; section < resol; section++) {
+ /* Encode vertex color using the sRGB curve. */
+ cdata[vertexindex] = color_float_to_byte(
+ color_srgb_to_linear_v3(CData->curve_vcol[curve]));
+ vertexindex++;
+ cdata[vertexindex] = color_float_to_byte(
+ color_srgb_to_linear_v3(CData->curve_vcol[curve]));
+ vertexindex++;
+ cdata[vertexindex] = color_float_to_byte(
+ color_srgb_to_linear_v3(CData->curve_vcol[curve]));
+ vertexindex++;
+ cdata[vertexindex] = color_float_to_byte(
+ color_srgb_to_linear_v3(CData->curve_vcol[curve]));
+ vertexindex++;
+ cdata[vertexindex] = color_float_to_byte(
+ color_srgb_to_linear_v3(CData->curve_vcol[curve]));
+ vertexindex++;
+ cdata[vertexindex] = color_float_to_byte(
+ color_srgb_to_linear_v3(CData->curve_vcol[curve]));
+ vertexindex++;
+ }
+ }
+ }
+ }
}
/* Hair Curve Sync */
void BlenderSync::sync_curve_settings()
{
- PointerRNA csscene = RNA_pointer_get(&b_scene.ptr, "cycles_curves");
-
- CurveSystemManager *curve_system_manager = scene->curve_system_manager;
- CurveSystemManager prev_curve_system_manager = *curve_system_manager;
-
- curve_system_manager->use_curves = get_boolean(csscene, "use_curves");
- curve_system_manager->minimum_width = get_float(csscene, "minimum_width");
- curve_system_manager->maximum_width = get_float(csscene, "maximum_width");
-
- curve_system_manager->primitive =
- (CurvePrimitiveType)get_enum(csscene,
- "primitive",
- CURVE_NUM_PRIMITIVE_TYPES,
- CURVE_LINE_SEGMENTS);
- curve_system_manager->curve_shape =
- (CurveShapeType)get_enum(csscene,
- "shape",
- CURVE_NUM_SHAPE_TYPES,
- CURVE_THICK);
- curve_system_manager->resolution = get_int(csscene, "resolution");
- curve_system_manager->subdivisions = get_int(csscene, "subdivisions");
- curve_system_manager->use_backfacing = !get_boolean(csscene, "cull_backfacing");
-
- /* Triangles */
- if(curve_system_manager->primitive == CURVE_TRIANGLES) {
- /* camera facing planes */
- if(curve_system_manager->curve_shape == CURVE_RIBBON) {
- curve_system_manager->triangle_method = CURVE_CAMERA_TRIANGLES;
- curve_system_manager->resolution = 1;
- }
- else if(curve_system_manager->curve_shape == CURVE_THICK) {
- curve_system_manager->triangle_method = CURVE_TESSELATED_TRIANGLES;
- }
- }
- /* Line Segments */
- else if(curve_system_manager->primitive == CURVE_LINE_SEGMENTS) {
- if(curve_system_manager->curve_shape == CURVE_RIBBON) {
- /* tangent shading */
- curve_system_manager->line_method = CURVE_UNCORRECTED;
- curve_system_manager->use_encasing = true;
- curve_system_manager->use_backfacing = false;
- curve_system_manager->use_tangent_normal_geometry = true;
- }
- else if(curve_system_manager->curve_shape == CURVE_THICK) {
- curve_system_manager->line_method = CURVE_ACCURATE;
- curve_system_manager->use_encasing = false;
- curve_system_manager->use_tangent_normal_geometry = false;
- }
- }
- /* Curve Segments */
- else if(curve_system_manager->primitive == CURVE_SEGMENTS) {
- if(curve_system_manager->curve_shape == CURVE_RIBBON) {
- curve_system_manager->primitive = CURVE_RIBBONS;
- curve_system_manager->use_backfacing = false;
- }
- }
-
- if(curve_system_manager->modified_mesh(prev_curve_system_manager)) {
- BL::BlendData::objects_iterator b_ob;
-
- for(b_data.objects.begin(b_ob); b_ob != b_data.objects.end(); ++b_ob) {
- if(object_is_mesh(*b_ob)) {
- BL::Object::particle_systems_iterator b_psys;
- for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys) {
- if((b_psys->settings().render_type()==BL::ParticleSettings::render_type_PATH)&&(b_psys->settings().type()==BL::ParticleSettings::type_HAIR)) {
- BL::ID key = BKE_object_is_modified(*b_ob)? *b_ob: b_ob->data();
- mesh_map.set_recalc(key);
- object_map.set_recalc(*b_ob);
- }
- }
- }
- }
- }
-
- if(curve_system_manager->modified(prev_curve_system_manager))
- curve_system_manager->tag_update(scene);
+ PointerRNA csscene = RNA_pointer_get(&b_scene.ptr, "cycles_curves");
+
+ CurveSystemManager *curve_system_manager = scene->curve_system_manager;
+ CurveSystemManager prev_curve_system_manager = *curve_system_manager;
+
+ curve_system_manager->use_curves = get_boolean(csscene, "use_curves");
+ curve_system_manager->minimum_width = get_float(csscene, "minimum_width");
+ curve_system_manager->maximum_width = get_float(csscene, "maximum_width");
+
+ curve_system_manager->primitive = (CurvePrimitiveType)get_enum(
+ csscene, "primitive", CURVE_NUM_PRIMITIVE_TYPES, CURVE_LINE_SEGMENTS);
+ curve_system_manager->curve_shape = (CurveShapeType)get_enum(
+ csscene, "shape", CURVE_NUM_SHAPE_TYPES, CURVE_THICK);
+ curve_system_manager->resolution = get_int(csscene, "resolution");
+ curve_system_manager->subdivisions = get_int(csscene, "subdivisions");
+ curve_system_manager->use_backfacing = !get_boolean(csscene, "cull_backfacing");
+
+ /* Triangles */
+ if (curve_system_manager->primitive == CURVE_TRIANGLES) {
+ /* camera facing planes */
+ if (curve_system_manager->curve_shape == CURVE_RIBBON) {
+ curve_system_manager->triangle_method = CURVE_CAMERA_TRIANGLES;
+ curve_system_manager->resolution = 1;
+ }
+ else if (curve_system_manager->curve_shape == CURVE_THICK) {
+ curve_system_manager->triangle_method = CURVE_TESSELATED_TRIANGLES;
+ }
+ }
+ /* Line Segments */
+ else if (curve_system_manager->primitive == CURVE_LINE_SEGMENTS) {
+ if (curve_system_manager->curve_shape == CURVE_RIBBON) {
+ /* tangent shading */
+ curve_system_manager->line_method = CURVE_UNCORRECTED;
+ curve_system_manager->use_encasing = true;
+ curve_system_manager->use_backfacing = false;
+ curve_system_manager->use_tangent_normal_geometry = true;
+ }
+ else if (curve_system_manager->curve_shape == CURVE_THICK) {
+ curve_system_manager->line_method = CURVE_ACCURATE;
+ curve_system_manager->use_encasing = false;
+ curve_system_manager->use_tangent_normal_geometry = false;
+ }
+ }
+ /* Curve Segments */
+ else if (curve_system_manager->primitive == CURVE_SEGMENTS) {
+ if (curve_system_manager->curve_shape == CURVE_RIBBON) {
+ curve_system_manager->primitive = CURVE_RIBBONS;
+ curve_system_manager->use_backfacing = false;
+ }
+ }
+
+ if (curve_system_manager->modified_mesh(prev_curve_system_manager)) {
+ BL::BlendData::objects_iterator b_ob;
+
+ for (b_data.objects.begin(b_ob); b_ob != b_data.objects.end(); ++b_ob) {
+ if (object_is_mesh(*b_ob)) {
+ BL::Object::particle_systems_iterator b_psys;
+ for (b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end();
+ ++b_psys) {
+ if ((b_psys->settings().render_type() == BL::ParticleSettings::render_type_PATH) &&
+ (b_psys->settings().type() == BL::ParticleSettings::type_HAIR)) {
+ BL::ID key = BKE_object_is_modified(*b_ob) ? *b_ob : b_ob->data();
+ mesh_map.set_recalc(key);
+ object_map.set_recalc(*b_ob);
+ }
+ }
+ }
+ }
+ }
+
+ if (curve_system_manager->modified(prev_curve_system_manager))
+ curve_system_manager->tag_update(scene);
}
-void BlenderSync::sync_curves(Mesh *mesh,
- BL::Mesh& b_mesh,
- BL::Object& b_ob,
- bool motion,
- int motion_step)
+void BlenderSync::sync_curves(
+ Mesh *mesh, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step)
{
- if(!motion) {
- /* Clear stored curve data */
- mesh->curve_keys.clear();
- mesh->curve_radius.clear();
- mesh->curve_first_key.clear();
- mesh->curve_shader.clear();
- mesh->curve_attributes.clear();
- }
-
- /* obtain general settings */
- const bool use_curves = scene->curve_system_manager->use_curves;
-
- if(!(use_curves && b_ob.mode() != b_ob.mode_PARTICLE_EDIT)) {
- if(!motion)
- mesh->compute_bounds();
- return;
- }
-
- const int primitive = scene->curve_system_manager->primitive;
- const int triangle_method = scene->curve_system_manager->triangle_method;
- const int resolution = scene->curve_system_manager->resolution;
- const size_t vert_num = mesh->verts.size();
- const size_t tri_num = mesh->num_triangles();
- int used_res = 1;
-
- /* extract particle hair data - should be combined with connecting to mesh later*/
-
- ParticleCurveData CData;
-
- ObtainCacheParticleData(mesh, &b_mesh, &b_ob, &CData, !preview);
-
- /* add hair geometry to mesh */
- if(primitive == CURVE_TRIANGLES) {
- 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;
- }
- }
- else {
- if(motion)
- ExportCurveSegmentsMotion(mesh, &CData, motion_step);
- else
- ExportCurveSegments(scene, mesh, &CData);
- }
-
- /* generated coordinates from first key. we should ideally get this from
- * blender to handle deforming objects */
- if(!motion) {
- if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
- float3 loc, size;
- mesh_texture_space(b_mesh, loc, size);
-
- if(primitive == CURVE_TRIANGLES) {
- Attribute *attr_generated = mesh->attributes.add(ATTR_STD_GENERATED);
- float3 *generated = attr_generated->data_float3();
-
- for(size_t i = vert_num; i < mesh->verts.size(); i++)
- generated[i] = mesh->verts[i]*size - loc;
- }
- else {
- Attribute *attr_generated = mesh->curve_attributes.add(ATTR_STD_GENERATED);
- float3 *generated = attr_generated->data_float3();
-
- for(size_t i = 0; i < mesh->num_curves(); i++) {
- float3 co = mesh->curve_keys[mesh->get_curve(i).first_key];
- generated[i] = co*size - loc;
- }
- }
- }
- }
-
- /* create vertex color attributes */
- if(!motion) {
- BL::Mesh::vertex_colors_iterator l;
- int vcol_num = 0;
-
- for(b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l, vcol_num++) {
- if(!mesh->need_attribute(scene, ustring(l->name().c_str())))
- continue;
-
- ObtainCacheParticleVcol(mesh, &b_mesh, &b_ob, &CData, !preview, vcol_num);
-
- if(primitive == CURVE_TRIANGLES) {
- Attribute *attr_vcol = mesh->attributes.add(
- ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CORNER_BYTE);
-
- uchar4 *cdata = attr_vcol->data_uchar4();
-
- ExportCurveTriangleVcol(&CData, tri_num * 3, used_res, cdata);
- }
- else {
- Attribute *attr_vcol = mesh->curve_attributes.add(
- ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CURVE);
-
- float3 *fdata = attr_vcol->data_float3();
-
- if(fdata) {
- size_t i = 0;
-
- /* Encode vertex color using the sRGB curve. */
- for(size_t curve = 0; curve < CData.curve_vcol.size(); curve++) {
- fdata[i++] = color_srgb_to_linear_v3(CData.curve_vcol[curve]);
- }
- }
- }
- }
- }
-
- /* create UV attributes */
- if(!motion) {
- BL::Mesh::uv_layers_iterator l;
- int uv_num = 0;
-
- for(b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l, uv_num++) {
- bool active_render = l->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_uv;
-
- ObtainCacheParticleUV(mesh, &b_mesh, &b_ob, &CData, !preview, uv_num);
-
- if(primitive == CURVE_TRIANGLES) {
- if(active_render)
- attr_uv = mesh->attributes.add(std, name);
- else
- attr_uv = mesh->attributes.add(name, TypeFloat2, ATTR_ELEMENT_CORNER);
-
- float2 *uv = attr_uv->data_float2();
-
- ExportCurveTriangleUV(&CData, tri_num * 3, used_res, uv);
- }
- else {
- if(active_render)
- attr_uv = mesh->curve_attributes.add(std, name);
- else
- attr_uv = mesh->curve_attributes.add(name, TypeFloat2, ATTR_ELEMENT_CURVE);
-
- float2 *uv = attr_uv->data_float2();
-
- if(uv) {
- size_t i = 0;
-
- for(size_t curve = 0; curve < CData.curve_uv.size(); curve++) {
- uv[i++] = CData.curve_uv[curve];
- }
- }
- }
- }
- }
- }
-
- mesh->compute_bounds();
+ if (!motion) {
+ /* Clear stored curve data */
+ mesh->curve_keys.clear();
+ mesh->curve_radius.clear();
+ mesh->curve_first_key.clear();
+ mesh->curve_shader.clear();
+ mesh->curve_attributes.clear();
+ }
+
+ /* obtain general settings */
+ const bool use_curves = scene->curve_system_manager->use_curves;
+
+ if (!(use_curves && b_ob.mode() != b_ob.mode_PARTICLE_EDIT)) {
+ if (!motion)
+ mesh->compute_bounds();
+ return;
+ }
+
+ const int primitive = scene->curve_system_manager->primitive;
+ const int triangle_method = scene->curve_system_manager->triangle_method;
+ const int resolution = scene->curve_system_manager->resolution;
+ const size_t vert_num = mesh->verts.size();
+ const size_t tri_num = mesh->num_triangles();
+ int used_res = 1;
+
+ /* extract particle hair data - should be combined with connecting to mesh later*/
+
+ ParticleCurveData CData;
+
+ ObtainCacheParticleData(mesh, &b_mesh, &b_ob, &CData, !preview);
+
+ /* add hair geometry to mesh */
+ if (primitive == CURVE_TRIANGLES) {
+ 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;
+ }
+ }
+ else {
+ if (motion)
+ ExportCurveSegmentsMotion(mesh, &CData, motion_step);
+ else
+ ExportCurveSegments(scene, mesh, &CData);
+ }
+
+ /* generated coordinates from first key. we should ideally get this from
+ * blender to handle deforming objects */
+ if (!motion) {
+ if (mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
+ float3 loc, size;
+ mesh_texture_space(b_mesh, loc, size);
+
+ if (primitive == CURVE_TRIANGLES) {
+ Attribute *attr_generated = mesh->attributes.add(ATTR_STD_GENERATED);
+ float3 *generated = attr_generated->data_float3();
+
+ for (size_t i = vert_num; i < mesh->verts.size(); i++)
+ generated[i] = mesh->verts[i] * size - loc;
+ }
+ else {
+ Attribute *attr_generated = mesh->curve_attributes.add(ATTR_STD_GENERATED);
+ float3 *generated = attr_generated->data_float3();
+
+ for (size_t i = 0; i < mesh->num_curves(); i++) {
+ float3 co = mesh->curve_keys[mesh->get_curve(i).first_key];
+ generated[i] = co * size - loc;
+ }
+ }
+ }
+ }
+
+ /* create vertex color attributes */
+ if (!motion) {
+ BL::Mesh::vertex_colors_iterator l;
+ int vcol_num = 0;
+
+ for (b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l, vcol_num++) {
+ if (!mesh->need_attribute(scene, ustring(l->name().c_str())))
+ continue;
+
+ ObtainCacheParticleVcol(mesh, &b_mesh, &b_ob, &CData, !preview, vcol_num);
+
+ if (primitive == CURVE_TRIANGLES) {
+ Attribute *attr_vcol = mesh->attributes.add(
+ ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CORNER_BYTE);
+
+ uchar4 *cdata = attr_vcol->data_uchar4();
+
+ ExportCurveTriangleVcol(&CData, tri_num * 3, used_res, cdata);
+ }
+ else {
+ Attribute *attr_vcol = mesh->curve_attributes.add(
+ ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CURVE);
+
+ float3 *fdata = attr_vcol->data_float3();
+
+ if (fdata) {
+ size_t i = 0;
+
+ /* Encode vertex color using the sRGB curve. */
+ for (size_t curve = 0; curve < CData.curve_vcol.size(); curve++) {
+ fdata[i++] = color_srgb_to_linear_v3(CData.curve_vcol[curve]);
+ }
+ }
+ }
+ }
+ }
+
+ /* create UV attributes */
+ if (!motion) {
+ BL::Mesh::uv_layers_iterator l;
+ int uv_num = 0;
+
+ for (b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l, uv_num++) {
+ bool active_render = l->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_uv;
+
+ ObtainCacheParticleUV(mesh, &b_mesh, &b_ob, &CData, !preview, uv_num);
+
+ if (primitive == CURVE_TRIANGLES) {
+ if (active_render)
+ attr_uv = mesh->attributes.add(std, name);
+ else
+ attr_uv = mesh->attributes.add(name, TypeFloat2, ATTR_ELEMENT_CORNER);
+
+ float2 *uv = attr_uv->data_float2();
+
+ ExportCurveTriangleUV(&CData, tri_num * 3, used_res, uv);
+ }
+ else {
+ if (active_render)
+ attr_uv = mesh->curve_attributes.add(std, name);
+ else
+ attr_uv = mesh->curve_attributes.add(name, TypeFloat2, ATTR_ELEMENT_CURVE);
+
+ float2 *uv = attr_uv->data_float2();
+
+ if (uv) {
+ size_t i = 0;
+
+ for (size_t curve = 0; curve < CData.curve_uv.size(); curve++) {
+ uv[i++] = CData.curve_uv[curve];
+ }
+ }
+ }
+ }
+ }
+ }
+
+ mesh->compute_bounds();
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_device.cpp b/intern/cycles/blender/blender_device.cpp
index 969601b1c37..98fc0c6dec4 100644
--- a/intern/cycles/blender/blender_device.cpp
+++ b/intern/cycles/blender/blender_device.cpp
@@ -19,91 +19,89 @@
CCL_NAMESPACE_BEGIN
-int blender_device_threads(BL::Scene& b_scene)
+int blender_device_threads(BL::Scene &b_scene)
{
- BL::RenderSettings b_r = b_scene.render();
+ BL::RenderSettings b_r = b_scene.render();
- if(b_r.threads_mode() == BL::RenderSettings::threads_mode_FIXED)
- return b_r.threads();
- else
- return 0;
+ if (b_r.threads_mode() == BL::RenderSettings::threads_mode_FIXED)
+ return b_r.threads();
+ else
+ return 0;
}
-DeviceInfo blender_device_info(BL::Preferences& b_preferences, BL::Scene& b_scene, bool background)
+DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scene, bool background)
{
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
- /* Default to CPU device. */
- DeviceInfo device = Device::available_devices(DEVICE_MASK_CPU).front();
+ /* Default to CPU device. */
+ DeviceInfo device = Device::available_devices(DEVICE_MASK_CPU).front();
- if(get_enum(cscene, "device") == 2) {
- /* Find network device. */
- vector<DeviceInfo> devices = Device::available_devices(DEVICE_MASK_NETWORK);
- if(!devices.empty()) {
- device = devices.front();
- }
- }
- else if(get_enum(cscene, "device") == 1) {
- /* Find cycles preferences. */
- PointerRNA cpreferences;
+ if (get_enum(cscene, "device") == 2) {
+ /* Find network device. */
+ vector<DeviceInfo> devices = Device::available_devices(DEVICE_MASK_NETWORK);
+ if (!devices.empty()) {
+ device = devices.front();
+ }
+ }
+ else if (get_enum(cscene, "device") == 1) {
+ /* Find cycles preferences. */
+ PointerRNA cpreferences;
- BL::Preferences::addons_iterator b_addon_iter;
- for(b_preferences.addons.begin(b_addon_iter); b_addon_iter != b_preferences.addons.end(); ++b_addon_iter) {
- if(b_addon_iter->module() == "cycles") {
- cpreferences = b_addon_iter->preferences().ptr;
- break;
- }
- }
+ BL::Preferences::addons_iterator b_addon_iter;
+ for (b_preferences.addons.begin(b_addon_iter); b_addon_iter != b_preferences.addons.end();
+ ++b_addon_iter) {
+ if (b_addon_iter->module() == "cycles") {
+ cpreferences = b_addon_iter->preferences().ptr;
+ break;
+ }
+ }
- /* Test if we are using GPU devices. */
- enum ComputeDevice {
- COMPUTE_DEVICE_CPU = 0,
- COMPUTE_DEVICE_CUDA = 1,
- COMPUTE_DEVICE_OPENCL = 2,
- COMPUTE_DEVICE_NUM = 3,
- };
+ /* Test if we are using GPU devices. */
+ enum ComputeDevice {
+ COMPUTE_DEVICE_CPU = 0,
+ COMPUTE_DEVICE_CUDA = 1,
+ COMPUTE_DEVICE_OPENCL = 2,
+ COMPUTE_DEVICE_NUM = 3,
+ };
- ComputeDevice compute_device = (ComputeDevice)get_enum(cpreferences,
- "compute_device_type",
- COMPUTE_DEVICE_NUM,
- COMPUTE_DEVICE_CPU);
+ ComputeDevice compute_device = (ComputeDevice)get_enum(
+ cpreferences, "compute_device_type", COMPUTE_DEVICE_NUM, COMPUTE_DEVICE_CPU);
- if(compute_device != COMPUTE_DEVICE_CPU) {
- /* Query GPU devices with matching types. */
- uint mask = DEVICE_MASK_CPU;
- if(compute_device == COMPUTE_DEVICE_CUDA) {
- mask |= DEVICE_MASK_CUDA;
- }
- else if(compute_device == COMPUTE_DEVICE_OPENCL) {
- mask |= DEVICE_MASK_OPENCL;
- }
- vector<DeviceInfo> devices = Device::available_devices(mask);
+ if (compute_device != COMPUTE_DEVICE_CPU) {
+ /* Query GPU devices with matching types. */
+ uint mask = DEVICE_MASK_CPU;
+ if (compute_device == COMPUTE_DEVICE_CUDA) {
+ mask |= DEVICE_MASK_CUDA;
+ }
+ else if (compute_device == COMPUTE_DEVICE_OPENCL) {
+ mask |= DEVICE_MASK_OPENCL;
+ }
+ vector<DeviceInfo> devices = Device::available_devices(mask);
- /* Match device preferences and available devices. */
- vector<DeviceInfo> used_devices;
- RNA_BEGIN(&cpreferences, device, "devices") {
- if(get_boolean(device, "use")) {
- string id = get_string(device, "id");
- foreach(DeviceInfo& info, devices) {
- if(info.id == id) {
- used_devices.push_back(info);
- break;
- }
- }
- }
- } RNA_END;
+ /* Match device preferences and available devices. */
+ vector<DeviceInfo> used_devices;
+ RNA_BEGIN (&cpreferences, device, "devices") {
+ if (get_boolean(device, "use")) {
+ string id = get_string(device, "id");
+ foreach (DeviceInfo &info, devices) {
+ if (info.id == id) {
+ used_devices.push_back(info);
+ break;
+ }
+ }
+ }
+ }
+ RNA_END;
- if(!used_devices.empty()) {
- int threads = blender_device_threads(b_scene);
- device = Device::get_multi_device(used_devices,
- threads,
- background);
- }
- /* Else keep using the CPU device that was set before. */
- }
- }
+ if (!used_devices.empty()) {
+ int threads = blender_device_threads(b_scene);
+ device = Device::get_multi_device(used_devices, threads, background);
+ }
+ /* Else keep using the CPU device that was set before. */
+ }
+ }
- return device;
+ return device;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_device.h b/intern/cycles/blender/blender_device.h
index 061020936e2..fd6c045c966 100644
--- a/intern/cycles/blender/blender_device.h
+++ b/intern/cycles/blender/blender_device.h
@@ -27,11 +27,13 @@
CCL_NAMESPACE_BEGIN
/* Get number of threads to use for rendering. */
-int blender_device_threads(BL::Scene& b_scene);
+int blender_device_threads(BL::Scene &b_scene);
/* Convert Blender settings to device specification. */
-DeviceInfo blender_device_info(BL::Preferences& b_preferences, BL::Scene& b_scene, bool background);
+DeviceInfo blender_device_info(BL::Preferences &b_preferences,
+ BL::Scene &b_scene,
+ bool background);
CCL_NAMESPACE_END
-#endif /* __BLENDER_DEVICE_H__ */
+#endif /* __BLENDER_DEVICE_H__ */
diff --git a/intern/cycles/blender/blender_logging.cpp b/intern/cycles/blender/blender_logging.cpp
index 3fca4efd097..b42a1f47821 100644
--- a/intern/cycles/blender/blender_logging.cpp
+++ b/intern/cycles/blender/blender_logging.cpp
@@ -19,15 +19,15 @@
void CCL_init_logging(const char *argv0)
{
- ccl::util_logging_init(argv0);
+ ccl::util_logging_init(argv0);
}
void CCL_start_debug_logging()
{
- ccl::util_logging_start();
+ ccl::util_logging_start();
}
void CCL_logging_verbosity_set(int verbosity)
{
- ccl::util_logging_verbosity_set(verbosity);
+ ccl::util_logging_verbosity_set(verbosity);
}
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index 9b2c2c8e5d5..de594f4fb6c 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -38,1241 +38,1174 @@ CCL_NAMESPACE_BEGIN
/* Tangent Space */
struct MikkUserData {
- MikkUserData(const BL::Mesh& b_mesh,
- const char *layer_name,
- const Mesh *mesh,
- float3 *tangent,
- float *tangent_sign)
- : mesh(mesh),
- texface(NULL),
- orco(NULL),
- tangent(tangent),
- tangent_sign(tangent_sign)
- {
- const AttributeSet& attributes = (mesh->subd_faces.size()) ?
- mesh->subd_attributes : mesh->attributes;
-
- Attribute *attr_vN = attributes.find(ATTR_STD_VERTEX_NORMAL);
- vertex_normal = attr_vN->data_float3();
-
- if(layer_name == NULL) {
- Attribute *attr_orco = attributes.find(ATTR_STD_GENERATED);
-
- if(attr_orco) {
- orco = attr_orco->data_float3();
- mesh_texture_space(*(BL::Mesh*)&b_mesh, orco_loc, orco_size);
- }
- }
- else {
- Attribute *attr_uv = attributes.find(ustring(layer_name));
- if(attr_uv != NULL) {
- texface = attr_uv->data_float2();
- }
- }
- }
-
- const Mesh *mesh;
- int num_faces;
-
- float3 *vertex_normal;
- float2 *texface;
- float3 *orco;
- float3 orco_loc, orco_size;
-
- float3 *tangent;
- float *tangent_sign;
+ MikkUserData(const BL::Mesh &b_mesh,
+ const char *layer_name,
+ const Mesh *mesh,
+ float3 *tangent,
+ float *tangent_sign)
+ : mesh(mesh), texface(NULL), orco(NULL), tangent(tangent), tangent_sign(tangent_sign)
+ {
+ const AttributeSet &attributes = (mesh->subd_faces.size()) ? mesh->subd_attributes :
+ mesh->attributes;
+
+ Attribute *attr_vN = attributes.find(ATTR_STD_VERTEX_NORMAL);
+ vertex_normal = attr_vN->data_float3();
+
+ if (layer_name == NULL) {
+ Attribute *attr_orco = attributes.find(ATTR_STD_GENERATED);
+
+ if (attr_orco) {
+ orco = attr_orco->data_float3();
+ mesh_texture_space(*(BL::Mesh *)&b_mesh, orco_loc, orco_size);
+ }
+ }
+ else {
+ Attribute *attr_uv = attributes.find(ustring(layer_name));
+ if (attr_uv != NULL) {
+ texface = attr_uv->data_float2();
+ }
+ }
+ }
+
+ const Mesh *mesh;
+ int num_faces;
+
+ float3 *vertex_normal;
+ float2 *texface;
+ float3 *orco;
+ float3 orco_loc, orco_size;
+
+ float3 *tangent;
+ float *tangent_sign;
};
static int mikk_get_num_faces(const SMikkTSpaceContext *context)
{
- const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
- if(userdata->mesh->subd_faces.size()) {
- return userdata->mesh->subd_faces.size();
- }
- else {
- return userdata->mesh->num_triangles();
- }
+ const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
+ if (userdata->mesh->subd_faces.size()) {
+ return userdata->mesh->subd_faces.size();
+ }
+ else {
+ return userdata->mesh->num_triangles();
+ }
}
-static int mikk_get_num_verts_of_face(const SMikkTSpaceContext *context,
- const int face_num)
+static int mikk_get_num_verts_of_face(const SMikkTSpaceContext *context, const int face_num)
{
- const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
- if(userdata->mesh->subd_faces.size()) {
- const Mesh *mesh = userdata->mesh;
- return mesh->subd_faces[face_num].num_corners;
- }
- else {
- return 3;
- }
+ const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
+ if (userdata->mesh->subd_faces.size()) {
+ const Mesh *mesh = userdata->mesh;
+ return mesh->subd_faces[face_num].num_corners;
+ }
+ else {
+ return 3;
+ }
}
static int mikk_vertex_index(const Mesh *mesh, const int face_num, const int vert_num)
{
- if(mesh->subd_faces.size()) {
- const Mesh::SubdFace& face = mesh->subd_faces[face_num];
- return mesh->subd_face_corners[face.start_corner + vert_num];
- }
- else {
- return mesh->triangles[face_num * 3 + vert_num];
- }
+ if (mesh->subd_faces.size()) {
+ const Mesh::SubdFace &face = mesh->subd_faces[face_num];
+ return mesh->subd_face_corners[face.start_corner + vert_num];
+ }
+ else {
+ return mesh->triangles[face_num * 3 + vert_num];
+ }
}
static int mikk_corner_index(const Mesh *mesh, const int face_num, const int vert_num)
{
- if(mesh->subd_faces.size()) {
- const Mesh::SubdFace& face = mesh->subd_faces[face_num];
- return face.start_corner + vert_num;
- }
- else {
- return face_num * 3 + vert_num;
- }
+ if (mesh->subd_faces.size()) {
+ const Mesh::SubdFace &face = mesh->subd_faces[face_num];
+ return face.start_corner + vert_num;
+ }
+ else {
+ return face_num * 3 + vert_num;
+ }
}
static void mikk_get_position(const SMikkTSpaceContext *context,
float P[3],
- const int face_num, const int vert_num)
+ const int face_num,
+ const int vert_num)
{
- const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
- const Mesh *mesh = userdata->mesh;
- const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num);
- const float3 vP = mesh->verts[vertex_index];
- P[0] = vP.x;
- P[1] = vP.y;
- P[2] = vP.z;
+ const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
+ const Mesh *mesh = userdata->mesh;
+ const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num);
+ const float3 vP = mesh->verts[vertex_index];
+ P[0] = vP.x;
+ P[1] = vP.y;
+ P[2] = vP.z;
}
static void mikk_get_texture_coordinate(const SMikkTSpaceContext *context,
float uv[2],
- const int face_num, const int vert_num)
+ const int face_num,
+ const int vert_num)
{
- const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
- const Mesh *mesh = userdata->mesh;
- if(userdata->texface != NULL) {
- const int corner_index = mikk_corner_index(mesh, face_num, vert_num);
- float2 tfuv = userdata->texface[corner_index];
- uv[0] = tfuv.x;
- uv[1] = tfuv.y;
- }
- else if(userdata->orco != NULL) {
- const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num);
- const float3 orco_loc = userdata->orco_loc;
- const float3 orco_size = userdata->orco_size;
- const float3 orco = (userdata->orco[vertex_index] + orco_loc) / orco_size;
-
- const float2 tmp = map_to_sphere(orco);
- uv[0] = tmp.x;
- uv[1] = tmp.y;
- }
- else {
- uv[0] = 0.0f;
- uv[1] = 0.0f;
- }
+ const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
+ const Mesh *mesh = userdata->mesh;
+ if (userdata->texface != NULL) {
+ const int corner_index = mikk_corner_index(mesh, face_num, vert_num);
+ float2 tfuv = userdata->texface[corner_index];
+ uv[0] = tfuv.x;
+ uv[1] = tfuv.y;
+ }
+ else if (userdata->orco != NULL) {
+ const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num);
+ const float3 orco_loc = userdata->orco_loc;
+ const float3 orco_size = userdata->orco_size;
+ const float3 orco = (userdata->orco[vertex_index] + orco_loc) / orco_size;
+
+ const float2 tmp = map_to_sphere(orco);
+ uv[0] = tmp.x;
+ uv[1] = tmp.y;
+ }
+ else {
+ uv[0] = 0.0f;
+ uv[1] = 0.0f;
+ }
}
-static void mikk_get_normal(const SMikkTSpaceContext *context, float N[3],
- const int face_num, const int vert_num)
+static void mikk_get_normal(const SMikkTSpaceContext *context,
+ float N[3],
+ const int face_num,
+ const int vert_num)
{
- const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
- const Mesh *mesh = userdata->mesh;
- float3 vN;
- if(mesh->subd_faces.size()) {
- const Mesh::SubdFace& face = mesh->subd_faces[face_num];
- if(face.smooth) {
- const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num);
- vN = userdata->vertex_normal[vertex_index];
- }
- else {
- vN = face.normal(mesh);
- }
- }
- else {
- if(mesh->smooth[face_num]) {
- const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num);
- vN = userdata->vertex_normal[vertex_index];
- }
- else {
- const Mesh::Triangle tri = mesh->get_triangle(face_num);
- vN = tri.compute_normal(&mesh->verts[0]);
- }
- }
- N[0] = vN.x;
- N[1] = vN.y;
- N[2] = vN.z;
+ const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
+ const Mesh *mesh = userdata->mesh;
+ float3 vN;
+ if (mesh->subd_faces.size()) {
+ const Mesh::SubdFace &face = mesh->subd_faces[face_num];
+ if (face.smooth) {
+ const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num);
+ vN = userdata->vertex_normal[vertex_index];
+ }
+ else {
+ vN = face.normal(mesh);
+ }
+ }
+ else {
+ if (mesh->smooth[face_num]) {
+ const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num);
+ vN = userdata->vertex_normal[vertex_index];
+ }
+ else {
+ const Mesh::Triangle tri = mesh->get_triangle(face_num);
+ vN = tri.compute_normal(&mesh->verts[0]);
+ }
+ }
+ N[0] = vN.x;
+ N[1] = vN.y;
+ N[2] = vN.z;
}
static void mikk_set_tangent_space(const SMikkTSpaceContext *context,
const float T[],
const float sign,
- const int face_num, const int vert_num)
+ const int face_num,
+ const int vert_num)
{
- MikkUserData *userdata = (MikkUserData *)context->m_pUserData;
- const Mesh *mesh = userdata->mesh;
- const int corner_index = mikk_corner_index(mesh, face_num, vert_num);
- userdata->tangent[corner_index] = make_float3(T[0], T[1], T[2]);
- if(userdata->tangent_sign != NULL) {
- userdata->tangent_sign[corner_index] = sign;
- }
+ MikkUserData *userdata = (MikkUserData *)context->m_pUserData;
+ const Mesh *mesh = userdata->mesh;
+ const int corner_index = mikk_corner_index(mesh, face_num, vert_num);
+ userdata->tangent[corner_index] = make_float3(T[0], T[1], T[2]);
+ if (userdata->tangent_sign != NULL) {
+ userdata->tangent_sign[corner_index] = sign;
+ }
}
-static void mikk_compute_tangents(const BL::Mesh& b_mesh,
- const char *layer_name,
- Mesh *mesh,
- bool need_sign,
- bool active_render)
+static void mikk_compute_tangents(
+ const BL::Mesh &b_mesh, const char *layer_name, Mesh *mesh, bool need_sign, bool active_render)
{
- /* Create tangent attributes. */
- AttributeSet& attributes = (mesh->subd_faces.size()) ?
- mesh->subd_attributes : mesh->attributes;
- Attribute *attr;
- ustring name;
- if(layer_name != NULL) {
- name = ustring((string(layer_name) + ".tangent").c_str());
- }
- else {
- name = ustring("orco.tangent");
- }
- if(active_render) {
- attr = attributes.add(ATTR_STD_UV_TANGENT, name);
- }
- else {
- attr = attributes.add(name, TypeDesc::TypeVector, ATTR_ELEMENT_CORNER);
- }
- float3 *tangent = attr->data_float3();
- /* Create bitangent sign attribute. */
- float *tangent_sign = NULL;
- if(need_sign) {
- Attribute *attr_sign;
- ustring name_sign;
- if(layer_name != NULL) {
- name_sign = ustring((string(layer_name) +
- ".tangent_sign").c_str());
- }
- else {
- name_sign = ustring("orco.tangent_sign");
- }
-
- if(active_render) {
- attr_sign = attributes.add(ATTR_STD_UV_TANGENT_SIGN, name_sign);
- }
- else {
- attr_sign = attributes.add(name_sign,
- TypeDesc::TypeFloat,
- ATTR_ELEMENT_CORNER);
- }
- tangent_sign = attr_sign->data_float();
- }
- /* Setup userdata. */
- MikkUserData userdata(b_mesh, layer_name, mesh, tangent, tangent_sign);
- /* Setup interface. */
- SMikkTSpaceInterface sm_interface;
- memset(&sm_interface, 0, sizeof(sm_interface));
- sm_interface.m_getNumFaces = mikk_get_num_faces;
- sm_interface.m_getNumVerticesOfFace = mikk_get_num_verts_of_face;
- sm_interface.m_getPosition = mikk_get_position;
- sm_interface.m_getTexCoord = mikk_get_texture_coordinate;
- sm_interface.m_getNormal = mikk_get_normal;
- sm_interface.m_setTSpaceBasic = mikk_set_tangent_space;
- /* Setup context. */
- SMikkTSpaceContext context;
- memset(&context, 0, sizeof(context));
- context.m_pUserData = &userdata;
- context.m_pInterface = &sm_interface;
- /* Compute tangents. */
- genTangSpaceDefault(&context);
+ /* Create tangent attributes. */
+ AttributeSet &attributes = (mesh->subd_faces.size()) ? mesh->subd_attributes : mesh->attributes;
+ Attribute *attr;
+ ustring name;
+ if (layer_name != NULL) {
+ name = ustring((string(layer_name) + ".tangent").c_str());
+ }
+ else {
+ name = ustring("orco.tangent");
+ }
+ if (active_render) {
+ attr = attributes.add(ATTR_STD_UV_TANGENT, name);
+ }
+ else {
+ attr = attributes.add(name, TypeDesc::TypeVector, ATTR_ELEMENT_CORNER);
+ }
+ float3 *tangent = attr->data_float3();
+ /* Create bitangent sign attribute. */
+ float *tangent_sign = NULL;
+ if (need_sign) {
+ Attribute *attr_sign;
+ ustring name_sign;
+ if (layer_name != NULL) {
+ name_sign = ustring((string(layer_name) + ".tangent_sign").c_str());
+ }
+ else {
+ name_sign = ustring("orco.tangent_sign");
+ }
+
+ if (active_render) {
+ attr_sign = attributes.add(ATTR_STD_UV_TANGENT_SIGN, name_sign);
+ }
+ else {
+ attr_sign = attributes.add(name_sign, TypeDesc::TypeFloat, ATTR_ELEMENT_CORNER);
+ }
+ tangent_sign = attr_sign->data_float();
+ }
+ /* Setup userdata. */
+ MikkUserData userdata(b_mesh, layer_name, mesh, tangent, tangent_sign);
+ /* Setup interface. */
+ SMikkTSpaceInterface sm_interface;
+ memset(&sm_interface, 0, sizeof(sm_interface));
+ sm_interface.m_getNumFaces = mikk_get_num_faces;
+ sm_interface.m_getNumVerticesOfFace = mikk_get_num_verts_of_face;
+ sm_interface.m_getPosition = mikk_get_position;
+ sm_interface.m_getTexCoord = mikk_get_texture_coordinate;
+ sm_interface.m_getNormal = mikk_get_normal;
+ sm_interface.m_setTSpaceBasic = mikk_set_tangent_space;
+ /* Setup context. */
+ SMikkTSpaceContext context;
+ memset(&context, 0, sizeof(context));
+ context.m_pUserData = &userdata;
+ context.m_pInterface = &sm_interface;
+ /* Compute tangents. */
+ genTangSpaceDefault(&context);
}
/* Create Volume Attribute */
-static void create_mesh_volume_attribute(BL::Object& b_ob,
- Mesh *mesh,
- ImageManager *image_manager,
- AttributeStandard std,
- float frame)
+static void create_mesh_volume_attribute(
+ BL::Object &b_ob, Mesh *mesh, ImageManager *image_manager, AttributeStandard std, float frame)
{
- BL::SmokeDomainSettings b_domain = object_smoke_domain_find(b_ob);
-
- if(!b_domain)
- return;
-
- mesh->volume_isovalue = b_domain.clipping();
-
- Attribute *attr = mesh->attributes.add(std);
- VoxelAttribute *volume_data = attr->data_voxel();
- ImageMetaData metadata;
- bool animated = false;
- bool use_alpha = true;
-
- volume_data->manager = image_manager;
- volume_data->slot = image_manager->add_image(
- Attribute::standard_name(std),
- b_ob.ptr.data,
- animated,
- frame,
- INTERPOLATION_LINEAR,
- EXTENSION_CLIP,
- use_alpha,
- metadata);
+ BL::SmokeDomainSettings b_domain = object_smoke_domain_find(b_ob);
+
+ if (!b_domain)
+ return;
+
+ mesh->volume_isovalue = b_domain.clipping();
+
+ Attribute *attr = mesh->attributes.add(std);
+ VoxelAttribute *volume_data = attr->data_voxel();
+ ImageMetaData metadata;
+ bool animated = false;
+ bool use_alpha = true;
+
+ volume_data->manager = image_manager;
+ volume_data->slot = image_manager->add_image(Attribute::standard_name(std),
+ b_ob.ptr.data,
+ animated,
+ frame,
+ INTERPOLATION_LINEAR,
+ EXTENSION_CLIP,
+ use_alpha,
+ metadata);
}
-static void create_mesh_volume_attributes(Scene *scene,
- BL::Object& b_ob,
- Mesh *mesh,
- float frame)
+static void create_mesh_volume_attributes(Scene *scene, BL::Object &b_ob, Mesh *mesh, float frame)
{
- /* for smoke volume rendering */
- if(mesh->need_attribute(scene, ATTR_STD_VOLUME_DENSITY))
- create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_DENSITY, frame);
- if(mesh->need_attribute(scene, ATTR_STD_VOLUME_COLOR))
- create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_COLOR, frame);
- if(mesh->need_attribute(scene, ATTR_STD_VOLUME_FLAME))
- create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_FLAME, frame);
- if(mesh->need_attribute(scene, ATTR_STD_VOLUME_HEAT))
- create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_HEAT, frame);
- if(mesh->need_attribute(scene, ATTR_STD_VOLUME_TEMPERATURE))
- create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_TEMPERATURE, frame);
- if(mesh->need_attribute(scene, ATTR_STD_VOLUME_VELOCITY))
- create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_VELOCITY, frame);
+ /* for smoke volume rendering */
+ if (mesh->need_attribute(scene, ATTR_STD_VOLUME_DENSITY))
+ create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_DENSITY, frame);
+ if (mesh->need_attribute(scene, ATTR_STD_VOLUME_COLOR))
+ create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_COLOR, frame);
+ if (mesh->need_attribute(scene, ATTR_STD_VOLUME_FLAME))
+ create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_FLAME, frame);
+ if (mesh->need_attribute(scene, ATTR_STD_VOLUME_HEAT))
+ create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_HEAT, frame);
+ if (mesh->need_attribute(scene, ATTR_STD_VOLUME_TEMPERATURE))
+ create_mesh_volume_attribute(
+ b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_TEMPERATURE, frame);
+ if (mesh->need_attribute(scene, ATTR_STD_VOLUME_VELOCITY))
+ create_mesh_volume_attribute(
+ b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_VELOCITY, frame);
}
/* Create vertex color attributes. */
-static void attr_create_vertex_color(Scene *scene,
- Mesh *mesh,
- BL::Mesh& b_mesh,
- bool subdivision)
+static void attr_create_vertex_color(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivision)
{
- if(subdivision) {
- BL::Mesh::vertex_colors_iterator l;
-
- 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;
-
- Attribute *attr = mesh->subd_attributes.add(ustring(l->name().c_str()),
- TypeDesc::TypeColor,
- ATTR_ELEMENT_CORNER_BYTE);
-
- BL::Mesh::polygons_iterator p;
- uchar4 *cdata = attr->data_uchar4();
-
- 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());
- /* Compress/encode vertex color using the sRGB curve. */
- *(cdata++) = color_float_to_byte(color_srgb_to_linear_v3(color));
- }
- }
- }
- }
- else {
- BL::Mesh::vertex_colors_iterator l;
- 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;
-
- Attribute *attr = mesh->attributes.add(ustring(l->name().c_str()),
- TypeDesc::TypeColor,
- ATTR_ELEMENT_CORNER_BYTE);
-
- BL::Mesh::loop_triangles_iterator t;
- uchar4 *cdata = attr->data_uchar4();
-
- for(b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
- int3 li = get_int3(t->loops());
- float3 c1 = get_float3(l->data[li[0]].color());
- float3 c2 = get_float3(l->data[li[1]].color());
- float3 c3 = get_float3(l->data[li[2]].color());
-
- /* Compress/encode vertex color using the sRGB curve. */
- cdata[0] = color_float_to_byte(color_srgb_to_linear_v3(c1));
- cdata[1] = color_float_to_byte(color_srgb_to_linear_v3(c2));
- cdata[2] = color_float_to_byte(color_srgb_to_linear_v3(c3));
- cdata += 3;
- }
- }
- }
+ if (subdivision) {
+ BL::Mesh::vertex_colors_iterator l;
+
+ 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;
+
+ Attribute *attr = mesh->subd_attributes.add(
+ ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CORNER_BYTE);
+
+ BL::Mesh::polygons_iterator p;
+ uchar4 *cdata = attr->data_uchar4();
+
+ 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());
+ /* Compress/encode vertex color using the sRGB curve. */
+ *(cdata++) = color_float_to_byte(color_srgb_to_linear_v3(color));
+ }
+ }
+ }
+ }
+ else {
+ BL::Mesh::vertex_colors_iterator l;
+ 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;
+
+ Attribute *attr = mesh->attributes.add(
+ ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CORNER_BYTE);
+
+ BL::Mesh::loop_triangles_iterator t;
+ uchar4 *cdata = attr->data_uchar4();
+
+ for (b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
+ int3 li = get_int3(t->loops());
+ float3 c1 = get_float3(l->data[li[0]].color());
+ float3 c2 = get_float3(l->data[li[1]].color());
+ float3 c3 = get_float3(l->data[li[2]].color());
+
+ /* Compress/encode vertex color using the sRGB curve. */
+ cdata[0] = color_float_to_byte(color_srgb_to_linear_v3(c1));
+ cdata[1] = color_float_to_byte(color_srgb_to_linear_v3(c2));
+ cdata[2] = color_float_to_byte(color_srgb_to_linear_v3(c3));
+ cdata += 3;
+ }
+ }
+ }
}
/* Create uv map attributes. */
-static void attr_create_uv_map(Scene *scene,
- Mesh *mesh,
- BL::Mesh& b_mesh)
+static void attr_create_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh)
{
- if(b_mesh.uv_layers.length() != 0) {
- BL::Mesh::uv_layers_iterator l;
-
- for(b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l) {
- const bool active_render = l->active_render();
- AttributeStandard uv_std = (active_render)? ATTR_STD_UV: ATTR_STD_NONE;
- ustring uv_name = ustring(l->name().c_str());
- AttributeStandard tangent_std = (active_render)? ATTR_STD_UV_TANGENT
- : ATTR_STD_NONE;
- ustring tangent_name = ustring(
- (string(l->name().c_str()) + ".tangent").c_str());
-
- /* Denotes whether UV map was requested directly. */
- const bool need_uv = mesh->need_attribute(scene, uv_name) ||
- mesh->need_attribute(scene, uv_std);
- /* Denotes whether tangent was requested directly. */
- const bool need_tangent =
- mesh->need_attribute(scene, tangent_name) ||
- (active_render && mesh->need_attribute(scene, tangent_std));
-
- /* UV map */
- /* NOTE: We create temporary UV layer if its needed for tangent but
- * wasn't requested by other nodes in shaders.
- */
- Attribute *uv_attr = NULL;
- if(need_uv || need_tangent) {
- if(active_render) {
- uv_attr = mesh->attributes.add(uv_std, uv_name);
- }
- else {
- uv_attr = mesh->attributes.add(uv_name,
- TypeFloat2,
- ATTR_ELEMENT_CORNER);
- }
-
- BL::Mesh::loop_triangles_iterator t;
- float2 *fdata = uv_attr->data_float2();
-
- for(b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
- int3 li = get_int3(t->loops());
- fdata[0] = get_float2(l->data[li[0]].uv());
- fdata[1] = get_float2(l->data[li[1]].uv());
- fdata[2] = get_float2(l->data[li[2]].uv());
- fdata += 3;
- }
- }
-
- /* UV tangent */
- if(need_tangent) {
- AttributeStandard sign_std =
- (active_render)? ATTR_STD_UV_TANGENT_SIGN
- : ATTR_STD_NONE;
- ustring sign_name = ustring(
- (string(l->name().c_str()) + ".tangent_sign").c_str());
- bool need_sign = (mesh->need_attribute(scene, sign_name) ||
- mesh->need_attribute(scene, sign_std));
- mikk_compute_tangents(b_mesh,
- l->name().c_str(),
- mesh,
- need_sign,
- active_render);
- }
- /* Remove temporarily created UV attribute. */
- if(!need_uv && uv_attr != NULL) {
- mesh->attributes.remove(uv_attr);
- }
- }
- }
- 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, need_sign, true);
- if(!mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
- mesh->attributes.remove(ATTR_STD_GENERATED);
- }
- }
+ if (b_mesh.uv_layers.length() != 0) {
+ BL::Mesh::uv_layers_iterator l;
+
+ for (b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l) {
+ const bool active_render = l->active_render();
+ AttributeStandard uv_std = (active_render) ? ATTR_STD_UV : ATTR_STD_NONE;
+ ustring uv_name = ustring(l->name().c_str());
+ AttributeStandard tangent_std = (active_render) ? ATTR_STD_UV_TANGENT : ATTR_STD_NONE;
+ ustring tangent_name = ustring((string(l->name().c_str()) + ".tangent").c_str());
+
+ /* Denotes whether UV map was requested directly. */
+ const bool need_uv = mesh->need_attribute(scene, uv_name) ||
+ mesh->need_attribute(scene, uv_std);
+ /* Denotes whether tangent was requested directly. */
+ const bool need_tangent = mesh->need_attribute(scene, tangent_name) ||
+ (active_render && mesh->need_attribute(scene, tangent_std));
+
+ /* UV map */
+ /* NOTE: We create temporary UV layer if its needed for tangent but
+ * wasn't requested by other nodes in shaders.
+ */
+ Attribute *uv_attr = NULL;
+ if (need_uv || need_tangent) {
+ if (active_render) {
+ uv_attr = mesh->attributes.add(uv_std, uv_name);
+ }
+ else {
+ uv_attr = mesh->attributes.add(uv_name, TypeFloat2, ATTR_ELEMENT_CORNER);
+ }
+
+ BL::Mesh::loop_triangles_iterator t;
+ float2 *fdata = uv_attr->data_float2();
+
+ for (b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
+ int3 li = get_int3(t->loops());
+ fdata[0] = get_float2(l->data[li[0]].uv());
+ fdata[1] = get_float2(l->data[li[1]].uv());
+ fdata[2] = get_float2(l->data[li[2]].uv());
+ fdata += 3;
+ }
+ }
+
+ /* UV tangent */
+ if (need_tangent) {
+ AttributeStandard sign_std = (active_render) ? ATTR_STD_UV_TANGENT_SIGN : ATTR_STD_NONE;
+ ustring sign_name = ustring((string(l->name().c_str()) + ".tangent_sign").c_str());
+ bool need_sign = (mesh->need_attribute(scene, sign_name) ||
+ mesh->need_attribute(scene, sign_std));
+ mikk_compute_tangents(b_mesh, l->name().c_str(), mesh, need_sign, active_render);
+ }
+ /* Remove temporarily created UV attribute. */
+ if (!need_uv && uv_attr != NULL) {
+ mesh->attributes.remove(uv_attr);
+ }
+ }
+ }
+ 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, need_sign, true);
+ if (!mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
+ mesh->attributes.remove(ATTR_STD_GENERATED);
+ }
+ }
}
-static void attr_create_subd_uv_map(Scene *scene,
- Mesh *mesh,
- BL::Mesh& b_mesh,
- bool subdivide_uvs)
+static void attr_create_subd_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivide_uvs)
{
- if(b_mesh.uv_layers.length() != 0) {
- 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 = l->active_render();
- AttributeStandard uv_std = (active_render)? ATTR_STD_UV: ATTR_STD_NONE;
- ustring uv_name = ustring(l->name().c_str());
- AttributeStandard tangent_std = (active_render)? ATTR_STD_UV_TANGENT
- : ATTR_STD_NONE;
- ustring tangent_name = ustring(
- (string(l->name().c_str()) + ".tangent").c_str());
-
- /* Denotes whether UV map was requested directly. */
- const bool need_uv = mesh->need_attribute(scene, uv_name) ||
- mesh->need_attribute(scene, uv_std);
- /* Denotes whether tangent was requested directly. */
- const bool need_tangent =
- mesh->need_attribute(scene, tangent_name) ||
- (active_render && mesh->need_attribute(scene, tangent_std));
-
- Attribute *uv_attr = NULL;
-
- /* UV map */
- if(need_uv || need_tangent) {
- if(active_render)
- uv_attr = mesh->subd_attributes.add(uv_std, uv_name);
- else
- uv_attr = mesh->subd_attributes.add(uv_name, TypeFloat2, ATTR_ELEMENT_CORNER);
-
- if(subdivide_uvs) {
- uv_attr->flags |= ATTR_SUBDIVIDED;
- }
-
- BL::Mesh::polygons_iterator p;
- float2 *fdata = uv_attr->data_float2();
-
- 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_float2(l->data[p->loop_start() + j].uv());
- }
- }
- }
-
- /* UV tangent */
- if(need_tangent) {
- AttributeStandard sign_std =
- (active_render)? ATTR_STD_UV_TANGENT_SIGN
- : ATTR_STD_NONE;
- ustring sign_name = ustring(
- (string(l->name().c_str()) + ".tangent_sign").c_str());
- bool need_sign = (mesh->need_attribute(scene, sign_name) ||
- mesh->need_attribute(scene, sign_std));
- mikk_compute_tangents(b_mesh,
- l->name().c_str(),
- mesh,
- need_sign,
- active_render);
- }
- /* Remove temporarily created UV attribute. */
- if(!need_uv && uv_attr != NULL) {
- mesh->subd_attributes.remove(uv_attr);
- }
- }
- }
- 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, need_sign, true);
- if(!mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
- mesh->subd_attributes.remove(ATTR_STD_GENERATED);
- }
- }
+ if (b_mesh.uv_layers.length() != 0) {
+ 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 = l->active_render();
+ AttributeStandard uv_std = (active_render) ? ATTR_STD_UV : ATTR_STD_NONE;
+ ustring uv_name = ustring(l->name().c_str());
+ AttributeStandard tangent_std = (active_render) ? ATTR_STD_UV_TANGENT : ATTR_STD_NONE;
+ ustring tangent_name = ustring((string(l->name().c_str()) + ".tangent").c_str());
+
+ /* Denotes whether UV map was requested directly. */
+ const bool need_uv = mesh->need_attribute(scene, uv_name) ||
+ mesh->need_attribute(scene, uv_std);
+ /* Denotes whether tangent was requested directly. */
+ const bool need_tangent = mesh->need_attribute(scene, tangent_name) ||
+ (active_render && mesh->need_attribute(scene, tangent_std));
+
+ Attribute *uv_attr = NULL;
+
+ /* UV map */
+ if (need_uv || need_tangent) {
+ if (active_render)
+ uv_attr = mesh->subd_attributes.add(uv_std, uv_name);
+ else
+ uv_attr = mesh->subd_attributes.add(uv_name, TypeFloat2, ATTR_ELEMENT_CORNER);
+
+ if (subdivide_uvs) {
+ uv_attr->flags |= ATTR_SUBDIVIDED;
+ }
+
+ BL::Mesh::polygons_iterator p;
+ float2 *fdata = uv_attr->data_float2();
+
+ 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_float2(l->data[p->loop_start() + j].uv());
+ }
+ }
+ }
+
+ /* UV tangent */
+ if (need_tangent) {
+ AttributeStandard sign_std = (active_render) ? ATTR_STD_UV_TANGENT_SIGN : ATTR_STD_NONE;
+ ustring sign_name = ustring((string(l->name().c_str()) + ".tangent_sign").c_str());
+ bool need_sign = (mesh->need_attribute(scene, sign_name) ||
+ mesh->need_attribute(scene, sign_std));
+ mikk_compute_tangents(b_mesh, l->name().c_str(), mesh, need_sign, active_render);
+ }
+ /* Remove temporarily created UV attribute. */
+ if (!need_uv && uv_attr != NULL) {
+ mesh->subd_attributes.remove(uv_attr);
+ }
+ }
+ }
+ 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, need_sign, true);
+ if (!mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
+ mesh->subd_attributes.remove(ATTR_STD_GENERATED);
+ }
+ }
}
/* Create vertex pointiness attributes. */
/* Compare vertices by sum of their coordinates. */
class VertexAverageComparator {
-public:
- VertexAverageComparator(const array<float3>& verts)
- : verts_(verts) {
- }
-
- bool operator()(const int& vert_idx_a, const int& vert_idx_b)
- {
- const float3 &vert_a = verts_[vert_idx_a];
- const float3 &vert_b = verts_[vert_idx_b];
- if(vert_a == vert_b) {
- /* Special case for doubles, so we ensure ordering. */
- return vert_idx_a > vert_idx_b;
- }
- const float x1 = vert_a.x + vert_a.y + vert_a.z;
- const float x2 = vert_b.x + vert_b.y + vert_b.z;
- return x1 < x2;
- }
-
-protected:
- const array<float3>& verts_;
+ public:
+ VertexAverageComparator(const array<float3> &verts) : verts_(verts)
+ {
+ }
+
+ bool operator()(const int &vert_idx_a, const int &vert_idx_b)
+ {
+ const float3 &vert_a = verts_[vert_idx_a];
+ const float3 &vert_b = verts_[vert_idx_b];
+ if (vert_a == vert_b) {
+ /* Special case for doubles, so we ensure ordering. */
+ return vert_idx_a > vert_idx_b;
+ }
+ const float x1 = vert_a.x + vert_a.y + vert_a.z;
+ const float x2 = vert_b.x + vert_b.y + vert_b.z;
+ return x1 < x2;
+ }
+
+ protected:
+ const array<float3> &verts_;
};
-static void attr_create_pointiness(Scene *scene,
- Mesh *mesh,
- BL::Mesh& b_mesh,
- bool subdivision)
+static void attr_create_pointiness(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivision)
{
- if(!mesh->need_attribute(scene, ATTR_STD_POINTINESS)) {
- return;
- }
- const int num_verts = b_mesh.vertices.length();
- if(num_verts == 0) {
- return;
- }
- /* STEP 1: Find out duplicated vertices and point duplicates to a single
- * original vertex.
- */
- vector<int> sorted_vert_indeices(num_verts);
- for(int vert_index = 0; vert_index < num_verts; ++vert_index) {
- sorted_vert_indeices[vert_index] = vert_index;
- }
- VertexAverageComparator compare(mesh->verts);
- sort(sorted_vert_indeices.begin(), sorted_vert_indeices.end(), compare);
- /* This array stores index of the original vertex for the given vertex
- * index.
- */
- vector<int> vert_orig_index(num_verts);
- for(int sorted_vert_index = 0;
- sorted_vert_index < num_verts;
- ++sorted_vert_index)
- {
- const int vert_index = sorted_vert_indeices[sorted_vert_index];
- const float3 &vert_co = mesh->verts[vert_index];
- bool found = false;
- for(int other_sorted_vert_index = sorted_vert_index + 1;
- other_sorted_vert_index < num_verts;
- ++other_sorted_vert_index)
- {
- const int other_vert_index =
- sorted_vert_indeices[other_sorted_vert_index];
- const float3 &other_vert_co = mesh->verts[other_vert_index];
- /* We are too far away now, we wouldn't have duplicate. */
- if((other_vert_co.x + other_vert_co.y + other_vert_co.z) -
- (vert_co.x + vert_co.y + vert_co.z) > 3 * FLT_EPSILON)
- {
- break;
- }
- /* Found duplicate. */
- if(len_squared(other_vert_co - vert_co) < FLT_EPSILON) {
- found = true;
- vert_orig_index[vert_index] = other_vert_index;
- break;
- }
- }
- if(!found) {
- vert_orig_index[vert_index] = vert_index;
- }
- }
- /* Make sure we always points to the very first orig vertex. */
- for(int vert_index = 0; vert_index < num_verts; ++vert_index) {
- int orig_index = vert_orig_index[vert_index];
- while(orig_index != vert_orig_index[orig_index]) {
- orig_index = vert_orig_index[orig_index];
- }
- vert_orig_index[vert_index] = orig_index;
- }
- sorted_vert_indeices.free_memory();
- /* STEP 2: Calculate vertex normals taking into account their possible
- * duplicates which gets "welded" together.
- */
- vector<float3> vert_normal(num_verts, make_float3(0.0f, 0.0f, 0.0f));
- /* First we accumulate all vertex normals in the original index. */
- for(int vert_index = 0; vert_index < num_verts; ++vert_index) {
- const float3 normal = get_float3(b_mesh.vertices[vert_index].normal());
- const int orig_index = vert_orig_index[vert_index];
- vert_normal[orig_index] += normal;
- }
- /* Then we normalize the accumulated result and flush it to all duplicates
- * as well.
- */
- for(int vert_index = 0; vert_index < num_verts; ++vert_index) {
- const int orig_index = vert_orig_index[vert_index];
- vert_normal[vert_index] = normalize(vert_normal[orig_index]);
- }
- /* STEP 3: Calculate pointiness using single ring neighborhood. */
- vector<int> counter(num_verts, 0);
- vector<float> raw_data(num_verts, 0.0f);
- vector<float3> edge_accum(num_verts, make_float3(0.0f, 0.0f, 0.0f));
- BL::Mesh::edges_iterator e;
- EdgeMap visited_edges;
- int edge_index = 0;
- memset(&counter[0], 0, sizeof(int) * counter.size());
- for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++edge_index) {
- const int v0 = vert_orig_index[b_mesh.edges[edge_index].vertices()[0]],
- v1 = vert_orig_index[b_mesh.edges[edge_index].vertices()[1]];
- if(visited_edges.exists(v0, v1)) {
- continue;
- }
- visited_edges.insert(v0, v1);
- float3 co0 = get_float3(b_mesh.vertices[v0].co()),
- co1 = get_float3(b_mesh.vertices[v1].co());
- float3 edge = normalize(co1 - co0);
- edge_accum[v0] += edge;
- edge_accum[v1] += -edge;
- ++counter[v0];
- ++counter[v1];
- }
- for(int vert_index = 0; vert_index < num_verts; ++vert_index) {
- const int orig_index = vert_orig_index[vert_index];
- if(orig_index != vert_index) {
- /* Skip duplicates, they'll be overwritten later on. */
- continue;
- }
- if(counter[vert_index] > 0) {
- const float3 normal = vert_normal[vert_index];
- const float angle =
- safe_acosf(dot(normal,
- edge_accum[vert_index] / counter[vert_index]));
- raw_data[vert_index] = angle * M_1_PI_F;
- }
- else {
- raw_data[vert_index] = 0.0f;
- }
- }
- /* STEP 3: Blur vertices to approximate 2 ring neighborhood. */
- AttributeSet& attributes = (subdivision)? mesh->subd_attributes: mesh->attributes;
- Attribute *attr = attributes.add(ATTR_STD_POINTINESS);
- float *data = attr->data_float();
- memcpy(data, &raw_data[0], sizeof(float) * raw_data.size());
- memset(&counter[0], 0, sizeof(int) * counter.size());
- edge_index = 0;
- visited_edges.clear();
- for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++edge_index) {
- const int v0 = vert_orig_index[b_mesh.edges[edge_index].vertices()[0]],
- v1 = vert_orig_index[b_mesh.edges[edge_index].vertices()[1]];
- if(visited_edges.exists(v0, v1)) {
- continue;
- }
- visited_edges.insert(v0, v1);
- data[v0] += raw_data[v1];
- data[v1] += raw_data[v0];
- ++counter[v0];
- ++counter[v1];
- }
- for(int vert_index = 0; vert_index < num_verts; ++vert_index) {
- data[vert_index] /= counter[vert_index] + 1;
- }
- /* STEP 4: Copy attribute to the duplicated vertices. */
- for(int vert_index = 0; vert_index < num_verts; ++vert_index) {
- const int orig_index = vert_orig_index[vert_index];
- data[vert_index] = data[orig_index];
- }
+ if (!mesh->need_attribute(scene, ATTR_STD_POINTINESS)) {
+ return;
+ }
+ const int num_verts = b_mesh.vertices.length();
+ if (num_verts == 0) {
+ return;
+ }
+ /* STEP 1: Find out duplicated vertices and point duplicates to a single
+ * original vertex.
+ */
+ vector<int> sorted_vert_indeices(num_verts);
+ for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
+ sorted_vert_indeices[vert_index] = vert_index;
+ }
+ VertexAverageComparator compare(mesh->verts);
+ sort(sorted_vert_indeices.begin(), sorted_vert_indeices.end(), compare);
+ /* This array stores index of the original vertex for the given vertex
+ * index.
+ */
+ vector<int> vert_orig_index(num_verts);
+ for (int sorted_vert_index = 0; sorted_vert_index < num_verts; ++sorted_vert_index) {
+ const int vert_index = sorted_vert_indeices[sorted_vert_index];
+ const float3 &vert_co = mesh->verts[vert_index];
+ bool found = false;
+ for (int other_sorted_vert_index = sorted_vert_index + 1; other_sorted_vert_index < num_verts;
+ ++other_sorted_vert_index) {
+ const int other_vert_index = sorted_vert_indeices[other_sorted_vert_index];
+ const float3 &other_vert_co = mesh->verts[other_vert_index];
+ /* We are too far away now, we wouldn't have duplicate. */
+ if ((other_vert_co.x + other_vert_co.y + other_vert_co.z) -
+ (vert_co.x + vert_co.y + vert_co.z) >
+ 3 * FLT_EPSILON) {
+ break;
+ }
+ /* Found duplicate. */
+ if (len_squared(other_vert_co - vert_co) < FLT_EPSILON) {
+ found = true;
+ vert_orig_index[vert_index] = other_vert_index;
+ break;
+ }
+ }
+ if (!found) {
+ vert_orig_index[vert_index] = vert_index;
+ }
+ }
+ /* Make sure we always points to the very first orig vertex. */
+ for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
+ int orig_index = vert_orig_index[vert_index];
+ while (orig_index != vert_orig_index[orig_index]) {
+ orig_index = vert_orig_index[orig_index];
+ }
+ vert_orig_index[vert_index] = orig_index;
+ }
+ sorted_vert_indeices.free_memory();
+ /* STEP 2: Calculate vertex normals taking into account their possible
+ * duplicates which gets "welded" together.
+ */
+ vector<float3> vert_normal(num_verts, make_float3(0.0f, 0.0f, 0.0f));
+ /* First we accumulate all vertex normals in the original index. */
+ for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
+ const float3 normal = get_float3(b_mesh.vertices[vert_index].normal());
+ const int orig_index = vert_orig_index[vert_index];
+ vert_normal[orig_index] += normal;
+ }
+ /* Then we normalize the accumulated result and flush it to all duplicates
+ * as well.
+ */
+ for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
+ const int orig_index = vert_orig_index[vert_index];
+ vert_normal[vert_index] = normalize(vert_normal[orig_index]);
+ }
+ /* STEP 3: Calculate pointiness using single ring neighborhood. */
+ vector<int> counter(num_verts, 0);
+ vector<float> raw_data(num_verts, 0.0f);
+ vector<float3> edge_accum(num_verts, make_float3(0.0f, 0.0f, 0.0f));
+ BL::Mesh::edges_iterator e;
+ EdgeMap visited_edges;
+ int edge_index = 0;
+ memset(&counter[0], 0, sizeof(int) * counter.size());
+ for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++edge_index) {
+ const int v0 = vert_orig_index[b_mesh.edges[edge_index].vertices()[0]],
+ v1 = vert_orig_index[b_mesh.edges[edge_index].vertices()[1]];
+ if (visited_edges.exists(v0, v1)) {
+ continue;
+ }
+ visited_edges.insert(v0, v1);
+ float3 co0 = get_float3(b_mesh.vertices[v0].co()), co1 = get_float3(b_mesh.vertices[v1].co());
+ float3 edge = normalize(co1 - co0);
+ edge_accum[v0] += edge;
+ edge_accum[v1] += -edge;
+ ++counter[v0];
+ ++counter[v1];
+ }
+ for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
+ const int orig_index = vert_orig_index[vert_index];
+ if (orig_index != vert_index) {
+ /* Skip duplicates, they'll be overwritten later on. */
+ continue;
+ }
+ if (counter[vert_index] > 0) {
+ const float3 normal = vert_normal[vert_index];
+ const float angle = safe_acosf(dot(normal, edge_accum[vert_index] / counter[vert_index]));
+ raw_data[vert_index] = angle * M_1_PI_F;
+ }
+ else {
+ raw_data[vert_index] = 0.0f;
+ }
+ }
+ /* STEP 3: Blur vertices to approximate 2 ring neighborhood. */
+ AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes;
+ Attribute *attr = attributes.add(ATTR_STD_POINTINESS);
+ float *data = attr->data_float();
+ memcpy(data, &raw_data[0], sizeof(float) * raw_data.size());
+ memset(&counter[0], 0, sizeof(int) * counter.size());
+ edge_index = 0;
+ visited_edges.clear();
+ for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++edge_index) {
+ const int v0 = vert_orig_index[b_mesh.edges[edge_index].vertices()[0]],
+ v1 = vert_orig_index[b_mesh.edges[edge_index].vertices()[1]];
+ if (visited_edges.exists(v0, v1)) {
+ continue;
+ }
+ visited_edges.insert(v0, v1);
+ data[v0] += raw_data[v1];
+ data[v1] += raw_data[v0];
+ ++counter[v0];
+ ++counter[v1];
+ }
+ for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
+ data[vert_index] /= counter[vert_index] + 1;
+ }
+ /* STEP 4: Copy attribute to the duplicated vertices. */
+ for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
+ const int orig_index = vert_orig_index[vert_index];
+ data[vert_index] = data[orig_index];
+ }
}
/* Create Mesh */
static void create_mesh(Scene *scene,
Mesh *mesh,
- BL::Mesh& b_mesh,
- const vector<Shader*>& used_shaders,
+ BL::Mesh &b_mesh,
+ const vector<Shader *> &used_shaders,
bool subdivision = false,
bool subdivide_uvs = true)
{
- /* count vertices and faces */
- int numverts = b_mesh.vertices.length();
- int numfaces = (!subdivision) ? b_mesh.loop_triangles.length() : b_mesh.polygons.length();
- int numtris = 0;
- int numcorners = 0;
- int numngons = 0;
- bool use_loop_normals = b_mesh.use_auto_smooth() && (mesh->subdivision_type != Mesh::SUBDIVISION_CATMULL_CLARK);
-
- /* If no faces, create empty mesh. */
- if(numfaces == 0) {
- return;
- }
-
- if(!subdivision) {
- numtris = numfaces;
- }
- else {
- BL::Mesh::polygons_iterator p;
- 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 */
- BL::Mesh::vertices_iterator v;
- for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v)
- mesh->add_vertex(get_float3(v->co()));
-
- 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)
- *N = get_float3(v->normal());
- N = attr_N->data_float3();
-
- /* create generated coordinates from undeformed coordinates */
- const bool need_default_tangent =
- (subdivision == false) &&
- (b_mesh.uv_layers.length() == 0) &&
- (mesh->need_attribute(scene, ATTR_STD_UV_TANGENT));
- if(mesh->need_attribute(scene, ATTR_STD_GENERATED) ||
- need_default_tangent)
- {
- Attribute *attr = attributes.add(ATTR_STD_GENERATED);
- attr->flags |= ATTR_SUBDIVIDED;
-
- float3 loc, size;
- mesh_texture_space(b_mesh, loc, size);
-
- float3 *generated = attr->data_float3();
- size_t i = 0;
-
- for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v) {
- generated[i++] = get_float3(v->undeformed_co())*size - loc;
- }
- }
-
- /* create faces */
- if(!subdivision) {
- BL::Mesh::loop_triangles_iterator t;
-
- for(b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
- BL::MeshPolygon p = b_mesh.polygons[t->polygon_index()];
- int3 vi = get_int3(t->vertices());
-
- int shader = clamp(p.material_index(), 0, used_shaders.size()-1);
- bool smooth = p.use_smooth() || use_loop_normals;
-
- if(use_loop_normals) {
- BL::Array<float, 9> loop_normals = t->split_normals();
- for(int i = 0; i < 3; i++) {
- N[vi[i]] = make_float3(loop_normals[i * 3],
- loop_normals[i * 3 + 1],
- loop_normals[i * 3 + 2]);
- }
- }
-
- /* Create triangles.
- *
- * NOTE: Autosmooth is already taken care about.
- */
- mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth);
- }
- }
- else {
- BL::Mesh::polygons_iterator p;
- 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;
-
- vi.resize(n);
- for(int i = 0; i < n; i++) {
- /* NOTE: Autosmooth is already taken care about. */
- vi[i] = b_mesh.loops[p->loop_start() + i].vertex_index();
- }
-
- /* 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_pointiness(scene, mesh, b_mesh, subdivision);
- attr_create_vertex_color(scene, mesh, b_mesh, subdivision);
-
- if(subdivision) {
- attr_create_subd_uv_map(scene, mesh, b_mesh, subdivide_uvs);
- }
- else {
- attr_create_uv_map(scene, mesh, b_mesh);
- }
-
- /* for volume objects, create a matrix to transform from object space to
- * mesh texture space. this does not work with deformations but that can
- * probably only be done well with a volume grid mapping of coordinates */
- if(mesh->need_attribute(scene, ATTR_STD_GENERATED_TRANSFORM)) {
- Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED_TRANSFORM);
- Transform *tfm = attr->data_transform();
-
- float3 loc, size;
- mesh_texture_space(b_mesh, loc, size);
-
- *tfm = transform_translate(-loc)*transform_scale(size);
- }
+ /* count vertices and faces */
+ int numverts = b_mesh.vertices.length();
+ int numfaces = (!subdivision) ? b_mesh.loop_triangles.length() : b_mesh.polygons.length();
+ int numtris = 0;
+ int numcorners = 0;
+ int numngons = 0;
+ bool use_loop_normals = b_mesh.use_auto_smooth() &&
+ (mesh->subdivision_type != Mesh::SUBDIVISION_CATMULL_CLARK);
+
+ /* If no faces, create empty mesh. */
+ if (numfaces == 0) {
+ return;
+ }
+
+ if (!subdivision) {
+ numtris = numfaces;
+ }
+ else {
+ BL::Mesh::polygons_iterator p;
+ 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 */
+ BL::Mesh::vertices_iterator v;
+ for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v)
+ mesh->add_vertex(get_float3(v->co()));
+
+ 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)
+ *N = get_float3(v->normal());
+ N = attr_N->data_float3();
+
+ /* create generated coordinates from undeformed coordinates */
+ const bool need_default_tangent = (subdivision == false) && (b_mesh.uv_layers.length() == 0) &&
+ (mesh->need_attribute(scene, ATTR_STD_UV_TANGENT));
+ if (mesh->need_attribute(scene, ATTR_STD_GENERATED) || need_default_tangent) {
+ Attribute *attr = attributes.add(ATTR_STD_GENERATED);
+ attr->flags |= ATTR_SUBDIVIDED;
+
+ float3 loc, size;
+ mesh_texture_space(b_mesh, loc, size);
+
+ float3 *generated = attr->data_float3();
+ size_t i = 0;
+
+ for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v) {
+ generated[i++] = get_float3(v->undeformed_co()) * size - loc;
+ }
+ }
+
+ /* create faces */
+ if (!subdivision) {
+ BL::Mesh::loop_triangles_iterator t;
+
+ for (b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
+ BL::MeshPolygon p = b_mesh.polygons[t->polygon_index()];
+ int3 vi = get_int3(t->vertices());
+
+ int shader = clamp(p.material_index(), 0, used_shaders.size() - 1);
+ bool smooth = p.use_smooth() || use_loop_normals;
+
+ if (use_loop_normals) {
+ BL::Array<float, 9> loop_normals = t->split_normals();
+ for (int i = 0; i < 3; i++) {
+ N[vi[i]] = make_float3(
+ loop_normals[i * 3], loop_normals[i * 3 + 1], loop_normals[i * 3 + 2]);
+ }
+ }
+
+ /* Create triangles.
+ *
+ * NOTE: Autosmooth is already taken care about.
+ */
+ mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth);
+ }
+ }
+ else {
+ BL::Mesh::polygons_iterator p;
+ 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;
+
+ vi.resize(n);
+ for (int i = 0; i < n; i++) {
+ /* NOTE: Autosmooth is already taken care about. */
+ vi[i] = b_mesh.loops[p->loop_start() + i].vertex_index();
+ }
+
+ /* 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_pointiness(scene, mesh, b_mesh, subdivision);
+ attr_create_vertex_color(scene, mesh, b_mesh, subdivision);
+
+ if (subdivision) {
+ attr_create_subd_uv_map(scene, mesh, b_mesh, subdivide_uvs);
+ }
+ else {
+ attr_create_uv_map(scene, mesh, b_mesh);
+ }
+
+ /* for volume objects, create a matrix to transform from object space to
+ * mesh texture space. this does not work with deformations but that can
+ * probably only be done well with a volume grid mapping of coordinates */
+ if (mesh->need_attribute(scene, ATTR_STD_GENERATED_TRANSFORM)) {
+ Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED_TRANSFORM);
+ Transform *tfm = attr->data_transform();
+
+ float3 loc, size;
+ mesh_texture_space(b_mesh, loc, size);
+
+ *tfm = transform_translate(-loc) * transform_scale(size);
+ }
}
static void create_subd_mesh(Scene *scene,
Mesh *mesh,
- BL::Object& b_ob,
- BL::Mesh& b_mesh,
- const vector<Shader*>& used_shaders,
+ BL::Object &b_ob,
+ BL::Mesh &b_mesh,
+ const vector<Shader *> &used_shaders,
float dicing_rate,
int max_subdivisions)
{
- BL::SubsurfModifier subsurf_mod(b_ob.modifiers[b_ob.modifiers.length()-1]);
- bool subdivide_uvs = subsurf_mod.uv_smooth() != BL::SubsurfModifier::uv_smooth_NONE;
+ BL::SubsurfModifier subsurf_mod(b_ob.modifiers[b_ob.modifiers.length() - 1]);
+ bool subdivide_uvs = subsurf_mod.uv_smooth() != BL::SubsurfModifier::uv_smooth_NONE;
- create_mesh(scene, mesh, b_mesh, used_shaders, true, subdivide_uvs);
+ create_mesh(scene, mesh, b_mesh, used_shaders, true, subdivide_uvs);
- /* export creases */
- size_t num_creases = 0;
- BL::Mesh::edges_iterator e;
+ /* 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++;
- }
- }
+ 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);
+ mesh->subd_creases.resize(num_creases);
- 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();
+ 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++;
- }
- }
+ crease++;
+ }
+ }
- /* set subd params */
- if(!mesh->subd_params) {
- mesh->subd_params = new SubdParams(mesh);
- }
- SubdParams& sdparams = *mesh->subd_params;
+ /* set subd params */
+ if (!mesh->subd_params) {
+ mesh->subd_params = new SubdParams(mesh);
+ }
+ SubdParams &sdparams = *mesh->subd_params;
- PointerRNA cobj = RNA_pointer_get(&b_ob.ptr, "cycles");
+ 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;
+ sdparams.dicing_rate = max(0.1f, RNA_float_get(&cobj, "dicing_rate") * dicing_rate);
+ sdparams.max_level = max_subdivisions;
- sdparams.objecttoworld = get_transform(b_ob.matrix_world());
+ sdparams.objecttoworld = get_transform(b_ob.matrix_world());
}
/* Sync */
-static void sync_mesh_fluid_motion(BL::Object& b_ob, Scene *scene, Mesh *mesh)
+static void sync_mesh_fluid_motion(BL::Object &b_ob, Scene *scene, Mesh *mesh)
{
- if(scene->need_motion() == Scene::MOTION_NONE)
- return;
+ if (scene->need_motion() == Scene::MOTION_NONE)
+ return;
- BL::DomainFluidSettings b_fluid_domain = object_fluid_domain_find(b_ob);
+ BL::DomainFluidSettings b_fluid_domain = object_fluid_domain_find(b_ob);
- if(!b_fluid_domain)
- return;
+ if (!b_fluid_domain)
+ return;
- /* If the mesh has modifiers following the fluid domain we can't export motion. */
- if(b_fluid_domain.fluid_mesh_vertices.length() != mesh->verts.size())
- return;
+ /* If the mesh has modifiers following the fluid domain we can't export motion. */
+ if (b_fluid_domain.fluid_mesh_vertices.length() != mesh->verts.size())
+ return;
- /* Find or add attribute */
- float3 *P = &mesh->verts[0];
- Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ /* Find or add attribute */
+ float3 *P = &mesh->verts[0];
+ Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
- if(!attr_mP) {
- attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
- }
+ if (!attr_mP) {
+ attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
+ }
- /* Only export previous and next frame, we don't have any in between data. */
- float motion_times[2] = {-1.0f, 1.0f};
- for(int step = 0; step < 2; step++) {
- float relative_time = motion_times[step] * scene->motion_shutter_time() * 0.5f;
- float3 *mP = attr_mP->data_float3() + step*mesh->verts.size();
+ /* Only export previous and next frame, we don't have any in between data. */
+ float motion_times[2] = {-1.0f, 1.0f};
+ for (int step = 0; step < 2; step++) {
+ float relative_time = motion_times[step] * scene->motion_shutter_time() * 0.5f;
+ float3 *mP = attr_mP->data_float3() + step * mesh->verts.size();
- BL::DomainFluidSettings::fluid_mesh_vertices_iterator fvi;
- int i = 0;
+ BL::DomainFluidSettings::fluid_mesh_vertices_iterator fvi;
+ int i = 0;
- for(b_fluid_domain.fluid_mesh_vertices.begin(fvi); fvi != b_fluid_domain.fluid_mesh_vertices.end(); ++fvi, ++i) {
- mP[i] = P[i] + get_float3(fvi->velocity()) * relative_time;
- }
- }
+ for (b_fluid_domain.fluid_mesh_vertices.begin(fvi);
+ fvi != b_fluid_domain.fluid_mesh_vertices.end();
+ ++fvi, ++i) {
+ mP[i] = P[i] + get_float3(fvi->velocity()) * relative_time;
+ }
+ }
}
-Mesh *BlenderSync::sync_mesh(BL::Depsgraph& b_depsgraph,
- BL::Object& b_ob,
- BL::Object& b_ob_instance,
+Mesh *BlenderSync::sync_mesh(BL::Depsgraph &b_depsgraph,
+ BL::Object &b_ob,
+ BL::Object &b_ob_instance,
bool object_updated,
bool show_self,
bool show_particles)
{
- /* test if we can instance or if the object is modified */
- BL::ID b_ob_data = b_ob.data();
- BL::ID key = (BKE_object_is_modified(b_ob))? b_ob_instance: b_ob_data;
- BL::Material material_override = view_layer.material_override;
-
- /* find shader indices */
- vector<Shader*> used_shaders;
-
- BL::Object::material_slots_iterator slot;
- for(b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) {
- if(material_override) {
- find_shader(material_override, used_shaders, scene->default_surface);
- }
- else {
- BL::ID b_material(slot->material());
- find_shader(b_material, used_shaders, scene->default_surface);
- }
- }
-
- if(used_shaders.size() == 0) {
- if(material_override)
- find_shader(material_override, used_shaders, scene->default_surface);
- else
- used_shaders.push_back(scene->default_surface);
- }
-
- /* test if we need to sync */
- int requested_geometry_flags = Mesh::GEOMETRY_NONE;
- if(view_layer.use_surfaces) {
- requested_geometry_flags |= Mesh::GEOMETRY_TRIANGLES;
- }
- if(view_layer.use_hair) {
- requested_geometry_flags |= Mesh::GEOMETRY_CURVES;
- }
- 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(requested_geometry_flags != mesh->geometry_flags);
- else {
- /* even if not tagged for recalc, we may need to sync anyway
- * because the shader needs different mesh attributes */
- bool attribute_recalc = false;
-
- foreach(Shader *shader, mesh->used_shaders)
- if(shader->need_update_mesh)
- attribute_recalc = true;
-
- if(!attribute_recalc)
- return mesh;
- }
- }
-
- /* ensure we only sync instanced meshes once */
- if(mesh_synced.find(mesh) != mesh_synced.end())
- return mesh;
-
- progress.set_sync_status("Synchronizing object", b_ob.name());
-
- mesh_synced.insert(mesh);
-
- /* create derived mesh */
- array<int> oldtriangles;
- array<Mesh::SubdFace> oldsubd_faces;
- array<int> oldsubd_face_corners;
- oldtriangles.steal_data(mesh->triangles);
- oldsubd_faces.steal_data(mesh->subd_faces);
- oldsubd_face_corners.steal_data(mesh->subd_face_corners);
-
- /* compares curve_keys rather than strands in order to handle quick hair
- * adjustments in dynamic BVH - other methods could probably do this better*/
- array<float3> oldcurve_keys;
- array<float> oldcurve_radius;
- oldcurve_keys.steal_data(mesh->curve_keys);
- oldcurve_radius.steal_data(mesh->curve_radius);
-
- mesh->clear();
- mesh->used_shaders = used_shaders;
- mesh->name = ustring(b_ob_data.name().c_str());
-
- if(requested_geometry_flags != Mesh::GEOMETRY_NONE) {
- /* Adaptive subdivision setup. Not for baking since that requires
- * exact mapping to the Blender mesh. */
- if(scene->bake_manager->get_baking()) {
- mesh->subdivision_type = Mesh::SUBDIVISION_NONE;
- }
- else {
- mesh->subdivision_type = object_subdivision_type(b_ob, preview, experimental);
- }
-
- /* For some reason, meshes do not need this... */
- bool need_undeformed = mesh->need_attribute(scene, ATTR_STD_GENERATED);
-
- BL::Mesh b_mesh = object_to_mesh(b_data,
- b_ob,
- b_depsgraph,
- need_undeformed,
- mesh->subdivision_type);
-
- if(b_mesh) {
- /* Sync mesh itself. */
- if(view_layer.use_surfaces && show_self) {
- 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, false);
-
- create_mesh_volume_attributes(scene, b_ob, mesh, b_scene.frame_current());
- }
-
- /* Sync hair curves. */
- if(view_layer.use_hair && show_particles && mesh->subdivision_type == Mesh::SUBDIVISION_NONE) {
- sync_curves(mesh, b_mesh, b_ob, false);
- }
-
- free_object_to_mesh(b_data, b_ob, b_mesh);
- }
- }
- mesh->geometry_flags = requested_geometry_flags;
-
- /* fluid motion */
- sync_mesh_fluid_motion(b_ob, scene, mesh);
-
- /* tag update */
- bool rebuild = (oldtriangles != mesh->triangles) ||
- (oldsubd_faces != mesh->subd_faces) ||
- (oldsubd_face_corners != mesh->subd_face_corners) ||
- (oldcurve_keys != mesh->curve_keys) ||
- (oldcurve_radius != mesh->curve_radius);
-
- mesh->tag_update(scene, rebuild);
-
- return mesh;
+ /* test if we can instance or if the object is modified */
+ BL::ID b_ob_data = b_ob.data();
+ BL::ID key = (BKE_object_is_modified(b_ob)) ? b_ob_instance : b_ob_data;
+ BL::Material material_override = view_layer.material_override;
+
+ /* find shader indices */
+ vector<Shader *> used_shaders;
+
+ BL::Object::material_slots_iterator slot;
+ for (b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) {
+ if (material_override) {
+ find_shader(material_override, used_shaders, scene->default_surface);
+ }
+ else {
+ BL::ID b_material(slot->material());
+ find_shader(b_material, used_shaders, scene->default_surface);
+ }
+ }
+
+ if (used_shaders.size() == 0) {
+ if (material_override)
+ find_shader(material_override, used_shaders, scene->default_surface);
+ else
+ used_shaders.push_back(scene->default_surface);
+ }
+
+ /* test if we need to sync */
+ int requested_geometry_flags = Mesh::GEOMETRY_NONE;
+ if (view_layer.use_surfaces) {
+ requested_geometry_flags |= Mesh::GEOMETRY_TRIANGLES;
+ }
+ if (view_layer.use_hair) {
+ requested_geometry_flags |= Mesh::GEOMETRY_CURVES;
+ }
+ 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 (requested_geometry_flags != mesh->geometry_flags)
+ ;
+ else {
+ /* even if not tagged for recalc, we may need to sync anyway
+ * because the shader needs different mesh attributes */
+ bool attribute_recalc = false;
+
+ foreach (Shader *shader, mesh->used_shaders)
+ if (shader->need_update_mesh)
+ attribute_recalc = true;
+
+ if (!attribute_recalc)
+ return mesh;
+ }
+ }
+
+ /* ensure we only sync instanced meshes once */
+ if (mesh_synced.find(mesh) != mesh_synced.end())
+ return mesh;
+
+ progress.set_sync_status("Synchronizing object", b_ob.name());
+
+ mesh_synced.insert(mesh);
+
+ /* create derived mesh */
+ array<int> oldtriangles;
+ array<Mesh::SubdFace> oldsubd_faces;
+ array<int> oldsubd_face_corners;
+ oldtriangles.steal_data(mesh->triangles);
+ oldsubd_faces.steal_data(mesh->subd_faces);
+ oldsubd_face_corners.steal_data(mesh->subd_face_corners);
+
+ /* compares curve_keys rather than strands in order to handle quick hair
+ * adjustments in dynamic BVH - other methods could probably do this better*/
+ array<float3> oldcurve_keys;
+ array<float> oldcurve_radius;
+ oldcurve_keys.steal_data(mesh->curve_keys);
+ oldcurve_radius.steal_data(mesh->curve_radius);
+
+ mesh->clear();
+ mesh->used_shaders = used_shaders;
+ mesh->name = ustring(b_ob_data.name().c_str());
+
+ if (requested_geometry_flags != Mesh::GEOMETRY_NONE) {
+ /* Adaptive subdivision setup. Not for baking since that requires
+ * exact mapping to the Blender mesh. */
+ if (scene->bake_manager->get_baking()) {
+ mesh->subdivision_type = Mesh::SUBDIVISION_NONE;
+ }
+ else {
+ mesh->subdivision_type = object_subdivision_type(b_ob, preview, experimental);
+ }
+
+ /* For some reason, meshes do not need this... */
+ bool need_undeformed = mesh->need_attribute(scene, ATTR_STD_GENERATED);
+
+ BL::Mesh b_mesh = object_to_mesh(
+ b_data, b_ob, b_depsgraph, need_undeformed, mesh->subdivision_type);
+
+ if (b_mesh) {
+ /* Sync mesh itself. */
+ if (view_layer.use_surfaces && show_self) {
+ 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, false);
+
+ create_mesh_volume_attributes(scene, b_ob, mesh, b_scene.frame_current());
+ }
+
+ /* Sync hair curves. */
+ if (view_layer.use_hair && show_particles &&
+ mesh->subdivision_type == Mesh::SUBDIVISION_NONE) {
+ sync_curves(mesh, b_mesh, b_ob, false);
+ }
+
+ free_object_to_mesh(b_data, b_ob, b_mesh);
+ }
+ }
+ mesh->geometry_flags = requested_geometry_flags;
+
+ /* fluid motion */
+ sync_mesh_fluid_motion(b_ob, scene, mesh);
+
+ /* tag update */
+ bool rebuild = (oldtriangles != mesh->triangles) || (oldsubd_faces != mesh->subd_faces) ||
+ (oldsubd_face_corners != mesh->subd_face_corners) ||
+ (oldcurve_keys != mesh->curve_keys) || (oldcurve_radius != mesh->curve_radius);
+
+ mesh->tag_update(scene, rebuild);
+
+ return mesh;
}
-void BlenderSync::sync_mesh_motion(BL::Depsgraph& b_depsgraph,
- BL::Object& b_ob,
+void BlenderSync::sync_mesh_motion(BL::Depsgraph &b_depsgraph,
+ BL::Object &b_ob,
Object *object,
float motion_time)
{
- /* ensure we only sync instanced meshes once */
- Mesh *mesh = object->mesh;
-
- if(mesh_motion_synced.find(mesh) != mesh_motion_synced.end())
- return;
-
- mesh_motion_synced.insert(mesh);
-
- /* ensure we only motion sync meshes that also had mesh synced, to avoid
- * unnecessary work and to ensure that its attributes were clear */
- if(mesh_synced.find(mesh) == mesh_synced.end())
- return;
-
- /* Find time matching motion step required by mesh. */
- int motion_step = mesh->motion_step(motion_time);
- if(motion_step < 0) {
- return;
- }
-
- /* skip empty meshes */
- const size_t numverts = mesh->verts.size();
- const size_t numkeys = mesh->curve_keys.size();
-
- if(!numverts && !numkeys)
- return;
-
- /* skip objects without deforming modifiers. this is not totally reliable,
- * would need a more extensive check to see which objects are animated */
- BL::Mesh b_mesh(PointerRNA_NULL);
-
- /* fluid motion is exported immediate with mesh, skip here */
- BL::DomainFluidSettings b_fluid_domain = object_fluid_domain_find(b_ob);
- if(b_fluid_domain)
- return;
-
- 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_depsgraph,
- false,
- Mesh::SUBDIVISION_NONE);
- }
-
- if(!b_mesh) {
- /* if we have no motion blur on this frame, but on other frames, copy */
- if(numverts) {
- /* triangles */
- Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
-
- if(attr_mP) {
- Attribute *attr_mN = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
- Attribute *attr_N = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL);
- float3 *P = &mesh->verts[0];
- float3 *N = (attr_N)? attr_N->data_float3(): NULL;
-
- memcpy(attr_mP->data_float3() + motion_step*numverts, P, sizeof(float3)*numverts);
- if(attr_mN)
- memcpy(attr_mN->data_float3() + motion_step*numverts, N, sizeof(float3)*numverts);
- }
- }
-
- if(numkeys) {
- /* curves */
- Attribute *attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
-
- if(attr_mP) {
- float3 *keys = &mesh->curve_keys[0];
- memcpy(attr_mP->data_float3() + motion_step*numkeys, keys, sizeof(float3)*numkeys);
- }
- }
-
- return;
- }
-
- /* TODO(sergey): Perform preliminary check for number of verticies. */
- if(numverts) {
- /* Find attributes. */
- Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
- Attribute *attr_mN = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
- Attribute *attr_N = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL);
- bool new_attribute = false;
- /* Add new attributes if they don't exist already. */
- if(!attr_mP) {
- attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
- if(attr_N)
- attr_mN = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_NORMAL);
-
- new_attribute = true;
- }
- /* Load vertex data from mesh. */
- float3 *mP = attr_mP->data_float3() + motion_step*numverts;
- float3 *mN = (attr_mN)? attr_mN->data_float3() + motion_step*numverts: NULL;
- /* NOTE: We don't copy more that existing amount of vertices to prevent
- * possible memory corruption.
- */
- BL::Mesh::vertices_iterator v;
- int i = 0;
- for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end() && i < numverts; ++v, ++i) {
- mP[i] = get_float3(v->co());
- if(mN)
- mN[i] = get_float3(v->normal());
- }
- if(new_attribute) {
- /* In case of new attribute, we verify if there really was any motion. */
- if(b_mesh.vertices.length() != numverts ||
- memcmp(mP, &mesh->verts[0], sizeof(float3)*numverts) == 0)
- {
- /* no motion, remove attributes again */
- if(b_mesh.vertices.length() != numverts) {
- VLOG(1) << "Topology differs, disabling motion blur for object "
- << b_ob.name();
- }
- else {
- VLOG(1) << "No actual deformation motion for object "
- << b_ob.name();
- }
- mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
- if(attr_mN)
- mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_NORMAL);
- }
- else if(motion_step > 0) {
- VLOG(1) << "Filling deformation motion for object " << b_ob.name();
- /* motion, fill up previous steps that we might have skipped because
- * they had no motion, but we need them anyway now */
- float3 *P = &mesh->verts[0];
- float3 *N = (attr_N)? attr_N->data_float3(): NULL;
- for(int step = 0; step < motion_step; step++) {
- memcpy(attr_mP->data_float3() + step*numverts, P, sizeof(float3)*numverts);
- if(attr_mN)
- memcpy(attr_mN->data_float3() + step*numverts, N, sizeof(float3)*numverts);
- }
- }
- }
- else {
- if(b_mesh.vertices.length() != numverts) {
- VLOG(1) << "Topology differs, discarding motion blur for object "
- << b_ob.name() << " at time " << motion_step;
- memcpy(mP, &mesh->verts[0], sizeof(float3)*numverts);
- if(mN != NULL) {
- memcpy(mN, attr_N->data_float3(), sizeof(float3)*numverts);
- }
- }
- }
- }
-
- /* hair motion */
- if(numkeys)
- sync_curves(mesh, b_mesh, b_ob, true, motion_step);
-
- /* free derived mesh */
- free_object_to_mesh(b_data, b_ob, b_mesh);
+ /* ensure we only sync instanced meshes once */
+ Mesh *mesh = object->mesh;
+
+ if (mesh_motion_synced.find(mesh) != mesh_motion_synced.end())
+ return;
+
+ mesh_motion_synced.insert(mesh);
+
+ /* ensure we only motion sync meshes that also had mesh synced, to avoid
+ * unnecessary work and to ensure that its attributes were clear */
+ if (mesh_synced.find(mesh) == mesh_synced.end())
+ return;
+
+ /* Find time matching motion step required by mesh. */
+ int motion_step = mesh->motion_step(motion_time);
+ if (motion_step < 0) {
+ return;
+ }
+
+ /* skip empty meshes */
+ const size_t numverts = mesh->verts.size();
+ const size_t numkeys = mesh->curve_keys.size();
+
+ if (!numverts && !numkeys)
+ return;
+
+ /* skip objects without deforming modifiers. this is not totally reliable,
+ * would need a more extensive check to see which objects are animated */
+ BL::Mesh b_mesh(PointerRNA_NULL);
+
+ /* fluid motion is exported immediate with mesh, skip here */
+ BL::DomainFluidSettings b_fluid_domain = object_fluid_domain_find(b_ob);
+ if (b_fluid_domain)
+ return;
+
+ 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_depsgraph, false, Mesh::SUBDIVISION_NONE);
+ }
+
+ if (!b_mesh) {
+ /* if we have no motion blur on this frame, but on other frames, copy */
+ if (numverts) {
+ /* triangles */
+ Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+
+ if (attr_mP) {
+ Attribute *attr_mN = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
+ Attribute *attr_N = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL);
+ float3 *P = &mesh->verts[0];
+ float3 *N = (attr_N) ? attr_N->data_float3() : NULL;
+
+ memcpy(attr_mP->data_float3() + motion_step * numverts, P, sizeof(float3) * numverts);
+ if (attr_mN)
+ memcpy(attr_mN->data_float3() + motion_step * numverts, N, sizeof(float3) * numverts);
+ }
+ }
+
+ if (numkeys) {
+ /* curves */
+ Attribute *attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+
+ if (attr_mP) {
+ float3 *keys = &mesh->curve_keys[0];
+ memcpy(attr_mP->data_float3() + motion_step * numkeys, keys, sizeof(float3) * numkeys);
+ }
+ }
+
+ return;
+ }
+
+ /* TODO(sergey): Perform preliminary check for number of verticies. */
+ if (numverts) {
+ /* Find attributes. */
+ Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ Attribute *attr_mN = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
+ Attribute *attr_N = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL);
+ bool new_attribute = false;
+ /* Add new attributes if they don't exist already. */
+ if (!attr_mP) {
+ attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
+ if (attr_N)
+ attr_mN = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_NORMAL);
+
+ new_attribute = true;
+ }
+ /* Load vertex data from mesh. */
+ float3 *mP = attr_mP->data_float3() + motion_step * numverts;
+ float3 *mN = (attr_mN) ? attr_mN->data_float3() + motion_step * numverts : NULL;
+ /* NOTE: We don't copy more that existing amount of vertices to prevent
+ * possible memory corruption.
+ */
+ BL::Mesh::vertices_iterator v;
+ int i = 0;
+ for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end() && i < numverts; ++v, ++i) {
+ mP[i] = get_float3(v->co());
+ if (mN)
+ mN[i] = get_float3(v->normal());
+ }
+ if (new_attribute) {
+ /* In case of new attribute, we verify if there really was any motion. */
+ if (b_mesh.vertices.length() != numverts ||
+ memcmp(mP, &mesh->verts[0], sizeof(float3) * numverts) == 0) {
+ /* no motion, remove attributes again */
+ if (b_mesh.vertices.length() != numverts) {
+ VLOG(1) << "Topology differs, disabling motion blur for object " << b_ob.name();
+ }
+ else {
+ VLOG(1) << "No actual deformation motion for object " << b_ob.name();
+ }
+ mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
+ if (attr_mN)
+ mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_NORMAL);
+ }
+ else if (motion_step > 0) {
+ VLOG(1) << "Filling deformation motion for object " << b_ob.name();
+ /* motion, fill up previous steps that we might have skipped because
+ * they had no motion, but we need them anyway now */
+ float3 *P = &mesh->verts[0];
+ float3 *N = (attr_N) ? attr_N->data_float3() : NULL;
+ for (int step = 0; step < motion_step; step++) {
+ memcpy(attr_mP->data_float3() + step * numverts, P, sizeof(float3) * numverts);
+ if (attr_mN)
+ memcpy(attr_mN->data_float3() + step * numverts, N, sizeof(float3) * numverts);
+ }
+ }
+ }
+ else {
+ if (b_mesh.vertices.length() != numverts) {
+ VLOG(1) << "Topology differs, discarding motion blur for object " << b_ob.name()
+ << " at time " << motion_step;
+ memcpy(mP, &mesh->verts[0], sizeof(float3) * numverts);
+ if (mN != NULL) {
+ memcpy(mN, attr_N->data_float3(), sizeof(float3) * numverts);
+ }
+ }
+ }
+ }
+
+ /* hair motion */
+ if (numkeys)
+ sync_curves(mesh, b_mesh, b_ob, true, motion_step);
+
+ /* free derived mesh */
+ free_object_to_mesh(b_data, b_ob, b_mesh);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index a296488a14a..095ecd59985 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -37,646 +37,631 @@ CCL_NAMESPACE_BEGIN
/* Utilities */
-bool BlenderSync::BKE_object_is_modified(BL::Object& b_ob)
+bool BlenderSync::BKE_object_is_modified(BL::Object &b_ob)
{
- /* test if we can instance or if the object is modified */
- if(b_ob.type() == BL::Object::type_META) {
- /* multi-user and dupli metaballs are fused, can't instance */
- return true;
- }
- else if(ccl::BKE_object_is_modified(b_ob, b_scene, preview)) {
- /* modifiers */
- return true;
- }
- else {
- /* object level material links */
- BL::Object::material_slots_iterator slot;
- for(b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot)
- if(slot->link() == BL::MaterialSlot::link_OBJECT)
- return true;
- }
-
- return false;
+ /* test if we can instance or if the object is modified */
+ if (b_ob.type() == BL::Object::type_META) {
+ /* multi-user and dupli metaballs are fused, can't instance */
+ return true;
+ }
+ else if (ccl::BKE_object_is_modified(b_ob, b_scene, preview)) {
+ /* modifiers */
+ return true;
+ }
+ else {
+ /* object level material links */
+ BL::Object::material_slots_iterator slot;
+ for (b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot)
+ if (slot->link() == BL::MaterialSlot::link_OBJECT)
+ return true;
+ }
+
+ return false;
}
-bool BlenderSync::object_is_mesh(BL::Object& b_ob)
+bool BlenderSync::object_is_mesh(BL::Object &b_ob)
{
- BL::ID b_ob_data = b_ob.data();
-
- if(!b_ob_data) {
- return false;
- }
-
- if(b_ob.type() == BL::Object::type_CURVE) {
- /* Skip exporting curves without faces, overhead can be
- * significant if there are many for path animation. */
- BL::Curve b_curve(b_ob.data());
-
- return (b_curve.bevel_object() ||
- b_curve.extrude() != 0.0f ||
- b_curve.bevel_depth() != 0.0f ||
- b_curve.dimensions() == BL::Curve::dimensions_2D ||
- b_ob.modifiers.length());
- }
- else {
- return (b_ob_data.is_a(&RNA_Mesh) ||
- b_ob_data.is_a(&RNA_Curve) ||
- b_ob_data.is_a(&RNA_MetaBall));
- }
+ BL::ID b_ob_data = b_ob.data();
+
+ if (!b_ob_data) {
+ return false;
+ }
+
+ if (b_ob.type() == BL::Object::type_CURVE) {
+ /* Skip exporting curves without faces, overhead can be
+ * significant if there are many for path animation. */
+ BL::Curve b_curve(b_ob.data());
+
+ return (b_curve.bevel_object() || b_curve.extrude() != 0.0f || b_curve.bevel_depth() != 0.0f ||
+ b_curve.dimensions() == BL::Curve::dimensions_2D || b_ob.modifiers.length());
+ }
+ else {
+ return (b_ob_data.is_a(&RNA_Mesh) || b_ob_data.is_a(&RNA_Curve) ||
+ b_ob_data.is_a(&RNA_MetaBall));
+ }
}
-bool BlenderSync::object_is_light(BL::Object& b_ob)
+bool BlenderSync::object_is_light(BL::Object &b_ob)
{
- BL::ID b_ob_data = b_ob.data();
+ BL::ID b_ob_data = b_ob.data();
- return (b_ob_data && b_ob_data.is_a(&RNA_Light));
+ return (b_ob_data && b_ob_data.is_a(&RNA_Light));
}
-static uint object_ray_visibility(BL::Object& b_ob)
+static uint object_ray_visibility(BL::Object &b_ob)
{
- PointerRNA cvisibility = RNA_pointer_get(&b_ob.ptr, "cycles_visibility");
- uint flag = 0;
+ PointerRNA cvisibility = RNA_pointer_get(&b_ob.ptr, "cycles_visibility");
+ uint flag = 0;
- flag |= get_boolean(cvisibility, "camera")? PATH_RAY_CAMERA: 0;
- flag |= get_boolean(cvisibility, "diffuse")? PATH_RAY_DIFFUSE: 0;
- 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;
+ flag |= get_boolean(cvisibility, "camera") ? PATH_RAY_CAMERA : 0;
+ flag |= get_boolean(cvisibility, "diffuse") ? PATH_RAY_DIFFUSE : 0;
+ 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;
+ return flag;
}
/* Light */
-void BlenderSync::sync_light(BL::Object& b_parent,
+void BlenderSync::sync_light(BL::Object &b_parent,
int persistent_id[OBJECT_PERSISTENT_ID_SIZE],
- BL::Object& b_ob,
- BL::Object& b_ob_instance,
+ BL::Object &b_ob,
+ BL::Object &b_ob_instance,
int random_id,
- Transform& tfm,
+ Transform &tfm,
bool *use_portal)
{
- /* test if we need to sync */
- Light *light;
- ObjectKey key(b_parent, persistent_id, b_ob_instance);
-
- if(!light_map.sync(&light, b_ob, b_parent, key)) {
- if(light->is_portal)
- *use_portal = true;
- return;
- }
-
- BL::Light b_light(b_ob.data());
-
- /* type */
- switch(b_light.type()) {
- case BL::Light::type_POINT: {
- BL::PointLight b_point_light(b_light);
- light->size = b_point_light.shadow_soft_size();
- light->type = LIGHT_POINT;
- break;
- }
- case BL::Light::type_SPOT: {
- BL::SpotLight b_spot_light(b_light);
- light->size = b_spot_light.shadow_soft_size();
- light->type = LIGHT_SPOT;
- light->spot_angle = b_spot_light.spot_size();
- light->spot_smooth = b_spot_light.spot_blend();
- break;
- }
- /* Hemi were removed from 2.8 */
- // case BL::Light::type_HEMI: {
- // light->type = LIGHT_DISTANT;
- // light->size = 0.0f;
- // break;
- // }
- case BL::Light::type_SUN: {
- BL::SunLight b_sun_light(b_light);
- light->size = b_sun_light.shadow_soft_size();
- light->type = LIGHT_DISTANT;
- break;
- }
- case BL::Light::type_AREA: {
- BL::AreaLight b_area_light(b_light);
- light->size = 1.0f;
- light->axisu = transform_get_column(&tfm, 0);
- light->axisv = transform_get_column(&tfm, 1);
- light->sizeu = b_area_light.size();
- switch(b_area_light.shape()) {
- case BL::AreaLight::shape_SQUARE:
- light->sizev = light->sizeu;
- light->round = false;
- break;
- case BL::AreaLight::shape_RECTANGLE:
- light->sizev = b_area_light.size_y();
- light->round = false;
- break;
- case BL::AreaLight::shape_DISK:
- light->sizev = light->sizeu;
- light->round = true;
- break;
- case BL::AreaLight::shape_ELLIPSE:
- light->sizev = b_area_light.size_y();
- light->round = true;
- break;
- }
- light->type = LIGHT_AREA;
- break;
- }
- }
-
- /* location and (inverted!) direction */
- light->co = transform_get_column(&tfm, 3);
- light->dir = -transform_get_column(&tfm, 2);
- light->tfm = tfm;
-
- /* shader */
- vector<Shader*> used_shaders;
- find_shader(b_light, used_shaders, scene->default_light);
- light->shader = used_shaders[0];
-
- /* shadow */
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
- PointerRNA clight = RNA_pointer_get(&b_light.ptr, "cycles");
- light->cast_shadow = get_boolean(clight, "cast_shadow");
- light->use_mis = get_boolean(clight, "use_multiple_importance_sampling");
-
- int samples = get_int(clight, "samples");
- if(get_boolean(cscene, "use_square_samples"))
- light->samples = samples * samples;
- else
- light->samples = samples;
-
- light->max_bounces = get_int(clight, "max_bounces");
-
- if(b_ob != b_ob_instance) {
- light->random_id = random_id;
- }
- else {
- light->random_id = hash_int_2d(hash_string(b_ob.name().c_str()), 0);
- }
-
- if(light->type == LIGHT_AREA)
- light->is_portal = get_boolean(clight, "is_portal");
- else
- light->is_portal = false;
-
- if(light->is_portal)
- *use_portal = true;
-
- /* visibility */
- uint visibility = object_ray_visibility(b_ob);
- 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);
+ /* test if we need to sync */
+ Light *light;
+ ObjectKey key(b_parent, persistent_id, b_ob_instance);
+
+ if (!light_map.sync(&light, b_ob, b_parent, key)) {
+ if (light->is_portal)
+ *use_portal = true;
+ return;
+ }
+
+ BL::Light b_light(b_ob.data());
+
+ /* type */
+ switch (b_light.type()) {
+ case BL::Light::type_POINT: {
+ BL::PointLight b_point_light(b_light);
+ light->size = b_point_light.shadow_soft_size();
+ light->type = LIGHT_POINT;
+ break;
+ }
+ case BL::Light::type_SPOT: {
+ BL::SpotLight b_spot_light(b_light);
+ light->size = b_spot_light.shadow_soft_size();
+ light->type = LIGHT_SPOT;
+ light->spot_angle = b_spot_light.spot_size();
+ light->spot_smooth = b_spot_light.spot_blend();
+ break;
+ }
+ /* Hemi were removed from 2.8 */
+ // case BL::Light::type_HEMI: {
+ // light->type = LIGHT_DISTANT;
+ // light->size = 0.0f;
+ // break;
+ // }
+ case BL::Light::type_SUN: {
+ BL::SunLight b_sun_light(b_light);
+ light->size = b_sun_light.shadow_soft_size();
+ light->type = LIGHT_DISTANT;
+ break;
+ }
+ case BL::Light::type_AREA: {
+ BL::AreaLight b_area_light(b_light);
+ light->size = 1.0f;
+ light->axisu = transform_get_column(&tfm, 0);
+ light->axisv = transform_get_column(&tfm, 1);
+ light->sizeu = b_area_light.size();
+ switch (b_area_light.shape()) {
+ case BL::AreaLight::shape_SQUARE:
+ light->sizev = light->sizeu;
+ light->round = false;
+ break;
+ case BL::AreaLight::shape_RECTANGLE:
+ light->sizev = b_area_light.size_y();
+ light->round = false;
+ break;
+ case BL::AreaLight::shape_DISK:
+ light->sizev = light->sizeu;
+ light->round = true;
+ break;
+ case BL::AreaLight::shape_ELLIPSE:
+ light->sizev = b_area_light.size_y();
+ light->round = true;
+ break;
+ }
+ light->type = LIGHT_AREA;
+ break;
+ }
+ }
+
+ /* location and (inverted!) direction */
+ light->co = transform_get_column(&tfm, 3);
+ light->dir = -transform_get_column(&tfm, 2);
+ light->tfm = tfm;
+
+ /* shader */
+ vector<Shader *> used_shaders;
+ find_shader(b_light, used_shaders, scene->default_light);
+ light->shader = used_shaders[0];
+
+ /* shadow */
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+ PointerRNA clight = RNA_pointer_get(&b_light.ptr, "cycles");
+ light->cast_shadow = get_boolean(clight, "cast_shadow");
+ light->use_mis = get_boolean(clight, "use_multiple_importance_sampling");
+
+ int samples = get_int(clight, "samples");
+ if (get_boolean(cscene, "use_square_samples"))
+ light->samples = samples * samples;
+ else
+ light->samples = samples;
+
+ light->max_bounces = get_int(clight, "max_bounces");
+
+ if (b_ob != b_ob_instance) {
+ light->random_id = random_id;
+ }
+ else {
+ light->random_id = hash_int_2d(hash_string(b_ob.name().c_str()), 0);
+ }
+
+ if (light->type == LIGHT_AREA)
+ light->is_portal = get_boolean(clight, "is_portal");
+ else
+ light->is_portal = false;
+
+ if (light->is_portal)
+ *use_portal = true;
+
+ /* visibility */
+ uint visibility = object_ray_visibility(b_ob);
+ 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);
}
void BlenderSync::sync_background_light(bool use_portal)
{
- BL::World b_world = b_scene.world();
-
- if(b_world) {
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
- PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles");
-
- enum SamplingMethod {
- SAMPLING_NONE = 0,
- SAMPLING_AUTOMATIC,
- SAMPLING_MANUAL,
- SAMPLING_NUM
- };
- int sampling_method = get_enum(cworld, "sampling_method", SAMPLING_NUM, SAMPLING_AUTOMATIC);
- bool sample_as_light = (sampling_method != SAMPLING_NONE);
-
- if(sample_as_light || use_portal) {
- /* test if we need to sync */
- Light *light;
- ObjectKey key(b_world, 0, b_world);
-
- if(light_map.sync(&light, b_world, b_world, key) ||
- world_recalc ||
- b_world.ptr.data != world_map)
- {
- light->type = LIGHT_BACKGROUND;
- if(sampling_method == SAMPLING_MANUAL) {
- light->map_resolution = get_int(cworld, "sample_map_resolution");
- }
- else {
- light->map_resolution = 0;
- }
- light->shader = scene->default_background;
- light->use_mis = sample_as_light;
- light->max_bounces = get_int(cworld, "max_bounces");
-
- int samples = get_int(cworld, "samples");
- if(get_boolean(cscene, "use_square_samples"))
- light->samples = samples * samples;
- else
- light->samples = samples;
-
- light->tag_update(scene);
- light_map.set_recalc(b_world);
- }
- }
- }
-
- world_map = b_world.ptr.data;
- world_recalc = false;
+ BL::World b_world = b_scene.world();
+
+ if (b_world) {
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+ PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles");
+
+ enum SamplingMethod { SAMPLING_NONE = 0, SAMPLING_AUTOMATIC, SAMPLING_MANUAL, SAMPLING_NUM };
+ int sampling_method = get_enum(cworld, "sampling_method", SAMPLING_NUM, SAMPLING_AUTOMATIC);
+ bool sample_as_light = (sampling_method != SAMPLING_NONE);
+
+ if (sample_as_light || use_portal) {
+ /* test if we need to sync */
+ Light *light;
+ ObjectKey key(b_world, 0, b_world);
+
+ if (light_map.sync(&light, b_world, b_world, key) || world_recalc ||
+ b_world.ptr.data != world_map) {
+ light->type = LIGHT_BACKGROUND;
+ if (sampling_method == SAMPLING_MANUAL) {
+ light->map_resolution = get_int(cworld, "sample_map_resolution");
+ }
+ else {
+ light->map_resolution = 0;
+ }
+ light->shader = scene->default_background;
+ light->use_mis = sample_as_light;
+ light->max_bounces = get_int(cworld, "max_bounces");
+
+ int samples = get_int(cworld, "samples");
+ if (get_boolean(cscene, "use_square_samples"))
+ light->samples = samples * samples;
+ else
+ light->samples = samples;
+
+ light->tag_update(scene);
+ light_map.set_recalc(b_world);
+ }
+ }
+ }
+
+ world_map = b_world.ptr.data;
+ world_recalc = false;
}
/* Object */
-Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph,
- BL::ViewLayer& b_view_layer,
- BL::DepsgraphObjectInstance& b_instance,
+Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
+ BL::ViewLayer &b_view_layer,
+ BL::DepsgraphObjectInstance &b_instance,
float motion_time,
bool show_self,
bool show_particles,
- BlenderObjectCulling& culling,
+ BlenderObjectCulling &culling,
bool *use_portal)
{
- const bool is_instance = b_instance.is_instance();
- BL::Object b_ob = b_instance.object();
- BL::Object b_parent = is_instance ? b_instance.parent()
- : b_instance.object();
- BL::Object b_ob_instance = is_instance ? b_instance.instance_object()
- : b_ob;
- const bool motion = motion_time != 0.0f;
- /*const*/ Transform tfm = get_transform(b_ob.matrix_world());
- int *persistent_id = NULL;
- BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id_array;
- if(is_instance) {
- persistent_id_array = b_instance.persistent_id();
- persistent_id = persistent_id_array.data;
- }
-
- /* light is handled separately */
- if(!motion && object_is_light(b_ob)) {
- /* TODO: don't use lights for excluded layers used as mask layer,
- * when dynamic overrides are back. */
+ const bool is_instance = b_instance.is_instance();
+ BL::Object b_ob = b_instance.object();
+ BL::Object b_parent = is_instance ? b_instance.parent() : b_instance.object();
+ BL::Object b_ob_instance = is_instance ? b_instance.instance_object() : b_ob;
+ const bool motion = motion_time != 0.0f;
+ /*const*/ Transform tfm = get_transform(b_ob.matrix_world());
+ int *persistent_id = NULL;
+ BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id_array;
+ if (is_instance) {
+ persistent_id_array = b_instance.persistent_id();
+ persistent_id = persistent_id_array.data;
+ }
+
+ /* light is handled separately */
+ if (!motion && object_is_light(b_ob)) {
+ /* TODO: don't use lights for excluded layers used as mask layer,
+ * when dynamic overrides are back. */
#if 0
- if(!((layer_flag & view_layer.holdout_layer) &&
- (layer_flag & view_layer.exclude_layer)))
+ if(!((layer_flag & view_layer.holdout_layer) &&
+ (layer_flag & view_layer.exclude_layer)))
#endif
- {
- sync_light(b_parent,
- persistent_id,
- b_ob,
- b_ob_instance,
- is_instance ? b_instance.random_id() : 0,
- tfm,
- use_portal);
- }
-
- return NULL;
- }
-
- /* only interested in object that we can create meshes from */
- if(!object_is_mesh(b_ob)) {
- return NULL;
- }
-
- /* Perform object culling. */
- if(culling.test(scene, b_ob, tfm)) {
- return NULL;
- }
-
- /* Visibility flags for both parent and child. */
- PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
- bool use_holdout = get_boolean(cobject, "is_holdout") ||
- b_parent.holdout_get(PointerRNA_NULL, b_view_layer);
- uint visibility = object_ray_visibility(b_ob) & PATH_RAY_ALL_VISIBILITY;
-
- if(b_parent.ptr.data != b_ob.ptr.data) {
- visibility &= object_ray_visibility(b_parent);
- }
-
- /* TODO: make holdout objects on excluded layer invisible for non-camera rays. */
+ {
+ sync_light(b_parent,
+ persistent_id,
+ b_ob,
+ b_ob_instance,
+ is_instance ? b_instance.random_id() : 0,
+ tfm,
+ use_portal);
+ }
+
+ return NULL;
+ }
+
+ /* only interested in object that we can create meshes from */
+ if (!object_is_mesh(b_ob)) {
+ return NULL;
+ }
+
+ /* Perform object culling. */
+ if (culling.test(scene, b_ob, tfm)) {
+ return NULL;
+ }
+
+ /* Visibility flags for both parent and child. */
+ PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
+ bool use_holdout = get_boolean(cobject, "is_holdout") ||
+ b_parent.holdout_get(PointerRNA_NULL, b_view_layer);
+ uint visibility = object_ray_visibility(b_ob) & PATH_RAY_ALL_VISIBILITY;
+
+ if (b_parent.ptr.data != b_ob.ptr.data) {
+ visibility &= object_ray_visibility(b_parent);
+ }
+
+ /* TODO: make holdout objects on excluded layer invisible for non-camera rays. */
#if 0
- if(use_holdout && (layer_flag & view_layer.exclude_layer)) {
- visibility &= ~(PATH_RAY_ALL_VISIBILITY - PATH_RAY_CAMERA);
- }
+ if(use_holdout && (layer_flag & view_layer.exclude_layer)) {
+ visibility &= ~(PATH_RAY_ALL_VISIBILITY - PATH_RAY_CAMERA);
+ }
#endif
- /* Clear camera visibility for indirect only objects. */
- bool use_indirect_only = b_parent.indirect_only_get(PointerRNA_NULL, b_view_layer);
- if(use_indirect_only) {
- visibility &= ~PATH_RAY_CAMERA;
- }
-
- /* Don't export completely invisible objects. */
- if(visibility == 0) {
- return NULL;
- }
-
- /* key to lookup object */
- ObjectKey key(b_parent, persistent_id, b_ob_instance);
- Object *object;
-
- /* motion vector case */
- if(motion) {
- object = object_map.find(key);
-
- if(object && object->use_motion()) {
- /* Set transform at matching motion time step. */
- int time_index = object->motion_step(motion_time);
- if(time_index >= 0) {
- object->motion[time_index] = tfm;
- }
-
- /* mesh deformation */
- if(object->mesh)
- sync_mesh_motion(b_depsgraph, b_ob, object, motion_time);
- }
-
- return object;
- }
-
- /* test if we need to sync */
- bool object_updated = false;
-
- if(object_map.sync(&object, b_ob, b_parent, key))
- object_updated = true;
-
- /* mesh sync */
- object->mesh = sync_mesh(b_depsgraph, b_ob, b_ob_instance, object_updated, show_self, show_particles);
-
- /* special case not tracked by object update flags */
-
- /* holdout */
- if(use_holdout != object->use_holdout) {
- object->use_holdout = use_holdout;
- scene->object_manager->tag_update(scene);
- object_updated = true;
- }
-
- if(visibility != object->visibility) {
- object->visibility = visibility;
- object_updated = true;
- }
-
- bool is_shadow_catcher = get_boolean(cobject, "is_shadow_catcher");
- if(is_shadow_catcher != object->is_shadow_catcher) {
- object->is_shadow_catcher = is_shadow_catcher;
- object_updated = true;
- }
-
- /* sync the asset name for Cryptomatte */
- BL::Object parent = b_ob.parent();
- ustring parent_name;
- if(parent) {
- while(parent.parent()) {
- parent = parent.parent();
- }
- parent_name = parent.name();
- }
- else {
- parent_name = b_ob.name();
- }
- if(object->asset_name != parent_name) {
- object->asset_name = parent_name;
- object_updated = true;
- }
-
- /* object sync
- * transform comparison should not be needed, but duplis don't work perfect
- * in the depsgraph and may not signal changes, so this is a workaround */
- if(object_updated || (object->mesh && object->mesh->need_update) || tfm != object->tfm) {
- object->name = b_ob.name().c_str();
- object->pass_id = b_ob.pass_index();
- object->tfm = tfm;
- object->motion.clear();
-
- /* motion blur */
- Scene::MotionType need_motion = scene->need_motion();
- if(need_motion != Scene::MOTION_NONE && object->mesh) {
- Mesh *mesh = object->mesh;
- mesh->use_motion_blur = false;
- mesh->motion_steps = 0;
-
- uint motion_steps;
-
- if(need_motion == Scene::MOTION_BLUR) {
- motion_steps = object_motion_steps(b_parent, b_ob);
- mesh->motion_steps = motion_steps;
- if(motion_steps && object_use_deform_motion(b_parent, b_ob)) {
- mesh->use_motion_blur = true;
- }
- }
- else {
- motion_steps = 3;
- mesh->motion_steps = motion_steps;
- }
-
- object->motion.clear();
- object->motion.resize(motion_steps, transform_empty());
-
- if(motion_steps) {
- object->motion[motion_steps/2] = tfm;
-
- for(size_t step = 0; step < motion_steps; step++) {
- motion_times.insert(object->motion_time(step));
- }
- }
- }
-
- /* dupli texture coordinates and random_id */
- if(is_instance) {
- object->dupli_generated = 0.5f*get_float3(b_instance.orco()) - make_float3(0.5f, 0.5f, 0.5f);
- object->dupli_uv = get_float2(b_instance.uv());
- object->random_id = b_instance.random_id();
- }
- else {
- object->dupli_generated = make_float3(0.0f, 0.0f, 0.0f);
- object->dupli_uv = make_float2(0.0f, 0.0f);
- object->random_id = hash_int_2d(hash_string(object->name.c_str()), 0);
- }
-
- object->tag_update(scene);
- }
-
- if(is_instance) {
- /* Sync possible particle data. */
- sync_dupli_particle(b_parent, b_instance, object);
- }
-
- return object;
+ /* Clear camera visibility for indirect only objects. */
+ bool use_indirect_only = b_parent.indirect_only_get(PointerRNA_NULL, b_view_layer);
+ if (use_indirect_only) {
+ visibility &= ~PATH_RAY_CAMERA;
+ }
+
+ /* Don't export completely invisible objects. */
+ if (visibility == 0) {
+ return NULL;
+ }
+
+ /* key to lookup object */
+ ObjectKey key(b_parent, persistent_id, b_ob_instance);
+ Object *object;
+
+ /* motion vector case */
+ if (motion) {
+ object = object_map.find(key);
+
+ if (object && object->use_motion()) {
+ /* Set transform at matching motion time step. */
+ int time_index = object->motion_step(motion_time);
+ if (time_index >= 0) {
+ object->motion[time_index] = tfm;
+ }
+
+ /* mesh deformation */
+ if (object->mesh)
+ sync_mesh_motion(b_depsgraph, b_ob, object, motion_time);
+ }
+
+ return object;
+ }
+
+ /* test if we need to sync */
+ bool object_updated = false;
+
+ if (object_map.sync(&object, b_ob, b_parent, key))
+ object_updated = true;
+
+ /* mesh sync */
+ object->mesh = sync_mesh(
+ b_depsgraph, b_ob, b_ob_instance, object_updated, show_self, show_particles);
+
+ /* special case not tracked by object update flags */
+
+ /* holdout */
+ if (use_holdout != object->use_holdout) {
+ object->use_holdout = use_holdout;
+ scene->object_manager->tag_update(scene);
+ object_updated = true;
+ }
+
+ if (visibility != object->visibility) {
+ object->visibility = visibility;
+ object_updated = true;
+ }
+
+ bool is_shadow_catcher = get_boolean(cobject, "is_shadow_catcher");
+ if (is_shadow_catcher != object->is_shadow_catcher) {
+ object->is_shadow_catcher = is_shadow_catcher;
+ object_updated = true;
+ }
+
+ /* sync the asset name for Cryptomatte */
+ BL::Object parent = b_ob.parent();
+ ustring parent_name;
+ if (parent) {
+ while (parent.parent()) {
+ parent = parent.parent();
+ }
+ parent_name = parent.name();
+ }
+ else {
+ parent_name = b_ob.name();
+ }
+ if (object->asset_name != parent_name) {
+ object->asset_name = parent_name;
+ object_updated = true;
+ }
+
+ /* object sync
+ * transform comparison should not be needed, but duplis don't work perfect
+ * in the depsgraph and may not signal changes, so this is a workaround */
+ if (object_updated || (object->mesh && object->mesh->need_update) || tfm != object->tfm) {
+ object->name = b_ob.name().c_str();
+ object->pass_id = b_ob.pass_index();
+ object->tfm = tfm;
+ object->motion.clear();
+
+ /* motion blur */
+ Scene::MotionType need_motion = scene->need_motion();
+ if (need_motion != Scene::MOTION_NONE && object->mesh) {
+ Mesh *mesh = object->mesh;
+ mesh->use_motion_blur = false;
+ mesh->motion_steps = 0;
+
+ uint motion_steps;
+
+ if (need_motion == Scene::MOTION_BLUR) {
+ motion_steps = object_motion_steps(b_parent, b_ob);
+ mesh->motion_steps = motion_steps;
+ if (motion_steps && object_use_deform_motion(b_parent, b_ob)) {
+ mesh->use_motion_blur = true;
+ }
+ }
+ else {
+ motion_steps = 3;
+ mesh->motion_steps = motion_steps;
+ }
+
+ object->motion.clear();
+ object->motion.resize(motion_steps, transform_empty());
+
+ if (motion_steps) {
+ object->motion[motion_steps / 2] = tfm;
+
+ for (size_t step = 0; step < motion_steps; step++) {
+ motion_times.insert(object->motion_time(step));
+ }
+ }
+ }
+
+ /* dupli texture coordinates and random_id */
+ if (is_instance) {
+ object->dupli_generated = 0.5f * get_float3(b_instance.orco()) -
+ make_float3(0.5f, 0.5f, 0.5f);
+ object->dupli_uv = get_float2(b_instance.uv());
+ object->random_id = b_instance.random_id();
+ }
+ else {
+ object->dupli_generated = make_float3(0.0f, 0.0f, 0.0f);
+ object->dupli_uv = make_float2(0.0f, 0.0f);
+ object->random_id = hash_int_2d(hash_string(object->name.c_str()), 0);
+ }
+
+ object->tag_update(scene);
+ }
+
+ if (is_instance) {
+ /* Sync possible particle data. */
+ sync_dupli_particle(b_parent, b_instance, object);
+ }
+
+ return object;
}
/* Object Loop */
-void BlenderSync::sync_objects(BL::Depsgraph& b_depsgraph, float motion_time)
+void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph, float motion_time)
{
- /* layer data */
- bool motion = motion_time != 0.0f;
-
- if(!motion) {
- /* prepare for sync */
- light_map.pre_sync();
- mesh_map.pre_sync();
- object_map.pre_sync();
- particle_system_map.pre_sync();
- motion_times.clear();
- }
- else {
- mesh_motion_synced.clear();
- }
-
- /* initialize culling */
- BlenderObjectCulling culling(scene, b_scene);
-
- /* object loop */
- bool cancel = false;
- bool use_portal = false;
-
- BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
-
- BL::Depsgraph::object_instances_iterator b_instance_iter;
- for(b_depsgraph.object_instances.begin(b_instance_iter);
- b_instance_iter != b_depsgraph.object_instances.end() && !cancel;
- ++b_instance_iter)
- {
- BL::DepsgraphObjectInstance b_instance = *b_instance_iter;
- BL::Object b_ob = b_instance.object();
-
- /* load per-object culling data */
- culling.init_object(scene, b_ob);
-
- /* test if object needs to be hidden */
- const bool show_self = b_instance.show_self();
- const bool show_particles = b_instance.show_particles();
-
- if(show_self || show_particles) {
- /* object itself */
- sync_object(b_depsgraph,
- b_view_layer,
- b_instance,
- motion_time,
- show_self,
- show_particles,
- culling,
- &use_portal);
- }
-
- cancel = progress.get_cancel();
- }
-
- progress.set_sync_status("");
-
- if(!cancel && !motion) {
- sync_background_light(use_portal);
-
- /* handle removed data and modified pointers */
- if(light_map.post_sync())
- scene->light_manager->tag_update(scene);
- if(mesh_map.post_sync())
- scene->mesh_manager->tag_update(scene);
- if(object_map.post_sync())
- scene->object_manager->tag_update(scene);
- if(particle_system_map.post_sync())
- scene->particle_system_manager->tag_update(scene);
- }
-
- if(motion)
- mesh_motion_synced.clear();
+ /* layer data */
+ bool motion = motion_time != 0.0f;
+
+ if (!motion) {
+ /* prepare for sync */
+ light_map.pre_sync();
+ mesh_map.pre_sync();
+ object_map.pre_sync();
+ particle_system_map.pre_sync();
+ motion_times.clear();
+ }
+ else {
+ mesh_motion_synced.clear();
+ }
+
+ /* initialize culling */
+ BlenderObjectCulling culling(scene, b_scene);
+
+ /* object loop */
+ bool cancel = false;
+ bool use_portal = false;
+
+ BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
+
+ BL::Depsgraph::object_instances_iterator b_instance_iter;
+ for (b_depsgraph.object_instances.begin(b_instance_iter);
+ b_instance_iter != b_depsgraph.object_instances.end() && !cancel;
+ ++b_instance_iter) {
+ BL::DepsgraphObjectInstance b_instance = *b_instance_iter;
+ BL::Object b_ob = b_instance.object();
+
+ /* load per-object culling data */
+ culling.init_object(scene, b_ob);
+
+ /* test if object needs to be hidden */
+ const bool show_self = b_instance.show_self();
+ const bool show_particles = b_instance.show_particles();
+
+ if (show_self || show_particles) {
+ /* object itself */
+ sync_object(b_depsgraph,
+ b_view_layer,
+ b_instance,
+ motion_time,
+ show_self,
+ show_particles,
+ culling,
+ &use_portal);
+ }
+
+ cancel = progress.get_cancel();
+ }
+
+ progress.set_sync_status("");
+
+ if (!cancel && !motion) {
+ sync_background_light(use_portal);
+
+ /* handle removed data and modified pointers */
+ if (light_map.post_sync())
+ scene->light_manager->tag_update(scene);
+ if (mesh_map.post_sync())
+ scene->mesh_manager->tag_update(scene);
+ if (object_map.post_sync())
+ scene->object_manager->tag_update(scene);
+ if (particle_system_map.post_sync())
+ scene->particle_system_manager->tag_update(scene);
+ }
+
+ if (motion)
+ mesh_motion_synced.clear();
}
-void BlenderSync::sync_motion(BL::RenderSettings& b_render,
- BL::Depsgraph& b_depsgraph,
- BL::Object& b_override,
- int width, int height,
+void BlenderSync::sync_motion(BL::RenderSettings &b_render,
+ BL::Depsgraph &b_depsgraph,
+ BL::Object &b_override,
+ int width,
+ int height,
void **python_thread_state)
{
- if(scene->need_motion() == Scene::MOTION_NONE)
- return;
-
- /* get camera object here to deal with camera switch */
- BL::Object b_cam = b_scene.camera();
- if(b_override)
- b_cam = b_override;
-
- Camera prevcam = *(scene->camera);
-
- int frame_center = b_scene.frame_current();
- float subframe_center = b_scene.frame_subframe();
- float frame_center_delta = 0.0f;
-
- if(scene->need_motion() != Scene::MOTION_PASS &&
- scene->camera->motion_position != Camera::MOTION_POSITION_CENTER)
- {
- float shuttertime = scene->camera->shuttertime;
- if(scene->camera->motion_position == Camera::MOTION_POSITION_END) {
- frame_center_delta = -shuttertime * 0.5f;
- }
- else {
- assert(scene->camera->motion_position == Camera::MOTION_POSITION_START);
- frame_center_delta = shuttertime * 0.5f;
- }
-
- float time = frame_center + subframe_center + frame_center_delta;
- int frame = (int)floorf(time);
- float subframe = time - frame;
- python_thread_state_restore(python_thread_state);
- b_engine.frame_set(frame, subframe);
- python_thread_state_save(python_thread_state);
- sync_camera_motion(b_render, b_cam, width, height, 0.0f);
- sync_objects(b_depsgraph, 0.0f);
- }
-
- /* always sample these times for camera motion */
- motion_times.insert(-1.0f);
- motion_times.insert(1.0f);
-
- /* note iteration over motion_times set happens in sorted order */
- foreach(float relative_time, motion_times) {
- /* center time is already handled. */
- if(relative_time == 0.0f) {
- continue;
- }
-
- VLOG(1) << "Synchronizing motion for the relative time "
- << relative_time << ".";
-
- /* fixed shutter time to get previous and next frame for motion pass */
- float shuttertime = scene->motion_shutter_time();
-
- /* compute frame and subframe time */
- float time = frame_center + subframe_center + frame_center_delta + relative_time * shuttertime * 0.5f;
- int frame = (int)floorf(time);
- float subframe = time - frame;
-
- /* change frame */
- python_thread_state_restore(python_thread_state);
- b_engine.frame_set(frame, subframe);
- python_thread_state_save(python_thread_state);
-
- /* sync camera, only supports two times at the moment */
- if(relative_time == -1.0f || relative_time == 1.0f) {
- sync_camera_motion(b_render,
- b_cam,
- width, height,
- relative_time);
- }
-
- /* sync object */
- sync_objects(b_depsgraph, relative_time);
- }
-
- /* we need to set the python thread state again because this
- * function assumes it is being executed from python and will
- * try to save the thread state */
- python_thread_state_restore(python_thread_state);
- b_engine.frame_set(frame_center, subframe_center);
- python_thread_state_save(python_thread_state);
-
- /* tag camera for motion update */
- if(scene->camera->motion_modified(prevcam))
- scene->camera->tag_update();
+ if (scene->need_motion() == Scene::MOTION_NONE)
+ return;
+
+ /* get camera object here to deal with camera switch */
+ BL::Object b_cam = b_scene.camera();
+ if (b_override)
+ b_cam = b_override;
+
+ Camera prevcam = *(scene->camera);
+
+ int frame_center = b_scene.frame_current();
+ float subframe_center = b_scene.frame_subframe();
+ float frame_center_delta = 0.0f;
+
+ if (scene->need_motion() != Scene::MOTION_PASS &&
+ scene->camera->motion_position != Camera::MOTION_POSITION_CENTER) {
+ float shuttertime = scene->camera->shuttertime;
+ if (scene->camera->motion_position == Camera::MOTION_POSITION_END) {
+ frame_center_delta = -shuttertime * 0.5f;
+ }
+ else {
+ assert(scene->camera->motion_position == Camera::MOTION_POSITION_START);
+ frame_center_delta = shuttertime * 0.5f;
+ }
+
+ float time = frame_center + subframe_center + frame_center_delta;
+ int frame = (int)floorf(time);
+ float subframe = time - frame;
+ python_thread_state_restore(python_thread_state);
+ b_engine.frame_set(frame, subframe);
+ python_thread_state_save(python_thread_state);
+ sync_camera_motion(b_render, b_cam, width, height, 0.0f);
+ sync_objects(b_depsgraph, 0.0f);
+ }
+
+ /* always sample these times for camera motion */
+ motion_times.insert(-1.0f);
+ motion_times.insert(1.0f);
+
+ /* note iteration over motion_times set happens in sorted order */
+ foreach (float relative_time, motion_times) {
+ /* center time is already handled. */
+ if (relative_time == 0.0f) {
+ continue;
+ }
+
+ VLOG(1) << "Synchronizing motion for the relative time " << relative_time << ".";
+
+ /* fixed shutter time to get previous and next frame for motion pass */
+ float shuttertime = scene->motion_shutter_time();
+
+ /* compute frame and subframe time */
+ float time = frame_center + subframe_center + frame_center_delta +
+ relative_time * shuttertime * 0.5f;
+ int frame = (int)floorf(time);
+ float subframe = time - frame;
+
+ /* change frame */
+ python_thread_state_restore(python_thread_state);
+ b_engine.frame_set(frame, subframe);
+ python_thread_state_save(python_thread_state);
+
+ /* sync camera, only supports two times at the moment */
+ if (relative_time == -1.0f || relative_time == 1.0f) {
+ sync_camera_motion(b_render, b_cam, width, height, relative_time);
+ }
+
+ /* sync object */
+ sync_objects(b_depsgraph, relative_time);
+ }
+
+ /* we need to set the python thread state again because this
+ * function assumes it is being executed from python and will
+ * try to save the thread state */
+ python_thread_state_restore(python_thread_state);
+ b_engine.frame_set(frame_center, subframe_center);
+ python_thread_state_save(python_thread_state);
+
+ /* tag camera for motion update */
+ if (scene->camera->motion_modified(prevcam))
+ scene->camera->tag_update();
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_object_cull.cpp b/intern/cycles/blender/blender_object_cull.cpp
index 680d9d7b1ff..74f8fb1dc53 100644
--- a/intern/cycles/blender/blender_object_cull.cpp
+++ b/intern/cycles/blender/blender_object_cull.cpp
@@ -22,72 +22,69 @@
CCL_NAMESPACE_BEGIN
-BlenderObjectCulling::BlenderObjectCulling(Scene *scene, BL::Scene& b_scene)
- : use_scene_camera_cull_(false),
- use_camera_cull_(false),
- camera_cull_margin_(0.0f),
- use_scene_distance_cull_(false),
- use_distance_cull_(false),
- distance_cull_margin_(0.0f)
+BlenderObjectCulling::BlenderObjectCulling(Scene *scene, BL::Scene &b_scene)
+ : use_scene_camera_cull_(false),
+ use_camera_cull_(false),
+ camera_cull_margin_(0.0f),
+ use_scene_distance_cull_(false),
+ use_distance_cull_(false),
+ distance_cull_margin_(0.0f)
{
- if(b_scene.render().use_simplify()) {
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
-
- use_scene_camera_cull_ = scene->camera->type != CAMERA_PANORAMA &&
- !b_scene.render().use_multiview() &&
- get_boolean(cscene, "use_camera_cull");
- use_scene_distance_cull_ = scene->camera->type != CAMERA_PANORAMA &&
- !b_scene.render().use_multiview() &&
- get_boolean(cscene, "use_distance_cull");
-
- camera_cull_margin_ = get_float(cscene, "camera_cull_margin");
- distance_cull_margin_ = get_float(cscene, "distance_cull_margin");
-
- if(distance_cull_margin_ == 0.0f) {
- use_scene_distance_cull_ = false;
- }
- }
+ if (b_scene.render().use_simplify()) {
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+
+ use_scene_camera_cull_ = scene->camera->type != CAMERA_PANORAMA &&
+ !b_scene.render().use_multiview() &&
+ get_boolean(cscene, "use_camera_cull");
+ use_scene_distance_cull_ = scene->camera->type != CAMERA_PANORAMA &&
+ !b_scene.render().use_multiview() &&
+ get_boolean(cscene, "use_distance_cull");
+
+ camera_cull_margin_ = get_float(cscene, "camera_cull_margin");
+ distance_cull_margin_ = get_float(cscene, "distance_cull_margin");
+
+ if (distance_cull_margin_ == 0.0f) {
+ use_scene_distance_cull_ = false;
+ }
+ }
}
-void BlenderObjectCulling::init_object(Scene *scene, BL::Object& b_ob)
+void BlenderObjectCulling::init_object(Scene *scene, BL::Object &b_ob)
{
- if(!use_scene_camera_cull_ && !use_scene_distance_cull_) {
- return;
- }
+ if (!use_scene_camera_cull_ && !use_scene_distance_cull_) {
+ return;
+ }
- PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
+ PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
- use_camera_cull_ = use_scene_camera_cull_ && get_boolean(cobject, "use_camera_cull");
- use_distance_cull_ = use_scene_distance_cull_ && get_boolean(cobject, "use_distance_cull");
+ use_camera_cull_ = use_scene_camera_cull_ && get_boolean(cobject, "use_camera_cull");
+ use_distance_cull_ = use_scene_distance_cull_ && get_boolean(cobject, "use_distance_cull");
- if(use_camera_cull_ || use_distance_cull_) {
- /* Need to have proper projection matrix. */
- scene->camera->update(scene);
- }
+ if (use_camera_cull_ || use_distance_cull_) {
+ /* Need to have proper projection matrix. */
+ scene->camera->update(scene);
+ }
}
-bool BlenderObjectCulling::test(Scene *scene, BL::Object& b_ob, Transform& tfm)
+bool BlenderObjectCulling::test(Scene *scene, BL::Object &b_ob, Transform &tfm)
{
- if(!use_camera_cull_ && !use_distance_cull_) {
- return false;
- }
-
- /* Compute world space bounding box corners. */
- float3 bb[8];
- BL::Array<float, 24> boundbox = b_ob.bound_box();
- for(int i = 0; i < 8; ++i) {
- float3 p = make_float3(boundbox[3 * i + 0],
- boundbox[3 * i + 1],
- boundbox[3 * i + 2]);
- bb[i] = transform_point(&tfm, p);
- }
-
- bool camera_culled = use_camera_cull_ && test_camera(scene, bb);
- bool distance_culled = use_distance_cull_ && test_distance(scene, bb);
-
- return ((camera_culled && distance_culled) ||
- (camera_culled && !use_distance_cull_) ||
- (distance_culled && !use_camera_cull_));
+ if (!use_camera_cull_ && !use_distance_cull_) {
+ return false;
+ }
+
+ /* Compute world space bounding box corners. */
+ float3 bb[8];
+ BL::Array<float, 24> boundbox = b_ob.bound_box();
+ for (int i = 0; i < 8; ++i) {
+ float3 p = make_float3(boundbox[3 * i + 0], boundbox[3 * i + 1], boundbox[3 * i + 2]);
+ bb[i] = transform_point(&tfm, p);
+ }
+
+ bool camera_culled = use_camera_cull_ && test_camera(scene, bb);
+ bool distance_culled = use_distance_cull_ && test_distance(scene, bb);
+
+ return ((camera_culled && distance_culled) || (camera_culled && !use_distance_cull_) ||
+ (distance_culled && !use_camera_cull_));
}
/* TODO(sergey): Not really optimal, consider approaches based on k-DOP in order
@@ -95,54 +92,50 @@ bool BlenderObjectCulling::test(Scene *scene, BL::Object& b_ob, Transform& tfm)
*/
bool BlenderObjectCulling::test_camera(Scene *scene, float3 bb[8])
{
- Camera *cam = scene->camera;
- const ProjectionTransform& worldtondc = cam->worldtondc;
- float3 bb_min = make_float3(FLT_MAX, FLT_MAX, FLT_MAX),
- bb_max = make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX);
- bool all_behind = true;
- for(int i = 0; i < 8; ++i) {
- float3 p = bb[i];
- 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 >= -camera_cull_margin_) {
- all_behind = false;
- }
- bb_min = min(bb_min, p);
- bb_max = max(bb_max, p);
- }
- if(all_behind) {
- return true;
- }
- return (bb_min.x >= 1.0f + camera_cull_margin_ ||
- bb_min.y >= 1.0f + camera_cull_margin_ ||
- bb_max.x <= -camera_cull_margin_ ||
- bb_max.y <= -camera_cull_margin_);
+ Camera *cam = scene->camera;
+ const ProjectionTransform &worldtondc = cam->worldtondc;
+ float3 bb_min = make_float3(FLT_MAX, FLT_MAX, FLT_MAX),
+ bb_max = make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX);
+ bool all_behind = true;
+ for (int i = 0; i < 8; ++i) {
+ float3 p = bb[i];
+ 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 >= -camera_cull_margin_) {
+ all_behind = false;
+ }
+ bb_min = min(bb_min, p);
+ bb_max = max(bb_max, p);
+ }
+ if (all_behind) {
+ return true;
+ }
+ return (bb_min.x >= 1.0f + camera_cull_margin_ || bb_min.y >= 1.0f + camera_cull_margin_ ||
+ bb_max.x <= -camera_cull_margin_ || bb_max.y <= -camera_cull_margin_);
}
bool BlenderObjectCulling::test_distance(Scene *scene, float3 bb[8])
{
- float3 camera_position = transform_get_column(&scene->camera->matrix, 3);
- float3 bb_min = make_float3(FLT_MAX, FLT_MAX, FLT_MAX),
- bb_max = make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX);
-
- /* Find min & max points for x & y & z on bounding box */
- for(int i = 0; i < 8; ++i) {
- float3 p = bb[i];
- bb_min = min(bb_min, p);
- bb_max = max(bb_max, p);
- }
-
- float3 closest_point = max(min(bb_max,camera_position),bb_min);
- return (len_squared(camera_position - closest_point) >
- distance_cull_margin_ * distance_cull_margin_);
+ float3 camera_position = transform_get_column(&scene->camera->matrix, 3);
+ float3 bb_min = make_float3(FLT_MAX, FLT_MAX, FLT_MAX),
+ bb_max = make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX);
+
+ /* Find min & max points for x & y & z on bounding box */
+ for (int i = 0; i < 8; ++i) {
+ float3 p = bb[i];
+ bb_min = min(bb_min, p);
+ bb_max = max(bb_max, p);
+ }
+
+ float3 closest_point = max(min(bb_max, camera_position), bb_min);
+ return (len_squared(camera_position - closest_point) >
+ distance_cull_margin_ * distance_cull_margin_);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_object_cull.h b/intern/cycles/blender/blender_object_cull.h
index 6e2a22438ec..0879db4f802 100644
--- a/intern/cycles/blender/blender_object_cull.h
+++ b/intern/cycles/blender/blender_object_cull.h
@@ -24,26 +24,25 @@ CCL_NAMESPACE_BEGIN
class Scene;
-class BlenderObjectCulling
-{
-public:
- BlenderObjectCulling(Scene *scene, BL::Scene& b_scene);
-
- void init_object(Scene *scene, BL::Object& b_ob);
- bool test(Scene *scene, BL::Object& b_ob, Transform& tfm);
-
-private:
- bool test_camera(Scene *scene, float3 bb[8]);
- bool test_distance(Scene *scene, float3 bb[8]);
-
- bool use_scene_camera_cull_;
- bool use_camera_cull_;
- float camera_cull_margin_;
- bool use_scene_distance_cull_;
- bool use_distance_cull_;
- float distance_cull_margin_;
+class BlenderObjectCulling {
+ public:
+ BlenderObjectCulling(Scene *scene, BL::Scene &b_scene);
+
+ void init_object(Scene *scene, BL::Object &b_ob);
+ bool test(Scene *scene, BL::Object &b_ob, Transform &tfm);
+
+ private:
+ bool test_camera(Scene *scene, float3 bb[8]);
+ bool test_distance(Scene *scene, float3 bb[8]);
+
+ bool use_scene_camera_cull_;
+ bool use_camera_cull_;
+ float camera_cull_margin_;
+ bool use_scene_distance_cull_;
+ bool use_distance_cull_;
+ float distance_cull_margin_;
};
CCL_NAMESPACE_END
-#endif /* __BLENDER_OBJECT_CULL_H__ */
+#endif /* __BLENDER_OBJECT_CULL_H__ */
diff --git a/intern/cycles/blender/blender_particles.cpp b/intern/cycles/blender/blender_particles.cpp
index a733a499826..d74f132ed60 100644
--- a/intern/cycles/blender/blender_particles.cpp
+++ b/intern/cycles/blender/blender_particles.cpp
@@ -27,66 +27,66 @@ CCL_NAMESPACE_BEGIN
/* Utilities */
-bool BlenderSync::sync_dupli_particle(BL::Object& b_ob,
- BL::DepsgraphObjectInstance& b_instance,
+bool BlenderSync::sync_dupli_particle(BL::Object &b_ob,
+ BL::DepsgraphObjectInstance &b_instance,
Object *object)
{
- /* test if this dupli was generated from a particle sytem */
- BL::ParticleSystem b_psys = b_instance.particle_system();
- if(!b_psys)
- return false;
-
- object->hide_on_missing_motion = true;
-
- /* test if we need particle data */
- if(!object->mesh->need_attribute(scene, ATTR_STD_PARTICLE))
- return false;
-
- /* don't handle child particles yet */
- BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id = b_instance.persistent_id();
-
- if(persistent_id[0] >= b_psys.particles.length())
- return false;
-
- /* find particle system */
- ParticleSystemKey key(b_ob, persistent_id);
- ParticleSystem *psys;
-
- bool first_use = !particle_system_map.is_used(key);
- bool need_update = particle_system_map.sync(&psys, b_ob, b_instance.object(), key);
-
- /* no update needed? */
- if(!need_update && !object->mesh->need_update && !scene->object_manager->need_update)
- return true;
-
- /* first time used in this sync loop? clear and tag update */
- if(first_use) {
- psys->particles.clear();
- psys->tag_update(scene);
- }
-
- /* add particle */
- BL::Particle b_pa = b_psys.particles[persistent_id[0]];
- Particle pa;
-
- pa.index = persistent_id[0];
- pa.age = b_scene.frame_current() - b_pa.birth_time();
- pa.lifetime = b_pa.lifetime();
- pa.location = get_float3(b_pa.location());
- pa.rotation = get_float4(b_pa.rotation());
- pa.size = b_pa.size();
- pa.velocity = get_float3(b_pa.velocity());
- pa.angular_velocity = get_float3(b_pa.angular_velocity());
-
- psys->particles.push_back_slow(pa);
-
- if(object->particle_index != psys->particles.size() - 1)
- scene->object_manager->tag_update(scene);
- object->particle_system = psys;
- object->particle_index = psys->particles.size() - 1;
-
- /* return that this object has particle data */
- return true;
+ /* test if this dupli was generated from a particle sytem */
+ BL::ParticleSystem b_psys = b_instance.particle_system();
+ if (!b_psys)
+ return false;
+
+ object->hide_on_missing_motion = true;
+
+ /* test if we need particle data */
+ if (!object->mesh->need_attribute(scene, ATTR_STD_PARTICLE))
+ return false;
+
+ /* don't handle child particles yet */
+ BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id = b_instance.persistent_id();
+
+ if (persistent_id[0] >= b_psys.particles.length())
+ return false;
+
+ /* find particle system */
+ ParticleSystemKey key(b_ob, persistent_id);
+ ParticleSystem *psys;
+
+ bool first_use = !particle_system_map.is_used(key);
+ bool need_update = particle_system_map.sync(&psys, b_ob, b_instance.object(), key);
+
+ /* no update needed? */
+ if (!need_update && !object->mesh->need_update && !scene->object_manager->need_update)
+ return true;
+
+ /* first time used in this sync loop? clear and tag update */
+ if (first_use) {
+ psys->particles.clear();
+ psys->tag_update(scene);
+ }
+
+ /* add particle */
+ BL::Particle b_pa = b_psys.particles[persistent_id[0]];
+ Particle pa;
+
+ pa.index = persistent_id[0];
+ pa.age = b_scene.frame_current() - b_pa.birth_time();
+ pa.lifetime = b_pa.lifetime();
+ pa.location = get_float3(b_pa.location());
+ pa.rotation = get_float4(b_pa.rotation());
+ pa.size = b_pa.size();
+ pa.velocity = get_float3(b_pa.velocity());
+ pa.angular_velocity = get_float3(b_pa.angular_velocity());
+
+ psys->particles.push_back_slow(pa);
+
+ if (object->particle_index != psys->particles.size() - 1)
+ scene->object_manager->tag_update(scene);
+ object->particle_system = psys;
+ object->particle_index = psys->particles.size() - 1;
+
+ /* return that this object has particle data */
+ return true;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp
index ccd783073a3..ffd1c70a4e4 100644
--- a/intern/cycles/blender/blender_python.cpp
+++ b/intern/cycles/blender/blender_python.cpp
@@ -35,14 +35,14 @@
#include "util/util_types.h"
#ifdef WITH_OSL
-#include "render/osl.h"
+# include "render/osl.h"
-#include <OSL/oslquery.h>
-#include <OSL/oslconfig.h>
+# include <OSL/oslquery.h>
+# include <OSL/oslconfig.h>
#endif
#ifdef WITH_OPENCL
-#include "device/device_intern.h"
+# include "device/device_intern.h"
#endif
CCL_NAMESPACE_BEGIN
@@ -54,9 +54,9 @@ bool debug_flags_set = false;
void *pylong_as_voidptr_typesafe(PyObject *object)
{
- if(object == Py_None)
- return NULL;
- return PyLong_AsVoidPtr(object);
+ if (object == Py_None)
+ return NULL;
+ return PyLong_AsVoidPtr(object);
}
/* Synchronize debug flags from a given Blender scene.
@@ -64,48 +64,48 @@ void *pylong_as_voidptr_typesafe(PyObject *object)
*/
bool debug_flags_sync_from_scene(BL::Scene b_scene)
{
- DebugFlagsRef flags = DebugFlags();
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
- /* Backup some settings for comparison. */
- DebugFlags::OpenCL::DeviceType opencl_device_type = flags.opencl.device_type;
- /* Synchronize shared flags. */
- flags.viewport_static_bvh = get_enum(cscene, "debug_bvh_type");
- /* Synchronize CPU flags. */
- flags.cpu.avx2 = get_boolean(cscene, "debug_use_cpu_avx2");
- flags.cpu.avx = get_boolean(cscene, "debug_use_cpu_avx");
- flags.cpu.sse41 = get_boolean(cscene, "debug_use_cpu_sse41");
- flags.cpu.sse3 = get_boolean(cscene, "debug_use_cpu_sse3");
- flags.cpu.sse2 = get_boolean(cscene, "debug_use_cpu_sse2");
- flags.cpu.bvh_layout = (BVHLayout)get_enum(cscene, "debug_bvh_layout");
- flags.cpu.split_kernel = get_boolean(cscene, "debug_use_cpu_split_kernel");
- /* Synchronize CUDA flags. */
- flags.cuda.adaptive_compile = get_boolean(cscene, "debug_use_cuda_adaptive_compile");
- flags.cuda.split_kernel = get_boolean(cscene, "debug_use_cuda_split_kernel");
- /* Synchronize OpenCL device type. */
- switch(get_enum(cscene, "debug_opencl_device_type")) {
- case 0:
- flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_NONE;
- break;
- case 1:
- flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_ALL;
- break;
- case 2:
- flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_DEFAULT;
- break;
- case 3:
- flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_CPU;
- break;
- case 4:
- flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_GPU;
- break;
- case 5:
- flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_ACCELERATOR;
- break;
- }
- /* Synchronize other OpenCL flags. */
- flags.opencl.debug = get_boolean(cscene, "debug_use_opencl_debug");
- flags.opencl.mem_limit = ((size_t)get_int(cscene, "debug_opencl_mem_limit"))*1024*1024;
- return flags.opencl.device_type != opencl_device_type;
+ DebugFlagsRef flags = DebugFlags();
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+ /* Backup some settings for comparison. */
+ DebugFlags::OpenCL::DeviceType opencl_device_type = flags.opencl.device_type;
+ /* Synchronize shared flags. */
+ flags.viewport_static_bvh = get_enum(cscene, "debug_bvh_type");
+ /* Synchronize CPU flags. */
+ flags.cpu.avx2 = get_boolean(cscene, "debug_use_cpu_avx2");
+ flags.cpu.avx = get_boolean(cscene, "debug_use_cpu_avx");
+ flags.cpu.sse41 = get_boolean(cscene, "debug_use_cpu_sse41");
+ flags.cpu.sse3 = get_boolean(cscene, "debug_use_cpu_sse3");
+ flags.cpu.sse2 = get_boolean(cscene, "debug_use_cpu_sse2");
+ flags.cpu.bvh_layout = (BVHLayout)get_enum(cscene, "debug_bvh_layout");
+ flags.cpu.split_kernel = get_boolean(cscene, "debug_use_cpu_split_kernel");
+ /* Synchronize CUDA flags. */
+ flags.cuda.adaptive_compile = get_boolean(cscene, "debug_use_cuda_adaptive_compile");
+ flags.cuda.split_kernel = get_boolean(cscene, "debug_use_cuda_split_kernel");
+ /* Synchronize OpenCL device type. */
+ switch (get_enum(cscene, "debug_opencl_device_type")) {
+ case 0:
+ flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_NONE;
+ break;
+ case 1:
+ flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_ALL;
+ break;
+ case 2:
+ flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_DEFAULT;
+ break;
+ case 3:
+ flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_CPU;
+ break;
+ case 4:
+ flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_GPU;
+ break;
+ case 5:
+ flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_ACCELERATOR;
+ break;
+ }
+ /* Synchronize other OpenCL flags. */
+ flags.opencl.debug = get_boolean(cscene, "debug_use_opencl_debug");
+ flags.opencl.mem_limit = ((size_t)get_int(cscene, "debug_opencl_mem_limit")) * 1024 * 1024;
+ return flags.opencl.device_type != opencl_device_type;
}
/* Reset debug flags to default values.
@@ -113,928 +113,958 @@ bool debug_flags_sync_from_scene(BL::Scene b_scene)
*/
bool debug_flags_reset()
{
- DebugFlagsRef flags = DebugFlags();
- /* Backup some settings for comparison. */
- DebugFlags::OpenCL::DeviceType opencl_device_type = flags.opencl.device_type;
- flags.reset();
- return flags.opencl.device_type != opencl_device_type;
+ DebugFlagsRef flags = DebugFlags();
+ /* Backup some settings for comparison. */
+ DebugFlags::OpenCL::DeviceType opencl_device_type = flags.opencl.device_type;
+ flags.reset();
+ return flags.opencl.device_type != opencl_device_type;
}
-} /* namespace */
+} /* namespace */
void python_thread_state_save(void **python_thread_state)
{
- *python_thread_state = (void*)PyEval_SaveThread();
+ *python_thread_state = (void *)PyEval_SaveThread();
}
void python_thread_state_restore(void **python_thread_state)
{
- PyEval_RestoreThread((PyThreadState*)*python_thread_state);
- *python_thread_state = NULL;
+ PyEval_RestoreThread((PyThreadState *)*python_thread_state);
+ *python_thread_state = NULL;
}
static const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)
{
- const char *result = _PyUnicode_AsString(py_str);
- if(result) {
- /* 99% of the time this is enough but we better support non unicode
- * chars since blender doesnt limit this.
- */
- return result;
- }
- else {
- PyErr_Clear();
- if(PyBytes_Check(py_str)) {
- return PyBytes_AS_STRING(py_str);
- }
- else if((*coerce = PyUnicode_EncodeFSDefault(py_str))) {
- return PyBytes_AS_STRING(*coerce);
- }
- else {
- /* Clear the error, so Cycles can be at leadt used without
- * GPU and OSL support,
- */
- PyErr_Clear();
- return "";
- }
- }
+ const char *result = _PyUnicode_AsString(py_str);
+ if (result) {
+ /* 99% of the time this is enough but we better support non unicode
+ * chars since blender doesnt limit this.
+ */
+ return result;
+ }
+ else {
+ PyErr_Clear();
+ if (PyBytes_Check(py_str)) {
+ return PyBytes_AS_STRING(py_str);
+ }
+ else if ((*coerce = PyUnicode_EncodeFSDefault(py_str))) {
+ return PyBytes_AS_STRING(*coerce);
+ }
+ else {
+ /* Clear the error, so Cycles can be at leadt used without
+ * GPU and OSL support,
+ */
+ PyErr_Clear();
+ return "";
+ }
+ }
}
static PyObject *init_func(PyObject * /*self*/, PyObject *args)
{
- PyObject *path, *user_path;
- int headless;
+ PyObject *path, *user_path;
+ int headless;
- if(!PyArg_ParseTuple(args, "OOi", &path, &user_path, &headless)) {
- return NULL;
- }
+ if (!PyArg_ParseTuple(args, "OOi", &path, &user_path, &headless)) {
+ return NULL;
+ }
- PyObject *path_coerce = NULL, *user_path_coerce = NULL;
- path_init(PyC_UnicodeAsByte(path, &path_coerce),
- PyC_UnicodeAsByte(user_path, &user_path_coerce));
- Py_XDECREF(path_coerce);
- Py_XDECREF(user_path_coerce);
+ PyObject *path_coerce = NULL, *user_path_coerce = NULL;
+ path_init(PyC_UnicodeAsByte(path, &path_coerce),
+ PyC_UnicodeAsByte(user_path, &user_path_coerce));
+ Py_XDECREF(path_coerce);
+ Py_XDECREF(user_path_coerce);
- BlenderSession::headless = headless;
+ BlenderSession::headless = headless;
- VLOG(2) << "Debug flags initialized to:\n"
- << DebugFlags();
+ VLOG(2) << "Debug flags initialized to:\n" << DebugFlags();
- Py_RETURN_NONE;
+ Py_RETURN_NONE;
}
-
static PyObject *exit_func(PyObject * /*self*/, PyObject * /*args*/)
{
- ShaderManager::free_memory();
- TaskScheduler::free_memory();
- Device::free_memory();
- Py_RETURN_NONE;
+ ShaderManager::free_memory();
+ TaskScheduler::free_memory();
+ Device::free_memory();
+ Py_RETURN_NONE;
}
static PyObject *create_func(PyObject * /*self*/, PyObject *args)
{
- PyObject *pyengine, *pypreferences, *pydata, *pyregion, *pyv3d, *pyrv3d;
- int preview_osl;
-
- if(!PyArg_ParseTuple(args, "OOOOOOi", &pyengine, &pypreferences, &pydata,
- &pyregion, &pyv3d, &pyrv3d, &preview_osl))
- {
- return NULL;
- }
-
- /* RNA */
- PointerRNA engineptr;
- RNA_pointer_create(NULL, &RNA_RenderEngine, (void*)PyLong_AsVoidPtr(pyengine), &engineptr);
- BL::RenderEngine engine(engineptr);
-
- PointerRNA preferencesptr;
- RNA_pointer_create(NULL, &RNA_Preferences, (void*)PyLong_AsVoidPtr(pypreferences), &preferencesptr);
- BL::Preferences preferences(preferencesptr);
-
- PointerRNA dataptr;
- RNA_main_pointer_create((Main*)PyLong_AsVoidPtr(pydata), &dataptr);
- BL::BlendData data(dataptr);
-
- PointerRNA regionptr;
- RNA_pointer_create(NULL, &RNA_Region, pylong_as_voidptr_typesafe(pyregion), &regionptr);
- BL::Region region(regionptr);
-
- PointerRNA v3dptr;
- RNA_pointer_create(NULL, &RNA_SpaceView3D, pylong_as_voidptr_typesafe(pyv3d), &v3dptr);
- BL::SpaceView3D v3d(v3dptr);
-
- PointerRNA rv3dptr;
- RNA_pointer_create(NULL, &RNA_RegionView3D, pylong_as_voidptr_typesafe(pyrv3d), &rv3dptr);
- BL::RegionView3D rv3d(rv3dptr);
-
- /* create session */
- BlenderSession *session;
-
- if(rv3d) {
- /* interactive viewport session */
- int width = region.width();
- int height = region.height();
-
- session = new BlenderSession(engine, preferences, data, v3d, rv3d, width, height);
- }
- else {
- /* offline session or preview render */
- session = new BlenderSession(engine, preferences, data, preview_osl);
- }
-
- return PyLong_FromVoidPtr(session);
+ PyObject *pyengine, *pypreferences, *pydata, *pyregion, *pyv3d, *pyrv3d;
+ int preview_osl;
+
+ if (!PyArg_ParseTuple(args,
+ "OOOOOOi",
+ &pyengine,
+ &pypreferences,
+ &pydata,
+ &pyregion,
+ &pyv3d,
+ &pyrv3d,
+ &preview_osl)) {
+ return NULL;
+ }
+
+ /* RNA */
+ PointerRNA engineptr;
+ RNA_pointer_create(NULL, &RNA_RenderEngine, (void *)PyLong_AsVoidPtr(pyengine), &engineptr);
+ BL::RenderEngine engine(engineptr);
+
+ PointerRNA preferencesptr;
+ RNA_pointer_create(
+ NULL, &RNA_Preferences, (void *)PyLong_AsVoidPtr(pypreferences), &preferencesptr);
+ BL::Preferences preferences(preferencesptr);
+
+ PointerRNA dataptr;
+ RNA_main_pointer_create((Main *)PyLong_AsVoidPtr(pydata), &dataptr);
+ BL::BlendData data(dataptr);
+
+ PointerRNA regionptr;
+ RNA_pointer_create(NULL, &RNA_Region, pylong_as_voidptr_typesafe(pyregion), &regionptr);
+ BL::Region region(regionptr);
+
+ PointerRNA v3dptr;
+ RNA_pointer_create(NULL, &RNA_SpaceView3D, pylong_as_voidptr_typesafe(pyv3d), &v3dptr);
+ BL::SpaceView3D v3d(v3dptr);
+
+ PointerRNA rv3dptr;
+ RNA_pointer_create(NULL, &RNA_RegionView3D, pylong_as_voidptr_typesafe(pyrv3d), &rv3dptr);
+ BL::RegionView3D rv3d(rv3dptr);
+
+ /* create session */
+ BlenderSession *session;
+
+ if (rv3d) {
+ /* interactive viewport session */
+ int width = region.width();
+ int height = region.height();
+
+ session = new BlenderSession(engine, preferences, data, v3d, rv3d, width, height);
+ }
+ else {
+ /* offline session or preview render */
+ session = new BlenderSession(engine, preferences, data, preview_osl);
+ }
+
+ return PyLong_FromVoidPtr(session);
}
static PyObject *free_func(PyObject * /*self*/, PyObject *value)
{
- delete (BlenderSession*)PyLong_AsVoidPtr(value);
+ delete (BlenderSession *)PyLong_AsVoidPtr(value);
- Py_RETURN_NONE;
+ Py_RETURN_NONE;
}
static PyObject *render_func(PyObject * /*self*/, PyObject *args)
{
- PyObject *pysession, *pydepsgraph;
+ PyObject *pysession, *pydepsgraph;
- if(!PyArg_ParseTuple(args, "OO", &pysession, &pydepsgraph))
- return NULL;
+ if (!PyArg_ParseTuple(args, "OO", &pysession, &pydepsgraph))
+ return NULL;
- BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
+ BlenderSession *session = (BlenderSession *)PyLong_AsVoidPtr(pysession);
- PointerRNA depsgraphptr;
- RNA_pointer_create(NULL, &RNA_Depsgraph, (ID*)PyLong_AsVoidPtr(pydepsgraph), &depsgraphptr);
- BL::Depsgraph b_depsgraph(depsgraphptr);
+ PointerRNA depsgraphptr;
+ RNA_pointer_create(NULL, &RNA_Depsgraph, (ID *)PyLong_AsVoidPtr(pydepsgraph), &depsgraphptr);
+ BL::Depsgraph b_depsgraph(depsgraphptr);
- python_thread_state_save(&session->python_thread_state);
+ python_thread_state_save(&session->python_thread_state);
- session->render(b_depsgraph);
+ session->render(b_depsgraph);
- python_thread_state_restore(&session->python_thread_state);
+ python_thread_state_restore(&session->python_thread_state);
- Py_RETURN_NONE;
+ Py_RETURN_NONE;
}
/* pixel_array and result passed as pointers */
static PyObject *bake_func(PyObject * /*self*/, PyObject *args)
{
- PyObject *pysession, *pydepsgraph, *pyobject;
- PyObject *pypixel_array, *pyresult;
- const char *pass_type;
- int num_pixels, depth, object_id, pass_filter;
-
- if(!PyArg_ParseTuple(args, "OOOsiiOiiO", &pysession, &pydepsgraph, &pyobject, &pass_type, &pass_filter, &object_id, &pypixel_array, &num_pixels, &depth, &pyresult))
- return NULL;
-
- BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
-
- PointerRNA depsgraphptr;
- RNA_pointer_create(NULL, &RNA_Depsgraph, PyLong_AsVoidPtr(pydepsgraph), &depsgraphptr);
- BL::Depsgraph b_depsgraph(depsgraphptr);
-
- PointerRNA objectptr;
- RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyobject), &objectptr);
- BL::Object b_object(objectptr);
-
- void *b_result = PyLong_AsVoidPtr(pyresult);
-
- PointerRNA bakepixelptr;
- RNA_pointer_create(NULL, &RNA_BakePixel, PyLong_AsVoidPtr(pypixel_array), &bakepixelptr);
- BL::BakePixel b_bake_pixel(bakepixelptr);
-
- python_thread_state_save(&session->python_thread_state);
-
- session->bake(b_depsgraph, b_object, pass_type, pass_filter, object_id, b_bake_pixel, (size_t)num_pixels, depth, (float *)b_result);
-
- python_thread_state_restore(&session->python_thread_state);
-
- Py_RETURN_NONE;
+ PyObject *pysession, *pydepsgraph, *pyobject;
+ PyObject *pypixel_array, *pyresult;
+ const char *pass_type;
+ int num_pixels, depth, object_id, pass_filter;
+
+ if (!PyArg_ParseTuple(args,
+ "OOOsiiOiiO",
+ &pysession,
+ &pydepsgraph,
+ &pyobject,
+ &pass_type,
+ &pass_filter,
+ &object_id,
+ &pypixel_array,
+ &num_pixels,
+ &depth,
+ &pyresult))
+ return NULL;
+
+ BlenderSession *session = (BlenderSession *)PyLong_AsVoidPtr(pysession);
+
+ PointerRNA depsgraphptr;
+ RNA_pointer_create(NULL, &RNA_Depsgraph, PyLong_AsVoidPtr(pydepsgraph), &depsgraphptr);
+ BL::Depsgraph b_depsgraph(depsgraphptr);
+
+ PointerRNA objectptr;
+ RNA_id_pointer_create((ID *)PyLong_AsVoidPtr(pyobject), &objectptr);
+ BL::Object b_object(objectptr);
+
+ void *b_result = PyLong_AsVoidPtr(pyresult);
+
+ PointerRNA bakepixelptr;
+ RNA_pointer_create(NULL, &RNA_BakePixel, PyLong_AsVoidPtr(pypixel_array), &bakepixelptr);
+ BL::BakePixel b_bake_pixel(bakepixelptr);
+
+ python_thread_state_save(&session->python_thread_state);
+
+ session->bake(b_depsgraph,
+ b_object,
+ pass_type,
+ pass_filter,
+ object_id,
+ b_bake_pixel,
+ (size_t)num_pixels,
+ depth,
+ (float *)b_result);
+
+ python_thread_state_restore(&session->python_thread_state);
+
+ Py_RETURN_NONE;
}
static PyObject *draw_func(PyObject * /*self*/, PyObject *args)
{
- PyObject *pysession, *pygraph, *pyv3d, *pyrv3d;
+ PyObject *pysession, *pygraph, *pyv3d, *pyrv3d;
- if(!PyArg_ParseTuple(args, "OOOO", &pysession, &pygraph, &pyv3d, &pyrv3d))
- return NULL;
+ if (!PyArg_ParseTuple(args, "OOOO", &pysession, &pygraph, &pyv3d, &pyrv3d))
+ return NULL;
- BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
+ BlenderSession *session = (BlenderSession *)PyLong_AsVoidPtr(pysession);
- if(PyLong_AsVoidPtr(pyrv3d)) {
- /* 3d view drawing */
- int viewport[4];
- glGetIntegerv(GL_VIEWPORT, viewport);
+ if (PyLong_AsVoidPtr(pyrv3d)) {
+ /* 3d view drawing */
+ int viewport[4];
+ glGetIntegerv(GL_VIEWPORT, viewport);
- session->draw(viewport[2], viewport[3]);
- }
+ session->draw(viewport[2], viewport[3]);
+ }
- Py_RETURN_NONE;
+ Py_RETURN_NONE;
}
static PyObject *reset_func(PyObject * /*self*/, PyObject *args)
{
- PyObject *pysession, *pydata, *pydepsgraph;
+ PyObject *pysession, *pydata, *pydepsgraph;
- if(!PyArg_ParseTuple(args, "OOO", &pysession, &pydata, &pydepsgraph))
- return NULL;
+ if (!PyArg_ParseTuple(args, "OOO", &pysession, &pydata, &pydepsgraph))
+ return NULL;
- BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
+ BlenderSession *session = (BlenderSession *)PyLong_AsVoidPtr(pysession);
- PointerRNA dataptr;
- RNA_main_pointer_create((Main*)PyLong_AsVoidPtr(pydata), &dataptr);
- BL::BlendData b_data(dataptr);
+ PointerRNA dataptr;
+ RNA_main_pointer_create((Main *)PyLong_AsVoidPtr(pydata), &dataptr);
+ BL::BlendData b_data(dataptr);
- PointerRNA depsgraphptr;
- RNA_pointer_create(NULL, &RNA_Depsgraph, PyLong_AsVoidPtr(pydepsgraph), &depsgraphptr);
- BL::Depsgraph b_depsgraph(depsgraphptr);
+ PointerRNA depsgraphptr;
+ RNA_pointer_create(NULL, &RNA_Depsgraph, PyLong_AsVoidPtr(pydepsgraph), &depsgraphptr);
+ BL::Depsgraph b_depsgraph(depsgraphptr);
- python_thread_state_save(&session->python_thread_state);
+ python_thread_state_save(&session->python_thread_state);
- session->reset_session(b_data, b_depsgraph);
+ session->reset_session(b_data, b_depsgraph);
- python_thread_state_restore(&session->python_thread_state);
+ python_thread_state_restore(&session->python_thread_state);
- Py_RETURN_NONE;
+ Py_RETURN_NONE;
}
static PyObject *sync_func(PyObject * /*self*/, PyObject *args)
{
- PyObject *pysession, *pydepsgraph;
+ PyObject *pysession, *pydepsgraph;
- if(!PyArg_ParseTuple(args, "OO", &pysession, &pydepsgraph))
- return NULL;
+ if (!PyArg_ParseTuple(args, "OO", &pysession, &pydepsgraph))
+ return NULL;
- BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
+ BlenderSession *session = (BlenderSession *)PyLong_AsVoidPtr(pysession);
- PointerRNA depsgraphptr;
- RNA_pointer_create(NULL, &RNA_Depsgraph, PyLong_AsVoidPtr(pydepsgraph), &depsgraphptr);
- BL::Depsgraph b_depsgraph(depsgraphptr);
+ PointerRNA depsgraphptr;
+ RNA_pointer_create(NULL, &RNA_Depsgraph, PyLong_AsVoidPtr(pydepsgraph), &depsgraphptr);
+ BL::Depsgraph b_depsgraph(depsgraphptr);
- python_thread_state_save(&session->python_thread_state);
+ python_thread_state_save(&session->python_thread_state);
- session->synchronize(b_depsgraph);
+ session->synchronize(b_depsgraph);
- python_thread_state_restore(&session->python_thread_state);
+ python_thread_state_restore(&session->python_thread_state);
- Py_RETURN_NONE;
+ Py_RETURN_NONE;
}
-static PyObject *available_devices_func(PyObject * /*self*/, PyObject * args)
+static PyObject *available_devices_func(PyObject * /*self*/, PyObject *args)
{
- const char *type_name;
- if(!PyArg_ParseTuple(args, "s", &type_name)) {
- return NULL;
- }
-
- DeviceType type = Device::type_from_string(type_name);
- uint mask = (type == DEVICE_NONE) ? DEVICE_MASK_ALL : DEVICE_MASK(type);
- mask |= DEVICE_MASK_CPU;
-
- vector<DeviceInfo> devices = Device::available_devices(mask);
- PyObject *ret = PyTuple_New(devices.size());
-
- for(size_t i = 0; i < devices.size(); i++) {
- DeviceInfo& device = devices[i];
- string type_name = Device::string_from_type(device.type);
- PyObject *device_tuple = PyTuple_New(3);
- PyTuple_SET_ITEM(device_tuple, 0, PyUnicode_FromString(device.description.c_str()));
- PyTuple_SET_ITEM(device_tuple, 1, PyUnicode_FromString(type_name.c_str()));
- PyTuple_SET_ITEM(device_tuple, 2, PyUnicode_FromString(device.id.c_str()));
- PyTuple_SET_ITEM(ret, i, device_tuple);
- }
-
- return ret;
+ const char *type_name;
+ if (!PyArg_ParseTuple(args, "s", &type_name)) {
+ return NULL;
+ }
+
+ DeviceType type = Device::type_from_string(type_name);
+ uint mask = (type == DEVICE_NONE) ? DEVICE_MASK_ALL : DEVICE_MASK(type);
+ mask |= DEVICE_MASK_CPU;
+
+ vector<DeviceInfo> devices = Device::available_devices(mask);
+ PyObject *ret = PyTuple_New(devices.size());
+
+ for (size_t i = 0; i < devices.size(); i++) {
+ DeviceInfo &device = devices[i];
+ string type_name = Device::string_from_type(device.type);
+ PyObject *device_tuple = PyTuple_New(3);
+ PyTuple_SET_ITEM(device_tuple, 0, PyUnicode_FromString(device.description.c_str()));
+ PyTuple_SET_ITEM(device_tuple, 1, PyUnicode_FromString(type_name.c_str()));
+ PyTuple_SET_ITEM(device_tuple, 2, PyUnicode_FromString(device.id.c_str()));
+ PyTuple_SET_ITEM(ret, i, device_tuple);
+ }
+
+ return ret;
}
#ifdef WITH_OSL
static PyObject *osl_update_node_func(PyObject * /*self*/, PyObject *args)
{
- PyObject *pydata, *pynodegroup, *pynode;
- const char *filepath = NULL;
-
- if(!PyArg_ParseTuple(args, "OOOs", &pydata, &pynodegroup, &pynode, &filepath))
- return NULL;
-
- /* RNA */
- PointerRNA dataptr;
- RNA_main_pointer_create((Main*)PyLong_AsVoidPtr(pydata), &dataptr);
- BL::BlendData b_data(dataptr);
-
- PointerRNA nodeptr;
- RNA_pointer_create((ID*)PyLong_AsVoidPtr(pynodegroup), &RNA_ShaderNodeScript, (void*)PyLong_AsVoidPtr(pynode), &nodeptr);
- BL::ShaderNodeScript b_node(nodeptr);
-
- /* update bytecode hash */
- string bytecode = b_node.bytecode();
-
- if(!bytecode.empty()) {
- MD5Hash md5;
- md5.append((const uint8_t*)bytecode.c_str(), bytecode.size());
- b_node.bytecode_hash(md5.get_hex().c_str());
- }
- else
- b_node.bytecode_hash("");
-
- /* query from file path */
- OSL::OSLQuery query;
-
- if(!OSLShaderManager::osl_query(query, filepath))
- Py_RETURN_FALSE;
-
- /* add new sockets from parameters */
- set<void*> used_sockets;
-
- for(int i = 0; i < query.nparams(); i++) {
- const OSL::OSLQuery::Parameter *param = query.getparam(i);
-
- /* skip unsupported types */
- if(param->varlenarray || param->isstruct || param->type.arraylen > 1)
- continue;
-
- /* determine socket type */
- string socket_type;
- BL::NodeSocket::type_enum data_type = BL::NodeSocket::type_VALUE;
- float4 default_float4 = make_float4(0.0f, 0.0f, 0.0f, 1.0f);
- float default_float = 0.0f;
- int default_int = 0;
- string default_string = "";
-
- if(param->isclosure) {
- socket_type = "NodeSocketShader";
- data_type = BL::NodeSocket::type_SHADER;
- }
- else if(param->type.vecsemantics == TypeDesc::COLOR) {
- socket_type = "NodeSocketColor";
- data_type = BL::NodeSocket::type_RGBA;
-
- if(param->validdefault) {
- default_float4[0] = param->fdefault[0];
- default_float4[1] = param->fdefault[1];
- default_float4[2] = param->fdefault[2];
- }
- }
- else if(param->type.vecsemantics == TypeDesc::POINT ||
- param->type.vecsemantics == TypeDesc::VECTOR ||
- param->type.vecsemantics == TypeDesc::NORMAL)
- {
- socket_type = "NodeSocketVector";
- data_type = BL::NodeSocket::type_VECTOR;
-
- if(param->validdefault) {
- default_float4[0] = param->fdefault[0];
- default_float4[1] = param->fdefault[1];
- default_float4[2] = param->fdefault[2];
- }
- }
- else if(param->type.aggregate == TypeDesc::SCALAR) {
- if(param->type.basetype == TypeDesc::INT) {
- socket_type = "NodeSocketInt";
- data_type = BL::NodeSocket::type_INT;
- if(param->validdefault)
- default_int = param->idefault[0];
- }
- else if(param->type.basetype == TypeDesc::FLOAT) {
- socket_type = "NodeSocketFloat";
- data_type = BL::NodeSocket::type_VALUE;
- if(param->validdefault)
- default_float = param->fdefault[0];
- }
- else if(param->type.basetype == TypeDesc::STRING) {
- socket_type = "NodeSocketString";
- data_type = BL::NodeSocket::type_STRING;
- if(param->validdefault)
- default_string = param->sdefault[0].string();
- }
- else
- continue;
- }
- else
- continue;
-
- /* find socket socket */
- BL::NodeSocket b_sock(PointerRNA_NULL);
- if(param->isoutput) {
- b_sock = b_node.outputs[param->name.string()];
- /* remove if type no longer matches */
- if(b_sock && b_sock.bl_idname() != socket_type) {
- b_node.outputs.remove(b_data, b_sock);
- b_sock = BL::NodeSocket(PointerRNA_NULL);
- }
- }
- else {
- b_sock = b_node.inputs[param->name.string()];
- /* remove if type no longer matches */
- if(b_sock && b_sock.bl_idname() != socket_type) {
- b_node.inputs.remove(b_data, b_sock);
- b_sock = BL::NodeSocket(PointerRNA_NULL);
- }
- }
-
- if(!b_sock) {
- /* create new socket */
- if(param->isoutput)
- b_sock = b_node.outputs.create(b_data, socket_type.c_str(), param->name.c_str(), param->name.c_str());
- else
- b_sock = b_node.inputs.create(b_data, socket_type.c_str(), param->name.c_str(), param->name.c_str());
-
- /* set default value */
- if(data_type == BL::NodeSocket::type_VALUE) {
- set_float(b_sock.ptr, "default_value", default_float);
- }
- else if(data_type == BL::NodeSocket::type_INT) {
- set_int(b_sock.ptr, "default_value", default_int);
- }
- else if(data_type == BL::NodeSocket::type_RGBA) {
- set_float4(b_sock.ptr, "default_value", default_float4);
- }
- else if(data_type == BL::NodeSocket::type_VECTOR) {
- set_float3(b_sock.ptr, "default_value", float4_to_float3(default_float4));
- }
- else if(data_type == BL::NodeSocket::type_STRING) {
- set_string(b_sock.ptr, "default_value", default_string);
- }
- }
-
- used_sockets.insert(b_sock.ptr.data);
- }
-
- /* remove unused parameters */
- bool removed;
-
- do {
- BL::Node::inputs_iterator b_input;
- BL::Node::outputs_iterator b_output;
-
- removed = false;
-
- for(b_node.inputs.begin(b_input); b_input != b_node.inputs.end(); ++b_input) {
- if(used_sockets.find(b_input->ptr.data) == used_sockets.end()) {
- b_node.inputs.remove(b_data, *b_input);
- removed = true;
- break;
- }
- }
-
- for(b_node.outputs.begin(b_output); b_output != b_node.outputs.end(); ++b_output) {
- if(used_sockets.find(b_output->ptr.data) == used_sockets.end()) {
- b_node.outputs.remove(b_data, *b_output);
- removed = true;
- break;
- }
- }
- } while(removed);
-
- Py_RETURN_TRUE;
+ PyObject *pydata, *pynodegroup, *pynode;
+ const char *filepath = NULL;
+
+ if (!PyArg_ParseTuple(args, "OOOs", &pydata, &pynodegroup, &pynode, &filepath))
+ return NULL;
+
+ /* RNA */
+ PointerRNA dataptr;
+ RNA_main_pointer_create((Main *)PyLong_AsVoidPtr(pydata), &dataptr);
+ BL::BlendData b_data(dataptr);
+
+ PointerRNA nodeptr;
+ RNA_pointer_create((ID *)PyLong_AsVoidPtr(pynodegroup),
+ &RNA_ShaderNodeScript,
+ (void *)PyLong_AsVoidPtr(pynode),
+ &nodeptr);
+ BL::ShaderNodeScript b_node(nodeptr);
+
+ /* update bytecode hash */
+ string bytecode = b_node.bytecode();
+
+ if (!bytecode.empty()) {
+ MD5Hash md5;
+ md5.append((const uint8_t *)bytecode.c_str(), bytecode.size());
+ b_node.bytecode_hash(md5.get_hex().c_str());
+ }
+ else
+ b_node.bytecode_hash("");
+
+ /* query from file path */
+ OSL::OSLQuery query;
+
+ if (!OSLShaderManager::osl_query(query, filepath))
+ Py_RETURN_FALSE;
+
+ /* add new sockets from parameters */
+ set<void *> used_sockets;
+
+ for (int i = 0; i < query.nparams(); i++) {
+ const OSL::OSLQuery::Parameter *param = query.getparam(i);
+
+ /* skip unsupported types */
+ if (param->varlenarray || param->isstruct || param->type.arraylen > 1)
+ continue;
+
+ /* determine socket type */
+ string socket_type;
+ BL::NodeSocket::type_enum data_type = BL::NodeSocket::type_VALUE;
+ float4 default_float4 = make_float4(0.0f, 0.0f, 0.0f, 1.0f);
+ float default_float = 0.0f;
+ int default_int = 0;
+ string default_string = "";
+
+ if (param->isclosure) {
+ socket_type = "NodeSocketShader";
+ data_type = BL::NodeSocket::type_SHADER;
+ }
+ else if (param->type.vecsemantics == TypeDesc::COLOR) {
+ socket_type = "NodeSocketColor";
+ data_type = BL::NodeSocket::type_RGBA;
+
+ if (param->validdefault) {
+ default_float4[0] = param->fdefault[0];
+ default_float4[1] = param->fdefault[1];
+ default_float4[2] = param->fdefault[2];
+ }
+ }
+ else if (param->type.vecsemantics == TypeDesc::POINT ||
+ param->type.vecsemantics == TypeDesc::VECTOR ||
+ param->type.vecsemantics == TypeDesc::NORMAL) {
+ socket_type = "NodeSocketVector";
+ data_type = BL::NodeSocket::type_VECTOR;
+
+ if (param->validdefault) {
+ default_float4[0] = param->fdefault[0];
+ default_float4[1] = param->fdefault[1];
+ default_float4[2] = param->fdefault[2];
+ }
+ }
+ else if (param->type.aggregate == TypeDesc::SCALAR) {
+ if (param->type.basetype == TypeDesc::INT) {
+ socket_type = "NodeSocketInt";
+ data_type = BL::NodeSocket::type_INT;
+ if (param->validdefault)
+ default_int = param->idefault[0];
+ }
+ else if (param->type.basetype == TypeDesc::FLOAT) {
+ socket_type = "NodeSocketFloat";
+ data_type = BL::NodeSocket::type_VALUE;
+ if (param->validdefault)
+ default_float = param->fdefault[0];
+ }
+ else if (param->type.basetype == TypeDesc::STRING) {
+ socket_type = "NodeSocketString";
+ data_type = BL::NodeSocket::type_STRING;
+ if (param->validdefault)
+ default_string = param->sdefault[0].string();
+ }
+ else
+ continue;
+ }
+ else
+ continue;
+
+ /* find socket socket */
+ BL::NodeSocket b_sock(PointerRNA_NULL);
+ if (param->isoutput) {
+ b_sock = b_node.outputs[param->name.string()];
+ /* remove if type no longer matches */
+ if (b_sock && b_sock.bl_idname() != socket_type) {
+ b_node.outputs.remove(b_data, b_sock);
+ b_sock = BL::NodeSocket(PointerRNA_NULL);
+ }
+ }
+ else {
+ b_sock = b_node.inputs[param->name.string()];
+ /* remove if type no longer matches */
+ if (b_sock && b_sock.bl_idname() != socket_type) {
+ b_node.inputs.remove(b_data, b_sock);
+ b_sock = BL::NodeSocket(PointerRNA_NULL);
+ }
+ }
+
+ if (!b_sock) {
+ /* create new socket */
+ if (param->isoutput)
+ b_sock = b_node.outputs.create(
+ b_data, socket_type.c_str(), param->name.c_str(), param->name.c_str());
+ else
+ b_sock = b_node.inputs.create(
+ b_data, socket_type.c_str(), param->name.c_str(), param->name.c_str());
+
+ /* set default value */
+ if (data_type == BL::NodeSocket::type_VALUE) {
+ set_float(b_sock.ptr, "default_value", default_float);
+ }
+ else if (data_type == BL::NodeSocket::type_INT) {
+ set_int(b_sock.ptr, "default_value", default_int);
+ }
+ else if (data_type == BL::NodeSocket::type_RGBA) {
+ set_float4(b_sock.ptr, "default_value", default_float4);
+ }
+ else if (data_type == BL::NodeSocket::type_VECTOR) {
+ set_float3(b_sock.ptr, "default_value", float4_to_float3(default_float4));
+ }
+ else if (data_type == BL::NodeSocket::type_STRING) {
+ set_string(b_sock.ptr, "default_value", default_string);
+ }
+ }
+
+ used_sockets.insert(b_sock.ptr.data);
+ }
+
+ /* remove unused parameters */
+ bool removed;
+
+ do {
+ BL::Node::inputs_iterator b_input;
+ BL::Node::outputs_iterator b_output;
+
+ removed = false;
+
+ for (b_node.inputs.begin(b_input); b_input != b_node.inputs.end(); ++b_input) {
+ if (used_sockets.find(b_input->ptr.data) == used_sockets.end()) {
+ b_node.inputs.remove(b_data, *b_input);
+ removed = true;
+ break;
+ }
+ }
+
+ for (b_node.outputs.begin(b_output); b_output != b_node.outputs.end(); ++b_output) {
+ if (used_sockets.find(b_output->ptr.data) == used_sockets.end()) {
+ b_node.outputs.remove(b_data, *b_output);
+ removed = true;
+ break;
+ }
+ }
+ } while (removed);
+
+ Py_RETURN_TRUE;
}
static PyObject *osl_compile_func(PyObject * /*self*/, PyObject *args)
{
- const char *inputfile = NULL, *outputfile = NULL;
+ const char *inputfile = NULL, *outputfile = NULL;
- if(!PyArg_ParseTuple(args, "ss", &inputfile, &outputfile))
- return NULL;
+ if (!PyArg_ParseTuple(args, "ss", &inputfile, &outputfile))
+ return NULL;
- /* return */
- if(!OSLShaderManager::osl_compile(inputfile, outputfile))
- Py_RETURN_FALSE;
+ /* return */
+ if (!OSLShaderManager::osl_compile(inputfile, outputfile))
+ Py_RETURN_FALSE;
- Py_RETURN_TRUE;
+ Py_RETURN_TRUE;
}
#endif
static PyObject *system_info_func(PyObject * /*self*/, PyObject * /*value*/)
{
- string system_info = Device::device_capabilities();
- return PyUnicode_FromString(system_info.c_str());
+ string system_info = Device::device_capabilities();
+ return PyUnicode_FromString(system_info.c_str());
}
#ifdef WITH_OPENCL
static PyObject *opencl_disable_func(PyObject * /*self*/, PyObject * /*value*/)
{
- VLOG(2) << "Disabling OpenCL platform.";
- DebugFlags().opencl.device_type = DebugFlags::OpenCL::DEVICE_NONE;
- Py_RETURN_NONE;
+ VLOG(2) << "Disabling OpenCL platform.";
+ DebugFlags().opencl.device_type = DebugFlags::OpenCL::DEVICE_NONE;
+ Py_RETURN_NONE;
}
static PyObject *opencl_compile_func(PyObject * /*self*/, PyObject *args)
{
- PyObject *sequence = PySequence_Fast(args, "Arguments must be a sequence");
- if(sequence == NULL) {
- Py_RETURN_FALSE;
- }
-
- vector<string> parameters;
- for(Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(sequence); i++) {
- PyObject *item = PySequence_Fast_GET_ITEM(sequence, i);
- PyObject *item_as_string = PyObject_Str(item);
- const char *parameter_string = PyUnicode_AsUTF8(item_as_string);
- parameters.push_back(parameter_string);
- Py_DECREF(item_as_string);
- }
- Py_DECREF(sequence);
-
- if (device_opencl_compile_kernel(parameters)) {
- Py_RETURN_TRUE;
- }
- else {
- Py_RETURN_FALSE;
- }
+ PyObject *sequence = PySequence_Fast(args, "Arguments must be a sequence");
+ if (sequence == NULL) {
+ Py_RETURN_FALSE;
+ }
+
+ vector<string> parameters;
+ for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(sequence); i++) {
+ PyObject *item = PySequence_Fast_GET_ITEM(sequence, i);
+ PyObject *item_as_string = PyObject_Str(item);
+ const char *parameter_string = PyUnicode_AsUTF8(item_as_string);
+ parameters.push_back(parameter_string);
+ Py_DECREF(item_as_string);
+ }
+ Py_DECREF(sequence);
+
+ if (device_opencl_compile_kernel(parameters)) {
+ Py_RETURN_TRUE;
+ }
+ else {
+ Py_RETURN_FALSE;
+ }
}
#endif
-static bool image_parse_filepaths(PyObject *pyfilepaths, vector<string>& filepaths)
+static bool image_parse_filepaths(PyObject *pyfilepaths, vector<string> &filepaths)
{
- if(PyUnicode_Check(pyfilepaths)) {
- const char *filepath = PyUnicode_AsUTF8(pyfilepaths);
- filepaths.push_back(filepath);
- return true;
- }
-
- PyObject *sequence = PySequence_Fast(pyfilepaths, "File paths must be a string or sequence of strings");
- if(sequence == NULL) {
- return false;
- }
-
- for(Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(sequence); i++) {
- PyObject *item = PySequence_Fast_GET_ITEM(sequence, i);
- const char *filepath = PyUnicode_AsUTF8(item);
- if(filepath == NULL) {
- PyErr_SetString(PyExc_ValueError, "File paths must be a string or sequence of strings.");
- Py_DECREF(sequence);
- return false;
- }
- filepaths.push_back(filepath);
- }
- Py_DECREF(sequence);
-
- return true;
+ if (PyUnicode_Check(pyfilepaths)) {
+ const char *filepath = PyUnicode_AsUTF8(pyfilepaths);
+ filepaths.push_back(filepath);
+ return true;
+ }
+
+ PyObject *sequence = PySequence_Fast(pyfilepaths,
+ "File paths must be a string or sequence of strings");
+ if (sequence == NULL) {
+ return false;
+ }
+
+ for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(sequence); i++) {
+ PyObject *item = PySequence_Fast_GET_ITEM(sequence, i);
+ const char *filepath = PyUnicode_AsUTF8(item);
+ if (filepath == NULL) {
+ PyErr_SetString(PyExc_ValueError, "File paths must be a string or sequence of strings.");
+ Py_DECREF(sequence);
+ return false;
+ }
+ filepaths.push_back(filepath);
+ }
+ Py_DECREF(sequence);
+
+ return true;
}
static PyObject *denoise_func(PyObject * /*self*/, PyObject *args, PyObject *keywords)
{
- static const char *keyword_list[] = {"preferences", "scene", "view_layer",
- "input", "output",
- "tile_size", "samples", NULL};
- PyObject *pypreferences, *pyscene, *pyviewlayer;
- PyObject *pyinput, *pyoutput = NULL;
- int tile_size = 0, samples = 0;
-
- if (!PyArg_ParseTupleAndKeywords(args, keywords, "OOOO|Oii", (char**)keyword_list,
- &pypreferences, &pyscene, &pyviewlayer,
- &pyinput, &pyoutput,
- &tile_size, &samples)) {
- return NULL;
- }
-
- /* Get device specification from preferences and scene. */
- PointerRNA preferencesptr;
- RNA_pointer_create(NULL, &RNA_Preferences, (void*)PyLong_AsVoidPtr(pypreferences), &preferencesptr);
- BL::Preferences b_preferences(preferencesptr);
-
- PointerRNA sceneptr;
- RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyscene), &sceneptr);
- BL::Scene b_scene(sceneptr);
-
- DeviceInfo device = blender_device_info(b_preferences, b_scene, true);
-
- /* Get denoising parameters from view layer. */
- PointerRNA viewlayerptr;
- RNA_pointer_create((ID*)PyLong_AsVoidPtr(pyscene), &RNA_ViewLayer, PyLong_AsVoidPtr(pyviewlayer), &viewlayerptr);
- PointerRNA cviewlayer = RNA_pointer_get(&viewlayerptr, "cycles");
-
- DenoiseParams params;
- params.radius = get_int(cviewlayer, "denoising_radius");
- params.strength = get_float(cviewlayer, "denoising_strength");
- params.feature_strength = get_float(cviewlayer, "denoising_feature_strength");
- params.relative_pca = get_boolean(cviewlayer, "denoising_relative_pca");
- params.neighbor_frames = get_int(cviewlayer, "denoising_neighbor_frames");
-
- /* Parse file paths list. */
- vector<string> input, output;
-
- if(!image_parse_filepaths(pyinput, input)) {
- return NULL;
- }
-
- if(pyoutput) {
- if(!image_parse_filepaths(pyoutput, output)) {
- return NULL;
- }
- }
- else {
- output = input;
- }
-
- if(input.empty()) {
- PyErr_SetString(PyExc_ValueError, "No input file paths specified.");
- return NULL;
- }
- if(input.size() != output.size()) {
- PyErr_SetString(PyExc_ValueError, "Number of input and output file paths does not match.");
- return NULL;
- }
-
- /* Create denoiser. */
- Denoiser denoiser(device);
- denoiser.params = params;
- denoiser.input = input;
- denoiser.output = output;
-
- if (tile_size > 0) {
- denoiser.tile_size = make_int2(tile_size, tile_size);
- }
- if (samples > 0) {
- denoiser.samples_override = samples;
- }
-
- /* Run denoiser. */
- if(!denoiser.run()) {
- PyErr_SetString(PyExc_ValueError, denoiser.error.c_str());
- return NULL;
- }
-
- Py_RETURN_NONE;
+ static const char *keyword_list[] = {
+ "preferences", "scene", "view_layer", "input", "output", "tile_size", "samples", NULL};
+ PyObject *pypreferences, *pyscene, *pyviewlayer;
+ PyObject *pyinput, *pyoutput = NULL;
+ int tile_size = 0, samples = 0;
+
+ if (!PyArg_ParseTupleAndKeywords(args,
+ keywords,
+ "OOOO|Oii",
+ (char **)keyword_list,
+ &pypreferences,
+ &pyscene,
+ &pyviewlayer,
+ &pyinput,
+ &pyoutput,
+ &tile_size,
+ &samples)) {
+ return NULL;
+ }
+
+ /* Get device specification from preferences and scene. */
+ PointerRNA preferencesptr;
+ RNA_pointer_create(
+ NULL, &RNA_Preferences, (void *)PyLong_AsVoidPtr(pypreferences), &preferencesptr);
+ BL::Preferences b_preferences(preferencesptr);
+
+ PointerRNA sceneptr;
+ RNA_id_pointer_create((ID *)PyLong_AsVoidPtr(pyscene), &sceneptr);
+ BL::Scene b_scene(sceneptr);
+
+ DeviceInfo device = blender_device_info(b_preferences, b_scene, true);
+
+ /* Get denoising parameters from view layer. */
+ PointerRNA viewlayerptr;
+ RNA_pointer_create((ID *)PyLong_AsVoidPtr(pyscene),
+ &RNA_ViewLayer,
+ PyLong_AsVoidPtr(pyviewlayer),
+ &viewlayerptr);
+ PointerRNA cviewlayer = RNA_pointer_get(&viewlayerptr, "cycles");
+
+ DenoiseParams params;
+ params.radius = get_int(cviewlayer, "denoising_radius");
+ params.strength = get_float(cviewlayer, "denoising_strength");
+ params.feature_strength = get_float(cviewlayer, "denoising_feature_strength");
+ params.relative_pca = get_boolean(cviewlayer, "denoising_relative_pca");
+ params.neighbor_frames = get_int(cviewlayer, "denoising_neighbor_frames");
+
+ /* Parse file paths list. */
+ vector<string> input, output;
+
+ if (!image_parse_filepaths(pyinput, input)) {
+ return NULL;
+ }
+
+ if (pyoutput) {
+ if (!image_parse_filepaths(pyoutput, output)) {
+ return NULL;
+ }
+ }
+ else {
+ output = input;
+ }
+
+ if (input.empty()) {
+ PyErr_SetString(PyExc_ValueError, "No input file paths specified.");
+ return NULL;
+ }
+ if (input.size() != output.size()) {
+ PyErr_SetString(PyExc_ValueError, "Number of input and output file paths does not match.");
+ return NULL;
+ }
+
+ /* Create denoiser. */
+ Denoiser denoiser(device);
+ denoiser.params = params;
+ denoiser.input = input;
+ denoiser.output = output;
+
+ if (tile_size > 0) {
+ denoiser.tile_size = make_int2(tile_size, tile_size);
+ }
+ if (samples > 0) {
+ denoiser.samples_override = samples;
+ }
+
+ /* Run denoiser. */
+ if (!denoiser.run()) {
+ PyErr_SetString(PyExc_ValueError, denoiser.error.c_str());
+ return NULL;
+ }
+
+ Py_RETURN_NONE;
}
static PyObject *merge_func(PyObject * /*self*/, PyObject *args, PyObject *keywords)
{
- static const char *keyword_list[] = {"input", "output", NULL};
- PyObject *pyinput, *pyoutput = NULL;
-
- if (!PyArg_ParseTupleAndKeywords(args, keywords, "OO", (char**)keyword_list, &pyinput, &pyoutput)) {
- return NULL;
- }
-
- /* Parse input list. */
- vector<string> input;
- if(!image_parse_filepaths(pyinput, input)) {
- return NULL;
- }
-
- /* Parse output string. */
- if(!PyUnicode_Check(pyoutput)) {
- PyErr_SetString(PyExc_ValueError, "Output must be a string.");
- return NULL;
- }
- string output = PyUnicode_AsUTF8(pyoutput);
-
- /* Merge. */
- ImageMerger merger;
- merger.input = input;
- merger.output = output;
-
- if(!merger.run()) {
- PyErr_SetString(PyExc_ValueError, merger.error.c_str());
- return NULL;
- }
-
- Py_RETURN_NONE;
+ static const char *keyword_list[] = {"input", "output", NULL};
+ PyObject *pyinput, *pyoutput = NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(
+ args, keywords, "OO", (char **)keyword_list, &pyinput, &pyoutput)) {
+ return NULL;
+ }
+
+ /* Parse input list. */
+ vector<string> input;
+ if (!image_parse_filepaths(pyinput, input)) {
+ return NULL;
+ }
+
+ /* Parse output string. */
+ if (!PyUnicode_Check(pyoutput)) {
+ PyErr_SetString(PyExc_ValueError, "Output must be a string.");
+ return NULL;
+ }
+ string output = PyUnicode_AsUTF8(pyoutput);
+
+ /* Merge. */
+ ImageMerger merger;
+ merger.input = input;
+ merger.output = output;
+
+ if (!merger.run()) {
+ PyErr_SetString(PyExc_ValueError, merger.error.c_str());
+ return NULL;
+ }
+
+ Py_RETURN_NONE;
}
-
static PyObject *debug_flags_update_func(PyObject * /*self*/, PyObject *args)
{
- PyObject *pyscene;
- if(!PyArg_ParseTuple(args, "O", &pyscene)) {
- return NULL;
- }
+ PyObject *pyscene;
+ if (!PyArg_ParseTuple(args, "O", &pyscene)) {
+ return NULL;
+ }
- PointerRNA sceneptr;
- RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyscene), &sceneptr);
- BL::Scene b_scene(sceneptr);
+ PointerRNA sceneptr;
+ RNA_id_pointer_create((ID *)PyLong_AsVoidPtr(pyscene), &sceneptr);
+ BL::Scene b_scene(sceneptr);
- if(debug_flags_sync_from_scene(b_scene)) {
- VLOG(2) << "Tagging device list for update.";
- Device::tag_update();
- }
+ if (debug_flags_sync_from_scene(b_scene)) {
+ VLOG(2) << "Tagging device list for update.";
+ Device::tag_update();
+ }
- VLOG(2) << "Debug flags set to:\n"
- << DebugFlags();
+ VLOG(2) << "Debug flags set to:\n" << DebugFlags();
- debug_flags_set = true;
+ debug_flags_set = true;
- Py_RETURN_NONE;
+ Py_RETURN_NONE;
}
static PyObject *debug_flags_reset_func(PyObject * /*self*/, PyObject * /*args*/)
{
- if(debug_flags_reset()) {
- VLOG(2) << "Tagging device list for update.";
- Device::tag_update();
- }
- if(debug_flags_set) {
- VLOG(2) << "Debug flags reset to:\n"
- << DebugFlags();
- debug_flags_set = false;
- }
- Py_RETURN_NONE;
+ if (debug_flags_reset()) {
+ VLOG(2) << "Tagging device list for update.";
+ Device::tag_update();
+ }
+ if (debug_flags_set) {
+ VLOG(2) << "Debug flags reset to:\n" << DebugFlags();
+ debug_flags_set = false;
+ }
+ Py_RETURN_NONE;
}
static PyObject *set_resumable_chunk_func(PyObject * /*self*/, PyObject *args)
{
- int num_resumable_chunks, current_resumable_chunk;
- if(!PyArg_ParseTuple(args, "ii",
- &num_resumable_chunks,
- &current_resumable_chunk)) {
- Py_RETURN_NONE;
- }
-
- if(num_resumable_chunks <= 0) {
- fprintf(stderr, "Cycles: Bad value for number of resumable chunks.\n");
- abort();
- Py_RETURN_NONE;
- }
- if(current_resumable_chunk < 1 ||
- current_resumable_chunk > num_resumable_chunks)
- {
- fprintf(stderr, "Cycles: Bad value for current resumable chunk number.\n");
- abort();
- Py_RETURN_NONE;
- }
-
- VLOG(1) << "Initialized resumable render: "
- << "num_resumable_chunks=" << num_resumable_chunks << ", "
- << "current_resumable_chunk=" << current_resumable_chunk;
- BlenderSession::num_resumable_chunks = num_resumable_chunks;
- BlenderSession::current_resumable_chunk = current_resumable_chunk;
-
- printf("Cycles: Will render chunk %d of %d\n",
- current_resumable_chunk,
- num_resumable_chunks);
-
- Py_RETURN_NONE;
+ int num_resumable_chunks, current_resumable_chunk;
+ if (!PyArg_ParseTuple(args, "ii", &num_resumable_chunks, &current_resumable_chunk)) {
+ Py_RETURN_NONE;
+ }
+
+ if (num_resumable_chunks <= 0) {
+ fprintf(stderr, "Cycles: Bad value for number of resumable chunks.\n");
+ abort();
+ Py_RETURN_NONE;
+ }
+ if (current_resumable_chunk < 1 || current_resumable_chunk > num_resumable_chunks) {
+ fprintf(stderr, "Cycles: Bad value for current resumable chunk number.\n");
+ abort();
+ Py_RETURN_NONE;
+ }
+
+ VLOG(1) << "Initialized resumable render: "
+ << "num_resumable_chunks=" << num_resumable_chunks << ", "
+ << "current_resumable_chunk=" << current_resumable_chunk;
+ BlenderSession::num_resumable_chunks = num_resumable_chunks;
+ BlenderSession::current_resumable_chunk = current_resumable_chunk;
+
+ printf("Cycles: Will render chunk %d of %d\n", current_resumable_chunk, num_resumable_chunks);
+
+ Py_RETURN_NONE;
}
static PyObject *set_resumable_chunk_range_func(PyObject * /*self*/, PyObject *args)
{
- int num_chunks, start_chunk, end_chunk;
- if(!PyArg_ParseTuple(args, "iii",
- &num_chunks,
- &start_chunk,
- &end_chunk)) {
- Py_RETURN_NONE;
- }
-
- if(num_chunks <= 0) {
- fprintf(stderr, "Cycles: Bad value for number of resumable chunks.\n");
- abort();
- Py_RETURN_NONE;
- }
- if(start_chunk < 1 || start_chunk > num_chunks) {
- fprintf(stderr, "Cycles: Bad value for start chunk number.\n");
- abort();
- Py_RETURN_NONE;
- }
- if(end_chunk < 1 || end_chunk > num_chunks) {
- fprintf(stderr, "Cycles: Bad value for start chunk number.\n");
- abort();
- Py_RETURN_NONE;
- }
- if(start_chunk > end_chunk) {
- fprintf(stderr, "Cycles: End chunk should be higher than start one.\n");
- abort();
- Py_RETURN_NONE;
- }
-
- VLOG(1) << "Initialized resumable render: "
- << "num_resumable_chunks=" << num_chunks << ", "
- << "start_resumable_chunk=" << start_chunk
- << "end_resumable_chunk=" << end_chunk;
- BlenderSession::num_resumable_chunks = num_chunks;
- BlenderSession::start_resumable_chunk = start_chunk;
- BlenderSession::end_resumable_chunk = end_chunk;
-
- printf("Cycles: Will render chunks %d to %d of %d\n",
- start_chunk,
- end_chunk,
- num_chunks);
-
- Py_RETURN_NONE;
+ int num_chunks, start_chunk, end_chunk;
+ if (!PyArg_ParseTuple(args, "iii", &num_chunks, &start_chunk, &end_chunk)) {
+ Py_RETURN_NONE;
+ }
+
+ if (num_chunks <= 0) {
+ fprintf(stderr, "Cycles: Bad value for number of resumable chunks.\n");
+ abort();
+ Py_RETURN_NONE;
+ }
+ if (start_chunk < 1 || start_chunk > num_chunks) {
+ fprintf(stderr, "Cycles: Bad value for start chunk number.\n");
+ abort();
+ Py_RETURN_NONE;
+ }
+ if (end_chunk < 1 || end_chunk > num_chunks) {
+ fprintf(stderr, "Cycles: Bad value for start chunk number.\n");
+ abort();
+ Py_RETURN_NONE;
+ }
+ if (start_chunk > end_chunk) {
+ fprintf(stderr, "Cycles: End chunk should be higher than start one.\n");
+ abort();
+ Py_RETURN_NONE;
+ }
+
+ VLOG(1) << "Initialized resumable render: "
+ << "num_resumable_chunks=" << num_chunks << ", "
+ << "start_resumable_chunk=" << start_chunk << "end_resumable_chunk=" << end_chunk;
+ BlenderSession::num_resumable_chunks = num_chunks;
+ BlenderSession::start_resumable_chunk = start_chunk;
+ BlenderSession::end_resumable_chunk = end_chunk;
+
+ printf("Cycles: Will render chunks %d to %d of %d\n", start_chunk, end_chunk, num_chunks);
+
+ Py_RETURN_NONE;
}
static PyObject *enable_print_stats_func(PyObject * /*self*/, PyObject * /*args*/)
{
- BlenderSession::print_render_stats = true;
- Py_RETURN_NONE;
+ BlenderSession::print_render_stats = true;
+ Py_RETURN_NONE;
}
static PyObject *get_device_types_func(PyObject * /*self*/, PyObject * /*args*/)
{
- vector<DeviceType> device_types = Device::available_types();
- bool has_cuda = false, has_opencl = false;
- foreach(DeviceType device_type, device_types) {
- has_cuda |= (device_type == DEVICE_CUDA);
- has_opencl |= (device_type == DEVICE_OPENCL);
- }
- PyObject *list = PyTuple_New(2);
- PyTuple_SET_ITEM(list, 0, PyBool_FromLong(has_cuda));
- PyTuple_SET_ITEM(list, 1, PyBool_FromLong(has_opencl));
- return list;
+ vector<DeviceType> device_types = Device::available_types();
+ bool has_cuda = false, has_opencl = false;
+ foreach (DeviceType device_type, device_types) {
+ has_cuda |= (device_type == DEVICE_CUDA);
+ has_opencl |= (device_type == DEVICE_OPENCL);
+ }
+ PyObject *list = PyTuple_New(2);
+ PyTuple_SET_ITEM(list, 0, PyBool_FromLong(has_cuda));
+ PyTuple_SET_ITEM(list, 1, PyBool_FromLong(has_opencl));
+ return list;
}
static PyMethodDef methods[] = {
- {"init", init_func, METH_VARARGS, ""},
- {"exit", exit_func, METH_VARARGS, ""},
- {"create", create_func, METH_VARARGS, ""},
- {"free", free_func, METH_O, ""},
- {"render", render_func, METH_VARARGS, ""},
- {"bake", bake_func, METH_VARARGS, ""},
- {"draw", draw_func, METH_VARARGS, ""},
- {"sync", sync_func, METH_VARARGS, ""},
- {"reset", reset_func, METH_VARARGS, ""},
+ {"init", init_func, METH_VARARGS, ""},
+ {"exit", exit_func, METH_VARARGS, ""},
+ {"create", create_func, METH_VARARGS, ""},
+ {"free", free_func, METH_O, ""},
+ {"render", render_func, METH_VARARGS, ""},
+ {"bake", bake_func, METH_VARARGS, ""},
+ {"draw", draw_func, METH_VARARGS, ""},
+ {"sync", sync_func, METH_VARARGS, ""},
+ {"reset", reset_func, METH_VARARGS, ""},
#ifdef WITH_OSL
- {"osl_update_node", osl_update_node_func, METH_VARARGS, ""},
- {"osl_compile", osl_compile_func, METH_VARARGS, ""},
+ {"osl_update_node", osl_update_node_func, METH_VARARGS, ""},
+ {"osl_compile", osl_compile_func, METH_VARARGS, ""},
#endif
- {"available_devices", available_devices_func, METH_VARARGS, ""},
- {"system_info", system_info_func, METH_NOARGS, ""},
+ {"available_devices", available_devices_func, METH_VARARGS, ""},
+ {"system_info", system_info_func, METH_NOARGS, ""},
#ifdef WITH_OPENCL
- {"opencl_disable", opencl_disable_func, METH_NOARGS, ""},
- {"opencl_compile", opencl_compile_func, METH_VARARGS, ""},
+ {"opencl_disable", opencl_disable_func, METH_NOARGS, ""},
+ {"opencl_compile", opencl_compile_func, METH_VARARGS, ""},
#endif
- /* Standalone denoising */
- {"denoise", (PyCFunction)denoise_func, METH_VARARGS|METH_KEYWORDS, ""},
- {"merge", (PyCFunction)merge_func, METH_VARARGS|METH_KEYWORDS, ""},
+ /* Standalone denoising */
+ {"denoise", (PyCFunction)denoise_func, METH_VARARGS | METH_KEYWORDS, ""},
+ {"merge", (PyCFunction)merge_func, METH_VARARGS | METH_KEYWORDS, ""},
- /* Debugging routines */
- {"debug_flags_update", debug_flags_update_func, METH_VARARGS, ""},
- {"debug_flags_reset", debug_flags_reset_func, METH_NOARGS, ""},
+ /* Debugging routines */
+ {"debug_flags_update", debug_flags_update_func, METH_VARARGS, ""},
+ {"debug_flags_reset", debug_flags_reset_func, METH_NOARGS, ""},
- /* Statistics. */
- {"enable_print_stats", enable_print_stats_func, METH_NOARGS, ""},
+ /* Statistics. */
+ {"enable_print_stats", enable_print_stats_func, METH_NOARGS, ""},
- /* Resumable render */
- {"set_resumable_chunk", set_resumable_chunk_func, METH_VARARGS, ""},
- {"set_resumable_chunk_range", set_resumable_chunk_range_func, METH_VARARGS, ""},
+ /* Resumable render */
+ {"set_resumable_chunk", set_resumable_chunk_func, METH_VARARGS, ""},
+ {"set_resumable_chunk_range", set_resumable_chunk_range_func, METH_VARARGS, ""},
- /* Compute Device selection */
- {"get_device_types", get_device_types_func, METH_VARARGS, ""},
+ /* Compute Device selection */
+ {"get_device_types", get_device_types_func, METH_VARARGS, ""},
- {NULL, NULL, 0, NULL},
+ {NULL, NULL, 0, NULL},
};
static struct PyModuleDef module = {
- PyModuleDef_HEAD_INIT,
- "_cycles",
- "Blender cycles render integration",
- -1,
- methods,
- NULL, NULL, NULL, NULL,
+ PyModuleDef_HEAD_INIT,
+ "_cycles",
+ "Blender cycles render integration",
+ -1,
+ methods,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
};
CCL_NAMESPACE_END
void *CCL_python_module_init()
{
- PyObject *mod = PyModule_Create(&ccl::module);
+ PyObject *mod = PyModule_Create(&ccl::module);
#ifdef WITH_OSL
- /* TODO(sergey): This gives us library we've been linking against.
- * In theory with dynamic OSL library it might not be
- * accurate, but there's nothing in OSL API which we
- * might use to get version in runtime.
- */
- int curversion = OSL_LIBRARY_VERSION_CODE;
- PyModule_AddObject(mod, "with_osl", Py_True);
- Py_INCREF(Py_True);
- PyModule_AddObject(mod, "osl_version",
- Py_BuildValue("(iii)",
- curversion / 10000, (curversion / 100) % 100, curversion % 100));
- PyModule_AddObject(mod, "osl_version_string",
- PyUnicode_FromFormat("%2d, %2d, %2d",
- curversion / 10000, (curversion / 100) % 100, curversion % 100));
+ /* TODO(sergey): This gives us library we've been linking against.
+ * In theory with dynamic OSL library it might not be
+ * accurate, but there's nothing in OSL API which we
+ * might use to get version in runtime.
+ */
+ int curversion = OSL_LIBRARY_VERSION_CODE;
+ PyModule_AddObject(mod, "with_osl", Py_True);
+ Py_INCREF(Py_True);
+ PyModule_AddObject(
+ mod,
+ "osl_version",
+ Py_BuildValue("(iii)", curversion / 10000, (curversion / 100) % 100, curversion % 100));
+ PyModule_AddObject(
+ mod,
+ "osl_version_string",
+ PyUnicode_FromFormat(
+ "%2d, %2d, %2d", curversion / 10000, (curversion / 100) % 100, curversion % 100));
#else
- PyModule_AddObject(mod, "with_osl", Py_False);
- Py_INCREF(Py_False);
- PyModule_AddStringConstant(mod, "osl_version", "unknown");
- PyModule_AddStringConstant(mod, "osl_version_string", "unknown");
+ PyModule_AddObject(mod, "with_osl", Py_False);
+ Py_INCREF(Py_False);
+ PyModule_AddStringConstant(mod, "osl_version", "unknown");
+ PyModule_AddStringConstant(mod, "osl_version_string", "unknown");
#endif
#ifdef WITH_CYCLES_DEBUG
- PyModule_AddObject(mod, "with_cycles_debug", Py_True);
- Py_INCREF(Py_True);
+ PyModule_AddObject(mod, "with_cycles_debug", Py_True);
+ Py_INCREF(Py_True);
#else
- PyModule_AddObject(mod, "with_cycles_debug", Py_False);
- Py_INCREF(Py_False);
+ PyModule_AddObject(mod, "with_cycles_debug", Py_False);
+ Py_INCREF(Py_False);
#endif
#ifdef WITH_NETWORK
- PyModule_AddObject(mod, "with_network", Py_True);
- Py_INCREF(Py_True);
+ PyModule_AddObject(mod, "with_network", Py_True);
+ Py_INCREF(Py_True);
#else /* WITH_NETWORK */
- PyModule_AddObject(mod, "with_network", Py_False);
- Py_INCREF(Py_False);
-#endif /* WITH_NETWORK */
+ PyModule_AddObject(mod, "with_network", Py_False);
+ Py_INCREF(Py_False);
+#endif /* WITH_NETWORK */
#ifdef WITH_EMBREE
- PyModule_AddObject(mod, "with_embree", Py_True);
- Py_INCREF(Py_True);
+ PyModule_AddObject(mod, "with_embree", Py_True);
+ Py_INCREF(Py_True);
#else /* WITH_EMBREE */
- PyModule_AddObject(mod, "with_embree", Py_False);
- Py_INCREF(Py_False);
-#endif /* WITH_EMBREE */
+ PyModule_AddObject(mod, "with_embree", Py_False);
+ Py_INCREF(Py_False);
+#endif /* WITH_EMBREE */
- return (void*)mod;
+ return (void *)mod;
}
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index cf856c3b3d4..29a97bf6546 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -53,1051 +53,1070 @@ int BlenderSession::start_resumable_chunk = 0;
int BlenderSession::end_resumable_chunk = 0;
bool BlenderSession::print_render_stats = false;
-BlenderSession::BlenderSession(BL::RenderEngine& b_engine,
- BL::Preferences& b_userpref,
- BL::BlendData& b_data,
+BlenderSession::BlenderSession(BL::RenderEngine &b_engine,
+ BL::Preferences &b_userpref,
+ BL::BlendData &b_data,
bool preview_osl)
-: session(NULL),
- sync(NULL),
- b_engine(b_engine),
- b_userpref(b_userpref),
- b_data(b_data),
- b_render(b_engine.render()),
- b_depsgraph(PointerRNA_NULL),
- b_scene(PointerRNA_NULL),
- b_v3d(PointerRNA_NULL),
- b_rv3d(PointerRNA_NULL),
- width(0),
- height(0),
- preview_osl(preview_osl),
- python_thread_state(NULL)
+ : session(NULL),
+ sync(NULL),
+ b_engine(b_engine),
+ b_userpref(b_userpref),
+ b_data(b_data),
+ b_render(b_engine.render()),
+ b_depsgraph(PointerRNA_NULL),
+ b_scene(PointerRNA_NULL),
+ b_v3d(PointerRNA_NULL),
+ b_rv3d(PointerRNA_NULL),
+ width(0),
+ height(0),
+ preview_osl(preview_osl),
+ python_thread_state(NULL)
{
- /* offline render */
- background = true;
- last_redraw_time = 0.0;
- start_resize_time = 0.0;
- last_status_time = 0.0;
+ /* offline render */
+ background = true;
+ last_redraw_time = 0.0;
+ start_resize_time = 0.0;
+ last_status_time = 0.0;
}
-BlenderSession::BlenderSession(BL::RenderEngine& b_engine,
- BL::Preferences& b_userpref,
- BL::BlendData& b_data,
- BL::SpaceView3D& b_v3d,
- BL::RegionView3D& b_rv3d,
- int width, int height)
-: session(NULL),
- sync(NULL),
- b_engine(b_engine),
- b_userpref(b_userpref),
- b_data(b_data),
- b_render(b_engine.render()),
- b_depsgraph(PointerRNA_NULL),
- b_scene(PointerRNA_NULL),
- b_v3d(b_v3d),
- b_rv3d(b_rv3d),
- width(width),
- height(height),
- preview_osl(false),
- python_thread_state(NULL)
+BlenderSession::BlenderSession(BL::RenderEngine &b_engine,
+ BL::Preferences &b_userpref,
+ BL::BlendData &b_data,
+ BL::SpaceView3D &b_v3d,
+ BL::RegionView3D &b_rv3d,
+ int width,
+ int height)
+ : session(NULL),
+ sync(NULL),
+ b_engine(b_engine),
+ b_userpref(b_userpref),
+ b_data(b_data),
+ b_render(b_engine.render()),
+ b_depsgraph(PointerRNA_NULL),
+ b_scene(PointerRNA_NULL),
+ b_v3d(b_v3d),
+ b_rv3d(b_rv3d),
+ width(width),
+ height(height),
+ preview_osl(false),
+ python_thread_state(NULL)
{
- /* 3d view render */
- background = false;
- last_redraw_time = 0.0;
- start_resize_time = 0.0;
- last_status_time = 0.0;
+ /* 3d view render */
+ background = false;
+ last_redraw_time = 0.0;
+ start_resize_time = 0.0;
+ last_status_time = 0.0;
}
BlenderSession::~BlenderSession()
{
- free_session();
+ free_session();
}
void BlenderSession::create()
{
- create_session();
+ create_session();
}
void BlenderSession::create_session()
{
- SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
- SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
- bool session_pause = BlenderSync::get_session_pause(b_scene, background);
-
- /* reset status/progress */
- last_status = "";
- last_error = "";
- last_progress = -1.0f;
- start_resize_time = 0.0;
-
- /* create session */
- session = new Session(session_params);
- 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(session_pause);
-
- /* create scene */
- scene = new Scene(scene_params, session->device);
- scene->name = b_scene.name();
-
- /* setup callbacks for builtin image support */
- scene->image_manager->builtin_image_info_cb = function_bind(&BlenderSession::builtin_image_info, this, _1, _2, _3);
- scene->image_manager->builtin_image_pixels_cb = function_bind(&BlenderSession::builtin_image_pixels, this, _1, _2, _3, _4, _5);
- scene->image_manager->builtin_image_float_pixels_cb = function_bind(&BlenderSession::builtin_image_float_pixels, this, _1, _2, _3, _4, _5);
-
- session->scene = scene;
-
- /* There is no single depsgraph to use for the entire render.
- * So we need to handle this differently.
- *
- * We could loop over the final render result render layers in pipeline and keep Cycles unaware of multiple layers,
- * or perhaps move syncing further down in the pipeline.
- */
- /* create sync */
- sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress);
- BL::Object b_camera_override(b_engine.camera_override());
- if(b_v3d) {
- sync->sync_view(b_v3d, b_rv3d, width, height);
- }
- else {
- sync->sync_camera(b_render, b_camera_override, width, height, "");
- }
-
- /* set buffer parameters */
- BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_v3d, b_rv3d, scene->camera, width, height);
- session->reset(buffer_params, session_params.samples);
-
- b_engine.use_highlight_tiles(session_params.progressive_refine == false);
-
- update_resumable_tile_manager(session_params.samples);
+ SessionParams session_params = BlenderSync::get_session_params(
+ b_engine, b_userpref, b_scene, background);
+ SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
+ bool session_pause = BlenderSync::get_session_pause(b_scene, background);
+
+ /* reset status/progress */
+ last_status = "";
+ last_error = "";
+ last_progress = -1.0f;
+ start_resize_time = 0.0;
+
+ /* create session */
+ session = new Session(session_params);
+ 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(session_pause);
+
+ /* create scene */
+ scene = new Scene(scene_params, session->device);
+ scene->name = b_scene.name();
+
+ /* setup callbacks for builtin image support */
+ scene->image_manager->builtin_image_info_cb = function_bind(
+ &BlenderSession::builtin_image_info, this, _1, _2, _3);
+ scene->image_manager->builtin_image_pixels_cb = function_bind(
+ &BlenderSession::builtin_image_pixels, this, _1, _2, _3, _4, _5);
+ scene->image_manager->builtin_image_float_pixels_cb = function_bind(
+ &BlenderSession::builtin_image_float_pixels, this, _1, _2, _3, _4, _5);
+
+ session->scene = scene;
+
+ /* There is no single depsgraph to use for the entire render.
+ * So we need to handle this differently.
+ *
+ * We could loop over the final render result render layers in pipeline and keep Cycles unaware of multiple layers,
+ * or perhaps move syncing further down in the pipeline.
+ */
+ /* create sync */
+ sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress);
+ BL::Object b_camera_override(b_engine.camera_override());
+ if (b_v3d) {
+ sync->sync_view(b_v3d, b_rv3d, width, height);
+ }
+ else {
+ sync->sync_camera(b_render, b_camera_override, width, height, "");
+ }
+
+ /* set buffer parameters */
+ BufferParams buffer_params = BlenderSync::get_buffer_params(
+ b_render, b_v3d, b_rv3d, scene->camera, width, height);
+ session->reset(buffer_params, session_params.samples);
+
+ b_engine.use_highlight_tiles(session_params.progressive_refine == false);
+
+ update_resumable_tile_manager(session_params.samples);
}
-void BlenderSession::reset_session(BL::BlendData& b_data, BL::Depsgraph& b_depsgraph)
+void BlenderSession::reset_session(BL::BlendData &b_data, BL::Depsgraph &b_depsgraph)
{
- this->b_data = b_data;
- this->b_depsgraph = b_depsgraph;
- this->b_scene = b_depsgraph.scene_eval();
-
- if(preview_osl) {
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
- RNA_boolean_set(&cscene, "shading_system", preview_osl);
- }
-
- if(b_v3d) {
- this->b_render = b_scene.render();
- }
- else {
- this->b_render = b_engine.render();
- width = render_resolution_x(b_render);
- height = render_resolution_y(b_render);
- }
-
- if(session == NULL) {
- create();
- }
-
- if(b_v3d) {
- /* NOTE: We need to create session, but all the code from below
- * will make viewport render to stuck on initialization.
- */
- return;
- }
-
- SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
- SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
-
- if(scene->params.modified(scene_params) ||
- session->params.modified(session_params) ||
- !scene_params.persistent_data)
- {
- /* if scene or session parameters changed, it's easier to simply re-create
- * them rather than trying to distinguish which settings need to be updated
- */
- free_session();
- create_session();
- return;
- }
-
- session->progress.reset();
- scene->reset();
-
- session->tile_manager.set_tile_order(session_params.tile_order);
-
- /* peak memory usage should show current render peak, not peak for all renders
- * made by this render session
- */
- session->stats.mem_peak = session->stats.mem_used;
-
- /* There is no single depsgraph to use for the entire render.
- * See note on create_session().
- */
- /* sync object should be re-created */
- sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress);
-
- BL::SpaceView3D b_null_space_view3d(PointerRNA_NULL);
- BL::RegionView3D b_null_region_view3d(PointerRNA_NULL);
- BufferParams buffer_params = BlenderSync::get_buffer_params(b_render,
- b_null_space_view3d,
- b_null_region_view3d,
- scene->camera,
- width, height);
- session->reset(buffer_params, session_params.samples);
-
- b_engine.use_highlight_tiles(session_params.progressive_refine == false);
-
- /* reset time */
- start_resize_time = 0.0;
+ this->b_data = b_data;
+ this->b_depsgraph = b_depsgraph;
+ this->b_scene = b_depsgraph.scene_eval();
+
+ if (preview_osl) {
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+ RNA_boolean_set(&cscene, "shading_system", preview_osl);
+ }
+
+ if (b_v3d) {
+ this->b_render = b_scene.render();
+ }
+ else {
+ this->b_render = b_engine.render();
+ width = render_resolution_x(b_render);
+ height = render_resolution_y(b_render);
+ }
+
+ if (session == NULL) {
+ create();
+ }
+
+ if (b_v3d) {
+ /* NOTE: We need to create session, but all the code from below
+ * will make viewport render to stuck on initialization.
+ */
+ return;
+ }
+
+ SessionParams session_params = BlenderSync::get_session_params(
+ b_engine, b_userpref, b_scene, background);
+ SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
+
+ if (scene->params.modified(scene_params) || session->params.modified(session_params) ||
+ !scene_params.persistent_data) {
+ /* if scene or session parameters changed, it's easier to simply re-create
+ * them rather than trying to distinguish which settings need to be updated
+ */
+ free_session();
+ create_session();
+ return;
+ }
+
+ session->progress.reset();
+ scene->reset();
+
+ session->tile_manager.set_tile_order(session_params.tile_order);
+
+ /* peak memory usage should show current render peak, not peak for all renders
+ * made by this render session
+ */
+ session->stats.mem_peak = session->stats.mem_used;
+
+ /* There is no single depsgraph to use for the entire render.
+ * See note on create_session().
+ */
+ /* sync object should be re-created */
+ sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress);
+
+ BL::SpaceView3D b_null_space_view3d(PointerRNA_NULL);
+ BL::RegionView3D b_null_region_view3d(PointerRNA_NULL);
+ BufferParams buffer_params = BlenderSync::get_buffer_params(
+ b_render, b_null_space_view3d, b_null_region_view3d, scene->camera, width, height);
+ session->reset(buffer_params, session_params.samples);
+
+ b_engine.use_highlight_tiles(session_params.progressive_refine == false);
+
+ /* reset time */
+ start_resize_time = 0.0;
}
void BlenderSession::free_session()
{
- if(sync)
- delete sync;
+ if (sync)
+ delete sync;
- delete session;
+ delete session;
}
-static ShaderEvalType get_shader_type(const string& pass_type)
+static ShaderEvalType get_shader_type(const string &pass_type)
{
- const char *shader_type = pass_type.c_str();
-
- /* data passes */
- if(strcmp(shader_type, "NORMAL")==0)
- return SHADER_EVAL_NORMAL;
- else if(strcmp(shader_type, "UV")==0)
- return SHADER_EVAL_UV;
- else if(strcmp(shader_type, "ROUGHNESS")==0)
- return SHADER_EVAL_ROUGHNESS;
- else if(strcmp(shader_type, "DIFFUSE_COLOR")==0)
- return SHADER_EVAL_DIFFUSE_COLOR;
- else if(strcmp(shader_type, "GLOSSY_COLOR")==0)
- return SHADER_EVAL_GLOSSY_COLOR;
- else if(strcmp(shader_type, "TRANSMISSION_COLOR")==0)
- return SHADER_EVAL_TRANSMISSION_COLOR;
- else if(strcmp(shader_type, "SUBSURFACE_COLOR")==0)
- return SHADER_EVAL_SUBSURFACE_COLOR;
- else if(strcmp(shader_type, "EMIT")==0)
- return SHADER_EVAL_EMISSION;
-
- /* light passes */
- else if(strcmp(shader_type, "AO")==0)
- return SHADER_EVAL_AO;
- else if(strcmp(shader_type, "COMBINED")==0)
- return SHADER_EVAL_COMBINED;
- else if(strcmp(shader_type, "SHADOW")==0)
- return SHADER_EVAL_SHADOW;
- else if(strcmp(shader_type, "DIFFUSE")==0)
- return SHADER_EVAL_DIFFUSE;
- else if(strcmp(shader_type, "GLOSSY")==0)
- return SHADER_EVAL_GLOSSY;
- else if(strcmp(shader_type, "TRANSMISSION")==0)
- return SHADER_EVAL_TRANSMISSION;
- else if(strcmp(shader_type, "SUBSURFACE")==0)
- return SHADER_EVAL_SUBSURFACE;
-
- /* extra */
- else if(strcmp(shader_type, "ENVIRONMENT")==0)
- return SHADER_EVAL_ENVIRONMENT;
-
- else
- return SHADER_EVAL_BAKE;
+ const char *shader_type = pass_type.c_str();
+
+ /* data passes */
+ if (strcmp(shader_type, "NORMAL") == 0)
+ return SHADER_EVAL_NORMAL;
+ else if (strcmp(shader_type, "UV") == 0)
+ return SHADER_EVAL_UV;
+ else if (strcmp(shader_type, "ROUGHNESS") == 0)
+ return SHADER_EVAL_ROUGHNESS;
+ else if (strcmp(shader_type, "DIFFUSE_COLOR") == 0)
+ return SHADER_EVAL_DIFFUSE_COLOR;
+ else if (strcmp(shader_type, "GLOSSY_COLOR") == 0)
+ return SHADER_EVAL_GLOSSY_COLOR;
+ else if (strcmp(shader_type, "TRANSMISSION_COLOR") == 0)
+ return SHADER_EVAL_TRANSMISSION_COLOR;
+ else if (strcmp(shader_type, "SUBSURFACE_COLOR") == 0)
+ return SHADER_EVAL_SUBSURFACE_COLOR;
+ else if (strcmp(shader_type, "EMIT") == 0)
+ return SHADER_EVAL_EMISSION;
+
+ /* light passes */
+ else if (strcmp(shader_type, "AO") == 0)
+ return SHADER_EVAL_AO;
+ else if (strcmp(shader_type, "COMBINED") == 0)
+ return SHADER_EVAL_COMBINED;
+ else if (strcmp(shader_type, "SHADOW") == 0)
+ return SHADER_EVAL_SHADOW;
+ else if (strcmp(shader_type, "DIFFUSE") == 0)
+ return SHADER_EVAL_DIFFUSE;
+ else if (strcmp(shader_type, "GLOSSY") == 0)
+ return SHADER_EVAL_GLOSSY;
+ else if (strcmp(shader_type, "TRANSMISSION") == 0)
+ return SHADER_EVAL_TRANSMISSION;
+ else if (strcmp(shader_type, "SUBSURFACE") == 0)
+ return SHADER_EVAL_SUBSURFACE;
+
+ /* extra */
+ else if (strcmp(shader_type, "ENVIRONMENT") == 0)
+ return SHADER_EVAL_ENVIRONMENT;
+
+ else
+ return SHADER_EVAL_BAKE;
}
-static BL::RenderResult begin_render_result(BL::RenderEngine& b_engine,
- int x, int y,
- int w, int h,
+static BL::RenderResult begin_render_result(BL::RenderEngine &b_engine,
+ int x,
+ int y,
+ int w,
+ int h,
const char *layername,
const char *viewname)
{
- return b_engine.begin_result(x, y, w, h, layername, viewname);
+ return b_engine.begin_result(x, y, w, h, layername, viewname);
}
-static void end_render_result(BL::RenderEngine& b_engine,
- BL::RenderResult& b_rr,
+static void end_render_result(BL::RenderEngine &b_engine,
+ BL::RenderResult &b_rr,
bool cancel,
bool highlight,
bool do_merge_results)
{
- b_engine.end_result(b_rr, (int)cancel, (int) highlight, (int)do_merge_results);
+ b_engine.end_result(b_rr, (int)cancel, (int)highlight, (int)do_merge_results);
}
-void BlenderSession::do_write_update_render_tile(RenderTile& rtile, bool do_update_only, bool highlight)
+void BlenderSession::do_write_update_render_tile(RenderTile &rtile,
+ bool do_update_only,
+ bool highlight)
{
- int x = rtile.x - session->tile_manager.params.full_x;
- int y = rtile.y - session->tile_manager.params.full_y;
- int w = rtile.w;
- int h = rtile.h;
-
- /* get render result */
- BL::RenderResult b_rr = begin_render_result(b_engine, x, y, w, h, b_rlay_name.c_str(), b_rview_name.c_str());
-
- /* can happen if the intersected rectangle gives 0 width or height */
- if(b_rr.ptr.data == NULL) {
- return;
- }
-
- BL::RenderResult::layers_iterator b_single_rlay;
- b_rr.layers.begin(b_single_rlay);
-
- /* layer will be missing if it was disabled in the UI */
- if(b_single_rlay == b_rr.layers.end())
- return;
-
- BL::RenderLayer b_rlay = *b_single_rlay;
-
- if(do_update_only) {
- /* Sample would be zero at initial tile update, which is only needed
- * to tag tile form blender side as IN PROGRESS for proper highlight
- * no buffers should be sent to blender yet. For denoise we also
- * keep showing the noisy buffers until denoise is done. */
- bool merge = (rtile.sample != 0) && (rtile.task != RenderTile::DENOISE);
-
- if(merge) {
- update_render_result(b_rr, b_rlay, rtile);
- }
-
- end_render_result(b_engine, b_rr, true, highlight, merge);
- }
- else {
- /* Write final render result. */
- write_render_result(b_rr, b_rlay, rtile);
- end_render_result(b_engine, b_rr, false, false, true);
- }
+ int x = rtile.x - session->tile_manager.params.full_x;
+ int y = rtile.y - session->tile_manager.params.full_y;
+ int w = rtile.w;
+ int h = rtile.h;
+
+ /* get render result */
+ BL::RenderResult b_rr = begin_render_result(
+ b_engine, x, y, w, h, b_rlay_name.c_str(), b_rview_name.c_str());
+
+ /* can happen if the intersected rectangle gives 0 width or height */
+ if (b_rr.ptr.data == NULL) {
+ return;
+ }
+
+ BL::RenderResult::layers_iterator b_single_rlay;
+ b_rr.layers.begin(b_single_rlay);
+
+ /* layer will be missing if it was disabled in the UI */
+ if (b_single_rlay == b_rr.layers.end())
+ return;
+
+ BL::RenderLayer b_rlay = *b_single_rlay;
+
+ if (do_update_only) {
+ /* Sample would be zero at initial tile update, which is only needed
+ * to tag tile form blender side as IN PROGRESS for proper highlight
+ * no buffers should be sent to blender yet. For denoise we also
+ * keep showing the noisy buffers until denoise is done. */
+ bool merge = (rtile.sample != 0) && (rtile.task != RenderTile::DENOISE);
+
+ if (merge) {
+ update_render_result(b_rr, b_rlay, rtile);
+ }
+
+ end_render_result(b_engine, b_rr, true, highlight, merge);
+ }
+ else {
+ /* Write final render result. */
+ write_render_result(b_rr, b_rlay, rtile);
+ end_render_result(b_engine, b_rr, false, false, true);
+ }
}
-void BlenderSession::write_render_tile(RenderTile& rtile)
+void BlenderSession::write_render_tile(RenderTile &rtile)
{
- do_write_update_render_tile(rtile, false, false);
+ do_write_update_render_tile(rtile, false, false);
}
-void BlenderSession::update_render_tile(RenderTile& rtile, bool highlight)
+void BlenderSession::update_render_tile(RenderTile &rtile, bool highlight)
{
- /* use final write for preview renders, otherwise render result wouldn't be
- * be updated in blender side
- * would need to be investigated a bit further, but for now shall be fine
- */
- if(!b_engine.is_preview())
- do_write_update_render_tile(rtile, true, highlight);
- else
- do_write_update_render_tile(rtile, false, false);
+ /* use final write for preview renders, otherwise render result wouldn't be
+ * be updated in blender side
+ * would need to be investigated a bit further, but for now shall be fine
+ */
+ if (!b_engine.is_preview())
+ do_write_update_render_tile(rtile, true, highlight);
+ else
+ do_write_update_render_tile(rtile, false, false);
}
-static void add_cryptomatte_layer(BL::RenderResult& b_rr, string name, string manifest)
+static void add_cryptomatte_layer(BL::RenderResult &b_rr, string name, string manifest)
{
- string identifier = string_printf("%08x", util_murmur_hash3(name.c_str(), name.length(), 0));
- string prefix = "cryptomatte/" + identifier.substr(0, 7) + "/";
+ string identifier = string_printf("%08x", util_murmur_hash3(name.c_str(), name.length(), 0));
+ string prefix = "cryptomatte/" + identifier.substr(0, 7) + "/";
- render_add_metadata(b_rr, prefix+"name", name);
- render_add_metadata(b_rr, prefix+"hash", "MurmurHash3_32");
- render_add_metadata(b_rr, prefix+"conversion", "uint32_to_float32");
- render_add_metadata(b_rr, prefix+"manifest", manifest);
+ render_add_metadata(b_rr, prefix + "name", name);
+ render_add_metadata(b_rr, prefix + "hash", "MurmurHash3_32");
+ render_add_metadata(b_rr, prefix + "conversion", "uint32_to_float32");
+ render_add_metadata(b_rr, prefix + "manifest", manifest);
}
-void BlenderSession::stamp_view_layer_metadata(Scene *scene, const string& view_layer_name)
+void BlenderSession::stamp_view_layer_metadata(Scene *scene, const string &view_layer_name)
{
- BL::RenderResult b_rr = b_engine.get_result();
- string prefix = "cycles." + view_layer_name + ".";
-
- /* Configured number of samples for the view layer. */
- b_rr.stamp_data_add_field(
- (prefix + "samples").c_str(),
- to_string(session->params.samples).c_str());
-
- /* Store ranged samples information. */
- if(session->tile_manager.range_num_samples != -1) {
- b_rr.stamp_data_add_field(
- (prefix + "range_start_sample").c_str(),
- to_string(session->tile_manager.range_start_sample).c_str());
- b_rr.stamp_data_add_field(
- (prefix + "range_num_samples").c_str(),
- to_string(session->tile_manager.range_num_samples).c_str());
- }
-
- /* Write cryptomatte metadata. */
- if(scene->film->cryptomatte_passes & CRYPT_OBJECT) {
- add_cryptomatte_layer(b_rr, view_layer_name + ".CryptoObject",
- scene->object_manager->get_cryptomatte_objects(scene));
- }
- if(scene->film->cryptomatte_passes & CRYPT_MATERIAL) {
- add_cryptomatte_layer(b_rr, view_layer_name + ".CryptoMaterial",
- scene->shader_manager->get_cryptomatte_materials(scene));
- }
- if(scene->film->cryptomatte_passes & CRYPT_ASSET) {
- add_cryptomatte_layer(b_rr, view_layer_name + ".CryptoAsset",
- scene->object_manager->get_cryptomatte_assets(scene));
- }
-
- /* Store synchronization and bare-render times. */
- double total_time, render_time;
- session->progress.get_time(total_time, render_time);
- b_rr.stamp_data_add_field((prefix + "total_time").c_str(),
- time_human_readable_from_seconds(total_time).c_str());
- b_rr.stamp_data_add_field((prefix + "render_time").c_str(),
- time_human_readable_from_seconds(render_time).c_str());
- b_rr.stamp_data_add_field((prefix + "synchronization_time").c_str(),
- time_human_readable_from_seconds(total_time - render_time).c_str());
+ BL::RenderResult b_rr = b_engine.get_result();
+ string prefix = "cycles." + view_layer_name + ".";
+
+ /* Configured number of samples for the view layer. */
+ b_rr.stamp_data_add_field((prefix + "samples").c_str(),
+ to_string(session->params.samples).c_str());
+
+ /* Store ranged samples information. */
+ if (session->tile_manager.range_num_samples != -1) {
+ b_rr.stamp_data_add_field((prefix + "range_start_sample").c_str(),
+ to_string(session->tile_manager.range_start_sample).c_str());
+ b_rr.stamp_data_add_field((prefix + "range_num_samples").c_str(),
+ to_string(session->tile_manager.range_num_samples).c_str());
+ }
+
+ /* Write cryptomatte metadata. */
+ if (scene->film->cryptomatte_passes & CRYPT_OBJECT) {
+ add_cryptomatte_layer(b_rr,
+ view_layer_name + ".CryptoObject",
+ scene->object_manager->get_cryptomatte_objects(scene));
+ }
+ if (scene->film->cryptomatte_passes & CRYPT_MATERIAL) {
+ add_cryptomatte_layer(b_rr,
+ view_layer_name + ".CryptoMaterial",
+ scene->shader_manager->get_cryptomatte_materials(scene));
+ }
+ if (scene->film->cryptomatte_passes & CRYPT_ASSET) {
+ add_cryptomatte_layer(b_rr,
+ view_layer_name + ".CryptoAsset",
+ scene->object_manager->get_cryptomatte_assets(scene));
+ }
+
+ /* Store synchronization and bare-render times. */
+ double total_time, render_time;
+ session->progress.get_time(total_time, render_time);
+ b_rr.stamp_data_add_field((prefix + "total_time").c_str(),
+ time_human_readable_from_seconds(total_time).c_str());
+ b_rr.stamp_data_add_field((prefix + "render_time").c_str(),
+ time_human_readable_from_seconds(render_time).c_str());
+ b_rr.stamp_data_add_field((prefix + "synchronization_time").c_str(),
+ time_human_readable_from_seconds(total_time - render_time).c_str());
}
-void BlenderSession::render(BL::Depsgraph& b_depsgraph_)
+void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
{
- b_depsgraph = b_depsgraph_;
-
- /* set callback to write out render results */
- session->write_render_tile_cb = function_bind(&BlenderSession::write_render_tile, this, _1);
- session->update_render_tile_cb = function_bind(&BlenderSession::update_render_tile, this, _1, _2);
-
- /* get buffer parameters */
- SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
- BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_v3d, b_rv3d, scene->camera, width, height);
-
- /* render each layer */
- BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
-
- /* temporary render result to find needed passes and views */
- BL::RenderResult b_rr = begin_render_result(b_engine, 0, 0, 1, 1, b_view_layer.name().c_str(), NULL);
- BL::RenderResult::layers_iterator b_single_rlay;
- b_rr.layers.begin(b_single_rlay);
- BL::RenderLayer b_rlay = *b_single_rlay;
- b_rlay_name = b_view_layer.name();
-
- /* add passes */
- vector<Pass> passes = sync->sync_render_passes(b_rlay, b_view_layer);
- buffer_params.passes = passes;
-
- PointerRNA crl = RNA_pointer_get(&b_view_layer.ptr, "cycles");
- bool full_denoising = get_boolean(crl, "use_denoising");
- bool write_denoising_passes = get_boolean(crl, "denoising_store_passes");
-
- bool run_denoising = full_denoising || write_denoising_passes;
-
- session->tile_manager.schedule_denoising = run_denoising;
- buffer_params.denoising_data_pass = run_denoising;
- buffer_params.denoising_clean_pass = (scene->film->denoising_flags & DENOISING_CLEAN_ALL_PASSES);
- buffer_params.denoising_prefiltered_pass = write_denoising_passes;
-
- session->params.run_denoising = run_denoising;
- session->params.full_denoising = full_denoising;
- session->params.write_denoising_passes = write_denoising_passes;
- session->params.denoising.radius = get_int(crl, "denoising_radius");
- session->params.denoising.strength = get_float(crl, "denoising_strength");
- session->params.denoising.feature_strength = get_float(crl, "denoising_feature_strength");
- session->params.denoising.relative_pca = get_boolean(crl, "denoising_relative_pca");
-
- scene->film->denoising_data_pass = buffer_params.denoising_data_pass;
- scene->film->denoising_clean_pass = buffer_params.denoising_clean_pass;
- scene->film->denoising_prefiltered_pass = buffer_params.denoising_prefiltered_pass;
-
- scene->film->pass_alpha_threshold = b_view_layer.pass_alpha_threshold();
- scene->film->tag_passes_update(scene, passes);
- scene->film->tag_update(scene);
- scene->integrator->tag_update(scene);
-
- BL::RenderResult::views_iterator b_view_iter;
-
- int num_views = 0;
- for(b_rr.views.begin(b_view_iter); b_view_iter != b_rr.views.end(); ++b_view_iter) {
- num_views++;
- }
-
- int view_index = 0;
- for(b_rr.views.begin(b_view_iter); b_view_iter != b_rr.views.end(); ++b_view_iter, ++view_index) {
- b_rview_name = b_view_iter->name();
-
- /* set the current view */
- b_engine.active_view_set(b_rview_name.c_str());
-
- /* update scene */
- BL::Object b_camera_override(b_engine.camera_override());
- sync->sync_camera(b_render, b_camera_override, width, height, b_rview_name.c_str());
- sync->sync_data(b_render,
- b_depsgraph,
- b_v3d,
- b_camera_override,
- width, height,
- &python_thread_state);
- builtin_images_load();
-
- /* Attempt to free all data which is held by Blender side, since at this
- * point we knwo that we've got everything to render current view layer.
- */
- /* At the moment we only free if we are not doing multi-view (or if we are rendering the last view).
- * See T58142/D4239 for discussion.
- */
- if(view_index == num_views - 1) {
- free_blender_memory_if_possible();
- }
-
- /* Make sure all views have different noise patterns. - hardcoded value just to make it random */
- if(view_index != 0) {
- scene->integrator->seed += hash_int_2d(scene->integrator->seed, hash_int(view_index * 0xdeadbeef));
- scene->integrator->tag_update(scene);
- }
-
- /* Update number of samples per layer. */
- int samples = sync->get_layer_samples();
- bool bound_samples = sync->get_layer_bound_samples();
- int effective_layer_samples;
-
- if(samples != 0 && (!bound_samples || (samples < session_params.samples)))
- effective_layer_samples = samples;
- else
- effective_layer_samples = session_params.samples;
-
- /* Update tile manager if we're doing resumable render. */
- update_resumable_tile_manager(effective_layer_samples);
-
- /* Update session itself. */
- session->reset(buffer_params, effective_layer_samples);
-
- /* render */
- session->start();
- session->wait();
-
- if(!b_engine.is_preview() && background && print_render_stats) {
- RenderStats stats;
- session->collect_statistics(&stats);
- printf("Render statistics:\n%s\n", stats.full_report().c_str());
- }
-
- if(session->progress.get_cancel())
- break;
- }
-
- /* add metadata */
- stamp_view_layer_metadata(scene, b_rlay_name);
-
- /* free result without merging */
- end_render_result(b_engine, b_rr, true, true, false);
-
- double total_time, render_time;
- session->progress.get_time(total_time, render_time);
- VLOG(1) << "Total render time: " << total_time;
- VLOG(1) << "Render time (without synchronization): " << render_time;
-
- /* clear callback */
- session->write_render_tile_cb = function_null;
- session->update_render_tile_cb = function_null;
-
- /* TODO: find a way to clear this data for persistent data render */
+ b_depsgraph = b_depsgraph_;
+
+ /* set callback to write out render results */
+ session->write_render_tile_cb = function_bind(&BlenderSession::write_render_tile, this, _1);
+ session->update_render_tile_cb = function_bind(
+ &BlenderSession::update_render_tile, this, _1, _2);
+
+ /* get buffer parameters */
+ SessionParams session_params = BlenderSync::get_session_params(
+ b_engine, b_userpref, b_scene, background);
+ BufferParams buffer_params = BlenderSync::get_buffer_params(
+ b_render, b_v3d, b_rv3d, scene->camera, width, height);
+
+ /* render each layer */
+ BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
+
+ /* temporary render result to find needed passes and views */
+ BL::RenderResult b_rr = begin_render_result(
+ b_engine, 0, 0, 1, 1, b_view_layer.name().c_str(), NULL);
+ BL::RenderResult::layers_iterator b_single_rlay;
+ b_rr.layers.begin(b_single_rlay);
+ BL::RenderLayer b_rlay = *b_single_rlay;
+ b_rlay_name = b_view_layer.name();
+
+ /* add passes */
+ vector<Pass> passes = sync->sync_render_passes(b_rlay, b_view_layer);
+ buffer_params.passes = passes;
+
+ PointerRNA crl = RNA_pointer_get(&b_view_layer.ptr, "cycles");
+ bool full_denoising = get_boolean(crl, "use_denoising");
+ bool write_denoising_passes = get_boolean(crl, "denoising_store_passes");
+
+ bool run_denoising = full_denoising || write_denoising_passes;
+
+ session->tile_manager.schedule_denoising = run_denoising;
+ buffer_params.denoising_data_pass = run_denoising;
+ buffer_params.denoising_clean_pass = (scene->film->denoising_flags & DENOISING_CLEAN_ALL_PASSES);
+ buffer_params.denoising_prefiltered_pass = write_denoising_passes;
+
+ session->params.run_denoising = run_denoising;
+ session->params.full_denoising = full_denoising;
+ session->params.write_denoising_passes = write_denoising_passes;
+ session->params.denoising.radius = get_int(crl, "denoising_radius");
+ session->params.denoising.strength = get_float(crl, "denoising_strength");
+ session->params.denoising.feature_strength = get_float(crl, "denoising_feature_strength");
+ session->params.denoising.relative_pca = get_boolean(crl, "denoising_relative_pca");
+
+ scene->film->denoising_data_pass = buffer_params.denoising_data_pass;
+ scene->film->denoising_clean_pass = buffer_params.denoising_clean_pass;
+ scene->film->denoising_prefiltered_pass = buffer_params.denoising_prefiltered_pass;
+
+ scene->film->pass_alpha_threshold = b_view_layer.pass_alpha_threshold();
+ scene->film->tag_passes_update(scene, passes);
+ scene->film->tag_update(scene);
+ scene->integrator->tag_update(scene);
+
+ BL::RenderResult::views_iterator b_view_iter;
+
+ int num_views = 0;
+ for (b_rr.views.begin(b_view_iter); b_view_iter != b_rr.views.end(); ++b_view_iter) {
+ num_views++;
+ }
+
+ int view_index = 0;
+ for (b_rr.views.begin(b_view_iter); b_view_iter != b_rr.views.end();
+ ++b_view_iter, ++view_index) {
+ b_rview_name = b_view_iter->name();
+
+ /* set the current view */
+ b_engine.active_view_set(b_rview_name.c_str());
+
+ /* update scene */
+ BL::Object b_camera_override(b_engine.camera_override());
+ sync->sync_camera(b_render, b_camera_override, width, height, b_rview_name.c_str());
+ sync->sync_data(
+ b_render, b_depsgraph, b_v3d, b_camera_override, width, height, &python_thread_state);
+ builtin_images_load();
+
+ /* Attempt to free all data which is held by Blender side, since at this
+ * point we knwo that we've got everything to render current view layer.
+ */
+ /* At the moment we only free if we are not doing multi-view (or if we are rendering the last view).
+ * See T58142/D4239 for discussion.
+ */
+ if (view_index == num_views - 1) {
+ free_blender_memory_if_possible();
+ }
+
+ /* Make sure all views have different noise patterns. - hardcoded value just to make it random */
+ if (view_index != 0) {
+ scene->integrator->seed += hash_int_2d(scene->integrator->seed,
+ hash_int(view_index * 0xdeadbeef));
+ scene->integrator->tag_update(scene);
+ }
+
+ /* Update number of samples per layer. */
+ int samples = sync->get_layer_samples();
+ bool bound_samples = sync->get_layer_bound_samples();
+ int effective_layer_samples;
+
+ if (samples != 0 && (!bound_samples || (samples < session_params.samples)))
+ effective_layer_samples = samples;
+ else
+ effective_layer_samples = session_params.samples;
+
+ /* Update tile manager if we're doing resumable render. */
+ update_resumable_tile_manager(effective_layer_samples);
+
+ /* Update session itself. */
+ session->reset(buffer_params, effective_layer_samples);
+
+ /* render */
+ session->start();
+ session->wait();
+
+ if (!b_engine.is_preview() && background && print_render_stats) {
+ RenderStats stats;
+ session->collect_statistics(&stats);
+ printf("Render statistics:\n%s\n", stats.full_report().c_str());
+ }
+
+ if (session->progress.get_cancel())
+ break;
+ }
+
+ /* add metadata */
+ stamp_view_layer_metadata(scene, b_rlay_name);
+
+ /* free result without merging */
+ end_render_result(b_engine, b_rr, true, true, false);
+
+ double total_time, render_time;
+ session->progress.get_time(total_time, render_time);
+ VLOG(1) << "Total render time: " << total_time;
+ VLOG(1) << "Render time (without synchronization): " << render_time;
+
+ /* clear callback */
+ session->write_render_tile_cb = function_null;
+ session->update_render_tile_cb = function_null;
+
+ /* TODO: find a way to clear this data for persistent data render */
#if 0
- /* free all memory used (host and device), so we wouldn't leave render
- * engine with extra memory allocated
- */
+ /* free all memory used (host and device), so we wouldn't leave render
+ * engine with extra memory allocated
+ */
- session->device_free();
+ session->device_free();
- delete sync;
- sync = NULL;
+ delete sync;
+ sync = NULL;
#endif
}
-static void populate_bake_data(BakeData *data, const
- int object_id,
- BL::BakePixel& pixel_array,
+static void populate_bake_data(BakeData *data,
+ const int object_id,
+ BL::BakePixel &pixel_array,
const int num_pixels)
{
- BL::BakePixel bp = pixel_array;
-
- int i;
- for(i = 0; i < num_pixels; i++) {
- if(bp.object_id() == object_id) {
- data->set(i, bp.primitive_id(), bp.uv(), bp.du_dx(), bp.du_dy(), bp.dv_dx(), bp.dv_dy());
- } else {
- data->set_null(i);
- }
- bp = bp.next();
- }
+ BL::BakePixel bp = pixel_array;
+
+ int i;
+ for (i = 0; i < num_pixels; i++) {
+ if (bp.object_id() == object_id) {
+ data->set(i, bp.primitive_id(), bp.uv(), bp.du_dx(), bp.du_dy(), bp.dv_dx(), bp.dv_dy());
+ }
+ else {
+ data->set_null(i);
+ }
+ bp = bp.next();
+ }
}
static int bake_pass_filter_get(const int pass_filter)
{
- int flag = BAKE_FILTER_NONE;
-
- if((pass_filter & BL::BakeSettings::pass_filter_DIRECT) != 0)
- flag |= BAKE_FILTER_DIRECT;
- if((pass_filter & BL::BakeSettings::pass_filter_INDIRECT) != 0)
- flag |= BAKE_FILTER_INDIRECT;
- if((pass_filter & BL::BakeSettings::pass_filter_COLOR) != 0)
- flag |= BAKE_FILTER_COLOR;
-
- if((pass_filter & BL::BakeSettings::pass_filter_DIFFUSE) != 0)
- flag |= BAKE_FILTER_DIFFUSE;
- if((pass_filter & BL::BakeSettings::pass_filter_GLOSSY) != 0)
- flag |= BAKE_FILTER_GLOSSY;
- if((pass_filter & BL::BakeSettings::pass_filter_TRANSMISSION) != 0)
- flag |= BAKE_FILTER_TRANSMISSION;
- if((pass_filter & BL::BakeSettings::pass_filter_SUBSURFACE) != 0)
- flag |= BAKE_FILTER_SUBSURFACE;
-
- if((pass_filter & BL::BakeSettings::pass_filter_EMIT) != 0)
- flag |= BAKE_FILTER_EMISSION;
- if((pass_filter & BL::BakeSettings::pass_filter_AO) != 0)
- flag |= BAKE_FILTER_AO;
-
- return flag;
+ int flag = BAKE_FILTER_NONE;
+
+ if ((pass_filter & BL::BakeSettings::pass_filter_DIRECT) != 0)
+ flag |= BAKE_FILTER_DIRECT;
+ if ((pass_filter & BL::BakeSettings::pass_filter_INDIRECT) != 0)
+ flag |= BAKE_FILTER_INDIRECT;
+ if ((pass_filter & BL::BakeSettings::pass_filter_COLOR) != 0)
+ flag |= BAKE_FILTER_COLOR;
+
+ if ((pass_filter & BL::BakeSettings::pass_filter_DIFFUSE) != 0)
+ flag |= BAKE_FILTER_DIFFUSE;
+ if ((pass_filter & BL::BakeSettings::pass_filter_GLOSSY) != 0)
+ flag |= BAKE_FILTER_GLOSSY;
+ if ((pass_filter & BL::BakeSettings::pass_filter_TRANSMISSION) != 0)
+ flag |= BAKE_FILTER_TRANSMISSION;
+ if ((pass_filter & BL::BakeSettings::pass_filter_SUBSURFACE) != 0)
+ flag |= BAKE_FILTER_SUBSURFACE;
+
+ if ((pass_filter & BL::BakeSettings::pass_filter_EMIT) != 0)
+ flag |= BAKE_FILTER_EMISSION;
+ if ((pass_filter & BL::BakeSettings::pass_filter_AO) != 0)
+ flag |= BAKE_FILTER_AO;
+
+ return flag;
}
-void BlenderSession::bake(BL::Depsgraph& b_depsgraph_,
- BL::Object& b_object,
- const string& pass_type,
+void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
+ BL::Object &b_object,
+ const string &pass_type,
const int pass_filter,
const int object_id,
- BL::BakePixel& pixel_array,
+ BL::BakePixel &pixel_array,
const size_t num_pixels,
const int /*depth*/,
float result[])
{
- b_depsgraph = b_depsgraph_;
-
- ShaderEvalType shader_type = get_shader_type(pass_type);
-
- /* Set baking flag in advance, so kernel loading can check if we need
- * any baking capabilities.
- */
- scene->bake_manager->set_baking(true);
-
- /* ensure kernels are loaded before we do any scene updates */
- session->load_kernels();
-
- if(shader_type == SHADER_EVAL_UV) {
- /* force UV to be available */
- Pass::add(PASS_UV, scene->film->passes);
- }
-
- int bake_pass_filter = bake_pass_filter_get(pass_filter);
- bake_pass_filter = BakeManager::shader_type_to_pass_filter(shader_type, bake_pass_filter);
-
- /* force use_light_pass to be true if we bake more than just colors */
- if(bake_pass_filter & ~BAKE_FILTER_COLOR) {
- Pass::add(PASS_LIGHT, scene->film->passes);
- }
-
- /* create device and update scene */
- scene->film->tag_update(scene);
- scene->integrator->tag_update(scene);
-
- if(!session->progress.get_cancel()) {
- /* update scene */
- BL::Object b_camera_override(b_engine.camera_override());
- sync->sync_camera(b_render, b_camera_override, width, height, "");
- sync->sync_data(b_render,
- b_depsgraph,
- b_v3d,
- b_camera_override,
- width, height,
- &python_thread_state);
- builtin_images_load();
- }
-
- BakeData *bake_data = NULL;
-
- if(!session->progress.get_cancel()) {
- /* get buffer parameters */
- SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
- BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, 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());
-
- /* set number of samples */
- session->tile_manager.set_samples(session_params.samples);
- session->reset(buffer_params, session_params.samples);
- session->update_scene();
-
- /* find object index. todo: is arbitrary - copied from mesh_displace.cpp */
- size_t object_index = OBJECT_NONE;
- int tri_offset = 0;
-
- for(size_t i = 0; i < scene->objects.size(); i++) {
- if(strcmp(scene->objects[i]->name.c_str(), b_object.name().c_str()) == 0) {
- object_index = i;
- tri_offset = scene->objects[i]->mesh->tri_offset;
- break;
- }
- }
-
- /* Object might have been disabled for rendering or excluded in some
- * other way, in that case Blender will report a warning afterwards. */
- if (object_index != OBJECT_NONE) {
- int object = object_index;
-
- bake_data = scene->bake_manager->init(object, tri_offset, num_pixels);
- populate_bake_data(bake_data, object_id, pixel_array, num_pixels);
- }
-
- /* set number of samples */
- session->tile_manager.set_samples(session_params.samples);
- session->reset(buffer_params, session_params.samples);
- session->update_scene();
-
- session->progress.set_update_callback(function_bind(&BlenderSession::update_bake_progress, this));
- }
-
- /* Perform bake. Check cancel to avoid crash with incomplete scene data. */
- if(!session->progress.get_cancel() && bake_data) {
- scene->bake_manager->bake(scene->device, &scene->dscene, scene, session->progress, shader_type, bake_pass_filter, bake_data, result);
- }
-
- /* free all memory used (host and device), so we wouldn't leave render
- * engine with extra memory allocated
- */
-
- session->device_free();
-
- delete sync;
- sync = NULL;
+ b_depsgraph = b_depsgraph_;
+
+ ShaderEvalType shader_type = get_shader_type(pass_type);
+
+ /* Set baking flag in advance, so kernel loading can check if we need
+ * any baking capabilities.
+ */
+ scene->bake_manager->set_baking(true);
+
+ /* ensure kernels are loaded before we do any scene updates */
+ session->load_kernels();
+
+ if (shader_type == SHADER_EVAL_UV) {
+ /* force UV to be available */
+ Pass::add(PASS_UV, scene->film->passes);
+ }
+
+ int bake_pass_filter = bake_pass_filter_get(pass_filter);
+ bake_pass_filter = BakeManager::shader_type_to_pass_filter(shader_type, bake_pass_filter);
+
+ /* force use_light_pass to be true if we bake more than just colors */
+ if (bake_pass_filter & ~BAKE_FILTER_COLOR) {
+ Pass::add(PASS_LIGHT, scene->film->passes);
+ }
+
+ /* create device and update scene */
+ scene->film->tag_update(scene);
+ scene->integrator->tag_update(scene);
+
+ if (!session->progress.get_cancel()) {
+ /* update scene */
+ BL::Object b_camera_override(b_engine.camera_override());
+ sync->sync_camera(b_render, b_camera_override, width, height, "");
+ sync->sync_data(
+ b_render, b_depsgraph, b_v3d, b_camera_override, width, height, &python_thread_state);
+ builtin_images_load();
+ }
+
+ BakeData *bake_data = NULL;
+
+ if (!session->progress.get_cancel()) {
+ /* get buffer parameters */
+ SessionParams session_params = BlenderSync::get_session_params(
+ b_engine, b_userpref, b_scene, background);
+ BufferParams buffer_params = BlenderSync::get_buffer_params(
+ b_render, 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());
+
+ /* set number of samples */
+ session->tile_manager.set_samples(session_params.samples);
+ session->reset(buffer_params, session_params.samples);
+ session->update_scene();
+
+ /* find object index. todo: is arbitrary - copied from mesh_displace.cpp */
+ size_t object_index = OBJECT_NONE;
+ int tri_offset = 0;
+
+ for (size_t i = 0; i < scene->objects.size(); i++) {
+ if (strcmp(scene->objects[i]->name.c_str(), b_object.name().c_str()) == 0) {
+ object_index = i;
+ tri_offset = scene->objects[i]->mesh->tri_offset;
+ break;
+ }
+ }
+
+ /* Object might have been disabled for rendering or excluded in some
+ * other way, in that case Blender will report a warning afterwards. */
+ if (object_index != OBJECT_NONE) {
+ int object = object_index;
+
+ bake_data = scene->bake_manager->init(object, tri_offset, num_pixels);
+ populate_bake_data(bake_data, object_id, pixel_array, num_pixels);
+ }
+
+ /* set number of samples */
+ session->tile_manager.set_samples(session_params.samples);
+ session->reset(buffer_params, session_params.samples);
+ session->update_scene();
+
+ session->progress.set_update_callback(
+ function_bind(&BlenderSession::update_bake_progress, this));
+ }
+
+ /* Perform bake. Check cancel to avoid crash with incomplete scene data. */
+ if (!session->progress.get_cancel() && bake_data) {
+ scene->bake_manager->bake(scene->device,
+ &scene->dscene,
+ scene,
+ session->progress,
+ shader_type,
+ bake_pass_filter,
+ bake_data,
+ result);
+ }
+
+ /* free all memory used (host and device), so we wouldn't leave render
+ * engine with extra memory allocated
+ */
+
+ session->device_free();
+
+ delete sync;
+ sync = NULL;
}
-void BlenderSession::do_write_update_render_result(BL::RenderResult& b_rr,
- BL::RenderLayer& b_rlay,
- RenderTile& rtile,
+void BlenderSession::do_write_update_render_result(BL::RenderResult &b_rr,
+ BL::RenderLayer &b_rlay,
+ RenderTile &rtile,
bool do_update_only)
{
- RenderBuffers *buffers = rtile.buffers;
-
- /* copy data from device */
- if(!buffers->copy_from_device())
- return;
-
- float exposure = scene->film->exposure;
-
- vector<float> pixels(rtile.w*rtile.h*4);
-
- /* Adjust absolute sample number to the range. */
- int sample = rtile.sample;
- const int range_start_sample = session->tile_manager.range_start_sample;
- if(range_start_sample != -1) {
- sample -= range_start_sample;
- }
-
- if(!do_update_only) {
- /* copy each pass */
- BL::RenderLayer::passes_iterator b_iter;
-
- for(b_rlay.passes.begin(b_iter); b_iter != b_rlay.passes.end(); ++b_iter) {
- BL::RenderPass b_pass(*b_iter);
-
- /* find matching pass type */
- PassType pass_type = BlenderSync::get_pass_type(b_pass);
- int components = b_pass.channels();
-
- bool read = false;
- if(pass_type != PASS_NONE) {
- /* copy pixels */
- read = buffers->get_pass_rect(pass_type, exposure, sample, components, &pixels[0], b_pass.name());
- }
- else {
- int denoising_offset = BlenderSync::get_denoising_pass(b_pass);
- if(denoising_offset >= 0) {
- read = buffers->get_denoising_pass_rect(denoising_offset, exposure, sample, components, &pixels[0]);
- }
- }
-
- if(!read) {
- memset(&pixels[0], 0, pixels.size()*sizeof(float));
- }
-
- b_pass.rect(&pixels[0]);
- }
- }
- else {
- /* copy combined pass */
- BL::RenderPass b_combined_pass(b_rlay.passes.find_by_name("Combined", b_rview_name.c_str()));
- if(buffers->get_pass_rect(PASS_COMBINED, exposure, sample, 4, &pixels[0], "Combined"))
- b_combined_pass.rect(&pixels[0]);
- }
-
- /* tag result as updated */
- b_engine.update_result(b_rr);
+ RenderBuffers *buffers = rtile.buffers;
+
+ /* copy data from device */
+ if (!buffers->copy_from_device())
+ return;
+
+ float exposure = scene->film->exposure;
+
+ vector<float> pixels(rtile.w * rtile.h * 4);
+
+ /* Adjust absolute sample number to the range. */
+ int sample = rtile.sample;
+ const int range_start_sample = session->tile_manager.range_start_sample;
+ if (range_start_sample != -1) {
+ sample -= range_start_sample;
+ }
+
+ if (!do_update_only) {
+ /* copy each pass */
+ BL::RenderLayer::passes_iterator b_iter;
+
+ for (b_rlay.passes.begin(b_iter); b_iter != b_rlay.passes.end(); ++b_iter) {
+ BL::RenderPass b_pass(*b_iter);
+
+ /* find matching pass type */
+ PassType pass_type = BlenderSync::get_pass_type(b_pass);
+ int components = b_pass.channels();
+
+ bool read = false;
+ if (pass_type != PASS_NONE) {
+ /* copy pixels */
+ read = buffers->get_pass_rect(
+ pass_type, exposure, sample, components, &pixels[0], b_pass.name());
+ }
+ else {
+ int denoising_offset = BlenderSync::get_denoising_pass(b_pass);
+ if (denoising_offset >= 0) {
+ read = buffers->get_denoising_pass_rect(
+ denoising_offset, exposure, sample, components, &pixels[0]);
+ }
+ }
+
+ if (!read) {
+ memset(&pixels[0], 0, pixels.size() * sizeof(float));
+ }
+
+ b_pass.rect(&pixels[0]);
+ }
+ }
+ else {
+ /* copy combined pass */
+ BL::RenderPass b_combined_pass(b_rlay.passes.find_by_name("Combined", b_rview_name.c_str()));
+ if (buffers->get_pass_rect(PASS_COMBINED, exposure, sample, 4, &pixels[0], "Combined"))
+ b_combined_pass.rect(&pixels[0]);
+ }
+
+ /* tag result as updated */
+ b_engine.update_result(b_rr);
}
-void BlenderSession::write_render_result(BL::RenderResult& b_rr,
- BL::RenderLayer& b_rlay,
- RenderTile& rtile)
+void BlenderSession::write_render_result(BL::RenderResult &b_rr,
+ BL::RenderLayer &b_rlay,
+ RenderTile &rtile)
{
- do_write_update_render_result(b_rr, b_rlay, rtile, false);
+ do_write_update_render_result(b_rr, b_rlay, rtile, false);
}
-void BlenderSession::update_render_result(BL::RenderResult& b_rr,
- BL::RenderLayer& b_rlay,
- RenderTile& rtile)
+void BlenderSession::update_render_result(BL::RenderResult &b_rr,
+ BL::RenderLayer &b_rlay,
+ RenderTile &rtile)
{
- do_write_update_render_result(b_rr, b_rlay, rtile, true);
+ do_write_update_render_result(b_rr, b_rlay, rtile, true);
}
-void BlenderSession::synchronize(BL::Depsgraph& b_depsgraph_)
+void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_)
{
- /* only used for viewport render */
- if(!b_v3d)
- return;
-
- /* on session/scene parameter changes, we recreate session entirely */
- SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
- SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
- bool session_pause = BlenderSync::get_session_pause(b_scene, background);
-
- if(session->params.modified(session_params) ||
- scene->params.modified(scene_params))
- {
- free_session();
- create_session();
- return;
- }
-
- /* increase samples, but never decrease */
- session->set_samples(session_params.samples);
- 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(b_depsgraph_);
-
- /* 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();
- return;
- }
-
- /* data and camera synchronize */
- b_depsgraph = b_depsgraph_;
-
- BL::Object b_camera_override(b_engine.camera_override());
- sync->sync_data(b_render,
- b_depsgraph,
- b_v3d,
- b_camera_override,
- width, height,
- &python_thread_state);
-
- if(b_rv3d)
- sync->sync_view(b_v3d, b_rv3d, width, height);
- else
- sync->sync_camera(b_render, b_camera_override, width, height, "");
-
- builtin_images_load();
-
- /* unlock */
- session->scene->mutex.unlock();
-
- /* reset if needed */
- if(scene->need_reset()) {
- BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_v3d, b_rv3d, scene->camera, width, height);
- session->reset(buffer_params, session_params.samples);
-
- /* reset time */
- start_resize_time = 0.0;
- }
-
- /* Start rendering thread, if it's not running already. Do this
- * after all scene data has been synced at least once. */
- session->start();
+ /* only used for viewport render */
+ if (!b_v3d)
+ return;
+
+ /* on session/scene parameter changes, we recreate session entirely */
+ SessionParams session_params = BlenderSync::get_session_params(
+ b_engine, b_userpref, b_scene, background);
+ SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
+ bool session_pause = BlenderSync::get_session_pause(b_scene, background);
+
+ if (session->params.modified(session_params) || scene->params.modified(scene_params)) {
+ free_session();
+ create_session();
+ return;
+ }
+
+ /* increase samples, but never decrease */
+ session->set_samples(session_params.samples);
+ 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(b_depsgraph_);
+
+ /* 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();
+ return;
+ }
+
+ /* data and camera synchronize */
+ b_depsgraph = b_depsgraph_;
+
+ BL::Object b_camera_override(b_engine.camera_override());
+ sync->sync_data(
+ b_render, b_depsgraph, b_v3d, b_camera_override, width, height, &python_thread_state);
+
+ if (b_rv3d)
+ sync->sync_view(b_v3d, b_rv3d, width, height);
+ else
+ sync->sync_camera(b_render, b_camera_override, width, height, "");
+
+ builtin_images_load();
+
+ /* unlock */
+ session->scene->mutex.unlock();
+
+ /* reset if needed */
+ if (scene->need_reset()) {
+ BufferParams buffer_params = BlenderSync::get_buffer_params(
+ b_render, b_v3d, b_rv3d, scene->camera, width, height);
+ session->reset(buffer_params, session_params.samples);
+
+ /* reset time */
+ start_resize_time = 0.0;
+ }
+
+ /* Start rendering thread, if it's not running already. Do this
+ * after all scene data has been synced at least once. */
+ session->start();
}
bool BlenderSession::draw(int w, int h)
{
- /* pause in redraw in case update is not being called due to final render */
- session->set_pause(BlenderSync::get_session_pause(b_scene, background));
-
- /* before drawing, we verify camera and viewport size changes, because
- * we do not get update callbacks for those, we must detect them here */
- if(session->ready_to_reset()) {
- bool reset = false;
-
- /* if dimensions changed, reset */
- if(width != w || height != h) {
- if(start_resize_time == 0.0) {
- /* don't react immediately to resizes to avoid flickery resizing
- * of the viewport, and some window managers changing the window
- * size temporarily on unminimize */
- start_resize_time = time_dt();
- tag_redraw();
- }
- else if(time_dt() - start_resize_time < 0.2) {
- tag_redraw();
- }
- else {
- width = w;
- height = h;
- reset = true;
- }
- }
-
- /* try to acquire mutex. if we can't, come back later */
- if(!session->scene->mutex.try_lock()) {
- tag_update();
- }
- else {
- /* update camera from 3d view */
-
- sync->sync_view(b_v3d, b_rv3d, width, height);
-
- if(scene->camera->need_update)
- reset = true;
-
- session->scene->mutex.unlock();
- }
-
- /* reset if requested */
- 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_v3d, b_rv3d, scene->camera, width, height);
- bool session_pause = BlenderSync::get_session_pause(b_scene, background);
-
- if(session_pause == false) {
- session->reset(buffer_params, session_params.samples);
- start_resize_time = 0.0;
- }
- }
- }
- else {
- tag_update();
- }
-
- /* update status and progress for 3d view draw */
- update_status_progress();
-
- /* draw */
- BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_v3d, b_rv3d, scene->camera, width, height);
- DeviceDrawParams draw_params;
-
- if(session->params.display_buffer_linear) {
- draw_params.bind_display_space_shader_cb = function_bind(&BL::RenderEngine::bind_display_space_shader, &b_engine, b_scene);
- draw_params.unbind_display_space_shader_cb = function_bind(&BL::RenderEngine::unbind_display_space_shader, &b_engine);
- }
-
- return !session->draw(buffer_params, draw_params);
+ /* pause in redraw in case update is not being called due to final render */
+ session->set_pause(BlenderSync::get_session_pause(b_scene, background));
+
+ /* before drawing, we verify camera and viewport size changes, because
+ * we do not get update callbacks for those, we must detect them here */
+ if (session->ready_to_reset()) {
+ bool reset = false;
+
+ /* if dimensions changed, reset */
+ if (width != w || height != h) {
+ if (start_resize_time == 0.0) {
+ /* don't react immediately to resizes to avoid flickery resizing
+ * of the viewport, and some window managers changing the window
+ * size temporarily on unminimize */
+ start_resize_time = time_dt();
+ tag_redraw();
+ }
+ else if (time_dt() - start_resize_time < 0.2) {
+ tag_redraw();
+ }
+ else {
+ width = w;
+ height = h;
+ reset = true;
+ }
+ }
+
+ /* try to acquire mutex. if we can't, come back later */
+ if (!session->scene->mutex.try_lock()) {
+ tag_update();
+ }
+ else {
+ /* update camera from 3d view */
+
+ sync->sync_view(b_v3d, b_rv3d, width, height);
+
+ if (scene->camera->need_update)
+ reset = true;
+
+ session->scene->mutex.unlock();
+ }
+
+ /* reset if requested */
+ 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_v3d, b_rv3d, scene->camera, width, height);
+ bool session_pause = BlenderSync::get_session_pause(b_scene, background);
+
+ if (session_pause == false) {
+ session->reset(buffer_params, session_params.samples);
+ start_resize_time = 0.0;
+ }
+ }
+ }
+ else {
+ tag_update();
+ }
+
+ /* update status and progress for 3d view draw */
+ update_status_progress();
+
+ /* draw */
+ BufferParams buffer_params = BlenderSync::get_buffer_params(
+ b_render, b_v3d, b_rv3d, scene->camera, width, height);
+ DeviceDrawParams draw_params;
+
+ if (session->params.display_buffer_linear) {
+ draw_params.bind_display_space_shader_cb = function_bind(
+ &BL::RenderEngine::bind_display_space_shader, &b_engine, b_scene);
+ draw_params.unbind_display_space_shader_cb = function_bind(
+ &BL::RenderEngine::unbind_display_space_shader, &b_engine);
+ }
+
+ return !session->draw(buffer_params, draw_params);
}
-void BlenderSession::get_status(string& status, string& substatus)
+void BlenderSession::get_status(string &status, string &substatus)
{
- session->progress.get_status(status, substatus);
+ session->progress.get_status(status, substatus);
}
-void BlenderSession::get_kernel_status(string& kernel_status)
+void BlenderSession::get_kernel_status(string &kernel_status)
{
- session->progress.get_kernel_status(kernel_status);
+ session->progress.get_kernel_status(kernel_status);
}
-void BlenderSession::get_progress(float& progress, double& total_time, double& render_time)
+void BlenderSession::get_progress(float &progress, double &total_time, double &render_time)
{
- session->progress.get_time(total_time, render_time);
- progress = session->progress.get_progress();
+ session->progress.get_time(total_time, render_time);
+ progress = session->progress.get_progress();
}
void BlenderSession::update_bake_progress()
{
- float progress = session->progress.get_progress();
+ float progress = session->progress.get_progress();
- if(progress != last_progress) {
- b_engine.update_progress(progress);
- last_progress = progress;
- }
+ if (progress != last_progress) {
+ b_engine.update_progress(progress);
+ last_progress = progress;
+ }
}
void BlenderSession::update_status_progress()
{
- string timestatus, status, substatus, kernel_status;
- string scene_status = "";
- float progress;
- double total_time, remaining_time = 0, render_time;
- float mem_used = (float)session->stats.mem_used / 1024.0f / 1024.0f;
- float mem_peak = (float)session->stats.mem_peak / 1024.0f / 1024.0f;
-
- get_status(status, substatus);
- get_kernel_status(kernel_status);
- get_progress(progress, total_time, render_time);
-
- if(progress > 0)
- remaining_time = (1.0 - (double)progress) * (render_time / (double)progress);
-
- if(background) {
- scene_status += " | " + scene->name;
- if(b_rlay_name != "")
- scene_status += ", " + b_rlay_name;
-
- if(b_rview_name != "")
- scene_status += ", " + b_rview_name;
-
- if(remaining_time > 0) {
- timestatus += "Remaining:" + time_human_readable_from_seconds(remaining_time) + " | ";
- }
-
- timestatus += string_printf("Mem:%.2fM, Peak:%.2fM", (double)mem_used, (double)mem_peak);
-
- if(status.size() > 0)
- status = " | " + status;
- if(substatus.size() > 0)
- status += " | " + substatus;
- if(kernel_status.size() > 0)
- status += " | " + kernel_status;
- }
-
- double current_time = time_dt();
- /* When rendering in a window, redraw the status at least once per second to keep the elapsed and remaining time up-to-date.
- * For headless rendering, only report when something significant changes to keep the console output readable. */
- if(status != last_status || (!headless && (current_time - last_status_time) > 1.0)) {
- b_engine.update_stats("", (timestatus + scene_status + status).c_str());
- b_engine.update_memory_stats(mem_used, mem_peak);
- last_status = status;
- last_status_time = current_time;
- }
- if(progress != last_progress) {
- b_engine.update_progress(progress);
- last_progress = progress;
- }
-
- if(session->progress.get_error()) {
- string error = session->progress.get_error_message();
- if(error != last_error) {
- /* TODO(sergey): Currently C++ RNA API doesn't let us to
- * use mnemonic name for the variable. Would be nice to
- * have this figured out.
- *
- * For until then, 1 << 5 means RPT_ERROR.
- */
- b_engine.report(1 << 5, error.c_str());
- b_engine.error_set(error.c_str());
- last_error = error;
- }
- }
+ string timestatus, status, substatus, kernel_status;
+ string scene_status = "";
+ float progress;
+ double total_time, remaining_time = 0, render_time;
+ float mem_used = (float)session->stats.mem_used / 1024.0f / 1024.0f;
+ float mem_peak = (float)session->stats.mem_peak / 1024.0f / 1024.0f;
+
+ get_status(status, substatus);
+ get_kernel_status(kernel_status);
+ get_progress(progress, total_time, render_time);
+
+ if (progress > 0)
+ remaining_time = (1.0 - (double)progress) * (render_time / (double)progress);
+
+ if (background) {
+ scene_status += " | " + scene->name;
+ if (b_rlay_name != "")
+ scene_status += ", " + b_rlay_name;
+
+ if (b_rview_name != "")
+ scene_status += ", " + b_rview_name;
+
+ if (remaining_time > 0) {
+ timestatus += "Remaining:" + time_human_readable_from_seconds(remaining_time) + " | ";
+ }
+
+ timestatus += string_printf("Mem:%.2fM, Peak:%.2fM", (double)mem_used, (double)mem_peak);
+
+ if (status.size() > 0)
+ status = " | " + status;
+ if (substatus.size() > 0)
+ status += " | " + substatus;
+ if (kernel_status.size() > 0)
+ status += " | " + kernel_status;
+ }
+
+ double current_time = time_dt();
+ /* When rendering in a window, redraw the status at least once per second to keep the elapsed and remaining time up-to-date.
+ * For headless rendering, only report when something significant changes to keep the console output readable. */
+ if (status != last_status || (!headless && (current_time - last_status_time) > 1.0)) {
+ b_engine.update_stats("", (timestatus + scene_status + status).c_str());
+ b_engine.update_memory_stats(mem_used, mem_peak);
+ last_status = status;
+ last_status_time = current_time;
+ }
+ if (progress != last_progress) {
+ b_engine.update_progress(progress);
+ last_progress = progress;
+ }
+
+ if (session->progress.get_error()) {
+ string error = session->progress.get_error_message();
+ if (error != last_error) {
+ /* TODO(sergey): Currently C++ RNA API doesn't let us to
+ * use mnemonic name for the variable. Would be nice to
+ * have this figured out.
+ *
+ * For until then, 1 << 5 means RPT_ERROR.
+ */
+ b_engine.report(1 << 5, error.c_str());
+ b_engine.error_set(error.c_str());
+ last_error = error;
+ }
+ }
}
void BlenderSession::tag_update()
{
- /* tell blender that we want to get another update callback */
- b_engine.tag_update();
+ /* tell blender that we want to get another update callback */
+ b_engine.tag_update();
}
void BlenderSession::tag_redraw()
{
- if(background) {
- /* update stats and progress, only for background here because
- * in 3d view we do it in draw for thread safety reasons */
- update_status_progress();
-
- /* offline render, redraw if timeout passed */
- if(time_dt() - last_redraw_time > 1.0) {
- b_engine.tag_redraw();
- last_redraw_time = time_dt();
- }
- }
- else {
- /* tell blender that we want to redraw */
- b_engine.tag_redraw();
- }
+ if (background) {
+ /* update stats and progress, only for background here because
+ * in 3d view we do it in draw for thread safety reasons */
+ update_status_progress();
+
+ /* offline render, redraw if timeout passed */
+ if (time_dt() - last_redraw_time > 1.0) {
+ b_engine.tag_redraw();
+ last_redraw_time = time_dt();
+ }
+ }
+ else {
+ /* tell blender that we want to redraw */
+ b_engine.tag_redraw();
+ }
}
void BlenderSession::test_cancel()
{
- /* test if we need to cancel rendering */
- if(background)
- if(b_engine.test_break())
- session->progress.set_cancel("Cancelled");
+ /* test if we need to cancel rendering */
+ if (background)
+ if (b_engine.test_break())
+ session->progress.set_cancel("Cancelled");
}
/* builtin image file name is actually an image datablock name with
@@ -1107,89 +1126,88 @@ void BlenderSession::test_cancel()
*/
int BlenderSession::builtin_image_frame(const string &builtin_name)
{
- int last = builtin_name.find_last_of('@');
- return atoi(builtin_name.substr(last + 1, builtin_name.size() - last - 1).c_str());
+ int last = builtin_name.find_last_of('@');
+ return atoi(builtin_name.substr(last + 1, builtin_name.size() - last - 1).c_str());
}
void BlenderSession::builtin_image_info(const string &builtin_name,
void *builtin_data,
- ImageMetaData& metadata)
+ ImageMetaData &metadata)
{
- /* empty image */
- metadata.width = 1;
- metadata.height = 1;
-
- if(!builtin_data)
- return;
-
- /* recover ID pointer */
- PointerRNA ptr;
- RNA_id_pointer_create((ID*)builtin_data, &ptr);
- BL::ID b_id(ptr);
-
- if(b_id.is_a(&RNA_Image)) {
- /* image data */
- BL::Image b_image(b_id);
-
- metadata.builtin_free_cache = !b_image.has_data();
- metadata.is_float = b_image.is_float();
- metadata.width = b_image.size()[0];
- metadata.height = b_image.size()[1];
- metadata.depth = 1;
- metadata.channels = b_image.channels();
- }
- else if(b_id.is_a(&RNA_Object)) {
- /* smoke volume data */
- BL::Object b_ob(b_id);
- BL::SmokeDomainSettings b_domain = object_smoke_domain_find(b_ob);
-
- metadata.is_float = true;
- metadata.depth = 1;
- metadata.channels = 1;
-
- if(!b_domain)
- return;
-
- if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_DENSITY) ||
- builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_FLAME) ||
- builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT) ||
- builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_TEMPERATURE))
- metadata.channels = 1;
- else if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_COLOR))
- metadata.channels = 4;
- else if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY))
- metadata.channels = 3;
- else
- return;
-
- int3 resolution = get_int3(b_domain.domain_resolution());
- int amplify = (b_domain.use_high_resolution())? b_domain.amplify() + 1: 1;
-
- /* Velocity and heat data is always low-resolution. */
- if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY) ||
- builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT))
- {
- amplify = 1;
- }
-
- metadata.width = resolution.x * amplify;
- metadata.height = resolution.y * amplify;
- metadata.depth = resolution.z * amplify;
- }
- else {
- /* TODO(sergey): Check we're indeed in shader node tree. */
- PointerRNA ptr;
- RNA_pointer_create(NULL, &RNA_Node, builtin_data, &ptr);
- BL::Node b_node(ptr);
- if(b_node.is_a(&RNA_ShaderNodeTexPointDensity)) {
- BL::ShaderNodeTexPointDensity b_point_density_node(b_node);
- metadata.channels = 4;
- metadata.width = b_point_density_node.resolution();
- metadata.height = metadata.width;
- metadata.depth = metadata.width;
- metadata.is_float = true;
- }
- }
+ /* empty image */
+ metadata.width = 1;
+ metadata.height = 1;
+
+ if (!builtin_data)
+ return;
+
+ /* recover ID pointer */
+ PointerRNA ptr;
+ RNA_id_pointer_create((ID *)builtin_data, &ptr);
+ BL::ID b_id(ptr);
+
+ if (b_id.is_a(&RNA_Image)) {
+ /* image data */
+ BL::Image b_image(b_id);
+
+ metadata.builtin_free_cache = !b_image.has_data();
+ metadata.is_float = b_image.is_float();
+ metadata.width = b_image.size()[0];
+ metadata.height = b_image.size()[1];
+ metadata.depth = 1;
+ metadata.channels = b_image.channels();
+ }
+ else if (b_id.is_a(&RNA_Object)) {
+ /* smoke volume data */
+ BL::Object b_ob(b_id);
+ BL::SmokeDomainSettings b_domain = object_smoke_domain_find(b_ob);
+
+ metadata.is_float = true;
+ metadata.depth = 1;
+ metadata.channels = 1;
+
+ if (!b_domain)
+ return;
+
+ if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_DENSITY) ||
+ builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_FLAME) ||
+ builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT) ||
+ builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_TEMPERATURE))
+ metadata.channels = 1;
+ else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_COLOR))
+ metadata.channels = 4;
+ else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY))
+ metadata.channels = 3;
+ else
+ return;
+
+ int3 resolution = get_int3(b_domain.domain_resolution());
+ int amplify = (b_domain.use_high_resolution()) ? b_domain.amplify() + 1 : 1;
+
+ /* Velocity and heat data is always low-resolution. */
+ if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY) ||
+ builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT)) {
+ amplify = 1;
+ }
+
+ metadata.width = resolution.x * amplify;
+ metadata.height = resolution.y * amplify;
+ metadata.depth = resolution.z * amplify;
+ }
+ else {
+ /* TODO(sergey): Check we're indeed in shader node tree. */
+ PointerRNA ptr;
+ RNA_pointer_create(NULL, &RNA_Node, builtin_data, &ptr);
+ BL::Node b_node(ptr);
+ if (b_node.is_a(&RNA_ShaderNodeTexPointDensity)) {
+ BL::ShaderNodeTexPointDensity b_point_density_node(b_node);
+ metadata.channels = 4;
+ metadata.width = b_point_density_node.resolution();
+ metadata.height = metadata.width;
+ metadata.depth = metadata.width;
+ metadata.is_float = true;
+ }
+ }
}
bool BlenderSession::builtin_image_pixels(const string &builtin_name,
@@ -1198,61 +1216,61 @@ bool BlenderSession::builtin_image_pixels(const string &builtin_name,
const size_t pixels_size,
const bool free_cache)
{
- if(!builtin_data) {
- return false;
- }
-
- const int frame = builtin_image_frame(builtin_name);
-
- PointerRNA ptr;
- RNA_id_pointer_create((ID*)builtin_data, &ptr);
- BL::Image b_image(ptr);
-
- const int width = b_image.size()[0];
- const int height = b_image.size()[1];
- const int channels = b_image.channels();
-
- unsigned char *image_pixels = image_get_pixels_for_frame(b_image, frame);
- const size_t num_pixels = ((size_t)width) * height;
-
- if(image_pixels && num_pixels * channels == pixels_size) {
- memcpy(pixels, image_pixels, pixels_size * sizeof(unsigned char));
- }
- else {
- if(channels == 1) {
- memset(pixels, 0, pixels_size * sizeof(unsigned char));
- }
- else {
- const size_t num_pixels_safe = pixels_size / channels;
- unsigned char *cp = pixels;
- for(size_t i = 0; i < num_pixels_safe; i++, cp += channels) {
- cp[0] = 255;
- cp[1] = 0;
- cp[2] = 255;
- if(channels == 4) {
- cp[3] = 255;
- }
- }
- }
- }
-
- if(image_pixels) {
- MEM_freeN(image_pixels);
- }
-
- /* Free image buffers to save memory during render. */
- if(free_cache) {
- b_image.buffers_free();
- }
-
- /* Premultiply, byte images are always straight for Blender. */
- unsigned char *cp = pixels;
- for(size_t i = 0; i < num_pixels; i++, cp += channels) {
- cp[0] = (cp[0] * cp[3]) >> 8;
- cp[1] = (cp[1] * cp[3]) >> 8;
- cp[2] = (cp[2] * cp[3]) >> 8;
- }
- return true;
+ if (!builtin_data) {
+ return false;
+ }
+
+ const int frame = builtin_image_frame(builtin_name);
+
+ PointerRNA ptr;
+ RNA_id_pointer_create((ID *)builtin_data, &ptr);
+ BL::Image b_image(ptr);
+
+ const int width = b_image.size()[0];
+ const int height = b_image.size()[1];
+ const int channels = b_image.channels();
+
+ unsigned char *image_pixels = image_get_pixels_for_frame(b_image, frame);
+ const size_t num_pixels = ((size_t)width) * height;
+
+ if (image_pixels && num_pixels * channels == pixels_size) {
+ memcpy(pixels, image_pixels, pixels_size * sizeof(unsigned char));
+ }
+ else {
+ if (channels == 1) {
+ memset(pixels, 0, pixels_size * sizeof(unsigned char));
+ }
+ else {
+ const size_t num_pixels_safe = pixels_size / channels;
+ unsigned char *cp = pixels;
+ for (size_t i = 0; i < num_pixels_safe; i++, cp += channels) {
+ cp[0] = 255;
+ cp[1] = 0;
+ cp[2] = 255;
+ if (channels == 4) {
+ cp[3] = 255;
+ }
+ }
+ }
+ }
+
+ if (image_pixels) {
+ MEM_freeN(image_pixels);
+ }
+
+ /* Free image buffers to save memory during render. */
+ if (free_cache) {
+ b_image.buffers_free();
+ }
+
+ /* Premultiply, byte images are always straight for Blender. */
+ unsigned char *cp = pixels;
+ for (size_t i = 0; i < num_pixels; i++, cp += channels) {
+ cp[0] = (cp[0] * cp[3]) >> 8;
+ cp[1] = (cp[1] * cp[3]) >> 8;
+ cp[2] = (cp[2] * cp[3]) >> 8;
+ }
+ return true;
}
bool BlenderSession::builtin_image_float_pixels(const string &builtin_name,
@@ -1261,225 +1279,225 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name,
const size_t pixels_size,
const bool free_cache)
{
- if(!builtin_data) {
- return false;
- }
-
- PointerRNA ptr;
- RNA_id_pointer_create((ID*)builtin_data, &ptr);
- BL::ID b_id(ptr);
-
- if(b_id.is_a(&RNA_Image)) {
- /* image data */
- BL::Image b_image(b_id);
- int frame = builtin_image_frame(builtin_name);
-
- const int width = b_image.size()[0];
- const int height = b_image.size()[1];
- const int channels = b_image.channels();
-
- float *image_pixels;
- image_pixels = image_get_float_pixels_for_frame(b_image, frame);
- const size_t num_pixels = ((size_t)width) * height;
-
- if(image_pixels && num_pixels * channels == pixels_size) {
- memcpy(pixels, image_pixels, pixels_size * sizeof(float));
- }
- else {
- if(channels == 1) {
- memset(pixels, 0, num_pixels * sizeof(float));
- }
- else {
- const size_t num_pixels_safe = pixels_size / channels;
- float *fp = pixels;
- for(int i = 0; i < num_pixels_safe; i++, fp += channels) {
- fp[0] = 1.0f;
- fp[1] = 0.0f;
- fp[2] = 1.0f;
- if(channels == 4) {
- fp[3] = 1.0f;
- }
- }
- }
- }
-
- if(image_pixels) {
- MEM_freeN(image_pixels);
- }
-
- /* Free image buffers to save memory during render. */
- if(free_cache) {
- b_image.buffers_free();
- }
-
- return true;
- }
- else if(b_id.is_a(&RNA_Object)) {
- /* smoke volume data */
- BL::Object b_ob(b_id);
- BL::SmokeDomainSettings b_domain = object_smoke_domain_find(b_ob);
-
- if(!b_domain) {
- return false;
- }
-
- int3 resolution = get_int3(b_domain.domain_resolution());
- int length, amplify = (b_domain.use_high_resolution())? b_domain.amplify() + 1: 1;
-
- /* Velocity and heat data is always low-resolution. */
- if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY) ||
- builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT))
- {
- amplify = 1;
- }
-
- const int width = resolution.x * amplify;
- const int height = resolution.y * amplify;
- const int depth = resolution.z * amplify;
- const size_t num_pixels = ((size_t)width) * height * depth;
-
- if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_DENSITY)) {
- SmokeDomainSettings_density_grid_get_length(&b_domain.ptr, &length);
- if(length == num_pixels) {
- SmokeDomainSettings_density_grid_get(&b_domain.ptr, pixels);
- return true;
- }
- }
- else if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_FLAME)) {
- /* this is in range 0..1, and interpreted by the OpenGL smoke viewer
- * as 1500..3000 K with the first part faded to zero density */
- SmokeDomainSettings_flame_grid_get_length(&b_domain.ptr, &length);
- if(length == num_pixels) {
- SmokeDomainSettings_flame_grid_get(&b_domain.ptr, pixels);
- return true;
- }
- }
- else if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_COLOR)) {
- /* the RGB is "premultiplied" by density for better interpolation results */
- SmokeDomainSettings_color_grid_get_length(&b_domain.ptr, &length);
- if(length == num_pixels*4) {
- SmokeDomainSettings_color_grid_get(&b_domain.ptr, pixels);
- return true;
- }
- }
- else if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY)) {
- SmokeDomainSettings_velocity_grid_get_length(&b_domain.ptr, &length);
- if(length == num_pixels*3) {
- SmokeDomainSettings_velocity_grid_get(&b_domain.ptr, pixels);
- return true;
- }
- }
- else if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT)) {
- SmokeDomainSettings_heat_grid_get_length(&b_domain.ptr, &length);
- if(length == num_pixels) {
- SmokeDomainSettings_heat_grid_get(&b_domain.ptr, pixels);
- return true;
- }
- }
- else if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_TEMPERATURE)) {
- SmokeDomainSettings_temperature_grid_get_length(&b_domain.ptr, &length);
- if(length == num_pixels) {
- SmokeDomainSettings_temperature_grid_get(&b_domain.ptr, pixels);
- return true;
- }
- }
- else {
- fprintf(stderr,
- "Cycles error: unknown volume attribute %s, skipping\n",
- builtin_name.c_str());
- pixels[0] = 0.0f;
- return false;
- }
-
- fprintf(stderr, "Cycles error: unexpected smoke volume resolution, skipping\n");
- }
- else {
- /* We originally were passing view_layer here but in reality we need a
- * a depsgraph to pass to the RE_point_density_minmax() function.
- */
- /* TODO(sergey): Check we're indeed in shader node tree. */
- PointerRNA ptr;
- RNA_pointer_create(NULL, &RNA_Node, builtin_data, &ptr);
- BL::Node b_node(ptr);
- if(b_node.is_a(&RNA_ShaderNodeTexPointDensity)) {
- BL::ShaderNodeTexPointDensity b_point_density_node(b_node);
- int length;
- b_point_density_node.calc_point_density(b_depsgraph, &length, &pixels);
- }
- }
-
- return false;
+ if (!builtin_data) {
+ return false;
+ }
+
+ PointerRNA ptr;
+ RNA_id_pointer_create((ID *)builtin_data, &ptr);
+ BL::ID b_id(ptr);
+
+ if (b_id.is_a(&RNA_Image)) {
+ /* image data */
+ BL::Image b_image(b_id);
+ int frame = builtin_image_frame(builtin_name);
+
+ const int width = b_image.size()[0];
+ const int height = b_image.size()[1];
+ const int channels = b_image.channels();
+
+ float *image_pixels;
+ image_pixels = image_get_float_pixels_for_frame(b_image, frame);
+ const size_t num_pixels = ((size_t)width) * height;
+
+ if (image_pixels && num_pixels * channels == pixels_size) {
+ memcpy(pixels, image_pixels, pixels_size * sizeof(float));
+ }
+ else {
+ if (channels == 1) {
+ memset(pixels, 0, num_pixels * sizeof(float));
+ }
+ else {
+ const size_t num_pixels_safe = pixels_size / channels;
+ float *fp = pixels;
+ for (int i = 0; i < num_pixels_safe; i++, fp += channels) {
+ fp[0] = 1.0f;
+ fp[1] = 0.0f;
+ fp[2] = 1.0f;
+ if (channels == 4) {
+ fp[3] = 1.0f;
+ }
+ }
+ }
+ }
+
+ if (image_pixels) {
+ MEM_freeN(image_pixels);
+ }
+
+ /* Free image buffers to save memory during render. */
+ if (free_cache) {
+ b_image.buffers_free();
+ }
+
+ return true;
+ }
+ else if (b_id.is_a(&RNA_Object)) {
+ /* smoke volume data */
+ BL::Object b_ob(b_id);
+ BL::SmokeDomainSettings b_domain = object_smoke_domain_find(b_ob);
+
+ if (!b_domain) {
+ return false;
+ }
+
+ int3 resolution = get_int3(b_domain.domain_resolution());
+ int length, amplify = (b_domain.use_high_resolution()) ? b_domain.amplify() + 1 : 1;
+
+ /* Velocity and heat data is always low-resolution. */
+ if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY) ||
+ builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT)) {
+ amplify = 1;
+ }
+
+ const int width = resolution.x * amplify;
+ const int height = resolution.y * amplify;
+ const int depth = resolution.z * amplify;
+ const size_t num_pixels = ((size_t)width) * height * depth;
+
+ if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_DENSITY)) {
+ SmokeDomainSettings_density_grid_get_length(&b_domain.ptr, &length);
+ if (length == num_pixels) {
+ SmokeDomainSettings_density_grid_get(&b_domain.ptr, pixels);
+ return true;
+ }
+ }
+ else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_FLAME)) {
+ /* this is in range 0..1, and interpreted by the OpenGL smoke viewer
+ * as 1500..3000 K with the first part faded to zero density */
+ SmokeDomainSettings_flame_grid_get_length(&b_domain.ptr, &length);
+ if (length == num_pixels) {
+ SmokeDomainSettings_flame_grid_get(&b_domain.ptr, pixels);
+ return true;
+ }
+ }
+ else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_COLOR)) {
+ /* the RGB is "premultiplied" by density for better interpolation results */
+ SmokeDomainSettings_color_grid_get_length(&b_domain.ptr, &length);
+ if (length == num_pixels * 4) {
+ SmokeDomainSettings_color_grid_get(&b_domain.ptr, pixels);
+ return true;
+ }
+ }
+ else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY)) {
+ SmokeDomainSettings_velocity_grid_get_length(&b_domain.ptr, &length);
+ if (length == num_pixels * 3) {
+ SmokeDomainSettings_velocity_grid_get(&b_domain.ptr, pixels);
+ return true;
+ }
+ }
+ else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT)) {
+ SmokeDomainSettings_heat_grid_get_length(&b_domain.ptr, &length);
+ if (length == num_pixels) {
+ SmokeDomainSettings_heat_grid_get(&b_domain.ptr, pixels);
+ return true;
+ }
+ }
+ else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_TEMPERATURE)) {
+ SmokeDomainSettings_temperature_grid_get_length(&b_domain.ptr, &length);
+ if (length == num_pixels) {
+ SmokeDomainSettings_temperature_grid_get(&b_domain.ptr, pixels);
+ return true;
+ }
+ }
+ else {
+ fprintf(
+ stderr, "Cycles error: unknown volume attribute %s, skipping\n", builtin_name.c_str());
+ pixels[0] = 0.0f;
+ return false;
+ }
+
+ fprintf(stderr, "Cycles error: unexpected smoke volume resolution, skipping\n");
+ }
+ else {
+ /* We originally were passing view_layer here but in reality we need a
+ * a depsgraph to pass to the RE_point_density_minmax() function.
+ */
+ /* TODO(sergey): Check we're indeed in shader node tree. */
+ PointerRNA ptr;
+ RNA_pointer_create(NULL, &RNA_Node, builtin_data, &ptr);
+ BL::Node b_node(ptr);
+ if (b_node.is_a(&RNA_ShaderNodeTexPointDensity)) {
+ BL::ShaderNodeTexPointDensity b_point_density_node(b_node);
+ int length;
+ b_point_density_node.calc_point_density(b_depsgraph, &length, &pixels);
+ }
+ }
+
+ return false;
}
void BlenderSession::builtin_images_load()
{
- /* Force builtin images to be loaded along with Blender data sync. This
- * is needed because we may be reading from depsgraph evaluated data which
- * can be freed by Blender before Cycles reads it. */
- ImageManager *manager = session->scene->image_manager;
- Device *device = session->device;
- manager->device_load_builtin(device, session->scene, session->progress);
+ /* Force builtin images to be loaded along with Blender data sync. This
+ * is needed because we may be reading from depsgraph evaluated data which
+ * can be freed by Blender before Cycles reads it. */
+ ImageManager *manager = session->scene->image_manager;
+ Device *device = session->device;
+ manager->device_load_builtin(device, session->scene, session->progress);
}
void BlenderSession::update_resumable_tile_manager(int num_samples)
{
- const int num_resumable_chunks = BlenderSession::num_resumable_chunks,
- current_resumable_chunk = BlenderSession::current_resumable_chunk;
- if(num_resumable_chunks == 0) {
- return;
- }
-
- if (num_resumable_chunks > num_samples) {
- fprintf(stderr, "Cycles warning: more sample chunks (%d) than samples (%d), "
- "this will cause some samples to be included in multiple chunks.\n",
- num_resumable_chunks, num_samples);
- }
-
- const float num_samples_per_chunk = (float)num_samples / num_resumable_chunks;
-
- float range_start_sample, range_num_samples;
- if(current_resumable_chunk != 0) {
- /* Single chunk rendering. */
- range_start_sample = num_samples_per_chunk * (current_resumable_chunk - 1);
- range_num_samples = num_samples_per_chunk;
- }
- else {
- /* Ranged-chunks. */
- const int num_chunks = end_resumable_chunk - start_resumable_chunk + 1;
- range_start_sample = num_samples_per_chunk * (start_resumable_chunk - 1);
- range_num_samples = num_chunks * num_samples_per_chunk;
- }
-
- /* Round after doing the multiplications with num_chunks and num_samples_per_chunk
- * to allow for many small chunks. */
- int rounded_range_start_sample = (int)floor(range_start_sample + 0.5f);
- int rounded_range_num_samples = max((int)floor(range_num_samples + 0.5f), 1);
-
- /* Make sure we don't overshoot. */
- if(rounded_range_start_sample + rounded_range_num_samples > num_samples) {
- rounded_range_num_samples = num_samples - rounded_range_num_samples;
- }
-
- VLOG(1) << "Samples range start is " << range_start_sample << ", "
- << "number of samples to render is " << range_num_samples;
-
- scene->integrator->start_sample = rounded_range_start_sample;
- scene->integrator->tag_update(scene);
-
- session->tile_manager.range_start_sample = rounded_range_start_sample;
- session->tile_manager.range_num_samples = rounded_range_num_samples;
+ const int num_resumable_chunks = BlenderSession::num_resumable_chunks,
+ current_resumable_chunk = BlenderSession::current_resumable_chunk;
+ if (num_resumable_chunks == 0) {
+ return;
+ }
+
+ if (num_resumable_chunks > num_samples) {
+ fprintf(stderr,
+ "Cycles warning: more sample chunks (%d) than samples (%d), "
+ "this will cause some samples to be included in multiple chunks.\n",
+ num_resumable_chunks,
+ num_samples);
+ }
+
+ const float num_samples_per_chunk = (float)num_samples / num_resumable_chunks;
+
+ float range_start_sample, range_num_samples;
+ if (current_resumable_chunk != 0) {
+ /* Single chunk rendering. */
+ range_start_sample = num_samples_per_chunk * (current_resumable_chunk - 1);
+ range_num_samples = num_samples_per_chunk;
+ }
+ else {
+ /* Ranged-chunks. */
+ const int num_chunks = end_resumable_chunk - start_resumable_chunk + 1;
+ range_start_sample = num_samples_per_chunk * (start_resumable_chunk - 1);
+ range_num_samples = num_chunks * num_samples_per_chunk;
+ }
+
+ /* Round after doing the multiplications with num_chunks and num_samples_per_chunk
+ * to allow for many small chunks. */
+ int rounded_range_start_sample = (int)floor(range_start_sample + 0.5f);
+ int rounded_range_num_samples = max((int)floor(range_num_samples + 0.5f), 1);
+
+ /* Make sure we don't overshoot. */
+ if (rounded_range_start_sample + rounded_range_num_samples > num_samples) {
+ rounded_range_num_samples = num_samples - rounded_range_num_samples;
+ }
+
+ VLOG(1) << "Samples range start is " << range_start_sample << ", "
+ << "number of samples to render is " << range_num_samples;
+
+ scene->integrator->start_sample = rounded_range_start_sample;
+ scene->integrator->tag_update(scene);
+
+ session->tile_manager.range_start_sample = rounded_range_start_sample;
+ session->tile_manager.range_num_samples = rounded_range_num_samples;
}
void BlenderSession::free_blender_memory_if_possible()
{
- if(!background) {
- /* During interactive render we can not free anything: attempts to save
- * memory would cause things to be allocated and evaluated for every
- * updated sample.
- */
- return;
- }
- b_engine.free_blender_memory();
+ if (!background) {
+ /* During interactive render we can not free anything: attempts to save
+ * memory would cause things to be allocated and evaluated for every
+ * updated sample.
+ */
+ return;
+ }
+ b_engine.free_blender_memory();
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h
index 2bfb9e56c37..f0107d4e0b1 100644
--- a/intern/cycles/blender/blender_session.h
+++ b/intern/cycles/blender/blender_session.h
@@ -33,159 +33,153 @@ class RenderBuffers;
class RenderTile;
class BlenderSession {
-public:
- BlenderSession(BL::RenderEngine& b_engine,
- BL::Preferences& b_userpref,
- BL::BlendData& b_data,
- bool preview_osl);
-
- BlenderSession(BL::RenderEngine& b_engine,
- BL::Preferences& b_userpref,
- BL::BlendData& b_data,
- BL::SpaceView3D& b_v3d,
- BL::RegionView3D& b_rv3d,
- int width, int height);
-
- ~BlenderSession();
-
- void create();
-
- /* session */
- void create_session();
- void free_session();
-
- void reset_session(BL::BlendData& b_data,
- BL::Depsgraph& b_depsgraph);
-
- /* offline render */
- void render(BL::Depsgraph& b_depsgraph);
-
- void bake(BL::Depsgraph& b_depsgrah,
- BL::Object& b_object,
- const string& pass_type,
- const int custom_flag,
- const int object_id,
- 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);
-
- /* update functions are used to update display buffer only after sample was rendered
- * only needed for better visual feedback */
- void update_render_result(BL::RenderResult& b_rr,
- BL::RenderLayer& b_rlay,
- RenderTile& rtile);
- void update_render_tile(RenderTile& rtile, bool highlight);
-
- /* interactive updates */
- void synchronize(BL::Depsgraph& b_depsgraph);
-
- /* drawing */
- bool draw(int w, int h);
- void tag_redraw();
- void tag_update();
- void get_status(string& status, string& substatus);
- void get_kernel_status(string& kernel_status);
- void get_progress(float& progress, double& total_time, double& render_time);
- void test_cancel();
- void update_status_progress();
- void update_bake_progress();
-
- bool background;
- Session *session;
- Scene *scene;
- BlenderSync *sync;
- double last_redraw_time;
-
- BL::RenderEngine b_engine;
- BL::Preferences b_userpref;
- BL::BlendData b_data;
- BL::RenderSettings b_render;
- BL::Depsgraph b_depsgraph;
- /* NOTE: Blender's scene might become invalid after call
- * free_blender_memory_if_possible().
- */
- BL::Scene b_scene;
- BL::SpaceView3D b_v3d;
- BL::RegionView3D b_rv3d;
- string b_rlay_name;
- string b_rview_name;
-
- string last_status;
- string last_error;
- float last_progress;
- double last_status_time;
-
- int width, height;
- bool preview_osl;
- double start_resize_time;
-
- void *python_thread_state;
-
- /* Global state which is common for all render sessions created from Blender.
- * Usually denotes command line arguments.
- */
-
- /* Blender is running from the command line, no windows are shown and some
- * extra render optimization is possible (possible to free draw-only data and
- * so on.
- */
- static bool headless;
-
- /* ** Resumable render ** */
-
- /* Overall number of chunks in which the sample range is to be devided. */
- static int num_resumable_chunks;
-
- /* Current resumable chunk index to render. */
- static int current_resumable_chunk;
-
- /* Alternative to single-chunk rendering to render a range of chunks. */
- static int start_resumable_chunk;
- static int end_resumable_chunk;
-
- static bool print_render_stats;
-
-protected:
- void stamp_view_layer_metadata(Scene *scene, const string& view_layer_name);
-
- void do_write_update_render_result(BL::RenderResult& b_rr,
- BL::RenderLayer& b_rlay,
- RenderTile& rtile,
- bool do_update_only);
- void do_write_update_render_tile(RenderTile& rtile, bool do_update_only, bool highlight);
-
- int builtin_image_frame(const string &builtin_name);
- void builtin_image_info(const string &builtin_name,
- void *builtin_data,
- ImageMetaData& metadata);
- bool builtin_image_pixels(const string &builtin_name,
- void *builtin_data,
- unsigned char *pixels,
- const size_t pixels_size,
- const bool free_cache);
- bool builtin_image_float_pixels(const string &builtin_name,
- void *builtin_data,
- float *pixels,
- const size_t pixels_size,
- const bool free_cache);
- void builtin_images_load();
-
- /* Update tile manager to reflect resumable render settings. */
- void update_resumable_tile_manager(int num_samples);
-
- /* Is used after each render layer synchronization is done with the goal
- * of freeing render engine data which is held from Blender side (for
- * example, dependency graph).
- */
- void free_blender_memory_if_possible();
+ public:
+ BlenderSession(BL::RenderEngine &b_engine,
+ BL::Preferences &b_userpref,
+ BL::BlendData &b_data,
+ bool preview_osl);
+
+ BlenderSession(BL::RenderEngine &b_engine,
+ BL::Preferences &b_userpref,
+ BL::BlendData &b_data,
+ BL::SpaceView3D &b_v3d,
+ BL::RegionView3D &b_rv3d,
+ int width,
+ int height);
+
+ ~BlenderSession();
+
+ void create();
+
+ /* session */
+ void create_session();
+ void free_session();
+
+ void reset_session(BL::BlendData &b_data, BL::Depsgraph &b_depsgraph);
+
+ /* offline render */
+ void render(BL::Depsgraph &b_depsgraph);
+
+ void bake(BL::Depsgraph &b_depsgrah,
+ BL::Object &b_object,
+ const string &pass_type,
+ const int custom_flag,
+ const int object_id,
+ 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);
+
+ /* update functions are used to update display buffer only after sample was rendered
+ * only needed for better visual feedback */
+ void update_render_result(BL::RenderResult &b_rr, BL::RenderLayer &b_rlay, RenderTile &rtile);
+ void update_render_tile(RenderTile &rtile, bool highlight);
+
+ /* interactive updates */
+ void synchronize(BL::Depsgraph &b_depsgraph);
+
+ /* drawing */
+ bool draw(int w, int h);
+ void tag_redraw();
+ void tag_update();
+ void get_status(string &status, string &substatus);
+ void get_kernel_status(string &kernel_status);
+ void get_progress(float &progress, double &total_time, double &render_time);
+ void test_cancel();
+ void update_status_progress();
+ void update_bake_progress();
+
+ bool background;
+ Session *session;
+ Scene *scene;
+ BlenderSync *sync;
+ double last_redraw_time;
+
+ BL::RenderEngine b_engine;
+ BL::Preferences b_userpref;
+ BL::BlendData b_data;
+ BL::RenderSettings b_render;
+ BL::Depsgraph b_depsgraph;
+ /* NOTE: Blender's scene might become invalid after call
+ * free_blender_memory_if_possible().
+ */
+ BL::Scene b_scene;
+ BL::SpaceView3D b_v3d;
+ BL::RegionView3D b_rv3d;
+ string b_rlay_name;
+ string b_rview_name;
+
+ string last_status;
+ string last_error;
+ float last_progress;
+ double last_status_time;
+
+ int width, height;
+ bool preview_osl;
+ double start_resize_time;
+
+ void *python_thread_state;
+
+ /* Global state which is common for all render sessions created from Blender.
+ * Usually denotes command line arguments.
+ */
+
+ /* Blender is running from the command line, no windows are shown and some
+ * extra render optimization is possible (possible to free draw-only data and
+ * so on.
+ */
+ static bool headless;
+
+ /* ** Resumable render ** */
+
+ /* Overall number of chunks in which the sample range is to be devided. */
+ static int num_resumable_chunks;
+
+ /* Current resumable chunk index to render. */
+ static int current_resumable_chunk;
+
+ /* Alternative to single-chunk rendering to render a range of chunks. */
+ static int start_resumable_chunk;
+ static int end_resumable_chunk;
+
+ static bool print_render_stats;
+
+ protected:
+ void stamp_view_layer_metadata(Scene *scene, const string &view_layer_name);
+
+ void do_write_update_render_result(BL::RenderResult &b_rr,
+ BL::RenderLayer &b_rlay,
+ RenderTile &rtile,
+ bool do_update_only);
+ void do_write_update_render_tile(RenderTile &rtile, bool do_update_only, bool highlight);
+
+ int builtin_image_frame(const string &builtin_name);
+ void builtin_image_info(const string &builtin_name, void *builtin_data, ImageMetaData &metadata);
+ bool builtin_image_pixels(const string &builtin_name,
+ void *builtin_data,
+ unsigned char *pixels,
+ const size_t pixels_size,
+ const bool free_cache);
+ bool builtin_image_float_pixels(const string &builtin_name,
+ void *builtin_data,
+ float *pixels,
+ const size_t pixels_size,
+ const bool free_cache);
+ void builtin_images_load();
+
+ /* Update tile manager to reflect resumable render settings. */
+ void update_resumable_tile_manager(int num_samples);
+
+ /* Is used after each render layer synchronization is done with the goal
+ * of freeing render engine data which is held from Blender side (for
+ * example, dependency graph).
+ */
+ void free_blender_memory_if_possible();
};
CCL_NAMESPACE_END
-#endif /* __BLENDER_SESSION_H__ */
+#endif /* __BLENDER_SESSION_H__ */
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index 44ff29d4bf8..169c4d414a6 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -34,1449 +34,1416 @@
CCL_NAMESPACE_BEGIN
-typedef map<void*, ShaderInput*> PtrInputMap;
-typedef map<void*, ShaderOutput*> PtrOutputMap;
-typedef map<string, ConvertNode*> ProxyMap;
+typedef map<void *, ShaderInput *> PtrInputMap;
+typedef map<void *, ShaderOutput *> PtrOutputMap;
+typedef map<string, ConvertNode *> ProxyMap;
/* Find */
-void BlenderSync::find_shader(BL::ID& id,
- vector<Shader*>& used_shaders,
- Shader *default_shader)
+void BlenderSync::find_shader(BL::ID &id, vector<Shader *> &used_shaders, Shader *default_shader)
{
- Shader *shader = (id)? shader_map.find(id): default_shader;
+ Shader *shader = (id) ? shader_map.find(id) : default_shader;
- used_shaders.push_back(shader);
- shader->tag_used(scene);
+ used_shaders.push_back(shader);
+ shader->tag_used(scene);
}
/* RNA translation utilities */
-static VolumeSampling get_volume_sampling(PointerRNA& ptr)
+static VolumeSampling get_volume_sampling(PointerRNA &ptr)
{
- return (VolumeSampling)get_enum(ptr,
- "volume_sampling",
- VOLUME_NUM_SAMPLING,
- VOLUME_SAMPLING_DISTANCE);
+ return (VolumeSampling)get_enum(
+ ptr, "volume_sampling", VOLUME_NUM_SAMPLING, VOLUME_SAMPLING_DISTANCE);
}
-static VolumeInterpolation get_volume_interpolation(PointerRNA& ptr)
+static VolumeInterpolation get_volume_interpolation(PointerRNA &ptr)
{
- return (VolumeInterpolation)get_enum(ptr,
- "volume_interpolation",
- VOLUME_NUM_INTERPOLATION,
- VOLUME_INTERPOLATION_LINEAR);
+ return (VolumeInterpolation)get_enum(
+ ptr, "volume_interpolation", VOLUME_NUM_INTERPOLATION, VOLUME_INTERPOLATION_LINEAR);
}
-static DisplacementMethod get_displacement_method(PointerRNA& ptr)
+static DisplacementMethod get_displacement_method(PointerRNA &ptr)
{
- return (DisplacementMethod)get_enum(ptr,
- "displacement_method",
- DISPLACE_NUM_METHODS,
- DISPLACE_BUMP);
+ 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) {
- return default_value;
- }
- return value;
+ if (value >= num_values) {
+ return default_value;
+ }
+ return value;
}
-template<typename NodeType>
-static InterpolationType get_image_interpolation(NodeType& b_node)
+template<typename NodeType> static InterpolationType get_image_interpolation(NodeType &b_node)
{
- int value = b_node.interpolation();
- return (InterpolationType)validate_enum_value(value,
- INTERPOLATION_NUM_TYPES,
- INTERPOLATION_LINEAR);
+ int value = b_node.interpolation();
+ return (InterpolationType)validate_enum_value(
+ value, INTERPOLATION_NUM_TYPES, INTERPOLATION_LINEAR);
}
-template<typename NodeType>
-static ExtensionType get_image_extension(NodeType& b_node)
+template<typename NodeType> static ExtensionType get_image_extension(NodeType &b_node)
{
- int value = b_node.extension();
- return (ExtensionType)validate_enum_value(value,
- EXTENSION_NUM_TYPES,
- EXTENSION_REPEAT);
+ int value = b_node.extension();
+ return (ExtensionType)validate_enum_value(value, EXTENSION_NUM_TYPES, EXTENSION_REPEAT);
}
/* Graph */
-static BL::NodeSocket get_node_output(BL::Node& b_node, const string& name)
+static BL::NodeSocket get_node_output(BL::Node &b_node, const string &name)
{
- BL::Node::outputs_iterator b_out;
+ BL::Node::outputs_iterator b_out;
- for(b_node.outputs.begin(b_out); b_out != b_node.outputs.end(); ++b_out)
- if(b_out->name() == name)
- return *b_out;
+ for (b_node.outputs.begin(b_out); b_out != b_node.outputs.end(); ++b_out)
+ if (b_out->name() == name)
+ return *b_out;
- assert(0);
+ assert(0);
- return *b_out;
+ return *b_out;
}
-static float3 get_node_output_rgba(BL::Node& b_node, const string& name)
+static float3 get_node_output_rgba(BL::Node &b_node, const string &name)
{
- BL::NodeSocket b_sock = get_node_output(b_node, name);
- float value[4];
- RNA_float_get_array(&b_sock.ptr, "default_value", value);
- return make_float3(value[0], value[1], value[2]);
+ BL::NodeSocket b_sock = get_node_output(b_node, name);
+ float value[4];
+ RNA_float_get_array(&b_sock.ptr, "default_value", value);
+ return make_float3(value[0], value[1], value[2]);
}
-static float get_node_output_value(BL::Node& b_node, const string& name)
+static float get_node_output_value(BL::Node &b_node, const string &name)
{
- BL::NodeSocket b_sock = get_node_output(b_node, name);
- return RNA_float_get(&b_sock.ptr, "default_value");
+ BL::NodeSocket b_sock = get_node_output(b_node, name);
+ return RNA_float_get(&b_sock.ptr, "default_value");
}
-static float3 get_node_output_vector(BL::Node& b_node, const string& name)
+static float3 get_node_output_vector(BL::Node &b_node, const string &name)
{
- BL::NodeSocket b_sock = get_node_output(b_node, name);
- float value[3];
- RNA_float_get_array(&b_sock.ptr, "default_value", value);
- return make_float3(value[0], value[1], value[2]);
+ BL::NodeSocket b_sock = get_node_output(b_node, name);
+ float value[3];
+ RNA_float_get_array(&b_sock.ptr, "default_value", value);
+ return make_float3(value[0], value[1], value[2]);
}
-static SocketType::Type convert_socket_type(BL::NodeSocket& b_socket)
+static SocketType::Type convert_socket_type(BL::NodeSocket &b_socket)
{
- switch(b_socket.type()) {
- case BL::NodeSocket::type_VALUE:
- return SocketType::FLOAT;
- case BL::NodeSocket::type_INT:
- return SocketType::INT;
- case BL::NodeSocket::type_VECTOR:
- return SocketType::VECTOR;
- case BL::NodeSocket::type_RGBA:
- return SocketType::COLOR;
- case BL::NodeSocket::type_STRING:
- return SocketType::STRING;
- case BL::NodeSocket::type_SHADER:
- return SocketType::CLOSURE;
-
- default:
- return SocketType::UNDEFINED;
- }
+ switch (b_socket.type()) {
+ case BL::NodeSocket::type_VALUE:
+ return SocketType::FLOAT;
+ case BL::NodeSocket::type_INT:
+ return SocketType::INT;
+ case BL::NodeSocket::type_VECTOR:
+ return SocketType::VECTOR;
+ case BL::NodeSocket::type_RGBA:
+ return SocketType::COLOR;
+ case BL::NodeSocket::type_STRING:
+ return SocketType::STRING;
+ case BL::NodeSocket::type_SHADER:
+ return SocketType::CLOSURE;
+
+ default:
+ return SocketType::UNDEFINED;
+ }
}
static void set_default_value(ShaderInput *input,
- BL::NodeSocket& b_sock,
- BL::BlendData& b_data,
- BL::ID& b_id)
+ BL::NodeSocket &b_sock,
+ BL::BlendData &b_data,
+ BL::ID &b_id)
{
- Node *node = input->parent;
- const SocketType& socket = input->socket_type;
-
- /* copy values for non linked inputs */
- switch(input->type()) {
- case SocketType::FLOAT: {
- node->set(socket, get_float(b_sock.ptr, "default_value"));
- break;
- }
- case SocketType::INT: {
- node->set(socket, get_int(b_sock.ptr, "default_value"));
- break;
- }
- case SocketType::COLOR: {
- node->set(socket, float4_to_float3(get_float4(b_sock.ptr, "default_value")));
- break;
- }
- case SocketType::NORMAL:
- case SocketType::POINT:
- case SocketType::VECTOR: {
- node->set(socket, get_float3(b_sock.ptr, "default_value"));
- break;
- }
- case SocketType::STRING: {
- node->set(socket, (ustring)blender_absolute_path(b_data, b_id, get_string(b_sock.ptr, "default_value")));
- break;
- }
- default:
- break;
- }
+ Node *node = input->parent;
+ const SocketType &socket = input->socket_type;
+
+ /* copy values for non linked inputs */
+ switch (input->type()) {
+ case SocketType::FLOAT: {
+ node->set(socket, get_float(b_sock.ptr, "default_value"));
+ break;
+ }
+ case SocketType::INT: {
+ node->set(socket, get_int(b_sock.ptr, "default_value"));
+ break;
+ }
+ case SocketType::COLOR: {
+ node->set(socket, float4_to_float3(get_float4(b_sock.ptr, "default_value")));
+ break;
+ }
+ case SocketType::NORMAL:
+ case SocketType::POINT:
+ case SocketType::VECTOR: {
+ node->set(socket, get_float3(b_sock.ptr, "default_value"));
+ break;
+ }
+ case SocketType::STRING: {
+ node->set(
+ socket,
+ (ustring)blender_absolute_path(b_data, b_id, get_string(b_sock.ptr, "default_value")));
+ break;
+ }
+ default:
+ break;
+ }
}
-static void get_tex_mapping(TextureMapping *mapping, BL::TexMapping& b_mapping)
+static void get_tex_mapping(TextureMapping *mapping, BL::TexMapping &b_mapping)
{
- if(!b_mapping)
- return;
+ if (!b_mapping)
+ return;
- mapping->translation = get_float3(b_mapping.translation());
- mapping->rotation = get_float3(b_mapping.rotation());
- mapping->scale = get_float3(b_mapping.scale());
- mapping->type = (TextureMapping::Type)b_mapping.vector_type();
+ mapping->translation = get_float3(b_mapping.translation());
+ mapping->rotation = get_float3(b_mapping.rotation());
+ mapping->scale = get_float3(b_mapping.scale());
+ mapping->type = (TextureMapping::Type)b_mapping.vector_type();
- mapping->x_mapping = (TextureMapping::Mapping)b_mapping.mapping_x();
- mapping->y_mapping = (TextureMapping::Mapping)b_mapping.mapping_y();
- mapping->z_mapping = (TextureMapping::Mapping)b_mapping.mapping_z();
+ mapping->x_mapping = (TextureMapping::Mapping)b_mapping.mapping_x();
+ mapping->y_mapping = (TextureMapping::Mapping)b_mapping.mapping_y();
+ mapping->z_mapping = (TextureMapping::Mapping)b_mapping.mapping_z();
}
-static void get_tex_mapping(TextureMapping *mapping,
- BL::ShaderNodeMapping& b_mapping)
+static void get_tex_mapping(TextureMapping *mapping, BL::ShaderNodeMapping &b_mapping)
{
- if(!b_mapping)
- return;
+ if (!b_mapping)
+ return;
- mapping->translation = get_float3(b_mapping.translation());
- mapping->rotation = get_float3(b_mapping.rotation());
- mapping->scale = get_float3(b_mapping.scale());
- mapping->type = (TextureMapping::Type)b_mapping.vector_type();
+ mapping->translation = get_float3(b_mapping.translation());
+ mapping->rotation = get_float3(b_mapping.rotation());
+ mapping->scale = get_float3(b_mapping.scale());
+ mapping->type = (TextureMapping::Type)b_mapping.vector_type();
- mapping->use_minmax = b_mapping.use_min() || b_mapping.use_max();
+ mapping->use_minmax = b_mapping.use_min() || b_mapping.use_max();
- if(b_mapping.use_min())
- mapping->min = get_float3(b_mapping.min());
- if(b_mapping.use_max())
- mapping->max = get_float3(b_mapping.max());
+ if (b_mapping.use_min())
+ mapping->min = get_float3(b_mapping.min());
+ if (b_mapping.use_max())
+ mapping->max = get_float3(b_mapping.max());
}
static ShaderNode *add_node(Scene *scene,
- BL::RenderEngine& b_engine,
- BL::BlendData& b_data,
- BL::Depsgraph& b_depsgraph,
- BL::Scene& b_scene,
+ BL::RenderEngine &b_engine,
+ BL::BlendData &b_data,
+ BL::Depsgraph &b_depsgraph,
+ BL::Scene &b_scene,
ShaderGraph *graph,
- BL::ShaderNodeTree& b_ntree,
- BL::ShaderNode& b_node)
+ BL::ShaderNodeTree &b_ntree,
+ BL::ShaderNode &b_node)
{
- ShaderNode *node = NULL;
-
- /* existing blender nodes */
- if(b_node.is_a(&RNA_ShaderNodeRGBCurve)) {
- BL::ShaderNodeRGBCurve b_curve_node(b_node);
- BL::CurveMapping mapping(b_curve_node.mapping());
- RGBCurvesNode *curves = new RGBCurvesNode();
- curvemapping_color_to_array(mapping,
- curves->curves,
- RAMP_TABLE_SIZE,
- true);
- curvemapping_minmax(mapping, true, &curves->min_x, &curves->max_x);
- node = curves;
- }
- if(b_node.is_a(&RNA_ShaderNodeVectorCurve)) {
- BL::ShaderNodeVectorCurve b_curve_node(b_node);
- BL::CurveMapping mapping(b_curve_node.mapping());
- VectorCurvesNode *curves = new VectorCurvesNode();
- curvemapping_color_to_array(mapping,
- curves->curves,
- RAMP_TABLE_SIZE,
- false);
- curvemapping_minmax(mapping, false, &curves->min_x, &curves->max_x);
- node = curves;
- }
- else if(b_node.is_a(&RNA_ShaderNodeValToRGB)) {
- RGBRampNode *ramp = new RGBRampNode();
- BL::ShaderNodeValToRGB b_ramp_node(b_node);
- BL::ColorRamp b_color_ramp(b_ramp_node.color_ramp());
- colorramp_to_array(b_color_ramp, ramp->ramp, ramp->ramp_alpha, RAMP_TABLE_SIZE);
- ramp->interpolate = b_color_ramp.interpolation() != BL::ColorRamp::interpolation_CONSTANT;
- node = ramp;
- }
- else if(b_node.is_a(&RNA_ShaderNodeRGB)) {
- ColorNode *color = new ColorNode();
- color->value = get_node_output_rgba(b_node, "Color");
- node = color;
- }
- else if(b_node.is_a(&RNA_ShaderNodeValue)) {
- ValueNode *value = new ValueNode();
- value->value = get_node_output_value(b_node, "Value");
- node = value;
- }
- else if(b_node.is_a(&RNA_ShaderNodeCameraData)) {
- node = new CameraNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeInvert)) {
- node = new InvertNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeGamma)) {
- node = new GammaNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeBrightContrast)) {
- node = new BrightContrastNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeMixRGB)) {
- BL::ShaderNodeMixRGB b_mix_node(b_node);
- MixNode *mix = new MixNode();
- mix->type = (NodeMix)b_mix_node.blend_type();
- mix->use_clamp = b_mix_node.use_clamp();
- node = mix;
- }
- else if(b_node.is_a(&RNA_ShaderNodeSeparateRGB)) {
- node = new SeparateRGBNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeCombineRGB)) {
- node = new CombineRGBNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeSeparateHSV)) {
- node = new SeparateHSVNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeCombineHSV)) {
- node = new CombineHSVNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeSeparateXYZ)) {
- node = new SeparateXYZNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeCombineXYZ)) {
- node = new CombineXYZNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeHueSaturation)) {
- node = new HSVNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeRGBToBW)) {
- node = new RGBToBWNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeMath)) {
- BL::ShaderNodeMath b_math_node(b_node);
- MathNode *math = new MathNode();
- math->type = (NodeMath)b_math_node.operation();
- math->use_clamp = b_math_node.use_clamp();
- node = math;
- }
- else if(b_node.is_a(&RNA_ShaderNodeVectorMath)) {
- BL::ShaderNodeVectorMath b_vector_math_node(b_node);
- VectorMathNode *vmath = new VectorMathNode();
- vmath->type = (NodeVectorMath)b_vector_math_node.operation();
- node = vmath;
- }
- else if(b_node.is_a(&RNA_ShaderNodeVectorTransform)) {
- BL::ShaderNodeVectorTransform b_vector_transform_node(b_node);
- VectorTransformNode *vtransform = new VectorTransformNode();
- vtransform->type = (NodeVectorTransformType)b_vector_transform_node.vector_type();
- vtransform->convert_from = (NodeVectorTransformConvertSpace)b_vector_transform_node.convert_from();
- vtransform->convert_to = (NodeVectorTransformConvertSpace)b_vector_transform_node.convert_to();
- node = vtransform;
- }
- else if(b_node.is_a(&RNA_ShaderNodeNormal)) {
- BL::Node::outputs_iterator out_it;
- b_node.outputs.begin(out_it);
-
- NormalNode *norm = new NormalNode();
- norm->direction = get_node_output_vector(b_node, "Normal");
- node = norm;
- }
- else if(b_node.is_a(&RNA_ShaderNodeMapping)) {
- BL::ShaderNodeMapping b_mapping_node(b_node);
- MappingNode *mapping = new MappingNode();
-
- get_tex_mapping(&mapping->tex_mapping, b_mapping_node);
-
- node = mapping;
- }
- else if(b_node.is_a(&RNA_ShaderNodeFresnel)) {
- node = new FresnelNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeLayerWeight)) {
- node = new LayerWeightNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeAddShader)) {
- node = new AddClosureNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeMixShader)) {
- node = new MixClosureNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeAttribute)) {
- BL::ShaderNodeAttribute b_attr_node(b_node);
- AttributeNode *attr = new AttributeNode();
- attr->attribute = b_attr_node.attribute_name();
- node = attr;
- }
- else if(b_node.is_a(&RNA_ShaderNodeBackground)) {
- node = new BackgroundNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeHoldout)) {
- node = new HoldoutNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeBsdfAnisotropic)) {
- BL::ShaderNodeBsdfAnisotropic b_aniso_node(b_node);
- AnisotropicBsdfNode *aniso = new AnisotropicBsdfNode();
-
- switch(b_aniso_node.distribution()) {
- case BL::ShaderNodeBsdfAnisotropic::distribution_BECKMANN:
- aniso->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID;
- break;
- case BL::ShaderNodeBsdfAnisotropic::distribution_GGX:
- aniso->distribution = CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID;
- break;
- case BL::ShaderNodeBsdfAnisotropic::distribution_MULTI_GGX:
- aniso->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID;
- break;
- case BL::ShaderNodeBsdfAnisotropic::distribution_ASHIKHMIN_SHIRLEY:
- aniso->distribution = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID;
- break;
- }
-
- node = aniso;
- }
- else if(b_node.is_a(&RNA_ShaderNodeBsdfDiffuse)) {
- node = new DiffuseBsdfNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeSubsurfaceScattering)) {
- BL::ShaderNodeSubsurfaceScattering b_subsurface_node(b_node);
-
- SubsurfaceScatteringNode *subsurface = new SubsurfaceScatteringNode();
-
- switch(b_subsurface_node.falloff()) {
- case BL::ShaderNodeSubsurfaceScattering::falloff_CUBIC:
- subsurface->falloff = CLOSURE_BSSRDF_CUBIC_ID;
- break;
- case BL::ShaderNodeSubsurfaceScattering::falloff_GAUSSIAN:
- subsurface->falloff = CLOSURE_BSSRDF_GAUSSIAN_ID;
- break;
- case BL::ShaderNodeSubsurfaceScattering::falloff_BURLEY:
- subsurface->falloff = CLOSURE_BSSRDF_BURLEY_ID;
- break;
- case BL::ShaderNodeSubsurfaceScattering::falloff_RANDOM_WALK:
- subsurface->falloff = CLOSURE_BSSRDF_RANDOM_WALK_ID;
- break;
- }
-
- node = subsurface;
- }
- else if(b_node.is_a(&RNA_ShaderNodeBsdfGlossy)) {
- BL::ShaderNodeBsdfGlossy b_glossy_node(b_node);
- GlossyBsdfNode *glossy = new GlossyBsdfNode();
-
- switch(b_glossy_node.distribution()) {
- case BL::ShaderNodeBsdfGlossy::distribution_SHARP:
- glossy->distribution = CLOSURE_BSDF_REFLECTION_ID;
- break;
- case BL::ShaderNodeBsdfGlossy::distribution_BECKMANN:
- glossy->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_ID;
- break;
- case BL::ShaderNodeBsdfGlossy::distribution_GGX:
- glossy->distribution = CLOSURE_BSDF_MICROFACET_GGX_ID;
- break;
- case BL::ShaderNodeBsdfGlossy::distribution_ASHIKHMIN_SHIRLEY:
- glossy->distribution = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID;
- break;
- case BL::ShaderNodeBsdfGlossy::distribution_MULTI_GGX:
- glossy->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID;
- break;
- }
- node = glossy;
- }
- else if(b_node.is_a(&RNA_ShaderNodeBsdfGlass)) {
- BL::ShaderNodeBsdfGlass b_glass_node(b_node);
- GlassBsdfNode *glass = new GlassBsdfNode();
- switch(b_glass_node.distribution()) {
- case BL::ShaderNodeBsdfGlass::distribution_SHARP:
- glass->distribution = CLOSURE_BSDF_SHARP_GLASS_ID;
- break;
- case BL::ShaderNodeBsdfGlass::distribution_BECKMANN:
- glass->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID;
- break;
- case BL::ShaderNodeBsdfGlass::distribution_GGX:
- glass->distribution = CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID;
- break;
- case BL::ShaderNodeBsdfGlass::distribution_MULTI_GGX:
- glass->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID;
- break;
- }
- node = glass;
- }
- else if(b_node.is_a(&RNA_ShaderNodeBsdfRefraction)) {
- BL::ShaderNodeBsdfRefraction b_refraction_node(b_node);
- RefractionBsdfNode *refraction = new RefractionBsdfNode();
- switch(b_refraction_node.distribution()) {
- case BL::ShaderNodeBsdfRefraction::distribution_SHARP:
- refraction->distribution = CLOSURE_BSDF_REFRACTION_ID;
- break;
- case BL::ShaderNodeBsdfRefraction::distribution_BECKMANN:
- refraction->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
- break;
- case BL::ShaderNodeBsdfRefraction::distribution_GGX:
- refraction->distribution = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
- break;
- }
- node = refraction;
- }
- else if(b_node.is_a(&RNA_ShaderNodeBsdfToon)) {
- BL::ShaderNodeBsdfToon b_toon_node(b_node);
- ToonBsdfNode *toon = new ToonBsdfNode();
- switch(b_toon_node.component()) {
- case BL::ShaderNodeBsdfToon::component_DIFFUSE:
- toon->component = CLOSURE_BSDF_DIFFUSE_TOON_ID;
- break;
- case BL::ShaderNodeBsdfToon::component_GLOSSY:
- toon->component = CLOSURE_BSDF_GLOSSY_TOON_ID;
- break;
- }
- node = toon;
- }
- else if(b_node.is_a(&RNA_ShaderNodeBsdfHair)) {
- BL::ShaderNodeBsdfHair b_hair_node(b_node);
- HairBsdfNode *hair = new HairBsdfNode();
- switch(b_hair_node.component()) {
- case BL::ShaderNodeBsdfHair::component_Reflection:
- hair->component = CLOSURE_BSDF_HAIR_REFLECTION_ID;
- break;
- case BL::ShaderNodeBsdfHair::component_Transmission:
- hair->component = CLOSURE_BSDF_HAIR_TRANSMISSION_ID;
- break;
- }
- node = hair;
- }
- else if(b_node.is_a(&RNA_ShaderNodeBsdfHairPrincipled)) {
- BL::ShaderNodeBsdfHairPrincipled b_principled_hair_node(b_node);
- PrincipledHairBsdfNode *principled_hair = new PrincipledHairBsdfNode();
- principled_hair->parametrization = (NodePrincipledHairParametrization) get_enum(b_principled_hair_node.ptr, "parametrization", NODE_PRINCIPLED_HAIR_NUM, NODE_PRINCIPLED_HAIR_REFLECTANCE);
- node = principled_hair;
- }
- else if(b_node.is_a(&RNA_ShaderNodeBsdfPrincipled)) {
- BL::ShaderNodeBsdfPrincipled b_principled_node(b_node);
- PrincipledBsdfNode *principled = new PrincipledBsdfNode();
- switch (b_principled_node.distribution()) {
- case BL::ShaderNodeBsdfPrincipled::distribution_GGX:
- principled->distribution = CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID;
- break;
- case BL::ShaderNodeBsdfPrincipled::distribution_MULTI_GGX:
- principled->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID;
- break;
- }
- switch (b_principled_node.subsurface_method()) {
- case BL::ShaderNodeBsdfPrincipled::subsurface_method_BURLEY:
- principled->subsurface_method = CLOSURE_BSSRDF_PRINCIPLED_ID;
- break;
- case BL::ShaderNodeBsdfPrincipled::subsurface_method_RANDOM_WALK:
- principled->subsurface_method = CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID;
- break;
- }
- node = principled;
- }
- else if(b_node.is_a(&RNA_ShaderNodeBsdfTranslucent)) {
- node = new TranslucentBsdfNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeBsdfTransparent)) {
- node = new TransparentBsdfNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeBsdfVelvet)) {
- node = new VelvetBsdfNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeEmission)) {
- node = new EmissionNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeAmbientOcclusion)) {
- BL::ShaderNodeAmbientOcclusion b_ao_node(b_node);
- AmbientOcclusionNode *ao = new AmbientOcclusionNode();
- ao->samples = b_ao_node.samples();
- ao->inside = b_ao_node.inside();
- ao->only_local = b_ao_node.only_local();
- node = ao;
- }
- else if(b_node.is_a(&RNA_ShaderNodeVolumeScatter)) {
- node = new ScatterVolumeNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeVolumeAbsorption)) {
- node = new AbsorptionVolumeNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeVolumePrincipled)) {
- PrincipledVolumeNode *principled = new PrincipledVolumeNode();
- node = principled;
- }
- else if(b_node.is_a(&RNA_ShaderNodeNewGeometry)) {
- node = new GeometryNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeWireframe)) {
- BL::ShaderNodeWireframe b_wireframe_node(b_node);
- WireframeNode *wire = new WireframeNode();
- wire->use_pixel_size = b_wireframe_node.use_pixel_size();
- node = wire;
- }
- else if(b_node.is_a(&RNA_ShaderNodeWavelength)) {
- node = new WavelengthNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeBlackbody)) {
- node = new BlackbodyNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeLightPath)) {
- node = new LightPathNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeLightFalloff)) {
- node = new LightFalloffNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeObjectInfo)) {
- node = new ObjectInfoNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeParticleInfo)) {
- node = new ParticleInfoNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeHairInfo)) {
- node = new HairInfoNode();
- }
- else if(b_node.is_a(&RNA_ShaderNodeBump)) {
- BL::ShaderNodeBump b_bump_node(b_node);
- BumpNode *bump = new BumpNode();
- bump->invert = b_bump_node.invert();
- node = bump;
- }
- else if(b_node.is_a(&RNA_ShaderNodeScript)) {
+ ShaderNode *node = NULL;
+
+ /* existing blender nodes */
+ if (b_node.is_a(&RNA_ShaderNodeRGBCurve)) {
+ BL::ShaderNodeRGBCurve b_curve_node(b_node);
+ BL::CurveMapping mapping(b_curve_node.mapping());
+ RGBCurvesNode *curves = new RGBCurvesNode();
+ curvemapping_color_to_array(mapping, curves->curves, RAMP_TABLE_SIZE, true);
+ curvemapping_minmax(mapping, true, &curves->min_x, &curves->max_x);
+ node = curves;
+ }
+ if (b_node.is_a(&RNA_ShaderNodeVectorCurve)) {
+ BL::ShaderNodeVectorCurve b_curve_node(b_node);
+ BL::CurveMapping mapping(b_curve_node.mapping());
+ VectorCurvesNode *curves = new VectorCurvesNode();
+ curvemapping_color_to_array(mapping, curves->curves, RAMP_TABLE_SIZE, false);
+ curvemapping_minmax(mapping, false, &curves->min_x, &curves->max_x);
+ node = curves;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeValToRGB)) {
+ RGBRampNode *ramp = new RGBRampNode();
+ BL::ShaderNodeValToRGB b_ramp_node(b_node);
+ BL::ColorRamp b_color_ramp(b_ramp_node.color_ramp());
+ colorramp_to_array(b_color_ramp, ramp->ramp, ramp->ramp_alpha, RAMP_TABLE_SIZE);
+ ramp->interpolate = b_color_ramp.interpolation() != BL::ColorRamp::interpolation_CONSTANT;
+ node = ramp;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeRGB)) {
+ ColorNode *color = new ColorNode();
+ color->value = get_node_output_rgba(b_node, "Color");
+ node = color;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeValue)) {
+ ValueNode *value = new ValueNode();
+ value->value = get_node_output_value(b_node, "Value");
+ node = value;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeCameraData)) {
+ node = new CameraNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeInvert)) {
+ node = new InvertNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeGamma)) {
+ node = new GammaNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBrightContrast)) {
+ node = new BrightContrastNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeMixRGB)) {
+ BL::ShaderNodeMixRGB b_mix_node(b_node);
+ MixNode *mix = new MixNode();
+ mix->type = (NodeMix)b_mix_node.blend_type();
+ mix->use_clamp = b_mix_node.use_clamp();
+ node = mix;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeSeparateRGB)) {
+ node = new SeparateRGBNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeCombineRGB)) {
+ node = new CombineRGBNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeSeparateHSV)) {
+ node = new SeparateHSVNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeCombineHSV)) {
+ node = new CombineHSVNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeSeparateXYZ)) {
+ node = new SeparateXYZNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeCombineXYZ)) {
+ node = new CombineXYZNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeHueSaturation)) {
+ node = new HSVNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeRGBToBW)) {
+ node = new RGBToBWNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeMath)) {
+ BL::ShaderNodeMath b_math_node(b_node);
+ MathNode *math = new MathNode();
+ math->type = (NodeMath)b_math_node.operation();
+ math->use_clamp = b_math_node.use_clamp();
+ node = math;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeVectorMath)) {
+ BL::ShaderNodeVectorMath b_vector_math_node(b_node);
+ VectorMathNode *vmath = new VectorMathNode();
+ vmath->type = (NodeVectorMath)b_vector_math_node.operation();
+ node = vmath;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeVectorTransform)) {
+ BL::ShaderNodeVectorTransform b_vector_transform_node(b_node);
+ VectorTransformNode *vtransform = new VectorTransformNode();
+ vtransform->type = (NodeVectorTransformType)b_vector_transform_node.vector_type();
+ vtransform->convert_from = (NodeVectorTransformConvertSpace)
+ b_vector_transform_node.convert_from();
+ vtransform->convert_to = (NodeVectorTransformConvertSpace)b_vector_transform_node.convert_to();
+ node = vtransform;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeNormal)) {
+ BL::Node::outputs_iterator out_it;
+ b_node.outputs.begin(out_it);
+
+ NormalNode *norm = new NormalNode();
+ norm->direction = get_node_output_vector(b_node, "Normal");
+ node = norm;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeMapping)) {
+ BL::ShaderNodeMapping b_mapping_node(b_node);
+ MappingNode *mapping = new MappingNode();
+
+ get_tex_mapping(&mapping->tex_mapping, b_mapping_node);
+
+ node = mapping;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeFresnel)) {
+ node = new FresnelNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeLayerWeight)) {
+ node = new LayerWeightNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeAddShader)) {
+ node = new AddClosureNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeMixShader)) {
+ node = new MixClosureNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeAttribute)) {
+ BL::ShaderNodeAttribute b_attr_node(b_node);
+ AttributeNode *attr = new AttributeNode();
+ attr->attribute = b_attr_node.attribute_name();
+ node = attr;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBackground)) {
+ node = new BackgroundNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeHoldout)) {
+ node = new HoldoutNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfAnisotropic)) {
+ BL::ShaderNodeBsdfAnisotropic b_aniso_node(b_node);
+ AnisotropicBsdfNode *aniso = new AnisotropicBsdfNode();
+
+ switch (b_aniso_node.distribution()) {
+ case BL::ShaderNodeBsdfAnisotropic::distribution_BECKMANN:
+ aniso->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID;
+ break;
+ case BL::ShaderNodeBsdfAnisotropic::distribution_GGX:
+ aniso->distribution = CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID;
+ break;
+ case BL::ShaderNodeBsdfAnisotropic::distribution_MULTI_GGX:
+ aniso->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID;
+ break;
+ case BL::ShaderNodeBsdfAnisotropic::distribution_ASHIKHMIN_SHIRLEY:
+ aniso->distribution = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID;
+ break;
+ }
+
+ node = aniso;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfDiffuse)) {
+ node = new DiffuseBsdfNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeSubsurfaceScattering)) {
+ BL::ShaderNodeSubsurfaceScattering b_subsurface_node(b_node);
+
+ SubsurfaceScatteringNode *subsurface = new SubsurfaceScatteringNode();
+
+ switch (b_subsurface_node.falloff()) {
+ case BL::ShaderNodeSubsurfaceScattering::falloff_CUBIC:
+ subsurface->falloff = CLOSURE_BSSRDF_CUBIC_ID;
+ break;
+ case BL::ShaderNodeSubsurfaceScattering::falloff_GAUSSIAN:
+ subsurface->falloff = CLOSURE_BSSRDF_GAUSSIAN_ID;
+ break;
+ case BL::ShaderNodeSubsurfaceScattering::falloff_BURLEY:
+ subsurface->falloff = CLOSURE_BSSRDF_BURLEY_ID;
+ break;
+ case BL::ShaderNodeSubsurfaceScattering::falloff_RANDOM_WALK:
+ subsurface->falloff = CLOSURE_BSSRDF_RANDOM_WALK_ID;
+ break;
+ }
+
+ node = subsurface;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfGlossy)) {
+ BL::ShaderNodeBsdfGlossy b_glossy_node(b_node);
+ GlossyBsdfNode *glossy = new GlossyBsdfNode();
+
+ switch (b_glossy_node.distribution()) {
+ case BL::ShaderNodeBsdfGlossy::distribution_SHARP:
+ glossy->distribution = CLOSURE_BSDF_REFLECTION_ID;
+ break;
+ case BL::ShaderNodeBsdfGlossy::distribution_BECKMANN:
+ glossy->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_ID;
+ break;
+ case BL::ShaderNodeBsdfGlossy::distribution_GGX:
+ glossy->distribution = CLOSURE_BSDF_MICROFACET_GGX_ID;
+ break;
+ case BL::ShaderNodeBsdfGlossy::distribution_ASHIKHMIN_SHIRLEY:
+ glossy->distribution = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID;
+ break;
+ case BL::ShaderNodeBsdfGlossy::distribution_MULTI_GGX:
+ glossy->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID;
+ break;
+ }
+ node = glossy;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfGlass)) {
+ BL::ShaderNodeBsdfGlass b_glass_node(b_node);
+ GlassBsdfNode *glass = new GlassBsdfNode();
+ switch (b_glass_node.distribution()) {
+ case BL::ShaderNodeBsdfGlass::distribution_SHARP:
+ glass->distribution = CLOSURE_BSDF_SHARP_GLASS_ID;
+ break;
+ case BL::ShaderNodeBsdfGlass::distribution_BECKMANN:
+ glass->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID;
+ break;
+ case BL::ShaderNodeBsdfGlass::distribution_GGX:
+ glass->distribution = CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID;
+ break;
+ case BL::ShaderNodeBsdfGlass::distribution_MULTI_GGX:
+ glass->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID;
+ break;
+ }
+ node = glass;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfRefraction)) {
+ BL::ShaderNodeBsdfRefraction b_refraction_node(b_node);
+ RefractionBsdfNode *refraction = new RefractionBsdfNode();
+ switch (b_refraction_node.distribution()) {
+ case BL::ShaderNodeBsdfRefraction::distribution_SHARP:
+ refraction->distribution = CLOSURE_BSDF_REFRACTION_ID;
+ break;
+ case BL::ShaderNodeBsdfRefraction::distribution_BECKMANN:
+ refraction->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
+ break;
+ case BL::ShaderNodeBsdfRefraction::distribution_GGX:
+ refraction->distribution = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
+ break;
+ }
+ node = refraction;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfToon)) {
+ BL::ShaderNodeBsdfToon b_toon_node(b_node);
+ ToonBsdfNode *toon = new ToonBsdfNode();
+ switch (b_toon_node.component()) {
+ case BL::ShaderNodeBsdfToon::component_DIFFUSE:
+ toon->component = CLOSURE_BSDF_DIFFUSE_TOON_ID;
+ break;
+ case BL::ShaderNodeBsdfToon::component_GLOSSY:
+ toon->component = CLOSURE_BSDF_GLOSSY_TOON_ID;
+ break;
+ }
+ node = toon;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfHair)) {
+ BL::ShaderNodeBsdfHair b_hair_node(b_node);
+ HairBsdfNode *hair = new HairBsdfNode();
+ switch (b_hair_node.component()) {
+ case BL::ShaderNodeBsdfHair::component_Reflection:
+ hair->component = CLOSURE_BSDF_HAIR_REFLECTION_ID;
+ break;
+ case BL::ShaderNodeBsdfHair::component_Transmission:
+ hair->component = CLOSURE_BSDF_HAIR_TRANSMISSION_ID;
+ break;
+ }
+ node = hair;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfHairPrincipled)) {
+ BL::ShaderNodeBsdfHairPrincipled b_principled_hair_node(b_node);
+ PrincipledHairBsdfNode *principled_hair = new PrincipledHairBsdfNode();
+ principled_hair->parametrization = (NodePrincipledHairParametrization)get_enum(
+ b_principled_hair_node.ptr,
+ "parametrization",
+ NODE_PRINCIPLED_HAIR_NUM,
+ NODE_PRINCIPLED_HAIR_REFLECTANCE);
+ node = principled_hair;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfPrincipled)) {
+ BL::ShaderNodeBsdfPrincipled b_principled_node(b_node);
+ PrincipledBsdfNode *principled = new PrincipledBsdfNode();
+ switch (b_principled_node.distribution()) {
+ case BL::ShaderNodeBsdfPrincipled::distribution_GGX:
+ principled->distribution = CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID;
+ break;
+ case BL::ShaderNodeBsdfPrincipled::distribution_MULTI_GGX:
+ principled->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID;
+ break;
+ }
+ switch (b_principled_node.subsurface_method()) {
+ case BL::ShaderNodeBsdfPrincipled::subsurface_method_BURLEY:
+ principled->subsurface_method = CLOSURE_BSSRDF_PRINCIPLED_ID;
+ break;
+ case BL::ShaderNodeBsdfPrincipled::subsurface_method_RANDOM_WALK:
+ principled->subsurface_method = CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID;
+ break;
+ }
+ node = principled;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfTranslucent)) {
+ node = new TranslucentBsdfNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfTransparent)) {
+ node = new TransparentBsdfNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfVelvet)) {
+ node = new VelvetBsdfNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeEmission)) {
+ node = new EmissionNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeAmbientOcclusion)) {
+ BL::ShaderNodeAmbientOcclusion b_ao_node(b_node);
+ AmbientOcclusionNode *ao = new AmbientOcclusionNode();
+ ao->samples = b_ao_node.samples();
+ ao->inside = b_ao_node.inside();
+ ao->only_local = b_ao_node.only_local();
+ node = ao;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeVolumeScatter)) {
+ node = new ScatterVolumeNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeVolumeAbsorption)) {
+ node = new AbsorptionVolumeNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeVolumePrincipled)) {
+ PrincipledVolumeNode *principled = new PrincipledVolumeNode();
+ node = principled;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeNewGeometry)) {
+ node = new GeometryNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeWireframe)) {
+ BL::ShaderNodeWireframe b_wireframe_node(b_node);
+ WireframeNode *wire = new WireframeNode();
+ wire->use_pixel_size = b_wireframe_node.use_pixel_size();
+ node = wire;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeWavelength)) {
+ node = new WavelengthNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBlackbody)) {
+ node = new BlackbodyNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeLightPath)) {
+ node = new LightPathNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeLightFalloff)) {
+ node = new LightFalloffNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeObjectInfo)) {
+ node = new ObjectInfoNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeParticleInfo)) {
+ node = new ParticleInfoNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeHairInfo)) {
+ node = new HairInfoNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBump)) {
+ BL::ShaderNodeBump b_bump_node(b_node);
+ BumpNode *bump = new BumpNode();
+ bump->invert = b_bump_node.invert();
+ node = bump;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeScript)) {
#ifdef WITH_OSL
- if(scene->shader_manager->use_osl()) {
- /* create script node */
- BL::ShaderNodeScript b_script_node(b_node);
-
- OSLShaderManager *manager = (OSLShaderManager*)scene->shader_manager;
- string bytecode_hash = b_script_node.bytecode_hash();
-
- if(!bytecode_hash.empty()) {
- node = manager->osl_node("", bytecode_hash, b_script_node.bytecode());
- }
- else {
- string absolute_filepath = blender_absolute_path(b_data, b_ntree, b_script_node.filepath());
- node = manager->osl_node(absolute_filepath, "");
- }
- }
+ if (scene->shader_manager->use_osl()) {
+ /* create script node */
+ BL::ShaderNodeScript b_script_node(b_node);
+
+ OSLShaderManager *manager = (OSLShaderManager *)scene->shader_manager;
+ string bytecode_hash = b_script_node.bytecode_hash();
+
+ if (!bytecode_hash.empty()) {
+ node = manager->osl_node("", bytecode_hash, b_script_node.bytecode());
+ }
+ else {
+ string absolute_filepath = blender_absolute_path(
+ b_data, b_ntree, b_script_node.filepath());
+ node = manager->osl_node(absolute_filepath, "");
+ }
+ }
#else
- (void) b_data;
- (void) b_ntree;
+ (void)b_data;
+ (void)b_ntree;
#endif
- }
- else if(b_node.is_a(&RNA_ShaderNodeTexImage)) {
- BL::ShaderNodeTexImage b_image_node(b_node);
- BL::Image b_image(b_image_node.image());
- BL::ImageUser b_image_user(b_image_node.image_user());
- ImageTextureNode *image = new ImageTextureNode();
- if(b_image) {
- /* builtin images will use callback-based reading because
- * they could only be loaded correct from blender side
- */
- bool is_builtin = b_image.packed_file() ||
- b_image.source() == BL::Image::source_GENERATED ||
- b_image.source() == BL::Image::source_MOVIE ||
- (b_engine.is_preview() &&
- b_image.source() != BL::Image::source_SEQUENCE);
-
- if(is_builtin) {
- /* for builtin images we're using image datablock name to find an image to
- * read pixels from later
- *
- * also store frame number as well, so there's no differences in handling
- * builtin names for packed images and movies
- */
- int scene_frame = b_scene.frame_current();
- int image_frame = image_user_frame_number(b_image_user,
- scene_frame);
- image->filename = b_image.name() + "@" + string_printf("%d", image_frame);
- image->builtin_data = b_image.ptr.data;
- }
- else {
- image->filename = image_user_file_path(b_image_user,
- b_image,
- b_scene.frame_current());
- image->builtin_data = NULL;
- }
-
- image->animated = b_image_node.image_user().use_auto_refresh();
- image->use_alpha = b_image.use_alpha();
-
- /* TODO: restore */
- /* TODO(sergey): Does not work properly when we change builtin type. */
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexImage)) {
+ BL::ShaderNodeTexImage b_image_node(b_node);
+ BL::Image b_image(b_image_node.image());
+ BL::ImageUser b_image_user(b_image_node.image_user());
+ ImageTextureNode *image = new ImageTextureNode();
+ if (b_image) {
+ /* builtin images will use callback-based reading because
+ * they could only be loaded correct from blender side
+ */
+ bool is_builtin = b_image.packed_file() || b_image.source() == BL::Image::source_GENERATED ||
+ b_image.source() == BL::Image::source_MOVIE ||
+ (b_engine.is_preview() && b_image.source() != BL::Image::source_SEQUENCE);
+
+ if (is_builtin) {
+ /* for builtin images we're using image datablock name to find an image to
+ * read pixels from later
+ *
+ * also store frame number as well, so there's no differences in handling
+ * builtin names for packed images and movies
+ */
+ int scene_frame = b_scene.frame_current();
+ int image_frame = image_user_frame_number(b_image_user, scene_frame);
+ image->filename = b_image.name() + "@" + string_printf("%d", image_frame);
+ image->builtin_data = b_image.ptr.data;
+ }
+ else {
+ image->filename = image_user_file_path(b_image_user, b_image, b_scene.frame_current());
+ image->builtin_data = NULL;
+ }
+
+ image->animated = b_image_node.image_user().use_auto_refresh();
+ image->use_alpha = b_image.use_alpha();
+
+ /* TODO: restore */
+ /* TODO(sergey): Does not work properly when we change builtin type. */
#if 0
- if(b_image.is_updated()) {
- scene->image_manager->tag_reload_image(
- image->filename.string(),
- image->builtin_data,
- get_image_interpolation(b_image_node),
- get_image_extension(b_image_node),
- image->use_alpha);
- }
+ if(b_image.is_updated()) {
+ scene->image_manager->tag_reload_image(
+ image->filename.string(),
+ image->builtin_data,
+ get_image_interpolation(b_image_node),
+ get_image_extension(b_image_node),
+ image->use_alpha);
+ }
#endif
- }
- image->color_space = (NodeImageColorSpace)b_image_node.color_space();
- image->projection = (NodeImageProjection)b_image_node.projection();
- image->interpolation = get_image_interpolation(b_image_node);
- image->extension = get_image_extension(b_image_node);
- image->projection_blend = b_image_node.projection_blend();
- BL::TexMapping b_texture_mapping(b_image_node.texture_mapping());
- get_tex_mapping(&image->tex_mapping, b_texture_mapping);
- node = image;
- }
- else if(b_node.is_a(&RNA_ShaderNodeTexEnvironment)) {
- BL::ShaderNodeTexEnvironment b_env_node(b_node);
- BL::Image b_image(b_env_node.image());
- BL::ImageUser b_image_user(b_env_node.image_user());
- EnvironmentTextureNode *env = new EnvironmentTextureNode();
- if(b_image) {
- bool is_builtin = b_image.packed_file() ||
- b_image.source() == BL::Image::source_GENERATED ||
- b_image.source() == BL::Image::source_MOVIE ||
- (b_engine.is_preview() &&
- b_image.source() != BL::Image::source_SEQUENCE);
-
- if(is_builtin) {
- int scene_frame = b_scene.frame_current();
- int image_frame = image_user_frame_number(b_image_user,
- scene_frame);
- env->filename = b_image.name() + "@" + string_printf("%d", image_frame);
- env->builtin_data = b_image.ptr.data;
- }
- else {
- env->filename = image_user_file_path(b_image_user,
- b_image,
- b_scene.frame_current());
- env->builtin_data = NULL;
- }
-
- env->animated = b_env_node.image_user().use_auto_refresh();
- env->use_alpha = b_image.use_alpha();
-
- /* TODO: restore */
- /* TODO(sergey): Does not work properly when we change builtin type. */
+ }
+ image->color_space = (NodeImageColorSpace)b_image_node.color_space();
+ image->projection = (NodeImageProjection)b_image_node.projection();
+ image->interpolation = get_image_interpolation(b_image_node);
+ image->extension = get_image_extension(b_image_node);
+ image->projection_blend = b_image_node.projection_blend();
+ BL::TexMapping b_texture_mapping(b_image_node.texture_mapping());
+ get_tex_mapping(&image->tex_mapping, b_texture_mapping);
+ node = image;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexEnvironment)) {
+ BL::ShaderNodeTexEnvironment b_env_node(b_node);
+ BL::Image b_image(b_env_node.image());
+ BL::ImageUser b_image_user(b_env_node.image_user());
+ EnvironmentTextureNode *env = new EnvironmentTextureNode();
+ if (b_image) {
+ bool is_builtin = b_image.packed_file() || b_image.source() == BL::Image::source_GENERATED ||
+ b_image.source() == BL::Image::source_MOVIE ||
+ (b_engine.is_preview() && b_image.source() != BL::Image::source_SEQUENCE);
+
+ if (is_builtin) {
+ int scene_frame = b_scene.frame_current();
+ int image_frame = image_user_frame_number(b_image_user, scene_frame);
+ env->filename = b_image.name() + "@" + string_printf("%d", image_frame);
+ env->builtin_data = b_image.ptr.data;
+ }
+ else {
+ env->filename = image_user_file_path(b_image_user, b_image, b_scene.frame_current());
+ env->builtin_data = NULL;
+ }
+
+ env->animated = b_env_node.image_user().use_auto_refresh();
+ env->use_alpha = b_image.use_alpha();
+
+ /* TODO: restore */
+ /* TODO(sergey): Does not work properly when we change builtin type. */
#if 0
- if(b_image.is_updated()) {
- scene->image_manager->tag_reload_image(
- env->filename.string(),
- env->builtin_data,
- get_image_interpolation(b_env_node),
- EXTENSION_REPEAT,
- env->use_alpha);
- }
+ if(b_image.is_updated()) {
+ scene->image_manager->tag_reload_image(
+ env->filename.string(),
+ env->builtin_data,
+ get_image_interpolation(b_env_node),
+ EXTENSION_REPEAT,
+ env->use_alpha);
+ }
#endif
- }
- env->color_space = (NodeImageColorSpace)b_env_node.color_space();
- env->interpolation = get_image_interpolation(b_env_node);
- env->projection = (NodeEnvironmentProjection)b_env_node.projection();
- BL::TexMapping b_texture_mapping(b_env_node.texture_mapping());
- get_tex_mapping(&env->tex_mapping, b_texture_mapping);
- node = env;
- }
- else if(b_node.is_a(&RNA_ShaderNodeTexGradient)) {
- BL::ShaderNodeTexGradient b_gradient_node(b_node);
- GradientTextureNode *gradient = new GradientTextureNode();
- gradient->type = (NodeGradientType)b_gradient_node.gradient_type();
- BL::TexMapping b_texture_mapping(b_gradient_node.texture_mapping());
- get_tex_mapping(&gradient->tex_mapping, b_texture_mapping);
- node = gradient;
- }
- else if(b_node.is_a(&RNA_ShaderNodeTexVoronoi)) {
- BL::ShaderNodeTexVoronoi b_voronoi_node(b_node);
- VoronoiTextureNode *voronoi = new VoronoiTextureNode();
- voronoi->coloring = (NodeVoronoiColoring)b_voronoi_node.coloring();
- voronoi->metric = (NodeVoronoiDistanceMetric)b_voronoi_node.distance();
- voronoi->feature = (NodeVoronoiFeature)b_voronoi_node.feature();
- BL::TexMapping b_texture_mapping(b_voronoi_node.texture_mapping());
- get_tex_mapping(&voronoi->tex_mapping, b_texture_mapping);
- node = voronoi;
- }
- else if(b_node.is_a(&RNA_ShaderNodeTexMagic)) {
- BL::ShaderNodeTexMagic b_magic_node(b_node);
- MagicTextureNode *magic = new MagicTextureNode();
- magic->depth = b_magic_node.turbulence_depth();
- BL::TexMapping b_texture_mapping(b_magic_node.texture_mapping());
- get_tex_mapping(&magic->tex_mapping, b_texture_mapping);
- node = magic;
- }
- else if(b_node.is_a(&RNA_ShaderNodeTexWave)) {
- BL::ShaderNodeTexWave b_wave_node(b_node);
- WaveTextureNode *wave = new WaveTextureNode();
- wave->type = (NodeWaveType)b_wave_node.wave_type();
- wave->profile = (NodeWaveProfile)b_wave_node.wave_profile();
- BL::TexMapping b_texture_mapping(b_wave_node.texture_mapping());
- get_tex_mapping(&wave->tex_mapping, b_texture_mapping);
- node = wave;
- }
- else if(b_node.is_a(&RNA_ShaderNodeTexChecker)) {
- BL::ShaderNodeTexChecker b_checker_node(b_node);
- CheckerTextureNode *checker = new CheckerTextureNode();
- BL::TexMapping b_texture_mapping(b_checker_node.texture_mapping());
- get_tex_mapping(&checker->tex_mapping, b_texture_mapping);
- node = checker;
- }
- else if(b_node.is_a(&RNA_ShaderNodeTexBrick)) {
- BL::ShaderNodeTexBrick b_brick_node(b_node);
- BrickTextureNode *brick = new BrickTextureNode();
- brick->offset = b_brick_node.offset();
- brick->offset_frequency = b_brick_node.offset_frequency();
- brick->squash = b_brick_node.squash();
- brick->squash_frequency = b_brick_node.squash_frequency();
- BL::TexMapping b_texture_mapping(b_brick_node.texture_mapping());
- get_tex_mapping(&brick->tex_mapping, b_texture_mapping);
- node = brick;
- }
- else if(b_node.is_a(&RNA_ShaderNodeTexNoise)) {
- BL::ShaderNodeTexNoise b_noise_node(b_node);
- NoiseTextureNode *noise = new NoiseTextureNode();
- BL::TexMapping b_texture_mapping(b_noise_node.texture_mapping());
- get_tex_mapping(&noise->tex_mapping, b_texture_mapping);
- node = noise;
- }
- else if(b_node.is_a(&RNA_ShaderNodeTexMusgrave)) {
- BL::ShaderNodeTexMusgrave b_musgrave_node(b_node);
- MusgraveTextureNode *musgrave = new MusgraveTextureNode();
- musgrave->type = (NodeMusgraveType)b_musgrave_node.musgrave_type();
- BL::TexMapping b_texture_mapping(b_musgrave_node.texture_mapping());
- get_tex_mapping(&musgrave->tex_mapping, b_texture_mapping);
- node = musgrave;
- }
- else if(b_node.is_a(&RNA_ShaderNodeTexCoord)) {
- BL::ShaderNodeTexCoord b_tex_coord_node(b_node);
- TextureCoordinateNode *tex_coord = new TextureCoordinateNode();
- tex_coord->from_dupli = b_tex_coord_node.from_instancer();
- if(b_tex_coord_node.object()) {
- tex_coord->use_transform = true;
- tex_coord->ob_tfm = get_transform(b_tex_coord_node.object().matrix_world());
- }
- node = tex_coord;
- }
- else if(b_node.is_a(&RNA_ShaderNodeTexSky)) {
- BL::ShaderNodeTexSky b_sky_node(b_node);
- SkyTextureNode *sky = new SkyTextureNode();
- sky->type = (NodeSkyType)b_sky_node.sky_type();
- sky->sun_direction = normalize(get_float3(b_sky_node.sun_direction()));
- sky->turbidity = b_sky_node.turbidity();
- sky->ground_albedo = b_sky_node.ground_albedo();
- BL::TexMapping b_texture_mapping(b_sky_node.texture_mapping());
- get_tex_mapping(&sky->tex_mapping, b_texture_mapping);
- node = sky;
- }
- else if(b_node.is_a(&RNA_ShaderNodeTexIES)) {
- BL::ShaderNodeTexIES b_ies_node(b_node);
- IESLightNode *ies = new IESLightNode();
- switch(b_ies_node.mode()) {
- case BL::ShaderNodeTexIES::mode_EXTERNAL:
- ies->filename = blender_absolute_path(b_data, b_ntree, b_ies_node.filepath());
- break;
- case BL::ShaderNodeTexIES::mode_INTERNAL:
- ies->ies = get_text_datablock_content(b_ies_node.ies().ptr);
- if(ies->ies.empty()) {
- ies->ies = "\n";
- }
- break;
- }
- node = ies;
- }
- else if(b_node.is_a(&RNA_ShaderNodeNormalMap)) {
- BL::ShaderNodeNormalMap b_normal_map_node(b_node);
- NormalMapNode *nmap = new NormalMapNode();
- nmap->space = (NodeNormalMapSpace)b_normal_map_node.space();
- nmap->attribute = b_normal_map_node.uv_map();
- node = nmap;
- }
- else if(b_node.is_a(&RNA_ShaderNodeTangent)) {
- BL::ShaderNodeTangent b_tangent_node(b_node);
- TangentNode *tangent = new TangentNode();
- tangent->direction_type = (NodeTangentDirectionType)b_tangent_node.direction_type();
- tangent->axis = (NodeTangentAxis)b_tangent_node.axis();
- tangent->attribute = b_tangent_node.uv_map();
- node = tangent;
- }
- else if(b_node.is_a(&RNA_ShaderNodeUVMap)) {
- BL::ShaderNodeUVMap b_uvmap_node(b_node);
- UVMapNode *uvm = new UVMapNode();
- uvm->attribute = b_uvmap_node.uv_map();
- uvm->from_dupli = b_uvmap_node.from_instancer();
- node = uvm;
- }
- else if(b_node.is_a(&RNA_ShaderNodeTexPointDensity)) {
- BL::ShaderNodeTexPointDensity b_point_density_node(b_node);
- PointDensityTextureNode *point_density = new PointDensityTextureNode();
- point_density->filename = b_point_density_node.name();
- point_density->space = (NodeTexVoxelSpace)b_point_density_node.space();
- point_density->interpolation = get_image_interpolation(b_point_density_node);
- point_density->builtin_data = b_point_density_node.ptr.data;
- point_density->image_manager = scene->image_manager;
-
- /* TODO(sergey): Use more proper update flag. */
- if(true) {
- point_density->add_image();
- b_point_density_node.cache_point_density(b_depsgraph);
- scene->image_manager->tag_reload_image(
- point_density->filename.string(),
- point_density->builtin_data,
- point_density->interpolation,
- EXTENSION_CLIP,
- true);
- }
- node = point_density;
-
- /* Transformation form world space to texture space.
- *
- * NOTE: Do this after the texture is cached, this is because getting
- * min/max will need to access this cache.
- */
- BL::Object b_ob(b_point_density_node.object());
- if(b_ob) {
- float3 loc, size;
- point_density_texture_space(b_depsgraph,
- b_point_density_node,
- loc,
- size);
- point_density->tfm =
- transform_translate(-loc) * transform_scale(size) *
- transform_inverse(get_transform(b_ob.matrix_world()));
- }
- }
- else if(b_node.is_a(&RNA_ShaderNodeBevel)) {
- BL::ShaderNodeBevel b_bevel_node(b_node);
- BevelNode *bevel = new BevelNode();
- bevel->samples = b_bevel_node.samples();
- node = bevel;
- }
- else if(b_node.is_a(&RNA_ShaderNodeDisplacement)) {
- BL::ShaderNodeDisplacement b_disp_node(b_node);
- DisplacementNode *disp = new DisplacementNode();
- disp->space = (NodeNormalMapSpace)b_disp_node.space();
- node = disp;
- }
- else if(b_node.is_a(&RNA_ShaderNodeVectorDisplacement)) {
- BL::ShaderNodeVectorDisplacement b_disp_node(b_node);
- VectorDisplacementNode *disp = new VectorDisplacementNode();
- disp->space = (NodeNormalMapSpace)b_disp_node.space();
- disp->attribute = "";
- node = disp;
- }
-
- if(node) {
- node->name = b_node.name();
- graph->add(node);
- }
-
- return node;
+ }
+ env->color_space = (NodeImageColorSpace)b_env_node.color_space();
+ env->interpolation = get_image_interpolation(b_env_node);
+ env->projection = (NodeEnvironmentProjection)b_env_node.projection();
+ BL::TexMapping b_texture_mapping(b_env_node.texture_mapping());
+ get_tex_mapping(&env->tex_mapping, b_texture_mapping);
+ node = env;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexGradient)) {
+ BL::ShaderNodeTexGradient b_gradient_node(b_node);
+ GradientTextureNode *gradient = new GradientTextureNode();
+ gradient->type = (NodeGradientType)b_gradient_node.gradient_type();
+ BL::TexMapping b_texture_mapping(b_gradient_node.texture_mapping());
+ get_tex_mapping(&gradient->tex_mapping, b_texture_mapping);
+ node = gradient;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexVoronoi)) {
+ BL::ShaderNodeTexVoronoi b_voronoi_node(b_node);
+ VoronoiTextureNode *voronoi = new VoronoiTextureNode();
+ voronoi->coloring = (NodeVoronoiColoring)b_voronoi_node.coloring();
+ voronoi->metric = (NodeVoronoiDistanceMetric)b_voronoi_node.distance();
+ voronoi->feature = (NodeVoronoiFeature)b_voronoi_node.feature();
+ BL::TexMapping b_texture_mapping(b_voronoi_node.texture_mapping());
+ get_tex_mapping(&voronoi->tex_mapping, b_texture_mapping);
+ node = voronoi;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexMagic)) {
+ BL::ShaderNodeTexMagic b_magic_node(b_node);
+ MagicTextureNode *magic = new MagicTextureNode();
+ magic->depth = b_magic_node.turbulence_depth();
+ BL::TexMapping b_texture_mapping(b_magic_node.texture_mapping());
+ get_tex_mapping(&magic->tex_mapping, b_texture_mapping);
+ node = magic;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexWave)) {
+ BL::ShaderNodeTexWave b_wave_node(b_node);
+ WaveTextureNode *wave = new WaveTextureNode();
+ wave->type = (NodeWaveType)b_wave_node.wave_type();
+ wave->profile = (NodeWaveProfile)b_wave_node.wave_profile();
+ BL::TexMapping b_texture_mapping(b_wave_node.texture_mapping());
+ get_tex_mapping(&wave->tex_mapping, b_texture_mapping);
+ node = wave;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexChecker)) {
+ BL::ShaderNodeTexChecker b_checker_node(b_node);
+ CheckerTextureNode *checker = new CheckerTextureNode();
+ BL::TexMapping b_texture_mapping(b_checker_node.texture_mapping());
+ get_tex_mapping(&checker->tex_mapping, b_texture_mapping);
+ node = checker;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexBrick)) {
+ BL::ShaderNodeTexBrick b_brick_node(b_node);
+ BrickTextureNode *brick = new BrickTextureNode();
+ brick->offset = b_brick_node.offset();
+ brick->offset_frequency = b_brick_node.offset_frequency();
+ brick->squash = b_brick_node.squash();
+ brick->squash_frequency = b_brick_node.squash_frequency();
+ BL::TexMapping b_texture_mapping(b_brick_node.texture_mapping());
+ get_tex_mapping(&brick->tex_mapping, b_texture_mapping);
+ node = brick;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexNoise)) {
+ BL::ShaderNodeTexNoise b_noise_node(b_node);
+ NoiseTextureNode *noise = new NoiseTextureNode();
+ BL::TexMapping b_texture_mapping(b_noise_node.texture_mapping());
+ get_tex_mapping(&noise->tex_mapping, b_texture_mapping);
+ node = noise;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexMusgrave)) {
+ BL::ShaderNodeTexMusgrave b_musgrave_node(b_node);
+ MusgraveTextureNode *musgrave = new MusgraveTextureNode();
+ musgrave->type = (NodeMusgraveType)b_musgrave_node.musgrave_type();
+ BL::TexMapping b_texture_mapping(b_musgrave_node.texture_mapping());
+ get_tex_mapping(&musgrave->tex_mapping, b_texture_mapping);
+ node = musgrave;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexCoord)) {
+ BL::ShaderNodeTexCoord b_tex_coord_node(b_node);
+ TextureCoordinateNode *tex_coord = new TextureCoordinateNode();
+ tex_coord->from_dupli = b_tex_coord_node.from_instancer();
+ if (b_tex_coord_node.object()) {
+ tex_coord->use_transform = true;
+ tex_coord->ob_tfm = get_transform(b_tex_coord_node.object().matrix_world());
+ }
+ node = tex_coord;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexSky)) {
+ BL::ShaderNodeTexSky b_sky_node(b_node);
+ SkyTextureNode *sky = new SkyTextureNode();
+ sky->type = (NodeSkyType)b_sky_node.sky_type();
+ sky->sun_direction = normalize(get_float3(b_sky_node.sun_direction()));
+ sky->turbidity = b_sky_node.turbidity();
+ sky->ground_albedo = b_sky_node.ground_albedo();
+ BL::TexMapping b_texture_mapping(b_sky_node.texture_mapping());
+ get_tex_mapping(&sky->tex_mapping, b_texture_mapping);
+ node = sky;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexIES)) {
+ BL::ShaderNodeTexIES b_ies_node(b_node);
+ IESLightNode *ies = new IESLightNode();
+ switch (b_ies_node.mode()) {
+ case BL::ShaderNodeTexIES::mode_EXTERNAL:
+ ies->filename = blender_absolute_path(b_data, b_ntree, b_ies_node.filepath());
+ break;
+ case BL::ShaderNodeTexIES::mode_INTERNAL:
+ ies->ies = get_text_datablock_content(b_ies_node.ies().ptr);
+ if (ies->ies.empty()) {
+ ies->ies = "\n";
+ }
+ break;
+ }
+ node = ies;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeNormalMap)) {
+ BL::ShaderNodeNormalMap b_normal_map_node(b_node);
+ NormalMapNode *nmap = new NormalMapNode();
+ nmap->space = (NodeNormalMapSpace)b_normal_map_node.space();
+ nmap->attribute = b_normal_map_node.uv_map();
+ node = nmap;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTangent)) {
+ BL::ShaderNodeTangent b_tangent_node(b_node);
+ TangentNode *tangent = new TangentNode();
+ tangent->direction_type = (NodeTangentDirectionType)b_tangent_node.direction_type();
+ tangent->axis = (NodeTangentAxis)b_tangent_node.axis();
+ tangent->attribute = b_tangent_node.uv_map();
+ node = tangent;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeUVMap)) {
+ BL::ShaderNodeUVMap b_uvmap_node(b_node);
+ UVMapNode *uvm = new UVMapNode();
+ uvm->attribute = b_uvmap_node.uv_map();
+ uvm->from_dupli = b_uvmap_node.from_instancer();
+ node = uvm;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexPointDensity)) {
+ BL::ShaderNodeTexPointDensity b_point_density_node(b_node);
+ PointDensityTextureNode *point_density = new PointDensityTextureNode();
+ point_density->filename = b_point_density_node.name();
+ point_density->space = (NodeTexVoxelSpace)b_point_density_node.space();
+ point_density->interpolation = get_image_interpolation(b_point_density_node);
+ point_density->builtin_data = b_point_density_node.ptr.data;
+ point_density->image_manager = scene->image_manager;
+
+ /* TODO(sergey): Use more proper update flag. */
+ if (true) {
+ point_density->add_image();
+ b_point_density_node.cache_point_density(b_depsgraph);
+ scene->image_manager->tag_reload_image(point_density->filename.string(),
+ point_density->builtin_data,
+ point_density->interpolation,
+ EXTENSION_CLIP,
+ true);
+ }
+ node = point_density;
+
+ /* Transformation form world space to texture space.
+ *
+ * NOTE: Do this after the texture is cached, this is because getting
+ * min/max will need to access this cache.
+ */
+ BL::Object b_ob(b_point_density_node.object());
+ if (b_ob) {
+ float3 loc, size;
+ point_density_texture_space(b_depsgraph, b_point_density_node, loc, size);
+ point_density->tfm = transform_translate(-loc) * transform_scale(size) *
+ transform_inverse(get_transform(b_ob.matrix_world()));
+ }
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBevel)) {
+ BL::ShaderNodeBevel b_bevel_node(b_node);
+ BevelNode *bevel = new BevelNode();
+ bevel->samples = b_bevel_node.samples();
+ node = bevel;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeDisplacement)) {
+ BL::ShaderNodeDisplacement b_disp_node(b_node);
+ DisplacementNode *disp = new DisplacementNode();
+ disp->space = (NodeNormalMapSpace)b_disp_node.space();
+ node = disp;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeVectorDisplacement)) {
+ BL::ShaderNodeVectorDisplacement b_disp_node(b_node);
+ VectorDisplacementNode *disp = new VectorDisplacementNode();
+ disp->space = (NodeNormalMapSpace)b_disp_node.space();
+ disp->attribute = "";
+ node = disp;
+ }
+
+ if (node) {
+ node->name = b_node.name();
+ graph->add(node);
+ }
+
+ return node;
}
static bool node_use_modified_socket_name(ShaderNode *node)
{
- if(node->special_type == SHADER_SPECIAL_TYPE_SCRIPT)
- return false;
+ if (node->special_type == SHADER_SPECIAL_TYPE_SCRIPT)
+ return false;
- return true;
+ return true;
}
static ShaderInput *node_find_input_by_name(ShaderNode *node,
- BL::Node& b_node,
- BL::NodeSocket& b_socket)
+ BL::Node &b_node,
+ BL::NodeSocket &b_socket)
{
- string name = b_socket.name();
+ string name = b_socket.name();
- if(node_use_modified_socket_name(node)) {
- BL::Node::inputs_iterator b_input;
- bool found = false;
- int counter = 0, total = 0;
+ if (node_use_modified_socket_name(node)) {
+ BL::Node::inputs_iterator b_input;
+ bool found = false;
+ int counter = 0, total = 0;
- for(b_node.inputs.begin(b_input); b_input != b_node.inputs.end(); ++b_input) {
- if(b_input->name() == name) {
- if(!found)
- counter++;
- total++;
- }
+ for (b_node.inputs.begin(b_input); b_input != b_node.inputs.end(); ++b_input) {
+ if (b_input->name() == name) {
+ if (!found)
+ counter++;
+ total++;
+ }
- if(b_input->ptr.data == b_socket.ptr.data)
- found = true;
- }
+ if (b_input->ptr.data == b_socket.ptr.data)
+ found = true;
+ }
- /* rename if needed */
- if(name == "Shader")
- name = "Closure";
+ /* rename if needed */
+ if (name == "Shader")
+ name = "Closure";
- if(total > 1)
- name = string_printf("%s%d", name.c_str(), counter);
- }
+ if (total > 1)
+ name = string_printf("%s%d", name.c_str(), counter);
+ }
- return node->input(name.c_str());
+ return node->input(name.c_str());
}
static ShaderOutput *node_find_output_by_name(ShaderNode *node,
- BL::Node& b_node,
- BL::NodeSocket& b_socket)
+ BL::Node &b_node,
+ BL::NodeSocket &b_socket)
{
- string name = b_socket.name();
+ string name = b_socket.name();
- if(node_use_modified_socket_name(node)) {
- BL::Node::outputs_iterator b_output;
- bool found = false;
- int counter = 0, total = 0;
+ if (node_use_modified_socket_name(node)) {
+ BL::Node::outputs_iterator b_output;
+ bool found = false;
+ int counter = 0, total = 0;
- for(b_node.outputs.begin(b_output); b_output != b_node.outputs.end(); ++b_output) {
- if(b_output->name() == name) {
- if(!found)
- counter++;
- total++;
- }
+ for (b_node.outputs.begin(b_output); b_output != b_node.outputs.end(); ++b_output) {
+ if (b_output->name() == name) {
+ if (!found)
+ counter++;
+ total++;
+ }
- if(b_output->ptr.data == b_socket.ptr.data)
- found = true;
- }
+ if (b_output->ptr.data == b_socket.ptr.data)
+ found = true;
+ }
- /* rename if needed */
- if(name == "Shader")
- name = "Closure";
+ /* rename if needed */
+ if (name == "Shader")
+ name = "Closure";
- if(total > 1)
- name = string_printf("%s%d", name.c_str(), counter);
- }
+ if (total > 1)
+ name = string_printf("%s%d", name.c_str(), counter);
+ }
- return node->output(name.c_str());
+ return node->output(name.c_str());
}
static void add_nodes(Scene *scene,
- BL::RenderEngine& b_engine,
- BL::BlendData& b_data,
- BL::Depsgraph& b_depsgraph,
- BL::Scene& b_scene,
+ BL::RenderEngine &b_engine,
+ BL::BlendData &b_data,
+ BL::Depsgraph &b_depsgraph,
+ BL::Scene &b_scene,
ShaderGraph *graph,
- BL::ShaderNodeTree& b_ntree,
+ BL::ShaderNodeTree &b_ntree,
const ProxyMap &proxy_input_map,
const ProxyMap &proxy_output_map)
{
- /* add nodes */
- BL::ShaderNodeTree::nodes_iterator b_node;
- PtrInputMap input_map;
- PtrOutputMap output_map;
-
- BL::Node::inputs_iterator b_input;
- BL::Node::outputs_iterator b_output;
-
- /* find the node to use for output if there are multiple */
- BL::ShaderNode output_node = b_ntree.get_output_node(BL::ShaderNodeOutputMaterial::target_CYCLES);
-
- /* add nodes */
- for(b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) {
- if(b_node->mute() || b_node->is_a(&RNA_NodeReroute)) {
- /* replace muted node with internal links */
- BL::Node::internal_links_iterator b_link;
- for(b_node->internal_links.begin(b_link); b_link != b_node->internal_links.end(); ++b_link) {
- BL::NodeSocket to_socket(b_link->to_socket());
- SocketType::Type to_socket_type = convert_socket_type(to_socket);
- if(to_socket_type == SocketType::UNDEFINED) {
- continue;
- }
-
- ConvertNode *proxy = new ConvertNode(to_socket_type, to_socket_type, true);
-
- input_map[b_link->from_socket().ptr.data] = proxy->inputs[0];
- output_map[b_link->to_socket().ptr.data] = proxy->outputs[0];
-
- graph->add(proxy);
- }
- }
- else if(b_node->is_a(&RNA_ShaderNodeGroup) ||
- b_node->is_a(&RNA_NodeCustomGroup) ||
- b_node->is_a(&RNA_ShaderNodeCustomGroup)) {
-
- BL::ShaderNodeTree b_group_ntree(PointerRNA_NULL);
- if(b_node->is_a(&RNA_ShaderNodeGroup))
- b_group_ntree = BL::ShaderNodeTree(((BL::NodeGroup)(*b_node)).node_tree());
- else if (b_node->is_a(&RNA_NodeCustomGroup))
- b_group_ntree = BL::ShaderNodeTree(((BL::NodeCustomGroup)(*b_node)).node_tree());
- else
- b_group_ntree = BL::ShaderNodeTree(((BL::ShaderNodeCustomGroup)(*b_node)).node_tree());
-
- ProxyMap group_proxy_input_map, group_proxy_output_map;
-
- /* Add a proxy node for each socket
- * Do this even if the node group has no internal tree,
- * so that links have something to connect to and assert won't fail.
- */
- for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
- SocketType::Type input_type = convert_socket_type(*b_input);
- if(input_type == SocketType::UNDEFINED) {
- continue;
- }
-
- ConvertNode *proxy = new ConvertNode(input_type, input_type, true);
- graph->add(proxy);
-
- /* register the proxy node for internal binding */
- group_proxy_input_map[b_input->identifier()] = proxy;
-
- input_map[b_input->ptr.data] = proxy->inputs[0];
-
- set_default_value(proxy->inputs[0], *b_input, b_data, b_ntree);
- }
- for(b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
- SocketType::Type output_type = convert_socket_type(*b_output);
- if(output_type == SocketType::UNDEFINED) {
- continue;
- }
-
- ConvertNode *proxy = new ConvertNode(output_type, output_type, true);
- graph->add(proxy);
-
- /* register the proxy node for internal binding */
- group_proxy_output_map[b_output->identifier()] = proxy;
-
- output_map[b_output->ptr.data] = proxy->outputs[0];
- }
-
- if(b_group_ntree) {
- add_nodes(scene,
- b_engine,
- b_data,
- b_depsgraph,
- b_scene,
- graph,
- b_group_ntree,
- group_proxy_input_map,
- group_proxy_output_map);
- }
- }
- else if(b_node->is_a(&RNA_NodeGroupInput)) {
- /* map each socket to a proxy node */
- for(b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
- ProxyMap::const_iterator proxy_it = proxy_input_map.find(b_output->identifier());
- if(proxy_it != proxy_input_map.end()) {
- ConvertNode *proxy = proxy_it->second;
-
- output_map[b_output->ptr.data] = proxy->outputs[0];
- }
- }
- }
- else if(b_node->is_a(&RNA_NodeGroupOutput)) {
- BL::NodeGroupOutput b_output_node(*b_node);
- /* only the active group output is used */
- if(b_output_node.is_active_output()) {
- /* map each socket to a proxy node */
- for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
- ProxyMap::const_iterator proxy_it = proxy_output_map.find(b_input->identifier());
- if(proxy_it != proxy_output_map.end()) {
- ConvertNode *proxy = proxy_it->second;
-
- input_map[b_input->ptr.data] = proxy->inputs[0];
-
- set_default_value(proxy->inputs[0], *b_input, b_data, b_ntree);
- }
- }
- }
- }
- else {
- ShaderNode *node = NULL;
-
- if(b_node->ptr.data == output_node.ptr.data) {
- node = graph->output();
- }
- else {
- BL::ShaderNode b_shader_node(*b_node);
- node = add_node(scene,
- b_engine,
- b_data,
- b_depsgraph,
- b_scene,
- graph,
- b_ntree,
- b_shader_node);
- }
-
- if(node) {
- /* map node sockets for linking */
- for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
- ShaderInput *input = node_find_input_by_name(node, *b_node, *b_input);
- if(!input) {
- /* XXX should not happen, report error? */
- continue;
- }
- input_map[b_input->ptr.data] = input;
-
- set_default_value(input, *b_input, b_data, b_ntree);
- }
- for(b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
- ShaderOutput *output = node_find_output_by_name(node, *b_node, *b_output);
- if(!output) {
- /* XXX should not happen, report error? */
- continue;
- }
- output_map[b_output->ptr.data] = output;
- }
- }
- }
- }
-
- /* connect nodes */
- BL::NodeTree::links_iterator b_link;
-
- for(b_ntree.links.begin(b_link); b_link != b_ntree.links.end(); ++b_link) {
- /* Ignore invalid links to avoid unwanted cycles created in graph. */
- if(!b_link->is_valid()) {
- continue;
- }
- /* get blender link data */
- BL::NodeSocket b_from_sock = b_link->from_socket();
- BL::NodeSocket b_to_sock = b_link->to_socket();
-
- ShaderOutput *output = 0;
- ShaderInput *input = 0;
-
- PtrOutputMap::iterator output_it = output_map.find(b_from_sock.ptr.data);
- if(output_it != output_map.end())
- output = output_it->second;
- PtrInputMap::iterator input_it = input_map.find(b_to_sock.ptr.data);
- if(input_it != input_map.end())
- input = input_it->second;
-
- /* either node may be NULL when the node was not exported, typically
- * because the node type is not supported */
- if(output && input)
- graph->connect(output, input);
- }
+ /* add nodes */
+ BL::ShaderNodeTree::nodes_iterator b_node;
+ PtrInputMap input_map;
+ PtrOutputMap output_map;
+
+ BL::Node::inputs_iterator b_input;
+ BL::Node::outputs_iterator b_output;
+
+ /* find the node to use for output if there are multiple */
+ BL::ShaderNode output_node = b_ntree.get_output_node(
+ BL::ShaderNodeOutputMaterial::target_CYCLES);
+
+ /* add nodes */
+ for (b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) {
+ if (b_node->mute() || b_node->is_a(&RNA_NodeReroute)) {
+ /* replace muted node with internal links */
+ BL::Node::internal_links_iterator b_link;
+ for (b_node->internal_links.begin(b_link); b_link != b_node->internal_links.end();
+ ++b_link) {
+ BL::NodeSocket to_socket(b_link->to_socket());
+ SocketType::Type to_socket_type = convert_socket_type(to_socket);
+ if (to_socket_type == SocketType::UNDEFINED) {
+ continue;
+ }
+
+ ConvertNode *proxy = new ConvertNode(to_socket_type, to_socket_type, true);
+
+ input_map[b_link->from_socket().ptr.data] = proxy->inputs[0];
+ output_map[b_link->to_socket().ptr.data] = proxy->outputs[0];
+
+ graph->add(proxy);
+ }
+ }
+ else if (b_node->is_a(&RNA_ShaderNodeGroup) || b_node->is_a(&RNA_NodeCustomGroup) ||
+ b_node->is_a(&RNA_ShaderNodeCustomGroup)) {
+
+ BL::ShaderNodeTree b_group_ntree(PointerRNA_NULL);
+ if (b_node->is_a(&RNA_ShaderNodeGroup))
+ b_group_ntree = BL::ShaderNodeTree(((BL::NodeGroup)(*b_node)).node_tree());
+ else if (b_node->is_a(&RNA_NodeCustomGroup))
+ b_group_ntree = BL::ShaderNodeTree(((BL::NodeCustomGroup)(*b_node)).node_tree());
+ else
+ b_group_ntree = BL::ShaderNodeTree(((BL::ShaderNodeCustomGroup)(*b_node)).node_tree());
+
+ ProxyMap group_proxy_input_map, group_proxy_output_map;
+
+ /* Add a proxy node for each socket
+ * Do this even if the node group has no internal tree,
+ * so that links have something to connect to and assert won't fail.
+ */
+ for (b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
+ SocketType::Type input_type = convert_socket_type(*b_input);
+ if (input_type == SocketType::UNDEFINED) {
+ continue;
+ }
+
+ ConvertNode *proxy = new ConvertNode(input_type, input_type, true);
+ graph->add(proxy);
+
+ /* register the proxy node for internal binding */
+ group_proxy_input_map[b_input->identifier()] = proxy;
+
+ input_map[b_input->ptr.data] = proxy->inputs[0];
+
+ set_default_value(proxy->inputs[0], *b_input, b_data, b_ntree);
+ }
+ for (b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
+ SocketType::Type output_type = convert_socket_type(*b_output);
+ if (output_type == SocketType::UNDEFINED) {
+ continue;
+ }
+
+ ConvertNode *proxy = new ConvertNode(output_type, output_type, true);
+ graph->add(proxy);
+
+ /* register the proxy node for internal binding */
+ group_proxy_output_map[b_output->identifier()] = proxy;
+
+ output_map[b_output->ptr.data] = proxy->outputs[0];
+ }
+
+ if (b_group_ntree) {
+ add_nodes(scene,
+ b_engine,
+ b_data,
+ b_depsgraph,
+ b_scene,
+ graph,
+ b_group_ntree,
+ group_proxy_input_map,
+ group_proxy_output_map);
+ }
+ }
+ else if (b_node->is_a(&RNA_NodeGroupInput)) {
+ /* map each socket to a proxy node */
+ for (b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
+ ProxyMap::const_iterator proxy_it = proxy_input_map.find(b_output->identifier());
+ if (proxy_it != proxy_input_map.end()) {
+ ConvertNode *proxy = proxy_it->second;
+
+ output_map[b_output->ptr.data] = proxy->outputs[0];
+ }
+ }
+ }
+ else if (b_node->is_a(&RNA_NodeGroupOutput)) {
+ BL::NodeGroupOutput b_output_node(*b_node);
+ /* only the active group output is used */
+ if (b_output_node.is_active_output()) {
+ /* map each socket to a proxy node */
+ for (b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
+ ProxyMap::const_iterator proxy_it = proxy_output_map.find(b_input->identifier());
+ if (proxy_it != proxy_output_map.end()) {
+ ConvertNode *proxy = proxy_it->second;
+
+ input_map[b_input->ptr.data] = proxy->inputs[0];
+
+ set_default_value(proxy->inputs[0], *b_input, b_data, b_ntree);
+ }
+ }
+ }
+ }
+ else {
+ ShaderNode *node = NULL;
+
+ if (b_node->ptr.data == output_node.ptr.data) {
+ node = graph->output();
+ }
+ else {
+ BL::ShaderNode b_shader_node(*b_node);
+ node = add_node(
+ scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree, b_shader_node);
+ }
+
+ if (node) {
+ /* map node sockets for linking */
+ for (b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
+ ShaderInput *input = node_find_input_by_name(node, *b_node, *b_input);
+ if (!input) {
+ /* XXX should not happen, report error? */
+ continue;
+ }
+ input_map[b_input->ptr.data] = input;
+
+ set_default_value(input, *b_input, b_data, b_ntree);
+ }
+ for (b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
+ ShaderOutput *output = node_find_output_by_name(node, *b_node, *b_output);
+ if (!output) {
+ /* XXX should not happen, report error? */
+ continue;
+ }
+ output_map[b_output->ptr.data] = output;
+ }
+ }
+ }
+ }
+
+ /* connect nodes */
+ BL::NodeTree::links_iterator b_link;
+
+ for (b_ntree.links.begin(b_link); b_link != b_ntree.links.end(); ++b_link) {
+ /* Ignore invalid links to avoid unwanted cycles created in graph. */
+ if (!b_link->is_valid()) {
+ continue;
+ }
+ /* get blender link data */
+ BL::NodeSocket b_from_sock = b_link->from_socket();
+ BL::NodeSocket b_to_sock = b_link->to_socket();
+
+ ShaderOutput *output = 0;
+ ShaderInput *input = 0;
+
+ PtrOutputMap::iterator output_it = output_map.find(b_from_sock.ptr.data);
+ if (output_it != output_map.end())
+ output = output_it->second;
+ PtrInputMap::iterator input_it = input_map.find(b_to_sock.ptr.data);
+ if (input_it != input_map.end())
+ input = input_it->second;
+
+ /* either node may be NULL when the node was not exported, typically
+ * because the node type is not supported */
+ if (output && input)
+ graph->connect(output, input);
+ }
}
static void add_nodes(Scene *scene,
- BL::RenderEngine& b_engine,
- BL::BlendData& b_data,
- BL::Depsgraph& b_depsgraph,
- BL::Scene& b_scene,
+ BL::RenderEngine &b_engine,
+ BL::BlendData &b_data,
+ BL::Depsgraph &b_depsgraph,
+ BL::Scene &b_scene,
ShaderGraph *graph,
- BL::ShaderNodeTree& b_ntree)
+ BL::ShaderNodeTree &b_ntree)
{
- static const ProxyMap empty_proxy_map;
- add_nodes(scene,
- b_engine,
- b_data,
- b_depsgraph,
- b_scene,
- graph,
- b_ntree,
- empty_proxy_map,
- empty_proxy_map);
+ static const ProxyMap empty_proxy_map;
+ add_nodes(scene,
+ b_engine,
+ b_data,
+ b_depsgraph,
+ b_scene,
+ graph,
+ b_ntree,
+ empty_proxy_map,
+ empty_proxy_map);
}
/* Sync Materials */
-void BlenderSync::sync_materials(BL::Depsgraph& b_depsgraph, bool update_all)
+void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all)
{
- shader_map.set_default(scene->default_surface);
-
- TaskPool pool;
- set<Shader*> updated_shaders;
-
- BL::Depsgraph::ids_iterator b_id;
- for(b_depsgraph.ids.begin(b_id); b_id != b_depsgraph.ids.end(); ++b_id) {
- if(!b_id->is_a(&RNA_Material)) {
- continue;
- }
-
- BL::Material b_mat(*b_id);
- Shader *shader;
-
- /* test if we need to sync */
- if(shader_map.sync(&shader, b_mat) || shader->need_sync_object || update_all) {
- ShaderGraph *graph = new ShaderGraph();
-
- shader->name = b_mat.name().c_str();
- shader->pass_id = b_mat.pass_index();
- shader->need_sync_object = false;
-
- /* create nodes */
- if(b_mat.use_nodes() && b_mat.node_tree()) {
- BL::ShaderNodeTree b_ntree(b_mat.node_tree());
-
- add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree);
- }
- else {
- DiffuseBsdfNode *diffuse = new DiffuseBsdfNode();
- diffuse->color = get_float3(b_mat.diffuse_color());
- graph->add(diffuse);
-
- ShaderNode *out = graph->output();
- graph->connect(diffuse->output("BSDF"), out->input("Surface"));
- }
-
- /* settings */
- PointerRNA cmat = RNA_pointer_get(&b_mat.ptr, "cycles");
- shader->use_mis = get_boolean(cmat, "sample_as_light");
- shader->use_transparent_shadow = get_boolean(cmat, "use_transparent_shadow");
- 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 = get_displacement_method(cmat);
-
- shader->set_graph(graph);
-
- /* By simplifying the shader graph as soon as possible, some
- * redundant shader nodes might be removed which prevents loading
- * unnecessary attributes later.
- *
- * However, since graph simplification also accounts for e.g. mix
- * weight, this would cause frequent expensive resyncs in interactive
- * sessions, so for those sessions optimization is only performed
- * right before compiling.
- */
- if(!preview) {
- pool.push(function_bind(&ShaderGraph::simplify, graph, scene));
- /* NOTE: Update shaders out of the threads since those routines
- * are accessing and writing to a global context.
- */
- updated_shaders.insert(shader);
- }
- else {
- /* NOTE: Update tagging can access links which are being
- * optimized out.
- */
- shader->tag_update(scene);
- }
- }
- }
-
- pool.wait_work();
-
- foreach(Shader *shader, updated_shaders) {
- shader->tag_update(scene);
- }
+ shader_map.set_default(scene->default_surface);
+
+ TaskPool pool;
+ set<Shader *> updated_shaders;
+
+ BL::Depsgraph::ids_iterator b_id;
+ for (b_depsgraph.ids.begin(b_id); b_id != b_depsgraph.ids.end(); ++b_id) {
+ if (!b_id->is_a(&RNA_Material)) {
+ continue;
+ }
+
+ BL::Material b_mat(*b_id);
+ Shader *shader;
+
+ /* test if we need to sync */
+ if (shader_map.sync(&shader, b_mat) || shader->need_sync_object || update_all) {
+ ShaderGraph *graph = new ShaderGraph();
+
+ shader->name = b_mat.name().c_str();
+ shader->pass_id = b_mat.pass_index();
+ shader->need_sync_object = false;
+
+ /* create nodes */
+ if (b_mat.use_nodes() && b_mat.node_tree()) {
+ BL::ShaderNodeTree b_ntree(b_mat.node_tree());
+
+ add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree);
+ }
+ else {
+ DiffuseBsdfNode *diffuse = new DiffuseBsdfNode();
+ diffuse->color = get_float3(b_mat.diffuse_color());
+ graph->add(diffuse);
+
+ ShaderNode *out = graph->output();
+ graph->connect(diffuse->output("BSDF"), out->input("Surface"));
+ }
+
+ /* settings */
+ PointerRNA cmat = RNA_pointer_get(&b_mat.ptr, "cycles");
+ shader->use_mis = get_boolean(cmat, "sample_as_light");
+ shader->use_transparent_shadow = get_boolean(cmat, "use_transparent_shadow");
+ 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 = get_displacement_method(cmat);
+
+ shader->set_graph(graph);
+
+ /* By simplifying the shader graph as soon as possible, some
+ * redundant shader nodes might be removed which prevents loading
+ * unnecessary attributes later.
+ *
+ * However, since graph simplification also accounts for e.g. mix
+ * weight, this would cause frequent expensive resyncs in interactive
+ * sessions, so for those sessions optimization is only performed
+ * right before compiling.
+ */
+ if (!preview) {
+ pool.push(function_bind(&ShaderGraph::simplify, graph, scene));
+ /* NOTE: Update shaders out of the threads since those routines
+ * are accessing and writing to a global context.
+ */
+ updated_shaders.insert(shader);
+ }
+ else {
+ /* NOTE: Update tagging can access links which are being
+ * optimized out.
+ */
+ shader->tag_update(scene);
+ }
+ }
+ }
+
+ pool.wait_work();
+
+ foreach (Shader *shader, updated_shaders) {
+ shader->tag_update(scene);
+ }
}
/* Sync World */
-void BlenderSync::sync_world(BL::Depsgraph& b_depsgraph, bool update_all)
+void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, bool update_all)
{
- Background *background = scene->background;
- Background prevbackground = *background;
-
- BL::World b_world = b_scene.world();
-
- if(world_recalc || update_all || b_world.ptr.data != world_map) {
- Shader *shader = scene->default_background;
- ShaderGraph *graph = new ShaderGraph();
-
- /* create nodes */
- if(b_world && b_world.use_nodes() && b_world.node_tree()) {
- BL::ShaderNodeTree b_ntree(b_world.node_tree());
-
- add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree);
-
- /* volume */
- PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles");
- shader->heterogeneous_volume = !get_boolean(cworld, "homogeneous_volume");
- shader->volume_sampling_method = get_volume_sampling(cworld);
- shader->volume_interpolation_method = get_volume_interpolation(cworld);
- }
- else if(b_world) {
- BackgroundNode *background = new BackgroundNode();
- background->color = get_float3(b_world.color());
- graph->add(background);
-
- ShaderNode *out = graph->output();
- graph->connect(background->output("Background"), out->input("Surface"));
- }
-
- if(b_world) {
- /* AO */
- BL::WorldLighting b_light = b_world.light_settings();
-
- background->use_ao = b_light.use_ambient_occlusion();
- background->ao_factor = b_light.ao_factor();
- background->ao_distance = b_light.distance();
-
- /* visibility */
- PointerRNA cvisibility = RNA_pointer_get(&b_world.ptr, "cycles_visibility");
- uint visibility = 0;
-
- visibility |= get_boolean(cvisibility, "camera")? PATH_RAY_CAMERA: 0;
- 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;
- }
- else {
- background->use_ao = false;
- background->ao_factor = 0.0f;
- background->ao_distance = FLT_MAX;
- }
-
- shader->set_graph(graph);
- shader->tag_update(scene);
- background->tag_update(scene);
- }
-
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
-
- /* when doing preview render check for BI's transparency settings,
- * this is so because Blender's preview render routines are not able
- * to tweak all cycles's settings depending on different circumstances
- */
- if(b_engine.is_preview() == false)
- background->transparent = get_boolean(cscene, "film_transparent");
- else
- background->transparent = b_scene.render().alpha_mode() == BL::RenderSettings::alpha_mode_TRANSPARENT;
-
- if(background->transparent) {
- background->transparent_glass = get_boolean(cscene, "film_transparent_glass");
- background->transparent_roughness_threshold = get_float(cscene, "film_transparent_roughness");
- }
- else {
- background->transparent_glass = false;
- background->transparent_roughness_threshold = 0.0f;
- }
-
- background->use_shader = view_layer.use_background_shader;
- background->use_ao = background->use_ao && view_layer.use_background_ao;
-
- if(background->modified(prevbackground))
- background->tag_update(scene);
+ Background *background = scene->background;
+ Background prevbackground = *background;
+
+ BL::World b_world = b_scene.world();
+
+ if (world_recalc || update_all || b_world.ptr.data != world_map) {
+ Shader *shader = scene->default_background;
+ ShaderGraph *graph = new ShaderGraph();
+
+ /* create nodes */
+ if (b_world && b_world.use_nodes() && b_world.node_tree()) {
+ BL::ShaderNodeTree b_ntree(b_world.node_tree());
+
+ add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree);
+
+ /* volume */
+ PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles");
+ shader->heterogeneous_volume = !get_boolean(cworld, "homogeneous_volume");
+ shader->volume_sampling_method = get_volume_sampling(cworld);
+ shader->volume_interpolation_method = get_volume_interpolation(cworld);
+ }
+ else if (b_world) {
+ BackgroundNode *background = new BackgroundNode();
+ background->color = get_float3(b_world.color());
+ graph->add(background);
+
+ ShaderNode *out = graph->output();
+ graph->connect(background->output("Background"), out->input("Surface"));
+ }
+
+ if (b_world) {
+ /* AO */
+ BL::WorldLighting b_light = b_world.light_settings();
+
+ background->use_ao = b_light.use_ambient_occlusion();
+ background->ao_factor = b_light.ao_factor();
+ background->ao_distance = b_light.distance();
+
+ /* visibility */
+ PointerRNA cvisibility = RNA_pointer_get(&b_world.ptr, "cycles_visibility");
+ uint visibility = 0;
+
+ visibility |= get_boolean(cvisibility, "camera") ? PATH_RAY_CAMERA : 0;
+ 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;
+ }
+ else {
+ background->use_ao = false;
+ background->ao_factor = 0.0f;
+ background->ao_distance = FLT_MAX;
+ }
+
+ shader->set_graph(graph);
+ shader->tag_update(scene);
+ background->tag_update(scene);
+ }
+
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+
+ /* when doing preview render check for BI's transparency settings,
+ * this is so because Blender's preview render routines are not able
+ * to tweak all cycles's settings depending on different circumstances
+ */
+ if (b_engine.is_preview() == false)
+ background->transparent = get_boolean(cscene, "film_transparent");
+ else
+ background->transparent = b_scene.render().alpha_mode() ==
+ BL::RenderSettings::alpha_mode_TRANSPARENT;
+
+ if (background->transparent) {
+ background->transparent_glass = get_boolean(cscene, "film_transparent_glass");
+ background->transparent_roughness_threshold = get_float(cscene, "film_transparent_roughness");
+ }
+ else {
+ background->transparent_glass = false;
+ background->transparent_roughness_threshold = 0.0f;
+ }
+
+ background->use_shader = view_layer.use_background_shader;
+ background->use_ao = background->use_ao && view_layer.use_background_ao;
+
+ if (background->modified(prevbackground))
+ background->tag_update(scene);
}
/* Sync Lights */
-void BlenderSync::sync_lights(BL::Depsgraph& b_depsgraph, bool update_all)
+void BlenderSync::sync_lights(BL::Depsgraph &b_depsgraph, bool update_all)
{
- shader_map.set_default(scene->default_light);
-
- BL::Depsgraph::ids_iterator b_id;
- for(b_depsgraph.ids.begin(b_id); b_id != b_depsgraph.ids.end(); ++b_id) {
- if(!b_id->is_a(&RNA_Light)) {
- continue;
- }
-
- BL::Light b_light(*b_id);
- Shader *shader;
-
- /* test if we need to sync */
- if(shader_map.sync(&shader, b_light) || update_all) {
- ShaderGraph *graph = new ShaderGraph();
-
- /* create nodes */
- if(b_light.use_nodes() && b_light.node_tree()) {
- shader->name = b_light.name().c_str();
-
- BL::ShaderNodeTree b_ntree(b_light.node_tree());
-
- add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree);
- }
- else {
- float strength = 1.0f;
-
- if(b_light.type() == BL::Light::type_POINT ||
- b_light.type() == BL::Light::type_SPOT ||
- b_light.type() == BL::Light::type_AREA)
- {
- strength = 100.0f;
- }
-
- EmissionNode *emission = new EmissionNode();
- emission->color = get_float3(b_light.color());
- emission->strength = strength;
- graph->add(emission);
-
- ShaderNode *out = graph->output();
- graph->connect(emission->output("Emission"), out->input("Surface"));
- }
-
- shader->set_graph(graph);
- shader->tag_update(scene);
- }
- }
+ shader_map.set_default(scene->default_light);
+
+ BL::Depsgraph::ids_iterator b_id;
+ for (b_depsgraph.ids.begin(b_id); b_id != b_depsgraph.ids.end(); ++b_id) {
+ if (!b_id->is_a(&RNA_Light)) {
+ continue;
+ }
+
+ BL::Light b_light(*b_id);
+ Shader *shader;
+
+ /* test if we need to sync */
+ if (shader_map.sync(&shader, b_light) || update_all) {
+ ShaderGraph *graph = new ShaderGraph();
+
+ /* create nodes */
+ if (b_light.use_nodes() && b_light.node_tree()) {
+ shader->name = b_light.name().c_str();
+
+ BL::ShaderNodeTree b_ntree(b_light.node_tree());
+
+ add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree);
+ }
+ else {
+ float strength = 1.0f;
+
+ if (b_light.type() == BL::Light::type_POINT || b_light.type() == BL::Light::type_SPOT ||
+ b_light.type() == BL::Light::type_AREA) {
+ strength = 100.0f;
+ }
+
+ EmissionNode *emission = new EmissionNode();
+ emission->color = get_float3(b_light.color());
+ emission->strength = strength;
+ graph->add(emission);
+
+ ShaderNode *out = graph->output();
+ graph->connect(emission->output("Emission"), out->input("Surface"));
+ }
+
+ shader->set_graph(graph);
+ shader->tag_update(scene);
+ }
+ }
}
-void BlenderSync::sync_shaders(BL::Depsgraph& b_depsgraph)
+void BlenderSync::sync_shaders(BL::Depsgraph &b_depsgraph)
{
- /* for auto refresh images */
- bool auto_refresh_update = false;
+ /* for auto refresh images */
+ bool auto_refresh_update = false;
- if(preview) {
- ImageManager *image_manager = scene->image_manager;
- int frame = b_scene.frame_current();
- auto_refresh_update = image_manager->set_animation_frame_update(frame);
- }
+ if (preview) {
+ ImageManager *image_manager = scene->image_manager;
+ int frame = b_scene.frame_current();
+ auto_refresh_update = image_manager->set_animation_frame_update(frame);
+ }
- shader_map.pre_sync();
+ shader_map.pre_sync();
- sync_world(b_depsgraph, auto_refresh_update);
- sync_lights(b_depsgraph, auto_refresh_update);
- sync_materials(b_depsgraph, auto_refresh_update);
+ sync_world(b_depsgraph, auto_refresh_update);
+ sync_lights(b_depsgraph, auto_refresh_update);
+ sync_materials(b_depsgraph, auto_refresh_update);
- /* false = don't delete unused shaders, not supported */
- shader_map.post_sync(false);
+ /* false = don't delete unused shaders, not supported */
+ shader_map.post_sync(false);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index 063a2cd4d16..0ab6d88487e 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -45,32 +45,33 @@ static const char *cryptomatte_prefix = "Crypto";
/* Constructor */
-BlenderSync::BlenderSync(BL::RenderEngine& b_engine,
- BL::BlendData& b_data,
- BL::Scene& b_scene,
+BlenderSync::BlenderSync(BL::RenderEngine &b_engine,
+ BL::BlendData &b_data,
+ BL::Scene &b_scene,
Scene *scene,
bool preview,
Progress &progress)
-: b_engine(b_engine),
- b_data(b_data),
- b_scene(b_scene),
- shader_map(&scene->shaders),
- object_map(&scene->objects),
- mesh_map(&scene->meshes),
- light_map(&scene->lights),
- particle_system_map(&scene->particle_systems),
- world_map(NULL),
- world_recalc(false),
- scene(scene),
- preview(preview),
- experimental(false),
- dicing_rate(1.0f),
- max_subdivisions(12),
- progress(progress)
+ : b_engine(b_engine),
+ b_data(b_data),
+ b_scene(b_scene),
+ shader_map(&scene->shaders),
+ object_map(&scene->objects),
+ mesh_map(&scene->meshes),
+ light_map(&scene->lights),
+ particle_system_map(&scene->particle_systems),
+ world_map(NULL),
+ world_recalc(false),
+ scene(scene),
+ preview(preview),
+ experimental(false),
+ dicing_rate(1.0f),
+ max_subdivisions(12),
+ progress(progress)
{
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
- dicing_rate = preview ? RNA_float_get(&cscene, "preview_dicing_rate") : RNA_float_get(&cscene, "dicing_rate");
- max_subdivisions = RNA_int_get(&cscene, "max_subdivisions");
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+ dicing_rate = preview ? RNA_float_get(&cscene, "preview_dicing_rate") :
+ RNA_float_get(&cscene, "dicing_rate");
+ max_subdivisions = RNA_int_get(&cscene, "max_subdivisions");
}
BlenderSync::~BlenderSync()
@@ -79,788 +80,776 @@ BlenderSync::~BlenderSync()
/* Sync */
-void BlenderSync::sync_recalc(BL::Depsgraph& b_depsgraph)
+void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph)
{
- /* Sync recalc flags from blender to cycles. Actual update is done separate,
- * so we can do it later on if doing it immediate is not suitable. */
-
- bool has_updated_objects = b_depsgraph.id_type_updated(BL::DriverTarget::id_type_OBJECT);
-
- if(experimental) {
- /* Mark all meshes as needing to be exported again if dicing changed. */
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
- bool dicing_prop_changed = false;
-
- float updated_dicing_rate = preview ? RNA_float_get(&cscene, "preview_dicing_rate")
- : RNA_float_get(&cscene, "dicing_rate");
-
- if(dicing_rate != updated_dicing_rate) {
- dicing_rate = updated_dicing_rate;
- dicing_prop_changed = true;
- }
-
- int updated_max_subdivisions = RNA_int_get(&cscene, "max_subdivisions");
-
- if(max_subdivisions != updated_max_subdivisions) {
- max_subdivisions = updated_max_subdivisions;
- dicing_prop_changed = true;
- }
-
- if(dicing_prop_changed) {
- for(const pair<void*, Mesh*>& iter: mesh_map.key_to_scene_data()) {
- Mesh *mesh = iter.second;
- if(mesh->subdivision_type != Mesh::SUBDIVISION_NONE) {
- mesh_map.set_recalc(iter.first);
- }
- }
- }
- }
-
- /* Iterate over all IDs in this depsgraph. */
- BL::Depsgraph::updates_iterator b_update;
- for(b_depsgraph.updates.begin(b_update); b_update != b_depsgraph.updates.end(); ++b_update) {
- BL::ID b_id(b_update->id());
-
- /* Material */
- if(b_id.is_a(&RNA_Material)) {
- BL::Material b_mat(b_id);
- shader_map.set_recalc(b_mat);
- }
- /* Light */
- else if(b_id.is_a(&RNA_Light)) {
- BL::Light b_light(b_id);
- shader_map.set_recalc(b_light);
- }
- /* Object */
- else if(b_id.is_a(&RNA_Object)) {
- BL::Object b_ob(b_id);
- const bool updated_geometry = b_update->is_updated_geometry();
-
- if(b_update->is_updated_transform()) {
- object_map.set_recalc(b_ob);
- light_map.set_recalc(b_ob);
- }
-
- if(object_is_mesh(b_ob)) {
- if(updated_geometry ||
- (object_subdivision_type(b_ob, preview, experimental) != Mesh::SUBDIVISION_NONE))
- {
- BL::ID key = BKE_object_is_modified(b_ob)? b_ob: b_ob.data();
- mesh_map.set_recalc(key);
- }
- }
- else if(object_is_light(b_ob)) {
- if(updated_geometry) {
- light_map.set_recalc(b_ob);
- }
- }
-
- if(updated_geometry) {
- BL::Object::particle_systems_iterator b_psys;
- for(b_ob.particle_systems.begin(b_psys); b_psys != b_ob.particle_systems.end(); ++b_psys)
- particle_system_map.set_recalc(b_ob);
- }
- }
- /* Mesh */
- else if(b_id.is_a(&RNA_Mesh)) {
- BL::Mesh b_mesh(b_id);
- mesh_map.set_recalc(b_mesh);
- }
- /* World */
- else if(b_id.is_a(&RNA_World)) {
- BL::World b_world(b_id);
- if(world_map == b_world.ptr.data) {
- world_recalc = true;
- }
- }
- }
-
- /* Updates shader with object dependency if objects changed. */
- if(has_updated_objects) {
- if(scene->default_background->has_object_dependency) {
- world_recalc = true;
- }
-
- foreach(Shader *shader, scene->shaders) {
- if(shader->has_object_dependency) {
- shader->need_sync_object = true;
- }
- }
- }
+ /* Sync recalc flags from blender to cycles. Actual update is done separate,
+ * so we can do it later on if doing it immediate is not suitable. */
+
+ bool has_updated_objects = b_depsgraph.id_type_updated(BL::DriverTarget::id_type_OBJECT);
+
+ if (experimental) {
+ /* Mark all meshes as needing to be exported again if dicing changed. */
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+ bool dicing_prop_changed = false;
+
+ float updated_dicing_rate = preview ? RNA_float_get(&cscene, "preview_dicing_rate") :
+ RNA_float_get(&cscene, "dicing_rate");
+
+ if (dicing_rate != updated_dicing_rate) {
+ dicing_rate = updated_dicing_rate;
+ dicing_prop_changed = true;
+ }
+
+ int updated_max_subdivisions = RNA_int_get(&cscene, "max_subdivisions");
+
+ if (max_subdivisions != updated_max_subdivisions) {
+ max_subdivisions = updated_max_subdivisions;
+ dicing_prop_changed = true;
+ }
+
+ if (dicing_prop_changed) {
+ for (const pair<void *, Mesh *> &iter : mesh_map.key_to_scene_data()) {
+ Mesh *mesh = iter.second;
+ if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE) {
+ mesh_map.set_recalc(iter.first);
+ }
+ }
+ }
+ }
+
+ /* Iterate over all IDs in this depsgraph. */
+ BL::Depsgraph::updates_iterator b_update;
+ for (b_depsgraph.updates.begin(b_update); b_update != b_depsgraph.updates.end(); ++b_update) {
+ BL::ID b_id(b_update->id());
+
+ /* Material */
+ if (b_id.is_a(&RNA_Material)) {
+ BL::Material b_mat(b_id);
+ shader_map.set_recalc(b_mat);
+ }
+ /* Light */
+ else if (b_id.is_a(&RNA_Light)) {
+ BL::Light b_light(b_id);
+ shader_map.set_recalc(b_light);
+ }
+ /* Object */
+ else if (b_id.is_a(&RNA_Object)) {
+ BL::Object b_ob(b_id);
+ const bool updated_geometry = b_update->is_updated_geometry();
+
+ if (b_update->is_updated_transform()) {
+ object_map.set_recalc(b_ob);
+ light_map.set_recalc(b_ob);
+ }
+
+ if (object_is_mesh(b_ob)) {
+ if (updated_geometry ||
+ (object_subdivision_type(b_ob, preview, experimental) != Mesh::SUBDIVISION_NONE)) {
+ BL::ID key = BKE_object_is_modified(b_ob) ? b_ob : b_ob.data();
+ mesh_map.set_recalc(key);
+ }
+ }
+ else if (object_is_light(b_ob)) {
+ if (updated_geometry) {
+ light_map.set_recalc(b_ob);
+ }
+ }
+
+ if (updated_geometry) {
+ BL::Object::particle_systems_iterator b_psys;
+ for (b_ob.particle_systems.begin(b_psys); b_psys != b_ob.particle_systems.end(); ++b_psys)
+ particle_system_map.set_recalc(b_ob);
+ }
+ }
+ /* Mesh */
+ else if (b_id.is_a(&RNA_Mesh)) {
+ BL::Mesh b_mesh(b_id);
+ mesh_map.set_recalc(b_mesh);
+ }
+ /* World */
+ else if (b_id.is_a(&RNA_World)) {
+ BL::World b_world(b_id);
+ if (world_map == b_world.ptr.data) {
+ world_recalc = true;
+ }
+ }
+ }
+
+ /* Updates shader with object dependency if objects changed. */
+ if (has_updated_objects) {
+ if (scene->default_background->has_object_dependency) {
+ world_recalc = true;
+ }
+
+ foreach (Shader *shader, scene->shaders) {
+ if (shader->has_object_dependency) {
+ shader->need_sync_object = true;
+ }
+ }
+ }
}
-void BlenderSync::sync_data(BL::RenderSettings& b_render,
- BL::Depsgraph& b_depsgraph,
- BL::SpaceView3D& b_v3d,
- BL::Object& b_override,
- int width, int height,
+void BlenderSync::sync_data(BL::RenderSettings &b_render,
+ BL::Depsgraph &b_depsgraph,
+ BL::SpaceView3D &b_v3d,
+ BL::Object &b_override,
+ int width,
+ int height,
void **python_thread_state)
{
- BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
-
- sync_view_layer(b_v3d, b_view_layer);
- sync_integrator();
- sync_film();
- sync_shaders(b_depsgraph);
- sync_images();
- sync_curve_settings();
-
- mesh_synced.clear(); /* use for objects and motion sync */
-
- if(scene->need_motion() == Scene::MOTION_PASS ||
- scene->need_motion() == Scene::MOTION_NONE ||
- scene->camera->motion_position == Camera::MOTION_POSITION_CENTER)
- {
- sync_objects(b_depsgraph);
- }
- sync_motion(b_render,
- b_depsgraph,
- b_override,
- width, height,
- python_thread_state);
-
- mesh_synced.clear();
-
- free_data_after_sync(b_depsgraph);
+ BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
+
+ sync_view_layer(b_v3d, b_view_layer);
+ sync_integrator();
+ sync_film();
+ sync_shaders(b_depsgraph);
+ sync_images();
+ sync_curve_settings();
+
+ mesh_synced.clear(); /* use for objects and motion sync */
+
+ if (scene->need_motion() == Scene::MOTION_PASS || scene->need_motion() == Scene::MOTION_NONE ||
+ scene->camera->motion_position == Camera::MOTION_POSITION_CENTER) {
+ sync_objects(b_depsgraph);
+ }
+ sync_motion(b_render, b_depsgraph, b_override, width, height, python_thread_state);
+
+ mesh_synced.clear();
+
+ free_data_after_sync(b_depsgraph);
}
/* Integrator */
void BlenderSync::sync_integrator()
{
- BL::RenderSettings r = b_scene.render();
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
-
- experimental = (get_enum(cscene, "feature_set") != 0);
-
- Integrator *integrator = scene->integrator;
- Integrator previntegrator = *integrator;
-
- integrator->max_bounce = get_int(cscene, "max_bounces");
-
- integrator->max_diffuse_bounce = get_int(cscene, "diffuse_bounces");
- integrator->max_glossy_bounce = get_int(cscene, "glossy_bounces");
- integrator->max_transmission_bounce = get_int(cscene, "transmission_bounces");
- integrator->max_volume_bounce = get_int(cscene, "volume_bounces");
-
- integrator->transparent_max_bounce = get_int(cscene, "transparent_max_bounces");
-
- integrator->volume_max_steps = get_int(cscene, "volume_max_steps");
- integrator->volume_step_size = get_float(cscene, "volume_step_size");
-
- 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");
- if(get_boolean(cscene, "use_animated_seed")) {
- integrator->seed = hash_int_2d(b_scene.frame_current(),
- get_int(cscene, "seed"));
- if(b_scene.frame_subframe() != 0.0f) {
- /* TODO(sergey): Ideally should be some sort of hash_merge,
- * but this is good enough for now.
- */
- integrator->seed += hash_int_2d((int)(b_scene.frame_subframe() * (float)INT_MAX),
- get_int(cscene, "seed"));
- }
- }
-
- integrator->sampling_pattern = (SamplingPattern)get_enum(
- cscene,
- "sampling_pattern",
- SAMPLING_NUM_PATTERNS,
- SAMPLING_PATTERN_SOBOL);
-
- integrator->sample_clamp_direct = get_float(cscene, "sample_clamp_direct");
- integrator->sample_clamp_indirect = get_float(cscene, "sample_clamp_indirect");
- if(!preview) {
- if(integrator->motion_blur != r.use_motion_blur()) {
- scene->object_manager->tag_update(scene);
- scene->camera->tag_update();
- }
-
- integrator->motion_blur = r.use_motion_blur();
- }
-
- integrator->method = (Integrator::Method)get_enum(cscene,
- "progressive",
- Integrator::NUM_METHODS,
- Integrator::PATH);
-
- integrator->sample_all_lights_direct = get_boolean(cscene, "sample_all_lights_direct");
- integrator->sample_all_lights_indirect = get_boolean(cscene, "sample_all_lights_indirect");
- integrator->light_sampling_threshold = get_float(cscene, "light_sampling_threshold");
-
- int diffuse_samples = get_int(cscene, "diffuse_samples");
- int glossy_samples = get_int(cscene, "glossy_samples");
- int transmission_samples = get_int(cscene, "transmission_samples");
- int ao_samples = get_int(cscene, "ao_samples");
- int mesh_light_samples = get_int(cscene, "mesh_light_samples");
- int subsurface_samples = get_int(cscene, "subsurface_samples");
- int volume_samples = get_int(cscene, "volume_samples");
-
- if(get_boolean(cscene, "use_square_samples")) {
- integrator->diffuse_samples = diffuse_samples * diffuse_samples;
- integrator->glossy_samples = glossy_samples * glossy_samples;
- integrator->transmission_samples = transmission_samples * transmission_samples;
- integrator->ao_samples = ao_samples * ao_samples;
- integrator->mesh_light_samples = mesh_light_samples * mesh_light_samples;
- integrator->subsurface_samples = subsurface_samples * subsurface_samples;
- integrator->volume_samples = volume_samples * volume_samples;
- }
- else {
- integrator->diffuse_samples = diffuse_samples;
- integrator->glossy_samples = glossy_samples;
- integrator->transmission_samples = transmission_samples;
- integrator->ao_samples = ao_samples;
- integrator->mesh_light_samples = mesh_light_samples;
- integrator->subsurface_samples = subsurface_samples;
- integrator->volume_samples = volume_samples;
- }
-
- if(b_scene.render().use_simplify()) {
- if(preview) {
- integrator->ao_bounces = get_int(cscene, "ao_bounces");
- }
- else {
- integrator->ao_bounces = get_int(cscene, "ao_bounces_render");
- }
- }
- else {
- integrator->ao_bounces = 0;
- }
-
- if(integrator->modified(previntegrator))
- integrator->tag_update(scene);
+ BL::RenderSettings r = b_scene.render();
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+
+ experimental = (get_enum(cscene, "feature_set") != 0);
+
+ Integrator *integrator = scene->integrator;
+ Integrator previntegrator = *integrator;
+
+ integrator->max_bounce = get_int(cscene, "max_bounces");
+
+ integrator->max_diffuse_bounce = get_int(cscene, "diffuse_bounces");
+ integrator->max_glossy_bounce = get_int(cscene, "glossy_bounces");
+ integrator->max_transmission_bounce = get_int(cscene, "transmission_bounces");
+ integrator->max_volume_bounce = get_int(cscene, "volume_bounces");
+
+ integrator->transparent_max_bounce = get_int(cscene, "transparent_max_bounces");
+
+ integrator->volume_max_steps = get_int(cscene, "volume_max_steps");
+ integrator->volume_step_size = get_float(cscene, "volume_step_size");
+
+ 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");
+ if (get_boolean(cscene, "use_animated_seed")) {
+ integrator->seed = hash_int_2d(b_scene.frame_current(), get_int(cscene, "seed"));
+ if (b_scene.frame_subframe() != 0.0f) {
+ /* TODO(sergey): Ideally should be some sort of hash_merge,
+ * but this is good enough for now.
+ */
+ integrator->seed += hash_int_2d((int)(b_scene.frame_subframe() * (float)INT_MAX),
+ get_int(cscene, "seed"));
+ }
+ }
+
+ integrator->sampling_pattern = (SamplingPattern)get_enum(
+ cscene, "sampling_pattern", SAMPLING_NUM_PATTERNS, SAMPLING_PATTERN_SOBOL);
+
+ integrator->sample_clamp_direct = get_float(cscene, "sample_clamp_direct");
+ integrator->sample_clamp_indirect = get_float(cscene, "sample_clamp_indirect");
+ if (!preview) {
+ if (integrator->motion_blur != r.use_motion_blur()) {
+ scene->object_manager->tag_update(scene);
+ scene->camera->tag_update();
+ }
+
+ integrator->motion_blur = r.use_motion_blur();
+ }
+
+ integrator->method = (Integrator::Method)get_enum(
+ cscene, "progressive", Integrator::NUM_METHODS, Integrator::PATH);
+
+ integrator->sample_all_lights_direct = get_boolean(cscene, "sample_all_lights_direct");
+ integrator->sample_all_lights_indirect = get_boolean(cscene, "sample_all_lights_indirect");
+ integrator->light_sampling_threshold = get_float(cscene, "light_sampling_threshold");
+
+ int diffuse_samples = get_int(cscene, "diffuse_samples");
+ int glossy_samples = get_int(cscene, "glossy_samples");
+ int transmission_samples = get_int(cscene, "transmission_samples");
+ int ao_samples = get_int(cscene, "ao_samples");
+ int mesh_light_samples = get_int(cscene, "mesh_light_samples");
+ int subsurface_samples = get_int(cscene, "subsurface_samples");
+ int volume_samples = get_int(cscene, "volume_samples");
+
+ if (get_boolean(cscene, "use_square_samples")) {
+ integrator->diffuse_samples = diffuse_samples * diffuse_samples;
+ integrator->glossy_samples = glossy_samples * glossy_samples;
+ integrator->transmission_samples = transmission_samples * transmission_samples;
+ integrator->ao_samples = ao_samples * ao_samples;
+ integrator->mesh_light_samples = mesh_light_samples * mesh_light_samples;
+ integrator->subsurface_samples = subsurface_samples * subsurface_samples;
+ integrator->volume_samples = volume_samples * volume_samples;
+ }
+ else {
+ integrator->diffuse_samples = diffuse_samples;
+ integrator->glossy_samples = glossy_samples;
+ integrator->transmission_samples = transmission_samples;
+ integrator->ao_samples = ao_samples;
+ integrator->mesh_light_samples = mesh_light_samples;
+ integrator->subsurface_samples = subsurface_samples;
+ integrator->volume_samples = volume_samples;
+ }
+
+ if (b_scene.render().use_simplify()) {
+ if (preview) {
+ integrator->ao_bounces = get_int(cscene, "ao_bounces");
+ }
+ else {
+ integrator->ao_bounces = get_int(cscene, "ao_bounces_render");
+ }
+ }
+ else {
+ integrator->ao_bounces = 0;
+ }
+
+ if (integrator->modified(previntegrator))
+ integrator->tag_update(scene);
}
/* Film */
void BlenderSync::sync_film()
{
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
-
- Film *film = scene->film;
- Film prevfilm = *film;
-
- film->exposure = get_float(cscene, "film_exposure");
- film->filter_type = (FilterType)get_enum(cscene,
- "pixel_filter_type",
- FILTER_NUM_TYPES,
- FILTER_BLACKMAN_HARRIS);
- film->filter_width = (film->filter_type == FILTER_BOX)? 1.0f: get_float(cscene, "filter_width");
-
- if(b_scene.world()) {
- BL::WorldMistSettings b_mist = b_scene.world().mist_settings();
-
- film->mist_start = b_mist.start();
- film->mist_depth = b_mist.depth();
-
- switch(b_mist.falloff()) {
- case BL::WorldMistSettings::falloff_QUADRATIC:
- film->mist_falloff = 2.0f;
- break;
- case BL::WorldMistSettings::falloff_LINEAR:
- film->mist_falloff = 1.0f;
- break;
- case BL::WorldMistSettings::falloff_INVERSE_QUADRATIC:
- film->mist_falloff = 0.5f;
- break;
- }
- }
-
- if(film->modified(prevfilm))
- film->tag_update(scene);
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+
+ Film *film = scene->film;
+ Film prevfilm = *film;
+
+ film->exposure = get_float(cscene, "film_exposure");
+ film->filter_type = (FilterType)get_enum(
+ cscene, "pixel_filter_type", FILTER_NUM_TYPES, FILTER_BLACKMAN_HARRIS);
+ film->filter_width = (film->filter_type == FILTER_BOX) ? 1.0f :
+ get_float(cscene, "filter_width");
+
+ if (b_scene.world()) {
+ BL::WorldMistSettings b_mist = b_scene.world().mist_settings();
+
+ film->mist_start = b_mist.start();
+ film->mist_depth = b_mist.depth();
+
+ switch (b_mist.falloff()) {
+ case BL::WorldMistSettings::falloff_QUADRATIC:
+ film->mist_falloff = 2.0f;
+ break;
+ case BL::WorldMistSettings::falloff_LINEAR:
+ film->mist_falloff = 1.0f;
+ break;
+ case BL::WorldMistSettings::falloff_INVERSE_QUADRATIC:
+ film->mist_falloff = 0.5f;
+ break;
+ }
+ }
+
+ if (film->modified(prevfilm))
+ film->tag_update(scene);
}
/* Render Layer */
-void BlenderSync::sync_view_layer(BL::SpaceView3D& /*b_v3d*/, BL::ViewLayer& b_view_layer)
+void BlenderSync::sync_view_layer(BL::SpaceView3D & /*b_v3d*/, BL::ViewLayer &b_view_layer)
{
- /* render layer */
- view_layer.name = b_view_layer.name();
- view_layer.use_background_shader = b_view_layer.use_sky();
- view_layer.use_background_ao = b_view_layer.use_ao();
- view_layer.use_surfaces = b_view_layer.use_solid();
- view_layer.use_hair = b_view_layer.use_strand();
-
- /* Material override. */
- view_layer.material_override = b_view_layer.material_override();
-
- /* Sample override. */
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
- int use_layer_samples = get_enum(cscene, "use_layer_samples");
-
- view_layer.bound_samples = (use_layer_samples == 1);
- view_layer.samples = 0;
-
- if(use_layer_samples != 2) {
- int samples = b_view_layer.samples();
- if(get_boolean(cscene, "use_square_samples"))
- view_layer.samples = samples * samples;
- else
- view_layer.samples = samples;
- }
-
+ /* render layer */
+ view_layer.name = b_view_layer.name();
+ view_layer.use_background_shader = b_view_layer.use_sky();
+ view_layer.use_background_ao = b_view_layer.use_ao();
+ view_layer.use_surfaces = b_view_layer.use_solid();
+ view_layer.use_hair = b_view_layer.use_strand();
+
+ /* Material override. */
+ view_layer.material_override = b_view_layer.material_override();
+
+ /* Sample override. */
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+ int use_layer_samples = get_enum(cscene, "use_layer_samples");
+
+ view_layer.bound_samples = (use_layer_samples == 1);
+ view_layer.samples = 0;
+
+ if (use_layer_samples != 2) {
+ int samples = b_view_layer.samples();
+ if (get_boolean(cscene, "use_square_samples"))
+ view_layer.samples = samples * samples;
+ else
+ view_layer.samples = samples;
+ }
}
/* Images */
void BlenderSync::sync_images()
{
- /* Sync is a convention for this API, but currently it frees unused buffers. */
-
- const bool is_interface_locked = b_engine.render() &&
- b_engine.render().use_lock_interface();
- if(is_interface_locked == false && BlenderSession::headless == false) {
- /* If interface is not locked, it's possible image is needed for
- * the display.
- */
- return;
- }
- /* Free buffers used by images which are not needed for render. */
- BL::BlendData::images_iterator b_image;
- for(b_data.images.begin(b_image);
- b_image != b_data.images.end();
- ++b_image)
- {
- /* TODO(sergey): Consider making it an utility function to check
- * whether image is considered builtin.
- */
- const bool is_builtin = b_image->packed_file() ||
- b_image->source() == BL::Image::source_GENERATED ||
- b_image->source() == BL::Image::source_MOVIE ||
- b_engine.is_preview();
- if(is_builtin == false) {
- b_image->buffers_free();
- }
- /* TODO(sergey): Free builtin images not used by any shader. */
- }
+ /* Sync is a convention for this API, but currently it frees unused buffers. */
+
+ const bool is_interface_locked = b_engine.render() && b_engine.render().use_lock_interface();
+ if (is_interface_locked == false && BlenderSession::headless == false) {
+ /* If interface is not locked, it's possible image is needed for
+ * the display.
+ */
+ return;
+ }
+ /* Free buffers used by images which are not needed for render. */
+ BL::BlendData::images_iterator b_image;
+ for (b_data.images.begin(b_image); b_image != b_data.images.end(); ++b_image) {
+ /* TODO(sergey): Consider making it an utility function to check
+ * whether image is considered builtin.
+ */
+ const bool is_builtin = b_image->packed_file() ||
+ b_image->source() == BL::Image::source_GENERATED ||
+ b_image->source() == BL::Image::source_MOVIE || b_engine.is_preview();
+ if (is_builtin == false) {
+ b_image->buffers_free();
+ }
+ /* TODO(sergey): Free builtin images not used by any shader. */
+ }
}
/* Passes */
-PassType BlenderSync::get_pass_type(BL::RenderPass& b_pass)
+PassType BlenderSync::get_pass_type(BL::RenderPass &b_pass)
{
- string name = b_pass.name();
-#define MAP_PASS(passname, passtype) if(name == passname) return passtype;
- /* NOTE: Keep in sync with defined names from DNA_scene_types.h */
- MAP_PASS("Combined", PASS_COMBINED);
- MAP_PASS("Depth", PASS_DEPTH);
- MAP_PASS("Mist", PASS_MIST);
- MAP_PASS("Normal", PASS_NORMAL);
- MAP_PASS("IndexOB", PASS_OBJECT_ID);
- MAP_PASS("UV", PASS_UV);
- MAP_PASS("Vector", PASS_MOTION);
- MAP_PASS("IndexMA", PASS_MATERIAL_ID);
-
- MAP_PASS("DiffDir", PASS_DIFFUSE_DIRECT);
- MAP_PASS("GlossDir", PASS_GLOSSY_DIRECT);
- MAP_PASS("TransDir", PASS_TRANSMISSION_DIRECT);
- MAP_PASS("SubsurfaceDir", PASS_SUBSURFACE_DIRECT);
- MAP_PASS("VolumeDir", PASS_VOLUME_DIRECT);
-
- MAP_PASS("DiffInd", PASS_DIFFUSE_INDIRECT);
- MAP_PASS("GlossInd", PASS_GLOSSY_INDIRECT);
- MAP_PASS("TransInd", PASS_TRANSMISSION_INDIRECT);
- MAP_PASS("SubsurfaceInd", PASS_SUBSURFACE_INDIRECT);
- MAP_PASS("VolumeInd", PASS_VOLUME_INDIRECT);
-
- MAP_PASS("DiffCol", PASS_DIFFUSE_COLOR);
- MAP_PASS("GlossCol", PASS_GLOSSY_COLOR);
- MAP_PASS("TransCol", PASS_TRANSMISSION_COLOR);
- MAP_PASS("SubsurfaceCol", PASS_SUBSURFACE_COLOR);
-
- MAP_PASS("Emit", PASS_EMISSION);
- MAP_PASS("Env", PASS_BACKGROUND);
- MAP_PASS("AO", PASS_AO);
- MAP_PASS("Shadow", PASS_SHADOW);
+ string name = b_pass.name();
+#define MAP_PASS(passname, passtype) \
+ if (name == passname) \
+ return passtype;
+ /* NOTE: Keep in sync with defined names from DNA_scene_types.h */
+ MAP_PASS("Combined", PASS_COMBINED);
+ MAP_PASS("Depth", PASS_DEPTH);
+ MAP_PASS("Mist", PASS_MIST);
+ MAP_PASS("Normal", PASS_NORMAL);
+ MAP_PASS("IndexOB", PASS_OBJECT_ID);
+ MAP_PASS("UV", PASS_UV);
+ MAP_PASS("Vector", PASS_MOTION);
+ MAP_PASS("IndexMA", PASS_MATERIAL_ID);
+
+ MAP_PASS("DiffDir", PASS_DIFFUSE_DIRECT);
+ MAP_PASS("GlossDir", PASS_GLOSSY_DIRECT);
+ MAP_PASS("TransDir", PASS_TRANSMISSION_DIRECT);
+ MAP_PASS("SubsurfaceDir", PASS_SUBSURFACE_DIRECT);
+ MAP_PASS("VolumeDir", PASS_VOLUME_DIRECT);
+
+ MAP_PASS("DiffInd", PASS_DIFFUSE_INDIRECT);
+ MAP_PASS("GlossInd", PASS_GLOSSY_INDIRECT);
+ MAP_PASS("TransInd", PASS_TRANSMISSION_INDIRECT);
+ MAP_PASS("SubsurfaceInd", PASS_SUBSURFACE_INDIRECT);
+ MAP_PASS("VolumeInd", PASS_VOLUME_INDIRECT);
+
+ MAP_PASS("DiffCol", PASS_DIFFUSE_COLOR);
+ MAP_PASS("GlossCol", PASS_GLOSSY_COLOR);
+ MAP_PASS("TransCol", PASS_TRANSMISSION_COLOR);
+ MAP_PASS("SubsurfaceCol", PASS_SUBSURFACE_COLOR);
+
+ MAP_PASS("Emit", PASS_EMISSION);
+ MAP_PASS("Env", PASS_BACKGROUND);
+ MAP_PASS("AO", PASS_AO);
+ MAP_PASS("Shadow", PASS_SHADOW);
#ifdef __KERNEL_DEBUG__
- MAP_PASS("Debug BVH Traversed Nodes", PASS_BVH_TRAVERSED_NODES);
- MAP_PASS("Debug BVH Traversed Instances", PASS_BVH_TRAVERSED_INSTANCES);
- MAP_PASS("Debug BVH Intersections", PASS_BVH_INTERSECTIONS);
- MAP_PASS("Debug Ray Bounces", PASS_RAY_BOUNCES);
+ MAP_PASS("Debug BVH Traversed Nodes", PASS_BVH_TRAVERSED_NODES);
+ MAP_PASS("Debug BVH Traversed Instances", PASS_BVH_TRAVERSED_INSTANCES);
+ MAP_PASS("Debug BVH Intersections", PASS_BVH_INTERSECTIONS);
+ MAP_PASS("Debug Ray Bounces", PASS_RAY_BOUNCES);
#endif
- MAP_PASS("Debug Render Time", PASS_RENDER_TIME);
- if(string_startswith(name, cryptomatte_prefix)) {
- return PASS_CRYPTOMATTE;
- }
+ MAP_PASS("Debug Render Time", PASS_RENDER_TIME);
+ if (string_startswith(name, cryptomatte_prefix)) {
+ return PASS_CRYPTOMATTE;
+ }
#undef MAP_PASS
- return PASS_NONE;
+ return PASS_NONE;
}
-int BlenderSync::get_denoising_pass(BL::RenderPass& b_pass)
+int BlenderSync::get_denoising_pass(BL::RenderPass &b_pass)
{
- string name = b_pass.name();
-
- if(name == "Noisy Image") return DENOISING_PASS_PREFILTERED_COLOR;
-
- if(name.substr(0, 10) != "Denoising ") {
- return -1;
- }
- name = name.substr(10);
-
-#define MAP_PASS(passname, offset) if(name == passname) return offset;
- MAP_PASS("Normal", DENOISING_PASS_PREFILTERED_NORMAL);
- MAP_PASS("Albedo", DENOISING_PASS_PREFILTERED_ALBEDO);
- MAP_PASS("Depth", DENOISING_PASS_PREFILTERED_DEPTH);
- MAP_PASS("Shadowing", DENOISING_PASS_PREFILTERED_SHADOWING);
- MAP_PASS("Variance", DENOISING_PASS_PREFILTERED_VARIANCE);
- MAP_PASS("Intensity", DENOISING_PASS_PREFILTERED_INTENSITY);
- MAP_PASS("Clean", DENOISING_PASS_CLEAN);
+ string name = b_pass.name();
+
+ if (name == "Noisy Image")
+ return DENOISING_PASS_PREFILTERED_COLOR;
+
+ if (name.substr(0, 10) != "Denoising ") {
+ return -1;
+ }
+ name = name.substr(10);
+
+#define MAP_PASS(passname, offset) \
+ if (name == passname) \
+ return offset;
+ MAP_PASS("Normal", DENOISING_PASS_PREFILTERED_NORMAL);
+ MAP_PASS("Albedo", DENOISING_PASS_PREFILTERED_ALBEDO);
+ MAP_PASS("Depth", DENOISING_PASS_PREFILTERED_DEPTH);
+ MAP_PASS("Shadowing", DENOISING_PASS_PREFILTERED_SHADOWING);
+ MAP_PASS("Variance", DENOISING_PASS_PREFILTERED_VARIANCE);
+ MAP_PASS("Intensity", DENOISING_PASS_PREFILTERED_INTENSITY);
+ MAP_PASS("Clean", DENOISING_PASS_CLEAN);
#undef MAP_PASS
- return -1;
+ return -1;
}
-vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer& b_rlay,
- BL::ViewLayer& b_view_layer)
+vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, BL::ViewLayer &b_view_layer)
{
- vector<Pass> passes;
- Pass::add(PASS_COMBINED, passes);
-
- /* loop over passes */
- BL::RenderLayer::passes_iterator b_pass_iter;
-
- for(b_rlay.passes.begin(b_pass_iter); b_pass_iter != b_rlay.passes.end(); ++b_pass_iter) {
- BL::RenderPass b_pass(*b_pass_iter);
- PassType pass_type = get_pass_type(b_pass);
-
- if(pass_type == PASS_MOTION && scene->integrator->motion_blur)
- continue;
- if(pass_type != PASS_NONE)
- Pass::add(pass_type, passes);
- }
-
- PointerRNA crp = RNA_pointer_get(&b_view_layer.ptr, "cycles");
- bool full_denoising = get_boolean(crp, "use_denoising");
- bool write_denoising_passes = get_boolean(crp, "denoising_store_passes");
-
- scene->film->denoising_flags = 0;
- if(full_denoising || write_denoising_passes) {
-#define MAP_OPTION(name, flag) if(!get_boolean(crp, name)) scene->film->denoising_flags |= flag;
- MAP_OPTION("denoising_diffuse_direct", DENOISING_CLEAN_DIFFUSE_DIR);
- MAP_OPTION("denoising_diffuse_indirect", DENOISING_CLEAN_DIFFUSE_IND);
- MAP_OPTION("denoising_glossy_direct", DENOISING_CLEAN_GLOSSY_DIR);
- MAP_OPTION("denoising_glossy_indirect", DENOISING_CLEAN_GLOSSY_IND);
- MAP_OPTION("denoising_transmission_direct", DENOISING_CLEAN_TRANSMISSION_DIR);
- MAP_OPTION("denoising_transmission_indirect", DENOISING_CLEAN_TRANSMISSION_IND);
- MAP_OPTION("denoising_subsurface_direct", DENOISING_CLEAN_SUBSURFACE_DIR);
- MAP_OPTION("denoising_subsurface_indirect", DENOISING_CLEAN_SUBSURFACE_IND);
+ vector<Pass> passes;
+ Pass::add(PASS_COMBINED, passes);
+
+ /* loop over passes */
+ BL::RenderLayer::passes_iterator b_pass_iter;
+
+ for (b_rlay.passes.begin(b_pass_iter); b_pass_iter != b_rlay.passes.end(); ++b_pass_iter) {
+ BL::RenderPass b_pass(*b_pass_iter);
+ PassType pass_type = get_pass_type(b_pass);
+
+ if (pass_type == PASS_MOTION && scene->integrator->motion_blur)
+ continue;
+ if (pass_type != PASS_NONE)
+ Pass::add(pass_type, passes);
+ }
+
+ PointerRNA crp = RNA_pointer_get(&b_view_layer.ptr, "cycles");
+ bool full_denoising = get_boolean(crp, "use_denoising");
+ bool write_denoising_passes = get_boolean(crp, "denoising_store_passes");
+
+ scene->film->denoising_flags = 0;
+ if (full_denoising || write_denoising_passes) {
+#define MAP_OPTION(name, flag) \
+ if (!get_boolean(crp, name)) \
+ scene->film->denoising_flags |= flag;
+ MAP_OPTION("denoising_diffuse_direct", DENOISING_CLEAN_DIFFUSE_DIR);
+ MAP_OPTION("denoising_diffuse_indirect", DENOISING_CLEAN_DIFFUSE_IND);
+ MAP_OPTION("denoising_glossy_direct", DENOISING_CLEAN_GLOSSY_DIR);
+ MAP_OPTION("denoising_glossy_indirect", DENOISING_CLEAN_GLOSSY_IND);
+ MAP_OPTION("denoising_transmission_direct", DENOISING_CLEAN_TRANSMISSION_DIR);
+ MAP_OPTION("denoising_transmission_indirect", DENOISING_CLEAN_TRANSMISSION_IND);
+ MAP_OPTION("denoising_subsurface_direct", DENOISING_CLEAN_SUBSURFACE_DIR);
+ MAP_OPTION("denoising_subsurface_indirect", DENOISING_CLEAN_SUBSURFACE_IND);
#undef MAP_OPTION
- b_engine.add_pass("Noisy Image", 4, "RGBA", b_view_layer.name().c_str());
- }
-
- if(write_denoising_passes) {
- b_engine.add_pass("Denoising Normal", 3, "XYZ", b_view_layer.name().c_str());
- b_engine.add_pass("Denoising Albedo", 3, "RGB", b_view_layer.name().c_str());
- b_engine.add_pass("Denoising Depth", 1, "Z", b_view_layer.name().c_str());
- b_engine.add_pass("Denoising Shadowing", 1, "X", b_view_layer.name().c_str());
- b_engine.add_pass("Denoising Variance", 3, "RGB", b_view_layer.name().c_str());
- b_engine.add_pass("Denoising Intensity", 1, "X", b_view_layer.name().c_str());
-
- if(scene->film->denoising_flags & DENOISING_CLEAN_ALL_PASSES) {
- b_engine.add_pass("Denoising Clean", 3, "RGB", b_view_layer.name().c_str());
- }
- }
+ b_engine.add_pass("Noisy Image", 4, "RGBA", b_view_layer.name().c_str());
+ }
+
+ if (write_denoising_passes) {
+ b_engine.add_pass("Denoising Normal", 3, "XYZ", b_view_layer.name().c_str());
+ b_engine.add_pass("Denoising Albedo", 3, "RGB", b_view_layer.name().c_str());
+ b_engine.add_pass("Denoising Depth", 1, "Z", b_view_layer.name().c_str());
+ b_engine.add_pass("Denoising Shadowing", 1, "X", b_view_layer.name().c_str());
+ b_engine.add_pass("Denoising Variance", 3, "RGB", b_view_layer.name().c_str());
+ b_engine.add_pass("Denoising Intensity", 1, "X", b_view_layer.name().c_str());
+
+ if (scene->film->denoising_flags & DENOISING_CLEAN_ALL_PASSES) {
+ b_engine.add_pass("Denoising Clean", 3, "RGB", b_view_layer.name().c_str());
+ }
+ }
#ifdef __KERNEL_DEBUG__
- if(get_boolean(crp, "pass_debug_bvh_traversed_nodes")) {
- b_engine.add_pass("Debug BVH Traversed Nodes", 1, "X", b_view_layer.name().c_str());
- Pass::add(PASS_BVH_TRAVERSED_NODES, passes);
- }
- if(get_boolean(crp, "pass_debug_bvh_traversed_instances")) {
- b_engine.add_pass("Debug BVH Traversed Instances", 1, "X", b_view_layer.name().c_str());
- Pass::add(PASS_BVH_TRAVERSED_INSTANCES, passes);
- }
- if(get_boolean(crp, "pass_debug_bvh_intersections")) {
- b_engine.add_pass("Debug BVH Intersections", 1, "X", b_view_layer.name().c_str());
- Pass::add(PASS_BVH_INTERSECTIONS, passes);
- }
- if(get_boolean(crp, "pass_debug_ray_bounces")) {
- b_engine.add_pass("Debug Ray Bounces", 1, "X", b_view_layer.name().c_str());
- Pass::add(PASS_RAY_BOUNCES, passes);
- }
+ if (get_boolean(crp, "pass_debug_bvh_traversed_nodes")) {
+ b_engine.add_pass("Debug BVH Traversed Nodes", 1, "X", b_view_layer.name().c_str());
+ Pass::add(PASS_BVH_TRAVERSED_NODES, passes);
+ }
+ if (get_boolean(crp, "pass_debug_bvh_traversed_instances")) {
+ b_engine.add_pass("Debug BVH Traversed Instances", 1, "X", b_view_layer.name().c_str());
+ Pass::add(PASS_BVH_TRAVERSED_INSTANCES, passes);
+ }
+ if (get_boolean(crp, "pass_debug_bvh_intersections")) {
+ b_engine.add_pass("Debug BVH Intersections", 1, "X", b_view_layer.name().c_str());
+ Pass::add(PASS_BVH_INTERSECTIONS, passes);
+ }
+ if (get_boolean(crp, "pass_debug_ray_bounces")) {
+ b_engine.add_pass("Debug Ray Bounces", 1, "X", b_view_layer.name().c_str());
+ Pass::add(PASS_RAY_BOUNCES, passes);
+ }
#endif
- if(get_boolean(crp, "pass_debug_render_time")) {
- b_engine.add_pass("Debug Render Time", 1, "X", b_view_layer.name().c_str());
- Pass::add(PASS_RENDER_TIME, passes);
- }
- if(get_boolean(crp, "use_pass_volume_direct")) {
- b_engine.add_pass("VolumeDir", 3, "RGB", b_view_layer.name().c_str());
- Pass::add(PASS_VOLUME_DIRECT, passes);
- }
- if(get_boolean(crp, "use_pass_volume_indirect")) {
- b_engine.add_pass("VolumeInd", 3, "RGB", b_view_layer.name().c_str());
- Pass::add(PASS_VOLUME_INDIRECT, passes);
- }
-
- /* Cryptomatte stores two ID/weight pairs per RGBA layer.
- * User facing paramter is the number of pairs. */
- int crypto_depth = min(16, get_int(crp, "pass_crypto_depth")) / 2;
- scene->film->cryptomatte_depth = crypto_depth;
- scene->film->cryptomatte_passes = CRYPT_NONE;
- if(get_boolean(crp, "use_pass_crypto_object")) {
- for(int i = 0; i < crypto_depth; ++i) {
- string passname = cryptomatte_prefix + string_printf("Object%02d", i);
- b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
- Pass::add(PASS_CRYPTOMATTE, passes, passname.c_str());
- }
- scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes | CRYPT_OBJECT);
- }
- if(get_boolean(crp, "use_pass_crypto_material")) {
- for(int i = 0; i < crypto_depth; ++i) {
- string passname = cryptomatte_prefix + string_printf("Material%02d", i);
- b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
- Pass::add(PASS_CRYPTOMATTE, passes, passname.c_str());
- }
- scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes | CRYPT_MATERIAL);
- }
- if(get_boolean(crp, "use_pass_crypto_asset")) {
- for(int i = 0; i < crypto_depth; ++i) {
- string passname = cryptomatte_prefix + string_printf("Asset%02d", i);
- b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
- Pass::add(PASS_CRYPTOMATTE, passes, passname.c_str());
- }
- scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes | CRYPT_ASSET);
- }
- if(get_boolean(crp, "pass_crypto_accurate") && scene->film->cryptomatte_passes != CRYPT_NONE) {
- scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes | CRYPT_ACCURATE);
- }
-
- return passes;
+ if (get_boolean(crp, "pass_debug_render_time")) {
+ b_engine.add_pass("Debug Render Time", 1, "X", b_view_layer.name().c_str());
+ Pass::add(PASS_RENDER_TIME, passes);
+ }
+ if (get_boolean(crp, "use_pass_volume_direct")) {
+ b_engine.add_pass("VolumeDir", 3, "RGB", b_view_layer.name().c_str());
+ Pass::add(PASS_VOLUME_DIRECT, passes);
+ }
+ if (get_boolean(crp, "use_pass_volume_indirect")) {
+ b_engine.add_pass("VolumeInd", 3, "RGB", b_view_layer.name().c_str());
+ Pass::add(PASS_VOLUME_INDIRECT, passes);
+ }
+
+ /* Cryptomatte stores two ID/weight pairs per RGBA layer.
+ * User facing paramter is the number of pairs. */
+ int crypto_depth = min(16, get_int(crp, "pass_crypto_depth")) / 2;
+ scene->film->cryptomatte_depth = crypto_depth;
+ scene->film->cryptomatte_passes = CRYPT_NONE;
+ if (get_boolean(crp, "use_pass_crypto_object")) {
+ for (int i = 0; i < crypto_depth; ++i) {
+ string passname = cryptomatte_prefix + string_printf("Object%02d", i);
+ b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
+ Pass::add(PASS_CRYPTOMATTE, passes, passname.c_str());
+ }
+ scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes |
+ CRYPT_OBJECT);
+ }
+ if (get_boolean(crp, "use_pass_crypto_material")) {
+ for (int i = 0; i < crypto_depth; ++i) {
+ string passname = cryptomatte_prefix + string_printf("Material%02d", i);
+ b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
+ Pass::add(PASS_CRYPTOMATTE, passes, passname.c_str());
+ }
+ scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes |
+ CRYPT_MATERIAL);
+ }
+ if (get_boolean(crp, "use_pass_crypto_asset")) {
+ for (int i = 0; i < crypto_depth; ++i) {
+ string passname = cryptomatte_prefix + string_printf("Asset%02d", i);
+ b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
+ Pass::add(PASS_CRYPTOMATTE, passes, passname.c_str());
+ }
+ scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes |
+ CRYPT_ASSET);
+ }
+ if (get_boolean(crp, "pass_crypto_accurate") && scene->film->cryptomatte_passes != CRYPT_NONE) {
+ scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes |
+ CRYPT_ACCURATE);
+ }
+
+ return passes;
}
-void BlenderSync::free_data_after_sync(BL::Depsgraph& b_depsgraph)
+void BlenderSync::free_data_after_sync(BL::Depsgraph &b_depsgraph)
{
- /* When viewport display is not needed during render we can force some
- * caches to be releases from blender side in order to reduce peak memory
- * footprint during synchronization process.
- */
- const bool is_interface_locked = b_engine.render() &&
- b_engine.render().use_lock_interface();
- const bool can_free_caches = BlenderSession::headless || is_interface_locked;
- if(!can_free_caches) {
- return;
- }
- /* TODO(sergey): We can actually remove the whole dependency graph,
- * but that will need some API support first.
- */
- BL::Depsgraph::objects_iterator b_ob;
- for(b_depsgraph.objects.begin(b_ob);
- b_ob != b_depsgraph.objects.end();
- ++b_ob)
- {
- b_ob->cache_release();
- }
+ /* When viewport display is not needed during render we can force some
+ * caches to be releases from blender side in order to reduce peak memory
+ * footprint during synchronization process.
+ */
+ const bool is_interface_locked = b_engine.render() && b_engine.render().use_lock_interface();
+ const bool can_free_caches = BlenderSession::headless || is_interface_locked;
+ if (!can_free_caches) {
+ return;
+ }
+ /* TODO(sergey): We can actually remove the whole dependency graph,
+ * but that will need some API support first.
+ */
+ BL::Depsgraph::objects_iterator b_ob;
+ for (b_depsgraph.objects.begin(b_ob); b_ob != b_depsgraph.objects.end(); ++b_ob) {
+ b_ob->cache_release();
+ }
}
/* Scene Parameters */
-SceneParams BlenderSync::get_scene_params(BL::Scene& b_scene,
- bool background)
+SceneParams BlenderSync::get_scene_params(BL::Scene &b_scene, bool background)
{
- BL::RenderSettings r = b_scene.render();
- SceneParams params;
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
- const bool shadingsystem = RNA_boolean_get(&cscene, "shading_system");
-
- if(shadingsystem == 0)
- params.shadingsystem = SHADINGSYSTEM_SVM;
- else if(shadingsystem == 1)
- params.shadingsystem = SHADINGSYSTEM_OSL;
-
- if(background || DebugFlags().viewport_static_bvh)
- params.bvh_type = SceneParams::BVH_STATIC;
- else
- params.bvh_type = SceneParams::BVH_DYNAMIC;
-
- params.use_bvh_spatial_split = RNA_boolean_get(&cscene, "debug_use_spatial_splits");
- params.use_bvh_unaligned_nodes = RNA_boolean_get(&cscene, "debug_use_hair_bvh");
- params.num_bvh_time_steps = RNA_int_get(&cscene, "debug_bvh_time_steps");
-
- if(background && params.shadingsystem != SHADINGSYSTEM_OSL)
- params.persistent_data = r.use_persistent_data();
- else
- params.persistent_data = false;
-
- int texture_limit;
- if(background) {
- texture_limit = RNA_enum_get(&cscene, "texture_limit_render");
- }
- else {
- texture_limit = RNA_enum_get(&cscene, "texture_limit");
- }
- if(texture_limit > 0 && b_scene.render().use_simplify()) {
- params.texture_limit = 1 << (texture_limit + 6);
- }
- else {
- params.texture_limit = 0;
- }
-
- /* TODO(sergey): Once OSL supports per-microarchitecture optimization get
- * rid of this.
- */
- if(params.shadingsystem == SHADINGSYSTEM_OSL) {
- params.bvh_layout = BVH_LAYOUT_BVH4;
- }
- else {
- params.bvh_layout = DebugFlags().cpu.bvh_layout;
- }
+ BL::RenderSettings r = b_scene.render();
+ SceneParams params;
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+ const bool shadingsystem = RNA_boolean_get(&cscene, "shading_system");
+
+ if (shadingsystem == 0)
+ params.shadingsystem = SHADINGSYSTEM_SVM;
+ else if (shadingsystem == 1)
+ params.shadingsystem = SHADINGSYSTEM_OSL;
+
+ if (background || DebugFlags().viewport_static_bvh)
+ params.bvh_type = SceneParams::BVH_STATIC;
+ else
+ params.bvh_type = SceneParams::BVH_DYNAMIC;
+
+ params.use_bvh_spatial_split = RNA_boolean_get(&cscene, "debug_use_spatial_splits");
+ params.use_bvh_unaligned_nodes = RNA_boolean_get(&cscene, "debug_use_hair_bvh");
+ params.num_bvh_time_steps = RNA_int_get(&cscene, "debug_bvh_time_steps");
+
+ if (background && params.shadingsystem != SHADINGSYSTEM_OSL)
+ params.persistent_data = r.use_persistent_data();
+ else
+ params.persistent_data = false;
+
+ int texture_limit;
+ if (background) {
+ texture_limit = RNA_enum_get(&cscene, "texture_limit_render");
+ }
+ else {
+ texture_limit = RNA_enum_get(&cscene, "texture_limit");
+ }
+ if (texture_limit > 0 && b_scene.render().use_simplify()) {
+ params.texture_limit = 1 << (texture_limit + 6);
+ }
+ else {
+ params.texture_limit = 0;
+ }
+
+ /* TODO(sergey): Once OSL supports per-microarchitecture optimization get
+ * rid of this.
+ */
+ if (params.shadingsystem == SHADINGSYSTEM_OSL) {
+ params.bvh_layout = BVH_LAYOUT_BVH4;
+ }
+ else {
+ params.bvh_layout = DebugFlags().cpu.bvh_layout;
+ }
#ifdef WITH_EMBREE
- params.bvh_layout = RNA_boolean_get(&cscene, "use_bvh_embree") ? BVH_LAYOUT_EMBREE : params.bvh_layout;
+ params.bvh_layout = RNA_boolean_get(&cscene, "use_bvh_embree") ? BVH_LAYOUT_EMBREE :
+ params.bvh_layout;
#endif
- return params;
+ return params;
}
/* Session Parameters */
-bool BlenderSync::get_session_pause(BL::Scene& b_scene, bool background)
+bool BlenderSync::get_session_pause(BL::Scene &b_scene, bool background)
{
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
- return (background)? false: get_boolean(cscene, "preview_pause");
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+ return (background) ? false : get_boolean(cscene, "preview_pause");
}
-SessionParams BlenderSync::get_session_params(BL::RenderEngine& b_engine,
- BL::Preferences& b_preferences,
- BL::Scene& b_scene,
+SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine,
+ BL::Preferences &b_preferences,
+ BL::Scene &b_scene,
bool background)
{
- SessionParams params;
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
-
- /* feature set */
- params.experimental = (get_enum(cscene, "feature_set") != 0);
-
- /* Background */
- params.background = background;
-
- /* Device */
- params.threads = blender_device_threads(b_scene);
- params.device = blender_device_info(b_preferences, b_scene, params.background);
-
- /* samples */
- int samples = get_int(cscene, "samples");
- int aa_samples = get_int(cscene, "aa_samples");
- int preview_samples = get_int(cscene, "preview_samples");
- int preview_aa_samples = get_int(cscene, "preview_aa_samples");
-
- if(get_boolean(cscene, "use_square_samples")) {
- aa_samples = aa_samples * aa_samples;
- preview_aa_samples = preview_aa_samples * preview_aa_samples;
-
- samples = samples * samples;
- preview_samples = preview_samples * preview_samples;
- }
-
- if(get_enum(cscene, "progressive") == 0) {
- if(background) {
- params.samples = aa_samples;
- }
- else {
- params.samples = preview_aa_samples;
- if(params.samples == 0)
- params.samples = INT_MAX;
- }
- }
- else {
- if(background) {
- params.samples = samples;
- }
- else {
- params.samples = preview_samples;
- if(params.samples == 0)
- params.samples = INT_MAX;
- }
- }
-
- /* Clamp samples. */
- params.samples = min(params.samples, Integrator::MAX_SAMPLES);
-
- /* tiles */
- const bool is_cpu = (params.device.type == DEVICE_CPU);
- if(!is_cpu && !background) {
- /* currently GPU could be much slower than CPU when using tiles,
- * still need to be investigated, but meanwhile make it possible
- * to work in viewport smoothly
- */
- int debug_tile_size = get_int(cscene, "debug_tile_size");
-
- params.tile_size = make_int2(debug_tile_size, debug_tile_size);
- }
- else {
- int tile_x = b_engine.tile_x();
- int tile_y = b_engine.tile_y();
-
- params.tile_size = make_int2(tile_x, tile_y);
- }
-
- if((BlenderSession::headless == false) && background) {
- params.tile_order = (TileOrder)get_enum(cscene, "tile_order");
- }
- else {
- params.tile_order = TILE_BOTTOM_TO_TOP;
- }
-
- /* other parameters */
- params.start_resolution = get_int(cscene, "preview_start_resolution");
- params.pixel_size = b_engine.get_preview_pixel_size(b_scene);
-
- /* other parameters */
- params.cancel_timeout = (double)get_float(cscene, "debug_cancel_timeout");
- params.reset_timeout = (double)get_float(cscene, "debug_reset_timeout");
- params.text_timeout = (double)get_float(cscene, "debug_text_timeout");
-
- /* progressive refine */
- BL::RenderSettings b_r = b_scene.render();
- params.progressive_refine = (b_engine.is_preview() ||
- get_boolean(cscene, "use_progressive_refine")) &&
- !b_r.use_save_buffers();
-
- if(params.progressive_refine) {
- BL::Scene::view_layers_iterator b_view_layer;
- for(b_scene.view_layers.begin(b_view_layer); b_view_layer != b_scene.view_layers.end(); ++b_view_layer) {
- PointerRNA crl = RNA_pointer_get(&b_view_layer->ptr, "cycles");
- if(get_boolean(crl, "use_denoising")) {
- params.progressive_refine = false;
- }
- }
- }
-
- if(background) {
- if(params.progressive_refine)
- params.progressive = true;
- else
- params.progressive = false;
-
- params.start_resolution = INT_MAX;
- params.pixel_size = 1;
- }
- else
- params.progressive = true;
-
- /* shading system - scene level needs full refresh */
- const bool shadingsystem = RNA_boolean_get(&cscene, "shading_system");
-
- if(shadingsystem == 0)
- params.shadingsystem = SHADINGSYSTEM_SVM;
- else if(shadingsystem == 1)
- params.shadingsystem = SHADINGSYSTEM_OSL;
-
- /* color managagement */
- params.display_buffer_linear = b_engine.support_display_space_shader(b_scene);
-
- if(b_engine.is_preview()) {
- /* For preview rendering we're using same timeout as
- * blender's job update.
- */
- params.progressive_update_timeout = 0.1;
- }
-
- params.use_profiling = params.device.has_profiling && !b_engine.is_preview() &&
- background && BlenderSession::print_render_stats;
-
- return params;
+ SessionParams params;
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+
+ /* feature set */
+ params.experimental = (get_enum(cscene, "feature_set") != 0);
+
+ /* Background */
+ params.background = background;
+
+ /* Device */
+ params.threads = blender_device_threads(b_scene);
+ params.device = blender_device_info(b_preferences, b_scene, params.background);
+
+ /* samples */
+ int samples = get_int(cscene, "samples");
+ int aa_samples = get_int(cscene, "aa_samples");
+ int preview_samples = get_int(cscene, "preview_samples");
+ int preview_aa_samples = get_int(cscene, "preview_aa_samples");
+
+ if (get_boolean(cscene, "use_square_samples")) {
+ aa_samples = aa_samples * aa_samples;
+ preview_aa_samples = preview_aa_samples * preview_aa_samples;
+
+ samples = samples * samples;
+ preview_samples = preview_samples * preview_samples;
+ }
+
+ if (get_enum(cscene, "progressive") == 0) {
+ if (background) {
+ params.samples = aa_samples;
+ }
+ else {
+ params.samples = preview_aa_samples;
+ if (params.samples == 0)
+ params.samples = INT_MAX;
+ }
+ }
+ else {
+ if (background) {
+ params.samples = samples;
+ }
+ else {
+ params.samples = preview_samples;
+ if (params.samples == 0)
+ params.samples = INT_MAX;
+ }
+ }
+
+ /* Clamp samples. */
+ params.samples = min(params.samples, Integrator::MAX_SAMPLES);
+
+ /* tiles */
+ const bool is_cpu = (params.device.type == DEVICE_CPU);
+ if (!is_cpu && !background) {
+ /* currently GPU could be much slower than CPU when using tiles,
+ * still need to be investigated, but meanwhile make it possible
+ * to work in viewport smoothly
+ */
+ int debug_tile_size = get_int(cscene, "debug_tile_size");
+
+ params.tile_size = make_int2(debug_tile_size, debug_tile_size);
+ }
+ else {
+ int tile_x = b_engine.tile_x();
+ int tile_y = b_engine.tile_y();
+
+ params.tile_size = make_int2(tile_x, tile_y);
+ }
+
+ if ((BlenderSession::headless == false) && background) {
+ params.tile_order = (TileOrder)get_enum(cscene, "tile_order");
+ }
+ else {
+ params.tile_order = TILE_BOTTOM_TO_TOP;
+ }
+
+ /* other parameters */
+ params.start_resolution = get_int(cscene, "preview_start_resolution");
+ params.pixel_size = b_engine.get_preview_pixel_size(b_scene);
+
+ /* other parameters */
+ params.cancel_timeout = (double)get_float(cscene, "debug_cancel_timeout");
+ params.reset_timeout = (double)get_float(cscene, "debug_reset_timeout");
+ params.text_timeout = (double)get_float(cscene, "debug_text_timeout");
+
+ /* progressive refine */
+ BL::RenderSettings b_r = b_scene.render();
+ params.progressive_refine = (b_engine.is_preview() ||
+ get_boolean(cscene, "use_progressive_refine")) &&
+ !b_r.use_save_buffers();
+
+ if (params.progressive_refine) {
+ BL::Scene::view_layers_iterator b_view_layer;
+ for (b_scene.view_layers.begin(b_view_layer); b_view_layer != b_scene.view_layers.end();
+ ++b_view_layer) {
+ PointerRNA crl = RNA_pointer_get(&b_view_layer->ptr, "cycles");
+ if (get_boolean(crl, "use_denoising")) {
+ params.progressive_refine = false;
+ }
+ }
+ }
+
+ if (background) {
+ if (params.progressive_refine)
+ params.progressive = true;
+ else
+ params.progressive = false;
+
+ params.start_resolution = INT_MAX;
+ params.pixel_size = 1;
+ }
+ else
+ params.progressive = true;
+
+ /* shading system - scene level needs full refresh */
+ const bool shadingsystem = RNA_boolean_get(&cscene, "shading_system");
+
+ if (shadingsystem == 0)
+ params.shadingsystem = SHADINGSYSTEM_SVM;
+ else if (shadingsystem == 1)
+ params.shadingsystem = SHADINGSYSTEM_OSL;
+
+ /* color managagement */
+ params.display_buffer_linear = b_engine.support_display_space_shader(b_scene);
+
+ if (b_engine.is_preview()) {
+ /* For preview rendering we're using same timeout as
+ * blender's job update.
+ */
+ params.progressive_update_timeout = 0.1;
+ }
+
+ params.use_profiling = params.device.has_profiling && !b_engine.is_preview() && background &&
+ BlenderSession::print_render_stats;
+
+ return params;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index 8af3fde3323..00afceebde3 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -49,171 +49,173 @@ class ShaderGraph;
class ShaderNode;
class BlenderSync {
-public:
- BlenderSync(BL::RenderEngine& b_engine,
- BL::BlendData& b_data,
- BL::Scene& b_scene,
- Scene *scene,
- bool preview,
- Progress &progress);
- ~BlenderSync();
-
- /* sync */
- void sync_recalc(BL::Depsgraph& b_depsgraph);
- void sync_data(BL::RenderSettings& b_render,
- BL::Depsgraph& b_depsgraph,
- BL::SpaceView3D& b_v3d,
- BL::Object& b_override,
- int width, int height,
- void **python_thread_state);
- void sync_view_layer(BL::SpaceView3D& b_v3d, BL::ViewLayer& b_view_layer);
- vector<Pass> sync_render_passes(BL::RenderLayer& b_render_layer,
- BL::ViewLayer& b_view_layer);
- void sync_integrator();
- void sync_camera(BL::RenderSettings& b_render,
- BL::Object& b_override,
- int width, int height,
- const char *viewname);
- void sync_view(BL::SpaceView3D& b_v3d,
- BL::RegionView3D& b_rv3d,
- int width, int height);
- inline int get_layer_samples() { return view_layer.samples; }
- inline int get_layer_bound_samples() { return view_layer.bound_samples; }
-
- /* get parameters */
- static SceneParams get_scene_params(BL::Scene& b_scene,
- bool background);
- static SessionParams get_session_params(BL::RenderEngine& b_engine,
- BL::Preferences& b_userpref,
- BL::Scene& b_scene,
- bool background);
- static bool get_session_pause(BL::Scene& b_scene, bool background);
- static BufferParams get_buffer_params(BL::RenderSettings& b_render,
- BL::SpaceView3D& b_v3d,
- BL::RegionView3D& b_rv3d,
- Camera *cam,
- int width, int height);
-
- static PassType get_pass_type(BL::RenderPass& b_pass);
- static int get_denoising_pass(BL::RenderPass& b_pass);
-
-private:
- /* sync */
- void sync_lights(BL::Depsgraph& b_depsgraph, bool update_all);
- void sync_materials(BL::Depsgraph& b_depsgraph, bool update_all);
- void sync_objects(BL::Depsgraph& b_depsgraph, float motion_time = 0.0f);
- void sync_motion(BL::RenderSettings& b_render,
- BL::Depsgraph& b_depsgraph,
- BL::Object& b_override,
- int width, int height,
- void **python_thread_state);
- void sync_film();
- void sync_view();
- void sync_world(BL::Depsgraph& b_depsgraph, bool update_all);
- void sync_shaders(BL::Depsgraph& b_depsgraph);
- void sync_curve_settings();
-
- void sync_nodes(Shader *shader, BL::ShaderNodeTree& b_ntree);
- Mesh *sync_mesh(BL::Depsgraph& b_depsgrpah,
- BL::Object& b_ob,
- BL::Object& b_ob_instance,
- bool object_updated,
- bool show_self,
- bool show_particles);
- void sync_curves(Mesh *mesh,
- BL::Mesh& b_mesh,
- BL::Object& b_ob,
- bool motion,
- int motion_step = 0);
- Object *sync_object(BL::Depsgraph& b_depsgraph,
- BL::ViewLayer& b_view_layer,
- BL::DepsgraphObjectInstance& b_instance,
- float motion_time,
- bool show_self,
- bool show_particles,
- BlenderObjectCulling& culling,
- bool *use_portal);
- void sync_light(BL::Object& b_parent,
- int persistent_id[OBJECT_PERSISTENT_ID_SIZE],
- BL::Object& b_ob,
- BL::Object& b_ob_instance,
- int random_id,
- Transform& tfm,
- bool *use_portal);
- void sync_background_light(bool use_portal);
- void sync_mesh_motion(BL::Depsgraph& b_depsgraph,
- BL::Object& b_ob,
- Object *object,
- float motion_time);
- void sync_camera_motion(BL::RenderSettings& b_render,
- BL::Object& b_ob,
- int width, int height,
- float motion_time);
-
- /* particles */
- bool sync_dupli_particle(BL::Object& b_ob,
- BL::DepsgraphObjectInstance& b_instance,
- Object *object);
-
- /* Images. */
- void sync_images();
-
- /* Early data free. */
- void free_data_after_sync(BL::Depsgraph& b_depsgraph);
-
- /* util */
- void find_shader(BL::ID& id, vector<Shader*>& used_shaders, Shader *default_shader);
- bool BKE_object_is_modified(BL::Object& b_ob);
- bool object_is_mesh(BL::Object& b_ob);
- bool object_is_light(BL::Object& b_ob);
-
- /* variables */
- BL::RenderEngine b_engine;
- BL::BlendData b_data;
- BL::Scene b_scene;
-
- id_map<void*, Shader> shader_map;
- id_map<ObjectKey, Object> object_map;
- id_map<void*, Mesh> mesh_map;
- id_map<ObjectKey, Light> light_map;
- id_map<ParticleSystemKey, ParticleSystem> particle_system_map;
- set<Mesh*> mesh_synced;
- set<Mesh*> mesh_motion_synced;
- set<float> motion_times;
- void *world_map;
- bool world_recalc;
-
- Scene *scene;
- bool preview;
- bool experimental;
-
- float dicing_rate;
- int max_subdivisions;
-
- struct RenderLayerInfo {
- RenderLayerInfo()
- : material_override(PointerRNA_NULL),
- use_background_shader(true),
- use_background_ao(true),
- use_surfaces(true),
- use_hair(true),
- samples(0),
- bound_samples(false)
- {}
-
- string name;
- BL::Material material_override;
- bool use_background_shader;
- bool use_background_ao;
- bool use_surfaces;
- bool use_hair;
- int samples;
- bool bound_samples;
- } view_layer;
-
- Progress &progress;
+ public:
+ BlenderSync(BL::RenderEngine &b_engine,
+ BL::BlendData &b_data,
+ BL::Scene &b_scene,
+ Scene *scene,
+ bool preview,
+ Progress &progress);
+ ~BlenderSync();
+
+ /* sync */
+ void sync_recalc(BL::Depsgraph &b_depsgraph);
+ void sync_data(BL::RenderSettings &b_render,
+ BL::Depsgraph &b_depsgraph,
+ BL::SpaceView3D &b_v3d,
+ BL::Object &b_override,
+ int width,
+ int height,
+ void **python_thread_state);
+ void sync_view_layer(BL::SpaceView3D &b_v3d, BL::ViewLayer &b_view_layer);
+ vector<Pass> sync_render_passes(BL::RenderLayer &b_render_layer, BL::ViewLayer &b_view_layer);
+ void sync_integrator();
+ void sync_camera(BL::RenderSettings &b_render,
+ BL::Object &b_override,
+ int width,
+ int height,
+ const char *viewname);
+ void sync_view(BL::SpaceView3D &b_v3d, BL::RegionView3D &b_rv3d, int width, int height);
+ inline int get_layer_samples()
+ {
+ return view_layer.samples;
+ }
+ inline int get_layer_bound_samples()
+ {
+ return view_layer.bound_samples;
+ }
+
+ /* get parameters */
+ static SceneParams get_scene_params(BL::Scene &b_scene, bool background);
+ static SessionParams get_session_params(BL::RenderEngine &b_engine,
+ BL::Preferences &b_userpref,
+ BL::Scene &b_scene,
+ bool background);
+ static bool get_session_pause(BL::Scene &b_scene, bool background);
+ static BufferParams get_buffer_params(BL::RenderSettings &b_render,
+ BL::SpaceView3D &b_v3d,
+ BL::RegionView3D &b_rv3d,
+ Camera *cam,
+ int width,
+ int height);
+
+ static PassType get_pass_type(BL::RenderPass &b_pass);
+ static int get_denoising_pass(BL::RenderPass &b_pass);
+
+ private:
+ /* sync */
+ void sync_lights(BL::Depsgraph &b_depsgraph, bool update_all);
+ void sync_materials(BL::Depsgraph &b_depsgraph, bool update_all);
+ void sync_objects(BL::Depsgraph &b_depsgraph, float motion_time = 0.0f);
+ void sync_motion(BL::RenderSettings &b_render,
+ BL::Depsgraph &b_depsgraph,
+ BL::Object &b_override,
+ int width,
+ int height,
+ void **python_thread_state);
+ void sync_film();
+ void sync_view();
+ void sync_world(BL::Depsgraph &b_depsgraph, bool update_all);
+ void sync_shaders(BL::Depsgraph &b_depsgraph);
+ void sync_curve_settings();
+
+ void sync_nodes(Shader *shader, BL::ShaderNodeTree &b_ntree);
+ Mesh *sync_mesh(BL::Depsgraph &b_depsgrpah,
+ BL::Object &b_ob,
+ BL::Object &b_ob_instance,
+ bool object_updated,
+ bool show_self,
+ bool show_particles);
+ void sync_curves(
+ Mesh *mesh, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step = 0);
+ Object *sync_object(BL::Depsgraph &b_depsgraph,
+ BL::ViewLayer &b_view_layer,
+ BL::DepsgraphObjectInstance &b_instance,
+ float motion_time,
+ bool show_self,
+ bool show_particles,
+ BlenderObjectCulling &culling,
+ bool *use_portal);
+ void sync_light(BL::Object &b_parent,
+ int persistent_id[OBJECT_PERSISTENT_ID_SIZE],
+ BL::Object &b_ob,
+ BL::Object &b_ob_instance,
+ int random_id,
+ Transform &tfm,
+ bool *use_portal);
+ void sync_background_light(bool use_portal);
+ void sync_mesh_motion(BL::Depsgraph &b_depsgraph,
+ BL::Object &b_ob,
+ Object *object,
+ float motion_time);
+ void sync_camera_motion(
+ BL::RenderSettings &b_render, BL::Object &b_ob, int width, int height, float motion_time);
+
+ /* particles */
+ bool sync_dupli_particle(BL::Object &b_ob,
+ BL::DepsgraphObjectInstance &b_instance,
+ Object *object);
+
+ /* Images. */
+ void sync_images();
+
+ /* Early data free. */
+ void free_data_after_sync(BL::Depsgraph &b_depsgraph);
+
+ /* util */
+ void find_shader(BL::ID &id, vector<Shader *> &used_shaders, Shader *default_shader);
+ bool BKE_object_is_modified(BL::Object &b_ob);
+ bool object_is_mesh(BL::Object &b_ob);
+ bool object_is_light(BL::Object &b_ob);
+
+ /* variables */
+ BL::RenderEngine b_engine;
+ BL::BlendData b_data;
+ BL::Scene b_scene;
+
+ id_map<void *, Shader> shader_map;
+ id_map<ObjectKey, Object> object_map;
+ id_map<void *, Mesh> mesh_map;
+ id_map<ObjectKey, Light> light_map;
+ id_map<ParticleSystemKey, ParticleSystem> particle_system_map;
+ set<Mesh *> mesh_synced;
+ set<Mesh *> mesh_motion_synced;
+ set<float> motion_times;
+ void *world_map;
+ bool world_recalc;
+
+ Scene *scene;
+ bool preview;
+ bool experimental;
+
+ float dicing_rate;
+ int max_subdivisions;
+
+ struct RenderLayerInfo {
+ RenderLayerInfo()
+ : material_override(PointerRNA_NULL),
+ use_background_shader(true),
+ use_background_ao(true),
+ use_surfaces(true),
+ use_hair(true),
+ samples(0),
+ bound_samples(false)
+ {
+ }
+
+ string name;
+ BL::Material material_override;
+ bool use_background_shader;
+ bool use_background_ao;
+ bool use_surfaces;
+ bool use_hair;
+ int samples;
+ bool bound_samples;
+ } view_layer;
+
+ Progress &progress;
};
CCL_NAMESPACE_END
-#endif /* __BLENDER_SYNC_H__ */
+#endif /* __BLENDER_SYNC_H__ */
diff --git a/intern/cycles/blender/blender_texture.cpp b/intern/cycles/blender/blender_texture.cpp
index a0371a7eed8..7b05f361a29 100644
--- a/intern/cycles/blender/blender_texture.cpp
+++ b/intern/cycles/blender/blender_texture.cpp
@@ -22,36 +22,36 @@ namespace {
/* Point density helpers. */
-void density_texture_space_invert(float3& loc,
- float3& size)
+void density_texture_space_invert(float3 &loc, float3 &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);
+ 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);
}
-} /* namespace */
+} /* namespace */
-void point_density_texture_space(BL::Depsgraph& b_depsgraph,
- BL::ShaderNodeTexPointDensity& b_point_density_node,
- float3& loc,
- float3& size)
+void point_density_texture_space(BL::Depsgraph &b_depsgraph,
+ BL::ShaderNodeTexPointDensity &b_point_density_node,
+ float3 &loc,
+ float3 &size)
{
- BL::Object b_ob(b_point_density_node.object());
- if(!b_ob) {
- loc = make_float3(0.0f, 0.0f, 0.0f);
- size = make_float3(0.0f, 0.0f, 0.0f);
- return;
- }
- float3 min, max;
- b_point_density_node.calc_point_density_minmax(b_depsgraph,
- &min[0],
- &max[0]);
- loc = (min + max) * 0.5f;
- size = (max - min) * 0.5f;
- density_texture_space_invert(loc, size);
+ BL::Object b_ob(b_point_density_node.object());
+ if (!b_ob) {
+ loc = make_float3(0.0f, 0.0f, 0.0f);
+ size = make_float3(0.0f, 0.0f, 0.0f);
+ return;
+ }
+ float3 min, max;
+ b_point_density_node.calc_point_density_minmax(b_depsgraph, &min[0], &max[0]);
+ loc = (min + max) * 0.5f;
+ size = (max - min) * 0.5f;
+ density_texture_space_invert(loc, size);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_texture.h b/intern/cycles/blender/blender_texture.h
index b4e166c5cdd..896bf62da70 100644
--- a/intern/cycles/blender/blender_texture.h
+++ b/intern/cycles/blender/blender_texture.h
@@ -22,11 +22,11 @@
CCL_NAMESPACE_BEGIN
-void point_density_texture_space(BL::Depsgraph& b_depsgraph,
- BL::ShaderNodeTexPointDensity& b_point_density_node,
- float3& loc,
- float3& size);
+void point_density_texture_space(BL::Depsgraph &b_depsgraph,
+ BL::ShaderNodeTexPointDensity &b_point_density_node,
+ float3 &loc,
+ float3 &size);
CCL_NAMESPACE_END
-#endif /* __BLENDER_TEXTURE_H__ */
+#endif /* __BLENDER_TEXTURE_H__ */
diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h
index f302b09459f..e68f92474bf 100644
--- a/intern/cycles/blender/blender_util.h
+++ b/intern/cycles/blender/blender_util.h
@@ -43,338 +43,320 @@ CCL_NAMESPACE_BEGIN
void python_thread_state_save(void **python_thread_state);
void python_thread_state_restore(void **python_thread_state);
-static inline BL::Mesh object_to_mesh(BL::BlendData& data,
- BL::Object& object,
- BL::Depsgraph& depsgraph,
+static inline BL::Mesh object_to_mesh(BL::BlendData &data,
+ BL::Object &object,
+ BL::Depsgraph &depsgraph,
bool calc_undeformed,
Mesh::SubdivisionType subdivision_type)
{
- /* TODO: make this work with copy-on-write, modifiers are already evaluated. */
+ /* TODO: make this work with copy-on-write, modifiers are already evaluated. */
#if 0
- bool subsurf_mod_show_render = false;
- bool subsurf_mod_show_viewport = false;
+ bool subsurf_mod_show_render = false;
+ bool subsurf_mod_show_viewport = false;
- if(subdivision_type != Mesh::SUBDIVISION_NONE) {
- BL::Modifier subsurf_mod = object.modifiers[object.modifiers.length()-1];
+ if(subdivision_type != Mesh::SUBDIVISION_NONE) {
+ 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();
+ subsurf_mod_show_render = subsurf_mod.show_render();
+ subsurf_mod_show_viewport = subsurf_mod.show_viewport();
- subsurf_mod.show_render(false);
- subsurf_mod.show_viewport(false);
- }
+ subsurf_mod.show_render(false);
+ subsurf_mod.show_viewport(false);
+ }
#endif
- BL::Mesh mesh(PointerRNA_NULL);
- if(object.type() == BL::Object::type_MESH) {
- /* TODO: calc_undeformed is not used. */
- mesh = BL::Mesh(object.data());
-
- /* Make a copy to split faces if we use autosmooth, otherwise not needed.
- * Also in edit mode do we need to make a copy, to ensure data layers like
- * UV are not empty. */
- if (mesh.is_editmode() ||
- (mesh.use_auto_smooth() && subdivision_type == Mesh::SUBDIVISION_NONE))
- {
- mesh = data.meshes.new_from_object(depsgraph, object, false, false);
- }
- }
- else {
- mesh = data.meshes.new_from_object(depsgraph, object, true, calc_undeformed);
- }
+ BL::Mesh mesh(PointerRNA_NULL);
+ if (object.type() == BL::Object::type_MESH) {
+ /* TODO: calc_undeformed is not used. */
+ mesh = BL::Mesh(object.data());
+
+ /* Make a copy to split faces if we use autosmooth, otherwise not needed.
+ * Also in edit mode do we need to make a copy, to ensure data layers like
+ * UV are not empty. */
+ if (mesh.is_editmode() ||
+ (mesh.use_auto_smooth() && subdivision_type == Mesh::SUBDIVISION_NONE)) {
+ mesh = data.meshes.new_from_object(depsgraph, object, false, false);
+ }
+ }
+ else {
+ mesh = data.meshes.new_from_object(depsgraph, object, true, calc_undeformed);
+ }
#if 0
- if(subdivision_type != Mesh::SUBDIVISION_NONE) {
- BL::Modifier subsurf_mod = object.modifiers[object.modifiers.length()-1];
+ if(subdivision_type != Mesh::SUBDIVISION_NONE) {
+ 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);
- }
+ subsurf_mod.show_render(subsurf_mod_show_render);
+ subsurf_mod.show_viewport(subsurf_mod_show_viewport);
+ }
#endif
- if((bool)mesh && subdivision_type == Mesh::SUBDIVISION_NONE) {
- if(mesh.use_auto_smooth()) {
- mesh.split_faces(false);
- }
+ if ((bool)mesh && subdivision_type == Mesh::SUBDIVISION_NONE) {
+ if (mesh.use_auto_smooth()) {
+ mesh.split_faces(false);
+ }
- mesh.calc_loop_triangles();
- }
+ mesh.calc_loop_triangles();
+ }
- return mesh;
+ return mesh;
}
-static inline void free_object_to_mesh(BL::BlendData& data,
- BL::Object& object,
- BL::Mesh& mesh)
+static inline void free_object_to_mesh(BL::BlendData &data, BL::Object &object, BL::Mesh &mesh)
{
- /* Free mesh if we didn't just use the existing one. */
- if(object.data().ptr.data != mesh.ptr.data) {
- data.meshes.remove(mesh, false, true, false);
- }
+ /* Free mesh if we didn't just use the existing one. */
+ if (object.data().ptr.data != mesh.ptr.data) {
+ data.meshes.remove(mesh, false, true, false);
+ }
}
-static inline void colorramp_to_array(BL::ColorRamp& ramp,
- array<float3>& ramp_color,
- array<float>& ramp_alpha,
+static inline void colorramp_to_array(BL::ColorRamp &ramp,
+ array<float3> &ramp_color,
+ array<float> &ramp_alpha,
int size)
{
- ramp_color.resize(size);
- ramp_alpha.resize(size);
+ ramp_color.resize(size);
+ ramp_alpha.resize(size);
- for(int i = 0; i < size; i++) {
- float color[4];
+ for (int i = 0; i < size; i++) {
+ float color[4];
- ramp.evaluate((float)i/(float)(size-1), color);
- ramp_color[i] = make_float3(color[0], color[1], color[2]);
- ramp_alpha[i] = color[3];
- }
+ ramp.evaluate((float)i / (float)(size - 1), color);
+ ramp_color[i] = make_float3(color[0], color[1], color[2]);
+ ramp_alpha[i] = color[3];
+ }
}
-static inline void curvemap_minmax_curve(/*const*/ BL::CurveMap& curve,
- float *min_x,
- float *max_x)
+static inline void curvemap_minmax_curve(/*const*/ BL::CurveMap &curve, float *min_x, float *max_x)
{
- *min_x = min(*min_x, curve.points[0].location()[0]);
- *max_x = max(*max_x, curve.points[curve.points.length() - 1].location()[0]);
+ *min_x = min(*min_x, curve.points[0].location()[0]);
+ *max_x = max(*max_x, curve.points[curve.points.length() - 1].location()[0]);
}
-static inline void curvemapping_minmax(/*const*/ BL::CurveMapping& cumap,
+static inline void curvemapping_minmax(/*const*/ BL::CurveMapping &cumap,
bool rgb_curve,
float *min_x,
float *max_x)
{
- /* const int num_curves = cumap.curves.length(); */ /* Gives linking error so far. */
- const int num_curves = rgb_curve? 4: 3;
- *min_x = FLT_MAX;
- *max_x = -FLT_MAX;
- for(int i = 0; i < num_curves; ++i) {
- BL::CurveMap map(cumap.curves[i]);
- curvemap_minmax_curve(map, min_x, max_x);
- }
+ /* const int num_curves = cumap.curves.length(); */ /* Gives linking error so far. */
+ const int num_curves = rgb_curve ? 4 : 3;
+ *min_x = FLT_MAX;
+ *max_x = -FLT_MAX;
+ for (int i = 0; i < num_curves; ++i) {
+ BL::CurveMap map(cumap.curves[i]);
+ curvemap_minmax_curve(map, min_x, max_x);
+ }
}
-static inline void curvemapping_to_array(BL::CurveMapping& cumap,
- array<float>& data,
- int size)
+static inline void curvemapping_to_array(BL::CurveMapping &cumap, array<float> &data, int size)
{
- cumap.update();
- BL::CurveMap curve = cumap.curves[0];
- data.resize(size);
- for(int i = 0; i < size; i++) {
- float t = (float)i/(float)(size-1);
- data[i] = curve.evaluate(t);
- }
+ cumap.update();
+ BL::CurveMap curve = cumap.curves[0];
+ data.resize(size);
+ for (int i = 0; i < size; i++) {
+ float t = (float)i / (float)(size - 1);
+ data[i] = curve.evaluate(t);
+ }
}
-static inline void curvemapping_color_to_array(BL::CurveMapping& cumap,
- array<float3>& data,
+static inline void curvemapping_color_to_array(BL::CurveMapping &cumap,
+ array<float3> &data,
int size,
bool rgb_curve)
{
- float min_x = 0.0f, max_x = 1.0f;
+ float min_x = 0.0f, max_x = 1.0f;
- /* TODO(sergey): There is no easy way to automatically guess what is
- * the range to be used here for the case when mapping is applied on
- * top of another mapping (i.e. R curve applied on top of common
- * one).
- *
- * Using largest possible range form all curves works correct for the
- * cases like vector curves and should be good enough heuristic for
- * the color curves as well.
- *
- * There might be some better estimations here tho.
- */
- curvemapping_minmax(cumap, rgb_curve, &min_x, &max_x);
+ /* TODO(sergey): There is no easy way to automatically guess what is
+ * the range to be used here for the case when mapping is applied on
+ * top of another mapping (i.e. R curve applied on top of common
+ * one).
+ *
+ * Using largest possible range form all curves works correct for the
+ * cases like vector curves and should be good enough heuristic for
+ * the color curves as well.
+ *
+ * There might be some better estimations here tho.
+ */
+ curvemapping_minmax(cumap, rgb_curve, &min_x, &max_x);
- const float range_x = max_x - min_x;
+ const float range_x = max_x - min_x;
- cumap.update();
+ cumap.update();
- BL::CurveMap mapR = cumap.curves[0];
- BL::CurveMap mapG = cumap.curves[1];
- BL::CurveMap mapB = cumap.curves[2];
+ BL::CurveMap mapR = cumap.curves[0];
+ BL::CurveMap mapG = cumap.curves[1];
+ BL::CurveMap mapB = cumap.curves[2];
- data.resize(size);
+ data.resize(size);
- if(rgb_curve) {
- BL::CurveMap mapI = cumap.curves[3];
- for(int i = 0; i < size; i++) {
- const float t = min_x + (float)i/(float)(size-1) * range_x;
- data[i] = make_float3(mapR.evaluate(mapI.evaluate(t)),
- mapG.evaluate(mapI.evaluate(t)),
- mapB.evaluate(mapI.evaluate(t)));
- }
- }
- else {
- for(int i = 0; i < size; i++) {
- float t = min_x + (float)i/(float)(size-1) * range_x;
- data[i] = make_float3(mapR.evaluate(t),
- mapG.evaluate(t),
- mapB.evaluate(t));
- }
- }
+ if (rgb_curve) {
+ BL::CurveMap mapI = cumap.curves[3];
+ for (int i = 0; i < size; i++) {
+ const float t = min_x + (float)i / (float)(size - 1) * range_x;
+ data[i] = make_float3(mapR.evaluate(mapI.evaluate(t)),
+ mapG.evaluate(mapI.evaluate(t)),
+ mapB.evaluate(mapI.evaluate(t)));
+ }
+ }
+ else {
+ for (int i = 0; i < size; i++) {
+ float t = min_x + (float)i / (float)(size - 1) * range_x;
+ data[i] = make_float3(mapR.evaluate(t), mapG.evaluate(t), mapB.evaluate(t));
+ }
+ }
}
-static inline bool BKE_object_is_modified(BL::Object& self,
- BL::Scene& scene,
- bool preview)
+static inline bool BKE_object_is_modified(BL::Object &self, BL::Scene &scene, bool preview)
{
- return self.is_modified(scene, (preview)? (1<<0): (1<<1))? true: false;
+ return self.is_modified(scene, (preview) ? (1 << 0) : (1 << 1)) ? true : false;
}
-static inline bool BKE_object_is_deform_modified(BL::Object& self,
- BL::Scene& scene,
- bool preview)
+static inline bool BKE_object_is_deform_modified(BL::Object &self, BL::Scene &scene, bool preview)
{
- return self.is_deform_modified(scene, (preview)? (1<<0): (1<<1))? true: false;
+ return self.is_deform_modified(scene, (preview) ? (1 << 0) : (1 << 1)) ? true : false;
}
-static inline int render_resolution_x(BL::RenderSettings& b_render)
+static inline int render_resolution_x(BL::RenderSettings &b_render)
{
- return b_render.resolution_x()*b_render.resolution_percentage()/100;
+ return b_render.resolution_x() * b_render.resolution_percentage() / 100;
}
-static inline int render_resolution_y(BL::RenderSettings& b_render)
+static inline int render_resolution_y(BL::RenderSettings &b_render)
{
- return b_render.resolution_y()*b_render.resolution_percentage()/100;
+ return b_render.resolution_y() * b_render.resolution_percentage() / 100;
}
-static inline string image_user_file_path(BL::ImageUser& iuser,
- BL::Image& ima,
- int cfra)
+static inline string image_user_file_path(BL::ImageUser &iuser, BL::Image &ima, int cfra)
{
- char filepath[1024];
- BKE_image_user_frame_calc(iuser.ptr.data, cfra);
- BKE_image_user_file_path(iuser.ptr.data, ima.ptr.data, filepath);
- return string(filepath);
+ char filepath[1024];
+ BKE_image_user_frame_calc(iuser.ptr.data, cfra);
+ BKE_image_user_file_path(iuser.ptr.data, ima.ptr.data, filepath);
+ return string(filepath);
}
-static inline int image_user_frame_number(BL::ImageUser& iuser, int cfra)
+static inline int image_user_frame_number(BL::ImageUser &iuser, int cfra)
{
- BKE_image_user_frame_calc(iuser.ptr.data, cfra);
- return iuser.frame_current();
+ BKE_image_user_frame_calc(iuser.ptr.data, cfra);
+ return iuser.frame_current();
}
-static inline unsigned char *image_get_pixels_for_frame(BL::Image& image,
- int frame)
+static inline unsigned char *image_get_pixels_for_frame(BL::Image &image, int frame)
{
- return BKE_image_get_pixels_for_frame(image.ptr.data, frame);
+ return BKE_image_get_pixels_for_frame(image.ptr.data, frame);
}
-static inline float *image_get_float_pixels_for_frame(BL::Image& image,
- int frame)
+static inline float *image_get_float_pixels_for_frame(BL::Image &image, int frame)
{
- return BKE_image_get_float_pixels_for_frame(image.ptr.data, frame);
+ return BKE_image_get_float_pixels_for_frame(image.ptr.data, frame);
}
-static inline void render_add_metadata(BL::RenderResult& b_rr, string name, string value)
+static inline void render_add_metadata(BL::RenderResult &b_rr, string name, string value)
{
- b_rr.stamp_data_add_field(name.c_str(), value.c_str());
+ b_rr.stamp_data_add_field(name.c_str(), value.c_str());
}
-
/* Utilities */
-static inline Transform get_transform(const BL::Array<float, 16>& array)
+static inline Transform get_transform(const BL::Array<float, 16> &array)
{
- ProjectionTransform projection;
+ ProjectionTransform projection;
- /* We assume both types to be just 16 floats, and transpose because blender
- * use column major matrix order while we use row major. */
- memcpy((void *)&projection, &array, sizeof(float)*16);
- projection = projection_transpose(projection);
+ /* We assume both types to be just 16 floats, and transpose because blender
+ * use column major matrix order while we use row major. */
+ memcpy((void *)&projection, &array, sizeof(float) * 16);
+ projection = projection_transpose(projection);
- /* Drop last row, matrix is assumed to be affine transform. */
- return projection_to_transform(projection);
+ /* Drop last row, matrix is assumed to be affine transform. */
+ return projection_to_transform(projection);
}
-static inline float2 get_float2(const BL::Array<float, 2>& array)
+static inline float2 get_float2(const BL::Array<float, 2> &array)
{
- return make_float2(array[0], array[1]);
+ return make_float2(array[0], array[1]);
}
-static inline float3 get_float3(const BL::Array<float, 2>& array)
+static inline float3 get_float3(const BL::Array<float, 2> &array)
{
- return make_float3(array[0], array[1], 0.0f);
+ return make_float3(array[0], array[1], 0.0f);
}
-static inline float3 get_float3(const BL::Array<float, 3>& array)
+static inline float3 get_float3(const BL::Array<float, 3> &array)
{
- return make_float3(array[0], array[1], array[2]);
+ return make_float3(array[0], array[1], array[2]);
}
-static inline float3 get_float3(const BL::Array<float, 4>& array)
+static inline float3 get_float3(const BL::Array<float, 4> &array)
{
- return make_float3(array[0], array[1], array[2]);
+ return make_float3(array[0], array[1], array[2]);
}
-static inline float4 get_float4(const BL::Array<float, 4>& array)
+static inline float4 get_float4(const BL::Array<float, 4> &array)
{
- return make_float4(array[0], array[1], array[2], array[3]);
+ return make_float4(array[0], array[1], array[2], array[3]);
}
-static inline int3 get_int3(const BL::Array<int, 3>& array)
+static inline int3 get_int3(const BL::Array<int, 3> &array)
{
- return make_int3(array[0], array[1], array[2]);
+ return make_int3(array[0], array[1], array[2]);
}
-static inline int4 get_int4(const BL::Array<int, 4>& array)
+static inline int4 get_int4(const BL::Array<int, 4> &array)
{
- return make_int4(array[0], array[1], array[2], array[3]);
+ return make_int4(array[0], array[1], array[2], array[3]);
}
-static inline float3 get_float3(PointerRNA& ptr, const char *name)
+static inline float3 get_float3(PointerRNA &ptr, const char *name)
{
- float3 f;
- RNA_float_get_array(&ptr, name, &f.x);
- return f;
+ float3 f;
+ RNA_float_get_array(&ptr, name, &f.x);
+ return f;
}
-static inline void set_float3(PointerRNA& ptr, const char *name, float3 value)
+static inline void set_float3(PointerRNA &ptr, const char *name, float3 value)
{
- RNA_float_set_array(&ptr, name, &value.x);
+ RNA_float_set_array(&ptr, name, &value.x);
}
-static inline float4 get_float4(PointerRNA& ptr, const char *name)
+static inline float4 get_float4(PointerRNA &ptr, const char *name)
{
- float4 f;
- RNA_float_get_array(&ptr, name, &f.x);
- return f;
+ float4 f;
+ RNA_float_get_array(&ptr, name, &f.x);
+ return f;
}
-static inline void set_float4(PointerRNA& ptr, const char *name, float4 value)
+static inline void set_float4(PointerRNA &ptr, const char *name, float4 value)
{
- RNA_float_set_array(&ptr, name, &value.x);
+ RNA_float_set_array(&ptr, name, &value.x);
}
-static inline bool get_boolean(PointerRNA& ptr, const char *name)
+static inline bool get_boolean(PointerRNA &ptr, const char *name)
{
- return RNA_boolean_get(&ptr, name)? true: false;
+ return RNA_boolean_get(&ptr, name) ? true : false;
}
-static inline void set_boolean(PointerRNA& ptr, const char *name, bool value)
+static inline void set_boolean(PointerRNA &ptr, const char *name, bool value)
{
- RNA_boolean_set(&ptr, name, (int)value);
+ RNA_boolean_set(&ptr, name, (int)value);
}
-static inline float get_float(PointerRNA& ptr, const char *name)
+static inline float get_float(PointerRNA &ptr, const char *name)
{
- return RNA_float_get(&ptr, name);
+ return RNA_float_get(&ptr, name);
}
-static inline void set_float(PointerRNA& ptr, const char *name, float value)
+static inline void set_float(PointerRNA &ptr, const char *name, float value)
{
- RNA_float_set(&ptr, name, value);
+ RNA_float_set(&ptr, name, value);
}
-static inline int get_int(PointerRNA& ptr, const char *name)
+static inline int get_int(PointerRNA &ptr, const char *name)
{
- return RNA_int_get(&ptr, name);
+ return RNA_int_get(&ptr, name);
}
-static inline void set_int(PointerRNA& ptr, const char *name, int value)
+static inline void set_int(PointerRNA &ptr, const char *name, int value)
{
- RNA_int_set(&ptr, name, value);
+ RNA_int_set(&ptr, name, value);
}
/* Get a RNA enum value with sanity check: if the RNA value is above num_values
@@ -384,215 +366,214 @@ static inline void set_int(PointerRNA& ptr, const char *name, int value)
* from 0 to num_values-1. Be careful to use it with enums where some values are
* deprecated!
*/
-static inline int get_enum(PointerRNA& ptr,
+static inline int get_enum(PointerRNA &ptr,
const char *name,
int num_values = -1,
int default_value = -1)
{
- int value = RNA_enum_get(&ptr, name);
- if(num_values != -1 && value >= num_values) {
- assert(default_value != -1);
- value = default_value;
- }
- return value;
+ int value = RNA_enum_get(&ptr, name);
+ if (num_values != -1 && value >= num_values) {
+ assert(default_value != -1);
+ value = default_value;
+ }
+ return value;
}
-static inline string get_enum_identifier(PointerRNA& ptr, const char *name)
+static inline string get_enum_identifier(PointerRNA &ptr, const char *name)
{
- PropertyRNA *prop = RNA_struct_find_property(&ptr, name);
- const char *identifier = "";
- int value = RNA_property_enum_get(&ptr, prop);
+ PropertyRNA *prop = RNA_struct_find_property(&ptr, name);
+ const char *identifier = "";
+ int value = RNA_property_enum_get(&ptr, prop);
- RNA_property_enum_identifier(NULL, &ptr, prop, value, &identifier);
+ RNA_property_enum_identifier(NULL, &ptr, prop, value, &identifier);
- return string(identifier);
+ return string(identifier);
}
-static inline void set_enum(PointerRNA& ptr, const char *name, int value)
+static inline void set_enum(PointerRNA &ptr, const char *name, int value)
{
- RNA_enum_set(&ptr, name, value);
+ RNA_enum_set(&ptr, name, value);
}
-static inline void set_enum(PointerRNA& ptr, const char *name, const string &identifier)
+static inline void set_enum(PointerRNA &ptr, const char *name, const string &identifier)
{
- RNA_enum_set_identifier(NULL, &ptr, name, identifier.c_str());
+ RNA_enum_set_identifier(NULL, &ptr, name, identifier.c_str());
}
-static inline string get_string(PointerRNA& ptr, const char *name)
+static inline string get_string(PointerRNA &ptr, const char *name)
{
- char cstrbuf[1024];
- char *cstr = RNA_string_get_alloc(&ptr, name, cstrbuf, sizeof(cstrbuf));
- string str(cstr);
- if(cstr != cstrbuf)
- MEM_freeN(cstr);
+ char cstrbuf[1024];
+ char *cstr = RNA_string_get_alloc(&ptr, name, cstrbuf, sizeof(cstrbuf));
+ string str(cstr);
+ if (cstr != cstrbuf)
+ MEM_freeN(cstr);
- return str;
+ return str;
}
-static inline void set_string(PointerRNA& ptr, const char *name, const string &value)
+static inline void set_string(PointerRNA &ptr, const char *name, const string &value)
{
- RNA_string_set(&ptr, name, value.c_str());
+ RNA_string_set(&ptr, name, value.c_str());
}
/* Relative Paths */
-static inline string blender_absolute_path(BL::BlendData& b_data,
- BL::ID& b_id,
- const string& path)
+static inline string blender_absolute_path(BL::BlendData &b_data, BL::ID &b_id, const string &path)
{
- if(path.size() >= 2 && path[0] == '/' && path[1] == '/') {
- string dirname;
+ if (path.size() >= 2 && path[0] == '/' && path[1] == '/') {
+ string dirname;
- if(b_id.library()) {
- BL::ID b_library_id(b_id.library());
- dirname = blender_absolute_path(b_data,
- b_library_id,
- b_id.library().filepath());
- }
- else
- dirname = b_data.filepath();
+ if (b_id.library()) {
+ BL::ID b_library_id(b_id.library());
+ dirname = blender_absolute_path(b_data, b_library_id, b_id.library().filepath());
+ }
+ else
+ dirname = b_data.filepath();
- return path_join(path_dirname(dirname), path.substr(2));
- }
+ return path_join(path_dirname(dirname), path.substr(2));
+ }
- return path;
+ return path;
}
-static inline string get_text_datablock_content(const PointerRNA& ptr)
+static inline string get_text_datablock_content(const PointerRNA &ptr)
{
- if(ptr.data == NULL) {
- return "";
- }
+ if (ptr.data == NULL) {
+ return "";
+ }
- string content;
- BL::Text::lines_iterator iter;
- for(iter.begin(ptr); iter; ++iter) {
- content += iter->body() + "\n";
- }
+ string content;
+ BL::Text::lines_iterator iter;
+ for (iter.begin(ptr); iter; ++iter) {
+ content += iter->body() + "\n";
+ }
- return content;
+ return content;
}
/* Texture Space */
-static inline void mesh_texture_space(BL::Mesh& b_mesh,
- float3& loc,
- float3& size)
+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());
+ 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;
+ 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);
+ loc = loc * size - make_float3(0.5f, 0.5f, 0.5f);
}
/* Object motion steps, returns 0 if no motion blur needed. */
-static inline uint object_motion_steps(BL::Object& b_parent, BL::Object& b_ob)
+static inline uint object_motion_steps(BL::Object &b_parent, BL::Object &b_ob)
{
- /* Get motion enabled and steps from object itself. */
- PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
- bool use_motion = get_boolean(cobject, "use_motion_blur");
- if(!use_motion) {
- return 0;
- }
+ /* Get motion enabled and steps from object itself. */
+ PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
+ bool use_motion = get_boolean(cobject, "use_motion_blur");
+ if (!use_motion) {
+ return 0;
+ }
- uint steps = max(1, get_int(cobject, "motion_steps"));
+ uint steps = max(1, get_int(cobject, "motion_steps"));
- /* Also check parent object, so motion blur and steps can be
- * controlled by dupligroup duplicator for linked groups. */
- if(b_parent.ptr.data != b_ob.ptr.data) {
- PointerRNA parent_cobject = RNA_pointer_get(&b_parent.ptr, "cycles");
- use_motion &= get_boolean(parent_cobject, "use_motion_blur");
+ /* Also check parent object, so motion blur and steps can be
+ * controlled by dupligroup duplicator for linked groups. */
+ if (b_parent.ptr.data != b_ob.ptr.data) {
+ PointerRNA parent_cobject = RNA_pointer_get(&b_parent.ptr, "cycles");
+ use_motion &= get_boolean(parent_cobject, "use_motion_blur");
- if(!use_motion) {
- return 0;
- }
+ if (!use_motion) {
+ return 0;
+ }
- steps = max(steps, get_int(parent_cobject, "motion_steps"));
- }
+ steps = max(steps, get_int(parent_cobject, "motion_steps"));
+ }
- /* Use uneven number of steps so we get one keyframe at the current frame,
- * and use 2^(steps - 1) so objects with more/fewer steps still have samples
- * at the same times, to avoid sampling at many different times. */
- return (2 << (steps - 1)) + 1;
+ /* Use uneven number of steps so we get one keyframe at the current frame,
+ * and use 2^(steps - 1) so objects with more/fewer steps still have samples
+ * at the same times, to avoid sampling at many different times. */
+ return (2 << (steps - 1)) + 1;
}
/* object uses deformation motion blur */
-static inline bool object_use_deform_motion(BL::Object& b_parent,
- BL::Object& b_ob)
+static inline bool object_use_deform_motion(BL::Object &b_parent, BL::Object &b_ob)
{
- PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
- bool use_deform_motion = get_boolean(cobject, "use_deform_motion");
- /* If motion blur is enabled for the object we also check
- * whether it's enabled for the parent object as well.
- *
- * This way we can control motion blur from the dupligroup
- * duplicator much easier.
- */
- if(use_deform_motion && b_parent.ptr.data != b_ob.ptr.data) {
- PointerRNA parent_cobject = RNA_pointer_get(&b_parent.ptr, "cycles");
- use_deform_motion &= get_boolean(parent_cobject, "use_deform_motion");
- }
- return use_deform_motion;
+ PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
+ bool use_deform_motion = get_boolean(cobject, "use_deform_motion");
+ /* If motion blur is enabled for the object we also check
+ * whether it's enabled for the parent object as well.
+ *
+ * This way we can control motion blur from the dupligroup
+ * duplicator much easier.
+ */
+ if (use_deform_motion && b_parent.ptr.data != b_ob.ptr.data) {
+ PointerRNA parent_cobject = RNA_pointer_get(&b_parent.ptr, "cycles");
+ use_deform_motion &= get_boolean(parent_cobject, "use_deform_motion");
+ }
+ return use_deform_motion;
}
-static inline BL::SmokeDomainSettings object_smoke_domain_find(BL::Object& b_ob)
+static inline BL::SmokeDomainSettings object_smoke_domain_find(BL::Object &b_ob)
{
- BL::Object::modifiers_iterator b_mod;
+ BL::Object::modifiers_iterator b_mod;
- for(b_ob.modifiers.begin(b_mod); b_mod != b_ob.modifiers.end(); ++b_mod) {
- if(b_mod->is_a(&RNA_SmokeModifier)) {
- BL::SmokeModifier b_smd(*b_mod);
+ for (b_ob.modifiers.begin(b_mod); b_mod != b_ob.modifiers.end(); ++b_mod) {
+ if (b_mod->is_a(&RNA_SmokeModifier)) {
+ BL::SmokeModifier b_smd(*b_mod);
- if(b_smd.smoke_type() == BL::SmokeModifier::smoke_type_DOMAIN)
- return b_smd.domain_settings();
- }
- }
+ if (b_smd.smoke_type() == BL::SmokeModifier::smoke_type_DOMAIN)
+ return b_smd.domain_settings();
+ }
+ }
- return BL::SmokeDomainSettings(PointerRNA_NULL);
+ return BL::SmokeDomainSettings(PointerRNA_NULL);
}
static inline BL::DomainFluidSettings object_fluid_domain_find(BL::Object b_ob)
{
- BL::Object::modifiers_iterator b_mod;
+ BL::Object::modifiers_iterator b_mod;
- for(b_ob.modifiers.begin(b_mod); b_mod != b_ob.modifiers.end(); ++b_mod) {
- if(b_mod->is_a(&RNA_FluidSimulationModifier)) {
- BL::FluidSimulationModifier b_fmd(*b_mod);
- BL::FluidSettings fss = b_fmd.settings();
+ for (b_ob.modifiers.begin(b_mod); b_mod != b_ob.modifiers.end(); ++b_mod) {
+ if (b_mod->is_a(&RNA_FluidSimulationModifier)) {
+ BL::FluidSimulationModifier b_fmd(*b_mod);
+ BL::FluidSettings fss = b_fmd.settings();
- if(fss.type() == BL::FluidSettings::type_DOMAIN)
- return (BL::DomainFluidSettings)b_fmd.settings();
- }
- }
+ if (fss.type() == BL::FluidSettings::type_DOMAIN)
+ return (BL::DomainFluidSettings)b_fmd.settings();
+ }
+ }
- return BL::DomainFluidSettings(PointerRNA_NULL);
+ return BL::DomainFluidSettings(PointerRNA_NULL);
}
-static inline Mesh::SubdivisionType object_subdivision_type(BL::Object& b_ob, bool preview, bool experimental)
+static inline Mesh::SubdivisionType object_subdivision_type(BL::Object &b_ob,
+ bool preview,
+ bool experimental)
{
- PointerRNA cobj = RNA_pointer_get(&b_ob.ptr, "cycles");
+ 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 (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_boolean_get(&cobj, "use_adaptive_subdivision")) {
- BL::SubsurfModifier subsurf(mod);
+ if (enabled && mod.type() == BL::Modifier::type_SUBSURF &&
+ RNA_boolean_get(&cobj, "use_adaptive_subdivision")) {
+ BL::SubsurfModifier subsurf(mod);
- if(subsurf.subdivision_type() == BL::SubsurfModifier::subdivision_type_CATMULL_CLARK) {
- return Mesh::SUBDIVISION_CATMULL_CLARK;
- }
- else {
- return Mesh::SUBDIVISION_LINEAR;
- }
- }
- }
+ if (subsurf.subdivision_type() == BL::SubsurfModifier::subdivision_type_CATMULL_CLARK) {
+ return Mesh::SUBDIVISION_CATMULL_CLARK;
+ }
+ else {
+ return Mesh::SUBDIVISION_LINEAR;
+ }
+ }
+ }
- return Mesh::SUBDIVISION_NONE;
+ return Mesh::SUBDIVISION_NONE;
}
/* ID Map
@@ -600,144 +581,143 @@ static inline Mesh::SubdivisionType object_subdivision_type(BL::Object& b_ob, bo
* Utility class to keep in sync with blender data.
* Used for objects, meshes, lights and shaders. */
-template<typename K, typename T>
-class id_map {
-public:
- id_map(vector<T*> *scene_data_)
- {
- scene_data = scene_data_;
- }
-
- T *find(const BL::ID& id)
- {
- return find(id.ptr.id.data);
- }
-
- T *find(const K& key)
- {
- if(b_map.find(key) != b_map.end()) {
- T *data = b_map[key];
- return data;
- }
-
- return NULL;
- }
-
- void set_recalc(const BL::ID& id)
- {
- b_recalc.insert(id.ptr.data);
- }
-
- void set_recalc(void *id_ptr)
- {
- b_recalc.insert(id_ptr);
- }
-
- bool has_recalc()
- {
- return !(b_recalc.empty());
- }
-
- void pre_sync()
- {
- used_set.clear();
- }
-
- bool sync(T **r_data, const BL::ID& id)
- {
- return sync(r_data, id, id, id.ptr.id.data);
- }
-
- bool sync(T **r_data, const BL::ID& id, const BL::ID& parent, const K& key)
- {
- T *data = find(key);
- bool recalc;
-
- if(!data) {
- /* add data if it didn't exist yet */
- data = new T();
- scene_data->push_back(data);
- b_map[key] = data;
- recalc = true;
- }
- else {
- recalc = (b_recalc.find(id.ptr.data) != b_recalc.end());
- if(parent.ptr.data)
- recalc = recalc || (b_recalc.find(parent.ptr.data) != b_recalc.end());
- }
-
- used(data);
-
- *r_data = data;
- return recalc;
- }
-
- bool is_used(const K& key)
- {
- T *data = find(key);
- return (data) ? used_set.find(data) != used_set.end() : false;
- }
-
- void used(T *data)
- {
- /* tag data as still in use */
- used_set.insert(data);
- }
-
- void set_default(T *data)
- {
- b_map[NULL] = data;
- }
-
- bool post_sync(bool do_delete = true)
- {
- /* remove unused data */
- vector<T*> new_scene_data;
- typename vector<T*>::iterator it;
- bool deleted = false;
-
- for(it = scene_data->begin(); it != scene_data->end(); it++) {
- T *data = *it;
-
- if(do_delete && used_set.find(data) == used_set.end()) {
- delete data;
- deleted = true;
- }
- else
- new_scene_data.push_back(data);
- }
-
- *scene_data = new_scene_data;
-
- /* update mapping */
- map<K, T*> new_map;
- typedef pair<const K, T*> TMapPair;
- typename map<K, T*>::iterator jt;
-
- for(jt = b_map.begin(); jt != b_map.end(); jt++) {
- TMapPair& pair = *jt;
-
- if(used_set.find(pair.second) != used_set.end())
- new_map[pair.first] = pair.second;
- }
-
- used_set.clear();
- b_recalc.clear();
- b_map = new_map;
-
- return deleted;
- }
-
- const map<K, T*>& key_to_scene_data()
- {
- return b_map;
- }
-
-protected:
- vector<T*> *scene_data;
- map<K, T*> b_map;
- set<T*> used_set;
- set<void*> b_recalc;
+template<typename K, typename T> class id_map {
+ public:
+ id_map(vector<T *> *scene_data_)
+ {
+ scene_data = scene_data_;
+ }
+
+ T *find(const BL::ID &id)
+ {
+ return find(id.ptr.id.data);
+ }
+
+ T *find(const K &key)
+ {
+ if (b_map.find(key) != b_map.end()) {
+ T *data = b_map[key];
+ return data;
+ }
+
+ return NULL;
+ }
+
+ void set_recalc(const BL::ID &id)
+ {
+ b_recalc.insert(id.ptr.data);
+ }
+
+ void set_recalc(void *id_ptr)
+ {
+ b_recalc.insert(id_ptr);
+ }
+
+ bool has_recalc()
+ {
+ return !(b_recalc.empty());
+ }
+
+ void pre_sync()
+ {
+ used_set.clear();
+ }
+
+ bool sync(T **r_data, const BL::ID &id)
+ {
+ return sync(r_data, id, id, id.ptr.id.data);
+ }
+
+ bool sync(T **r_data, const BL::ID &id, const BL::ID &parent, const K &key)
+ {
+ T *data = find(key);
+ bool recalc;
+
+ if (!data) {
+ /* add data if it didn't exist yet */
+ data = new T();
+ scene_data->push_back(data);
+ b_map[key] = data;
+ recalc = true;
+ }
+ else {
+ recalc = (b_recalc.find(id.ptr.data) != b_recalc.end());
+ if (parent.ptr.data)
+ recalc = recalc || (b_recalc.find(parent.ptr.data) != b_recalc.end());
+ }
+
+ used(data);
+
+ *r_data = data;
+ return recalc;
+ }
+
+ bool is_used(const K &key)
+ {
+ T *data = find(key);
+ return (data) ? used_set.find(data) != used_set.end() : false;
+ }
+
+ void used(T *data)
+ {
+ /* tag data as still in use */
+ used_set.insert(data);
+ }
+
+ void set_default(T *data)
+ {
+ b_map[NULL] = data;
+ }
+
+ bool post_sync(bool do_delete = true)
+ {
+ /* remove unused data */
+ vector<T *> new_scene_data;
+ typename vector<T *>::iterator it;
+ bool deleted = false;
+
+ for (it = scene_data->begin(); it != scene_data->end(); it++) {
+ T *data = *it;
+
+ if (do_delete && used_set.find(data) == used_set.end()) {
+ delete data;
+ deleted = true;
+ }
+ else
+ new_scene_data.push_back(data);
+ }
+
+ *scene_data = new_scene_data;
+
+ /* update mapping */
+ map<K, T *> new_map;
+ typedef pair<const K, T *> TMapPair;
+ typename map<K, T *>::iterator jt;
+
+ for (jt = b_map.begin(); jt != b_map.end(); jt++) {
+ TMapPair &pair = *jt;
+
+ if (used_set.find(pair.second) != used_set.end())
+ new_map[pair.first] = pair.second;
+ }
+
+ used_set.clear();
+ b_recalc.clear();
+ b_map = new_map;
+
+ return deleted;
+ }
+
+ const map<K, T *> &key_to_scene_data()
+ {
+ return b_map;
+ }
+
+ protected:
+ vector<T *> *scene_data;
+ map<K, T *> b_map;
+ set<T *> used_set;
+ set<void *> b_recalc;
};
/* Object Key */
@@ -745,91 +725,95 @@ protected:
enum { OBJECT_PERSISTENT_ID_SIZE = 16 };
struct ObjectKey {
- void *parent;
- int id[OBJECT_PERSISTENT_ID_SIZE];
- void *ob;
-
- ObjectKey(void *parent_, int id_[OBJECT_PERSISTENT_ID_SIZE], void *ob_)
- : parent(parent_), ob(ob_)
- {
- if(id_)
- memcpy(id, id_, sizeof(id));
- else
- memset(id, 0, sizeof(id));
- }
-
- bool operator<(const ObjectKey& k) const
- {
- if(ob < k.ob) {
- return true;
- }
- else if(ob == k.ob) {
- if(parent < k.parent)
- return true;
- else if(parent == k.parent)
- return memcmp(id, k.id, sizeof(id)) < 0;
- }
-
- return false;
- }
+ void *parent;
+ int id[OBJECT_PERSISTENT_ID_SIZE];
+ void *ob;
+
+ ObjectKey(void *parent_, int id_[OBJECT_PERSISTENT_ID_SIZE], void *ob_)
+ : parent(parent_), ob(ob_)
+ {
+ if (id_)
+ memcpy(id, id_, sizeof(id));
+ else
+ memset(id, 0, sizeof(id));
+ }
+
+ bool operator<(const ObjectKey &k) const
+ {
+ if (ob < k.ob) {
+ return true;
+ }
+ else if (ob == k.ob) {
+ if (parent < k.parent)
+ return true;
+ else if (parent == k.parent)
+ return memcmp(id, k.id, sizeof(id)) < 0;
+ }
+
+ return false;
+ }
};
/* Particle System Key */
struct ParticleSystemKey {
- void *ob;
- int id[OBJECT_PERSISTENT_ID_SIZE];
-
- ParticleSystemKey(void *ob_, int id_[OBJECT_PERSISTENT_ID_SIZE])
- : ob(ob_)
- {
- if(id_)
- memcpy(id, id_, sizeof(id));
- else
- memset(id, 0, sizeof(id));
- }
-
- bool operator<(const ParticleSystemKey& k) const
- {
- /* first id is particle index, we don't compare that */
- if(ob < k.ob)
- return true;
- else if(ob == k.ob)
- return memcmp(id+1, k.id+1, sizeof(int)*(OBJECT_PERSISTENT_ID_SIZE-1)) < 0;
-
- return false;
- }
+ void *ob;
+ int id[OBJECT_PERSISTENT_ID_SIZE];
+
+ ParticleSystemKey(void *ob_, int id_[OBJECT_PERSISTENT_ID_SIZE]) : ob(ob_)
+ {
+ if (id_)
+ memcpy(id, id_, sizeof(id));
+ else
+ memset(id, 0, sizeof(id));
+ }
+
+ bool operator<(const ParticleSystemKey &k) const
+ {
+ /* first id is particle index, we don't compare that */
+ if (ob < k.ob)
+ return true;
+ else if (ob == k.ob)
+ return memcmp(id + 1, k.id + 1, sizeof(int) * (OBJECT_PERSISTENT_ID_SIZE - 1)) < 0;
+
+ return false;
+ }
};
class EdgeMap {
-public:
- EdgeMap() {
- }
-
- void clear() {
- edges_.clear();
- }
-
- void insert(int v0, int v1) {
- get_sorted_verts(v0, v1);
- edges_.insert(std::pair<int, int>(v0, v1));
- }
-
- bool exists(int v0, int v1) {
- get_sorted_verts(v0, v1);
- return edges_.find(std::pair<int, int>(v0, v1)) != edges_.end();
- }
-
-protected:
- void get_sorted_verts(int& v0, int& v1) {
- if(v0 > v1) {
- swap(v0, v1);
- }
- }
-
- set< std::pair<int, int> > edges_;
+ public:
+ EdgeMap()
+ {
+ }
+
+ void clear()
+ {
+ edges_.clear();
+ }
+
+ void insert(int v0, int v1)
+ {
+ get_sorted_verts(v0, v1);
+ edges_.insert(std::pair<int, int>(v0, v1));
+ }
+
+ bool exists(int v0, int v1)
+ {
+ get_sorted_verts(v0, v1);
+ return edges_.find(std::pair<int, int>(v0, v1)) != edges_.end();
+ }
+
+ protected:
+ void get_sorted_verts(int &v0, int &v1)
+ {
+ if (v0 > v1) {
+ swap(v0, v1);
+ }
+ }
+
+ set<std::pair<int, int>> edges_;
};
CCL_NAMESPACE_END
-#endif /* __BLENDER_UTIL_H__ */
+#endif /* __BLENDER_UTIL_H__ */