94 std::unique_ptr<
Curves, std::function<void(
Curves *)>> converted_curves;
96 switch (context.object->type) {
98 const Curve *legacy_curve =
static_cast<Curve *
>(context.object->data);
99 converted_curves = std::unique_ptr<
Curves, std::function<void(
Curves *)>>(
101 curves_id = converted_curves.get();
105 curves_id =
static_cast<Curves *
>(context.object->data);
113 if (curves.points_num() == 0) {
119 const std::array<int, CURVE_TYPES_NUM> &curve_type_counts = curves.curve_type_counts();
120 const int number_of_curve_types = std::count_if(curve_type_counts.begin(),
121 curve_type_counts.end(),
122 [](
const int count) { return count > 0; });
123 if (number_of_curve_types > 1) {
124 CLOG_WARN(&
LOG,
"Cannot export mixed curve types in the same Curves object");
129 CLOG_WARN(&
LOG,
"Cannot export mixed cyclic and non-cyclic curves in the same Curves object");
133 const bool is_cyclic = curves.cyclic().first();
134 Alembic::AbcGeom::BasisType curve_basis = Alembic::AbcGeom::kNoBasis;
135 Alembic::AbcGeom::CurveType curve_type = Alembic::AbcGeom::kLinear;
136 Alembic::AbcGeom::CurvePeriodicity periodicity =
is_cyclic ? Alembic::AbcGeom::kPeriodic :
137 Alembic::AbcGeom::kNonPeriodic;
139 switch (blender_curve_type) {
141 curve_basis = Alembic::AbcGeom::kNoBasis;
142 curve_type = Alembic::AbcGeom::kLinear;
145 curve_basis = Alembic::AbcGeom::kCatmullromBasis;
146 curve_type = Alembic::AbcGeom::kLinear;
149 curve_basis = Alembic::AbcGeom::kBezierBasis;
150 curve_type = Alembic::AbcGeom::kCubic;
153 curve_basis = Alembic::AbcGeom::kBsplineBasis;
154 curve_type = Alembic::AbcGeom::kVariableOrder;
158 std::vector<Imath::V3f>
verts;
159 std::vector<int32_t> vert_counts;
160 std::vector<float> widths;
161 std::vector<float> weights;
162 std::vector<float> knots;
163 std::vector<uint8_t> orders;
166 const Span<float> nurbs_weights = curves.nurbs_weights();
172 vert_counts.resize(curves.curves_num());
173 const OffsetIndices points_by_curve = curves.points_by_curve();
175 const Span<float3> handles_l = curves.handle_positions_left();
176 const Span<float3> handles_r = curves.handle_positions_right();
178 for (
const int i_curve : curves.curves_range()) {
179 const IndexRange points = points_by_curve[i_curve];
180 const size_t current_vert_count =
verts.
size();
182 const int start_point_index = points.first();
183 const int last_point_index = points.last();
191 for (
const int i_point : points.drop_back(1)) {
193 widths.push_back(radii[i_point] * 2.0f);
202 widths.push_back(radii[last_point_index] * 2.0f);
211 vert_counts[i_curve] =
verts.size() - current_vert_count;
215 verts.resize(curves.points_num());
216 widths.resize(curves.points_num());
217 for (
const int i_point : curves.points_range()) {
219 widths[i_point] = radii[i_point] * 2.0f;
223 weights.resize(curves.points_num());
224 std::copy_n(nurbs_weights.
data(), weights.size(), weights.data());
226 orders.resize(curves.curves_num());
227 for (
const int i_curve : curves.curves_range()) {
228 orders[i_curve] = nurbs_orders[i_curve];
235 Alembic::AbcGeom::OFloatGeomParam::Sample width_sample;
236 width_sample.setVals(widths);
243 OV2fGeomParam::Sample(),
244 ON3fGeomParam::Sample(),
252 abc_curve_schema_.set(
sample);