Blender  V2.93
abc_util.cc
Go to the documentation of this file.
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 
21 #include "abc_util.h"
22 
23 #include "abc_axis_conversion.h"
24 #include "abc_reader_camera.h"
25 #include "abc_reader_curves.h"
26 #include "abc_reader_mesh.h"
27 #include "abc_reader_nurbs.h"
28 #include "abc_reader_points.h"
29 #include "abc_reader_transform.h"
30 
31 #include <Alembic/AbcMaterial/IMaterial.h>
32 
33 #include <algorithm>
34 
35 #include "DNA_object_types.h"
36 
37 #include "BLI_math_geom.h"
38 
39 #include "PIL_time.h"
40 
41 namespace blender::io::alembic {
42 
43 std::string get_id_name(const Object *const ob)
44 {
45  if (!ob) {
46  return "";
47  }
48 
49  return get_id_name(&ob->id);
50 }
51 
52 std::string get_id_name(const ID *const id)
53 {
54  return get_valid_abc_name(id->name + 2);
55 }
56 
57 std::string get_valid_abc_name(const char *name)
58 {
59  std::string name_string(name);
60  std::replace(name_string.begin(), name_string.end(), ' ', '_');
61  std::replace(name_string.begin(), name_string.end(), '.', '_');
62  std::replace(name_string.begin(), name_string.end(), ':', '_');
63  return name_string;
64 }
65 
75 std::string get_object_dag_path_name(const Object *const ob, Object *dupli_parent)
76 {
77  std::string name = get_id_name(ob);
78 
79  Object *p = ob->parent;
80 
81  while (p) {
82  name = get_id_name(p) + "/" + name;
83  p = p->parent;
84  }
85 
86  if (dupli_parent && (ob != dupli_parent)) {
87  name = get_id_name(dupli_parent) + "/" + name;
88  }
89 
90  return name;
91 }
92 
93 Imath::M44d convert_matrix_datatype(float mat[4][4])
94 {
95  Imath::M44d m;
96 
97  for (int i = 0; i < 4; i++) {
98  for (int j = 0; j < 4; j++) {
99  m[i][j] = mat[i][j];
100  }
101  }
102 
103  return m;
104 }
105 
106 void convert_matrix_datatype(const Imath::M44d &xform, float r_mat[4][4])
107 {
108  for (int i = 0; i < 4; i++) {
109  for (int j = 0; j < 4; j++) {
110  r_mat[i][j] = static_cast<float>(xform[i][j]);
111  }
112  }
113 }
114 
115 void split(const std::string &s, const char delim, std::vector<std::string> &tokens)
116 {
117  tokens.clear();
118 
119  std::stringstream ss(s);
120  std::string item;
121 
122  while (std::getline(ss, item, delim)) {
123  if (!item.empty()) {
124  tokens.push_back(item);
125  }
126  }
127 }
128 
129 bool has_property(const Alembic::Abc::ICompoundProperty &prop, const std::string &name)
130 {
131  if (!prop.valid()) {
132  return false;
133  }
134 
135  return prop.getPropertyHeader(name) != nullptr;
136 }
137 
138 using index_time_pair_t = std::pair<Alembic::AbcCoreAbstract::index_t, float>;
139 
141  const Alembic::AbcCoreAbstract::TimeSamplingPtr &time_sampling,
142  int samples_number,
143  Alembic::AbcGeom::index_t &i0,
144  Alembic::AbcGeom::index_t &i1)
145 {
146  samples_number = std::max(samples_number, 1);
147 
148  index_time_pair_t t0 = time_sampling->getFloorIndex(time, samples_number);
149  i0 = i1 = t0.first;
150 
151  if (samples_number == 1 || (fabs(time - t0.second) < 0.0001f)) {
152  return 0.0f;
153  }
154 
155  index_time_pair_t t1 = time_sampling->getCeilIndex(time, samples_number);
156  i1 = t1.first;
157 
158  if (i0 == i1) {
159  return 0.0f;
160  }
161 
162  const float bias = (time - t0.second) / (t1.second - t0.second);
163 
164  if (fabs(1.0f - bias) < 0.0001f) {
165  i0 = i1;
166  return 0.0f;
167  }
168 
169  return bias;
170 }
171 
172 //#define USE_NURBS
173 
174 AbcObjectReader *create_reader(const Alembic::AbcGeom::IObject &object, ImportSettings &settings)
175 {
176  AbcObjectReader *reader = nullptr;
177 
178  const Alembic::AbcGeom::MetaData &md = object.getMetaData();
179 
180  if (Alembic::AbcGeom::IXform::matches(md)) {
181  reader = new AbcEmptyReader(object, settings);
182  }
183  else if (Alembic::AbcGeom::IPolyMesh::matches(md)) {
184  reader = new AbcMeshReader(object, settings);
185  }
186  else if (Alembic::AbcGeom::ISubD::matches(md)) {
187  reader = new AbcSubDReader(object, settings);
188  }
189  else if (Alembic::AbcGeom::INuPatch::matches(md)) {
190 #ifdef USE_NURBS
191  /* TODO(kevin): importing cyclic NURBS from other software crashes
192  * at the moment. This is due to the fact that NURBS in other
193  * software have duplicated points which causes buffer overflows in
194  * Blender. Need to figure out exactly how these points are
195  * duplicated, in all cases (cyclic U, cyclic V, and cyclic UV).
196  * Until this is fixed, disabling NURBS reading. */
197  reader = new AbcNurbsReader(child, settings);
198 #endif
199  }
200  else if (Alembic::AbcGeom::ICamera::matches(md)) {
201  reader = new AbcCameraReader(object, settings);
202  }
203  else if (Alembic::AbcGeom::IPoints::matches(md)) {
204  reader = new AbcPointsReader(object, settings);
205  }
206  else if (Alembic::AbcMaterial::IMaterial::matches(md)) {
207  /* Pass for now. */
208  }
209  else if (Alembic::AbcGeom::ILight::matches(md)) {
210  /* Pass for now. */
211  }
212  else if (Alembic::AbcGeom::IFaceSet::matches(md)) {
213  /* Pass, those are handled in the mesh reader. */
214  }
215  else if (Alembic::AbcGeom::ICurves::matches(md)) {
216  reader = new AbcCurveReader(object, settings);
217  }
218  else {
219  std::cerr << "Alembic: unknown how to handle objects of schema '" << md.get("schemaObjTitle")
220  << "', skipping object '" << object.getFullName() << "'" << std::endl;
221  }
222 
223  return reader;
224 }
225 
226 /* ********************** */
227 
228 ScopeTimer::ScopeTimer(const char *message)
229  : m_message(message), m_start(PIL_check_seconds_timer())
230 {
231 }
232 
234 {
235  fprintf(stderr, "%s: %fs\n", m_message, PIL_check_seconds_timer() - m_start);
236 }
237 
238 /* ********************** */
239 
240 std::string SimpleLogger::str() const
241 {
242  return m_stream.str();
243 }
244 
246 {
247  m_stream.clear();
248  m_stream.str("");
249 }
250 
251 std::ostringstream &SimpleLogger::stream()
252 {
253  return m_stream;
254 }
255 
256 std::ostream &operator<<(std::ostream &os, const SimpleLogger &logger)
257 {
258  os << logger.str();
259  return os;
260 }
261 
262 } // namespace blender::io::alembic
Object is a sort of wrapper for general info.
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint i1
Platform independent time functions.
ScopeTimer(const char *message)
Definition: abc_util.cc:228
std::ostringstream & stream()
Definition: abc_util.cc:251
double time
static void get_weight_and_index(CDStreamConfig &config, Alembic::AbcCoreAbstract::TimeSamplingPtr time_sampling, size_t samples_number)
std::string get_valid_abc_name(const char *name)
Definition: abc_util.cc:57
std::ostream & operator<<(std::ostream &os, const SimpleLogger &logger)
Definition: abc_util.cc:256
std::string get_object_dag_path_name(const Object *const ob, Object *dupli_parent)
get_object_dag_path_name returns the name under which the object will be exported in the Alembic file...
Definition: abc_util.cc:75
std::string get_id_name(const Object *const ob)
Definition: abc_util.cc:43
Imath::M44d convert_matrix_datatype(float mat[4][4])
Definition: abc_util.cc:93
bool has_property(const Alembic::Abc::ICompoundProperty &prop, const std::string &name)
Definition: abc_util.cc:129
AbcObjectReader * create_reader(const Alembic::AbcGeom::IObject &object, ImportSettings &settings)
Definition: abc_util.cc:174
std::pair< Alembic::AbcCoreAbstract::index_t, float > index_time_pair_t
Definition: abc_util.cc:138
void split(const std::string &s, const char delim, std::vector< std::string > &tokens)
Definition: abc_util.cc:115
Definition: DNA_ID.h:273
char name[66]
Definition: DNA_ID.h:283
struct Object * parent
double PIL_check_seconds_timer(void)
Definition: time.c:80
float max
ccl_device_inline float2 fabs(const float2 &a)