/* taper rules: - only 1 curve - first point left, last point right - based on subdivided points in original curve, not on points in taper curve (still) */ float calc_taper(Scene *scene, Object *taperobj, int cur, int tot) { DispList *dl; if(taperobj==NULL || taperobj->type!=OB_CURVE) return 1.0; dl= taperobj->disp.first; if(dl==NULL) { makeDispListCurveTypes(scene, taperobj, 0); dl= taperobj->disp.first; } if(dl) { float fac= ((float)cur)/(float)(tot-1); float minx, dx, *fp; int a; /* horizontal size */ minx= dl->verts[0]; dx= dl->verts[3*(dl->nr-1)] - minx; if(dx > 0.0f) { fp= dl->verts; for(a=0; a<dl->nr; a++, fp+=3) { if( (fp[0]-minx)/dx >= fac) { /* interpolate with prev */ if(a>0) { float fac1= (fp[-3]-minx)/dx; float fac2= (fp[0]-minx)/dx; if(fac1!=fac2) return fp[1]*(fac1-fac)/(fac1-fac2) + fp[-2]*(fac-fac2)/(fac1-fac2); } return fp[1]; } } return fp[-2]; // last y coord } } return 1.0; }
static void precalculate_effector(EffectorCache *eff) { unsigned int cfra = (unsigned int)(eff->scene->r.cfra >= 0 ? eff->scene->r.cfra : -eff->scene->r.cfra); if(!eff->pd->rng) eff->pd->rng = rng_new(eff->pd->seed + cfra); else rng_srandom(eff->pd->rng, eff->pd->seed + cfra); if(eff->pd->forcefield == PFIELD_GUIDE && eff->ob->type==OB_CURVE) { Curve *cu= eff->ob->data; if(cu->flag & CU_PATH) { if(cu->path==NULL || cu->path->data==NULL) makeDispListCurveTypes(eff->scene, eff->ob, 0); if(cu->path && cu->path->data) { where_on_path(eff->ob, 0.0, eff->guide_loc, eff->guide_dir, NULL, &eff->guide_radius, NULL); mul_m4_v3(eff->ob->obmat, eff->guide_loc); mul_mat3_m4_v3(eff->ob->obmat, eff->guide_dir); } } } else if(eff->pd->shape == PFIELD_SHAPE_SURFACE) { eff->surmd = (SurfaceModifierData *)modifiers_findByType ( eff->ob, eModifierType_Surface ); if(eff->ob->type == OB_CURVE) eff->flag |= PE_USE_NORMAL_DATA; } else if(eff->psys) psys_update_particle_tree(eff->psys, eff->scene->r.cfra); /* Store object velocity */ if(eff->ob) { float old_vel[3]; where_is_object_time(eff->scene, eff->ob, cfra - 1.0f); copy_v3_v3(old_vel, eff->ob->obmat[3]); where_is_object_time(eff->scene, eff->ob, cfra); sub_v3_v3v3(eff->velocity, eff->ob->obmat[3], old_vel); } }
static int meshdeform_bind_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); Object *ob = ED_object_active_context(C); MeshDeformModifierData *mmd = (MeshDeformModifierData *)edit_modifier_property_get(op, ob, eModifierType_MeshDeform); if (!mmd) return OPERATOR_CANCELLED; if(mmd->bindcagecos) { MEM_freeN(mmd->bindcagecos); if(mmd->dyngrid) MEM_freeN(mmd->dyngrid); if(mmd->dyninfluences) MEM_freeN(mmd->dyninfluences); if(mmd->bindinfluences) MEM_freeN(mmd->bindinfluences); if(mmd->bindoffsets) MEM_freeN(mmd->bindoffsets); if(mmd->dynverts) MEM_freeN(mmd->dynverts); if(mmd->bindweights) MEM_freeN(mmd->bindweights); /* deprecated */ if(mmd->bindcos) MEM_freeN(mmd->bindcos); /* deprecated */ mmd->bindcagecos= NULL; mmd->dyngrid= NULL; mmd->dyninfluences= NULL; mmd->bindoffsets= NULL; mmd->dynverts= NULL; mmd->bindweights= NULL; /* deprecated */ mmd->bindcos= NULL; /* deprecated */ mmd->totvert= 0; mmd->totcagevert= 0; mmd->totinfluence= 0; DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); } else { DerivedMesh *dm; int mode= mmd->modifier.mode; /* force modifier to run, it will call binding routine */ mmd->bindfunc= mesh_deform_bind; mmd->modifier.mode |= eModifierMode_Realtime; if(ob->type == OB_MESH) { dm= mesh_create_derived_view(scene, ob, 0); dm->release(dm); } else if(ob->type == OB_LATTICE) { lattice_calc_modifiers(scene, ob); } else if(ob->type==OB_MBALL) { makeDispListMBall(scene, ob); } else if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) { makeDispListCurveTypes(scene, ob, 0); } mmd->bindfunc= NULL; mmd->modifier.mode= mode; } return OPERATOR_FINISHED; }
static void do_nla(Scene *scene, Object *ob, int blocktype) { bPose *tpose= NULL; Key *key= NULL; ListBase tchanbase={NULL, NULL}, chanbase={NULL, NULL}; bActionStrip *strip, *striplast=NULL, *stripfirst=NULL; float striptime, frametime, length, actlength; float blendfac, stripframe; float scene_cfra= BKE_curframe(scene); int doit, dostride; if(blocktype==ID_AR) { copy_pose(&tpose, ob->pose, 1); rest_pose(ob->pose); // potentially destroying current not-keyed pose } else { key= ob_get_key(ob); } /* check on extend to left or right, when no strip is hit by 'cfra' */ for (strip=ob->nlastrips.first; strip; strip=strip->next) { /* escape loop on a hit */ if( scene_cfra >= strip->start && scene_cfra <= strip->end + 0.1f) /* note 0.1 comes back below */ break; if(scene_cfra < strip->start) { if(stripfirst==NULL) stripfirst= strip; else if(stripfirst->start > strip->start) stripfirst= strip; } else if(scene_cfra > strip->end) { if(striplast==NULL) striplast= strip; else if(striplast->end < strip->end) striplast= strip; } } if(strip==NULL) { /* extend */ if(striplast) scene_cfra= striplast->end; else if(stripfirst) scene_cfra= stripfirst->start; } /* and now go over all strips */ for (strip=ob->nlastrips.first; strip; strip=strip->next){ doit=dostride= 0; if (strip->act && !(strip->flag & ACTSTRIP_MUTE)) { /* so theres an action */ /* Determine if the current frame is within the strip's range */ length = strip->end-strip->start; actlength = strip->actend-strip->actstart; striptime = (scene_cfra-(strip->start)) / length; stripframe = (scene_cfra-(strip->start)) ; if (striptime>=0.0){ if(blocktype==ID_AR) rest_pose(tpose); /* To handle repeat, we add 0.1 frame extra to make sure the last frame is included */ if (striptime < 1.0f + 0.1f/length) { /* Handle path */ if ((strip->flag & ACTSTRIP_USESTRIDE) && (blocktype==ID_AR) && (ob->ipoflag & OB_DISABLE_PATH)==0){ Object *parent= get_parent_path(ob); if (parent) { Curve *cu = parent->data; float ctime, pdist; if (cu->flag & CU_PATH){ /* Ensure we have a valid path */ if(cu->path==NULL || cu->path->data==NULL) makeDispListCurveTypes(scene, parent, 0); if(cu->path) { /* Find the position on the path */ ctime= bsystem_time(scene, ob, scene_cfra, 0.0); if(calc_ipo_spec(cu->ipo, CU_SPEED, &ctime)==0) { /* correct for actions not starting on zero */ ctime= (ctime - strip->actstart)/cu->pathlen; CLAMP(ctime, 0.0, 1.0); } pdist = ctime*cu->path->totdist; if(tpose && strip->stridechannel[0]) { striptime= stridechannel_frame(parent, ob->size[0], strip, cu->path, pdist, tpose->stride_offset); } else { if (strip->stridelen) { striptime = pdist / strip->stridelen; striptime = (float)fmod (striptime+strip->actoffs, 1.0); } else striptime = 0; } frametime = (striptime * actlength) + strip->actstart; frametime= bsystem_time(scene, ob, frametime, 0.0); if(blocktype==ID_AR) { extract_pose_from_action (tpose, strip->act, frametime); } else if(blocktype==ID_OB) { extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", frametime); if(key) extract_ipochannels_from_action(&tchanbase, &key->id, strip->act, "Shape", frametime); } doit=dostride= 1; } } } } /* To handle repeat, we add 0.1 frame extra to make sure the last frame is included */ else { /* Mod to repeat */ if(strip->repeat!=1.0f) { float cycle= striptime*strip->repeat; striptime = (float)fmod (cycle, 1.0f + 0.1f/length); cycle-= striptime; if(blocktype==ID_AR) cyclic_offs_bone(ob, tpose, strip, cycle); } frametime = (striptime * actlength) + strip->actstart; frametime= nla_time(scene, frametime, (float)strip->repeat); if(blocktype==ID_AR) { extract_pose_from_action (tpose, strip->act, frametime); } else if(blocktype==ID_OB) { extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", frametime); if(key) extract_ipochannels_from_action(&tchanbase, &key->id, strip->act, "Shape", frametime); } doit=1; } } /* Handle extend */ else { if (strip->flag & ACTSTRIP_HOLDLASTFRAME){ /* we want the strip to hold on the exact fraction of the repeat value */ frametime = actlength * (strip->repeat-(int)strip->repeat); if(frametime<=0.000001f) frametime= actlength; /* rounding errors... */ frametime= bsystem_time(scene, ob, frametime+strip->actstart, 0.0); if(blocktype==ID_AR) extract_pose_from_action (tpose, strip->act, frametime); else if(blocktype==ID_OB) { extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", frametime); if(key) extract_ipochannels_from_action(&tchanbase, &key->id, strip->act, "Shape", frametime); } /* handle cycle hold */ if(strip->repeat!=1.0f) { if(blocktype==ID_AR) cyclic_offs_bone(ob, tpose, strip, strip->repeat-1.0f); } doit=1; } } /* Handle blendin & blendout */ if (doit){ /* Handle blendin */ if (strip->blendin>0.0 && stripframe<=strip->blendin && scene_cfra>=strip->start){ blendfac = stripframe/strip->blendin; } else if (strip->blendout>0.0 && stripframe>=(length-strip->blendout) && scene_cfra<=strip->end){ blendfac = (length-stripframe)/(strip->blendout); } else blendfac = 1; if(blocktype==ID_AR) {/* Blend this pose with the accumulated pose */ /* offset bone, for matching cycles */ blend_pose_offset_bone (strip, ob->pose, tpose, blendfac, strip->mode); blend_poses (ob->pose, tpose, blendfac, strip->mode); if(dostride) blend_pose_strides (ob->pose, tpose, blendfac, strip->mode); } else { blend_ipochannels(&chanbase, &tchanbase, blendfac, strip->mode); BLI_freelistN(&tchanbase); } } } } } if(blocktype==ID_OB) { execute_ipochannels(&chanbase); } else if(blocktype==ID_AR) { /* apply stride offset to object */ add_v3_v3(ob->obmat[3], ob->pose->stride_offset); } /* free */ if (tpose) free_pose(tpose); if(chanbase.first) BLI_freelistN(&chanbase); }
struct chartrans *BKE_text_to_curve(Main *bmain, Scene *scene, Object *ob, int mode) { VFont *vfont, *oldvfont; VFontData *vfd= NULL; Curve *cu; CharInfo *info = NULL, *custrinfo; TextBox *tb; VChar *che; struct chartrans *chartransdata=NULL, *ct; float *f, xof, yof, xtrax, linedist, *linedata, *linedata2, *linedata3, *linedata4; float twidth, maxlen= 0; int i, slen, j; int curbox; int selstart, selend; int utf8len; short cnr=0, lnr=0, wsnr= 0; wchar_t *mem, *tmp, ascii; /* renark: do calculations including the trailing '\0' of a string * because the cursor can be at that location */ if (ob->type!=OB_FONT) return NULL; // Set font data cu= (Curve *) ob->data; vfont= cu->vfont; if (cu->str == NULL) return NULL; if (vfont == NULL) return NULL; // Create unicode string utf8len = BLI_strlen_utf8(cu->str); mem = MEM_callocN(((utf8len + 1) * sizeof(wchar_t)), "convertedmem"); BLI_strncpy_wchar_from_utf8(mem, cu->str, utf8len + 1); // Count the wchar_t string length slen = wcslen(mem); if (cu->ulheight == 0.0f) cu->ulheight = 0.05f; if (cu->strinfo==NULL) /* old file */ cu->strinfo = MEM_callocN((slen+4) * sizeof(CharInfo), "strinfo compat"); custrinfo= cu->strinfo; if (cu->editfont) custrinfo= cu->editfont->textbufinfo; if (cu->tb==NULL) cu->tb= MEM_callocN(MAXTEXTBOX*sizeof(TextBox), "TextBox compat"); vfd= vfont_get_data(bmain, vfont); /* The VFont Data can not be found */ if (!vfd) { if (mem) MEM_freeN(mem); return NULL; } /* calc offset and rotation of each char */ ct = chartransdata = (struct chartrans*)MEM_callocN((slen+1)* sizeof(struct chartrans),"buildtext"); /* We assume the worst case: 1 character per line (is freed at end anyway) */ linedata= MEM_mallocN(sizeof(float)*(slen*2 + 1),"buildtext2"); linedata2= MEM_mallocN(sizeof(float)*(slen*2 + 1),"buildtext3"); linedata3= MEM_callocN(sizeof(float)*(slen*2 + 1),"buildtext4"); linedata4= MEM_callocN(sizeof(float)*(slen*2 + 1),"buildtext5"); linedist= cu->linedist; xof= cu->xof + (cu->tb[0].x/cu->fsize); yof= cu->yof + (cu->tb[0].y/cu->fsize); xtrax= 0.5f*cu->spacing-0.5f; oldvfont = NULL; for (i=0; i<slen; i++) custrinfo[i].flag &= ~(CU_CHINFO_WRAP|CU_CHINFO_SMALLCAPS_CHECK); if (cu->selboxes) MEM_freeN(cu->selboxes); cu->selboxes = NULL; if (BKE_font_getselection(ob, &selstart, &selend)) cu->selboxes = MEM_callocN((selend-selstart+1)*sizeof(SelBox), "font selboxes"); tb = &(cu->tb[0]); curbox= 0; for (i = 0 ; i<=slen ; i++) { makebreak: // Characters in the list info = &(custrinfo[i]); ascii = mem[i]; if (info->flag & CU_CHINFO_SMALLCAPS) { ascii = towupper(ascii); if (mem[i] != ascii) { mem[i]= ascii; info->flag |= CU_CHINFO_SMALLCAPS_CHECK; } } vfont = which_vfont(cu, info); if (vfont==NULL) break; che= find_vfont_char(vfd, ascii); /* * The character wasn't in the current curve base so load it * But if the font is FO_BUILTIN_NAME then do not try loading since * whole font is in the memory already */ if (che == NULL && strcmp(vfont->name, FO_BUILTIN_NAME)) { BLI_vfontchar_from_freetypefont(vfont, ascii); } /* Try getting the character again from the list */ che= find_vfont_char(vfd, ascii); /* No VFont found */ if (vfont==NULL) { if (mem) MEM_freeN(mem); MEM_freeN(chartransdata); return NULL; } if (vfont != oldvfont) { vfd= vfont_get_data(bmain, vfont); oldvfont = vfont; } /* VFont Data for VFont couldn't be found */ if (!vfd) { if (mem) MEM_freeN(mem); MEM_freeN(chartransdata); return NULL; } twidth = char_width(cu, che, info); // Calculate positions if ((tb->w != 0.0f) && (ct->dobreak==0) && ((xof-(tb->x/cu->fsize)+twidth)*cu->fsize) > tb->w + cu->xof*cu->fsize) { // fprintf(stderr, "linewidth exceeded: %c%c%c...\n", mem[i], mem[i+1], mem[i+2]); for (j=i; j && (mem[j] != '\n') && (mem[j] != '\r') && (chartransdata[j].dobreak==0); j--) { if (mem[j]==' ' || mem[j]=='-') { ct -= (i-(j-1)); cnr -= (i-(j-1)); if (mem[j] == ' ') wsnr--; if (mem[j] == '-') wsnr++; i = j-1; xof = ct->xof; ct[1].dobreak = 1; custrinfo[i+1].flag |= CU_CHINFO_WRAP; goto makebreak; } if (chartransdata[j].dobreak) { // fprintf(stderr, "word too long: %c%c%c...\n", mem[j], mem[j+1], mem[j+2]); ct->dobreak= 1; custrinfo[i+1].flag |= CU_CHINFO_WRAP; ct -= 1; cnr -= 1; i--; xof = ct->xof; goto makebreak; } } } if (ascii== '\n' || ascii== '\r' || ascii==0 || ct->dobreak) { ct->xof= xof; ct->yof= yof; ct->linenr= lnr; ct->charnr= cnr; yof-= linedist; maxlen= MAX2(maxlen, (xof-tb->x/cu->fsize)); linedata[lnr]= xof-tb->x/cu->fsize; linedata2[lnr]= cnr; linedata3[lnr]= tb->w/cu->fsize; linedata4[lnr]= wsnr; if ( (tb->h != 0.0f) && ((-(yof-(tb->y/cu->fsize))) > ((tb->h/cu->fsize)-(linedist*cu->fsize)) - cu->yof) && (cu->totbox > (curbox+1)) ) { maxlen= 0; tb++; curbox++; yof= cu->yof + tb->y/cu->fsize; } /* XXX, has been unused for years, need to check if this is useful, r4613 r5282 - campbell */ #if 0 if (ascii == '\n' || ascii == '\r') xof = cu->xof; else xof= cu->xof + (tb->x/cu->fsize); #else xof= cu->xof + (tb->x/cu->fsize); #endif lnr++; cnr= 0; wsnr= 0; } else if (ascii==9) { /* TAB */ float tabfac; ct->xof= xof; ct->yof= yof; ct->linenr= lnr; ct->charnr= cnr++; tabfac= (xof-cu->xof+0.01f); tabfac= 2.0f*ceilf(tabfac/2.0f); xof= cu->xof+tabfac; } else { SelBox *sb= NULL; float wsfac; ct->xof= xof; ct->yof= yof; ct->linenr= lnr; ct->charnr= cnr++; if (cu->selboxes && (i>=selstart) && (i<=selend)) { sb = &(cu->selboxes[i-selstart]); sb->y = yof*cu->fsize-linedist*cu->fsize*0.1f; sb->h = linedist*cu->fsize; sb->w = xof*cu->fsize; } if (ascii==32) { wsfac = cu->wordspace; wsnr++; } else wsfac = 1.0f; // Set the width of the character twidth = char_width(cu, che, info); xof += (twidth*wsfac*(1.0f+(info->kern/40.0f)) ) + xtrax; if (sb) sb->w = (xof*cu->fsize) - sb->w; } ct++; } cu->lines= 1; ct= chartransdata; tmp = mem; for (i= 0; i<=slen; i++, tmp++, ct++) { ascii = *tmp; if (ascii== '\n' || ascii== '\r' || ct->dobreak) cu->lines++; } // linedata is now: width of line // linedata2 is now: number of characters // linedata3 is now: maxlen of that line // linedata4 is now: number of whitespaces of line if (cu->spacemode!=CU_LEFT) { ct= chartransdata; if (cu->spacemode==CU_RIGHT) { for (i=0;i<lnr;i++) linedata[i]= linedata3[i]-linedata[i]; for (i=0; i<=slen; i++) { ct->xof+= linedata[ct->linenr]; ct++; } } else if (cu->spacemode==CU_MIDDLE) { for (i=0;i<lnr;i++) linedata[i]= (linedata3[i]-linedata[i])/2; for (i=0; i<=slen; i++) { ct->xof+= linedata[ct->linenr]; ct++; } } else if ((cu->spacemode==CU_FLUSH) && (cu->tb[0].w != 0.0f)) { for (i=0;i<lnr;i++) if (linedata2[i]>1) linedata[i]= (linedata3[i]-linedata[i])/(linedata2[i]-1); for (i=0; i<=slen; i++) { for (j=i; (!ELEM3(mem[j], '\0', '\n', '\r')) && (chartransdata[j].dobreak == 0) && (j < slen); j++) { /* do nothing */ } // if ((mem[j]!='\r') && (mem[j]!='\n') && (mem[j])) { ct->xof+= ct->charnr*linedata[ct->linenr]; // } ct++; } } else if ((cu->spacemode==CU_JUSTIFY) && (cu->tb[0].w != 0.0f)) { float curofs= 0.0f; for (i=0; i<=slen; i++) { for (j=i; (mem[j]) && (mem[j]!='\n') && (mem[j]!='\r') && (chartransdata[j].dobreak==0) && (j<slen); j++); if ((mem[j]!='\r') && (mem[j]!='\n') && ((chartransdata[j].dobreak!=0))) { if (mem[i]==' ') curofs += (linedata3[ct->linenr]-linedata[ct->linenr])/linedata4[ct->linenr]; ct->xof+= curofs; } if (mem[i]=='\n' || mem[i]=='\r' || chartransdata[i].dobreak) curofs= 0; ct++; } } } /* TEXT ON CURVE */ /* Note: Only OB_CURVE objects could have a path */ if (cu->textoncurve && cu->textoncurve->type==OB_CURVE) { Curve *cucu= cu->textoncurve->data; int oldflag= cucu->flag; cucu->flag |= (CU_PATH+CU_FOLLOW); if (cucu->path==NULL) makeDispListCurveTypes(scene, cu->textoncurve, 0); if (cucu->path) { float distfac, imat[4][4], imat3[3][3], cmat[3][3]; float minx, maxx, miny, maxy; float timeofs, sizefac; invert_m4_m4(imat, ob->obmat); copy_m3_m4(imat3, imat); copy_m3_m4(cmat, cu->textoncurve->obmat); mul_m3_m3m3(cmat, cmat, imat3); sizefac= normalize_v3(cmat[0])/cu->fsize; minx=miny= 1.0e20f; maxx=maxy= -1.0e20f; ct= chartransdata; for (i=0; i<=slen; i++, ct++) { if (minx>ct->xof) minx= ct->xof; if (maxx<ct->xof) maxx= ct->xof; if (miny>ct->yof) miny= ct->yof; if (maxy<ct->yof) maxy= ct->yof; } /* we put the x-coordinaat exact at the curve, the y is rotated */ /* length correction */ distfac= sizefac*cucu->path->totdist/(maxx-minx); timeofs= 0.0f; if (distfac > 1.0f) { /* path longer than text: spacemode involves */ distfac= 1.0f/distfac; if (cu->spacemode==CU_RIGHT) { timeofs= 1.0f-distfac; } else if (cu->spacemode==CU_MIDDLE) { timeofs= (1.0f-distfac)/2.0f; } else if (cu->spacemode==CU_FLUSH) distfac= 1.0f; } else distfac= 1.0; distfac/= (maxx-minx); timeofs+= distfac*cu->xof; /* not cyclic */ ct= chartransdata; for (i=0; i<=slen; i++, ct++) { float ctime, dtime, vec[4], tvec[4], rotvec[3]; float si, co; /* rotate around center character */ ascii = mem[i]; che= find_vfont_char(vfd, ascii); twidth = char_width(cu, che, info); dtime= distfac*0.5f*twidth; ctime= timeofs + distfac*( ct->xof - minx); CLAMP(ctime, 0.0f, 1.0f); /* calc the right loc AND the right rot separately */ /* vec, tvec need 4 items */ where_on_path(cu->textoncurve, ctime, vec, tvec, NULL, NULL, NULL); where_on_path(cu->textoncurve, ctime+dtime, tvec, rotvec, NULL, NULL, NULL); mul_v3_fl(vec, sizefac); ct->rot= (float)(M_PI-atan2(rotvec[1], rotvec[0])); si= (float)sin(ct->rot); co= (float)cos(ct->rot); yof= ct->yof; ct->xof= vec[0] + si*yof; ct->yof= vec[1] + co*yof; } cucu->flag= oldflag; } } if (cu->selboxes) { ct= chartransdata; for (i=0; i<=selend; i++, ct++) { if (i>=selstart) { cu->selboxes[i-selstart].x = ct->xof*cu->fsize; cu->selboxes[i-selstart].y = ct->yof*cu->fsize; } } } if (mode==FO_CURSUP || mode==FO_CURSDOWN || mode==FO_PAGEUP || mode==FO_PAGEDOWN) { /* 2: curs up * 3: curs down */ ct= chartransdata+cu->pos; if ((mode==FO_CURSUP || mode==FO_PAGEUP) && ct->linenr==0); else if ((mode==FO_CURSDOWN || mode==FO_PAGEDOWN) && ct->linenr==lnr); else { switch(mode) { case FO_CURSUP: lnr= ct->linenr-1; break; case FO_CURSDOWN: lnr= ct->linenr+1; break; case FO_PAGEUP: lnr= ct->linenr-10; break; case FO_PAGEDOWN: lnr= ct->linenr+10; break; } cnr= ct->charnr; /* seek for char with lnr en cnr */ cu->pos= 0; ct= chartransdata; for (i= 0; i<slen; i++) { if (ct->linenr==lnr) { if (ct->charnr==cnr) break; if ( (ct+1)->charnr==0) break; } else if (ct->linenr>lnr) break; cu->pos++; ct++; } } } /* cursor first */ if (cu->editfont) { float si, co; ct= chartransdata+cu->pos; si= (float)sin(ct->rot); co= (float)cos(ct->rot); f= cu->editfont->textcurs[0]; f[0]= cu->fsize*(-0.1f*co + ct->xof); f[1]= cu->fsize*(0.1f*si + ct->yof); f[2]= cu->fsize*(0.1f*co + ct->xof); f[3]= cu->fsize*(-0.1f*si + ct->yof); f[4]= cu->fsize*( 0.1f*co + 0.8f*si + ct->xof); f[5]= cu->fsize*(-0.1f*si + 0.8f*co + ct->yof); f[6]= cu->fsize*(-0.1f*co + 0.8f*si + ct->xof); f[7]= cu->fsize*( 0.1f*si + 0.8f*co + ct->yof); } MEM_freeN(linedata); MEM_freeN(linedata2); MEM_freeN(linedata3); MEM_freeN(linedata4); if (mode == FO_SELCHANGE) { MEM_freeN(chartransdata); MEM_freeN(mem); return NULL; } if (mode == FO_EDIT) { /* make nurbdata */ freeNurblist(&cu->nurb); ct= chartransdata; if (cu->sepchar==0) { for (i= 0; i<slen; i++) { unsigned long cha = (uintptr_t) mem[i]; info = &(custrinfo[i]); if (info->mat_nr > (ob->totcol)) { /* printf("Error: Illegal material index (%d) in text object, setting to 0\n", info->mat_nr); */ info->mat_nr = 0; } // We do not want to see any character for \n or \r if (cha != '\n' && cha != '\r') buildchar(bmain, cu, cha, info, ct->xof, ct->yof, ct->rot, i); if ((info->flag & CU_CHINFO_UNDERLINE) && (cu->textoncurve == NULL) && (cha != '\n') && (cha != '\r')) { float ulwidth, uloverlap= 0.0f; if ( (i<(slen-1)) && (mem[i+1] != '\n') && (mem[i+1] != '\r') && ((mem[i+1] != ' ') || (custrinfo[i+1].flag & CU_CHINFO_UNDERLINE)) && ((custrinfo[i+1].flag & CU_CHINFO_WRAP)==0) ) { uloverlap = xtrax + 0.1f; } // Find the character, the characters has to be in the memory already // since character checking has been done earlier already. che= find_vfont_char(vfd, cha); twidth = char_width(cu, che, info); ulwidth = cu->fsize * ((twidth* (1.0f+(info->kern/40.0f)))+uloverlap); build_underline(cu, ct->xof*cu->fsize, ct->yof*cu->fsize + (cu->ulpos-0.05f)*cu->fsize, ct->xof*cu->fsize + ulwidth, ct->yof*cu->fsize + (cu->ulpos-0.05f)*cu->fsize - cu->ulheight*cu->fsize, i, info->mat_nr); } ct++; } } else { int outta = 0; for (i= 0; (i<slen) && (outta==0); i++) { ascii = mem[i]; info = &(custrinfo[i]); if (cu->sepchar == (i+1)) { float vecyo[3]; vecyo[0]= ct->xof; vecyo[1]= ct->yof; vecyo[2]= 0.0f; mem[0] = ascii; mem[1] = 0; custrinfo[0]= *info; cu->pos = 1; cu->len = 1; mul_v3_m4v3(ob->loc, ob->obmat, vecyo); outta = 1; cu->sepchar = 0; } ct++; } } } if (mode==FO_DUPLI) { MEM_freeN(mem); return chartransdata; } if (mem) MEM_freeN(mem); MEM_freeN(chartransdata); return NULL; }
/* 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; }
/* axis is using another define!!! */ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, CurveDeform *cd, float *quatp) { Curve *cu= par->data; float fac, loc[4], dir[3], new_quat[4], radius; short /*upflag, */ index; index= axis-1; if(index>2) index -= 3; /* negative */ /* to be sure, mostly after file load */ if(cu->path==NULL) { makeDispListCurveTypes(scene, par, 0); if(cu->path==NULL) return 0; // happens on append... } /* options */ if(ELEM3(axis, OB_NEGX+1, OB_NEGY+1, OB_NEGZ+1)) { /* OB_NEG# 0-5, MOD_CURVE_POS# 1-6 */ if(cu->flag & CU_STRETCH) fac= (-co[index]-cd->dmax[index])/(cd->dmax[index] - cd->dmin[index]); else fac= (cd->dloc[index])/(cu->path->totdist) - (co[index]-cd->dmax[index])/(cu->path->totdist); } else { if(cu->flag & CU_STRETCH) fac= (co[index]-cd->dmin[index])/(cd->dmax[index] - cd->dmin[index]); else fac= (cd->dloc[index])/(cu->path->totdist) + (co[index]-cd->dmin[index])/(cu->path->totdist); } #if 0 // XXX old animation system /* we want the ipo to work on the default 100 frame range, because there's no actual time involved in path position */ // huh? by WHY!!!!???? - Aligorith if(cu->ipo) { fac*= 100.0f; if(calc_ipo_spec(cu->ipo, CU_SPEED, &fac)==0) fac/= 100.0; } #endif // XXX old animation system if( where_on_path_deform(par, fac, loc, dir, new_quat, &radius)) { /* returns OK */ float quat[4], cent[3]; #if 0 // XXX - 2.4x Z-Up, Now use bevel tilt. if(cd->no_rot_axis) /* set by caller */ dir[cd->no_rot_axis-1]= 0.0f; /* -1 for compatibility with old track defines */ vec_to_quat( quat,dir, axis-1, upflag); /* the tilt */ if(loc[3]!=0.0) { normalize_v3(dir); q[0]= (float)cos(0.5*loc[3]); fac= (float)sin(0.5*loc[3]); q[1]= -fac*dir[0]; q[2]= -fac*dir[1]; q[3]= -fac*dir[2]; mul_qt_qtqt(quat, q, quat); } #endif if(cd->no_rot_axis) { /* set by caller */ /* this is not exactly the same as 2.4x, since the axis is having rotation removed rather than * changing the axis before calculating the tilt but serves much the same purpose */ float dir_flat[3]={0,0,0}, q[4]; copy_v3_v3(dir_flat, dir); dir_flat[cd->no_rot_axis-1]= 0.0f; normalize_v3(dir); normalize_v3(dir_flat); rotation_between_vecs_to_quat(q, dir, dir_flat); /* Could this be done faster? */ mul_qt_qtqt(new_quat, q, new_quat); } /* Logic for 'cent' orientation * * * The way 'co' is copied to 'cent' may seem to have no meaning, but it does. * * Use a curve modifier to stretch a cube out, color each side RGB, positive side light, negative dark. * view with X up (default), from the angle that you can see 3 faces RGB colors (light), anti-clockwise * Notice X,Y,Z Up all have light colors and each ordered CCW. * * Now for Neg Up XYZ, the colors are all dark, and ordered clockwise - Campbell * * note: moved functions into quat_apply_track/vec_apply_track * */ copy_qt_qt(quat, new_quat); copy_v3_v3(cent, co); /* zero the axis which is not used, * the big block of text above now applies to these 3 lines */ quat_apply_track(quat, axis-1, (axis==1 || axis==3) ? 1:0); /* up flag is a dummy, set so no rotation is done */ vec_apply_track(cent, axis-1); cent[axis < 4 ? axis-1 : axis-4]= 0.0f; /* scale if enabled */ if(cu->flag & CU_PATH_RADIUS) mul_v3_fl(cent, radius); /* local rotation */ normalize_qt(quat); mul_qt_v3(quat, cent); /* translation */ add_v3_v3v3(co, cent, loc); if(quatp) copy_qt_qt(quatp, quat); return 1; } return 0; }