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->cmap_fname = 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"
@@ -25,6 +29,83 @@
CCL_NAMESPACE_BEGIN
+CustomMap::error_t CustomMap::load_grid(ifstream &infile) {
+ if (!bool(infile >> Nx)) return data_corrupted;
+ if (!bool(infile >> Ny)) return data_corrupted;
+ if (Nx < 2 || Nx < 2) return invalid_dim;
+ int tot = Nx * Ny;
+ if (mask & mask_X) grid_x = vector<float>(tot);
+ if (mask & mask_Y) grid_y = vector<float>(tot);
+ if (mask & mask_U) grid_u = vector<float>(tot);
+ if (mask & mask_V) grid_v = vector<float>(tot);
+ if (mask & mask_I) grid_i = vector<float>(tot);
+ bool success = true;
+ for (int i=0; i < tot && success; i++) {
+ if (mask & mask_X) success &= bool(infile >> grid_x[i]);
+ if (mask & mask_Y) success &= bool(infile >> grid_y[i]);
+ if (mask & mask_U) success &= bool(infile >> grid_u[i]);
+ if (mask & mask_V) success &= bool(infile >> grid_v[i]);
+ if (mask & mask_I) success &= bool(infile >> grid_i[i]);
+ }
+ return success ? no_error : data_corrupted;
+}
+
+CustomMap::error_t CustomMap::load(const char *fname) {
+ error_t retv;
+ ifstream infile(fname);
+ if (!infile.is_open()) return couldnt_open;
+ int magic=0;
+ if (!bool(infile >> magic)) return data_corrupted;
+ if (magic != 0xd157047) {
+ // try to load as warpmesh format
+ if (magic > 0 && magic < 6) {
+ type = magic;
+ mask = mask_all;
+ retv = load_grid(infile);
+ if (retv != no_error)
+ Nx = Ny = 0;
+ return retv;
+ }
+ return data_corrupted;
+ }
+ int tmask;
+ if (!bool(infile >> tmask)) return data_corrupted;
+ if (tmask & ~mask_all) return data_corrupted;
+ mask = (CustomMap::mask_t) tmask;
+ if (!bool(infile >> type)) return data_corrupted;
+ retv = load_grid(infile);
+ if (retv != no_error)
+ Nx = Ny = 0;
+ return retv;
+}
+
+CustomMap::error_t CustomMap::save(const char *fname) {
+ ofstream outfile(fname);
+ if (!outfile.is_open()) return couldnt_open;
+ outfile << 0xd157047 << ' ' << (int) mask << ' ' << type << endl;
+ outfile << Nx << ' ' << Ny << endl;
+ for (int i=0; i < Nx * Ny; i++) {
+ if (mask & mask_X) outfile << grid_x[i] << ' ';
+ if (mask & mask_Y) outfile << grid_y[i] << ' ';
+ if (mask & mask_U) outfile << grid_u[i] << ' ';
+ if (mask & mask_V) outfile << grid_v[i] << ' ';
+ if (mask & mask_I) outfile << grid_i[i];
+ outfile << endl;
+ }
+ return no_error;
+}
+
+void CustomMap::display(error_t error) {
+ if (error < invalid_dim || error > couldnt_open)
+ return;
+ const char* msgs[] = {
+ "invalid dimensions",
+ "data corrupted",
+ "could not open the file"
+ };
+ fprintf(stderr, "Custom map: %s.\n", msgs[(int)error - 1]);
+}
+
Camera::Camera()
{
shuttertime = 1.0f;
@@ -46,6 +127,8 @@
fisheye_lens = 10.5f;
fov = M_PI_4_F;
+ custom_map.Nx = custom_map.Ny = 0;
+
sensorwidth = 0.036;
sensorheight = 0.024;
@@ -91,7 +174,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 +213,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 +225,19 @@
dx = transform_direction(&cameratoworld, dx);
dy = transform_direction(&cameratoworld, dy);
+ /* panorama - custom map */
+ if (!cmap_fname.empty()) {
+ CustomMap::error_t err = custom_map.load(cmap_fname.c_str());
+ if (err)
+ custom_map.display(err);
+ else {
+ if (custom_map.type < 2 || custom_map.type > 3) {
+ fprintf(stderr, "Custom map: unsupported projection.\n");
+ custom_map.Nx = custom_map.Ny = 0;
+ }
+ }
+ }
+
need_update = false;
need_device_update = true;
}
@@ -229,6 +325,16 @@
kcam->fisheye_fov = fisheye_fov;
kcam->fisheye_lens = fisheye_lens;
+ if(!custom_map.Nx) {
+ kcam->cmap_lt_u = kcam->cmap_lt_v = TABLE_OFFSET_INVALID;
+ } else {
+ kcam->cmap_lt_u = scene->lookup_tables->add_table(dscene, custom_map.grid_u);
+ kcam->cmap_lt_v = scene->lookup_tables->add_table(dscene, custom_map.grid_v);
+ }
+ kcam->cmap_Nx = custom_map.Nx;
+ kcam->cmap_Ny = custom_map.Ny;
+ kcam->cmap_type = custom_map.type;
+
/* sensor size */
kcam->sensorwidth = sensorwidth;
kcam->sensorheight = sensorheight;
@@ -250,9 +356,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_u != TABLE_OFFSET_INVALID) {
+ scene->lookup_tables->remove_table(kcam->cmap_lt_u);
+ scene->lookup_tables->remove_table(kcam->cmap_lt_v);
+ kcam->cmap_lt_u = kcam->cmap_lt_v = TABLE_OFFSET_INVALID;
+ }
}
bool Camera::modified(const Camera& cam)
@@ -276,7 +387,8 @@
(matrix == cam.matrix) &&
(panorama_type == cam.panorama_type) &&
(fisheye_fov == cam.fisheye_fov) &&
- (fisheye_lens == cam.fisheye_lens));
+ (fisheye_lens == cam.fisheye_lens) &&
+ (cmap_fname == cam.cmap_fname));
}
bool Camera::motion_modified(const Camera& cam)
Index: intern/cycles/render/camera.h
===================================================================
--- intern/cycles/render/camera.h (revision 56903)
+++ intern/cycles/render/camera.h (working copy)
@@ -31,6 +31,30 @@
class DeviceScene;
class Scene;
+class CustomMap {
+public:
+ int type;
+ int Nx, Ny;
+ vector<float> grid_x, grid_y;
+ vector<float> grid_u, grid_v;
+ vector<float> grid_i;
+
+ typedef enum error {
+ no_error, invalid_dim, data_corrupted, couldnt_open
+ } error_t;
+
+ typedef enum mask {
+ mask_X=1, mask_Y=2, mask_U=4, mask_V=8, mask_I=0x10, mask_all=0x1f
+ } mask_t;
+
+ mask_t mask;
+
+ error_t load_grid(ifstream &infile);
+ error_t load(const char *fname);
+ error_t save(const char *fname);
+ void display(error_t error);
+};
+
/* Camera
*
* The camera parameters are quite standard, tested to be both compatible with
@@ -55,6 +79,10 @@
PanoramaType panorama_type;
float fisheye_fov;
float fisheye_lens;
+
+ /* panorama - custom map */
+ string cmap_fname;
+ CustomMap custom_map;
/* sensor */
float sensorwidth;
@@ -108,7 +136,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/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/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,11 @@
float fisheye_fov;
float fisheye_lens;
+ /* panorama - custom map */
+ int cmap_type;
+ int cmap_Nx, cmap_Ny;
+ int cmap_lt_u, cmap_lt_v;
+
/* 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,23 @@
);
}
+__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_Nx)
+ 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_u,
+ kernel_data.cam.cmap_Nx, kernel_data.cam.cmap_Ny);
+ float v2 = lookup_table_read_2D(kg, u, v, kernel_data.cam.cmap_lt_v,
+ kernel_data.cam.cmap_Nx, kernel_data.cam.cmap_Ny);
+ // return the direction for the mapped coordinates
+ if (kernel_data.cam.cmap_type == 2)
+ return fisheye_to_direction(u2, v2, M_PI_F); //kernel_data.cam.fisheye_fov);
+ return equirectangular_to_direction(u2, v2);
+}
+
/* Mirror Ball <-> Cartesion direction */
__device float3 mirrorball_to_direction(float u, float v)
@@ -183,6 +200,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