static void imb_stereo3d_read_interlace(Stereo3DData *s3d, enum eStereo3dInterlaceType mode, const bool swap) { int x, y; size_t width = s3d->x; size_t height = s3d->y; const size_t channels = s3d->channels; const int stride_from = width; const int stride_to = width; if (s3d->is_float) { float *rect_left = s3d->rectf.left; float *rect_right = s3d->rectf.right; const float *rect_from = s3d->rectf.stereo; switch (mode) { case S3D_INTERLACE_ROW: { char i = (char) swap; for (y = 0; y < height; y++) { const float *from = rect_from + stride_from * y * channels; float *to[2] = { rect_left + stride_to * y * channels, rect_right + stride_to * y * channels, }; memcpy(to[i], from, sizeof(float) * channels * stride_to); i = !i; } break; } case S3D_INTERLACE_COLUMN: { if (channels == 1) { for (y = 0; y < height; y++) { const float *from = rect_from + stride_from * y; float *to[2] = { rect_left + stride_to * y, rect_right + stride_to * y, }; char i = (char) swap; for (x = 0; x < width; x++, from += 1, to[0] += 1, to[1] += 1) { to[i][0] = from[0]; i = !i; } } } else if (channels == 3) { for (y = 0; y < height; y++) { const float *from = rect_from + stride_from * y * 3; float *to[2] = { rect_left + stride_to * y * 3, rect_right + stride_to * y * 3, }; char i = (char) swap; for (x = 0; x < width; x++, from += 3, to[0] += 3, to[1] += 3) { copy_v3_v3(to[i], from); i = !i; } } } else if (channels == 4) { for (y = 0; y < height; y++) { const float *from = rect_from + stride_from * y * channels; float *to[2] = { rect_left + stride_to * y * channels, rect_right + stride_to * y * channels, }; char i = (char) swap; for (x = 0; x < width; x++, from += 4, to[0] += 4, to[1] += 4) { copy_v4_v4(to[i], from); i = !i; } } } break; } case S3D_INTERLACE_CHECKERBOARD: { if (channels == 1) { char i = (char) swap; for (y = 0; y < height; y++) { const float *from = rect_from + stride_from * y; float *to[2] = { rect_left + stride_to * y, rect_right + stride_to * y, }; char j = i; for (x = 0; x < width; x++, from += 1, to[0] += 1, to[1] += 1) { to[j][0] = from[0]; j = !j; } i = !i; } } else if (channels == 3) { char i = (char) swap; for (y = 0; y < height; y++) { const float *from = rect_from + stride_from * y * 3; float *to[2] = { rect_left + stride_to * y * 3, rect_right + stride_to * y * 3, }; char j = i; for (x = 0; x < width; x++, from += 3, to[0] += 3, to[1] += 3) { copy_v3_v3(to[j], from); j = !j; } i = !i; } } else if (channels == 4) { char i = (char) swap; for (y = 0; y < height; y++) { const float *from = rect_from + stride_from * y * 4; float *to[2] = { rect_left + stride_to * y * 4, rect_right + stride_to * y * 4, }; char j = i; for (x = 0; x < width; x++, from += 4, to[0] += 4, to[1] += 4) { copy_v4_v4(to[j], from); j = !j; } i = !i; } } break; } default: { break; } } } else { uchar *rect_left = s3d->rect.right; uchar *rect_right = s3d->rect.left; const uchar *rect_from = s3d->rect.stereo; switch (mode) { case S3D_INTERLACE_ROW: { char i = (char) swap; for (y = 0; y < height; y++) { const uchar *from = rect_from + stride_from * y * channels; uchar *to[2] = { rect_left + stride_to * y * channels, rect_right + stride_to * y * channels, }; memcpy(to[i], from, sizeof(uchar) * channels * stride_to); i = !i; } break; } case S3D_INTERLACE_COLUMN: { if (channels == 1) { for (y = 0; y < height; y++) { const uchar *from = rect_from + stride_from * y; uchar *to[2] = { rect_left + stride_to * y, rect_right + stride_to * y, }; char i = (char) swap; for (x = 0; x < width; x++, from += 1, to[0] += 1, to[1] += 1) { to[i][0] = from[0]; i = !i; } } } else if (channels == 3) { for (y = 0; y < height; y++) { const uchar *from = rect_from + stride_from * y * 3; uchar *to[2] = { rect_left + stride_to * y * 3, rect_right + stride_to * y * 3, }; char i = (char) swap; for (x = 0; x < width; x++, from += 3, to[0] += 3, to[1] += 3) { copy_v3_v3_uchar(to[i], from); i = !i; } } } else if (channels == 4) { for (y = 0; y < height; y++) { const uchar *from = rect_from + stride_from * y * 4; uchar *to[2] = { rect_left + stride_to * y * 4, rect_right + stride_to * y * 4, }; char i = (char) swap; for (x = 0; x < width; x++, from += 4, to[0] += 4, to[1] += 4) { copy_v4_v4_uchar(to[i], from); i = !i; } } } break; } case S3D_INTERLACE_CHECKERBOARD: { if (channels == 1) { char i = (char) swap; for (y = 0; y < height; y++) { const uchar *from = rect_from + stride_from * y; uchar *to[2] = { rect_left + stride_to * y, rect_right + stride_to * y, }; char j = i; for (x = 0; x < width; x++, from += 1, to[0] += 1, to[1] += 1) { to[j][0] = from[0]; j = !j; } i = !i; } } else if (channels == 3) { char i = (char) swap; for (y = 0; y < height; y++) { const uchar *from = rect_from + stride_from * y * 3; uchar *to[2] = { rect_left + stride_to * y * 3, rect_right + stride_to * y * 3, }; char j = i; for (x = 0; x < width; x++, from += 3, to[0] += 3, to[1] += 3) { copy_v3_v3_uchar(to[j], from); j = !j; } i = !i; } } else if (channels == 4) { char i = (char) swap; for (y = 0; y < height; y++) { const uchar *from = rect_from + stride_from * y * 4; uchar *to[2] = { rect_left + stride_to * y * 4, rect_right + stride_to * y * 4, }; char j = i; for (x = 0; x < width; x++, from += 4, to[0] += 4, to[1] += 4) { copy_v4_v4_uchar(to[j], from); j = !j; } i = !i; } } break; } default: { break; } } } }
static void update_tface_color_layer(DerivedMesh *dm, bool use_mcol) { const MPoly *mp = dm->getPolyArray(dm); const int mpoly_num = dm->getNumPolys(dm); MTexPoly *mtexpoly = DM_get_poly_data_layer(dm, CD_MTEXPOLY); MLoopCol *finalCol; int i, j; MLoopCol *mloopcol = NULL; /* cache material values to avoid a lot of lookups */ Material *ma = NULL; short mat_nr_prev = -1; enum { COPY_CALC, COPY_ORIG, COPY_PREV, } copy_mode = COPY_CALC; if (use_mcol) { mloopcol = dm->getLoopDataArray(dm, CD_PREVIEW_MLOOPCOL); if (!mloopcol) mloopcol = dm->getLoopDataArray(dm, CD_MLOOPCOL); } if (CustomData_has_layer(&dm->loopData, CD_TEXTURE_MLOOPCOL)) { finalCol = CustomData_get_layer(&dm->loopData, CD_TEXTURE_MLOOPCOL); } else { finalCol = MEM_mallocN(sizeof(MLoopCol) * dm->numLoopData, "add_tface_color_layer"); CustomData_add_layer(&dm->loopData, CD_TEXTURE_MLOOPCOL, CD_ASSIGN, finalCol, dm->numLoopData); } for (i = mpoly_num; i--; mp++) { const short mat_nr = mp->mat_nr; if (UNLIKELY(mat_nr_prev != mat_nr)) { ma = give_current_material(Gtexdraw.ob, mat_nr + 1); copy_mode = COPY_CALC; mat_nr_prev = mat_nr; } /* avoid lookups */ if (copy_mode == COPY_ORIG) { memcpy(&finalCol[mp->loopstart], &mloopcol[mp->loopstart], sizeof(*finalCol) * mp->totloop); } else if (copy_mode == COPY_PREV) { int loop_index = mp->loopstart; const MLoopCol *lcol_prev = &finalCol[(mp - 1)->loopstart]; for (j = 0; j < mp->totloop; j++, loop_index++) { finalCol[loop_index] = *lcol_prev; } } /* (copy_mode == COPY_CALC) */ else if (ma && (ma->game.flag & GEMAT_INVISIBLE)) { if (mloopcol) { memcpy(&finalCol[mp->loopstart], &mloopcol[mp->loopstart], sizeof(*finalCol) * mp->totloop); copy_mode = COPY_ORIG; } else { memset(&finalCol[mp->loopstart], 0xff, sizeof(*finalCol) * mp->totloop); copy_mode = COPY_PREV; } } else if (mtexpoly && set_draw_settings_cached(0, mtexpoly, ma, Gtexdraw)) { int loop_index = mp->loopstart; for (j = 0; j < mp->totloop; j++, loop_index++) { finalCol[loop_index].r = 255; finalCol[loop_index].g = 0; finalCol[loop_index].b = 255; } copy_mode = COPY_PREV; } else if (ma && (ma->shade_flag & MA_OBCOLOR)) { int loop_index = mp->loopstart; for (j = 0; j < mp->totloop; j++, loop_index++) { copy_v3_v3_uchar(&finalCol[loop_index].r, Gtexdraw.obcol); } copy_mode = COPY_PREV; } else { if (mloopcol) { memcpy(&finalCol[mp->loopstart], &mloopcol[mp->loopstart], sizeof(*finalCol) * mp->totloop); copy_mode = COPY_ORIG; } else if (mtexpoly) { memset(&finalCol[mp->loopstart], 0xff, sizeof(*finalCol) * mp->totloop); copy_mode = COPY_PREV; } else { float col[3]; if (ma) { int loop_index = mp->loopstart; MLoopCol lcol; if (Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r); else copy_v3_v3(col, &ma->r); rgb_float_to_uchar((unsigned char *)&lcol.r, col); lcol.a = 255; for (j = 0; j < mp->totloop; j++, loop_index++) { finalCol[loop_index] = lcol; } } else { memset(&finalCol[mp->loopstart], 0xff, sizeof(*finalCol) * mp->totloop); } copy_mode = COPY_PREV; } } } }