ClangFormat: apply to source, most of intern
[blender.git] / source / blender / alembic / intern / abc_util.h
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16
17 /** \file
18  * \ingroup balembic
19  */
20
21 #ifndef __ABC_UTIL_H__
22 #define __ABC_UTIL_H__
23
24 #include <Alembic/Abc/All.h>
25 #include <Alembic/AbcGeom/All.h>
26
27 #ifdef _MSC_VER
28 #  define ABC_INLINE static __forceinline
29 #else
30 #  define ABC_INLINE static inline
31 #endif
32
33 /**
34  * \brief The CacheReader struct is only used for anonymous pointers,
35  * to interface between C and C++ code. This library only creates
36  * pointers to AbcObjectReader (or subclasses thereof).
37  */
38 struct CacheReader {
39   int unused;
40 };
41
42 using Alembic::Abc::chrono_t;
43
44 class AbcObjectReader;
45 struct ImportSettings;
46
47 struct Base;
48 struct ID;
49 struct Object;
50
51 std::string get_id_name(const ID *const id);
52 std::string get_id_name(const Object *const ob);
53 std::string get_object_dag_path_name(const Object *const ob, Object *dupli_parent);
54
55 Imath::M44d convert_matrix(float mat[4][4]);
56
57 typedef enum {
58   ABC_MATRIX_WORLD = 1,
59   ABC_MATRIX_LOCAL = 2,
60 } AbcMatrixMode;
61 void create_transform_matrix(Object *obj,
62                              float r_transform_mat[4][4],
63                              AbcMatrixMode mode,
64                              Object *proxy_from);
65
66 void split(const std::string &s, const char delim, std::vector<std::string> &tokens);
67
68 template<class TContainer> bool begins_with(const TContainer &input, const TContainer &match)
69 {
70   return input.size() >= match.size() && std::equal(match.begin(), match.end(), input.begin());
71 }
72
73 void convert_matrix(const Imath::M44d &xform, Object *ob, float r_mat[4][4]);
74
75 template<typename Schema>
76 void get_min_max_time_ex(const Schema &schema, chrono_t &min, chrono_t &max)
77 {
78   const Alembic::Abc::TimeSamplingPtr &time_samp = schema.getTimeSampling();
79
80   if (!schema.isConstant()) {
81     const size_t num_samps = schema.getNumSamples();
82
83     if (num_samps > 0) {
84       const chrono_t min_time = time_samp->getSampleTime(0);
85       min = std::min(min, min_time);
86
87       const chrono_t max_time = time_samp->getSampleTime(num_samps - 1);
88       max = std::max(max, max_time);
89     }
90   }
91 }
92
93 template<typename Schema>
94 void get_min_max_time(const Alembic::AbcGeom::IObject &object,
95                       const Schema &schema,
96                       chrono_t &min,
97                       chrono_t &max)
98 {
99   get_min_max_time_ex(schema, min, max);
100
101   const Alembic::AbcGeom::IObject &parent = object.getParent();
102   if (parent.valid() && Alembic::AbcGeom::IXform::matches(parent.getMetaData())) {
103     Alembic::AbcGeom::IXform xform(parent, Alembic::AbcGeom::kWrapExisting);
104     get_min_max_time_ex(xform.getSchema(), min, max);
105   }
106 }
107
108 bool has_property(const Alembic::Abc::ICompoundProperty &prop, const std::string &name);
109
110 float get_weight_and_index(float time,
111                            const Alembic::AbcCoreAbstract::TimeSamplingPtr &time_sampling,
112                            int samples_number,
113                            Alembic::AbcGeom::index_t &i0,
114                            Alembic::AbcGeom::index_t &i1);
115
116 AbcObjectReader *create_reader(const Alembic::AbcGeom::IObject &object, ImportSettings &settings);
117
118 /* ************************** */
119
120 /* TODO(kevin): for now keeping these transformations hardcoded to make sure
121  * everything works properly, and also because Alembic is almost exclusively
122  * used in Y-up software, but eventually they'll be set by the user in the UI
123  * like other importers/exporters do, to support other axis. */
124
125 /* Copy from Y-up to Z-up. */
126
127 ABC_INLINE void copy_zup_from_yup(float zup[3], const float yup[3])
128 {
129   const float old_yup1 = yup[1]; /* in case zup == yup */
130   zup[0] = yup[0];
131   zup[1] = -yup[2];
132   zup[2] = old_yup1;
133 }
134
135 ABC_INLINE void copy_zup_from_yup(short zup[3], const short yup[3])
136 {
137   const short old_yup1 = yup[1]; /* in case zup == yup */
138   zup[0] = yup[0];
139   zup[1] = -yup[2];
140   zup[2] = old_yup1;
141 }
142
143 /* Copy from Z-up to Y-up. */
144
145 ABC_INLINE void copy_yup_from_zup(float yup[3], const float zup[3])
146 {
147   const float old_zup1 = zup[1]; /* in case yup == zup */
148   yup[0] = zup[0];
149   yup[1] = zup[2];
150   yup[2] = -old_zup1;
151 }
152
153 ABC_INLINE void copy_yup_from_zup(short yup[3], const short zup[3])
154 {
155   const short old_zup1 = zup[1]; /* in case yup == zup */
156   yup[0] = zup[0];
157   yup[1] = zup[2];
158   yup[2] = -old_zup1;
159 }
160
161 /* Names are given in (dst, src) order, just like
162  * the parameters of copy_m44_axis_swap() */
163 typedef enum {
164   ABC_ZUP_FROM_YUP = 1,
165   ABC_YUP_FROM_ZUP = 2,
166 } AbcAxisSwapMode;
167
168 /* Create a rotation matrix for each axis from euler angles.
169  * Euler angles are swapped to change coordinate system. */
170 void create_swapped_rotation_matrix(float rot_x_mat[3][3],
171                                     float rot_y_mat[3][3],
172                                     float rot_z_mat[3][3],
173                                     const float euler[3],
174                                     AbcAxisSwapMode mode);
175
176 void copy_m44_axis_swap(float dst_mat[4][4], float src_mat[4][4], AbcAxisSwapMode mode);
177
178 /* *************************** */
179
180 #undef ABC_DEBUG_TIME
181
182 class ScopeTimer {
183   const char *m_message;
184   double m_start;
185
186  public:
187   ScopeTimer(const char *message);
188   ~ScopeTimer();
189 };
190
191 #ifdef ABC_DEBUG_TIME
192 #  define SCOPE_TIMER(message) ScopeTimer prof(message)
193 #else
194 #  define SCOPE_TIMER(message)
195 #endif
196
197 /* *************************** */
198
199 /**
200  * Utility class whose purpose is to more easily log related information. An
201  * instance of the SimpleLogger can be created in any context, and will hold a
202  * copy of all the strings passed to its output stream.
203  *
204  * Different instances of the class may be accessed from different threads,
205  * although accessing the same instance from different threads will lead to race
206  * conditions.
207  */
208 class SimpleLogger {
209   std::ostringstream m_stream;
210
211  public:
212   /**
213    * Check whether or not the SimpleLogger's stream is empty.
214    */
215   bool empty();
216
217   /**
218    * Return a copy of the string contained in the SimpleLogger's stream.
219    */
220   std::string str() const;
221
222   /**
223    * Remove the bits set on the SimpleLogger's stream and clear its string.
224    */
225   void clear();
226
227   /**
228    * Return a reference to the SimpleLogger's stream, in order to e.g. push
229    * content into it.
230    */
231   std::ostringstream &stream();
232 };
233
234 #define ABC_LOG(logger) logger.stream()
235
236 /**
237  * Pass the content of the logger's stream to the specified std::ostream.
238  */
239 std::ostream &operator<<(std::ostream &os, const SimpleLogger &logger);
240
241 #endif /* __ABC_UTIL_H__ */