Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan deWerd <jjoonathan@gmail.com>2014-07-30 03:18:56 +0400
committerJonathan deWerd <jjoonathan@gmail.com>2014-07-30 03:18:56 +0400
commit09636bf86453e3f71fa7e29041d11c362f3ac2be (patch)
treec9aa62e5bcc3d472dac8b51b8c5b15c45ff01851
parentca5b2d3c5c71278a4f9409a3c9d4063a70feca8c (diff)
Added UV-mesh cache so editing is fast, implemented NurbTrim. DNA is still buggy.
-rw-r--r--release/scripts/startup/bl_ui/properties_data_curve.py1
-rw-r--r--source/blender/blenkernel/BKE_curve.h13
-rw-r--r--source/blender/blenkernel/intern/curve.cpp117
-rw-r--r--source/blender/blenkernel/intern/surf_gridmesh.h4
-rw-r--r--source/blender/editors/curve/editcurve.c1
-rw-r--r--source/blender/editors/io/io_rhino_import.cpp85
-rw-r--r--source/blender/makesdna/DNA_curve_types.h29
-rw-r--r--source/blender/makesrna/intern/rna_curve.c9
8 files changed, 168 insertions, 91 deletions
diff --git a/release/scripts/startup/bl_ui/properties_data_curve.py b/release/scripts/startup/bl_ui/properties_data_curve.py
index ecf9e5cab90..af22c881c04 100644
--- a/release/scripts/startup/bl_ui/properties_data_curve.py
+++ b/release/scripts/startup/bl_ui/properties_data_curve.py
@@ -296,6 +296,7 @@ class DATA_PT_active_spline(CurveButtonsPanelActive, Panel):
col.prop(act_spline, "radius_interpolation", text="Radius")
layout.prop(act_spline, "use_smooth")
+ layout.prop(act_spline, "resolution_trim")
class DATA_PT_font(CurveButtonsPanelText, Panel):
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index 386324ba398..98f1b8ccb81 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -48,6 +48,7 @@ struct TextBox;
struct rctf;
struct DispList;
struct BPoint;
+struct NurbTrim;
typedef struct CurveCache {
ListBase disp;
@@ -152,7 +153,6 @@ void BKE_nurbs_surf_eval(float u, float v,
int pntsv, int orderv, float *V,
struct BPoint *P, int nd, struct BPoint *out, BSplineCacheU *ucache DEFAULT_NULL);
-
bool BKE_nurbList_index_get_co(struct ListBase *editnurb, const int index, float r_co[3]);
int BKE_nurbList_verts_count(struct ListBase *nurb);
@@ -166,6 +166,9 @@ void BKE_nurbList_handles_recalculate(struct ListBase *editnurb, const bool calc
void BKE_nurbList_handles_autocalc(ListBase *editnurb, int flag);
void BKE_nurbList_flag_set(ListBase *editnurb, short flag);
+void BKE_nurbTrim_free(struct NurbTrim *nt);
+struct NurbTrim *BKE_nurbTrim_duplicate(struct NurbTrim *nt);
+
void BKE_nurb_free(struct Nurb *nu);
struct Nurb *BKE_nurb_duplicate(struct Nurb *nu);
struct Nurb *BKE_nurb_copy(struct Nurb *src, int pntsu, int pntsv);
@@ -175,6 +178,9 @@ void BKE_nurb_minmax(struct Nurb *nu, bool use_radius, float min[3], float max[3
void BKE_nurb_makeFaces(struct Nurb *nu, float *coord_array, int rowstride, int resolu, int resolv);
void BKE_nurb_makeCurve(struct Nurb *nu, float *coord_array, float *tilt_array, float *radius_array, float *weight_array, int resolu, int stride);
+void BKE_nurb_compute_trimmed_UV_mesh(struct Nurb* nu);
+void BKE_nurb_clear_cached_UV_mesh(struct Nurb* nu, bool free_mem);
+void BKE_nurb_make_displist(struct Nurb *nurb, struct DispList *dl);
void BKE_nurb_knot_calc_u(struct Nurb *nu);
void BKE_nurb_knot_calc_v(struct Nurb *nu);
@@ -210,9 +216,4 @@ void BKE_nurb_handles_autocalc(struct Nurb *nu, int flag);
void BKE_nurb_bezt_handle_test(struct BezTriple *bezt, const bool use_handle);
void BKE_nurb_handles_test(struct Nurb *nu, const bool use_handles);
-/* Does not traverse nurb's linked list. Fills dl with a mesh corresponding to
- * the single surface nurb, performing trim if necessary.
- */
-void BKE_nurb_make_displist(struct Nurb *nurb, struct DispList *dl);
-
#endif /* __BKE_CURVE_H__ */
diff --git a/source/blender/blenkernel/intern/curve.cpp b/source/blender/blenkernel/intern/curve.cpp
index b4660d2adf8..6730e119eda 100644
--- a/source/blender/blenkernel/intern/curve.cpp
+++ b/source/blender/blenkernel/intern/curve.cpp
@@ -539,20 +539,18 @@ void BKE_nurb_free(Nurb *nu)
if (nu->knotsv)
MEM_freeN(nu->knotsv);
nu->knotsv = NULL;
-
- BKE_nurbList_free(&nu->outer_trim);
- LinkedNurbList *innertrim = (LinkedNurbList*)nu->inner_trim.first;
- while (innertrim) {
- LinkedNurbList *tofree = innertrim;
- innertrim = innertrim->next;
- BKE_nurbList_free(&tofree->nurb_list);
- MEM_freeN(tofree);
+ for (NurbTrim *nt = (NurbTrim*)nu->trims.first; nt; nt=nt->next) {
+ BKE_nurbTrim_free(nt);
}
MEM_freeN(nu);
}
+void BKE_nurbTrim_free(NurbTrim *nt) {
+ BKE_nurbList_free(&nt->nurb_list);
+ MEM_freeN(nt);
+}
void BKE_nurbList_free(ListBase *lb)
{
@@ -607,18 +605,12 @@ Nurb *BKE_nurb_duplicate(Nurb *nu)
}
}
- newnu->inner_trim.first = newnu->inner_trim.last = NULL;
- newnu->outer_trim.first = newnu->outer_trim.last = NULL;
-
- BKE_nurbList_duplicate(&newnu->outer_trim, &nu->outer_trim);
-
- LinkedNurbList *lnl = (LinkedNurbList*)nu->inner_trim.first;
- while (lnl) {
- LinkedNurbList *lnl_dup = (LinkedNurbList*)MEM_callocN(sizeof(LinkedNurbList),"duplicateNurb6");
- BKE_nurbList_duplicate(&lnl_dup->nurb_list, &lnl->nurb_list);
- lnl = lnl->next;
- BLI_addtail(&newnu->inner_trim, lnl_dup);
+ newnu->trims.first = newnu->trims.last = NULL;
+ for (NurbTrim *nt = (NurbTrim*)nu->trims.first; nt; nt=nt->next) {
+ NurbTrim *dup_nt = BKE_nurbTrim_duplicate(nt);
+ BLI_addtail(&newnu->trims, dup_nt);
}
+ BKE_nurb_clear_cached_UV_mesh(newnu,false);
return newnu;
}
@@ -639,10 +631,18 @@ Nurb *BKE_nurb_copy(Nurb *src, int pntsu, int pntsv)
else {
newnu->bp = (BPoint *)MEM_mallocN(pntsu * pntsv * sizeof(BPoint), "copyNurb3");
}
+
+ BKE_nurb_clear_cached_UV_mesh(newnu,false);
return newnu;
}
+NurbTrim *BKE_nurbTrim_duplicate(NurbTrim *nt) {
+ NurbTrim *ret = (NurbTrim*)MEM_callocN(sizeof(NurbTrim), "duplicateNurbTrim");
+ BKE_nurbList_duplicate(&ret->nurb_list, &nt->nurb_list);
+ return ret;
+}
+
void BKE_nurbList_duplicate(ListBase *lb1, ListBase *lb2)
{
Nurb *nu, *nun;
@@ -755,6 +755,7 @@ void BKE_nurb_points_add(Nurb *nu, int number)
}
nu->pntsu += number;
+ BKE_nurb_clear_cached_UV_mesh(nu, true);
}
void BKE_nurb_bezierPoints_add(Nurb *nu, int number)
@@ -769,6 +770,7 @@ void BKE_nurb_bezierPoints_add(Nurb *nu, int number)
}
nu->pntsu += number;
+ BKE_nurb_clear_cached_UV_mesh(nu, true);
}
@@ -4018,11 +4020,8 @@ void BKE_nurb_domain(struct Nurb *nu, float *umin, float *umax, float *vmin, flo
}
float subj0[] = {0.512000,0.938000, 0.374000,0.950000, 0.248000,0.908000, 0.170000,0.866000, 0.092000,0.740000, 0.092000,0.602000, 0.092000,0.440000, 0.116000,0.260000, 0.254000,0.110000, 0.476000,0.074000, 0.746000,0.092000, 0.836000,0.206000, 0.848000,0.422000, 0.812000,0.644000, 0.716000,0.686000, 0.614000,0.734000, 0.488000,0.728000, 0.386000,0.710000, 0.260000,0.626000, 0.272000,0.476000, 0.350000,0.338000, 0.482000,0.278000, 0.632000,0.308000, 0.644000,0.404000, 0.638000,0.494000, 0.590000,0.572000, 0.494000,0.584000, 0.422000,0.518000, 0.458000,0.392000, 0.548000,0.398000, 0.506000,0.506000, 0.572000,0.506000, 0.596000,0.386000, 0.566000,0.338000, 0.470000,0.338000, 0.368000,0.434000, 0.374000,0.608000, 0.578000,0.656000, 0.680000,0.644000, 0.740000,0.554000, 0.782000,0.308000, 0.758000,0.224000, 0.548000,0.164000, 0.338000,0.224000, 0.212000,0.374000, 0.170000,0.626000, 0.236000,0.764000, 0.368000,0.824000, 0.524000,0.836000, 1.184000,0.848000}; int subj0_nv=50;
-void BKE_nurb_make_displist(struct Nurb *nu, struct DispList *dl) {
+void BKE_nurb_compute_trimmed_UV_mesh(struct Nurb* nu) {
bool remap_coords = true; // Remove trimmed verts (only useful for meshgen)
- dl->col = nu->mat_nr;
- dl->charidx = nu->charidx;
- dl->rt = nu->flag & ~CU_2D;
// Figure out the domain
int totu=(nu->pntsu-nu->orderu+1)*nu->resolu, totv=(nu->pntsv-nu->orderv+1)*nu->resolv;
@@ -4032,7 +4031,7 @@ void BKE_nurb_make_displist(struct Nurb *nu, struct DispList *dl) {
// Trim the uniform grid in 2D UV space
GridMesh *gm = new GridMesh();
int coords_len = (totu+1)*(totv+1)*2;
- GridMeshCoord *coords=NULL, *nors=NULL;
+ GridMeshCoord *coords=NULL;
if (!remap_coords) {
coords = (GridMeshCoord*)MEM_mallocN(coords_len * sizeof(GridMeshCoord), "NURBS_tess_1");
gm->mallocN = MEM_mallocN;
@@ -4127,7 +4126,6 @@ void BKE_nurb_make_displist(struct Nurb *nu, struct DispList *dl) {
if (remap_coords) {
int num_used_idxs = int(used_idxs->size());
coords = (GridMeshCoord*)MEM_mallocN(3*sizeof(float)*num_used_idxs, "NURBS_tess_2.3");
- nors = (GridMeshCoord*)MEM_mallocN(3*sizeof(float)*num_used_idxs, "NURBS_tess_2.4");
coords_len = num_used_idxs;
int newidx=0;
std::map<int,int>::iterator it=used_idxs->begin(),end=used_idxs->end();
@@ -4141,34 +4139,59 @@ void BKE_nurb_make_displist(struct Nurb *nu, struct DispList *dl) {
idxs[i] = (*used_idxs)[idxs[i]];
}
}
- dl->verts = (float*)coords;
- dl->index = idxs;
- dl->nors = (float*)nors;
- dl->type = DL_INDEX3;
- dl->parts = ii/3;
- dl->nr = coords_len;
- if (nu->flag&CU_SMOOTH)
- dl->rt |= CU_SMOOTH;
- // Pushforward through the NURBS map
- BSplineCacheU cacheU;
+ nu->UV_verts_count = coords_len;
+ nu->UV_tri_count = ii/3;
+ if (nu->UV_verts) MEM_freeN(nu->UV_verts);
+ nu->UV_verts = (float*)coords;
+ if (nu->UV_idxs) MEM_freeN(nu->UV_idxs);
+ nu->UV_idxs = idxs;
+
+ MEM_freeN(coords_tmp);
+ MEM_freeN(idx_tmp);
+ delete gm;
+}
+
+void BKE_nurb_clear_cached_UV_mesh(struct Nurb* nu, bool free_mem) {
+ nu->UV_verts_count = nu->UV_tri_count = 0;
+ if (free_mem) {
+ MEM_freeN(nu->UV_verts);
+ MEM_freeN(nu->UV_idxs);
+ }
+}
+
+void BKE_nurb_make_displist(struct Nurb *nu, struct DispList *dl) {
+ if (!nu->UV_verts) BKE_nurb_compute_trimmed_UV_mesh(nu);
+
+ float (*coords)[3] = (float(*)[3])MEM_mallocN(sizeof(*coords)*nu->UV_verts_count, "NURBS_tess_3dpts_1");
+ float (*nors)[3] = (float(*)[3])MEM_mallocN(sizeof(*nors)*nu->UV_verts_count, "NURBS_tess_3dpts_2");
+ int (*idxs)[3] = (int(*)[3])MEM_mallocN(sizeof(*idxs)*nu->UV_tri_count, "NURBS_tess_3dpts_3");
+
+ // Push trimmed UV mesh forward through the NURBS map
+ BSplineCacheU cacheU; // Make repeated evals at same u coord efficient
cacheU.u = 1.0/0; // First eval should always miss
- for (int coord=0; coord<coords_len; coord++) {
- float *xyz = (float*)&coords[coord];
- float *norm = (float*)&nors[coord];
+ for (int coord=0; coord<nu->UV_verts_count; coord++) {
+ float *uv_in = (float*)&nu->UV_verts[coord];
+ float *xyz_out = (float*)&coords[coord];
+ float *norm_out = (float*)&nors[coord];
BPoint out[3]; // { surf_pt, u_partial_deriv, v_partal_deriv }
- BKE_nurbs_surf_eval(xyz[0], xyz[1],
+ BKE_nurbs_surf_eval(uv_in[0], uv_in[1],
nu->pntsu, nu->orderu, nu->knotsu,
nu->pntsv, nu->orderv, nu->knotsv,
nu->bp, 1, out, &cacheU);
- copy_v3_v3(xyz, out[0].vec);
- cross_v3_v3v3(norm, out[1].vec, out[2].vec);
+ copy_v3_v3(xyz_out, out[0].vec);
+ cross_v3_v3v3(norm_out, out[1].vec, out[2].vec);
}
- // Cleanup
- //MEM_freeN(coords);
- //MEM_freeN(idxs);
- MEM_freeN(coords_tmp);
- MEM_freeN(idx_tmp);
- delete gm;
+ dl->col = nu->mat_nr;
+ dl->charidx = nu->charidx;
+ dl->rt = nu->flag & ~CU_2D;
+ dl->verts = (float*)coords;
+ dl->index = (int*)idxs;
+ dl->nors = (float*)nors;
+ dl->type = DL_INDEX3;
+ dl->parts = nu->UV_tri_count;
+ dl->nr = nu->UV_verts_count;
+ if (nu->flag&CU_SMOOTH)
+ dl->rt |= CU_SMOOTH;
}
diff --git a/source/blender/blenkernel/intern/surf_gridmesh.h b/source/blender/blenkernel/intern/surf_gridmesh.h
index 50ff336d2a0..be327b459f2 100644
--- a/source/blender/blenkernel/intern/surf_gridmesh.h
+++ b/source/blender/blenkernel/intern/surf_gridmesh.h
@@ -18,9 +18,9 @@
#endif
struct GridMeshCoord {
- float x,y,z;
+ float x,y;
GridMeshCoord() {}
- GridMeshCoord(float x_, float y_, float z_) : x(x_), y(y_), z(z_) {}
+ GridMeshCoord(float x_, float y_, float z_) : x(x_), y(y_) {}
};
struct GridMeshVert {
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 2968b6860fc..2955c5c01c9 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -4973,6 +4973,7 @@ static int addvert_Nurb(bContext *C, short mode, float location[3])
newbp->f1 |= SELECT;
newnu = (Nurb *)MEM_mallocN(sizeof(Nurb), "addvert_Nurb newnu");
+ BKE_nurb_clear_cached_UV_mesh(newnu, false);
memcpy(newnu, nu, sizeof(Nurb));
BLI_addtail(&editnurb->nurbs, newnu);
newnu->bp = newbp;
diff --git a/source/blender/editors/io/io_rhino_import.cpp b/source/blender/editors/io/io_rhino_import.cpp
index fddc97c1866..f383a246f47 100644
--- a/source/blender/editors/io/io_rhino_import.cpp
+++ b/source/blender/editors/io/io_rhino_import.cpp
@@ -28,6 +28,7 @@
#include <cstdlib>
#include <vector>
#include <time.h>
+#include <limits>
extern "C" {
#include "DNA_scene_types.h"
@@ -151,17 +152,60 @@ static int analyze_knots(float *knots, int num_knots, int order, bool periodic,
return CU_NURB_CUSTOMKNOT;
}
-static void normalize_knots(float *knots, int num_knots) {
+/* Determines smallest, second smallest knots and scales them to correspond to
+ * 0 and 1 respectively.
+ * uv=='u': operate on u knots
+ * uv=='v': operate on v knots
+ */
+static void normalize_knots(Nurb *nu, char uv) {
float tol = .001;
+ float *knots = (uv=='u')? nu->knotsu : nu->knotsv;
+ int num_knots = (uv=='u')? KNOTSU(nu) : KNOTSV(nu);
int i=0;
- for (; i<num_knots; i++) {
- if (abs(knots[i]-0)>tol) break;
+ float lowest=std::numeric_limits<float>::infinity();
+ float second_lowest=lowest; /* constraint: second_lowest > lowest (NOT >=). */
+ for (int i=0; i<num_knots; i++) {
+ if (knots[i] <= lowest) {
+ lowest = knots[i];
+ continue;
+ }
+ if (knots[i] <= lowest+tol) continue;
+ /* have: knots[i] > lowest+tol */
+ if (knots[i] <= second_lowest) {
+ second_lowest = knots[i];
+ continue;
+ }
+ /* have: knots[i]>lowest && knots[i]>second_lowest => nothing to do */
+ }
+ if (lowest==second_lowest) {
+ fprintf(stderr, "Could not normalize knots: lowest = second lowest.\n");
+ return;
+ }
+ if (!isfinite(lowest) || !isfinite(second_lowest)) {
+ fprintf(stderr, "Could not normalize knots: too few?\n");
+ return;
}
- if (i==num_knots) return;
- float mult = 1.0 / knots[i];
+ // (new knot) = ((old knot)-(smallest knot)) / ((sec smallest knot)-(smallest knot))
+ double denominator = 1.0 / (second_lowest-lowest);
for (; i<num_knots; i++) {
- knots[i] *= mult;
+ knots[i] = (knots[i]-lowest)*denominator;
+ }
+
+ // Now we rescale the trim curves so that they hold position rel. to knots
+ int uv_idx = (uv=='u')? 0 : 1;
+ for (NurbTrim *nt = (NurbTrim*)nu->trims.first; nt; nt=nt->next) {
+ for (Nurb *trim_nurb = (Nurb*)nt->nurb_list.first; trim_nurb; trim_nurb=trim_nurb->next) {
+ int ptsu = std::max(trim_nurb->pntsu,1);
+ int ptsv = std::max(trim_nurb->pntsv,1);
+ int bp_count = ptsu*ptsv;
+ BPoint *bp = trim_nurb->bp; // Control points
+ for (int bpnum=0; bpnum<bp_count; bpnum++) {
+ double old = bp[bpnum].vec[uv_idx];
+ bp[bpnum].vec[uv_idx] = (old-lowest)*denominator;
+ }
+ }
}
+ BKE_nurb_clear_cached_UV_mesh(nu,true);
}
/****************************** Curve Import *********************************/
@@ -237,9 +281,7 @@ static Nurb *nurb_from_ON_NurbsCurve(ON_NurbsCurve *nc) {
nu->flagu = analyze_knots(nu->knotsu, nu->pntsu+nu->orderu, nu->orderu, nc->IsPeriodic());
double minu,maxu;
nc->GetDomain(&minu, &maxu);
- nu->minu = minu;
- nu->maxu = maxu;
- //normalize_knots(nu->knotsu, nu->pntsu+nu->orderu);
+ normalize_knots(nu, 'u');
return nu;
}
@@ -620,9 +662,11 @@ static Nurb* rhino_import_nurbs_surf(bContext *C,
}
nu->knotsv[i] = nu->knotsv[i-1];
nu->flagu = analyze_knots(nu->knotsu, nu->pntsu+nu->orderu, nu->orderu, surf->IsPeriodic(0));
- normalize_knots(nu->knotsu, nu->pntsu+nu->orderu);
+ normalize_knots(nu, 'u');
nu->flagv = analyze_knots(nu->knotsv, nu->pntsv+nu->orderv, nu->orderv, surf->IsPeriodic(1));
- normalize_knots(nu->knotsv, nu->pntsv+nu->orderv);
+ normalize_knots(nu, 'v');
+ // If trim curves are deformed on import, check for knot agreement between
+ // this point, after executing the next two calls
BKE_nurb_knot_calc_u(nu);
BKE_nurb_knot_calc_v(nu);
@@ -691,14 +735,9 @@ static void rhino_import_brep_face(bContext *C,
ON_BrepLoop *loop = face->Loop(loopnum);
int trim_count = loop->TrimCount();
printf(" loop: 0x%lx\n",long(loop));
- ListBase *nurb_list;
- if (loop!=outer_loop) {
- LinkedNurbList *lnl = (LinkedNurbList*)MEM_callocN(sizeof(LinkedNurbList),"NURBS trim link");
- BLI_addtail(&nu->inner_trim, lnl);
- nurb_list = &lnl->nurb_list;
- } else {
- nurb_list = &nu->outer_trim;
- }
+ NurbTrim *trim = (NurbTrim*)MEM_callocN(sizeof(NurbTrim),"NURBS_imported_trim");
+ trim->type = (loop==outer_loop)? CU_TRIM_EXTERIOR : CU_TRIM_INTERIOR;
+ ListBase *nurb_list = &trim->nurb_list;
for (int trimnum=0; trimnum<trim_count; trimnum++) {
ON_BrepTrim *trim = loop->Trim(trimnum);
ON_Curve *cu = const_cast<ON_Curve*>(trim->ProxyCurve());
@@ -706,13 +745,7 @@ static void rhino_import_brep_face(bContext *C,
Nurb *trim_nurb = rhino_import_curve(C, cu, parentObj, parentAttrs, false, true, true);
BLI_addtail(nurb_list, trim_nurb);
}
- }
-
- for (LinkedNurbList *lnl = (LinkedNurbList*)nu->inner_trim.first; lnl; lnl=lnl->next) {
- printf("lnl 0x%lx first:0x%lx last:0x%lx\n",lnl,lnl->nurb_list.first,lnl->nurb_list.last);
- for (Nurb *ln=(Nurb*)lnl->nurb_list.first; ln; ln=ln->next) {
- printf("\tln 0x%lx->0x%lx outer_trim:0x%lx inner_trim:0x%lx\n",ln->prev,ln->next,ln->outer_trim.first,ln->inner_trim.first);
- }
+ BLI_addtail(&nu->trims, trim);
}
if (should_destroy_ns) delete ns;
diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h
index 506708ba54b..665b0c2210a 100644
--- a/source/blender/makesdna/DNA_curve_types.h
+++ b/source/blender/makesdna/DNA_curve_types.h
@@ -134,10 +134,11 @@ typedef struct BPoint {
float radius, pad; /* user-set radius per point for beveling etc */
} BPoint;
-typedef struct LinkedNurbList {
- struct LinkedNurbList *prev, *next;
- ListBase nurb_list; /* A list of Nurb objects */
-} LinkedNurbList;
+typedef struct NurbTrim {
+ struct NurbTrim *prev, *next;
+ ListBase nurb_list; /* A list of Nurb objects to trim with */
+ short type; /* NURBS_TRIM_OUTER, NURBS_TRIM_INNER */
+} NurbTrim;
/**
* \note Nurb name is misleading, since it can be used for polygons too,
@@ -148,8 +149,11 @@ typedef struct Nurb {
short type;
short mat_nr; /* index into material list */
short hide, flag;
+
int pntsu, pntsv; /* number of points in the U or V directions */
- short pad[2];
+
+ short pad;
+ short resol_trim; /* tessellation res of trim curve (per pt) */
short resolu, resolv; /* tessellation resolution in the U or V directions */
short orderu, orderv;
short flagu, flagv;
@@ -160,12 +164,15 @@ typedef struct Nurb {
short tilt_interp; /* KEY_LINEAR, KEY_CARDINAL, KEY_BSPLINE */
short radius_interp;
-
int charidx;
- float minu, maxu;
- ListBase outer_trim; /* A list of Nurb objects */
- ListBase inner_trim; /* A list of LinkedNurbList objects */
+ ListBase trims;
+
+ unsigned UV_verts_count; /* UV mesh is cached */
+ unsigned UV_tri_count;
+ float *UV_verts; /* 2*UV_verts_count floats */
+ int *UV_idxs; /* 3*UV_tri_count ints */
+
} Nurb;
typedef struct CharInfo {
@@ -335,6 +342,10 @@ enum {
#define CU_NURBS 4
#define CU_TYPE (CU_POLY|CU_BEZIER|CU_BSPLINE|CU_CARDINAL|CU_NURBS)
+/* trim curve type */
+#define CU_TRIM_INTERIOR 1
+#define CU_TRIM_EXTERIOR 2
+
/* only for adding */
#define CU_PRIMITIVE 0xF00
diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c
index 29f1dd5f29f..2e5792bb8b7 100644
--- a/source/blender/makesrna/intern/rna_curve.c
+++ b/source/blender/makesrna/intern/rna_curve.c
@@ -1677,7 +1677,14 @@ static void rna_def_curve_nurb(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 1, 64, 1, -1);
RNA_def_property_ui_text(prop, "Resolution V", "Surface subdivisions per segment");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
-
+
+ prop = RNA_def_property(srna, "resolution_trim", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "resol_trim");
+ RNA_def_property_range(prop, 1, 1024);
+ RNA_def_property_ui_range(prop, 1, 64, 1, -1);
+ RNA_def_property_ui_text(prop, "Trim Resolution", "Subdivisions per segment of trim curves");
+ RNA_def_property_update(prop, 0, "rna_Curve_update_data");
+
prop = RNA_def_property(srna, "use_cyclic_u", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flagu", CU_NURB_CYCLIC);
RNA_def_property_ui_text(prop, "Cyclic U", "Make this curve or surface a closed loop in the U direction");