Blender V4.3
obj_import_nurbs.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "BKE_lib_id.hh"
10#include "BKE_object.hh"
11
12#include "BLI_listbase.h"
13#include "BLI_math_vector.h"
14
15#include "DNA_curve_types.h"
16
17#include "IO_wavefront_obj.hh"
19#include "obj_import_nurbs.hh"
20#include "obj_import_objects.hh"
21
22namespace blender::io::obj {
23
25{
26 BLI_assert(!curve_geometry_.nurbs_element_.curv_indices.is_empty());
27
28 Curve *curve = static_cast<Curve *>(BKE_id_new_nomain(ID_CU_LEGACY, nullptr));
29
31
32 curve->flag = CU_3D;
33 curve->resolu = curve->resolv = 12;
34 /* Only one NURBS spline will be created in the curve object. */
35 curve->actnu = 0;
36
37 Nurb *nurb = static_cast<Nurb *>(MEM_callocN(sizeof(Nurb), __func__));
38 BLI_addtail(BKE_curve_nurbs_get(curve), nurb);
39 this->create_nurbs(curve);
40
41 return curve;
42}
43
45{
46 std::string ob_name = get_geometry_name(curve_geometry_.geometry_name_,
47 import_params.collection_separator);
48 if (ob_name.empty() && !curve_geometry_.nurbs_element_.group_.empty()) {
49 ob_name = curve_geometry_.nurbs_element_.group_;
50 }
51 if (ob_name.empty()) {
52 ob_name = "Untitled";
53 }
55
56 Curve *curve = BKE_curve_add(bmain, ob_name.c_str(), OB_CURVES_LEGACY);
57 Object *obj = BKE_object_add_only_object(bmain, OB_CURVES_LEGACY, ob_name.c_str());
58
59 curve->flag = CU_3D;
60 curve->resolu = curve->resolv = 12;
61 /* Only one NURBS spline will be created in the curve object. */
62 curve->actnu = 0;
63
64 Nurb *nurb = static_cast<Nurb *>(MEM_callocN(sizeof(Nurb), __func__));
65 BLI_addtail(BKE_curve_nurbs_get(curve), nurb);
66 this->create_nurbs(curve);
67
68 obj->data = curve;
69 transform_object(obj, import_params);
70
71 return obj;
72}
73
74void CurveFromGeometry::create_nurbs(Curve *curve)
75{
76 const NurbsElement &nurbs_geometry = curve_geometry_.nurbs_element_;
77 Nurb *nurb = static_cast<Nurb *>(curve->nurb.first);
78
79 nurb->type = CU_NURBS;
80 nurb->flag = CU_3D;
81 nurb->next = nurb->prev = nullptr;
82 /* BKE_nurb_points_add later on will update pntsu. If this were set to total curve points,
83 * we get double the total points in viewport. */
84 nurb->pntsu = 0;
85 /* Total points = pntsu * pntsv. */
86 nurb->pntsv = 1;
87 nurb->orderu = nurb->orderv = (nurbs_geometry.degree + 1 > SHRT_MAX) ? 4 :
88 nurbs_geometry.degree + 1;
89 nurb->resolu = nurb->resolv = curve->resolu;
90
91 const int64_t tot_vert{nurbs_geometry.curv_indices.size()};
92
93 BKE_nurb_points_add(nurb, tot_vert);
94 for (int i = 0; i < tot_vert; i++) {
95 BPoint &bpoint = nurb->bp[i];
96 copy_v3_v3(bpoint.vec, global_vertices_.vertices[nurbs_geometry.curv_indices[i]]);
97 bpoint.vec[3] = 1.0f;
98 bpoint.weight = 1.0f;
99 }
100
102
103 /* Figure out whether curve should have U endpoint flag set:
104 * the parameters should have at least (degree+1) values on each end,
105 * and their values should match curve range. */
106 bool do_endpoints = false;
107 int deg1 = nurbs_geometry.degree + 1;
108 if (nurbs_geometry.parm.size() >= deg1 * 2) {
109 do_endpoints = true;
110 const float2 range = nurbs_geometry.range;
111 for (int i = 0; i < deg1; ++i) {
112 if (abs(nurbs_geometry.parm[i] - range.x) > 0.0001f) {
113 do_endpoints = false;
114 break;
115 }
116 if (abs(nurbs_geometry.parm[nurbs_geometry.parm.size() - 1 - i] - range.y) > 0.0001f) {
117 do_endpoints = false;
118 break;
119 }
120 }
121 }
122 if (do_endpoints) {
123 nurb->flagu = CU_NURB_ENDPOINT;
124 }
125}
126
127} // namespace blender::io::obj
void BKE_curve_init(Curve *cu, short curve_type)
Definition curve.cc:347
ListBase * BKE_curve_nurbs_get(Curve *cu)
Definition curve.cc:4965
void BKE_nurb_knot_calc_u(Nurb *nu)
Definition curve.cc:1181
Curve * BKE_curve_add(Main *bmain, const char *name, int type)
Definition curve.cc:386
void BKE_nurb_points_add(Nurb *nu, int number)
Definition curve.cc:862
void * BKE_id_new_nomain(short type, const char *name)
Definition lib_id.cc:1487
General operations, lookup, etc. for blender objects.
Object * BKE_object_add_only_object(Main *bmain, int type, const char *name) ATTR_RETURNS_NONNULL
#define BLI_assert(a)
Definition BLI_assert.h:50
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:110
MINLINE void copy_v3_v3(float r[3], const float a[3])
@ ID_CU_LEGACY
@ CU_NURBS
@ CU_3D
@ CU_NURB_ENDPOINT
@ OB_CURVES_LEGACY
int64_t size() const
bool is_empty() const
Object * create_curve_object(Main *bmain, const OBJImportParams &import_params)
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
void transform_object(Object *object, const OBJImportParams &import_params)
std::string get_geometry_name(const std::string &full_name, char separator)
__int64 int64_t
Definition stdint.h:89
float vec[4]
short flagu
short orderu
struct Nurb * next
short orderv
short flag
short type
BPoint * bp
short resolu
struct Nurb * prev
short resolv
ccl_device_inline int abs(int x)
Definition util/math.h:120