static void *init_heights_data(MultiresBakeRender *bkr, Image *ima) { MHeightBakeData *height_data; ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); DerivedMesh *lodm= bkr->lores_dm; height_data= MEM_callocN(sizeof(MHeightBakeData), "MultiresBake heightData"); height_data->ima= ima; height_data->heights= MEM_callocN(sizeof(float)*ibuf->x*ibuf->y, "MultiresBake heights"); height_data->height_max= -FLT_MAX; height_data->height_min= FLT_MAX; if(!bkr->use_lores_mesh) { SubsurfModifierData smd= {{NULL}}; int ss_lvl= bkr->tot_lvl - bkr->lvl; CLAMP(ss_lvl, 0, 6); smd.levels= smd.renderLevels= ss_lvl; smd.flags|= eSubsurfModifierFlag_SubsurfUv; if(bkr->simple) smd.subdivType= ME_SIMPLE_SUBSURF; height_data->ssdm= subsurf_make_derived_from_derived(bkr->lores_dm, &smd, 0, NULL, 0, 0, 0); } height_data->origindex= lodm->getFaceDataArray(lodm, CD_ORIGINDEX); return (void*)height_data; }
static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *derivedData, ModifierApplyFlag flag) { SubsurfModifierData *smd = (SubsurfModifierData *) md; SubsurfFlags subsurf_flags = 0; DerivedMesh *result; const int useRenderParams = flag & MOD_APPLY_RENDER; const int isFinalCalc = flag & MOD_APPLY_USECACHE; if (useRenderParams) subsurf_flags |= SUBSURF_USE_RENDER_PARAMS; if (isFinalCalc) subsurf_flags |= SUBSURF_IS_FINAL_CALC; if (ob->flag & OB_MODE_EDIT) subsurf_flags |= SUBSURF_IN_EDIT_MODE; result = subsurf_make_derived_from_derived(derivedData, smd, NULL, subsurf_flags); if (useRenderParams || !isFinalCalc) { DerivedMesh *cddm = CDDM_copy(result); result->release(result); result = cddm; } return result; }
static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *derivedData, ModifierApplyFlag flag) { SubsurfModifierData *smd = (SubsurfModifierData *) md; SubsurfFlags subsurf_flags = 0; DerivedMesh *result; const bool useRenderParams = (flag & MOD_APPLY_RENDER) != 0; const bool isFinalCalc = (flag & MOD_APPLY_USECACHE) != 0; #ifdef WITH_OPENSUBDIV const bool allow_gpu = (flag & MOD_APPLY_ALLOW_GPU) != 0; const bool do_cddm_convert = useRenderParams || (!isFinalCalc && !smd->use_opensubdiv); #else const bool do_cddm_convert = useRenderParams || !isFinalCalc; #endif if (useRenderParams) subsurf_flags |= SUBSURF_USE_RENDER_PARAMS; if (isFinalCalc) subsurf_flags |= SUBSURF_IS_FINAL_CALC; if (ob->mode & OB_MODE_EDIT) subsurf_flags |= SUBSURF_IN_EDIT_MODE; #ifdef WITH_OPENSUBDIV /* TODO(sergey): Not entirely correct, modifiers on top of subsurf * could be disabled. */ if (md->next == NULL && allow_gpu && do_cddm_convert == false && smd->use_opensubdiv) { if (U.opensubdiv_compute_type == USER_OPENSUBDIV_COMPUTE_NONE) { modifier_setError(md, "OpenSubdiv is disabled in User Preferences"); } else if ((DAG_get_eval_flags_for_object(md->scene, ob) & DAG_EVAL_NEED_CPU) == 0) { subsurf_flags |= SUBSURF_USE_GPU_BACKEND; } else { modifier_setError(md, "OpenSubdiv is disabled due to dependencies"); } } #endif result = subsurf_make_derived_from_derived(derivedData, smd, NULL, subsurf_flags); result->cd_flag = derivedData->cd_flag; if (do_cddm_convert) { DerivedMesh *cddm = CDDM_copy(result); result->release(result); result = cddm; } return result; }
static DerivedMesh *applyModifierEM(ModifierData *md, Object *UNUSED(ob), struct EditMesh *UNUSED(editData), DerivedMesh *derivedData) { SubsurfModifierData *smd = (SubsurfModifierData*) md; DerivedMesh *result; result = subsurf_make_derived_from_derived(derivedData, smd, 0, NULL, 0, 1, 1); return result; }
static DerivedMesh *applyModifierEM(ModifierData *md, Object *UNUSED(ob), struct BMEditMesh *UNUSED(editData), DerivedMesh *derivedData) { SubsurfModifierData *smd = (SubsurfModifierData *) md; DerivedMesh *result; result = subsurf_make_derived_from_derived(derivedData, smd, NULL, (SUBSURF_FOR_EDIT_MODE | SUBSURF_IN_EDIT_MODE)); return result; }
static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *derivedData, int useRenderParams, int isFinalCalc) { SubsurfModifierData *smd = (SubsurfModifierData*) md; DerivedMesh *result; result = subsurf_make_derived_from_derived(derivedData, smd, useRenderParams, NULL, isFinalCalc, 0, (ob->flag & OB_MODE_EDIT)); if(useRenderParams || !isFinalCalc) { DerivedMesh *cddm= CDDM_copy(result); result->release(result); result= cddm; } return result; }
static DerivedMesh *applyModifierEM(ModifierData *md, Object *UNUSED(ob), struct BMEditMesh *UNUSED(editData), DerivedMesh *derivedData, ModifierApplyFlag flag) { SubsurfModifierData *smd = (SubsurfModifierData *) md; DerivedMesh *result; /* 'orco' using editmode flags would cause cache to be used twice in editbmesh_calc_modifiers */ SubsurfFlags ss_flags = (flag & MOD_APPLY_ORCO) ? 0 : (SUBSURF_FOR_EDIT_MODE | SUBSURF_IN_EDIT_MODE); #ifdef WITH_OPENSUBDIV const bool allow_gpu = (flag & MOD_APPLY_ALLOW_GPU) != 0; if (md->next == NULL && allow_gpu && smd->use_opensubdiv) { modifier_setError(md, "OpenSubdiv is not supported in edit mode"); } #endif result = subsurf_make_derived_from_derived(derivedData, smd, NULL, ss_flags); return result; }
static void *init_heights_data(MultiresBakeRender *bkr, Image *ima) { MHeightBakeData *height_data; ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL, IMA_IBUF_IMA); DerivedMesh *lodm = bkr->lores_dm; BakeImBufuserData *userdata = ibuf->userdata; if (userdata->displacement_buffer == NULL) userdata->displacement_buffer = MEM_callocN(sizeof(float) * ibuf->x * ibuf->y, "MultiresBake heights"); height_data = MEM_callocN(sizeof(MHeightBakeData), "MultiresBake heightData"); height_data->ima = ima; height_data->heights = userdata->displacement_buffer; if (!bkr->use_lores_mesh) { SubsurfModifierData smd = {{NULL}}; int ss_lvl = bkr->tot_lvl - bkr->lvl; CLAMP(ss_lvl, 0, 6); if (ss_lvl > 0) { smd.levels = smd.renderLevels = ss_lvl; smd.flags |= eSubsurfModifierFlag_SubsurfUv; if (bkr->simple) smd.subdivType = ME_SIMPLE_SUBSURF; height_data->ssdm = subsurf_make_derived_from_derived(bkr->lores_dm, &smd, NULL, 0); init_ccgdm_arrays(height_data->ssdm); } } height_data->orig_index_mf_to_mpoly = lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX); height_data->orig_index_mp_to_orig = lodm->getPolyDataArray(lodm, CD_ORIGINDEX); BKE_image_release_ibuf(ima, ibuf, NULL); return (void *)height_data; }
static DerivedMesh *applyModifierEM(ModifierData *md, Object *UNUSED(ob), struct BMEditMesh *UNUSED(editData), DerivedMesh *derivedData, ModifierApplyFlag flag) { SubsurfModifierData *smd = (SubsurfModifierData *) md; DerivedMesh *result; /* 'orco' using editmode flags would cause cache to be used twice in editbmesh_calc_modifiers */ SubsurfFlags ss_flags = (flag & MOD_APPLY_ORCO) ? 0 : (SUBSURF_FOR_EDIT_MODE | SUBSURF_IN_EDIT_MODE); #ifdef WITH_OPENSUBDIV const bool allow_gpu = (flag & MOD_APPLY_ALLOW_GPU) != 0; /* TODO(sergey): Not entirely correct, modifiers on top of subsurf * could be disabled. */ if (md->next == NULL && allow_gpu && smd->use_opensubdiv) { ss_flags |= SUBSURF_USE_GPU_BACKEND; } #endif result = subsurf_make_derived_from_derived(derivedData, smd, NULL, ss_flags); return result; }
/* Main shrinkwrap function */ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int numVerts, bool for_render) { DerivedMesh *ss_mesh = NULL; ShrinkwrapCalcData calc = NULL_ShrinkwrapCalcData; /* remove loop dependencies on derived meshes (TODO should this be done elsewhere?) */ if (smd->target == ob) smd->target = NULL; if (smd->auxTarget == ob) smd->auxTarget = NULL; /* Configure Shrinkwrap calc data */ calc.smd = smd; calc.ob = ob; calc.numVerts = numVerts; calc.vertexCos = vertexCos; /* DeformVertex */ calc.vgroup = defgroup_name_index(calc.ob, calc.smd->vgroup_name); if (dm) { calc.dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); } else if (calc.ob->type == OB_LATTICE) { calc.dvert = BKE_lattice_deform_verts_get(calc.ob); } if (smd->target) { calc.target = object_get_derived_final(smd->target, for_render); /* TODO there might be several "bugs" on non-uniform scales matrixs * because it will no longer be nearest surface, not sphere projection * because space has been deformed */ SPACE_TRANSFORM_SETUP(&calc.local2target, ob, smd->target); /* TODO: smd->keepDist is in global units.. must change to local */ calc.keepDist = smd->keepDist; } calc.vgroup = defgroup_name_index(calc.ob, smd->vgroup_name); if (dm != NULL && smd->shrinkType == MOD_SHRINKWRAP_PROJECT) { /* Setup arrays to get vertexs positions, normals and deform weights */ calc.vert = dm->getVertDataArray(dm, CD_MVERT); calc.dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); /* Using vertexs positions/normals as if a subsurface was applied */ if (smd->subsurfLevels) { SubsurfModifierData ssmd = {{NULL}}; ssmd.subdivType = ME_CC_SUBSURF; /* catmull clark */ ssmd.levels = smd->subsurfLevels; /* levels */ ss_mesh = subsurf_make_derived_from_derived(dm, &ssmd, NULL, (ob->mode & OB_MODE_EDIT) ? SUBSURF_IN_EDIT_MODE : 0); if (ss_mesh) { calc.vert = ss_mesh->getVertDataArray(ss_mesh, CD_MVERT); if (calc.vert) { /* TRICKY: this code assumes subsurface will have the transformed original vertices * in their original order at the end of the vert array. */ calc.vert = calc.vert + ss_mesh->getNumVerts(ss_mesh) - dm->getNumVerts(dm); } } /* Just to make sure we are not leaving any memory behind */ assert(ssmd.emCache == NULL); assert(ssmd.mCache == NULL); } } /* Projecting target defined - lets work! */ if (calc.target) { switch (smd->shrinkType) { case MOD_SHRINKWRAP_NEAREST_SURFACE: TIMEIT_BENCH(shrinkwrap_calc_nearest_surface_point(&calc), deform_surface); break; case MOD_SHRINKWRAP_PROJECT: TIMEIT_BENCH(shrinkwrap_calc_normal_projection(&calc, for_render), deform_project); break; case MOD_SHRINKWRAP_NEAREST_VERTEX: TIMEIT_BENCH(shrinkwrap_calc_nearest_vertex(&calc), deform_vertex); break; } } /* free memory */ if (ss_mesh) ss_mesh->release(ss_mesh); }