[Bf-committers] help needed to cleanup bezier code "makeCyclic()"

Dietrich Bollmann diresu at web.de
Sat Jun 21 13:38:33 CEST 2008


Hi,

I wrote a python function makeCyclic() for bezier curves using the
function makecyclicNurb() from file source/blender/src/editcurve.c
with only minimal changes.

It works - but I have to admit, that I do not really understand the
copy-and-pasted code in all its details :)

As the original code was written for the Blender gui I am quite sure
that not all of it is needed in the Python version of the original
function.

Is there anybody who could help me to clean up the function from all
things not necessary in the python version so that I could make it a
useful patch?

Another problem is that the code is duplicated in the sources: 
once in source/blender/src/editcurve.c
once more in source/blender/python/api2_2x/CurNurb.c .

Probably it would be nicer to write some general function, add it to
source/blender/blenkernel/intern/curve.c and make the code in
editcurve.c and CurNurb.c rely on it rather than having everything
twice.

Any idea how to separate out a general function?

Thanks, Dietrich

PS: I send this code to bf-committers rather than to bf-python
as it deals to 95% with the bezier code and only to a small
percentage with the python API.

Here an example of how to use the function makeCyclic():

dietrich at pippi:~/blendev/working/branches/pyg/blender $ blender --bcp
5555 --geometry 500x400+0+500 &
dietrich at pippi:~/blendev/working/branches/pyg/blender $ blash --port
5555
This is Blash - the GNU BLender-Again SHell :)
Handling client 127.0.0.1
Connection to Blender Server established.   (IP address: 127.0.0.1,
port: 5555)
>>> 
>>> from Blender import *
>>> 
>>> def makeBezTriple(p): 
...         bt = BezTriple.New(p[0], p[1], p[2])
...         bt.handleTypes = (BezTriple.HandleTypes.AUTO,
BezTriple.HandleTypes.AUTO) 
...         return bt
... 
>>> def makeBezier(points, scene):
...         cu = Curve.New()
...         bt = makeBezTriple(points[0])
...         cu.appendNurb(bt)
...         for p in points[1:]:
...                 bt = makeBezTriple(p)
...                 cu[0].append(bt)
...         cu.update()
...         obj = scene.objects.new(cu)
...         return obj
... 
>>> # making the bezier curve
>>> scene = Scene.GetCurrent()
>>> points = [(1, 1, 0), (-1, 1, 0), (-1, -1, 0), (1, -1, 0)]
>>> b = makeBezier(points, scene)
>>> Redraw()
>>> 
>>> # making it cyclic
>>> b.data[0].isCyclic()
False
>>> b.data[0].makeCyclic()
>>> b.data.update()
>>> Redraw()
>>> b.data[0].isCyclic()
True
>>> 

Here is the code - Note that I also appended a path to this email:

/**
 * CurNurb_makeCyclic()
 * 
 * Make this spline cyclic (closed)
 * 
 * Reusing the code from function `makecyclicNurb()'
 * file source/blender/src/editcurve.c
 * 
 * Dietrich Bollmann (dietrich)
 */
static PyObject *CurNurb_makeCyclic( BPy_CurNurb * self )
{
	printf("hi dietrich :)");

	// make the curve cyclic
	makecyclicNurb2(self->nurb);

	return Py_None;
}

/**
 * makecyclicNurb2()
 * 
 * make this spline cyclic (closed)
 * 
 * An adapted copy of function `makecyclicNurb()'
 * file source/blender/src/editcurve.c
 * 
 * Dietrich Bollmann (dietrich)
 */
void makecyclicNurb2(Nurb *nu)
{
	BezTriple *bezt;
	BPoint *bp;
	float *fp;
	int a, b, cyclmode=0;

	if( nu->pntsu>1 || nu->pntsv>1) {
		if( (nu->type & 7)==0 ) {
			a= nu->pntsu;
			bp= nu->bp;
			while(a--) {
				if( bp->f1 & SELECT ) {
					if(nu->flagu & CU_CYCLIC) nu->flagu--;
					else nu->flagu++;
					break;
				}
				bp++;
			}
		}
		else if( (nu->type & 7)==CU_BEZIER ) {
			a= nu->pntsu;
			bezt= nu->bezt;
			while(a--) {
				if( BEZSELECTED_HIDDENHANDLES(bezt) ) {
					if(nu->flagu & CU_CYCLIC) nu->flagu--;
					else nu->flagu++;
					break;
				}
				bezt++;
			}
			calchandlesNurb(nu);
		}
		else if(nu->pntsv==1 && (nu->type & 7)==CU_NURBS) {
			a= nu->pntsu;
			bp= nu->bp;
			while(a--) {
				if( bp->f1 & SELECT ) {
					if(nu->flagu & CU_CYCLIC) nu->flagu--;
					else {
						nu->flagu++;
						nu->flagu &= ~2;	/* endpoint flag, fixme */
						fp= MEM_mallocN(sizeof(float)*KNOTSU(nu), "makecyclicN");
						b= (nu->orderu+nu->pntsu);
						memcpy(fp, nu->knotsu, sizeof(float)*b);
						MEM_freeN(nu->knotsu);
						nu->knotsu= fp;
							
						makeknots(nu, 1, 0);	/* 1==u  0==uniform */
							
					}
					break;
				}
				bp++;
			}
		}
		else if(nu->type==CU_NURBS) {
			a= nu->pntsu*nu->pntsv;
			bp= nu->bp;
			while(a--) {
	
				if( bp->f1 & SELECT) {
					if(cyclmode==1 && nu->pntsu>1) {
						if(nu->flagu & CU_CYCLIC) nu->flagu--;
						else {
							nu->flagu++;
							fp= MEM_mallocN(sizeof(float)*KNOTSU(nu), "makecyclicN");
							b= (nu->orderu+nu->pntsu);
							memcpy(fp, nu->knotsu, sizeof(float)*b);
							MEM_freeN(nu->knotsu);
							nu->knotsu= fp;
								
							makeknots(nu, 1, 0);	/* 1==u  0==uniform */
						}
					}
					if(cyclmode==2 && nu->pntsv>1) {
						if(nu->flagv & 1) nu->flagv--;
						else {
							nu->flagv++;
							fp= MEM_mallocN(sizeof(float)*KNOTSV(nu), "makecyclicN");
							b= (nu->orderv+nu->pntsv);
							memcpy(fp, nu->knotsv, sizeof(float)*b);
							MEM_freeN(nu->knotsv);
							nu->knotsv= fp;
								
							makeknots(nu, 2, 0);	/* 2==v  0==uniform */
						}
					}
					break;
				}
				bp++;
			}
		}
	}
}


-------------- next part --------------
A non-text attachment was scrubbed...
Name: make-cyclic.txt
Type: text/x-patch
Size: 4940 bytes
Desc: not available
Url : http://lists.blender.org/pipermail/bf-committers/attachments/20080621/5fb89eaa/attachment.bin 


More information about the Bf-committers mailing list