5#include "testing/testing.h"
8#include <pxr/base/plug/registry.h>
9#include <pxr/base/tf/stringUtils.h>
10#include <pxr/base/vt/types.h>
11#include <pxr/base/vt/value.h>
12#include <pxr/usd/sdf/types.h>
13#include <pxr/usd/usd/object.h>
14#include <pxr/usd/usd/prim.h>
15#include <pxr/usd/usd/stage.h>
16#include <pxr/usd/usdGeom/basisCurves.h>
17#include <pxr/usd/usdGeom/curves.h>
18#include <pxr/usd/usdGeom/mesh.h>
19#include <pxr/usd/usdGeom/nurbsCurves.h>
20#include <pxr/usd/usdGeom/subset.h>
21#include <pxr/usd/usdGeom/tokens.h>
50 const bool is_periodic,
51 const int vertex_count);
53 const bool is_periodic,
54 const int vertex_count);
56 const int vertex_count,
57 const int knots_count,
60 const int vertex_count,
61 const int knots_count,
86 BlendfileLoadingBaseTest::SetUp();
114 EXPECT_TRUE(result) <<
"USD export should succed.";
117 ASSERT_NE(
stage,
nullptr) <<
"Stage should not be null after opening usd file.";
120 std::string prim_name = pxr::TfMakeValidIdentifier(
"BezierCurve");
121 pxr::UsdPrim test_prim =
stage->GetPrimAtPath(pxr::SdfPath(
"/BezierCurve/" + prim_name));
122 EXPECT_TRUE(test_prim.IsValid());
127 std::string prim_name = pxr::TfMakeValidIdentifier(
"BezierCircle");
128 pxr::UsdPrim test_prim =
stage->GetPrimAtPath(pxr::SdfPath(
"/BezierCircle/" + prim_name));
129 EXPECT_TRUE(test_prim.IsValid());
134 std::string prim_name = pxr::TfMakeValidIdentifier(
"NurbsCurve");
135 pxr::UsdPrim test_prim =
stage->GetPrimAtPath(pxr::SdfPath(
"/NurbsCurve/" + prim_name));
136 EXPECT_TRUE(test_prim.IsValid());
141 std::string prim_name = pxr::TfMakeValidIdentifier(
"NurbsCircle");
142 pxr::UsdPrim test_prim =
stage->GetPrimAtPath(pxr::SdfPath(
"/NurbsCircle/" + prim_name));
143 EXPECT_TRUE(test_prim.IsValid());
148 std::string prim_name = pxr::TfMakeValidIdentifier(
"Curves");
149 pxr::UsdPrim test_prim =
stage->GetPrimAtPath(pxr::SdfPath(
"/Cube/Curves/" + prim_name));
150 EXPECT_TRUE(test_prim.IsValid());
160 const bool is_periodic,
161 const int vertex_count)
163 auto curve = pxr::UsdGeomBasisCurves(prim);
166 pxr::UsdAttribute basis_attr = curve.GetBasisAttr();
167 basis_attr.Get(&basis);
168 auto basis_token = basis.Get<pxr::TfToken>();
170 EXPECT_EQ(basis_token, pxr::UsdGeomTokens->catmullRom)
171 <<
"Basis token should be catmullRom for catmullRom curve";
174 pxr::UsdAttribute type_attr = curve.GetTypeAttr();
175 type_attr.Get(&type);
176 auto type_token = type.Get<pxr::TfToken>();
178 EXPECT_EQ(type_token, pxr::UsdGeomTokens->cubic)
179 <<
"Type token should be cubic for catmullRom curve";
182 pxr::UsdAttribute wrap_attr = curve.GetWrapAttr();
183 wrap_attr.Get(&
wrap);
184 auto wrap_token =
wrap.Get<pxr::TfToken>();
187 EXPECT_EQ(wrap_token, pxr::UsdGeomTokens->periodic)
188 <<
"Wrap token should be periodic for periodic curve";
191 EXPECT_EQ(wrap_token, pxr::UsdGeomTokens->pinned)
192 <<
"Wrap token should be pinned for nonperiodic catmullRom curve";
195 pxr::UsdAttribute vert_count_attr = curve.GetCurveVertexCountsAttr();
196 pxr::VtArray<int> vert_counts;
197 vert_count_attr.Get(&vert_counts);
199 EXPECT_EQ(vert_counts.size(), 3) <<
"Prim should contain verts for three curves";
200 EXPECT_EQ(vert_counts[0], vertex_count) <<
"Curve 0 should have " << vertex_count <<
" verts.";
201 EXPECT_EQ(vert_counts[1], vertex_count) <<
"Curve 1 should have " << vertex_count <<
" verts.";
202 EXPECT_EQ(vert_counts[2], vertex_count) <<
"Curve 2 should have " << vertex_count <<
" verts.";
210 const bool is_periodic,
211 const int vertex_count)
213 auto curve = pxr::UsdGeomBasisCurves(bezier_prim);
216 pxr::UsdAttribute basis_attr = curve.GetBasisAttr();
217 basis_attr.Get(&basis);
218 auto basis_token = basis.Get<pxr::TfToken>();
220 EXPECT_EQ(basis_token, pxr::UsdGeomTokens->bezier)
221 <<
"Basis token should be bezier for bezier curve";
224 pxr::UsdAttribute type_attr = curve.GetTypeAttr();
225 type_attr.Get(&type);
226 auto type_token = type.Get<pxr::TfToken>();
228 EXPECT_EQ(type_token, pxr::UsdGeomTokens->cubic)
229 <<
"Type token should be cubic for bezier curve";
232 pxr::UsdAttribute wrap_attr = curve.GetWrapAttr();
233 wrap_attr.Get(&
wrap);
234 auto wrap_token =
wrap.Get<pxr::TfToken>();
237 EXPECT_EQ(wrap_token, pxr::UsdGeomTokens->periodic)
238 <<
"Wrap token should be periodic for periodic curve";
241 EXPECT_EQ(wrap_token, pxr::UsdGeomTokens->nonperiodic)
242 <<
"Wrap token should be nonperiodic for nonperiodic curve";
245 auto widths_interp_token = curve.GetWidthsInterpolation();
246 EXPECT_EQ(widths_interp_token, pxr::UsdGeomTokens->varying)
247 <<
"Widths interpolation token should be varying for bezier curve";
249 pxr::UsdAttribute vert_count_attr = curve.GetCurveVertexCountsAttr();
250 pxr::VtArray<int> vert_counts;
251 vert_count_attr.Get(&vert_counts);
253 EXPECT_EQ(vert_counts.size(), 1) <<
"Prim should only contains verts for a single curve";
254 EXPECT_EQ(vert_counts[0], vertex_count) <<
"Curve should have " << vertex_count <<
" verts.";
263 const int vertex_count,
264 const int knots_count,
267 auto curve = pxr::UsdGeomNurbsCurves(nurbs_prim);
269 pxr::UsdAttribute order_attr = curve.GetOrderAttr();
270 pxr::VtArray<int> orders;
271 order_attr.Get(&orders);
273 EXPECT_EQ(orders.size(), 2) <<
"Prim should contain orders for two curves";
274 EXPECT_EQ(orders[0], order) <<
"Curves should have order " << order;
275 EXPECT_EQ(orders[1], order) <<
"Curves should have order " << order;
277 pxr::UsdAttribute knots_attr = curve.GetKnotsAttr();
278 pxr::VtArray<double> knots;
279 knots_attr.Get(&knots);
281 EXPECT_EQ(knots.size(), knots_count) <<
"Curve should have " << knots_count <<
" knots.";
282 for (
int i = 0; i < 2; i++) {
283 int zeroth_knot_index = i * (knots_count / 2);
285 EXPECT_EQ(knots[zeroth_knot_index], knots[zeroth_knot_index + 1])
286 <<
"NURBS curve should satisfy this knots rule for a nonperiodic curve";
287 EXPECT_EQ(knots[knots.size() - 1], knots[knots.size() - 2])
288 <<
"NURBS curve should satisfy this knots rule for a nonperiodic curve";
291 auto widths_interp_token = curve.GetWidthsInterpolation();
292 EXPECT_EQ(widths_interp_token, pxr::UsdGeomTokens->vertex)
293 <<
"Widths interpolation token should be vertex for NURBS curve";
295 pxr::UsdAttribute vert_count_attr = curve.GetCurveVertexCountsAttr();
296 pxr::VtArray<int> vert_counts;
297 vert_count_attr.Get(&vert_counts);
299 EXPECT_EQ(vert_counts.size(), 2) <<
"Prim should contain verts for two curves";
300 EXPECT_EQ(vert_counts[0], vertex_count) <<
"Curve should have " << vertex_count <<
" verts.";
301 EXPECT_EQ(vert_counts[1], vertex_count) <<
"Curve should have " << vertex_count <<
" verts.";
310 const int vertex_count,
311 const int knots_count,
314 auto curve = pxr::UsdGeomNurbsCurves(nurbs_prim);
316 pxr::UsdAttribute order_attr = curve.GetOrderAttr();
317 pxr::VtArray<int> orders;
318 order_attr.Get(&orders);
320 EXPECT_EQ(orders.size(), 1) <<
"Prim should contain orders for one curves";
321 EXPECT_EQ(orders[0], order) <<
"Curve should have order " << order;
323 pxr::UsdAttribute knots_attr = curve.GetKnotsAttr();
324 pxr::VtArray<double> knots;
325 knots_attr.Get(&knots);
327 EXPECT_EQ(knots.size(), knots_count) <<
"Curve should have " << knots_count <<
" knots.";
329 EXPECT_EQ(knots[0], knots[1] - (knots[knots.size() - 2] - knots[knots.size() - 3]))
330 <<
"NURBS curve should satisfy this knots rule for a periodic curve";
331 EXPECT_EQ(knots[knots.size() - 1], knots[knots.size() - 2] + (knots[2] - knots[1]))
332 <<
"NURBS curve should satisfy this knots rule for a periodic curve";
334 auto widths_interp_token = curve.GetWidthsInterpolation();
335 EXPECT_EQ(widths_interp_token, pxr::UsdGeomTokens->vertex)
336 <<
"Widths interpolation token should be vertex for NURBS curve";
338 pxr::UsdAttribute vert_count_attr = curve.GetCurveVertexCountsAttr();
339 pxr::VtArray<int> vert_counts;
340 vert_count_attr.Get(&vert_counts);
342 EXPECT_EQ(vert_counts.size(), 1) <<
"Prim should contain verts for one curve";
343 EXPECT_EQ(vert_counts[0], vertex_count) <<
"Curve should have " << vertex_count <<
" verts.";
void CTX_data_main_set(bContext *C, Main *bmain)
void CTX_free(bContext *C)
void CTX_data_scene_set(bContext *C, Scene *scene)
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
File and directory operations.
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
int BLI_delete(const char *path, bool dir, bool recursive) ATTR_NONNULL()
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
external readfile function prototypes.
virtual void depsgraph_create(eEvaluationMode depsgraph_evaluation_mode)
bool blendfile_load(const char *filepath)
struct BlendFileData * bfile
constexpr const char * c_str() const
virtual void TearDown() override
bool load_file_and_depsgraph(const StringRefNull &filepath, const eEvaluationMode eval_mode=DAG_EVAL_VIEWPORT)
virtual void SetUp() override
static void check_catmullRom_curve(const pxr::UsdPrim prim, const bool is_periodic, const int vertex_count)
static void check_nurbs_circle(const pxr::UsdPrim nurbs_prim, const int vertex_count, const int knots_count, const int order)
bool USD_export(const bContext *C, const char *filepath, const USDExportParams *params, bool as_background_job, ReportList *reports)
const StringRefNull output_filename
TEST_F(UsdCurvesTest, usd_export_curves)
static void check_bezier_curve(const pxr::UsdPrim bezier_prim, const bool is_periodic, const int vertex_count)
static void check_nurbs_curve(const pxr::UsdPrim nurbs_prim, const int vertex_count, const int knots_count, const int order)
const StringRefNull usd_curves_test_filename
float wrap(float value, float max, float min)