Exemplo n.º 1
0
static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase,
                              const bool for_render, const bool use_render_resolution)
{
	Nurb *nu;
	DispList *dl;
	BezTriple *bezt, *prevbezt;
	BPoint *bp;
	float *data;
	int a, len, resolu;
	const bool editmode = (!for_render && (cu->editnurb || cu->editfont));

	nu = nubase->first;
	while (nu) {
		if (nu->hide == 0 || editmode == false) {
			if (use_render_resolution && cu->resolu_ren != 0)
				resolu = cu->resolu_ren;
			else
				resolu = nu->resolu;

			if (!BKE_nurb_check_valid_u(nu)) {
				/* pass */
			}
			else if (nu->type == CU_BEZIER) {
				/* count */
				len = 0;
				a = nu->pntsu - 1;
				if (nu->flagu & CU_NURB_CYCLIC) a++;

				prevbezt = nu->bezt;
				bezt = prevbezt + 1;
				while (a--) {
					if (a == 0 && (nu->flagu & CU_NURB_CYCLIC))
						bezt = nu->bezt;

					if (prevbezt->h2 == HD_VECT && bezt->h1 == HD_VECT)
						len++;
					else
						len += resolu;

					if (a == 0 && (nu->flagu & CU_NURB_CYCLIC) == 0)
						len++;

					prevbezt = bezt;
					bezt++;
				}

				dl = MEM_callocN(sizeof(DispList), "makeDispListbez");
				/* len+1 because of 'forward_diff_bezier' function */
				dl->verts = MEM_mallocN((len + 1) * sizeof(float[3]), "dlverts");
				BLI_addtail(dispbase, dl);
				dl->parts = 1;
				dl->nr = len;
				dl->col = nu->mat_nr;
				dl->charidx = nu->charidx;

				data = dl->verts;

				/* check that (len != 2) so we don't immediately loop back on ourselves */
				if (nu->flagu & CU_NURB_CYCLIC && (dl->nr != 2)) {
					dl->type = DL_POLY;
					a = nu->pntsu;
				}
				else {
					dl->type = DL_SEGM;
					a = nu->pntsu - 1;
				}

				prevbezt = nu->bezt;
				bezt = prevbezt + 1;

				while (a--) {
					if (a == 0 && dl->type == DL_POLY)
						bezt = nu->bezt;

					if (prevbezt->h2 == HD_VECT && bezt->h1 == HD_VECT) {
						copy_v3_v3(data, prevbezt->vec[1]);
						data += 3;
					}
					else {
						int j;
						for (j = 0; j < 3; j++) {
							BKE_curve_forward_diff_bezier(prevbezt->vec[1][j],
							                              prevbezt->vec[2][j],
							                              bezt->vec[0][j],
							                              bezt->vec[1][j],
							                              data + j, resolu, 3 * sizeof(float));
						}

						data += 3 * resolu;
					}

					if (a == 0 && dl->type == DL_SEGM) {
						copy_v3_v3(data, bezt->vec[1]);
					}

					prevbezt = bezt;
					bezt++;
				}
			}
			else if (nu->type == CU_NURBS) {
				len = (resolu * SEGMENTSU(nu));

				dl = MEM_callocN(sizeof(DispList), "makeDispListsurf");
				dl->verts = MEM_mallocN(len * sizeof(float[3]), "dlverts");
				BLI_addtail(dispbase, dl);
				dl->parts = 1;

				dl->nr = len;
				dl->col = nu->mat_nr;
				dl->charidx = nu->charidx;

				data = dl->verts;
				if (nu->flagu & CU_NURB_CYCLIC)
					dl->type = DL_POLY;
				else dl->type = DL_SEGM;
				BKE_nurb_makeCurve(nu, data, NULL, NULL, NULL, resolu, 3 * sizeof(float));
			}
			else if (nu->type == CU_POLY) {
				len = nu->pntsu;
				dl = MEM_callocN(sizeof(DispList), "makeDispListpoly");
				dl->verts = MEM_mallocN(len * sizeof(float[3]), "dlverts");
				BLI_addtail(dispbase, dl);
				dl->parts = 1;
				dl->nr = len;
				dl->col = nu->mat_nr;
				dl->charidx = nu->charidx;

				data = dl->verts;
				if ((nu->flagu & CU_NURB_CYCLIC) && (dl->nr != 2)) {
					dl->type = DL_POLY;
				}
				else {
					dl->type = DL_SEGM;
				}

				a = len;
				bp = nu->bp;
				while (a--) {
					copy_v3_v3(data, bp->vec);
					bp++;
					data += 3;
				}
			}
		}
		nu = nu->next;
	}
}
Exemplo n.º 2
0
static void calc_bevfac_mapping(Curve *cu, BevList *bl, Nurb *nu,
        int *r_start, float *r_firstblend, int *r_steps, float *r_lastblend)
{
	float tmpf, total_length = 0.0f;
	int end = 0, i;

	if ((BKE_nurb_check_valid_u(nu) == false) ||
	    /* not essential, but skips unnecessary calculation */
	    (min_ff(cu->bevfac1, cu->bevfac2) == 0.0f &&
	     max_ff(cu->bevfac1, cu->bevfac2) == 1.0f))
	{
		calc_bevfac_mapping_default(bl, r_start, r_firstblend, r_steps, r_lastblend);
		return;
	}

	if (ELEM(cu->bevfac1_mapping, CU_BEVFAC_MAP_SEGMENT, CU_BEVFAC_MAP_SPLINE) ||
	    ELEM(cu->bevfac2_mapping, CU_BEVFAC_MAP_SEGMENT, CU_BEVFAC_MAP_SPLINE))
	{
		for (i = 0; i < SEGMENTSU(nu); i++) {
			total_length += bl->seglen[i];
		}
	}

	switch (cu->bevfac1_mapping) {
		case CU_BEVFAC_MAP_RESOLU:
		{
			const float start_fl = cu->bevfac1 * (bl->nr - 1);
			*r_start = (int)start_fl;
			*r_firstblend = 1.0f - (start_fl - (*r_start));
			break;
		}
		case CU_BEVFAC_MAP_SEGMENT:
		{
			calc_bevfac_segment_mapping(bl, cu->bevfac1, total_length, r_start, r_firstblend);
			*r_firstblend = 1.0f - *r_firstblend;
			break;
		}
		case CU_BEVFAC_MAP_SPLINE:
		{
			calc_bevfac_spline_mapping(bl, cu->bevfac1, total_length, r_start, r_firstblend);
			*r_firstblend = 1.0f - *r_firstblend;
			break;
		}
	}

	switch (cu->bevfac2_mapping) {
		case CU_BEVFAC_MAP_RESOLU:
		{
			const float end_fl = cu->bevfac2 * (bl->nr - 1);
			end = (int)end_fl;

			*r_steps = 2 + end - *r_start;
			*r_lastblend = end_fl - end;
			break;
		}
		case CU_BEVFAC_MAP_SEGMENT:
		{
			calc_bevfac_segment_mapping(bl, cu->bevfac2, total_length, &end, r_lastblend);
			*r_steps = end - *r_start + 2;
			break;
		}
		case CU_BEVFAC_MAP_SPLINE:
		{
			calc_bevfac_spline_mapping(bl, cu->bevfac2, total_length, &end, r_lastblend);
			*r_steps = end - *r_start + 2;
			break;
		}
	}

	if (end < *r_start || (end == *r_start && *r_lastblend < 1.0f - *r_firstblend )) {
		SWAP(int, *r_start, end);
		tmpf = *r_lastblend;
		*r_lastblend = 1.0f - *r_firstblend;
		*r_firstblend = 1.0f - tmpf;
		*r_steps = end - *r_start + 2;
	}
Exemplo n.º 3
0
void BKE_displist_make_surf(Scene *scene, Object *ob, ListBase *dispbase,
                            DerivedMesh **r_dm_final,
                            const bool for_render, const bool for_orco, const bool use_render_resolution)
{
	ListBase nubase = {NULL, NULL};
	Nurb *nu;
	Curve *cu = ob->data;
	DispList *dl;
	float *data;
	int len;

	if (!for_render && cu->editnurb) {
		BKE_nurbList_duplicate(&nubase, BKE_curve_editNurbs_get(cu));
	}
	else {
		BKE_nurbList_duplicate(&nubase, &cu->nurb);
	}

	if (!for_orco)
		curve_calc_modifiers_pre(scene, ob, &nubase, for_render, use_render_resolution);

	for (nu = nubase.first; nu; nu = nu->next) {
		if ((for_render || nu->hide == 0) && BKE_nurb_check_valid_uv(nu)) {
			int resolu = nu->resolu, resolv = nu->resolv;

			if (use_render_resolution) {
				if (cu->resolu_ren)
					resolu = cu->resolu_ren;
				if (cu->resolv_ren)
					resolv = cu->resolv_ren;
			}

			if (nu->pntsv == 1) {
				len = SEGMENTSU(nu) * resolu;

				dl = MEM_callocN(sizeof(DispList), "makeDispListsurf");
				dl->verts = MEM_mallocN(len * sizeof(float[3]), "dlverts");

				BLI_addtail(dispbase, dl);
				dl->parts = 1;
				dl->nr = len;
				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;

				data = dl->verts;
				if (nu->flagu & CU_NURB_CYCLIC) dl->type = DL_POLY;
				else dl->type = DL_SEGM;

				BKE_nurb_makeCurve(nu, data, NULL, NULL, NULL, resolu, 3 * sizeof(float));
			}
			else {
				len = (nu->pntsu * resolu) * (nu->pntsv * resolv);

				dl = MEM_callocN(sizeof(DispList), "makeDispListsurf");
				dl->verts = MEM_mallocN(len * sizeof(float[3]), "dlverts");
				BLI_addtail(dispbase, dl);

				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;

				data = dl->verts;
				dl->type = DL_SURF;

				dl->parts = (nu->pntsu * resolu);  /* in reverse, because makeNurbfaces works that way */
				dl->nr = (nu->pntsv * resolv);
				if (nu->flagv & CU_NURB_CYCLIC) dl->flag |= DL_CYCL_U;  /* reverse too! */
				if (nu->flagu & CU_NURB_CYCLIC) dl->flag |= DL_CYCL_V;

				BKE_nurb_makeFaces(nu, data, 0, resolu, resolv);

				/* gl array drawing: using indices */
				displist_surf_indices(dl);
			}
		}
	}

	if (!for_orco) {
		BKE_nurbList_duplicate(&ob->curve_cache->deformed_nurbs, &nubase);
		curve_calc_modifiers_post(scene, ob, &nubase, dispbase, r_dm_final,
		                          for_render, use_render_resolution);
	}

	BKE_nurbList_free(&nubase);
}
Exemplo n.º 4
0
/* calculate a curve-deform path for a curve 
 * 	- only called from displist.c -> do_makeDispListCurveTypes
 */
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;
	ListBase *nurbs;
	
	/* 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;

	nurbs= BKE_curve_nurbs(cu);
	nu= nurbs->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), "calc_curvepath");
	
	/* 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)
			sub_v3_v3v3(xyz, bevpfirst->vec, bevp->vec);
		else
			sub_v3_v3v3(xyz, (bevp+1)->vec, bevp->vec);
		
		*fp= *(fp-1)+len_v3(xyz);
		bevp++;
	}
	
	path->totdist= *fp;
	
		/* the path verts  in path->data */
		/* now also with TILT value */
	pp= path->data = (PathPoint *)MEM_callocN(sizeof(PathPoint)*path->len, "pathdata");
	
	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;
		
		interp_v3_v3v3(pp->vec, bevp->vec, bevpn->vec, fac2);
		pp->vec[3]= fac1*bevp->alfa + fac2*bevpn->alfa;
		pp->radius= fac1*bevp->radius + fac2*bevpn->radius;
		pp->weight= fac1*bevp->weight + fac2*bevpn->weight;
		interp_qt_qtqt(pp->quat, bevp->quat, bevpn->quat, fac2);
		normalize_qt(pp->quat);
		
		pp++;
	}
	
	MEM_freeN(dist);
}
Exemplo n.º 5
0
static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase, int forRender)
{
	Nurb *nu;
	DispList *dl;
	BezTriple *bezt, *prevbezt;
	BPoint *bp;
	float *data;
	int a, len, resolu;
	
	nu= nubase->first;
	while(nu) {
		if(nu->hide==0) {
			
			if(forRender && cu->resolu_ren!=0)
				resolu= cu->resolu_ren;
			else
				resolu= nu->resolu;
			
			if(!check_valid_nurb_u(nu));
			else if(nu->type == CU_BEZIER) {
				
				/* count */
				len= 0;
				a= nu->pntsu-1;
				if(nu->flagu & CU_NURB_CYCLIC) a++;

				prevbezt= nu->bezt;
				bezt= prevbezt+1;
				while(a--) {
					if(a==0 && (nu->flagu & CU_NURB_CYCLIC)) bezt= nu->bezt;
					
					if(prevbezt->h2==HD_VECT && bezt->h1==HD_VECT) len++;
					else len+= resolu;
					
					if(a==0 && (nu->flagu & CU_NURB_CYCLIC)==0) len++;
					
					prevbezt= bezt;
					bezt++;
				}
				
				dl= MEM_callocN(sizeof(DispList), "makeDispListbez");
				/* len+1 because of 'forward_diff_bezier' function */
				dl->verts= MEM_callocN( (len+1)*3*sizeof(float), "dlverts");
				BLI_addtail(dispbase, dl);
				dl->parts= 1;
				dl->nr= len;
				dl->col= nu->mat_nr;
				dl->charidx= nu->charidx;

				data= dl->verts;

				if(nu->flagu & CU_NURB_CYCLIC) {
					dl->type= DL_POLY;
					a= nu->pntsu;
				}
				else {
					dl->type= DL_SEGM;
					a= nu->pntsu-1;
				}
				
				prevbezt= nu->bezt;
				bezt= prevbezt+1;
				
				while(a--) {
					if(a==0 && dl->type== DL_POLY) bezt= nu->bezt;
					
					if(prevbezt->h2==HD_VECT && bezt->h1==HD_VECT) {
						VECCOPY(data, prevbezt->vec[1]);
						data+= 3;
					}
					else {
						int j;
						for(j=0; j<3; j++) {
							forward_diff_bezier(	prevbezt->vec[1][j],
													prevbezt->vec[2][j],
													bezt->vec[0][j],
													bezt->vec[1][j],
													data+j, resolu, 3*sizeof(float));
						}
						
						data+= 3*resolu;
					}
					
					if(a==0 && dl->type==DL_SEGM) {
						VECCOPY(data, bezt->vec[1]);
					}
					
					prevbezt= bezt;
					bezt++;
				}
			}
			else if(nu->type == CU_NURBS) {
				len= (resolu*SEGMENTSU(nu));
				
				dl= MEM_callocN(sizeof(DispList), "makeDispListsurf");
				dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
				BLI_addtail(dispbase, dl);
				dl->parts= 1;
				
				dl->nr= len;
				dl->col= nu->mat_nr;
				dl->charidx = nu->charidx;

				data= dl->verts;
				if(nu->flagu & CU_NURB_CYCLIC) dl->type= DL_POLY;
				else dl->type= DL_SEGM;
				makeNurbcurve(nu, data, NULL, NULL, NULL, resolu, 3*sizeof(float));
			}
			else if(nu->type == CU_POLY) {
				len= nu->pntsu;
				dl= MEM_callocN(sizeof(DispList), "makeDispListpoly");
				dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
				BLI_addtail(dispbase, dl);
				dl->parts= 1;
				dl->nr= len;
				dl->col= nu->mat_nr;
				dl->charidx = nu->charidx;

				data= dl->verts;
				if(nu->flagu & CU_NURB_CYCLIC) dl->type= DL_POLY;
				else dl->type= DL_SEGM;
				
				a= len;
				bp= nu->bp;
				while(a--) {
					VECCOPY(data, bp->vec);
					bp++;
					data+= 3;
				}
			}
		}
		nu= nu->next;
	}
}
Exemplo n.º 6
0
void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase,
	DerivedMesh **derivedFinal, int forRender, int forOrco)
{
	ListBase *nubase;
	Nurb *nu;
	Curve *cu = ob->data;
	DispList *dl;
	float *data;
	int len;
	int numVerts;
	float (*originalVerts)[3];
	float (*deformedVerts)[3];

	if(!forRender && cu->editnurb)
		nubase= ED_curve_editnurbs(cu);
	else
		nubase= &cu->nurb;

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

	for (nu=nubase->first; nu; nu=nu->next) {
		if(forRender || nu->hide==0) {
			int resolu= nu->resolu, resolv= nu->resolv;

			if(forRender){
				if(cu->resolu_ren) resolu= cu->resolu_ren;
				if(cu->resolv_ren) resolv= cu->resolv_ren;
			}

			if(nu->pntsv==1) {
				len= SEGMENTSU(nu)*resolu;

				dl= MEM_callocN(sizeof(DispList), "makeDispListsurf");
				dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");

				BLI_addtail(dispbase, dl);
				dl->parts= 1;
				dl->nr= len;
				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;

				data= dl->verts;
				if(nu->flagu & CU_NURB_CYCLIC) dl->type= DL_POLY;
				else dl->type= DL_SEGM;

				makeNurbcurve(nu, data, NULL, NULL, NULL, resolu, 3*sizeof(float));
			}
			else {
				len= (nu->pntsu*resolu) * (nu->pntsv*resolv);
				
				dl= MEM_callocN(sizeof(DispList), "makeDispListsurf");
				dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
				BLI_addtail(dispbase, dl);

				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;

				data= dl->verts;
				dl->type= DL_SURF;

				dl->parts= (nu->pntsu*resolu);	/* in reverse, because makeNurbfaces works that way */
				dl->nr= (nu->pntsv*resolv);
				if(nu->flagv & CU_NURB_CYCLIC) dl->flag|= DL_CYCL_U;	/* reverse too! */
				if(nu->flagu & CU_NURB_CYCLIC) dl->flag|= DL_CYCL_V;

				makeNurbfaces(nu, data, 0, resolu, resolv);
				
				/* gl array drawing: using indices */
				displist_surf_indices(dl);
			}
		}
	}

	/* make copy of 'undeformed" displist for texture space calculation
	   actually, it's not totally undeformed -- pre-tesselation modifiers are
	   already applied, thats how it worked for years, so keep for compatibility (sergey) */
	copy_displist(&cu->disp, dispbase);

	if (!forRender) {
		tex_space_curve(cu);
	}

	if(!forOrco)
		curve_calc_modifiers_post(scene, ob, dispbase, derivedFinal,
			forRender, originalVerts, deformedVerts);
}