static void *do_multires_bake_thread(void *data_v) { MultiresBakeThread *handle = (MultiresBakeThread *) data_v; MResolvePixelData *data = &handle->data; MBakeRast *bake_rast = &handle->bake_rast; MultiresBakeRender *bkr = handle->bkr; int f; while ((f = multires_bake_queue_next_face(handle->queue)) >= 0) { MTFace *mtfate = &data->mtface[f]; int verts[3][2], nr_tris, t; if (multiresbake_test_break(bkr)) break; if (mtfate->tpage != handle->image) continue; data->face_index = f; /* might support other forms of diagonal splits later on such as * split by shortest diagonal.*/ verts[0][0] = 0; verts[1][0] = 1; verts[2][0] = 2; verts[0][1] = 0; verts[1][1] = 2; verts[2][1] = 3; nr_tris = data->mface[f].v4 != 0 ? 2 : 1; for (t = 0; t < nr_tris; t++) { data->i0 = verts[0][t]; data->i1 = verts[1][t]; data->i2 = verts[2][t]; bake_rasterize(bake_rast, mtfate->uv[data->i0], mtfate->uv[data->i1], mtfate->uv[data->i2]); /* tag image buffer for refresh */ if (data->ibuf->rect_float) data->ibuf->userflags |= IB_RECT_INVALID; data->ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; } /* update progress */ BLI_spin_lock(&handle->queue->spin); bkr->baked_faces++; if (bkr->do_update) *bkr->do_update = TRUE; if (bkr->progress) *bkr->progress = ((float)bkr->baked_objects + (float)bkr->baked_faces / handle->queue->tot_face) / bkr->tot_obj; BLI_spin_unlock(&handle->queue->spin); } return NULL; }
static void do_multires_bake(MultiresBakeRender *bkr, Image* ima, MPassKnownData passKnownData, MInitBakeData initBakeData, MApplyBakeData applyBakeData, MFreeBakeData freeBakeData) { DerivedMesh *dm= bkr->lores_dm; ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); const int lvl= bkr->lvl; const int tot_face= dm->getNumFaces(dm); MVert *mvert= dm->getVertArray(dm); MFace *mface= dm->getFaceArray(dm); MTFace *mtface= dm->getFaceDataArray(dm, CD_MTFACE); float *pvtangent= NULL; if(CustomData_get_layer_index(&dm->faceData, CD_TANGENT) == -1) DM_add_tangent_layer(dm); pvtangent= DM_get_face_data_layer(dm, CD_TANGENT); if(tot_face > 0) { /* sanity check */ int f= 0; MBakeRast bake_rast; MResolvePixelData data={NULL}; data.mface= mface; data.mvert= mvert; data.mtface= mtface; data.pvtangent= pvtangent; data.precomputed_normals= dm->getFaceDataArray(dm, CD_NORMAL); /* don't strictly need this */ data.w= ibuf->x; data.h= ibuf->y; data.lores_dm= dm; data.hires_dm= bkr->hires_dm; data.lvl= lvl; data.pass_data= passKnownData; if(initBakeData) data.bake_data= initBakeData(bkr, ima); init_bake_rast(&bake_rast, ibuf, &data, flush_pixel); for(f= 0; f<tot_face; f++) { MTFace *mtfate= &mtface[f]; int verts[3][2], nr_tris, t; if(multiresbake_test_break(bkr)) break; if(mtfate->tpage!=ima) continue; data.face_index= f; /* might support other forms of diagonal splits later on such as split by shortest diagonal.*/ verts[0][0]=0; verts[1][0]=1; verts[2][0]=2; verts[0][1]=0; verts[1][1]=2; verts[2][1]=3; nr_tris= mface[f].v4!=0 ? 2 : 1; for(t= 0; t<nr_tris; t++) { data.i0= verts[0][t]; data.i1= verts[1][t]; data.i2 =verts[2][t]; bake_rasterize(&bake_rast, mtfate->uv[data.i0], mtfate->uv[data.i1], mtfate->uv[data.i2]); } bkr->baked_faces++; if(bkr->do_update) *bkr->do_update= 1; if(bkr->progress) *bkr->progress= ((float)bkr->baked_objects + (float)bkr->baked_faces / tot_face) / bkr->tot_obj; } if(applyBakeData) applyBakeData(data.bake_data); if(freeBakeData) freeBakeData(data.bake_data); } }