Welcome to mirror list, hosted at ThFree Co, Russian Federation.

COM_BokehImageOperation.h « operations « compositor « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 28506ba36b51235a2e77c594cf1ee10e42a9c378 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/* SPDX-License-Identifier: GPL-2.0-or-later
 * Copyright 2011 Blender Foundation. */

#pragma once

#include "COM_MultiThreadedOperation.h"

namespace blender::compositor {

/**
 * \brief The BokehImageOperation class is an operation that creates an image useful to mimic the
 *internals of a camera.
 *
 * features:
 *  - number of flaps
 *  - angle offset of the flaps
 *  - rounding of the flaps (also used to make a circular lens)
 *  - simulate catadioptric
 *  - simulate lens-shift
 *
 * Per pixel the algorithm determines the edge of the bokeh on the same line as the center of the
 *image and the pixel is evaluating.
 *
 * The edge is detected by finding the closest point on the direct line between the two nearest
 *flap-corners. this edge is interpolated with a full circle. Result of this edge detection is
 *stored as the distance between the center of the image and the edge.
 *
 * catadioptric lenses are simulated to interpolate between the center of the image and the
 *distance of the edge. We now have three distances:
 *  - distance between the center of the image and the pixel to be evaluated
 *  - distance between the center of the image and the outer-edge
 *  - distance between the center of the image and the inner-edge
 *
 * With a simple compare it can be detected if the evaluated pixel is between the outer and inner
 *edge.
 */
class BokehImageOperation : public MultiThreadedOperation {
 private:
  /**
   * \brief Settings of the bokeh image
   */
  const NodeBokehImage *data_;

  /**
   * \brief precalculate center of the image
   */
  float center_[2];

  /**
   * \brief 1.0-rounding
   */
  float inverse_rounding_;

  /**
   * \brief distance of a full circle lens
   */
  float circular_distance_;

  /**
   * \brief radius when the first flap starts
   */
  float flap_rad_;

  /**
   * \brief radians of a single flap
   */
  float flap_rad_add_;

  /**
   * \brief should the data_ field by deleted when this operation is finished
   */
  bool delete_data_;

  /**
   * \brief determine the coordinate of a flap corner.
   *
   * \param r: result in bokeh-image space are stored [x,y]
   * \param flap_number: the flap number to calculate
   * \param distance: the lens distance is used to simulate lens shifts
   */
  void detemine_start_point_of_flap(float r[2], int flap_number, float distance);

  /**
   * \brief Determine if a coordinate is inside the bokeh image
   *
   * \param distance: the distance that will be used.
   * This parameter is modified a bit to mimic lens shifts.
   * \param x: the x coordinate of the pixel to evaluate
   * \param y: the y coordinate of the pixel to evaluate
   * \return float range 0..1 0 is completely outside
   */
  float is_inside_bokeh(float distance, float x, float y);

 public:
  BokehImageOperation();

  /**
   * \brief The inner loop of this operation.
   */
  void execute_pixel_sampled(float output[4], float x, float y, PixelSampler sampler) override;

  /**
   * \brief Initialize the execution
   */
  void init_execution() override;

  /**
   * \brief Deinitialize the execution
   */
  void deinit_execution() override;

  /**
   * \brief determine the resolution of this operation. currently fixed at [COM_BLUR_BOKEH_PIXELS,
   * COM_BLUR_BOKEH_PIXELS] \param resolution: \param preferred_resolution:
   */
  void determine_canvas(const rcti &preferred_area, rcti &r_area) override;

  /**
   * \brief set the node data
   * \param data:
   */
  void set_data(const NodeBokehImage *data)
  {
    data_ = data;
  }

  /**
   * \brief delete_data_on_finish
   *
   * There are cases that the compositor uses this operation on its own (see defocus node)
   * the delete_data_on_finish must only be called when the data has been created by the
   *compositor. It should not be called when the data has been created by the node-editor/user.
   */
  void delete_data_on_finish()
  {
    delete_data_ = true;
  }

  void update_memory_buffer_partial(MemoryBuffer *output,
                                    const rcti &area,
                                    Span<MemoryBuffer *> inputs) override;
};

}  // namespace blender::compositor