Improve USD camera import/export and round-tripping #112905

Merged
Brecht Van Lommel merged 3 commits from dkvnyc/blender:feature/CameraUSDRoundtripFixes into blender-v4.0-release 2023-10-05 19:47:19 +02:00
3 changed files with 24 additions and 17 deletions
Showing only changes of commit 1461b1fc3a - Show all commits

View File

@ -70,17 +70,18 @@ void USDCameraReader::read_object_data(Main *bmain, const double motionSampleTim
bcam->sensor_x = horAp.Get<float>() * tenth_unit_to_millimeters;
bcam->sensor_y = verAp.Get<float>() * tenth_unit_to_millimeters;
bcam->sensor_fit = bcam->sensor_x >= bcam->sensor_y ? CAMERA_SENSOR_FIT_HOR : CAMERA_SENSOR_FIT_VERT;
bcam->sensor_fit = bcam->sensor_x >= bcam->sensor_y ? CAMERA_SENSOR_FIT_HOR :
CAMERA_SENSOR_FIT_VERT;
float sensor_size = bcam->sensor_x >= bcam->sensor_y ? bcam->sensor_x : bcam->sensor_y;
bcam->shiftx = (horApOffset.Get<float>() * tenth_unit_to_millimeters) / sensor_size;
bcam->shifty = (verApOffset.Get<float>() * tenth_unit_to_millimeters) / sensor_size;
bcam->shiftx = (horApOffset.Get<float>() * tenth_unit_to_millimeters) / sensor_size;
bcam->shifty = (verApOffset.Get<float>() * tenth_unit_to_millimeters) / sensor_size;
bcam->type = (projectionVal.Get<pxr::TfToken>().GetString() == "perspective") ? CAM_PERSP :
CAM_ORTHO;
/* Calling UncheckedGet() to silence compiler warnings. */
bcam->clip_start = max_ff(1e-6f, clippingRangeVal.UncheckedGet<pxr::GfVec2f>()[0]); // see rna_camera.cc, "clip_start": RNA_def_property_range(prop, 1e-6f, FLT_MAX)
/* Call UncheckedGet() to silence compiler warnings.
* Clamp to 1e-6 matching range defined in RNA. */
bcam->clip_end = clippingRangeVal.UncheckedGet<pxr::GfVec2f>()[1];
bcam->dof.focus_distance = focalDistanceVal.Get<float>();

View File

@ -34,7 +34,8 @@ static void camera_sensor_size_for_render(const Camera *camera,
float sizey = rd->ysch * rd->yasp;
int sensor_fit = BKE_camera_sensor_fit(camera->sensor_fit, sizex, sizey);
float sensor_size = BKE_camera_sensor_size(camera->sensor_fit, camera->sensor_x, camera->sensor_y);
float sensor_size = BKE_camera_sensor_size(
camera->sensor_fit, camera->sensor_x, camera->sensor_y);
*r_sensor = sensor_size;
switch (sensor_fit) {
@ -63,11 +64,14 @@ void USDCameraWriter::do_write(HierarchyContext &context)
usd_camera.CreateProjectionAttr().Set(pxr::UsdGeomTokens->perspective);
/*
* tenth_unit_to_meters = stage_meters_per_unit / 10
* tenth_unit_to_millimeters = 1000 * unit_to_tenth_unit
* = 100 * stage_meters_per_unit
*/
/*
* For USD, these camera properties are in tenths of a world unit.
* https://graphics.pixar.com/usd/release/api/class_usd_geom_camera.html#UsdGeom_CameraUnits
*
* tenth_unit_to_meters = stage_meters_per_unit / 10
* tenth_unit_to_millimeters = 1000 * unit_to_tenth_unit
* = 100 * stage_meters_per_unit
*/
const float tenth_unit_to_mm = 100.0f * scene->unit.scale_length;
float sensor_size, aperture_x, aperture_y;
@ -76,8 +80,10 @@ void USDCameraWriter::do_write(HierarchyContext &context)
usd_camera.CreateFocalLengthAttr().Set(camera->lens / tenth_unit_to_mm, timecode);
usd_camera.CreateHorizontalApertureAttr().Set(aperture_x / tenth_unit_to_mm, timecode);
usd_camera.CreateVerticalApertureAttr().Set(aperture_y / tenth_unit_to_mm, timecode);
usd_camera.CreateHorizontalApertureOffsetAttr().Set(sensor_size * camera->shiftx / tenth_unit_to_mm, timecode);
usd_camera.CreateVerticalApertureOffsetAttr().Set(sensor_size * camera->shifty / tenth_unit_to_mm, timecode);
usd_camera.CreateHorizontalApertureOffsetAttr().Set(
sensor_size * camera->shiftx / tenth_unit_to_mm, timecode);
usd_camera.CreateVerticalApertureOffsetAttr().Set(
sensor_size * camera->shifty / tenth_unit_to_mm, timecode);
usd_camera.CreateClippingRangeAttr().Set(
pxr::VtValue(pxr::GfVec2f(camera->clip_start, camera->clip_end)), timecode);

View File

@ -183,8 +183,8 @@ class USDImportTest(AbstractUSDTest):
self.assertAlmostEqual(43.12, test_cam.lens, 2)
self.assertAlmostEqual(24.89, test_cam.sensor_width, 2)
self.assertAlmostEqual(14.00, test_cam.sensor_height, 2)
self.assertAlmostEqual(12.34, test_cam.shift_x, 2)
self.assertAlmostEqual(56.78, test_cam.shift_y, 2)
self.assertAlmostEqual(2.281, test_cam.shift_x, 2)
self.assertAlmostEqual(0.496, test_cam.shift_y, 2)
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()
@ -200,8 +200,8 @@ class USDImportTest(AbstractUSDTest):
self.assertAlmostEqual(4.312, test_cam.lens, 3)
self.assertAlmostEqual(2.489, test_cam.sensor_width, 3)
self.assertAlmostEqual(1.400, test_cam.sensor_height, 3)
self.assertAlmostEqual(1.234, test_cam.shift_x, 3)
self.assertAlmostEqual(5.678, test_cam.shift_y, 3)
self.assertAlmostEqual(2.281, test_cam.shift_x, 3)
self.assertAlmostEqual(0.496, test_cam.shift_y, 3)
def test_import_shader_varname_with_connection(self):
"""Test importing USD shader where uv primvar is a connection"""