From a5a4360d3212eb9cd0b02407458c72c24560e873 Mon Sep 17 00:00:00 2001 From: Jonathan deWerd Date: Wed, 30 Jul 2014 19:24:14 -0400 Subject: Trim curve import works! They don't rescale to blender-style knots automatically yet, so they're fragile to edits. --- source/blender/blenkernel/BKE_curve.h | 2 + source/blender/blenkernel/intern/curve.cpp | 84 ++++++++++++++++++++++++------ 2 files changed, 71 insertions(+), 15 deletions(-) diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index 98f1b8ccb81..c0766dd2eae 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -168,6 +168,7 @@ void BKE_nurbList_flag_set(ListBase *editnurb, short flag); void BKE_nurbTrim_free(struct NurbTrim *nt); struct NurbTrim *BKE_nurbTrim_duplicate(struct NurbTrim *nt); +int BKE_nurbTrim_tess(struct NurbTrim *nt, int resolution, float (**uv)[2]); // Returns: # verts in uv void BKE_nurb_free(struct Nurb *nu); struct Nurb *BKE_nurb_duplicate(struct Nurb *nu); @@ -175,6 +176,7 @@ struct Nurb *BKE_nurb_copy(struct Nurb *src, int pntsu, int pntsv); void BKE_nurb_ensure2D(struct Nurb *nu); void BKE_nurb_minmax(struct Nurb *nu, bool use_radius, float min[3], float max[3]); +void BKE_nurb_domain(struct Nurb *nu, float *umin, float *umax, float *vmin, float *vmax); 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); diff --git a/source/blender/blenkernel/intern/curve.cpp b/source/blender/blenkernel/intern/curve.cpp index c739008117e..582140d9827 100644 --- a/source/blender/blenkernel/intern/curve.cpp +++ b/source/blender/blenkernel/intern/curve.cpp @@ -539,9 +539,14 @@ void BKE_nurb_free(Nurb *nu) MEM_freeN(nu->knotsv); nu->knotsv = NULL; - for (NurbTrim *nt = (NurbTrim*)nu->trims.first; nt; nt=nt->next) { - BKE_nurbTrim_free(nt); + for (NurbTrim *nt = (NurbTrim*)nu->trims.first; nt;) { + NurbTrim *nt_to_free = nt; + nt = nt->next; + BKE_nurbTrim_free(nt_to_free); } + + if (nu->UV_idxs) MEM_freeN(nu->UV_idxs); + if (nu->UV_verts) MEM_freeN(nu->UV_verts); MEM_freeN(nu); } @@ -642,6 +647,35 @@ NurbTrim *BKE_nurbTrim_duplicate(NurbTrim *nt) { return ret; } +int BKE_nurbTrim_tess(struct NurbTrim *nt, int resolution, float (**uv_out)[2]) { + int tot_tess_pts = 0; + for (Nurb* nu = (Nurb*)nt->nurb_list.first; nu; nu=nu->next) { + tot_tess_pts += nu->pntsu * resolution + 1; + } + float (*uv)[2] = (float(*)[2])MEM_mallocN(sizeof(*uv)*tot_tess_pts, "BKE_nurbTrim_tess"); + *uv_out = uv; + for (Nurb* nu = (Nurb*)nt->nurb_list.first; nu; nu=nu->next) { + float *U = nu->knotsu; + int pntsu = nu->pntsu; + BPoint *bp = nu->bp; + int orderu = nu->orderu; + int tess_pts = nu->pntsu * resolution + 1; + float umin, umax; + BKE_nurb_domain(nu, &umin, &umax, NULL, NULL); + float du = (umax-umin)/(tess_pts-1); + for (int i=0; i<=tess_pts; i++) { + BPoint pt; + float u = (iknotsu[nu->pntsu + nu->orderu - 1]; else *umax = nu->knotsu[nu->pntsu]; - *vmin = nu->knotsv[nu->orderv - 1]; - if (nu->flagv & CU_NURB_CYCLIC) - *vmax = nu->knotsv[nu->pntsv + nu->orderv - 1]; - else - *vmax = nu->knotsv[nu->pntsv]; *umin = std::min(nu->knotsu[0], *umin); *umax = std::max(nu->knotsu[nu->pntsu+nu->orderu-1], *umax); - *vmin = std::min(nu->knotsv[0], *umin); - *vmax = std::max(nu->knotsv[nu->pntsv+nu->orderv-1], *umax); + if (nu->knotsv) { + *vmin = nu->knotsv[nu->orderv - 1]; + if (nu->flagv & CU_NURB_CYCLIC) + *vmax = nu->knotsv[nu->pntsv + nu->orderv - 1]; + else + *vmax = nu->knotsv[nu->pntsv]; + if (vmin) *vmin = std::min(nu->knotsv[0], *umin); + if (vmin) *vmax = std::max(nu->knotsv[nu->pntsv+nu->orderv-1], *umax); + } } 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; @@ -4039,8 +4075,23 @@ void BKE_nurb_compute_trimmed_UV_mesh(struct Nurb* nu) { } gm->set_ll_ur(ustart,vstart,uend,vend); gm->init_grid(totu,totv); - int s0poly = gm->poly_new(subj0, subj0_nv*2); - gm->bool_SUB(s0poly); + + // Trim + if (nu->resol_trim<1) nu->resol_trim = 1; + for (NurbTrim *nt=(NurbTrim*)nu->trims.first; nt; nt=nt->next) { + float (*trim_uv_pts)[2]; + int num_trimpts = BKE_nurbTrim_tess(nt, nu->resol_trim, &trim_uv_pts); + int trim_poly = gm->poly_new((float*)trim_uv_pts, num_trimpts*2); + switch (nt->type) { + case CU_TRIM_EXTERIOR: + gm->bool_AND(trim_poly); + break; + case CU_TRIM_INTERIOR: + default: + gm->bool_SUB(trim_poly); + } + MEM_freeN(trim_uv_pts); + } // Extract the results std::map *used_idxs; @@ -4054,16 +4105,19 @@ void BKE_nurb_compute_trimmed_UV_mesh(struct Nurb* nu) { int idxs_len = 4 * 3*sizeof(int)*totu*totv; int *idxs = (int*)MEM_mallocN(sizeof(int)*idxs_len, "NURBS_tess_2.0"); int ii=0; // Index index -#define TESS_MAX_POLY_VERTS 32 +#define TESS_MAX_POLY_VERTS 1024 float coords_tmp[TESS_MAX_POLY_VERTS][2]; int reindex_tmp[TESS_MAX_POLY_VERTS]; unsigned idx_tmp[TESS_MAX_POLY_VERTS][3]; std::vector degenerate_polys; - // Loop through every cell and push its triangles onto idxs + + // Loop through every cell, triangulate its polys, push them onto idxs for (int j=0; jpoly_for_cell(i, j); GridMeshVert *v = &gm->v[0]; + + // for (int poly=cell; poly; poly=v[poly].next_poly) { if (!v[poly].next) { continue; @@ -4152,8 +4206,8 @@ void BKE_nurb_compute_trimmed_UV_mesh(struct Nurb* nu) { 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); + if (nu->UV_verts) MEM_freeN(nu->UV_verts); + if (nu->UV_idxs) MEM_freeN(nu->UV_idxs); } } -- cgit v1.2.3