Page MenuHome

custom_map.patch

File Metadata

Author
Daniel M. Basso (dmbasso)
Created
Nov 13 2013, 5:09 PM

custom_map.patch

Index: intern/cycles/blender/addon/properties.py
===================================================================
--- intern/cycles/blender/addon/properties.py (revision 56903)
+++ intern/cycles/blender/addon/properties.py (working copy)
@@ -23,7 +23,8 @@
EnumProperty,
FloatProperty,
IntProperty,
- PointerProperty)
+ PointerProperty,
+ StringProperty)
# enums
@@ -62,6 +63,8 @@
('FISHEYE_EQUIDISTANT', "Fisheye Equidistant", "Ideal for fulldomes, ignore the sensor dimensions"),
('FISHEYE_EQUISOLID', "Fisheye Equisolid",
"Similar to most fisheye modern lens, takes sensor dimensions into consideration"),
+ ('CUSTOM_MAP', "Custom Map",
+ "Allows arbitrary distortions based on a mapping file"),
)
enum_curve_presets = (
@@ -471,6 +474,12 @@
min=0.01, soft_max=15.0, max=100.0,
default=10.5,
)
+ cls.custom_map = StringProperty(
+ name="Custom Map",
+ maxlen=1024,
+ description="Path to the mapping file",
+ subtype='FILE_PATH',
+ )
@classmethod
def unregister(cls):
Index: intern/cycles/blender/blender_camera.cpp
===================================================================
--- intern/cycles/blender/blender_camera.cpp (revision 56903)
+++ intern/cycles/blender/blender_camera.cpp (working copy)
@@ -51,6 +51,7 @@
PanoramaType panorama_type;
float fisheye_fov;
float fisheye_lens;
+ string custom_map;
enum { AUTO, HORIZONTAL, VERTICAL } sensor_fit;
float sensor_width;
@@ -67,8 +68,6 @@
static void blender_camera_init(BlenderCamera *bcam, BL::RenderSettings b_render, BL::Scene b_scene)
{
- memset(bcam, 0, sizeof(BlenderCamera));
-
bcam->type = CAMERA_PERSPECTIVE;
bcam->zoom = 1.0f;
bcam->pixelaspect = make_float2(1.0f, 1.0f);
@@ -76,14 +75,34 @@
bcam->sensor_height = 18.0f;
bcam->sensor_fit = BlenderCamera::AUTO;
bcam->shuttertime = 1.0f;
+ bcam->border.left = 0;
+ bcam->border.bottom = 0;
bcam->border.right = 1.0f;
bcam->border.top = 1.0f;
+ bcam->pano_viewplane.left = 0;
+ bcam->pano_viewplane.bottom = 0;
bcam->pano_viewplane.right = 1.0f;
bcam->pano_viewplane.top = 1.0f;
+ bcam->nearclip = 0;
+ bcam->farclip = 0;
+ bcam->ortho_scale = 0;
+ bcam->lens = 0;
+ bcam->aperturesize = 0;
+ bcam->apertureblades = 0;
+ bcam->aperturerotation = 0;
+ bcam->focaldistance = 0;
+ bcam->shift = make_float2(0, 0);
+ bcam->offset = make_float2(0, 0);
+ bcam->panorama_type = PANORAMA_EQUIRECTANGULAR;
+ bcam->fisheye_fov = 0;
+ bcam->fisheye_lens = 0;
+ bcam->custom_map = "";
/* render resolution */
bcam->full_width = render_resolution_x(b_render);
bcam->full_height = render_resolution_y(b_render);
+
+ memset(&bcam->matrix, 0, sizeof(Transform));
}
static float blender_camera_focal_distance(BL::Object b_ob, BL::Camera b_camera)
@@ -101,7 +120,7 @@
return fabsf(transform_get_column(&mat, 3).z);
}
-static void blender_camera_from_object(BlenderCamera *bcam, BL::Object b_ob, bool skip_panorama = false)
+static void blender_camera_from_object(BlenderCamera *bcam, BL::Object b_ob, BL::BlendData b_data, bool skip_panorama = false)
{
BL::ID b_ob_data = b_ob.data();
@@ -137,6 +156,9 @@
case 2:
bcam->panorama_type = PANORAMA_FISHEYE_EQUISOLID;
break;
+ case 3:
+ bcam->panorama_type = PANORAMA_CUSTOM_MAP;
+ break;
case 0:
default:
bcam->panorama_type = PANORAMA_EQUIRECTANGULAR;
@@ -146,6 +168,10 @@
bcam->fisheye_fov = RNA_float_get(&ccamera, "fisheye_fov");
bcam->fisheye_lens = RNA_float_get(&ccamera, "fisheye_lens");
+ char tfname[1024];
+ RNA_string_get(&ccamera, "custom_map", tfname);
+ bcam->custom_map = blender_absolute_path(b_data, b_ob_data, tfname);
+
bcam->ortho_scale = b_camera.ortho_scale();
bcam->lens = b_camera.lens();
@@ -329,6 +355,7 @@
cam->panorama_type = bcam->panorama_type;
cam->fisheye_fov = bcam->fisheye_fov;
cam->fisheye_lens = bcam->fisheye_lens;
+ cam->custom_map = bcam->custom_map;
/* perspective */
cam->fov = 2.0f * atanf((0.5f * sensor_size) / bcam->lens / aspectratio);
@@ -379,7 +406,7 @@
b_ob = b_override;
if(b_ob) {
- blender_camera_from_object(&bcam, b_ob);
+ blender_camera_from_object(&bcam, b_ob, b_data);
bcam.matrix = get_transform(b_ob.matrix_world());
}
@@ -407,10 +434,10 @@
/* Sync 3D View Camera */
-static void blender_camera_view_subset(BL::RenderSettings b_render, BL::Scene b_scene, BL::Object b_ob, BL::SpaceView3D b_v3d,
+static void blender_camera_view_subset(BL::RenderSettings b_render, BL::BlendData b_data, 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::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height, bool skip_panorama = false)
+static void blender_camera_from_view(BlenderCamera *bcam, BL::BlendData b_data, 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();
@@ -423,13 +450,13 @@
BL::Object b_ob = (b_v3d.lock_camera_and_layers())? b_scene.camera(): b_v3d.camera();
if(b_ob) {
- blender_camera_from_object(bcam, b_ob, skip_panorama);
+ blender_camera_from_object(bcam, b_ob, b_data, skip_panorama);
if(!skip_panorama && bcam->type == CAMERA_PANORAMA) {
/* in panorama camera view, we map viewplane to camera border */
BoundBox2D view_box, cam_box;
- blender_camera_view_subset(b_scene.render(), b_scene, b_ob, b_v3d, b_rv3d, width, height,
+ blender_camera_view_subset(b_scene.render(), b_data, b_scene, b_ob, b_v3d, b_rv3d, width, height,
&view_box, &cam_box);
bcam->pano_viewplane = view_box.make_relative_to(cam_box);
@@ -467,7 +494,7 @@
bcam->matrix = transform_inverse(get_transform(b_rv3d.view_matrix()));
}
-static void blender_camera_view_subset(BL::RenderSettings b_render, BL::Scene b_scene, BL::Object b_ob, BL::SpaceView3D b_v3d,
+static void blender_camera_view_subset(BL::RenderSettings b_render, BL::BlendData b_data, 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;
@@ -476,7 +503,7 @@
/* get viewport viewplane */
BlenderCamera view_bcam;
blender_camera_init(&view_bcam, b_render, b_scene);
- blender_camera_from_view(&view_bcam, b_scene, b_v3d, b_rv3d, width, height, true);
+ blender_camera_from_view(&view_bcam, b_data, b_scene, b_v3d, b_rv3d, width, height, true);
blender_camera_viewplane(&view_bcam, width, height,
&view, &view_aspect, &sensor_size);
@@ -484,7 +511,7 @@
/* get camera viewplane */
BlenderCamera cam_bcam;
blender_camera_init(&cam_bcam, b_render, b_scene);
- blender_camera_from_object(&cam_bcam, b_ob, true);
+ blender_camera_from_object(&cam_bcam, b_ob, b_data, true);
blender_camera_viewplane(&cam_bcam, cam_bcam.full_width, cam_bcam.full_height,
&cam, &cam_aspect, &sensor_size);
@@ -494,7 +521,7 @@
*cam_box = cam * (1.0f/cam_aspect);
}
-static void blender_camera_border(BlenderCamera *bcam, BL::RenderSettings b_render, BL::Scene b_scene, BL::SpaceView3D b_v3d,
+static void blender_camera_border(BlenderCamera *bcam, BL::BlendData b_data, BL::RenderSettings b_render, BL::Scene b_scene, BL::SpaceView3D b_v3d,
BL::RegionView3D b_rv3d, int width, int height)
{
bool is_camera_view;
@@ -532,7 +559,7 @@
/* determine camera viewport subset */
BoundBox2D view_box, cam_box;
- blender_camera_view_subset(b_render, b_scene, b_ob, b_v3d, b_rv3d, width, height,
+ blender_camera_view_subset(b_render, b_data, b_scene, b_ob, b_v3d, b_rv3d, width, height,
&view_box, &cam_box);
/* determine viewport subset matching camera border */
@@ -544,8 +571,8 @@
{
BlenderCamera bcam;
blender_camera_init(&bcam, b_scene.render(), b_scene);
- blender_camera_from_view(&bcam, b_scene, b_v3d, b_rv3d, width, height);
- blender_camera_border(&bcam, b_scene.render(), b_scene, b_v3d, b_rv3d, width, height);
+ blender_camera_from_view(&bcam, b_data, b_scene, b_v3d, b_rv3d, width, height);
+ blender_camera_border(&bcam, b_data, b_scene.render(), b_scene, b_v3d, b_rv3d, width, height);
blender_camera_sync(scene->camera, &bcam, width, height);
}
Index: intern/cycles/render/camera.cpp
===================================================================
--- intern/cycles/render/camera.cpp (revision 56903)
+++ intern/cycles/render/camera.cpp (working copy)
@@ -16,8 +16,12 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+#include <iostream>
+#include <fstream>
+
#include "camera.h"
#include "scene.h"
+#include "tables.h"
#include "device.h"
@@ -46,6 +50,8 @@
fisheye_lens = 10.5f;
fov = M_PI_4_F;
+ cmap_rows = cmap_cols = 0;
+
sensorwidth = 0.036;
sensorheight = 0.024;
@@ -91,7 +97,7 @@
/* raster to screen */
Transform screentondc =
transform_scale(1.0f/(viewplane.right - viewplane.left),
- 1.0f/(viewplane.top - viewplane.bottom), 1.0f) *
+ 1.0f/(viewplane.top - viewplane.bottom), 1.0f) *
transform_translate(-viewplane.left, -viewplane.bottom, 0.0f);
Transform screentoraster = ndctoraster * screentondc;
@@ -130,9 +136,9 @@
}
else if(type == CAMERA_PERSPECTIVE) {
dx = transform_perspective(&rastertocamera, make_float3(1, 0, 0)) -
- transform_perspective(&rastertocamera, make_float3(0, 0, 0));
+ transform_perspective(&rastertocamera, make_float3(0, 0, 0));
dy = transform_perspective(&rastertocamera, make_float3(0, 1, 0)) -
- transform_perspective(&rastertocamera, make_float3(0, 0, 0));
+ transform_perspective(&rastertocamera, make_float3(0, 0, 0));
}
else {
dx = make_float3(0, 0, 0);
@@ -142,6 +148,35 @@
dx = transform_direction(&cameratoworld, dx);
dy = transform_direction(&cameratoworld, dy);
+ /* panorama - custom map */
+ if (!custom_map.empty()) {
+ cmap_rows = cmap_cols = 0;
+ // load custom map file
+ std::ifstream infile(custom_map.c_str());
+ if (infile.is_open()) {
+ infile >> cmap_rows;
+ infile >> cmap_cols;
+ // make sure it has enough coordinates
+ if (cmap_cols < 2 || cmap_rows < 2) {
+ fprintf(stderr, "Custom map has invalid dimensions: %ix%i.\n", cmap_rows, cmap_cols);
+ cmap_rows = cmap_cols = 0;
+ } else {
+ int tot = cmap_rows * cmap_cols;
+ cmap_grid_x = vector<float>(tot);
+ cmap_grid_y = vector<float>(tot);
+ bool success = true;
+ for (int i=0; i < tot; i++) {
+ success &= bool(infile >> cmap_grid_x[i]);
+ success &= bool(infile >> cmap_grid_y[i]);
+ }
+ if (!success)
+ fprintf(stderr, "Warning, custom map might be corrupted.\n");
+ }
+ } else {
+ fprintf(stderr, "Could not load custom map \"%s\".\n", custom_map.c_str());
+ }
+ }
+
need_update = false;
need_device_update = true;
}
@@ -229,6 +264,15 @@
kcam->fisheye_fov = fisheye_fov;
kcam->fisheye_lens = fisheye_lens;
+ if(!cmap_rows) {
+ kcam->cmap_lt_x = kcam->cmap_lt_y = TABLE_OFFSET_INVALID;
+ } else {
+ kcam->cmap_lt_x = scene->lookup_tables->add_table(dscene, cmap_grid_x);
+ kcam->cmap_lt_y = scene->lookup_tables->add_table(dscene, cmap_grid_y);
+ }
+ kcam->cmap_rows = cmap_rows;
+ kcam->cmap_cols = cmap_cols;
+
/* sensor size */
kcam->sensorwidth = sensorwidth;
kcam->sensorheight = sensorheight;
@@ -250,9 +294,14 @@
previous_need_motion = need_motion;
}
-void Camera::device_free(Device *device, DeviceScene *dscene)
+void Camera::device_free(Device *device, DeviceScene *dscene, Scene *scene)
{
- /* nothing to free, only writing to constant memory */
+ KernelCamera *kcam = &dscene->data.cam;
+ if(kcam->cmap_lt_x != TABLE_OFFSET_INVALID) {
+ scene->lookup_tables->remove_table(kcam->cmap_lt_x);
+ scene->lookup_tables->remove_table(kcam->cmap_lt_y);
+ kcam->cmap_lt_x = kcam->cmap_lt_y = TABLE_OFFSET_INVALID;
+ }
}
bool Camera::modified(const Camera& cam)
@@ -276,7 +325,8 @@
(matrix == cam.matrix) &&
(panorama_type == cam.panorama_type) &&
(fisheye_fov == cam.fisheye_fov) &&
- (fisheye_lens == cam.fisheye_lens));
+ (fisheye_lens == cam.fisheye_lens) &&
+ (custom_map == cam.custom_map));
}
bool Camera::motion_modified(const Camera& cam)
Index: intern/cycles/render/scene.cpp
===================================================================
--- intern/cycles/render/scene.cpp (revision 56903)
+++ intern/cycles/render/scene.cpp (working copy)
@@ -92,7 +92,7 @@
particle_systems.clear();
if(device) {
- camera->device_free(device, &dscene);
+ camera->device_free(device, &dscene, this);
film->device_free(device, &dscene, this);
background->device_free(device, &dscene);
integrator->device_free(device, &dscene);
Index: intern/cycles/render/camera.h
===================================================================
--- intern/cycles/render/camera.h (revision 56903)
+++ intern/cycles/render/camera.h (working copy)
@@ -55,6 +55,11 @@
PanoramaType panorama_type;
float fisheye_fov;
float fisheye_lens;
+
+ /* panorama - custom map */
+ string custom_map;
+ vector<float> cmap_grid_x, cmap_grid_y;
+ int cmap_rows, cmap_cols;
/* sensor */
float sensorwidth;
@@ -108,7 +113,7 @@
void update();
void device_update(Device *device, DeviceScene *dscene, Scene *scene);
- void device_free(Device *device, DeviceScene *dscene);
+ void device_free(Device *device, DeviceScene *dscene, Scene *scene);
bool modified(const Camera& cam);
bool motion_modified(const Camera& cam);
Index: intern/cycles/app/cycles_xml.cpp
===================================================================
--- intern/cycles/app/cycles_xml.cpp (revision 56903)
+++ intern/cycles/app/cycles_xml.cpp (working copy)
@@ -311,6 +311,8 @@
cam->panorama_type = PANORAMA_FISHEYE_EQUIDISTANT;
else if(xml_equal_string(node, "panorama_type", "fisheye_equisolid"))
cam->panorama_type = PANORAMA_FISHEYE_EQUISOLID;
+ else if(xml_equal_string(node, "panorama_type", "custom_map"))
+ cam->panorama_type = PANORAMA_CUSTOM_MAP;
xml_read_float(&cam->fisheye_fov, node, "fisheye_fov");
xml_read_float(&cam->fisheye_lens, node, "fisheye_lens");
@@ -318,6 +320,7 @@
xml_read_float(&cam->sensorwidth, node, "sensorwidth");
xml_read_float(&cam->sensorheight, node, "sensorheight");
+ xml_read_string(&cam->custom_map, node, "custom_map");
cam->matrix = state.tfm;
Index: intern/cycles/kernel/kernel_types.h
===================================================================
--- intern/cycles/kernel/kernel_types.h (revision 56903)
+++ intern/cycles/kernel/kernel_types.h (working copy)
@@ -323,7 +323,8 @@
enum PanoramaType {
PANORAMA_EQUIRECTANGULAR,
PANORAMA_FISHEYE_EQUIDISTANT,
- PANORAMA_FISHEYE_EQUISOLID
+ PANORAMA_FISHEYE_EQUISOLID,
+ PANORAMA_CUSTOM_MAP
};
/* Differential */
@@ -555,6 +556,10 @@
float fisheye_fov;
float fisheye_lens;
+ /* panorama - custom map */
+ int cmap_lt_x, cmap_lt_y;
+ int cmap_rows, cmap_cols;
+
/* matrices */
Transform cameratoworld;
Transform rastertocamera;
Index: intern/cycles/kernel/kernel_projection.h
===================================================================
--- intern/cycles/kernel/kernel_projection.h (revision 56903)
+++ intern/cycles/kernel/kernel_projection.h (working copy)
@@ -144,6 +144,21 @@
);
}
+__device float3 custom_map_to_direction(KernelGlobals *kg, float u, float v)
+{
+ // in case the custom map couldn't be loaded,
+ // perform the regular equirectangular mapping
+ if (!kernel_data.cam.cmap_rows)
+ return equirectangular_to_direction(u, v);
+ // map the vector to new coordinates
+ float u2 = lookup_table_read_2D(kg, u, v, kernel_data.cam.cmap_lt_x,
+ kernel_data.cam.cmap_cols, kernel_data.cam.cmap_rows);
+ float v2 = lookup_table_read_2D(kg, u, v, kernel_data.cam.cmap_lt_y,
+ kernel_data.cam.cmap_cols, kernel_data.cam.cmap_rows);
+ // return the direction for the mapped coordinates
+ return equirectangular_to_direction(u2, v2);
+}
+
/* Mirror Ball <-> Cartesion direction */
__device float3 mirrorball_to_direction(float u, float v)
@@ -183,6 +198,8 @@
return equirectangular_to_direction(u, v);
case PANORAMA_FISHEYE_EQUIDISTANT:
return fisheye_to_direction(u, v, kernel_data.cam.fisheye_fov);
+ case PANORAMA_CUSTOM_MAP:
+ return custom_map_to_direction(kg, u, v);
case PANORAMA_FISHEYE_EQUISOLID:
default:
return fisheye_equisolid_to_direction(u, v, kernel_data.cam.fisheye_lens,
Index: release/scripts/startup/bl_ui/properties_data_camera.py
===================================================================
--- release/scripts/startup/bl_ui/properties_data_camera.py (revision 56903)
+++ release/scripts/startup/bl_ui/properties_data_camera.py (working copy)
@@ -98,6 +98,10 @@
row = layout.row()
row.prop(ccam, "fisheye_lens", text="Lens")
row.prop(ccam, "fisheye_fov")
+ elif ccam.panorama_type == 'CUSTOM_MAP':
+ row = layout.row()
+ row.prop(ccam, "custom_map", text="Custom Map")
+
elif engine == 'BLENDER_RENDER':
row = col.row()
if cam.lens_unit == 'MILLIMETERS':

Event Timeline