[Bf-blender-cvs] [7a75489] soc-2014-nurbs: Putting it all together: {BSpline, NURBS} values+derivates calculate & verify with Mathematica, smooth normals display properly.
Jonathan deWerd
noreply at git.blender.org
Sat Jul 26 20:47:55 CEST 2014
Commit: 7a75489f86d5892788626fb3da759b7ef6c053e9
Author: Jonathan deWerd
Date: Wed Jul 23 23:50:32 2014 -0400
Branches: soc-2014-nurbs
https://developer.blender.org/rB7a75489f86d5892788626fb3da759b7ef6c053e9
Putting it all together: {BSpline,NURBS} values+derivates calculate & verify with Mathematica, smooth normals display properly.
===================================================================
M source/blender/blenkernel/BKE_curve.h
M source/blender/blenkernel/BKE_displist.h
M source/blender/blenkernel/intern/curve.cpp
M source/blender/blenkernel/intern/curve_eval.cpp
M source/blender/blenkernel/intern/displist.c
M source/blender/editors/space_view3d/drawobject.c
M tests/interactive/curve_eval.h
M tests/interactive/nurbs_derivative_eval.cpp
M tests/interactive/nurbs_eval.nb
===================================================================
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index 378e3c0..f689175 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -47,6 +47,7 @@ struct Path;
struct TextBox;
struct rctf;
struct DispList;
+typedef struct BPoint BPoint;
typedef struct CurveCache {
ListBase disp;
@@ -56,6 +57,12 @@ typedef struct CurveCache {
#define NURBS_MAX_ORDER 10
+typedef struct BSplineCache {
+ float u;
+ int iu;
+ float Nu[NURBS_MAX_ORDER][NURBS_MAX_ORDER];
+} BSplineCacheU;
+
#define KNOTSU(nu) ( (nu)->orderu + (nu)->pntsu + (((nu)->flagu & CU_NURB_CYCLIC) ? ((nu)->orderu - 1) : 0) )
#define KNOTSV(nu) ( (nu)->orderv + (nu)->pntsv + (((nu)->flagv & CU_NURB_CYCLIC) ? ((nu)->orderv - 1) : 0) )
@@ -123,8 +130,28 @@ void BKE_curve_forward_diff_bezier(float q0, float q1, float q2, float q3, float
void BKE_curve_rect_from_textbox(const struct Curve *cu, const struct TextBox *tb, struct rctf *r_rect);
/* ** Nurbs ** */
+#ifdef __cplusplus
+#define DEFAULT_FALSE =false
+#define DEFAULT_NULL =NULL
+#else
+#define DEFAULT_FALSE
+#define DEFAULT_NULL
+#endif
+void BKE_bspline_knot_calc(int flags, int pnts, int order, float knots[]);
int BKE_bspline_nz_basis_range(float u, float *knots, int num_pts, int order);
-void BKE_bspline_basis_eval(float u, int i, float *U, int num_pts, int order, int nd, float out[][NURBS_MAX_ORDER]);
+void BKE_bspline_basis_eval(float u, int i, float *U, int num_knots, int order, int nd, float out[][NURBS_MAX_ORDER]);
+void BKE_bspline_curve_eval(float u, float *U, int num_pts, int order, BPoint *P, int stride, int nd, BPoint *out, bool premultiply_weight DEFAULT_FALSE);
+void BKE_nurbs_curve_eval(float u, float *U, int num_pts, int order, BPoint *P, int stride, int nd, BPoint *out);
+void BKE_bspline_surf_eval(float u, float v,
+ int pntsu, int orderu, float *U,
+ int pntsv, int orderv, float *V,
+ BPoint *P, int nd, BPoint *out,
+ bool premultiply_weights DEFAULT_FALSE, BSplineCacheU *ucache DEFAULT_NULL);
+void BKE_nurbs_surf_eval(float u, float v,
+ int pntsu, int orderu, float *U,
+ int pntsv, int orderv, float *V,
+ BPoint *P, int nd, BPoint *out, BSplineCacheU *ucache DEFAULT_NULL);
+
bool BKE_nurbList_index_get_co(struct ListBase *editnurb, const int index, float r_co[3]);
@@ -149,7 +176,6 @@ 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_knot_calc(int flags, int pnts, int order, float knots[]);
void BKE_nurb_knot_calc_u(struct Nurb *nu);
void BKE_nurb_knot_calc_v(struct Nurb *nu);
diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h
index 0afc457..bcda5e8 100644
--- a/source/blender/blenkernel/BKE_displist.h
+++ b/source/blender/blenkernel/BKE_displist.h
@@ -69,7 +69,8 @@ typedef struct DispList {
struct DispList *next, *prev;
short type, flag;
int parts, nr;
- short col, rt; /* rt used by initrenderNurbs */
+ short col;
+ short rt; /* CU_SMOOTH: smooth normals */
float *verts, *nors;
int *index;
int charidx;
diff --git a/source/blender/blenkernel/intern/curve.cpp b/source/blender/blenkernel/intern/curve.cpp
index 7c6d559..57bece1 100644
--- a/source/blender/blenkernel/intern/curve.cpp
+++ b/source/blender/blenkernel/intern/curve.cpp
@@ -150,7 +150,7 @@ void BKE_nurb_knot_calc_u(Nurb *nu)
{
int pnts=nu->pntsu, order=nu->orderu;
float *knots = (float*)MEM_mallocN(sizeof(float)*(pnts+2*order), "NURB_knots_u");
- BKE_nurb_knot_calc(nu->flagu, pnts, order, knots);
+ BKE_bspline_knot_calc(nu->flagu, pnts, order, knots);
if (nu->knotsu) MEM_freeN(nu->knotsu);
nu->knotsu = knots;
}
@@ -159,7 +159,7 @@ void BKE_nurb_knot_calc_v(Nurb *nu)
{
int pnts=nu->pntsv, order=nu->orderv;
float *knots = (float*)MEM_mallocN(sizeof(float)*(pnts+2*order), "NURB_knots_v");
- BKE_nurb_knot_calc(nu->flagv, pnts, order, knots);
+ BKE_bspline_knot_calc(nu->flagv, pnts, order, knots);
if (nu->knotsv) MEM_freeN(nu->knotsv);
nu->knotsv = knots;
}
@@ -4006,7 +4006,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;
+ GridMeshCoord *coords=NULL, *nors=NULL;
if (!remap_coords) {
coords = (GridMeshCoord*)MEM_mallocN(coords_len * sizeof(GridMeshCoord), "NURBS_tess_1");
gm->mallocN = MEM_mallocN;
@@ -4101,6 +4101,7 @@ 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();
@@ -4116,56 +4117,26 @@ void BKE_nurb_make_displist(struct Nurb *nu, struct DispList *dl) {
}
dl->verts = (float*)coords;
dl->index = idxs;
- dl->nors = NULL;
+ 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
- float basisu[2][NURBS_MAX_ORDER], basisv[2][NURBS_MAX_ORDER];
- memset(basisu, 0xFF, sizeof(basisu));
- memset(basisv, 0xFF, sizeof(basisv));
- int iu, iv;
- int orderu=nu->orderu, orderv=nu->orderv, pntsu=nu->pntsu, pntsv=nu->pntsv;
- int coord=0;
- float cached_v=0.0/0.0;
- for (; coord<coords_len; coord++) {
+ BSplineCacheU cacheU;
+ cacheU.u = 1.0/0; // First eval should always miss
+ for (int coord=0; coord<coords_len; coord++) {
float *xyz = (float*)&coords[coord];
- // Right now xyz = {u,v,0.0}. Apply the NURBS map to transform it to {x,y,z}
- if (xyz[1]!=cached_v) {
- /* only N(i-p)p, N(i-p+1)p, ..., Nip are nz*/
- iv = BKE_bspline_nz_basis_range(xyz[1], nu->knotsv, nu->pntsv, orderv);
- BKE_bspline_basis_eval(xyz[1], iv, nu->knotsv, nu->pntsv, orderv, 1, basisv);
- if (xyz[0]>0.75) {
- printf("vcoeff(%f): ",xyz[1]);
- for (int l=0; l<orderv; l++)
- printf((l!=orderv-1)?"%f, ":"%f\n",basisv[0][l]);
- }
- cached_v = xyz[1];
- }
- iu = BKE_bspline_nz_basis_range(xyz[0], nu->knotsu, nu->pntsu, orderu);
- BKE_bspline_basis_eval(xyz[0], iu, nu->knotsu, nu->pntsu, orderu, 1, basisu);
- if (xyz[0]>0.75) {
- printf("ucoeff(%f): ",xyz[0]);
- for (int l=0; l<orderu; l++)
- printf((l!=orderu-1)?"%f, ":"%f\n",basisu[0][l]);
- }
- cached_v = xyz[1];
- float accum[3] = {0,0,0};
- float hom_denominator = 0;
- for (int vi=0; vi<orderv; vi++) {
- for (int ui=0; ui<orderu; ui++) {
- float Nu=basisu[0][ui], Nv=basisv[0][vi];
- int ptu = iu-(orderu-1)+ui;
- int ptv = iv-(orderv-1)+vi;
- BPoint& ctrlpt = nu->bp[ptu+pntsu*ptv];
- float hom_wt = Nu*Nv*ctrlpt.vec[3];
- hom_denominator += hom_wt;
- float wcp[3]; mul_v3_v3fl(wcp, ctrlpt.vec, hom_wt);
- add_v3_v3(accum, wcp);
- }
- }
- mul_v3_v3fl(xyz, accum, 1/hom_denominator);
+ float *norm = (float*)&nors[coord];
+ BPoint out[3]; // { surf_pt, u_partial_deriv, v_partal_deriv }
+ BKE_nurbs_surf_eval(xyz[0], xyz[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);
}
// Cleanup
diff --git a/source/blender/blenkernel/intern/curve_eval.cpp b/source/blender/blenkernel/intern/curve_eval.cpp
index cbd2396..781974a 100644
--- a/source/blender/blenkernel/intern/curve_eval.cpp
+++ b/source/blender/blenkernel/intern/curve_eval.cpp
@@ -38,6 +38,7 @@
extern "C" {
#include "BKE_curve.h"
#include "DNA_curve_types.h"
+#include "BLI_math.h"
}
#endif
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 55b8ae5..9d741ec 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -1262,7 +1262,6 @@ void BKE_displist_make_surf(Scene *scene, Object *ob, ListBase *dispbase,
uint64_t timer_stop = mach_absolute_time();
int t = timer_stop-timer_start;
nu = nubase.first;
- printf("%i %i %i %i\n",len,nu->pntsu*nu->resolu,nu->pntsv*nu->resolv,t);
BKE_nurbList_free(&nubase);
}
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index a0f6d0d..400e934 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -4244,6 +4244,7 @@ static void drawDispListsolid(ListBase *lb, Object *ob, const short dflag,
}
else
glNormal3fv(ndata);
+ if (dl->rt & CU_SMOOTH) glShadeModel(GL_SMOOTH);
glDrawElements(GL_TRIANGLES, 3 * dl->parts, GL_UNSIGNED_INT, dl->index);
diff --git a/tests/interactive/curve_eval.h b/tests/interactive/curve_eval.h
index 8dbe657..d48f347 100644
--- a/tests/interactive/curve_eval.h
+++ b/tests/interactive/curve_eval.h
@@ -41,7 +41,7 @@ typedef struct BPoint {
* so that a surface patch only has to evaluate once per row. We could do
* this with columns, too, but at a much worse space/time tradeoff.
*/
-typedef struct BSplineCache {
+typedef struct BSplineCacheU {
float u;
int iu;
float Nu[NURBS_MAX_ORDER][NURBS_MAX_ORDER];
@@ -58,6 +58,10 @@ extern "C" {
int pntsv, int orderv, float *V,
BPoint *P, int nd, BPoint *out,
bool premultiply_weights=false, BSplineCacheU *ucache=NULL);
+ void BKE_nurbs_surf_eval(float u, float v,
+ int pntsu, int orderu, float *U,
+ int pntsv, int orderv, float *V,
+ BPoint *P, int nd, BPoint *out, BSplineCacheU *ucache=NULL);
}
inline void madd_v4_v4fl(float r[4], const float a[4], float f)
diff --git a/tests/interactive/nurbs_derivative_eval.cpp b/te
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list