Пример #1
0
static DerivedMesh *create_orco_dm(Scene *scene, Object *ob)
{
	DerivedMesh *dm;
	ListBase disp= {NULL, NULL};

	/* OrcoDM should be created from underformed disp lists */
	makeDispListCurveTypes_forOrco(scene, ob, &disp);
	dm= CDDM_from_curve_customDB(ob, &disp);

	freedisplist(&disp);

	return dm;
}
Пример #2
0
void makeDispListMBall(Scene *scene, Object *ob)
{
	if(!ob || ob->type!=OB_MBALL) return;

	// XXX: mball stuff uses plenty of global variables
	//      while this is unchanged updating during render is unsafe
	if(G.rendering) return;

	freedisplist(&(ob->disp));

	if(ob->type==OB_MBALL) {
		if(ob==find_basis_mball(scene, ob)) {
			metaball_polygonize(scene, ob, &ob->disp);
			tex_space_mball(ob);

			object_deform_mball(ob, &ob->disp);
		}
	}
	
	boundbox_displist(ob);
}
Пример #3
0
static void rna_ID_update_tag(ID *id, ReportList *reports, int flag)
{
	/* XXX, new function for this! */
#if 0
	if (ob->type == OB_FONT) {
		Curve *cu = ob->data;
		freedisplist(&cu->disp);
		BKE_vfont_to_curve(bmain, sce, ob, FO_EDIT, NULL);
	}
#endif

	if (flag == 0) {
		/* pass */
	}
	else {
		/* ensure flag us correct for the type */
		switch (GS(id->name)) {
			case ID_OB:
				if (flag & ~(OB_RECALC_ALL)) {
					BKE_report(reports, RPT_ERROR, "'Refresh' incompatible with Object ID type");
					return;
				}
				break;
				/* Could add particle updates later */
#if 0
			case ID_PA:
				if (flag & ~(OB_RECALC_ALL | PSYS_RECALC)) {
					BKE_report(reports, RPT_ERROR, "'Refresh' incompatible with ParticleSettings ID type");
					return;
				}
				break;
#endif
			default:
				BKE_report(reports, RPT_ERROR, "This ID type is not compatible with any 'refresh' options");
				return;
		}
	}

	DAG_id_tag_update(id, flag);
}
Пример #4
0
void copy_displist(ListBase *lbn, ListBase *lb)
{
	DispList *dln, *dl;
	
	freedisplist(lbn);
	
	dl= lb->first;
	while(dl) {
		
		dln= MEM_dupallocN(dl);
		BLI_addtail(lbn, dln);
		dln->verts= MEM_dupallocN(dl->verts);
		dln->nors= MEM_dupallocN(dl->nors);
		dln->index= MEM_dupallocN(dl->index);
		dln->col1= MEM_dupallocN(dl->col1);
		dln->col2= MEM_dupallocN(dl->col2);

		if(dl->bevelSplitFlag)
			dln->bevelSplitFlag= MEM_dupallocN(dl->bevelSplitFlag);

		dl= dl->next;
	}
}
Пример #5
0
void lattice_calc_modifiers(Scene *scene, Object *ob)
{
	Lattice *lt= ob->data;
	ModifierData *md = modifiers_getVirtualModifierList(ob);
	float (*vertexCos)[3] = NULL;
	int numVerts, editmode = (lt->editlatt!=NULL);

	freedisplist(&ob->disp);

	for (; md; md=md->next) {
		ModifierTypeInfo *mti = modifierType_getInfo(md->type);

		md->scene= scene;
		
		if (!(md->mode&eModifierMode_Realtime)) continue;
		if (editmode && !(md->mode&eModifierMode_Editmode)) continue;
		if (mti->isDisabled && mti->isDisabled(md, 0)) continue;
		if (mti->type!=eModifierTypeType_OnlyDeform) continue;

		if (!vertexCos) vertexCos = lattice_getVertexCos(ob, &numVerts);
		mti->deformVerts(md, ob, NULL, vertexCos, numVerts, 0, 0);
	}

	/* always displist to make this work like derivedmesh */
	if (!vertexCos) vertexCos = lattice_getVertexCos(ob, &numVerts);
	
	{
		DispList *dl = MEM_callocN(sizeof(*dl), "lt_dl");
		dl->type = DL_VERTS;
		dl->parts = 1;
		dl->nr = numVerts;
		dl->verts = (float*) vertexCos;
		
		BLI_addtail(&ob->disp, dl);
	}
}
Пример #6
0
static void bevels_to_filledpoly(Curve *cu, ListBase *dispbase)
{
	ListBase front, back;
	DispList *dl, *dlnew;
	float *fp, *fp1;
	int a, dpoly;
	
	front.first= front.last= back.first= back.last= NULL;
	
	dl= dispbase->first;
	while(dl) {
		if(dl->type==DL_SURF) {
			if( (dl->flag & DL_CYCL_V) && (dl->flag & DL_CYCL_U)==0 ) {
				if( (cu->flag & CU_BACK) && (dl->flag & DL_BACK_CURVE) ) {
					dlnew= MEM_callocN(sizeof(DispList), "filldisp");
					BLI_addtail(&front, dlnew);
					dlnew->verts= fp1= MEM_mallocN(sizeof(float)*3*dl->parts, "filldisp1");
					dlnew->nr= dl->parts;
					dlnew->parts= 1;
					dlnew->type= DL_POLY;
					dlnew->col= dl->col;
					dlnew->charidx = dl->charidx;
					
					fp= dl->verts;
					dpoly= 3*dl->nr;
					
					a= dl->parts;
					while(a--) {
						VECCOPY(fp1, fp);
						fp1+= 3;
						fp+= dpoly;
					}
				}
				if( (cu->flag & CU_FRONT) && (dl->flag & DL_FRONT_CURVE) ) {
					dlnew= MEM_callocN(sizeof(DispList), "filldisp");
					BLI_addtail(&back, dlnew);
					dlnew->verts= fp1= MEM_mallocN(sizeof(float)*3*dl->parts, "filldisp1");
					dlnew->nr= dl->parts;
					dlnew->parts= 1;
					dlnew->type= DL_POLY;
					dlnew->col= dl->col;
					dlnew->charidx= dl->charidx;
					
					fp= dl->verts+3*(dl->nr-1);
					dpoly= 3*dl->nr;
					
					a= dl->parts;
					while(a--) {
						VECCOPY(fp1, fp);
						fp1+= 3;
						fp+= dpoly;
					}
				}
			}
		}
		dl= dl->next;
	}

	filldisplist(&front, dispbase, 1);
	filldisplist(&back, dispbase, 0);
	
	freedisplist(&front);
	freedisplist(&back);

	filldisplist(dispbase, dispbase, 0);
	
}
Пример #7
0
static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispbase,
	DerivedMesh **derivedFinal, int forRender, int forOrco)
{
	Curve *cu = ob->data;

	/* we do allow duplis... this is only displist on curve level */
	if(!ELEM3(ob->type, OB_SURF, OB_CURVE, OB_FONT)) return;

	if(ob->type==OB_SURF) {
		makeDispListSurf(scene, ob, dispbase, derivedFinal, forRender, forOrco);
	}
	else if (ELEM(ob->type, OB_CURVE, OB_FONT)) {
		ListBase dlbev;
		ListBase *nubase;
		float (*originalVerts)[3];
		float (*deformedVerts)[3];
		int numVerts;

		nubase= BKE_curve_nurbs(cu);

		BLI_freelistN(&(cu->bev));

		if(cu->path) free_path(cu->path);
		cu->path= NULL;

		if(ob->type==OB_FONT) BKE_text_to_curve(scene, ob, 0);

		if(!forOrco) curve_calc_modifiers_pre(scene, ob, forRender, &originalVerts, &deformedVerts, &numVerts);

		makeBevelList(ob);

		/* If curve has no bevel will return nothing */
		makebevelcurve(scene, ob, &dlbev, forRender);

		/* no bevel or extrude, and no width correction? */
		if (!dlbev.first && cu->width==1.0f) {
			curve_to_displist(cu, nubase, dispbase, forRender);
		} else {
			float widfac= cu->width - 1.0f;
			BevList *bl= cu->bev.first;
			Nurb *nu= nubase->first;

			for (; bl && nu; bl=bl->next,nu=nu->next) {
				DispList *dl;
				float *fp1, *data;
				BevPoint *bevp;
				int a,b;

				if (bl->nr) { /* blank bevel lists can happen */

					/* exception handling; curve without bevel or extrude, with width correction */
					if(dlbev.first==NULL) {
						dl= MEM_callocN(sizeof(DispList), "makeDispListbev");
						dl->verts= MEM_callocN(3*sizeof(float)*bl->nr, "dlverts");
						BLI_addtail(dispbase, dl);

						if(bl->poly!= -1) dl->type= DL_POLY;
						else dl->type= DL_SEGM;

						if(dl->type==DL_SEGM) dl->flag = (DL_FRONT_CURVE|DL_BACK_CURVE);

						dl->parts= 1;
						dl->nr= bl->nr;
						dl->col= nu->mat_nr;
						dl->charidx= nu->charidx;

						/* dl->rt will be used as flag for render face and */
						/* CU_2D conflicts with R_NOPUNOFLIP */
						dl->rt= nu->flag & ~CU_2D;

						a= dl->nr;
						bevp= (BevPoint *)(bl+1);
						data= dl->verts;
						while(a--) {
							data[0]= bevp->vec[0]+widfac*bevp->sina;
							data[1]= bevp->vec[1]+widfac*bevp->cosa;
							data[2]= bevp->vec[2];
							bevp++;
							data+=3;
						}
					}
					else {
						DispList *dlb;

						for (dlb=dlbev.first; dlb; dlb=dlb->next) {
	
							/* for each part of the bevel use a separate displblock */
							dl= MEM_callocN(sizeof(DispList), "makeDispListbev1");
							dl->verts= data= MEM_callocN(3*sizeof(float)*dlb->nr*bl->nr, "dlverts");
							BLI_addtail(dispbase, dl);
	
							dl->type= DL_SURF;
							
							dl->flag= dlb->flag & (DL_FRONT_CURVE|DL_BACK_CURVE);
							if(dlb->type==DL_POLY) dl->flag |= DL_CYCL_U;
							if(bl->poly>=0) dl->flag |= DL_CYCL_V;
							
							dl->parts= bl->nr;
							dl->nr= dlb->nr;
							dl->col= nu->mat_nr;
							dl->charidx= nu->charidx;

							/* dl->rt will be used as flag for render face and */
							/* CU_2D conflicts with R_NOPUNOFLIP */
							dl->rt= nu->flag & ~CU_2D;

							dl->bevelSplitFlag= MEM_callocN(sizeof(*dl->col2)*((bl->nr+0x1F)>>5), "bevelSplitFlag");
	
							/* for each point of poly make a bevel piece */
							bevp= (BevPoint *)(bl+1);
							for(a=0; a<bl->nr; a++,bevp++) {
								float fac=1.0;
								if (cu->taperobj==NULL) {
									if ( (cu->bevobj!=NULL) || !((cu->flag & CU_FRONT) || (cu->flag & CU_BACK)) )
										fac = bevp->radius;
								} else {
									fac = calc_taper(scene, cu->taperobj, a, bl->nr);
								}

								if (bevp->split_tag) {
									dl->bevelSplitFlag[a>>5] |= 1<<(a&0x1F);
								}
	
									/* rotate bevel piece and write in data */
								fp1= dlb->verts;
								for (b=0; b<dlb->nr; b++,fp1+=3,data+=3) {
									if(cu->flag & CU_3D) {
										float vec[3];
	
										vec[0]= fp1[1]+widfac;
										vec[1]= fp1[2];
										vec[2]= 0.0;

										mul_qt_v3(bevp->quat, vec);

										data[0]= bevp->vec[0] + fac*vec[0];
										data[1]= bevp->vec[1] + fac*vec[1];
										data[2]= bevp->vec[2] + fac*vec[2];
									}
									else {
										data[0]= bevp->vec[0] + fac*(widfac+fp1[1])*bevp->sina;
										data[1]= bevp->vec[1] + fac*(widfac+fp1[1])*bevp->cosa;
										data[2]= bevp->vec[2] + fac*fp1[2];
									}
								}
							}
							
							/* gl array drawing: using indices */
							displist_surf_indices(dl);
						}
					}
				}

			}
			freedisplist(&dlbev);
		}
Пример #8
0
/* PolyFill function, uses Blenders scanfill to fill multiple poly lines */
static PyObject *M_Geometry_PolyFill( PyObject * self, PyObject * polyLineSeq )
{
	PyObject *tri_list; /*return this list of tri's */
	PyObject *polyLine, *polyVec;
	int i, len_polylines, len_polypoints, ls_error = 0;
	
	/* display listbase */
	ListBase dispbase={NULL, NULL};
	DispList *dl;
	float *fp; /*pointer to the array of malloced dl->verts to set the points from the vectors */
	int index, *dl_face, totpoints=0;
	
	
	dispbase.first= dispbase.last= NULL;
	
	
	if(!PySequence_Check(polyLineSeq)) {
		PyErr_SetString( PyExc_TypeError, "expected a sequence of poly lines" );
		return NULL;
	}
	
	len_polylines = PySequence_Size( polyLineSeq );
	
	for( i = 0; i < len_polylines; ++i ) {
		polyLine= PySequence_GetItem( polyLineSeq, i );
		if (!PySequence_Check(polyLine)) {
			freedisplist(&dispbase);
			Py_XDECREF(polyLine); /* may be null so use Py_XDECREF*/
			PyErr_SetString( PyExc_TypeError, "One or more of the polylines is not a sequence of Mathutils.Vector's" );
			return NULL;
		}
		
		len_polypoints= PySequence_Size( polyLine );
		if (len_polypoints>0) { /* dont bother adding edges as polylines */
#if 0
			if (EXPP_check_sequence_consistency( polyLine, &vector_Type ) != 1) {
				freedisplist(&dispbase);
				Py_DECREF(polyLine);
				PyErr_SetString( PyExc_TypeError, "A point in one of the polylines is not a Mathutils.Vector type" );
				return NULL;
			}
#endif
			dl= MEM_callocN(sizeof(DispList), "poly disp");
			BLI_addtail(&dispbase, dl);
			dl->type= DL_INDEX3;
			dl->nr= len_polypoints;
			dl->type= DL_POLY;
			dl->parts= 1; /* no faces, 1 edge loop */
			dl->col= 0; /* no material */
			dl->verts= fp= MEM_callocN( sizeof(float)*3*len_polypoints, "dl verts");
			dl->index= MEM_callocN(sizeof(int)*3*len_polypoints, "dl index");
			
			for( index = 0; index<len_polypoints; ++index, fp+=3) {
				polyVec= PySequence_GetItem( polyLine, index );
				if(VectorObject_Check(polyVec)) {
					
					if(!BaseMath_ReadCallback((VectorObject *)polyVec))
						ls_error= 1;
					
					fp[0] = ((VectorObject *)polyVec)->vec[0];
					fp[1] = ((VectorObject *)polyVec)->vec[1];
					if( ((VectorObject *)polyVec)->size > 2 )
						fp[2] = ((VectorObject *)polyVec)->vec[2];
					else
						fp[2]= 0.0f; /* if its a 2d vector then set the z to be zero */
				}
				else {
					ls_error= 1;
				}
				
				totpoints++;
				Py_DECREF(polyVec);
			}
		}
		Py_DECREF(polyLine);
	}
	
	if(ls_error) {
		freedisplist(&dispbase); /* possible some dl was allocated */
		PyErr_SetString( PyExc_TypeError, "A point in one of the polylines is not a Mathutils.Vector type" );
		return NULL;
	}
	else if (totpoints) {
		/* now make the list to return */
		filldisplist(&dispbase, &dispbase);
		
		/* The faces are stored in a new DisplayList
		thats added to the head of the listbase */
		dl= dispbase.first; 
		
		tri_list= PyList_New(dl->parts);
		if( !tri_list ) {
			freedisplist(&dispbase);
			PyErr_SetString( PyExc_RuntimeError, "Geometry.PolyFill failed to make a new list" );
			return NULL;
		}
		
		index= 0;
		dl_face= dl->index;
		while(index < dl->parts) {
			PyList_SetItem(tri_list, index, Py_BuildValue("iii", dl_face[0], dl_face[1], dl_face[2]) );
			dl_face+= 3;
			index++;
		}
		freedisplist(&dispbase);
	} else {
		/* no points, do this so scripts dont barf */
		freedisplist(&dispbase); /* possible some dl was allocated */
		tri_list= PyList_New(0);
	}
	
	return tri_list;
}
Пример #9
0
/* settings: 0 - preview, 1 - render */
Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_modifiers, int settings)
{
	Mesh *tmpmesh;
	Curve *tmpcu = NULL;
	Object *tmpobj = NULL;
	int render = settings == eModifierMode_Render, i;
	int cage = !apply_modifiers;

	/* perform the mesh extraction based on type */
	switch (ob->type) {
	case OB_FONT:
	case OB_CURVE:
	case OB_SURF:

		/* copies object and modifiers (but not the data) */
		tmpobj= copy_object(ob);
		tmpcu = (Curve *)tmpobj->data;
		tmpcu->id.us--;

		/* if getting the original caged mesh, delete object modifiers */
		if( cage )
			object_free_modifiers(tmpobj);

		/* copies the data */
		tmpobj->data = copy_curve( (Curve *) ob->data );

#if 0
		/* copy_curve() sets disp.first null, so currently not need */
		{
			Curve *cu;
			cu = (Curve *)tmpobj->data;
			if( cu->disp.first )
				MEM_freeN( cu->disp.first );
			cu->disp.first = NULL;
		}
	
#endif

		/* get updated display list, and convert to a mesh */
		makeDispListCurveTypes( sce, tmpobj, 0 );
		nurbs_to_mesh( tmpobj );
		
		/* nurbs_to_mesh changes the type to a mesh, check it worked */
		if (tmpobj->type != OB_MESH) {
			free_libblock_us( &(G.main->object), tmpobj );
			BKE_report(reports, RPT_ERROR, "cant convert curve to mesh. Does the curve have any segments?");
			return NULL;
		}
		tmpmesh = tmpobj->data;
		free_libblock_us( &G.main->object, tmpobj );
		break;

	case OB_MBALL: {
		/* metaballs don't have modifiers, so just convert to mesh */
		Object *basis_ob = find_basis_mball(sce, ob);
		/* todo, re-generatre for render-res */
		/* metaball_polygonize(scene, ob) */

		if(ob != basis_ob)
			return NULL; /* only do basis metaball */

		tmpmesh = add_mesh("Mesh");
			
		if(render) {
			ListBase disp = {NULL, NULL};
			makeDispListMBall_forRender(sce, ob, &disp);
			mball_to_mesh(&disp, tmpmesh);
			freedisplist(&disp);
		}
		else
			mball_to_mesh(&ob->disp, tmpmesh);
		break;

	}
	case OB_MESH:
		/* copies object and modifiers (but not the data) */
		if (cage) {
			/* copies the data */
			tmpmesh = copy_mesh( ob->data );
		/* if not getting the original caged mesh, get final derived mesh */
		} else {
			/* Make a dummy mesh, saves copying */
			DerivedMesh *dm;
			/* CustomDataMask mask = CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL; */
			CustomDataMask mask = CD_MASK_MESH; /* this seems more suitable, exporter,
												   for example, needs CD_MASK_MDEFORMVERT */
			
			/* Write the display mesh into the dummy mesh */
			if (render)
				dm = mesh_create_derived_render( sce, ob, mask );
			else
				dm = mesh_create_derived_view( sce, ob, mask );
			
			tmpmesh = add_mesh( "Mesh" );
			DM_to_mesh( dm, tmpmesh );
			dm->release( dm );
		}
		
		break;
	default:
		BKE_report(reports, RPT_ERROR, "Object does not have geometry data");
		return NULL;
	}

	/* Copy materials to new mesh */
	switch (ob->type) {
	case OB_SURF:
	case OB_FONT:
	case OB_CURVE:
		tmpmesh->totcol = tmpcu->totcol;		
		
		/* free old material list (if it exists) and adjust user counts */
		if( tmpcu->mat ) {
			for( i = tmpcu->totcol; i-- > 0; ) {
				/* are we an object material or data based? */

				tmpmesh->mat[i] = ob->matbits[i] ? ob->mat[i] : tmpcu->mat[i];

				if (tmpmesh->mat[i]) {
					tmpmesh->mat[i]->id.us++;
				}
			}
		}
		break;

#if 0
	/* Crashes when assigning the new material, not sure why */
	case OB_MBALL:
		tmpmb = (MetaBall *)ob->data;
		tmpmesh->totcol = tmpmb->totcol;
		
		/* free old material list (if it exists) and adjust user counts */
		if( tmpmb->mat ) {
			for( i = tmpmb->totcol; i-- > 0; ) {
				tmpmesh->mat[i] = tmpmb->mat[i]; /* CRASH HERE ??? */
				if (tmpmesh->mat[i]) {
					tmpmb->mat[i]->id.us++;
				}
			}
		}
		break;
#endif

	case OB_MESH:
		if (!cage) {
			Mesh *origmesh= ob->data;
			tmpmesh->flag= origmesh->flag;
			tmpmesh->mat = MEM_dupallocN(origmesh->mat);
			tmpmesh->totcol = origmesh->totcol;
			tmpmesh->smoothresh= origmesh->smoothresh;
			if( origmesh->mat ) {
				for( i = origmesh->totcol; i-- > 0; ) {
					/* are we an object material or data based? */
					tmpmesh->mat[i] = ob->matbits[i] ? ob->mat[i] : origmesh->mat[i];

					if (tmpmesh->mat[i]) {
						tmpmesh->mat[i]->id.us++;
					}
				}
			}
		}
		break;
	} /* end copy materials */

	/* we don't assign it to anything */
	tmpmesh->id.us--;
	
	/* make sure materials get updated in objects */
	test_object_materials( ( ID * ) tmpmesh );

	return tmpmesh;
}
Пример #10
0
void resizelattice(Lattice *lt, int uNew, int vNew, int wNew, Object *ltOb)
{
	BPoint *bp;
	int i, u, v, w;
	float fu, fv, fw, uc, vc, wc, du=0.0, dv=0.0, dw=0.0;
	float *co, (*vertexCos)[3] = NULL;
	
	/* vertex weight groups are just freed all for now */
	if(lt->dvert) {
		free_dverts(lt->dvert, lt->pntsu*lt->pntsv*lt->pntsw);
		lt->dvert= NULL;
	}
	
	while(uNew*vNew*wNew > 32000) {
		if( uNew>=vNew && uNew>=wNew) uNew--;
		else if( vNew>=uNew && vNew>=wNew) vNew--;
		else wNew--;
	}

	vertexCos = MEM_mallocN(sizeof(*vertexCos)*uNew*vNew*wNew, "tmp_vcos");

	calc_lat_fudu(lt->flag, uNew, &fu, &du);
	calc_lat_fudu(lt->flag, vNew, &fv, &dv);
	calc_lat_fudu(lt->flag, wNew, &fw, &dw);

		/* If old size is different then resolution changed in interface,
		 * try to do clever reinit of points. Pretty simply idea, we just
		 * deform new verts by old lattice, but scaling them to match old
		 * size first.
		 */
	if (ltOb) {
		if (uNew!=1 && lt->pntsu!=1) {
			fu = lt->fu;
			du = (lt->pntsu-1)*lt->du/(uNew-1);
		}

		if (vNew!=1 && lt->pntsv!=1) {
			fv = lt->fv;
			dv = (lt->pntsv-1)*lt->dv/(vNew-1);
		}

		if (wNew!=1 && lt->pntsw!=1) {
			fw = lt->fw;
			dw = (lt->pntsw-1)*lt->dw/(wNew-1);
		}
	}

	co = vertexCos[0];
	for(w=0,wc=fw; w<wNew; w++,wc+=dw) {
		for(v=0,vc=fv; v<vNew; v++,vc+=dv) {
			for(u=0,uc=fu; u<uNew; u++,co+=3,uc+=du) {
				co[0] = uc;
				co[1] = vc;
				co[2] = wc;
			}
		}
	}
	
	if (ltOb) {
		float mat[4][4];
		int typeu = lt->typeu, typev = lt->typev, typew = lt->typew;

			/* works best if we force to linear type (endpoints match) */
		lt->typeu = lt->typev = lt->typew = KEY_LINEAR;

			/* prevent using deformed locations */
		freedisplist(&ltOb->disp);

		copy_m4_m4(mat, ltOb->obmat);
		unit_m4(ltOb->obmat);
		lattice_deform_verts(ltOb, NULL, NULL, vertexCos, uNew*vNew*wNew, NULL);
		copy_m4_m4(ltOb->obmat, mat);

		lt->typeu = typeu;
		lt->typev = typev;
		lt->typew = typew;
	}

	lt->fu = fu;
	lt->fv = fv;
	lt->fw = fw;
	lt->du = du;
	lt->dv = dv;
	lt->dw = dw;

	lt->pntsu = uNew;
	lt->pntsv = vNew;
	lt->pntsw = wNew;

	MEM_freeN(lt->def);
	lt->def= MEM_callocN(lt->pntsu*lt->pntsv*lt->pntsw*sizeof(BPoint), "lattice bp");
	
	bp= lt->def;
	
	for (i=0; i<lt->pntsu*lt->pntsv*lt->pntsw; i++,bp++) {
		copy_v3_v3(bp->vec, vertexCos[i]);
	}

	MEM_freeN(vertexCos);
}