[Bf-blender-cvs] [d225331ac7d] sybren-usd: USD: Added exporting the camera
Sybren A. Stüvel
noreply at git.blender.org
Fri Jul 5 18:11:26 CEST 2019
Commit: d225331ac7d72d87f56e7dc7711702b997fe847a
Author: Sybren A. Stüvel
Date: Fri Jul 5 18:11:04 2019 +0200
Branches: sybren-usd
https://developer.blender.org/rBd225331ac7d72d87f56e7dc7711702b997fe847a
USD: Added exporting the camera
Only perspective cameras are supported for now. I also had to add a function
`BKE_camera_sensor_size_for_render()` that calculates the sensor width
or height, depending on the fitting parameter and the scene render
resolution aspect ratio.
===================================================================
M source/blender/blenkernel/BKE_camera.h
M source/blender/blenkernel/intern/camera.c
M source/blender/usd/CMakeLists.txt
M source/blender/usd/intern/usd_hierarchy_iterator.cc
M source/blender/usd/intern/usd_writer_abstract.cc
M source/blender/usd/intern/usd_writer_abstract.h
A source/blender/usd/intern/usd_writer_camera.cc
A source/blender/usd/intern/usd_writer_camera.h
===================================================================
diff --git a/source/blender/blenkernel/BKE_camera.h b/source/blender/blenkernel/BKE_camera.h
index caed4959eff..b299f6831f5 100644
--- a/source/blender/blenkernel/BKE_camera.h
+++ b/source/blender/blenkernel/BKE_camera.h
@@ -61,6 +61,12 @@ float BKE_camera_object_dof_distance(struct Object *ob);
int BKE_camera_sensor_fit(int sensor_fit, float sizex, float sizey);
float BKE_camera_sensor_size(int sensor_fit, float sensor_x, float sensor_y);
+/* Return the clamped sensor width/height for the given render data. */
+void BKE_camera_sensor_size_for_render(const struct Camera *camera,
+ const struct RenderData *rd,
+ float *r_sensor_x,
+ float *r_sensor_y);
+
/* Camera Parameters:
*
* Intermediate struct for storing camera parameters from various sources,
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index a8f38c3c4ce..deb047d84f5 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -168,6 +168,32 @@ int BKE_camera_sensor_fit(int sensor_fit, float sizex, float sizey)
return sensor_fit;
}
+void BKE_camera_sensor_size_for_render(const Camera *camera,
+ const struct RenderData *rd,
+ float *r_sensor_x,
+ float *r_sensor_y)
+{
+ /* Compute the final image size in pixels. */
+ float sizex = rd->xsch * rd->xasp;
+ float sizey = rd->ysch * rd->yasp;
+
+ int sensor_fit = BKE_camera_sensor_fit(camera->sensor_fit, sizex, sizey);
+
+ switch (sensor_fit) {
+ case CAMERA_SENSOR_FIT_HOR:
+ *r_sensor_x = camera->sensor_x;
+ *r_sensor_y = camera->sensor_x * sizey / sizex;
+ break;
+ case CAMERA_SENSOR_FIT_VERT:
+ *r_sensor_x = camera->sensor_y * sizex / sizey;
+ *r_sensor_y = camera->sensor_y;
+ break;
+ case CAMERA_SENSOR_FIT_AUTO:
+ BLI_assert(!"Camera fit should be either horizontal or vertical");
+ break;
+ }
+}
+
/******************************** Camera Params *******************************/
void BKE_camera_params_init(CameraParams *params)
diff --git a/source/blender/usd/CMakeLists.txt b/source/blender/usd/CMakeLists.txt
index 3694e85e3a2..3c76c95e31c 100644
--- a/source/blender/usd/CMakeLists.txt
+++ b/source/blender/usd/CMakeLists.txt
@@ -51,6 +51,7 @@ set(SRC
intern/usd_capi.cc
intern/usd_hierarchy_iterator.cc
intern/usd_writer_abstract.cc
+ intern/usd_writer_camera.cc
intern/usd_writer_hair.cc
intern/usd_writer_mesh.cc
intern/usd_writer_transform.cc
@@ -59,6 +60,7 @@ set(SRC
intern/abstract_hierarchy_iterator.h
intern/usd_hierarchy_iterator.h
intern/usd_writer_abstract.h
+ intern/usd_writer_camera.h
intern/usd_writer_hair.h
intern/usd_writer_mesh.h
intern/usd_writer_transform.h
diff --git a/source/blender/usd/intern/usd_hierarchy_iterator.cc b/source/blender/usd/intern/usd_hierarchy_iterator.cc
index de10a8e7e44..3cae06536a5 100644
--- a/source/blender/usd/intern/usd_hierarchy_iterator.cc
+++ b/source/blender/usd/intern/usd_hierarchy_iterator.cc
@@ -2,6 +2,7 @@
#include "usd_hierarchy_iterator.h"
#include "usd_writer_abstract.h"
+#include "usd_writer_camera.h"
#include "usd_writer_hair.h"
#include "usd_writer_mesh.h"
#include "usd_writer_transform.h"
@@ -85,6 +86,9 @@ AbstractHierarchyWriter *USDHierarchyIterator::create_data_writer(const Hierarch
case OB_MESH:
data_writer = new USDMeshWriter(usd_export_context);
break;
+ case OB_CAMERA:
+ data_writer = new USDCameraWriter(usd_export_context);
+ break;
case OB_EMPTY:
case OB_CURVE:
@@ -92,7 +96,6 @@ AbstractHierarchyWriter *USDHierarchyIterator::create_data_writer(const Hierarch
case OB_FONT:
case OB_MBALL:
case OB_LAMP:
- case OB_CAMERA:
case OB_SPEAKER:
case OB_LIGHTPROBE:
case OB_LATTICE:
@@ -107,7 +110,7 @@ AbstractHierarchyWriter *USDHierarchyIterator::create_data_writer(const Hierarch
return nullptr;
}
- if (!data_writer->is_supported()) {
+ if (!data_writer->is_supported(context.object)) {
// printf("USD-\033[34mXFORM-ONLY\033[0m object %s type=%d (data writer rejects the data)\n",
// context.object->id.name,
// context.object->type);
diff --git a/source/blender/usd/intern/usd_writer_abstract.cc b/source/blender/usd/intern/usd_writer_abstract.cc
index 793ff7c1ed7..6c2787f7384 100644
--- a/source/blender/usd/intern/usd_writer_abstract.cc
+++ b/source/blender/usd/intern/usd_writer_abstract.cc
@@ -25,7 +25,7 @@ USDAbstractWriter::~USDAbstractWriter()
{
}
-bool USDAbstractWriter::is_supported() const
+bool USDAbstractWriter::is_supported(const Object * /*object*/) const
{
return true;
}
diff --git a/source/blender/usd/intern/usd_writer_abstract.h b/source/blender/usd/intern/usd_writer_abstract.h
index 3e2feb3faf9..667baf0dc43 100644
--- a/source/blender/usd/intern/usd_writer_abstract.h
+++ b/source/blender/usd/intern/usd_writer_abstract.h
@@ -37,7 +37,7 @@ class USDAbstractWriter : public AbstractHierarchyWriter {
/* Returns true iff the data to be written is actually supported. This would, for example, allow
* a hypothetical camera writer accept a perspective camera but reject an orthogonal one. */
- virtual bool is_supported() const;
+ virtual bool is_supported(const Object *object) const;
const pxr::SdfPath &usd_path() const;
diff --git a/source/blender/usd/intern/usd_writer_camera.cc b/source/blender/usd/intern/usd_writer_camera.cc
new file mode 100644
index 00000000000..4fe52deb664
--- /dev/null
+++ b/source/blender/usd/intern/usd_writer_camera.cc
@@ -0,0 +1,61 @@
+#include "usd_writer_camera.h"
+#include "usd_hierarchy_iterator.h"
+
+#include <pxr/usd/usdGeom/camera.h>
+#include <pxr/usd/usdGeom/tokens.h>
+
+extern "C" {
+#include "BKE_camera.h"
+
+#include "DNA_camera_types.h"
+#include "DNA_scene_types.h"
+}
+
+USDCameraWriter::USDCameraWriter(const USDExporterContext &ctx) : USDAbstractWriter(ctx)
+{
+}
+
+bool USDCameraWriter::is_supported(const Object *object) const
+{
+ Camera *camera = static_cast<Camera *>(object->data);
+ return camera->type == CAM_PERSP;
+}
+
+void USDCameraWriter::do_write(HierarchyContext &context)
+{
+ pxr::UsdTimeCode timecode = get_export_time_code();
+ pxr::UsdGeomCamera usd_camera = pxr::UsdGeomCamera::Define(stage, usd_path_);
+
+ Camera *camera = static_cast<Camera *>(context.object->data);
+ Scene *scene = DEG_get_evaluated_scene(depsgraph);
+
+ usd_camera.CreateProjectionAttr().Set(pxr::UsdGeomTokens->perspective);
+
+ /* USD stores the focal length in "millimeters or tenths of world units", because at some point
+ * they decided world units might be centimeters. Quite confusing, as the USD Viewer shows the
+ * correct FoV when we write millimeters and not "tenths of world units".
+ */
+ usd_camera.CreateFocalLengthAttr().Set(camera->lens, timecode);
+
+ float aperture_x, aperture_y;
+ BKE_camera_sensor_size_for_render(camera, &scene->r, &aperture_x, &aperture_y);
+
+ float film_aspect = aperture_x / aperture_y;
+ usd_camera.CreateHorizontalApertureAttr().Set(aperture_x, timecode);
+ usd_camera.CreateVerticalApertureAttr().Set(aperture_y, timecode);
+ usd_camera.CreateHorizontalApertureOffsetAttr().Set(aperture_x * camera->shiftx, timecode);
+ usd_camera.CreateVerticalApertureOffsetAttr().Set(aperture_y * camera->shifty * film_aspect,
+ timecode);
+
+ usd_camera.CreateClippingRangeAttr().Set(
+ pxr::VtValue(pxr::GfVec2f(camera->clip_start, camera->clip_end)), timecode);
+
+ // Write DoF-related attributes.
+ if (camera->dof.flag & CAM_DOF_ENABLED) {
+ usd_camera.CreateFStopAttr().Set(camera->dof.aperture_fstop, timecode);
+
+ float focus_distance = scene->unit.scale_length *
+ BKE_camera_object_dof_distance(context.object);
+ usd_camera.CreateFocusDistanceAttr().Set(focus_distance, timecode);
+ }
+}
diff --git a/source/blender/usd/intern/usd_writer_camera.h b/source/blender/usd/intern/usd_writer_camera.h
new file mode 100644
index 00000000000..b5fb8074c1f
--- /dev/null
+++ b/source/blender/usd/intern/usd_writer_camera.h
@@ -0,0 +1,16 @@
+#ifndef __USD__USD_WRITER_CAMERA_H__
+#define __USD__USD_WRITER_CAMERA_H__
+
+#include "usd_writer_abstract.h"
+
+/* Writer for writing camera data to UsdGeomCamera. */
+class USDCameraWriter : public USDAbstractWriter {
+ public:
+ USDCameraWriter(const USDExporterContext &ctx);
+
+ protected:
+ virtual bool is_supported(const Object *object) const override;
+ virtual void do_write(HierarchyContext &context) override;
+};
+
+#endif /* __USD__USD_WRITER_CAMERA_H__ */
More information about the Bf-blender-cvs
mailing list