[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [17997] branches/nurbs/blender: Laurynas Duburas has supplied another excellent patch.
Emmanuel Stone
emmanuel.stone at gmail.com
Sun Dec 21 20:40:48 CET 2008
Revision: 17997
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17997
Author: eman
Date: 2008-12-21 20:40:47 +0100 (Sun, 21 Dec 2008)
Log Message:
-----------
Laurynas Duburas has supplied another excellent patch.
He's cleaned up the Insert Knots functionality, and written a new Refine function that calculates the best place to subdivide a surface.
Modified Paths:
--------------
branches/nurbs/blender/intern/nurbana/extern/nurbana.h
branches/nurbs/blender/intern/nurbana/intern/NURBS_Construct.cpp
branches/nurbs/blender/intern/nurbana/intern/NURBS_Knot.cpp
branches/nurbs/blender/intern/nurbana/intern/NURBS_Knot.h
branches/nurbs/blender/intern/nurbana/intern/NurbanaMath.cpp
branches/nurbs/blender/intern/nurbana/intern/NurbanaMath.h
branches/nurbs/blender/intern/nurbana/intern/Object_Base.cpp
branches/nurbs/blender/intern/nurbana/intern/Object_Base.h
branches/nurbs/blender/intern/nurbana/intern/Object_NURBS.cpp
branches/nurbs/blender/intern/nurbana/intern/Object_NURBS.h
branches/nurbs/blender/intern/nurbana/intern/libNurbana.cpp
branches/nurbs/blender/source/blender/blenkernel/intern/curve.c
branches/nurbs/blender/source/blender/src/editcurve.c
Modified: branches/nurbs/blender/intern/nurbana/extern/nurbana.h
===================================================================
--- branches/nurbs/blender/intern/nurbana/extern/nurbana.h 2008-12-21 17:44:27 UTC (rev 17996)
+++ branches/nurbs/blender/intern/nurbana/extern/nurbana.h 2008-12-21 19:40:47 UTC (rev 17997)
@@ -39,13 +39,13 @@
typedef float nbReal;
typedef struct nbReal3 {
- nbReal x;
+ nbReal x;
nbReal y;
nbReal z;
}nbReal3;
typedef struct nbReal4 {
- nbReal x;
+ nbReal x;
nbReal y;
nbReal z;
nbReal a;
@@ -53,11 +53,11 @@
typedef struct Point3d {
- nbReal x;
+ nbReal x;
nbReal y;
nbReal z;
nbReal H;
-
+
// This extra data should make Point4d 'struct'rally equivalent to BPoint from Blender::DNA_Data_Types.h
nbReal alfa, weight; /* alfa: tilt in 3D View, weight: used for softbody goal weight */
short f1, hide;
@@ -79,7 +79,7 @@
int numKnotsV;
nbReal *KnotU;
nbReal *KnotV;
- struct ControlPoint *CP;
+ struct ControlPoint *CP;
} Nurb_Extern;
typedef struct ControlPoint {
@@ -104,7 +104,7 @@
extern NurbanaObj_ptr NRB_CreatePrimitive(unsigned char type);
extern void NRB_removeObject(NurbanaObj_ptr nop);
-extern void NRB_changeCyclic(NurbanaObj_ptr nop,int uv);
+extern void NRB_changeCyclic(NurbanaObj_ptr nop,int uv);
@@ -112,9 +112,13 @@
extern void NRB_SizeChanged(NurbanaObj_ptr nop, int newU, int newV);
extern void NRB_UpdateSize(NurbanaObj_ptr nop);
+extern void NRB_setLength(int U, int V, int shiftU, int shiftV, int copyKnots, NurbanaObj_ptr nurb);
+extern void NRB_reallocKnots(int U, int V, int copy, NurbanaObj_ptr nurb);
+extern void NRB_reallocCtlPts(int U, int V, int shiftU, int shiftV, NurbanaObj_ptr nurb);
+
extern void NRB_ConvertToPrimitive(NurbanaObj_ptr nop,unsigned char type);
-extern void NRB_RecalculateKnots(NurbanaObj_ptr nop,int uv,int type);
+extern void NRB_RecalculateKnots(NurbanaObj_ptr nop,int uv,int type);
extern Nurb_ExternPtr NRB_getNurbData(NurbanaObj_ptr nop);
@@ -143,7 +147,8 @@
extern nbReal3_ptr NRB_GenerateNormals(NurbanaObj_ptr nop);
extern void NRB_Subdivide(NurbanaObj_ptr nop,int subdivideU, int subdivideV);
-extern void NRB_Refine(NurbanaObj_ptr nop,nbReal *X, int r, int UV);
+extern void NRB_Refine(NurbanaObj_ptr nop, int U, int V);
+extern void NRB_KnotInsert(NurbanaObj_ptr nop,nbReal *X, int r, int UV);
extern void NRB_DegreeElevate(NurbanaObj_ptr nop,int Uinc, int Vinc);
extern void NRB_DegreeReduce(NurbanaObj_ptr nop,int Udec, int Vdec);
Modified: branches/nurbs/blender/intern/nurbana/intern/NURBS_Construct.cpp
===================================================================
--- branches/nurbs/blender/intern/nurbana/intern/NURBS_Construct.cpp 2008-12-21 17:44:27 UTC (rev 17996)
+++ branches/nurbs/blender/intern/nurbana/intern/NURBS_Construct.cpp 2008-12-21 19:40:47 UTC (rev 17997)
@@ -73,7 +73,7 @@
for (i= 1; i < N; i++) {
NURBS_Knot::Difference(objs[i] -> KnotVector(0), objs[i] -> Length(0)+objs[i] -> Order(0),KVfnl,KVlen,Diff,Difflen);
if (Difflen)
- NURBS_Knot::Refine(objs[i],Diff,Difflen,0);
+ NURBS_Knot::Insert(objs[i],Diff,Difflen,0);
} //eof
// Copy new Points, KnotVector, etc... into obj1
@@ -171,9 +171,9 @@
//
// // Degree Elevate Tmp Surfaces with lower degree
// if (u - tmp1 -> Order(0) || v - tmp1 -> Order(1))
-// NURBS_Degree::Elevate(tmp1,u - tmp1 -> Order(0), v - tmp1 -> Order(1));
+// NURBS_Degree::Elevate(tmp1,u - tmp1 -> Order(0), v - tmp1 -> Order(1));
// if (u - tmp2 -> Order(0) || v - tmp2 -> Order(1))
-// NURBS_Degree::Elevate(tmp2,u - tmp2 -> Order(0), v - tmp2 -> Order(1));
+// NURBS_Degree::Elevate(tmp2,u - tmp2 -> Order(0), v - tmp2 -> Order(1));
//
// obj3 -> Order(0,u);
// obj3 -> Order(1,v);
Modified: branches/nurbs/blender/intern/nurbana/intern/NURBS_Knot.cpp
===================================================================
--- branches/nurbs/blender/intern/nurbana/intern/NURBS_Knot.cpp 2008-12-21 17:44:27 UTC (rev 17996)
+++ branches/nurbs/blender/intern/nurbana/intern/NURBS_Knot.cpp 2008-12-21 19:40:47 UTC (rev 17997)
@@ -126,16 +126,20 @@
/*
Searches for knot span having u.
If u is less than first knot value KnotVector[first], changes u's value to KnotVector[first] and returns appropriate span.
- If u is more than last knot value KnotVector[last], changes u's value to KnotVector[last - 1] and returns appropriate span.
+ If u is more than last knot value KnotVector[last], changes u's value to KnotVector[last - 1] and returns span i: k(i) < u = k(i + 1).
*/
int NURBS_Knot::FindSpanRef(nbReal &u, int first, int last, const nbReal *KnotVector) {
int low = first;
int high = last;
int mid = (low + high) / 2;
- if (u >= KnotVector [last])
+ if (u >= KnotVector [last]) {
u = KnotVector [last - 1];
- else if (u <= KnotVector [first])
+ for (mid = last - 2; mid > first; mid--)
+ if (KnotVector [mid] < u)
+ return mid;
+ }
+ else if (u < KnotVector [first])
u = KnotVector [first];
while (u < KnotVector[mid] || u >= KnotVector[mid+1]) {
@@ -198,14 +202,21 @@
} //eof NURBS_Knot::MergeKnotVectors()
+void NURBS_Knot::FixNewKnots(nbReal *newKnots, int count, nbReal maxValue) {
+ for (int i = count - 1; i >= 0; i--)
+ if (newKnots [i] >= maxValue)
+ newKnots [i] -= maxValue;
+ else break;
+}
-void NURBS_Knot::Refine(Object_NURBS *obj, nbReal *X, int r, bool UV) {
+void NURBS_Knot::Insert(Object_NURBS *obj, nbReal *X, int r, bool UV) {
int i,j,k,l,ind;
Point3d *Qw, *bufferQw, *Curve, *bufferCurve;
nbReal *Ubar, *bufferUbar, *knotVectCpy, *bufferKnotVectCpy, alfa;
const bool cyclic = obj -> Cyclic(UV);//for convenience
const int pitch = (UV ? obj -> Length(0) : obj -> Length(0) + r);
- const int degree = obj -> Order(UV) - 1;
+ const int order = obj -> Order(UV);
+ const int degree = order - 1;
//extra space will be allocated before buffers Qw, Curve and Ubar for cyclics
const int extra = cyclic ? degree : 0;
const int oldKnotCount = obj -> Length(UV) + obj -> Order(UV);
@@ -216,13 +227,18 @@
const int newLength = obj -> Length(UV) + r;
const int first = cyclic ? 0 : degree;
const int last = cyclic ? oldKnotCount - 1 : oldKnotCount - degree - 1;
+ if (cyclic)
+ //FIXME: This function works only with one knot, to work with array of knots
+ // fixed knots should be sorted. Alternatively NURBS_Knot::Insert could be fixed
+ // to accept knots higher than obj -> KnotVector(UV)[obj -> Length(UV)]. Or maybe something else
+ FixNewKnots(X, r, obj -> KnotVector(UV)[obj -> Length(UV)]);
const int a = FindSpanRef(X[0], first, last, obj -> KnotVector(UV));
// Allocate Memory for Qw
- bufferQw = (Point3d*) MEM_callocN(sizeof(Point3d) * (obj -> Length(UV) + r + extra + extra + 1), "Refine() Qw");// + 1 is for Qw[k-degree-1] = Qw[k-degree]
- bufferCurve = (Point3d*) MEM_callocN(sizeof(Point3d) * (obj -> Length(UV) + r + extra + extra), "Refine() Curve");
- bufferUbar = (nbReal*) MEM_callocN(sizeof(nbReal) * (oldKnotCount2 + r + extra), "Refine() Ubar");
- bufferKnotVectCpy = (nbReal*) MEM_callocN(sizeof(nbReal) * (oldKnotCount2 + extra), "Refine() knotVectCpy");
+ bufferQw = (Point3d*) MEM_callocN(sizeof(Point3d) * (obj -> Length(UV) + r + extra + extra + 1), "Insert() Qw");// + 1 is for Qw[k-degree-1] = Qw[k-degree]
+ bufferCurve = (Point3d*) MEM_callocN(sizeof(Point3d) * (obj -> Length(UV) + r + extra + extra), "Insert() Curve");
+ bufferUbar = (nbReal*) MEM_callocN(sizeof(nbReal) * (oldKnotCount2 + r + extra), "Insert() Ubar");
+ bufferKnotVectCpy = (nbReal*) MEM_callocN(sizeof(nbReal) * (oldKnotCount2 + extra), "Insert() knotVectCpy");
//skips extra space, if there is such
Qw = bufferQw + extra + 1;
@@ -233,10 +249,10 @@
//fill knot vector copy(copy by itself is needed only for alfa calculation and Ubar initialization)
memcpy(knotVectCpy, obj -> KnotVector(UV), oldKnotCount2 * sizeof(*knotVectCpy));
//fill extra space around knotVectCpy if cyclic case
- if (extra) {
- nbReal firstK = knotVectCpy [0], lastK = knotVectCpy [oldKnotCount - 1];
+ if (cyclic) {
+ nbReal firstK = knotVectCpy [0], lastK = knotVectCpy [oldKnotCount - order];
for (int i = 1; i <= extra; i++) {
- knotVectCpy [-i] = firstK - (lastK - knotVectCpy [oldKnotCount - i - 1]);
+ knotVectCpy [-i] = firstK - (lastK - knotVectCpy [oldKnotCount - i - order]);
//knotVectCpy [m + i - 1] = lastK + knotVectCpy [i] - firstK;
}
}
@@ -317,7 +333,7 @@
Qw[i + r + 1].x = Curve[i].x;
Qw[i + r + 1].y = Curve[i].y;
Qw[i + r + 1].z = Curve[i].z;
- Qw[i + r + 1].H = Curve[i].H;
+ Qw[i + r + 1].H = Curve[i].H;
} //eof
//copies starting knots to Ubar
@@ -364,9 +380,10 @@
} //eof
Ubar[k]= X[j];
//newly inserted knot appears at the end of knot vector also ...
- if (cyclic && (b < 2 * degree)) {
+ if (cyclic && (b <= 2 * degree)) {
//shift virtual knots
- memmove(Ubar + newKnotCount + b - degree, Ubar + newKnotCount + b - degree - 1, (2 * degree - b) * sizeof(*Ubar));
+ if (2 * degree - b)
+ memmove(Ubar + newKnotCount + b - degree, Ubar + newKnotCount + b - degree - 1, (2 * degree - b) * sizeof(*Ubar));
// and write down new one
Ubar[newKnotCount + b - degree - 1] = obj -> KnotVector(UV)[oldKnotCount - degree + r - j - 1] + X[j];
//FIXME knotVectCpy also needs update for multiple inserts
@@ -401,7 +418,7 @@
oldPoints -> z = Qw[i].z;
oldPoints -> H = Qw[i].H;
if (1.0 != oldPoints -> H) {
- nbReal w = 1.0 / oldPoints -> H;//FIXME
+ nbReal w = 1.0 / oldPoints -> H;//FIXME
oldPoints -> x *= w;
oldPoints -> y *= w;
oldPoints -> z *= w;
@@ -415,7 +432,7 @@
oldPoints -> z = Qw[i].z;
oldPoints -> H = Qw[i].H;
if (1.0 != oldPoints -> H) {
- nbReal w = 1.0 / oldPoints -> H;//FIXME
+ nbReal w = 1.0 / oldPoints -> H;//FIXME
oldPoints -> x *= w;
oldPoints -> y *= w;
oldPoints -> z *= w;
@@ -428,7 +445,7 @@
memcpy(obj -> KnotVector(UV), Ubar, newKnotCount2 * sizeof(*Ubar));
obj -> Length(UV, newLength);
- obj -> SetCacheTessBuffer();
+ obj -> SetCacheBuffer();
MEM_freeN(bufferQw);
MEM_freeN(bufferCurve);
MEM_freeN(bufferUbar);
@@ -438,7 +455,7 @@
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list