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 {
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); } } } }
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; }
/* 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); }
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); } }
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++; } } } }
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); }
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); }
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; }
/* 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); } } }