示例#1
0
文件: view3d_snap.c 项目: jinjoh/NOOR
static int snap_sel_to_grid(bContext *C, wmOperator *op)
{
	extern float originmat[3][3];	/* XXX object.c */
	Object *obedit= CTX_data_edit_object(C);
	Scene *scene= CTX_data_scene(C);
	View3D *v3d= CTX_wm_view3d(C);
	TransVert *tv;
	Object *ob;
	float gridf, imat[3][3], bmat[3][3], vec[3];
	int a;

	gridf= v3d->gridview;

	if(obedit) {
		tottrans= 0;
		
		if ELEM6(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) 
			make_trans_verts(obedit, bmat[0], bmat[1], 0);
		if(tottrans==0) return OPERATOR_CANCELLED;
		
		Mat3CpyMat4(bmat, obedit->obmat);
		Mat3Inv(imat, bmat);
		
		tv= transvmain;
		for(a=0; a<tottrans; a++, tv++) {
			
			VECCOPY(vec, tv->loc);
			Mat3MulVecfl(bmat, vec);
			VecAddf(vec, vec, obedit->obmat[3]);
			vec[0]= v3d->gridview*floor(.5+ vec[0]/gridf);
			vec[1]= v3d->gridview*floor(.5+ vec[1]/gridf);
			vec[2]= v3d->gridview*floor(.5+ vec[2]/gridf);
			VecSubf(vec, vec, obedit->obmat[3]);
			
			Mat3MulVecfl(imat, vec);
			VECCOPY(tv->loc, vec);
		}
		
		special_transvert_update(scene, obedit);
		
		MEM_freeN(transvmain);
		transvmain= NULL;
	
	}
	else {
示例#2
0
文件: anim.c 项目: jinjoh/NOOR
static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int level, int animated)
{
	DupliObject *dob;
	Group *group;
	GroupObject *go;
	float mat[4][4], tmat[4][4];
	
	if(ob->dup_group==NULL) return;
	group= ob->dup_group;
	
	/* simple preventing of too deep nested groups */
	if(level>MAX_DUPLI_RECUR) return;
	
	/* handles animated groups, and */
	/* we need to check update for objects that are not in scene... */
	group_handle_recalc_and_update(scene, ob, group);
	animated= animated || group_is_animated(ob, group);
	
	for(go= group->gobject.first; go; go= go->next) {
		/* note, if you check on layer here, render goes wrong... it still deforms verts and uses parent imat */
		if(go->ob!=ob) {
			
			/* Group Dupli Offset, should apply after everything else */
			if (group->dupli_ofs[0] || group->dupli_ofs[1] || group->dupli_ofs[2]) {
				Mat4CpyMat4(tmat, go->ob->obmat);
				VecSubf(tmat[3], tmat[3], group->dupli_ofs);
				Mat4MulMat4(mat, tmat, ob->obmat);
			} else {
				Mat4MulMat4(mat, go->ob->obmat, ob->obmat);
			}
			
			dob= new_dupli_object(lb, go->ob, mat, ob->lay, 0, OB_DUPLIGROUP, animated);
			dob->no_draw= (dob->origlay & group->layer)==0;
			
			if(go->ob->transflag & OB_DUPLI) {
				Mat4CpyMat4(dob->ob->obmat, dob->mat);
				object_duplilist_recursive((ID *)group, scene, go->ob, lb, ob->obmat, level+1, animated);
				Mat4CpyMat4(dob->ob->obmat, dob->omat);
			}
		}
	}
}
示例#3
0
static int precache_resolution(VolumePrecache *vp, float *bbmin, float *bbmax, int res)
{
	float dim[3], div;
	
	VecSubf(dim, bbmax, bbmin);
	
	div = MAX3(dim[0], dim[1], dim[2]);
	dim[0] /= div;
	dim[1] /= div;
	dim[2] /= div;
	
	vp->res[0] = dim[0] * (float)res;
	vp->res[1] = dim[1] * (float)res;
	vp->res[2] = dim[2] * (float)res;
	
	if ((vp->res[0] < 1) || (vp->res[1] < 1) || (vp->res[2] < 1))
		return 0;
	
	return 1;
}
示例#4
0
文件: volumetric.c 项目: jinjoh/NOOR
/* trilinear interpolation */
static void vol_get_precached_scattering(ShadeInput *shi, float *scatter_col, float *co)
{
	VolumePrecache *vp = shi->obi->volume_precache;
	float bbmin[3], bbmax[3], dim[3];
	float sample_co[3];
	
	if (!vp) return;
	
	/* convert input coords to 0.0, 1.0 */
	VECCOPY(bbmin, shi->obi->obr->boundbox[0]);
	VECCOPY(bbmax, shi->obi->obr->boundbox[1]);
	VecSubf(dim, bbmax, bbmin);

	sample_co[0] = ((co[0] - bbmin[0]) / dim[0]);
	sample_co[1] = ((co[1] - bbmin[1]) / dim[1]);
	sample_co[2] = ((co[2] - bbmin[2]) / dim[2]);

	scatter_col[0] = voxel_sample_triquadratic(vp->data_r, vp->res, sample_co);
	scatter_col[1] = voxel_sample_triquadratic(vp->data_g, vp->res, sample_co);
	scatter_col[2] = voxel_sample_triquadratic(vp->data_b, vp->res, sample_co);
}
示例#5
0
文件: anim.c 项目: jinjoh/NOOR
static void vertex_dupli__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
{
	DupliObject *dob;
	struct vertexDupliData *vdd= userData;
	float vec[3], q2[4], mat[3][3], tmat[4][4], obmat[4][4];
	
	VECCOPY(vec, co);
	Mat4MulVecfl(vdd->pmat, vec);
	VecSubf(vec, vec, vdd->pmat[3]);
	VecAddf(vec, vec, vdd->obmat[3]);
	
	Mat4CpyMat4(obmat, vdd->obmat);
	VECCOPY(obmat[3], vec);
	
	if(vdd->par->transflag & OB_DUPLIROT) {
		if(no_f) {
			vec[0]= -no_f[0]; vec[1]= -no_f[1]; vec[2]= -no_f[2];
		}
		else if(no_s) {
			vec[0]= -no_s[0]; vec[1]= -no_s[1]; vec[2]= -no_s[2];
		}
		
		vectoquat(vec, vdd->ob->trackflag, vdd->ob->upflag, q2);
		
		QuatToMat3(q2, mat);
		Mat4CpyMat4(tmat, obmat);
		Mat4MulMat43(obmat, tmat, mat);
	}
	dob= new_dupli_object(vdd->lb, vdd->ob, obmat, vdd->par->lay, index, OB_DUPLIVERTS, vdd->animated);
	if(vdd->orco)
		VECCOPY(dob->orco, vdd->orco[index]);
	
	if(vdd->ob->transflag & OB_DUPLI) {
		float tmpmat[4][4];
		Mat4CpyMat4(tmpmat, vdd->ob->obmat);
		Mat4CpyMat4(vdd->ob->obmat, obmat); /* pretend we are really this mat */
		object_duplilist_recursive((ID *)vdd->id, vdd->scene, vdd->ob, vdd->lb, obmat, vdd->level+1, vdd->animated);
		Mat4CpyMat4(vdd->ob->obmat, tmpmat);
	}
}
示例#6
0
static void precache_init_parts(Render *re, RayObject *tree, ShadeInput *shi, ObjectInstanceRen *obi, int totthread, int *parts)
{
	VolumePrecache *vp = obi->volume_precache;
	int i=0, x, y, z;
	float voxel[3];
	int sizex, sizey, sizez;
	float *bbmin=obi->obr->boundbox[0], *bbmax=obi->obr->boundbox[1];
	int *res;
	int minx, maxx;
	int miny, maxy;
	int minz, maxz;
	
	if (!vp) return;

	BLI_freelistN(&re->volume_precache_parts);
	
	/* currently we just subdivide the box, number of threads per side */
	parts[0] = parts[1] = parts[2] = totthread;
	res = vp->res;
	
	VecSubf(voxel, bbmax, bbmin);
	
	voxel[0] /= res[0];
	voxel[1] /= res[1];
	voxel[2] /= res[2];

	for (x=0; x < parts[0]; x++) {
		sizex = ceil(res[0] / (float)parts[0]);
		minx = x * sizex;
		maxx = minx + sizex;
		maxx = (maxx>res[0])?res[0]:maxx;
		
		for (y=0; y < parts[1]; y++) {
			sizey = ceil(res[1] / (float)parts[1]);
			miny = y * sizey;
			maxy = miny + sizey;
			maxy = (maxy>res[1])?res[1]:maxy;
			
			for (z=0; z < parts[2]; z++) {
				VolPrecachePart *pa= MEM_callocN(sizeof(VolPrecachePart), "new precache part");
				
				sizez = ceil(res[2] / (float)parts[2]);
				minz = z * sizez;
				maxz = minz + sizez;
				maxz = (maxz>res[2])?res[2]:maxz;
						
				pa->done = 0;
				pa->working = 0;
				
				pa->num = i;
				pa->tree = tree;
				pa->shi = shi;
				pa->obi = obi;
				VECCOPY(pa->bbmin, bbmin);
				VECCOPY(pa->voxel, voxel);
				VECCOPY(pa->res, res);
				
				pa->minx = minx; pa->maxx = maxx;
				pa->miny = miny; pa->maxy = maxy;
				pa->minz = minz; pa->maxz = maxz;
				
				
				BLI_addtail(&re->volume_precache_parts, pa);
				
				i++;
			}
		}
	}
}
示例#7
0
文件: anim.c 项目: jinjoh/NOOR
void calc_curvepath(Object *ob)
{
	BevList *bl;
	BevPoint *bevp, *bevpn, *bevpfirst, *bevplast;
	PathPoint *pp;
	Curve *cu;
	Nurb *nu;
	Path *path;
	float *fp, *dist, *maxdist, xyz[3];
	float fac, d=0, fac1, fac2;
	int a, tot, cycl=0;
	

	/* in a path vertices are with equal differences: path->len = number of verts */
	/* NOW WITH BEVELCURVE!!! */
	
	if(ob==NULL || ob->type != OB_CURVE) return;
	cu= ob->data;
	if(cu->editnurb) 
		nu= cu->editnurb->first;
	else 
		nu= cu->nurb.first;
	
	if(cu->path) free_path(cu->path);
	cu->path= NULL;
	
	bl= cu->bev.first;
	if(bl==NULL || !bl->nr) return;

	cu->path=path= MEM_callocN(sizeof(Path), "path");
	
	/* if POLY: last vertice != first vertice */
	cycl= (bl->poly!= -1);
	
	if(cycl) tot= bl->nr;
	else tot= bl->nr-1;
	
	path->len= tot+1;
	/* exception: vector handle paths and polygon paths should be subdivided at least a factor resolu */
	if(path->len<nu->resolu*SEGMENTSU(nu)) path->len= nu->resolu*SEGMENTSU(nu);
	
	dist= (float *)MEM_mallocN((tot+1)*4, "calcpathdist");

		/* all lengths in *dist */
	bevp= bevpfirst= (BevPoint *)(bl+1);
	fp= dist;
	*fp= 0;
	for(a=0; a<tot; a++) {
		fp++;
		if(cycl && a==tot-1)
			VecSubf(xyz, bevpfirst->vec, bevp->vec);
		else
			VecSubf(xyz, (bevp+1)->vec, bevp->vec);
		
		*fp= *(fp-1)+VecLength(xyz);
		bevp++;
	}
	
	path->totdist= *fp;

		/* the path verts  in path->data */
		/* now also with TILT value */
	pp= path->data = (PathPoint *)MEM_callocN(sizeof(PathPoint)*4*path->len, "pathdata"); // XXX - why *4? - in 2.4x each element was 4 and the size was 16, so better leave for now - Campbell
	
	bevp= bevpfirst;
	bevpn= bevp+1;
	bevplast= bevpfirst + (bl->nr-1);
	fp= dist+1;
	maxdist= dist+tot;
	fac= 1.0f/((float)path->len-1.0f);
        fac = fac * path->totdist;

	for(a=0; a<path->len; a++) {
		
		d= ((float)a)*fac;
		
		/* we're looking for location (distance) 'd' in the array */
		while((d>= *fp) && fp<maxdist) {
			fp++;
			if(bevp<bevplast) bevp++;
			bevpn= bevp+1;
			if(bevpn>bevplast) {
				if(cycl) bevpn= bevpfirst;
				else bevpn= bevplast;
			}
		}
		
		fac1= *(fp)- *(fp-1);
		fac2= *(fp)-d;
		fac1= fac2/fac1;
		fac2= 1.0f-fac1;

		VecLerpf(pp->vec, bevp->vec, bevpn->vec, fac2);
		pp->vec[3]= fac1*bevp->alfa + fac2*bevpn->alfa;
		pp->radius= fac1*bevp->radius + fac2*bevpn->radius;
		QuatInterpol(pp->quat, bevp->quat, bevpn->quat, fac2);
		NormalQuat(pp->quat);
		
		pp++;
	}
	
	MEM_freeN(dist);
}
示例#8
0
文件: anim.c 项目: jinjoh/NOOR
static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int level, int animated)
{
	Object *ob, *ob_iter;
	Base *base = NULL;
	DupliObject *dob;
	DerivedMesh *dm;
	Mesh *me= par->data;
	MTFace *mtface;
	MFace *mface;
	MVert *mvert;
	float pmat[4][4], imat[3][3], (*orco)[3] = NULL, w;
	int lay, oblay, totface, a;
	Scene *sce = NULL;
	Group *group = NULL;
	GroupObject *go = NULL;
	EditMesh *em;
	float ob__obmat[4][4]; /* needed for groups where the object matrix needs to be modified */
	
	/* simple preventing of too deep nested groups */
	if(level>MAX_DUPLI_RECUR) return;
	
	Mat4CpyMat4(pmat, par->obmat);
	
	em = BKE_mesh_get_editmesh(me);
	if(em) {
		int totvert;
		
		dm= editmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
		
		totface= dm->getNumFaces(dm);
		mface= MEM_mallocN(sizeof(MFace)*totface, "mface temp");
		dm->copyFaceArray(dm, mface);
		totvert= dm->getNumVerts(dm);
		mvert= MEM_mallocN(sizeof(MVert)*totvert, "mvert temp");
		dm->copyVertArray(dm, mvert);

		BKE_mesh_end_editmesh(me, em);
	}
	else {
		dm = mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH);
		
		totface= dm->getNumFaces(dm);
		mface= dm->getFaceArray(dm);
		mvert= dm->getVertArray(dm);
	}

	if(G.rendering) {

		orco= (float(*)[3])get_mesh_orco_verts(par);
		transform_mesh_orco_verts(me, orco, me->totvert, 0);
		mtface= me->mtface;
	}
	else {
		orco= NULL;
		mtface= NULL;
	}
	
	/* having to loop on scene OR group objects is NOT FUN */
	if (GS(id->name) == ID_SCE) {
		sce = (Scene *)id;
		lay= sce->lay;
		base= sce->base.first;
	} else {
		group = (Group *)id;
		lay= group->layer;
		go = group->gobject.first;
	}
	
	/* Start looping on Scene OR Group objects */
	while (base || go) { 
		if (sce) {
			ob_iter= base->object;
			oblay = base->lay;
		} else {
			ob_iter= go->ob;
			oblay = ob_iter->lay;
		}
		
		if (lay & oblay && scene->obedit!=ob_iter) {
			ob=ob_iter->parent;
			while(ob) {
				if(ob==par) {
					ob = ob_iter;
	/* End Scene/Group object loop, below is generic */
					
					/* par_space_mat - only used for groups so we can modify the space dupli's are in
					   when par_space_mat is NULL ob->obmat can be used instead of ob__obmat
					*/
					if(par_space_mat)
						Mat4MulMat4(ob__obmat, ob->obmat, par_space_mat);
					else
						Mat4CpyMat4(ob__obmat, ob->obmat);
					
					Mat3CpyMat4(imat, ob->parentinv);
						
					/* mballs have a different dupli handling */
					if(ob->type!=OB_MBALL) ob->flag |= OB_DONE;	/* doesnt render */

					for(a=0; a<totface; a++) {
						int mv1 = mface[a].v1;
						int mv2 = mface[a].v2;
						int mv3 = mface[a].v3;
						int mv4 = mface[a].v4;
						float *v1= mvert[mv1].co;
						float *v2= mvert[mv2].co;
						float *v3= mvert[mv3].co;
						float *v4= (mv4)? mvert[mv4].co: NULL;
						float cent[3], quat[4], mat[3][3], mat3[3][3], tmat[4][4], obmat[4][4];

						/* translation */
						if(v4)
							CalcCent4f(cent, v1, v2, v3, v4);
						else
							CalcCent3f(cent, v1, v2, v3);
						Mat4MulVecfl(pmat, cent);
						
						VecSubf(cent, cent, pmat[3]);
						VecAddf(cent, cent, ob__obmat[3]);
						
						Mat4CpyMat4(obmat, ob__obmat);
						
						VECCOPY(obmat[3], cent);
						
						/* rotation */
						triatoquat(v1, v2, v3, quat);
						QuatToMat3(quat, mat);
						
						/* scale */
						if(par->transflag & OB_DUPLIFACES_SCALE) {
							float size= v4?AreaQ3Dfl(v1, v2, v3, v4):AreaT3Dfl(v1, v2, v3);
							size= sqrt(size) * par->dupfacesca;
							Mat3MulFloat(mat[0], size);
						}
						
						Mat3CpyMat3(mat3, mat);
						Mat3MulMat3(mat, imat, mat3);
						
						Mat4CpyMat4(tmat, obmat);
						Mat4MulMat43(obmat, tmat, mat);
						
						dob= new_dupli_object(lb, ob, obmat, lay, a, OB_DUPLIFACES, animated);
						if(G.rendering) {
							w= (mv4)? 0.25f: 1.0f/3.0f;

							if(orco) {
								VECADDFAC(dob->orco, dob->orco, orco[mv1], w);
								VECADDFAC(dob->orco, dob->orco, orco[mv2], w);
								VECADDFAC(dob->orco, dob->orco, orco[mv3], w);
								if(mv4)
									VECADDFAC(dob->orco, dob->orco, orco[mv4], w);
							}

							if(mtface) {
								dob->uv[0] += w*mtface[a].uv[0][0];
								dob->uv[1] += w*mtface[a].uv[0][1];
								dob->uv[0] += w*mtface[a].uv[1][0];
								dob->uv[1] += w*mtface[a].uv[1][1];
								dob->uv[0] += w*mtface[a].uv[2][0];
								dob->uv[1] += w*mtface[a].uv[2][1];

								if(mv4) {
									dob->uv[0] += w*mtface[a].uv[3][0];
									dob->uv[1] += w*mtface[a].uv[3][1];
								}
							}
						}
						
						if(ob->transflag & OB_DUPLI) {
							float tmpmat[4][4];
							Mat4CpyMat4(tmpmat, ob->obmat);
							Mat4CpyMat4(ob->obmat, obmat); /* pretend we are really this mat */
							object_duplilist_recursive((ID *)id, scene, ob, lb, ob->obmat, level+1, animated);
							Mat4CpyMat4(ob->obmat, tmpmat);
						}
					}
					
					break;
				}
				ob= ob->parent;
			}
		}
		if (sce)	base= base->next;	/* scene loop */
		else		go= go->next;		/* group loop */
	}
	
	if(par->mode & OB_MODE_EDIT) {
		MEM_freeN(mface);
		MEM_freeN(mvert);
	}

	if(orco)
		MEM_freeN(orco);
	
	dm->release(dm);
}
示例#9
0
static float seam_cut_cost(Mesh *me, int e1, int e2, int vert, int target)
{
	MVert *v = me->mvert + vert;
	MEdge *med1 = me->medge + e1, *med2 = me->medge + e2;
	MEdge *tar = me->medge + target;
	MVert *v1 = me->mvert + ((med1->v1 == vert)? med1->v2: med1->v1);
	MVert *v2 = me->mvert + ((med2->v1 == vert)? med2->v2: med2->v1);
	MVert *tarvert1 = me->mvert + tar->v1;
	MVert *tarvert2 = me->mvert + tar->v2;
	float cost, d1[3], d2[3], EdgeVector[3];		// Heading[3],
	float TargetVector1[3], TargetVector2[3], TargetVector3[3], TargetVector4[3];
	cost = VecLenf(v1->co, v->co);
	cost += VecLenf(v->co, v2->co);

	VecSubf(d1, v1->co, v->co);
	VecSubf(d2, v->co, v2->co);

	VecSubf(TargetVector1, tarvert1->co, v1->co);
	VecSubf(TargetVector2, tarvert1->co, v2->co);
	VecSubf(TargetVector3, tarvert2->co, v1->co);
	VecSubf(TargetVector4, tarvert2->co, v2->co);

	float DistToTarget1 = TargetVector1[0] * TargetVector1[0] + TargetVector1[1] * TargetVector1[1] + TargetVector1[2] * TargetVector1[2];
	DistToTarget1 = sqrt(DistToTarget1);

	float DistToTarget2 = TargetVector2[0] * TargetVector2[0] + TargetVector2[1] * TargetVector2[1] + TargetVector2[2] * TargetVector2[2];
	DistToTarget2 = sqrt(DistToTarget2);

	float DistToTarget3 = TargetVector3[0] * TargetVector3[0] + TargetVector3[1] * TargetVector3[1] + TargetVector3[2] * TargetVector3[2];
	DistToTarget3 = sqrt(DistToTarget3);

	float DistToTarget4 = TargetVector4[0] * TargetVector4[0] + TargetVector4[1] * TargetVector4[1] + TargetVector4[2] * TargetVector4[2];
	DistToTarget4 = sqrt(DistToTarget4);

	float MinDist = DistToTarget1;
	if(DistToTarget2 < MinDist) MinDist = DistToTarget2;
	if(DistToTarget3 < MinDist) MinDist = DistToTarget3;
	if(DistToTarget4 < MinDist) MinDist = DistToTarget4;


	MVert *edgev1 = me->mvert + med2->v1;
	MVert *edgev2 = me->mvert + med2->v2;
	VecSubf(EdgeVector, edgev1->co, edgev2->co);
/*
	Normalise(TargetVector);
	Normalise(EdgeVector);

	Heading[0] = TargetVector[0] * EdgeVector[0];
	Heading[1] = TargetVector[1] * EdgeVector[1];
	Heading[2] = TargetVector[2] * EdgeVector[2];
*/
//	Normalise(Heading);

/*
	float VecX = d1[0]*d2[0];
	float VecY = d1[1]*d2[1];
	float VecZ = d1[2]*d2[2];

	float Length = (VecX * VecX + VecY * VecY + VecZ * VecZ);
	Length = (float)sqrt(Length);

	if(Length != 0)
	{
		VecX /= Length;
		VecY /= Length;
		VecZ /= Length;
	}

//	float Angle = acos(VecX + VecY + VecZ);

	float HeadingLength = Heading[0] * Heading[0] + Heading[1] * Heading[1] + Heading[2] * Heading[2];
	HeadingLength = sqrt(HeadingLength);


	if(HeadingLength != 0)
	{
		Heading[0] /= HeadingLength;
		Heading[1] /= HeadingLength;
		Heading[2] /= HeadingLength;
	}
*/
//	float Angle = acos(fabs(Heading[0] + Heading[1] + Heading[2]));	// heading towards target


//	cost = cost + 0.5f*cost*(2.0f + fabs(Angle));		//fabs(d1[0]*d2[0] + d1[1]*d2[1] + d1[2]*d2[2]));		// dodgy bastards!  Fixed that up for ya's
	cost = MinDist;		/// 50.0f + Angle;	// + fabs(Angle);
	//	cost = cost + 0.5f*cost*(2.0f - fabs(d1[0]*d2[0] + d1[1]*d2[1] + d1[2]*d2[2]));

	return cost;
}
示例#10
0
文件: view3d_snap.c 项目: jinjoh/NOOR
/* copied from editobject.c, now uses (almost) proper depgraph */
static void special_transvert_update(Scene *scene, Object *obedit)
{
	
	if(obedit) {
		
		DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
		
		if(obedit->type==OB_MESH) {
			Mesh *me= obedit->data;
			recalc_editnormals(me->edit_mesh);	// does face centers too
		}
		else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
			Curve *cu= obedit->data;
			Nurb *nu= cu->editnurb->first;
			
			while(nu) {
				test2DNurb(nu);
				testhandlesNurb(nu); /* test for bezier too */
				nu= nu->next;
			}
		}
		else if(obedit->type==OB_ARMATURE){
			bArmature *arm= obedit->data;
			EditBone *ebo;
			TransVert *tv= transvmain;
			int a=0;
			
			/* Ensure all bone tails are correctly adjusted */
			for (ebo= arm->edbo->first; ebo; ebo=ebo->next) {
				/* adjust tip if both ends selected */
				if ((ebo->flag & BONE_ROOTSEL) && (ebo->flag & BONE_TIPSEL)) {
					if (tv) {
						float diffvec[3];
						
						VecSubf(diffvec, tv->loc, tv->oldloc);
						VecAddf(ebo->tail, ebo->tail, diffvec);
						
						a++;
						if (a<tottrans) tv++;
					}
				}
			}
			
			/* Ensure all bones are correctly adjusted */
			for (ebo= arm->edbo->first; ebo; ebo=ebo->next) {
				if ((ebo->flag & BONE_CONNECTED) && ebo->parent){
					/* If this bone has a parent tip that has been moved */
					if (ebo->parent->flag & BONE_TIPSEL){
						VECCOPY (ebo->head, ebo->parent->tail);
					}
					/* If this bone has a parent tip that has NOT been moved */
					else{
						VECCOPY (ebo->parent->tail, ebo->head);
					}
				}
			}
			if(arm->flag & ARM_MIRROR_EDIT) 
				transform_armature_mirror_update(obedit);
		}
		else if(obedit->type==OB_LATTICE) {
			Lattice *lt= obedit->data;
			
			if(lt->editlatt->flag & LT_OUTSIDE) 
				outside_lattice(lt->editlatt);
		}
	}
}