Camera: Move panoramic projection settings to DNA #111310
|
@ -65,17 +65,6 @@ enum_filter_types = (
|
|||
('BLACKMAN_HARRIS', "Blackman-Harris", "Blackman-Harris filter"),
|
||||
)
|
||||
|
||||
enum_panorama_types = (
|
||||
('EQUIRECTANGULAR', "Equirectangular", "Spherical camera for environment maps, also known as Lat Long panorama", 0),
|
||||
('EQUIANGULAR_CUBEMAP_FACE', "Equiangular Cubemap Face", "Single face of an equiangular cubemap", 5),
|
||||
('MIRRORBALL', "Mirror Ball", "Mirror ball mapping for environment maps", 3),
|
||||
('FISHEYE_EQUIDISTANT', "Fisheye Equidistant", "Ideal for fulldomes, ignore the sensor dimensions", 1),
|
||||
('FISHEYE_EQUISOLID', "Fisheye Equisolid",
|
||||
"Similar to most fisheye modern lens, takes sensor dimensions into consideration", 2),
|
||||
('FISHEYE_LENS_POLYNOMIAL', "Fisheye Lens Polynomial",
|
||||
"Defines the lens projection as polynomial to allow real world camera lenses to be mimicked", 4),
|
||||
)
|
||||
|
||||
enum_curve_shape = (
|
||||
('RIBBONS', "Rounded Ribbons", "Render curves as flat ribbons with rounded normals, for fast rendering"),
|
||||
('THICK', "3D Curves", "Render curves as circular 3D geometry, for accurate results when viewing closely"),
|
||||
|
@ -1014,95 +1003,6 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
|||
del bpy.types.Scene.cycles
|
||||
|
||||
|
||||
class CyclesCameraSettings(bpy.types.PropertyGroup):
|
||||
|
||||
panorama_type: EnumProperty(
|
||||
name="Panorama Type",
|
||||
description="Distortion to use for the calculation",
|
||||
items=enum_panorama_types,
|
||||
default='FISHEYE_EQUISOLID',
|
||||
)
|
||||
fisheye_fov: FloatProperty(
|
||||
name="Field of View",
|
||||
description="Field of view for the fisheye lens",
|
||||
min=0.1745, soft_max=2.0 * pi, max=10.0 * pi,
|
||||
subtype='ANGLE',
|
||||
default=pi,
|
||||
)
|
||||
fisheye_lens: FloatProperty(
|
||||
name="Fisheye Lens",
|
||||
description="Lens focal length (mm)",
|
||||
min=0.01, soft_max=15.0, max=100.0,
|
||||
default=10.5,
|
||||
)
|
||||
latitude_min: FloatProperty(
|
||||
name="Min Latitude",
|
||||
description="Minimum latitude (vertical angle) for the equirectangular lens",
|
||||
min=-0.5 * pi, max=0.5 * pi,
|
||||
subtype='ANGLE',
|
||||
default=-0.5 * pi,
|
||||
)
|
||||
latitude_max: FloatProperty(
|
||||
name="Max Latitude",
|
||||
description="Maximum latitude (vertical angle) for the equirectangular lens",
|
||||
min=-0.5 * pi, max=0.5 * pi,
|
||||
subtype='ANGLE',
|
||||
default=0.5 * pi,
|
||||
)
|
||||
longitude_min: FloatProperty(
|
||||
name="Min Longitude",
|
||||
description="Minimum longitude (horizontal angle) for the equirectangular lens",
|
||||
min=-pi, max=pi,
|
||||
subtype='ANGLE',
|
||||
default=-pi,
|
||||
)
|
||||
longitude_max: FloatProperty(
|
||||
name="Max Longitude",
|
||||
description="Maximum longitude (horizontal angle) for the equirectangular lens",
|
||||
min=-pi, max=pi,
|
||||
subtype='ANGLE',
|
||||
default=pi,
|
||||
)
|
||||
|
||||
fisheye_polynomial_k0: FloatProperty(
|
||||
name="Fisheye Polynomial K0",
|
||||
description="Coefficient K0 of the lens polynomial",
|
||||
default=camera.default_fisheye_polynomial[0], precision=6, step=0.1, subtype='ANGLE',
|
||||
)
|
||||
fisheye_polynomial_k1: FloatProperty(
|
||||
name="Fisheye Polynomial K1",
|
||||
description="Coefficient K1 of the lens polynomial",
|
||||
default=camera.default_fisheye_polynomial[1], precision=6, step=0.1, subtype='ANGLE',
|
||||
)
|
||||
fisheye_polynomial_k2: FloatProperty(
|
||||
name="Fisheye Polynomial K2",
|
||||
description="Coefficient K2 of the lens polynomial",
|
||||
default=camera.default_fisheye_polynomial[2], precision=6, step=0.1, subtype='ANGLE',
|
||||
)
|
||||
fisheye_polynomial_k3: FloatProperty(
|
||||
name="Fisheye Polynomial K3",
|
||||
description="Coefficient K3 of the lens polynomial",
|
||||
default=camera.default_fisheye_polynomial[3], precision=6, step=0.1, subtype='ANGLE',
|
||||
)
|
||||
fisheye_polynomial_k4: FloatProperty(
|
||||
name="Fisheye Polynomial K4",
|
||||
description="Coefficient K4 of the lens polynomial",
|
||||
default=camera.default_fisheye_polynomial[4], precision=6, step=0.1, subtype='ANGLE',
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def register(cls):
|
||||
bpy.types.Camera.cycles = PointerProperty(
|
||||
name="Cycles Camera Settings",
|
||||
description="Cycles camera settings",
|
||||
type=cls,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def unregister(cls):
|
||||
del bpy.types.Camera.cycles
|
||||
|
||||
|
||||
class CyclesMaterialSettings(bpy.types.PropertyGroup):
|
||||
|
||||
emission_sampling: EnumProperty(
|
||||
|
@ -1837,7 +1737,6 @@ class CyclesView3DShadingSettings(bpy.types.PropertyGroup):
|
|||
|
||||
def register():
|
||||
bpy.utils.register_class(CyclesRenderSettings)
|
||||
bpy.utils.register_class(CyclesCameraSettings)
|
||||
bpy.utils.register_class(CyclesMaterialSettings)
|
||||
bpy.utils.register_class(CyclesLightSettings)
|
||||
bpy.utils.register_class(CyclesWorldSettings)
|
||||
|
@ -1858,7 +1757,6 @@ def register():
|
|||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(CyclesRenderSettings)
|
||||
bpy.utils.unregister_class(CyclesCameraSettings)
|
||||
bpy.utils.unregister_class(CyclesMaterialSettings)
|
||||
bpy.utils.unregister_class(CyclesLightSettings)
|
||||
bpy.utils.unregister_class(CyclesWorldSettings)
|
||||
|
|
|
@ -164,6 +164,26 @@ static float blender_camera_focal_distance(BL::RenderEngine &b_engine,
|
|||
return fabsf(dot(view_dir, dof_dir));
|
||||
}
|
||||
|
||||
static PanoramaType blender_panorama_type_to_cycles(const BL::Camera::panorama_type_enum type)
|
||||
{
|
||||
switch (type) {
|
||||
case BL::Camera::panorama_type_EQUIRECTANGULAR:
|
||||
return PANORAMA_EQUIRECTANGULAR;
|
||||
case BL::Camera::panorama_type_EQUIANGULAR_CUBEMAP_FACE:
|
||||
return PANORAMA_EQUIANGULAR_CUBEMAP_FACE;
|
||||
case BL::Camera::panorama_type_MIRRORBALL:
|
||||
return PANORAMA_MIRRORBALL;
|
||||
case BL::Camera::panorama_type_FISHEYE_EQUIDISTANT:
|
||||
return PANORAMA_FISHEYE_EQUIDISTANT;
|
||||
case BL::Camera::panorama_type_FISHEYE_EQUISOLID:
|
||||
return PANORAMA_FISHEYE_EQUISOLID;
|
||||
case BL::Camera::panorama_type_FISHEYE_LENS_POLYNOMIAL:
|
||||
return PANORAMA_FISHEYE_LENS_POLYNOMIAL;
|
||||
}
|
||||
/* Could happen if loading a newer file that has an unsupported type. */
|
||||
return PANORAMA_FISHEYE_EQUISOLID;
|
||||
}
|
||||
|
||||
static void blender_camera_from_object(BlenderCamera *bcam,
|
||||
BL::RenderEngine &b_engine,
|
||||
BL::Object &b_ob,
|
||||
|
@ -173,7 +193,6 @@ static void blender_camera_from_object(BlenderCamera *bcam,
|
|||
|
||||
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();
|
||||
fclem marked this conversation as resolved
Outdated
|
||||
bcam->farclip = b_camera.clip_end();
|
||||
|
@ -194,21 +213,19 @@ static void blender_camera_from_object(BlenderCamera *bcam,
|
|||
break;
|
||||
}
|
||||
|
||||
bcam->panorama_type = (PanoramaType)get_enum(
|
||||
ccamera, "panorama_type", PANORAMA_NUM_TYPES, PANORAMA_EQUIRECTANGULAR);
|
||||
bcam->panorama_type = blender_panorama_type_to_cycles(b_camera.panorama_type());
|
||||
bcam->fisheye_fov = b_camera.fisheye_fov();
|
||||
bcam->fisheye_lens = b_camera.fisheye_lens();
|
||||
bcam->latitude_min = b_camera.latitude_min();
|
||||
bcam->latitude_max = b_camera.latitude_max();
|
||||
bcam->longitude_min = b_camera.longitude_min();
|
||||
bcam->longitude_max = b_camera.longitude_max();
|
||||
|
||||
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->fisheye_polynomial_k0 = RNA_float_get(&ccamera, "fisheye_polynomial_k0");
|
||||
bcam->fisheye_polynomial_k1 = RNA_float_get(&ccamera, "fisheye_polynomial_k1");
|
||||
bcam->fisheye_polynomial_k2 = RNA_float_get(&ccamera, "fisheye_polynomial_k2");
|
||||
bcam->fisheye_polynomial_k3 = RNA_float_get(&ccamera, "fisheye_polynomial_k3");
|
||||
bcam->fisheye_polynomial_k4 = RNA_float_get(&ccamera, "fisheye_polynomial_k4");
|
||||
bcam->fisheye_polynomial_k0 = b_camera.fisheye_polynomial_k0();
|
||||
bcam->fisheye_polynomial_k1 = b_camera.fisheye_polynomial_k1();
|
||||
bcam->fisheye_polynomial_k2 = b_camera.fisheye_polynomial_k2();
|
||||
bcam->fisheye_polynomial_k3 = b_camera.fisheye_polynomial_k3();
|
||||
bcam->fisheye_polynomial_k4 = b_camera.fisheye_polynomial_k4();
|
||||
|
||||
bcam->interocular_distance = b_camera.stereo().interocular_distance();
|
||||
if (b_camera.stereo().convergence_mode() == BL::CameraStereoData::convergence_mode_PARALLEL) {
|
||||
|
|
|
@ -103,27 +103,26 @@ class DATA_PT_lens(CameraButtonsPanel, Panel):
|
|||
elif cam.type == 'PANO':
|
||||
engine = context.engine
|
||||
if engine == 'CYCLES':
|
||||
ccam = cam.cycles
|
||||
col.prop(ccam, "panorama_type")
|
||||
if ccam.panorama_type == 'FISHEYE_EQUIDISTANT':
|
||||
col.prop(ccam, "fisheye_fov")
|
||||
elif ccam.panorama_type == 'FISHEYE_EQUISOLID':
|
||||
col.prop(ccam, "fisheye_lens", text="Lens")
|
||||
col.prop(ccam, "fisheye_fov")
|
||||
elif ccam.panorama_type == 'EQUIRECTANGULAR':
|
||||
col.prop(cam, "panorama_type")
|
||||
if cam.panorama_type == 'FISHEYE_EQUIDISTANT':
|
||||
col.prop(cam, "fisheye_fov")
|
||||
elif cam.panorama_type == 'FISHEYE_EQUISOLID':
|
||||
col.prop(cam, "fisheye_lens", text="Lens")
|
||||
col.prop(cam, "fisheye_fov")
|
||||
elif cam.panorama_type == 'EQUIRECTANGULAR':
|
||||
sub = col.column(align=True)
|
||||
sub.prop(ccam, "latitude_min", text="Latitude Min")
|
||||
sub.prop(ccam, "latitude_max", text="Max")
|
||||
sub.prop(cam, "latitude_min", text="Latitude Min")
|
||||
sub.prop(cam, "latitude_max", text="Max")
|
||||
sub = col.column(align=True)
|
||||
sub.prop(ccam, "longitude_min", text="Longitude Min")
|
||||
sub.prop(ccam, "longitude_max", text="Max")
|
||||
elif ccam.panorama_type == 'FISHEYE_LENS_POLYNOMIAL':
|
||||
col.prop(ccam, "fisheye_fov")
|
||||
col.prop(ccam, "fisheye_polynomial_k0", text="K0")
|
||||
col.prop(ccam, "fisheye_polynomial_k1", text="K1")
|
||||
col.prop(ccam, "fisheye_polynomial_k2", text="K2")
|
||||
col.prop(ccam, "fisheye_polynomial_k3", text="K3")
|
||||
col.prop(ccam, "fisheye_polynomial_k4", text="K4")
|
||||
sub.prop(cam, "longitude_min", text="Longitude Min")
|
||||
sub.prop(cam, "longitude_max", text="Max")
|
||||
elif cam.panorama_type == 'FISHEYE_LENS_POLYNOMIAL':
|
||||
col.prop(cam, "fisheye_fov")
|
||||
col.prop(cam, "fisheye_polynomial_k0", text="K0")
|
||||
col.prop(cam, "fisheye_polynomial_k1", text="K1")
|
||||
col.prop(cam, "fisheye_polynomial_k2", text="K2")
|
||||
col.prop(cam, "fisheye_polynomial_k3", text="K3")
|
||||
col.prop(cam, "fisheye_polynomial_k4", text="K4")
|
||||
|
||||
elif engine in {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'}:
|
||||
if cam.lens_unit == 'MILLIMETERS':
|
||||
|
|
|
@ -29,7 +29,7 @@ extern "C" {
|
|||
|
||||
/* Blender file format version. */
|
||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||
#define BLENDER_FILE_SUBVERSION 16
|
||||
#define BLENDER_FILE_SUBVERSION 17
|
||||
|
||||
/* Minimum Blender version that supports reading file written with the current
|
||||
* version. Older Blender versions will test this and cancel loading the file, showing a warning to
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "BKE_action.h"
|
||||
#include "BKE_anim_data.h"
|
||||
#include "BKE_camera.h"
|
||||
#include "BKE_idprop.h"
|
||||
#include "BKE_idtype.h"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_lib_id.h"
|
||||
|
@ -103,10 +104,97 @@ static void camera_foreach_id(ID *id, LibraryForeachIDData *data)
|
|||
}
|
||||
}
|
||||
|
||||
struct CameraCyclesCompatibilityData {
|
||||
IDProperty *idprop_prev = nullptr;
|
||||
IDProperty *idprop_temp = nullptr;
|
||||
};
|
||||
|
||||
static CameraCyclesCompatibilityData camera_write_cycles_compatibility_data_create(ID *id)
|
||||
{
|
||||
auto cycles_data_ensure = [](IDProperty *group) {
|
||||
IDProperty *prop = IDP_GetPropertyTypeFromGroup(group, "cycles", IDP_GROUP);
|
||||
if (prop) {
|
||||
return prop;
|
||||
}
|
||||
IDPropertyTemplate val = {0};
|
||||
prop = IDP_New(IDP_GROUP, &val, "cycles");
|
||||
IDP_AddToGroup(group, prop);
|
||||
return prop;
|
||||
};
|
||||
|
||||
auto cycles_property_int_set = [](IDProperty *idprop, const char *name, int value) {
|
||||
IDProperty *prop = IDP_GetPropertyTypeFromGroup(idprop, name, IDP_INT);
|
||||
if (prop) {
|
||||
IDP_Int(prop) = value;
|
||||
}
|
||||
else {
|
||||
IDPropertyTemplate val = {0};
|
||||
val.i = value;
|
||||
IDP_AddToGroup(idprop, IDP_New(IDP_INT, &val, name));
|
||||
}
|
||||
};
|
||||
|
||||
auto cycles_property_float_set = [](IDProperty *idprop, const char *name, float value) {
|
||||
IDProperty *prop = IDP_GetPropertyTypeFromGroup(idprop, name, IDP_FLOAT);
|
||||
Sergey Sharybin
commented
The write code should not modify the input ID. In fact, the ID should be const-qualified. One way to achieve this I can think of is to make a shallow copy of the Camera, duplicate the ID properties, set the required properties, write using Additionally, such versioning should not happen for undo pushes. The write code should not modify the input ID. In fact, the ID should be const-qualified.
One way to achieve this I can think of is to make a shallow copy of the Camera, duplicate the ID properties, set the required properties, write using `BLO_write_struct_at_address`, and free the copied version of ID properties.
Additionally, such versioning should not happen for undo pushes.
Bastien Montagne
commented
@Sergey all IDs are already shallow-duplicated by generic write code, precisely because we do 'modify' these a lot when writing (esp. by setting many runtime data to NULL e.g.). @Sergey all IDs are already shallow-duplicated by generic write code, precisely because we do 'modify' these a lot when writing (esp. by setting many runtime data to NULL e.g.).
Sergey Sharybin
commented
Then no shallow-copy needed, but you still should not add ID properties to the original data-block. Then no shallow-copy needed, but you still should not add ID properties to the original data-block.
|
||||
if (prop) {
|
||||
IDP_Float(prop) = value;
|
||||
}
|
||||
else {
|
||||
IDPropertyTemplate val = {0};
|
||||
val.f = value;
|
||||
IDP_AddToGroup(idprop, IDP_New(IDP_FLOAT, &val, name));
|
||||
}
|
||||
};
|
||||
|
||||
/* For forward compatibility, still write panoramic properties as ID properties for
|
||||
* previous blender versions. */
|
||||
IDProperty *idprop_prev = IDP_GetProperties(id, false);
|
||||
fclem marked this conversation as resolved
Outdated
Bastien Montagne
commented
`previous blender versions`
|
||||
/* Make a copy to avoid modifying the original. */
|
||||
IDProperty *idprop_temp = idprop_prev ? IDP_CopyProperty(idprop_prev) :
|
||||
IDP_GetProperties(id, true);
|
||||
|
||||
Camera *cam = (Camera *)id;
|
||||
IDProperty *cycles_cam = cycles_data_ensure(idprop_temp);
|
||||
cycles_property_int_set(cycles_cam, "panorama_type", cam->panorama_type);
|
||||
cycles_property_float_set(cycles_cam, "fisheye_fov", cam->fisheye_fov);
|
||||
cycles_property_float_set(cycles_cam, "fisheye_lens", cam->fisheye_lens);
|
||||
cycles_property_float_set(cycles_cam, "latitude_min", cam->latitude_min);
|
||||
cycles_property_float_set(cycles_cam, "latitude_max", cam->latitude_max);
|
||||
cycles_property_float_set(cycles_cam, "longitude_min", cam->longitude_min);
|
||||
cycles_property_float_set(cycles_cam, "longitude_max", cam->longitude_max);
|
||||
cycles_property_float_set(cycles_cam, "fisheye_polynomial_k0", cam->fisheye_polynomial_k0);
|
||||
cycles_property_float_set(cycles_cam, "fisheye_polynomial_k1", cam->fisheye_polynomial_k1);
|
||||
cycles_property_float_set(cycles_cam, "fisheye_polynomial_k2", cam->fisheye_polynomial_k2);
|
||||
cycles_property_float_set(cycles_cam, "fisheye_polynomial_k3", cam->fisheye_polynomial_k3);
|
||||
cycles_property_float_set(cycles_cam, "fisheye_polynomial_k4", cam->fisheye_polynomial_k4);
|
||||
|
||||
id->properties = idprop_temp;
|
||||
|
||||
return {idprop_prev, idprop_temp};
|
||||
}
|
||||
|
||||
static void camera_write_cycles_compatibility_data_clear(ID *id,
|
||||
CameraCyclesCompatibilityData &data)
|
||||
{
|
||||
id->properties = data.idprop_prev;
|
||||
data.idprop_prev = nullptr;
|
||||
|
||||
if (data.idprop_temp) {
|
||||
IDP_FreeProperty(data.idprop_temp);
|
||||
data.idprop_temp = nullptr;
|
||||
fclem marked this conversation as resolved
Outdated
Bastien Montagne
commented
More of a 'good practice' than strictly required, but would clear both IDPropoerty pointers in More of a 'good practice' than strictly required, but would clear both IDPropoerty pointers in `data`. That way, any potential future access to these would give an obvious 'accessing NULL pointer' error.
|
||||
}
|
||||
}
|
||||
|
||||
static void camera_blend_write(BlendWriter *writer, ID *id, const void *id_address)
|
||||
{
|
||||
const bool is_undo = BLO_write_is_undo(writer);
|
||||
Camera *cam = (Camera *)id;
|
||||
|
||||
CameraCyclesCompatibilityData cycles_data;
|
||||
fclem marked this conversation as resolved
Outdated
Bastien Montagne
commented
Could be stored as a Could be stored as a `const bool is_undo` variable, instead of calling the function several times.
|
||||
if (!is_undo) {
|
||||
cycles_data = camera_write_cycles_compatibility_data_create(id);
|
||||
}
|
||||
|
||||
/* write LibData */
|
||||
BLO_write_id_struct(writer, Camera, id_address, &cam->id);
|
||||
BKE_id_blend_write(writer, &cam->id);
|
||||
|
@ -114,6 +202,10 @@ static void camera_blend_write(BlendWriter *writer, ID *id, const void *id_addre
|
|||
LISTBASE_FOREACH (CameraBGImage *, bgpic, &cam->bg_images) {
|
||||
BLO_write_struct(writer, CameraBGImage, bgpic);
|
||||
}
|
||||
|
||||
if (!is_undo) {
|
||||
camera_write_cycles_compatibility_data_clear(id, cycles_data);
|
||||
}
|
||||
}
|
||||
|
||||
static void camera_blend_read_data(BlendDataReader *reader, ID *id)
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "CLG_log.h"
|
||||
|
||||
#include "DNA_brush_types.h"
|
||||
#include "DNA_camera_types.h"
|
||||
#include "DNA_light_types.h"
|
||||
#include "DNA_lightprobe_types.h"
|
||||
#include "DNA_modifier_types.h"
|
||||
|
@ -675,19 +676,7 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
|
|||
FOREACH_NODETREE_END;
|
||||
}
|
||||
|
||||
/**
|
||||
* Versioning code until next subversion bump goes here.
|
||||
*
|
||||
* \note Be sure to check when bumping the version:
|
||||
* - #do_versions_after_linking_400 in this file.
|
||||
* - `versioning_userdef.cc`, #blo_do_versions_userdef
|
||||
* - `versioning_userdef.cc`, #do_versions_theme
|
||||
*
|
||||
* \note Keep this message at the bottom of the function.
|
||||
*/
|
||||
{
|
||||
/* Keep this block, even when empty. */
|
||||
|
||||
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 17)) {
|
||||
if (!DNA_struct_find(fd->filesdna, "NodeShaderHairPrincipled")) {
|
||||
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
|
||||
if (ntree->type == NTREE_SHADER) {
|
||||
|
@ -697,6 +686,56 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
|
|||
FOREACH_NODETREE_END;
|
||||
}
|
||||
|
||||
/* Panorama properties shared with Eevee. */
|
||||
if (!DNA_struct_elem_find(fd->filesdna, "Camera", "float", "fisheye_fov")) {
|
||||
Camera default_cam = *DNA_struct_default_get(Camera);
|
||||
LISTBASE_FOREACH (Camera *, camera, &bmain->cameras) {
|
||||
IDProperty *ccam = version_cycles_properties_from_ID(&camera->id);
|
||||
if (ccam) {
|
||||
camera->panorama_type = version_cycles_property_int(
|
||||
ccam, "panorama_type", default_cam.panorama_type);
|
||||
camera->fisheye_fov = version_cycles_property_float(
|
||||
ccam, "fisheye_fov", default_cam.fisheye_fov);
|
||||
camera->fisheye_lens = version_cycles_property_float(
|
||||
ccam, "fisheye_lens", default_cam.fisheye_lens);
|
||||
camera->latitude_min = version_cycles_property_float(
|
||||
ccam, "latitude_min", default_cam.latitude_min);
|
||||
camera->latitude_max = version_cycles_property_float(
|
||||
fclem marked this conversation as resolved
Outdated
Weizhen Huang
commented
I think it's not enough to do versioning for I think it's not enough to do versioning for `ccam`. If there is a camera in the scene, but the render engine is not Cycles (as in the default file), then after changing to Cycles all the camera parameters in panoramic type are zero instead of the default values.
|
||||
ccam, "latitude_max", default_cam.latitude_max);
|
||||
camera->longitude_min = version_cycles_property_float(
|
||||
ccam, "longitude_min", default_cam.longitude_min);
|
||||
camera->longitude_max = version_cycles_property_float(
|
||||
ccam, "longitude_max", default_cam.longitude_max);
|
||||
/* Fit to match default projective camera with focal_length 50 and sensor_width 36. */
|
||||
camera->fisheye_polynomial_k0 = version_cycles_property_float(
|
||||
fclem marked this conversation as resolved
Outdated
Sergey Sharybin
commented
Use functional cast: More about it https://wiki.blender.org/wiki/Style_Guide/C_Cpp#C.2B.2B_Type_Cast Use functional cast: `float(M_PI)`
More about it https://wiki.blender.org/wiki/Style_Guide/C_Cpp#C.2B.2B_Type_Cast
|
||||
ccam, "fisheye_polynomial_k0", default_cam.fisheye_polynomial_k0);
|
||||
camera->fisheye_polynomial_k1 = version_cycles_property_float(
|
||||
ccam, "fisheye_polynomial_k1", default_cam.fisheye_polynomial_k1);
|
||||
fclem marked this conversation as resolved
Outdated
Sergey Sharybin
commented
Why is it in some cases there is explicit cast to float, but not in others? Why is it in some cases there is explicit cast to float, but not in others?
Clément Foucault
commented
Because explicit cast is usually to avoid Because explicit cast is usually to avoid `double` promotion. Or maybe I'm missing something.
Sergey Sharybin
commented
Ah, it is expression vs. single value as an argument. Makes sense now. Ah, it is expression vs. single value as an argument. Makes sense now.
|
||||
camera->fisheye_polynomial_k2 = version_cycles_property_float(
|
||||
ccam, "fisheye_polynomial_k2", default_cam.fisheye_polynomial_k2);
|
||||
camera->fisheye_polynomial_k3 = version_cycles_property_float(
|
||||
fclem marked this conversation as resolved
Outdated
Bastien Montagne
commented
Rather than duplicating the info here (and risking future out-of-sync issues), would rather create a temp dummy Rather than duplicating the info here (and risking future out-of-sync issues), would rather create a temp dummy `Camera` data, initialize it (calling `camera_init_data` on it), and then copy the variables' values from it into the real ID. That way you get defaults as defined in DNA.
|
||||
ccam, "fisheye_polynomial_k3", default_cam.fisheye_polynomial_k3);
|
||||
camera->fisheye_polynomial_k4 = version_cycles_property_float(
|
||||
ccam, "fisheye_polynomial_k4", default_cam.fisheye_polynomial_k4);
|
||||
}
|
||||
else {
|
||||
camera->panorama_type = default_cam.panorama_type;
|
||||
camera->fisheye_fov = default_cam.fisheye_fov;
|
||||
camera->fisheye_lens = default_cam.fisheye_lens;
|
||||
camera->latitude_min = default_cam.latitude_min;
|
||||
camera->latitude_max = default_cam.latitude_max;
|
||||
camera->longitude_min = default_cam.longitude_min;
|
||||
camera->longitude_max = default_cam.longitude_max;
|
||||
/* Fit to match default projective camera with focal_length 50 and sensor_width 36. */
|
||||
camera->fisheye_polynomial_k0 = default_cam.fisheye_polynomial_k0;
|
||||
camera->fisheye_polynomial_k1 = default_cam.fisheye_polynomial_k1;
|
||||
camera->fisheye_polynomial_k2 = default_cam.fisheye_polynomial_k2;
|
||||
camera->fisheye_polynomial_k3 = default_cam.fisheye_polynomial_k3;
|
||||
camera->fisheye_polynomial_k4 = default_cam.fisheye_polynomial_k4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!DNA_struct_elem_find(fd->filesdna, "LightProbe", "float", "grid_flag")) {
|
||||
LISTBASE_FOREACH (LightProbe *, lightprobe, &bmain->lightprobes) {
|
||||
/* Keep old behavior of baking the whole lighting. */
|
||||
|
@ -711,4 +750,18 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Versioning code until next subversion bump goes here.
|
||||
*
|
||||
* \note Be sure to check when bumping the version:
|
||||
* - #do_versions_after_linking_400 in this file.
|
||||
* - `versioning_userdef.cc`, #blo_do_versions_userdef
|
||||
* - `versioning_userdef.cc`, #do_versions_theme
|
||||
*
|
||||
* \note Keep this message at the bottom of the function.
|
||||
*/
|
||||
{
|
||||
/* Keep this block, even when empty. */
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,20 @@
|
|||
.ortho_scale = 6.0, \
|
||||
.flag = CAM_SHOWPASSEPARTOUT, \
|
||||
.passepartalpha = 0.5f, \
|
||||
\
|
||||
.panorama_type = CAM_PANORAMA_FISHEYE_EQUISOLID,\
|
||||
.fisheye_fov = M_PI,\
|
||||
.fisheye_lens = 10.5f,\
|
||||
.latitude_min = -0.5f * (float)M_PI,\
|
||||
.latitude_max = 0.5f * (float)M_PI,\
|
||||
.longitude_min = -M_PI,\
|
||||
.longitude_max = M_PI,\
|
||||
/* Fit to match default projective camera with focal_length 50 and sensor_width 36. */ \
|
||||
.fisheye_polynomial_k0 = -1.1735143712967577e-05f,\
|
||||
fclem marked this conversation as resolved
Outdated
Weizhen Huang
commented
There should be a There should be a `f` suffix.
~~The default values in `addon/camera.py` can be deleted I think.~~ Turns out that the whole `addon/camera.py` is just for reference and not used. Probably fine to keep the default values there, but maybe refer to the function `fisheye_lens_polynomial_from_projective()` here to make it more clear where these values come from.
|
||||
.fisheye_polynomial_k1 = -0.019988736953434998f,\
|
||||
.fisheye_polynomial_k2 = -3.3525322965709175e-06f,\
|
||||
.fisheye_polynomial_k3 = 3.099275275886036e-06f,\
|
||||
.fisheye_polynomial_k4 = -2.6064646454854524e-08f,\
|
||||
\
|
||||
.dof = _DNA_DEFAULT_CameraDOFSettings, \
|
||||
\
|
||||
|
|
|
@ -91,6 +91,21 @@ typedef struct Camera {
|
|||
float shiftx, shifty;
|
||||
float dof_distance DNA_DEPRECATED;
|
||||
|
||||
char sensor_fit;
|
||||
char panorama_type;
|
||||
char _pad[2];
|
||||
|
||||
/** Fisheye properties. */
|
||||
float fisheye_fov;
|
||||
float fisheye_lens;
|
||||
float latitude_min, latitude_max;
|
||||
float longitude_min, longitude_max;
|
||||
float fisheye_polynomial_k0;
|
||||
float fisheye_polynomial_k1;
|
||||
float fisheye_polynomial_k2;
|
||||
float fisheye_polynomial_k3;
|
||||
float fisheye_polynomial_k4;
|
||||
|
||||
/** Old animation system, deprecated for 2.5. */
|
||||
struct Ipo *ipo DNA_DEPRECATED;
|
||||
|
||||
|
@ -101,9 +116,6 @@ typedef struct Camera {
|
|||
/* CameraBGImage reference images */
|
||||
struct ListBase bg_images;
|
||||
|
||||
char sensor_fit;
|
||||
char _pad[7];
|
||||
|
||||
/* Stereo settings */
|
||||
struct CameraStereoSettings stereo;
|
||||
|
||||
|
@ -120,6 +132,16 @@ enum {
|
|||
CAM_PANO = 2,
|
||||
};
|
||||
|
||||
/* panorama_type */
|
||||
enum {
|
||||
CAM_PANORAMA_EQUIRECTANGULAR = 0,
|
||||
CAM_PANORAMA_FISHEYE_EQUIDISTANT = 1,
|
||||
CAM_PANORAMA_FISHEYE_EQUISOLID = 2,
|
||||
CAM_PANORAMA_MIRRORBALL = 3,
|
||||
CAM_PANORAMA_FISHEYE_LENS_POLYNOMIAL = 4,
|
||||
CAM_PANORAMA_EQUIANGULAR_CUBEMAP_FACE = 5,
|
||||
};
|
||||
|
||||
/* dtx */
|
||||
enum {
|
||||
CAM_DTX_CENTER = (1 << 0),
|
||||
|
|
|
@ -593,6 +593,41 @@ void RNA_def_camera(BlenderRNA *brna)
|
|||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
static const EnumPropertyItem panorama_type_items[] = {
|
||||
{CAM_PANORAMA_EQUIRECTANGULAR,
|
||||
"EQUIRECTANGULAR",
|
||||
0,
|
||||
"Equirectangular",
|
||||
"Spherical camera for environment maps, also known as Lat Long panorama"},
|
||||
{CAM_PANORAMA_EQUIANGULAR_CUBEMAP_FACE,
|
||||
"EQUIANGULAR_CUBEMAP_FACE",
|
||||
0,
|
||||
"Equiangular Cubemap Face",
|
||||
"Single face of an equiangular cubemap"},
|
||||
{CAM_PANORAMA_MIRRORBALL,
|
||||
"MIRRORBALL",
|
||||
0,
|
||||
"Mirror Ball",
|
||||
"Mirror ball mapping for environment maps"},
|
||||
{CAM_PANORAMA_FISHEYE_EQUIDISTANT,
|
||||
"FISHEYE_EQUIDISTANT",
|
||||
0,
|
||||
"Fisheye Equidistant",
|
||||
"Ideal for fulldomes, ignore the sensor dimensions"},
|
||||
{CAM_PANORAMA_FISHEYE_EQUISOLID,
|
||||
"FISHEYE_EQUISOLID",
|
||||
0,
|
||||
"Fisheye Equisolid",
|
||||
"Similar to most fisheye modern lens, takes sensor dimensions into consideration"},
|
||||
{CAM_PANORAMA_FISHEYE_LENS_POLYNOMIAL,
|
||||
"FISHEYE_LENS_POLYNOMIAL",
|
||||
0,
|
||||
"Fisheye Lens Polynomial",
|
||||
"Defines the lens projection as polynomial to allow real world camera lenses to be "
|
||||
"mimicked"},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
srna = RNA_def_struct(brna, "Camera", "ID");
|
||||
RNA_def_struct_ui_text(srna, "Camera", "Camera data-block for storing camera settings");
|
||||
RNA_def_struct_ui_icon(srna, ICON_CAMERA_DATA);
|
||||
|
@ -817,6 +852,75 @@ void RNA_def_camera(BlenderRNA *brna)
|
|||
prop, "Harmonious Triangle B", "Display harmony B composition guide inside the camera view");
|
||||
RNA_def_property_update(prop, NC_CAMERA | ND_DRAW_RENDER_VIEWPORT, nullptr);
|
||||
|
||||
/* Panoramic settings. */
|
||||
prop = RNA_def_property(srna, "panorama_type", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, panorama_type_items);
|
||||
RNA_def_property_ui_text(prop, "Panorama Type", "Distortion to use for the calculation");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update");
|
||||
|
||||
prop = RNA_def_property(srna, "fisheye_fov", PROP_FLOAT, PROP_ANGLE);
|
||||
RNA_def_property_range(prop, 0.1745, 10.0 * M_PI);
|
||||
RNA_def_property_ui_range(prop, 0.1745, 2.0 * M_PI, 3, 2);
|
||||
RNA_def_property_ui_text(prop, "Field of View", "Field of view for the fisheye lens");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update");
|
||||
|
||||
prop = RNA_def_property(srna, "fisheye_lens", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_range(prop, 0.01, 100.0);
|
||||
RNA_def_property_ui_range(prop, 0.01, 15.0, 3, 2);
|
||||
RNA_def_property_ui_text(prop, "Fisheye Lens", "Lens focal length (mm)");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update");
|
||||
|
||||
prop = RNA_def_property(srna, "latitude_min", PROP_FLOAT, PROP_ANGLE);
|
||||
RNA_def_property_range(prop, -0.5 * M_PI, 0.5 * M_PI);
|
||||
RNA_def_property_ui_range(prop, -0.5 * M_PI, 0.5 * M_PI, 3, 2);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Min Latitude", "Minimum latitude (vertical angle) for the equirectangular lens");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update");
|
||||
|
||||
prop = RNA_def_property(srna, "latitude_max", PROP_FLOAT, PROP_ANGLE);
|
||||
RNA_def_property_range(prop, -0.5 * M_PI, 0.5 * M_PI);
|
||||
RNA_def_property_ui_range(prop, -0.5 * M_PI, 0.5 * M_PI, 3, 2);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Max Latitude", "Maximum latitude (vertical angle) for the equirectangular lens");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update");
|
||||
|
||||
prop = RNA_def_property(srna, "longitude_min", PROP_FLOAT, PROP_ANGLE);
|
||||
RNA_def_property_ui_range(prop, -M_PI, M_PI, 3, 2);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Min Longitude", "Minimum longitude (horizontal angle) for the equirectangular lens");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update");
|
||||
|
||||
prop = RNA_def_property(srna, "longitude_max", PROP_FLOAT, PROP_ANGLE);
|
||||
RNA_def_property_ui_range(prop, -M_PI, M_PI, 3, 2);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Max Longitude", "Maximum longitude (horizontal angle) for the equirectangular lens");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update");
|
||||
|
||||
prop = RNA_def_property(srna, "fisheye_polynomial_k0", PROP_FLOAT, PROP_ANGLE);
|
||||
RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 0.1, 6);
|
||||
RNA_def_property_ui_text(prop, "Fisheye Polynomial K0", "Coefficient K0 of the lens polynomial");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update");
|
||||
|
||||
prop = RNA_def_property(srna, "fisheye_polynomial_k1", PROP_FLOAT, PROP_ANGLE);
|
||||
RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 0.1, 6);
|
||||
RNA_def_property_ui_text(prop, "Fisheye Polynomial K1", "Coefficient K1 of the lens polynomial");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update");
|
||||
|
||||
prop = RNA_def_property(srna, "fisheye_polynomial_k2", PROP_FLOAT, PROP_ANGLE);
|
||||
RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 0.1, 6);
|
||||
RNA_def_property_ui_text(prop, "Fisheye Polynomial K2", "Coefficient K2 of the lens polynomial");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update");
|
||||
|
||||
prop = RNA_def_property(srna, "fisheye_polynomial_k3", PROP_FLOAT, PROP_ANGLE);
|
||||
RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 0.1, 6);
|
||||
RNA_def_property_ui_text(prop, "Fisheye Polynomial K3", "Coefficient K3 of the lens polynomial");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update");
|
||||
|
||||
prop = RNA_def_property(srna, "fisheye_polynomial_k4", PROP_FLOAT, PROP_ANGLE);
|
||||
RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 0.1, 6);
|
||||
RNA_def_property_ui_text(prop, "Fisheye Polynomial K4", "Coefficient K4 of the lens polynomial");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update");
|
||||
|
||||
/* pointers */
|
||||
prop = RNA_def_property(srna, "dof", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "CameraDOFSettings");
|
||||
|
|
Don't use
default
, and let compiler to point out at missing cases, to help in the future to who are adding new panorama types.What if you are loading a newer file with a non existing panorama type?
Good point.
Then you move the switch to a function like
blender_panorama_type_to_cycles
, replace assignment withreturn
, and explicitly outside of theswitch
statement returnPANORAMA_EQUIRECTANGULAR
with a comment that it is for the forward compatibility.best of many worlds: