1 /*
2  * Copyright 2011-2020 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef __GEOMETRY_H__
18 #define __GEOMETRY_H__
19 
20 #include "graph/node.h"
21 
22 #include "bvh/bvh_params.h"
23 
24 #include "render/attribute.h"
25 
26 #include "util/util_boundbox.h"
27 #include "util/util_set.h"
28 #include "util/util_transform.h"
29 #include "util/util_types.h"
30 #include "util/util_vector.h"
31 
32 CCL_NAMESPACE_BEGIN
33 
34 class BVH;
35 class Device;
36 class DeviceScene;
37 class Mesh;
38 class Progress;
39 class RenderStats;
40 class Scene;
41 class SceneParams;
42 class Shader;
43 class Volume;
44 
45 /* Geometry
46  *
47  * Base class for geometric types like Mesh and Hair. */
48 
49 class Geometry : public Node {
50  public:
51   NODE_ABSTRACT_DECLARE
52 
53   enum Type {
54     MESH,
55     HAIR,
56     VOLUME,
57   };
58 
59   Type type;
60 
61   /* Attributes */
62   AttributeSet attributes;
63 
64   /* Shaders */
65   vector<Shader *> used_shaders;
66 
67   /* Transform */
68   BoundBox bounds;
69   bool transform_applied;
70   bool transform_negative_scaled;
71   Transform transform_normal;
72 
73   /* Motion Blur */
74   uint motion_steps;
75   bool use_motion_blur;
76 
77   /* Maximum number of motion steps supported (due to Embree). */
78   static const uint MAX_MOTION_STEPS = 129;
79 
80   /* BVH */
81   BVH *bvh;
82   size_t attr_map_offset;
83   size_t prim_offset;
84   size_t optix_prim_offset;
85 
86   /* Shader Properties */
87   bool has_volume;         /* Set in the device_update_flags(). */
88   bool has_surface_bssrdf; /* Set in the device_update_flags(). */
89 
90   /* Update Flags */
91   bool need_update;
92   bool need_update_rebuild;
93 
94   /* Constructor/Destructor */
95   explicit Geometry(const NodeType *node_type, const Type type);
96   virtual ~Geometry();
97 
98   /* Geometry */
99   virtual void clear();
100   virtual void compute_bounds() = 0;
101   virtual void apply_transform(const Transform &tfm, const bool apply_to_motion) = 0;
102 
103   /* Attribute Requests */
104   bool need_attribute(Scene *scene, AttributeStandard std);
105   bool need_attribute(Scene *scene, ustring name);
106 
107   /* UDIM */
108   virtual void get_uv_tiles(ustring map, unordered_set<int> &tiles) = 0;
109 
110   /* Convert between normalized -1..1 motion time and index in the
111    * VERTEX_MOTION attribute. */
112   float motion_time(int step) const;
113   int motion_step(float time) const;
114 
115   /* BVH */
116   void compute_bvh(Device *device,
117                    DeviceScene *dscene,
118                    SceneParams *params,
119                    Progress *progress,
120                    int n,
121                    int total);
122 
123   /* Check whether the geometry should have own BVH built separately. Briefly,
124    * own BVH is needed for geometry, if:
125    *
126    * - It is instanced multiple times, so each instance object should share the
127    *   same BVH tree.
128    * - Special ray intersection is needed, for example to limit subsurface rays
129    *   to only the geometry itself.
130    * - The BVH layout requires the top level to only contain instances.
131    */
132   bool need_build_bvh(BVHLayout layout) const;
133 
134   /* Test if the geometry should be treated as instanced. */
135   bool is_instanced() const;
136 
137   bool has_true_displacement() const;
138   bool has_motion_blur() const;
139   bool has_voxel_attributes() const;
140 
141   /* Updates */
142   void tag_update(Scene *scene, bool rebuild);
143 };
144 
145 /* Geometry Manager */
146 
147 class GeometryManager {
148  public:
149   /* Update Flags */
150   bool need_update;
151   bool need_flags_update;
152 
153   /* Constructor/Destructor */
154   GeometryManager();
155   ~GeometryManager();
156 
157   /* Device Updates */
158   void device_update_preprocess(Device *device, Scene *scene, Progress &progress);
159   void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
160   void device_free(Device *device, DeviceScene *dscene);
161 
162   /* Updates */
163   void tag_update(Scene *scene);
164 
165   /* Statistics */
166   void collect_statistics(const Scene *scene, RenderStats *stats);
167 
168  protected:
169   bool displace(Device *device, DeviceScene *dscene, Scene *scene, Mesh *mesh, Progress &progress);
170 
171   void create_volume_mesh(Volume *volume, Progress &progress);
172 
173   /* Attributes */
174   void update_osl_attributes(Device *device,
175                              Scene *scene,
176                              vector<AttributeRequestSet> &geom_attributes);
177   void update_svm_attributes(Device *device,
178                              DeviceScene *dscene,
179                              Scene *scene,
180                              vector<AttributeRequestSet> &geom_attributes);
181 
182   /* Compute verts/triangles/curves offsets in global arrays. */
183   void mesh_calc_offset(Scene *scene);
184 
185   void device_update_object(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
186 
187   void device_update_mesh(Device *device,
188                           DeviceScene *dscene,
189                           Scene *scene,
190                           bool for_displacement,
191                           Progress &progress);
192 
193   void device_update_attributes(Device *device,
194                                 DeviceScene *dscene,
195                                 Scene *scene,
196                                 Progress &progress);
197 
198   void device_update_bvh(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
199 
200   void device_update_displacement_images(Device *device, Scene *scene, Progress &progress);
201 
202   void device_update_volume_images(Device *device, Scene *scene, Progress &progress);
203 };
204 
205 CCL_NAMESPACE_END
206 
207 #endif /* __GEOMETRY_H__ */
208