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