Blender  V2.93
abc_writer_curves.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  * The Original Code is Copyright (C) 2016 Kévin Dietrich.
17  * All rights reserved.
18  */
19 
24 #include "abc_writer_curves.h"
26 
27 #include "DNA_curve_types.h"
28 #include "DNA_object_types.h"
29 
30 #include "BKE_curve.h"
31 #include "BKE_mesh.h"
32 #include "BKE_object.h"
33 
34 #include "CLG_log.h"
35 static CLG_LogRef LOG = {"io.alembic"};
36 
37 using Alembic::AbcGeom::OCompoundProperty;
38 using Alembic::AbcGeom::OCurves;
39 using Alembic::AbcGeom::OCurvesSchema;
40 using Alembic::AbcGeom::OInt16Property;
41 using Alembic::AbcGeom::ON3fGeomParam;
42 using Alembic::AbcGeom::OV2fGeomParam;
43 
44 namespace blender::io::alembic {
45 
46 const std::string ABC_CURVE_RESOLUTION_U_PROPNAME("blender:resolution");
47 
49 {
50 }
51 
53 {
54  CLOG_INFO(&LOG, 2, "exporting %s", args_.abc_path.c_str());
55  abc_curve_ = OCurves(args_.abc_parent, args_.abc_name, timesample_index_);
56  abc_curve_schema_ = abc_curve_.getSchema();
57 
58  Curve *cu = static_cast<Curve *>(context->object->data);
59  OCompoundProperty user_props = abc_curve_schema_.getUserProperties();
60  OInt16Property user_prop_resolu(user_props, ABC_CURVE_RESOLUTION_U_PROPNAME);
61  user_prop_resolu.set(cu->resolu);
62 }
63 
64 Alembic::Abc::OObject ABCCurveWriter::get_alembic_object() const
65 {
66  return abc_curve_;
67 }
68 
69 Alembic::Abc::OCompoundProperty ABCCurveWriter::abc_prop_for_custom_props()
70 {
71  return abc_schema_prop_for_custom_props(abc_curve_schema_);
72 }
73 
75 {
76  Curve *curve = static_cast<Curve *>(context.object->data);
77 
78  std::vector<Imath::V3f> verts;
79  std::vector<int32_t> vert_counts;
80  std::vector<float> widths;
81  std::vector<float> weights;
82  std::vector<float> knots;
83  std::vector<uint8_t> orders;
84  Imath::V3f temp_vert;
85 
86  Alembic::AbcGeom::BasisType curve_basis = Alembic::AbcGeom::kNoBasis;
87  Alembic::AbcGeom::CurveType curve_type = Alembic::AbcGeom::kVariableOrder;
88  Alembic::AbcGeom::CurvePeriodicity periodicity = Alembic::AbcGeom::kNonPeriodic;
89 
90  Nurb *nurbs = static_cast<Nurb *>(curve->nurb.first);
91  for (; nurbs; nurbs = nurbs->next) {
92  if (nurbs->bp) {
93  curve_basis = Alembic::AbcGeom::kNoBasis;
94  curve_type = Alembic::AbcGeom::kVariableOrder;
95 
96  const int totpoint = nurbs->pntsu * nurbs->pntsv;
97 
98  const BPoint *point = nurbs->bp;
99 
100  for (int i = 0; i < totpoint; i++, point++) {
101  copy_yup_from_zup(temp_vert.getValue(), point->vec);
102  verts.push_back(temp_vert);
103  weights.push_back(point->vec[3]);
104  widths.push_back(point->radius);
105  }
106  }
107  else if (nurbs->bezt) {
108  curve_basis = Alembic::AbcGeom::kBezierBasis;
109  curve_type = Alembic::AbcGeom::kCubic;
110 
111  const int totpoint = nurbs->pntsu;
112 
113  const BezTriple *bezier = nurbs->bezt;
114 
115  /* TODO(kevin): store info about handles, Alembic doesn't have this. */
116  for (int i = 0; i < totpoint; i++, bezier++) {
117  copy_yup_from_zup(temp_vert.getValue(), bezier->vec[1]);
118  verts.push_back(temp_vert);
119  widths.push_back(bezier->radius);
120  }
121  }
122 
123  if ((nurbs->flagu & CU_NURB_ENDPOINT) != 0) {
124  periodicity = Alembic::AbcGeom::kNonPeriodic;
125  }
126  else if ((nurbs->flagu & CU_NURB_CYCLIC) != 0) {
127  periodicity = Alembic::AbcGeom::kPeriodic;
128 
129  /* Duplicate the start points to indicate that the curve is actually
130  * cyclic since other software need those.
131  */
132 
133  for (int i = 0; i < nurbs->orderu; i++) {
134  verts.push_back(verts[i]);
135  }
136  }
137 
138  if (nurbs->knotsu != nullptr) {
139  const size_t num_knots = KNOTSU(nurbs);
140 
141  /* Add an extra knot at the beginning and end of the array since most apps
142  * require/expect them. */
143  knots.resize(num_knots + 2);
144 
145  for (int i = 0; i < num_knots; i++) {
146  knots[i + 1] = nurbs->knotsu[i];
147  }
148 
149  if ((nurbs->flagu & CU_NURB_CYCLIC) != 0) {
150  knots[0] = nurbs->knotsu[0];
151  knots[num_knots - 1] = nurbs->knotsu[num_knots - 1];
152  }
153  else {
154  knots[0] = (2.0f * nurbs->knotsu[0] - nurbs->knotsu[1]);
155  knots[num_knots - 1] = (2.0f * nurbs->knotsu[num_knots - 1] -
156  nurbs->knotsu[num_knots - 2]);
157  }
158  }
159 
160  orders.push_back(nurbs->orderu);
161  vert_counts.push_back(verts.size());
162  }
163 
164  Alembic::AbcGeom::OFloatGeomParam::Sample width_sample;
165  width_sample.setVals(widths);
166 
167  OCurvesSchema::Sample sample(verts,
168  vert_counts,
169  curve_type,
170  periodicity,
171  width_sample,
172  OV2fGeomParam::Sample(), /* UVs */
173  ON3fGeomParam::Sample(), /* normals */
174  curve_basis,
175  weights,
176  orders,
177  knots);
178 
180  sample.setSelfBounds(bounding_box_);
181  abc_curve_schema_.set(sample);
182 }
183 
185  : ABCGenericMeshWriter(args)
186 {
187 }
188 
189 Mesh *ABCCurveMeshWriter::get_export_mesh(Object *object_eval, bool &r_needsfree)
190 {
191  Mesh *mesh_eval = BKE_object_get_evaluated_mesh(object_eval);
192  if (mesh_eval != nullptr) {
193  /* Mesh_eval only exists when generative modifiers are in use. */
194  r_needsfree = false;
195  return mesh_eval;
196  }
197 
198  r_needsfree = true;
199  return BKE_mesh_new_nomain_from_curve(object_eval);
200 }
201 
202 } // namespace blender::io::alembic
#define KNOTSU(nu)
Definition: BKE_curve.h:68
struct Mesh * BKE_mesh_new_nomain_from_curve(struct Object *ob)
Definition: mesh_convert.c:572
General operations, lookup, etc. for blender objects.
struct Mesh * BKE_object_get_evaluated_mesh(struct Object *object)
Definition: object.c:4459
#define CLOG_INFO(clg_ref, level,...)
Definition: CLG_log.h:201
@ CU_NURB_CYCLIC
@ CU_NURB_ENDPOINT
Object is a sort of wrapper for general info.
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]
static void sample(SocketReader *reader, int x, int y, float color[4])
BLI_INLINE void copy_yup_from_zup(float yup[3], const float zup[3])
const std::string ABC_CURVE_RESOLUTION_U_PROPNAME
struct SELECTID_Context context
Definition: select_engine.c:47
float vec[4]
float radius
float vec[3][3]
short resolu
ListBase nurb
void * first
Definition: DNA_listBase.h:47
short flagu
short orderu
struct Nurb * next
float * knotsu
BezTriple * bezt
BPoint * bp