23#include <pxr/usd/usdGeom/camera.h>
32template<
typename T>
struct SampleData {
37template<
typename T>
struct AttributeData {
38 std::optional<T> initial_value = std::nullopt;
39 Vector<SampleData<T>> samples;
43 initial_value = std::nullopt;
49bool read_attribute_values(
const pxr::UsdAttribute &attr,
50 const pxr::UsdTimeCode initial_time,
51 AttributeData<T> &
data)
56 if (attr.Get(&value, initial_time)) {
57 data.initial_value = value;
60 data.initial_value = std::nullopt;
63 if (attr.ValueMightBeTimeVarying()) {
64 std::vector<double> times;
65 attr.GetTimeSamples(×);
67 data.samples.resize(times.size());
70 attr.Get(&
data.samples[
i].value, times[
i]);
74 return data.initial_value.has_value() || !
data.samples.is_empty();
77void read_aperture_data(
Camera *camera,
78 const pxr::UsdAttribute &usd_horiz_aperture,
79 const pxr::UsdAttribute &usd_vert_aperture,
80 const pxr::UsdAttribute &usd_horiz_offset,
81 const pxr::UsdAttribute &usd_vert_offset,
82 const pxr::UsdTimeCode initial_time,
83 const double tenth_unit_to_millimeters,
84 animrig::Channelbag &channelbag)
88 if (usd_horiz_aperture.ValueMightBeTimeVarying() || usd_vert_aperture.ValueMightBeTimeVarying())
90 std::vector<double> times;
91 pxr::UsdAttribute::GetUnionedTimeSamples(
92 {usd_horiz_aperture, usd_vert_aperture, usd_horiz_offset, usd_vert_offset}, ×);
94 std::array<FCurve *, 5> curves = {
96 create_fcurve(channelbag, {
"sensor_height", 0}, times.size()),
102 const double time = times[
i];
104 float horiz_aperture, vert_aperture;
105 float shift_x, shift_y;
106 usd_horiz_aperture.Get(&horiz_aperture, time);
107 usd_vert_aperture.Get(&vert_aperture, time);
108 usd_horiz_offset.Get(&shift_x, time);
109 usd_vert_offset.Get(&shift_y, time);
111 const float sensor_x = horiz_aperture * tenth_unit_to_millimeters;
112 const float sensor_y = vert_aperture * tenth_unit_to_millimeters;
116 const float sensor_size = sensor_x >= sensor_y ? sensor_x : sensor_y;
117 shift_x = (shift_x * tenth_unit_to_millimeters) / sensor_size;
118 shift_y = (shift_y * tenth_unit_to_millimeters) / sensor_size;
127 else if (usd_horiz_offset.ValueMightBeTimeVarying() || usd_vert_offset.ValueMightBeTimeVarying())
131 float horiz_aperture, vert_aperture;
132 usd_horiz_aperture.Get(&horiz_aperture, initial_time);
133 usd_vert_aperture.Get(&vert_aperture, initial_time);
135 camera->
sensor_x = horiz_aperture * tenth_unit_to_millimeters;
136 camera->
sensor_y = vert_aperture * tenth_unit_to_millimeters;
142 std::vector<double> times;
143 if (usd_horiz_offset.GetTimeSamples(×)) {
146 const double time = times[
i];
148 usd_horiz_offset.Get(&shift, time);
150 shift = (shift * tenth_unit_to_millimeters) / sensor_size;
155 if (usd_vert_offset.GetTimeSamples(×)) {
158 const double time = times[
i];
160 usd_vert_offset.Get(&shift, time);
162 shift = (shift * tenth_unit_to_millimeters) / sensor_size;
169 float horiz_aperture, vert_aperture;
170 float shift_x, shift_y;
171 usd_horiz_aperture.Get(&horiz_aperture, initial_time);
172 usd_vert_aperture.Get(&vert_aperture, initial_time);
173 usd_horiz_offset.Get(&shift_x, initial_time);
174 usd_vert_offset.Get(&shift_y, initial_time);
176 camera->
sensor_x = horiz_aperture * tenth_unit_to_millimeters;
177 camera->
sensor_y = vert_aperture * tenth_unit_to_millimeters;
182 camera->
shiftx = (shift_x * tenth_unit_to_millimeters) / sensor_size;
183 camera->
shifty = (shift_y * tenth_unit_to_millimeters) / sensor_size;
199 pxr::UsdAttribute usd_focal_length = cam_prim_.GetFocalLengthAttr();
200 pxr::UsdAttribute usd_focus_dist = cam_prim_.GetFocusDistanceAttr();
201 pxr::UsdAttribute usd_fstop = cam_prim_.GetFStopAttr();
202 pxr::UsdAttribute usd_clipping_range = cam_prim_.GetClippingRangeAttr();
203 pxr::UsdAttribute usd_horiz_aperture = cam_prim_.GetHorizontalApertureAttr();
204 pxr::UsdAttribute usd_vert_aperture = cam_prim_.GetVerticalApertureAttr();
205 pxr::UsdAttribute usd_horiz_offset = cam_prim_.GetHorizontalApertureOffsetAttr();
206 pxr::UsdAttribute usd_vert_offset = cam_prim_.GetVerticalApertureOffsetAttr();
209 const bool is_time_varying = usd_focal_length.ValueMightBeTimeVarying() ||
210 usd_focus_dist.ValueMightBeTimeVarying() ||
211 usd_fstop.ValueMightBeTimeVarying() ||
212 usd_clipping_range.ValueMightBeTimeVarying() ||
213 usd_horiz_aperture.ValueMightBeTimeVarying() ||
214 usd_vert_aperture.ValueMightBeTimeVarying() ||
215 usd_horiz_offset.ValueMightBeTimeVarying() ||
216 usd_vert_offset.ValueMightBeTimeVarying();
221 if (is_time_varying) {
238 const double tenth_unit_to_millimeters = 100.0 *
settings_->stage_meters_per_unit;
239 auto scale_default = [](std::optional<float>
input,
double scale,
float default_value) {
240 return input.has_value() ?
input.value() * scale : default_value;
243 AttributeData<float>
data;
244 if (read_attribute_values(usd_focal_length, time,
data)) {
245 camera->
lens = scale_default(
data.initial_value, tenth_unit_to_millimeters, camera->
lens);
247 if (!
data.samples.is_empty()) {
256 if (read_attribute_values(usd_focus_dist, time,
data)) {
260 if (!
data.samples.is_empty()) {
272 if (read_attribute_values(usd_fstop, time,
data)) {
276 if (!
data.samples.is_empty()) {
281 const bool use_dof =
sample.value != 0.0f;
288 AttributeData<pxr::GfVec2f> clip_data;
289 if (read_attribute_values(usd_clipping_range, time, clip_data)) {
290 auto clamp_clip = [
this](pxr::GfVec2f value) {
296 pxr::GfVec2f clip_range = clip_data.initial_value.has_value() ?
297 clamp_clip(clip_data.initial_value.value()) :
302 if (!clip_data.samples.is_empty()) {
303 std::array<FCurve *, 2> curves = {
304 create_fcurve(channelbag, {
"clip_start", 0}, clip_data.samples.size()),
305 create_fcurve(channelbag, {
"clip_end", 0}, clip_data.samples.size())};
307 for (
int64_t i = 0;
i < clip_data.samples.size();
i++) {
308 const SampleData<pxr::GfVec2f> &
sample = clip_data.samples[
i];
309 clip_range = clamp_clip(
sample.value);
317 read_aperture_data(camera,
323 tenth_unit_to_millimeters,
328 pxr::TfToken projection;
329 cam_prim_.GetProjectionAttr().Get(&projection, time);
332 float horiz_aperture, vert_aperture;
333 usd_horiz_aperture.Get(&horiz_aperture, time);
334 usd_vert_aperture.Get(&vert_aperture, time);
Functions and classes to work with Actions.
Functions to work with AnimData.
Camera data-block and utility functions.
struct Camera * BKE_camera_add(struct Main *bmain, const char *name)
void BKE_fcurve_handles_recalc(FCurve *fcu)
General operations, lookup, etc. for blender objects.
Object * BKE_object_add_only_object(Main *bmain, int type, const char *name) ATTR_RETURNS_NONNULL
MINLINE float max_ff(float a, float b)
Object is a sort of wrapper for general info.
BMesh const char void * data
void reset()
clear internal cached data and reset random seed
blender::Span< const FCurve * > fcurves() const
void read_object_data(Main *bmain, pxr::UsdTimeCode time) override
void create_object(Main *bmain) override
const ImportSettings * settings_
bAction * id_action_ensure(Main *bmain, ID *id)
Channelbag & action_channelbag_ensure(bAction &dna_action, ID &animated_id)
void set_fcurve_sample(FCurve *fcu, int64_t sample_index, const float frame, const float value)
FCurve * create_fcurve(blender::animrig::Channelbag &channelbag, const blender::animrig::FCurveDescriptor &fcurve_descriptor, const int sample_count)
struct CameraDOFSettings dof