Blender  V3.3
abc_writer_curves.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2016 Kévin Dietrich. All rights reserved. */
3 
8 #include "abc_writer_curves.h"
10 
11 #include "DNA_curve_types.h"
12 #include "DNA_object_types.h"
13 
14 #include "BKE_curve.h"
15 #include "BKE_mesh.h"
16 #include "BKE_object.h"
17 
18 #include "CLG_log.h"
19 static CLG_LogRef LOG = {"io.alembic"};
20 
21 using Alembic::AbcGeom::OCompoundProperty;
22 using Alembic::AbcGeom::OCurves;
23 using Alembic::AbcGeom::OCurvesSchema;
24 using Alembic::AbcGeom::OInt16Property;
25 using Alembic::AbcGeom::ON3fGeomParam;
26 using Alembic::AbcGeom::OV2fGeomParam;
27 
28 namespace blender::io::alembic {
29 
30 const std::string ABC_CURVE_RESOLUTION_U_PROPNAME("blender:resolution");
31 
33 {
34 }
35 
37 {
38  CLOG_INFO(&LOG, 2, "exporting %s", args_.abc_path.c_str());
39  abc_curve_ = OCurves(args_.abc_parent, args_.abc_name, timesample_index_);
40  abc_curve_schema_ = abc_curve_.getSchema();
41 
42  Curve *cu = static_cast<Curve *>(context->object->data);
43  OCompoundProperty user_props = abc_curve_schema_.getUserProperties();
44  OInt16Property user_prop_resolu(user_props, ABC_CURVE_RESOLUTION_U_PROPNAME);
45  user_prop_resolu.set(cu->resolu);
46 }
47 
48 Alembic::Abc::OObject ABCCurveWriter::get_alembic_object() const
49 {
50  return abc_curve_;
51 }
52 
53 Alembic::Abc::OCompoundProperty ABCCurveWriter::abc_prop_for_custom_props()
54 {
55  return abc_schema_prop_for_custom_props(abc_curve_schema_);
56 }
57 
59 {
60  Curve *curve = static_cast<Curve *>(context.object->data);
61 
62  std::vector<Imath::V3f> verts;
63  std::vector<int32_t> vert_counts;
64  std::vector<float> widths;
65  std::vector<float> weights;
66  std::vector<float> knots;
67  std::vector<uint8_t> orders;
68  Imath::V3f temp_vert;
69 
70  Alembic::AbcGeom::BasisType curve_basis = Alembic::AbcGeom::kNoBasis;
71  Alembic::AbcGeom::CurveType curve_type = Alembic::AbcGeom::kVariableOrder;
72  Alembic::AbcGeom::CurvePeriodicity periodicity = Alembic::AbcGeom::kNonPeriodic;
73 
74  Nurb *nurbs = static_cast<Nurb *>(curve->nurb.first);
75  for (; nurbs; nurbs = nurbs->next) {
76  const size_t current_point_count = verts.size();
77  if (nurbs->bp) {
78  curve_basis = Alembic::AbcGeom::kNoBasis;
79  curve_type = Alembic::AbcGeom::kVariableOrder;
80 
81  const int totpoint = nurbs->pntsu * nurbs->pntsv;
82 
83  const BPoint *point = nurbs->bp;
84 
85  for (int i = 0; i < totpoint; i++, point++) {
86  copy_yup_from_zup(temp_vert.getValue(), point->vec);
87  verts.push_back(temp_vert);
88  weights.push_back(point->vec[3]);
89  widths.push_back(point->radius);
90  }
91  }
92  else if (nurbs->bezt) {
93  curve_basis = Alembic::AbcGeom::kBezierBasis;
94  curve_type = Alembic::AbcGeom::kCubic;
95 
96  const int totpoint = nurbs->pntsu;
97 
98  const BezTriple *bezier = nurbs->bezt;
99 
100  /* TODO(kevin): store info about handles, Alembic doesn't have this. */
101  for (int i = 0; i < totpoint; i++, bezier++) {
102  copy_yup_from_zup(temp_vert.getValue(), bezier->vec[1]);
103  verts.push_back(temp_vert);
104  widths.push_back(bezier->radius);
105  }
106  }
107 
108  if ((nurbs->flagu & CU_NURB_ENDPOINT) != 0) {
109  periodicity = Alembic::AbcGeom::kNonPeriodic;
110  }
111  else if ((nurbs->flagu & CU_NURB_CYCLIC) != 0) {
112  periodicity = Alembic::AbcGeom::kPeriodic;
113 
114  /* Duplicate the start points to indicate that the curve is actually
115  * cyclic since other software need those.
116  */
117 
118  for (int i = 0; i < nurbs->orderu; i++) {
119  verts.push_back(verts[i]);
120  }
121  }
122 
123  if (nurbs->knotsu != nullptr) {
124  const size_t num_knots = KNOTSU(nurbs);
125 
126  /* Add an extra knot at the beginning and end of the array since most apps
127  * require/expect them. */
128  knots.resize(num_knots + 2);
129 
130  for (int i = 0; i < num_knots; i++) {
131  knots[i + 1] = nurbs->knotsu[i];
132  }
133 
134  if ((nurbs->flagu & CU_NURB_CYCLIC) != 0) {
135  knots[0] = nurbs->knotsu[0];
136  knots[num_knots - 1] = nurbs->knotsu[num_knots - 1];
137  }
138  else {
139  knots[0] = (2.0f * nurbs->knotsu[0] - nurbs->knotsu[1]);
140  knots[num_knots - 1] = (2.0f * nurbs->knotsu[num_knots - 1] -
141  nurbs->knotsu[num_knots - 2]);
142  }
143  }
144 
145  orders.push_back(static_cast<uint8_t>(nurbs->orderu));
146  vert_counts.push_back(verts.size() - current_point_count);
147  }
148 
149  Alembic::AbcGeom::OFloatGeomParam::Sample width_sample;
150  width_sample.setVals(widths);
151 
152  OCurvesSchema::Sample sample(verts,
153  vert_counts,
154  curve_type,
155  periodicity,
156  width_sample,
157  OV2fGeomParam::Sample(), /* UVs */
158  ON3fGeomParam::Sample(), /* normals */
159  curve_basis,
160  weights,
161  orders,
162  knots);
163 
165  sample.setSelfBounds(bounding_box_);
166  abc_curve_schema_.set(sample);
167 }
168 
170  : ABCGenericMeshWriter(args)
171 {
172 }
173 
174 Mesh *ABCCurveMeshWriter::get_export_mesh(Object *object_eval, bool &r_needsfree)
175 {
176  Mesh *mesh_eval = BKE_object_get_evaluated_mesh(object_eval);
177  if (mesh_eval != nullptr) {
178  /* Mesh_eval only exists when generative modifiers are in use. */
179  r_needsfree = false;
180  return mesh_eval;
181  }
182 
183  r_needsfree = true;
184  return BKE_mesh_new_nomain_from_curve(object_eval);
185 }
186 
187 } // namespace blender::io::alembic
#define KNOTSU(nu)
Definition: BKE_curve.h:52
struct Mesh * BKE_mesh_new_nomain_from_curve(const struct Object *ob)
General operations, lookup, etc. for blender objects.
struct Mesh * BKE_object_get_evaluated_mesh(const struct Object *object)
#define CLOG_INFO(clg_ref, level,...)
Definition: CLG_log.h:187
@ CU_NURB_CYCLIC
@ CU_NURB_ENDPOINT
CurveType
Object is a sort of wrapper for general info.
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a point
static CLG_LogRef LOG
Alembic::Abc::OCompoundProperty abc_schema_prop_for_custom_props(T abc_schema)
const ABCWriterConstructorArgs args_
virtual void update_bounding_box(Object *object)
virtual Mesh * get_export_mesh(Object *object_eval, bool &r_needsfree) override
ABCCurveMeshWriter(const ABCWriterConstructorArgs &args)
virtual Alembic::Abc::OObject get_alembic_object() const override
ABCCurveWriter(const ABCWriterConstructorArgs &args)
virtual void create_alembic_objects(const HierarchyContext *context) override
virtual void do_write(HierarchyContext &context) override
Alembic::Abc::OCompoundProperty abc_prop_for_custom_props() override
Curve curve
static float verts[][3]
BLI_INLINE void copy_yup_from_zup(float yup[3], const float zup[3])
const std::string ABC_CURVE_RESOLUTION_U_PROPNAME
unsigned char uint8_t
Definition: stdint.h:78
float vec[3][3]
short resolu
ListBase nurb
void * first
Definition: DNA_listBase.h:31
short flagu
short orderu
struct Nurb * next
float * knotsu
BezTriple * bezt
BPoint * bp