Ejemplo n.º 1
0
/**
 * \note Only use in object mode.
 */
static void validate_object_select_id(
    struct Depsgraph *depsgraph, Scene *scene, ARegion *ar, View3D *v3d, Object *obact)
{
  RegionView3D *rv3d = ar->regiondata;
  Scene *scene_eval = (Scene *)DEG_get_evaluated_id(depsgraph, &scene->id);
  Object *obact_eval = DEG_get_evaluated_object(depsgraph, obact);

  BLI_assert(ar->regiontype == RGN_TYPE_WINDOW);

  if (obact_eval && (obact_eval->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT) ||
                     BKE_paint_select_face_test(obact_eval))) {
    /* do nothing */
  }
  /* texture paint mode sampling */
  else if (obact_eval && (obact_eval->mode & OB_MODE_TEXTURE_PAINT) &&
           (v3d->shading.type > OB_WIRE)) {
    /* do nothing */
  }
  else if ((obact_eval && (obact_eval->mode & OB_MODE_PARTICLE_EDIT)) && !XRAY_ENABLED(v3d)) {
    /* do nothing */
  }
  else {
    v3d->flag &= ~V3D_INVALID_BACKBUF;
    return;
  }

  if (!(v3d->flag & V3D_INVALID_BACKBUF)) {
    return;
  }

  if (obact_eval && ((obact_eval->base_flag & BASE_VISIBLE) != 0)) {
    uint dummy_vert_ofs, dummy_edge_ofs, dummy_face_ofs;
    DRW_framebuffer_select_id_setup(ar, true);
    DRW_draw_select_id_object(scene_eval,
                              rv3d,
                              obact_eval,
                              scene->toolsettings->selectmode,
                              false,
                              1,
                              &dummy_vert_ofs,
                              &dummy_edge_ofs,
                              &dummy_face_ofs);

    DRW_framebuffer_select_id_release(ar);
  }

  /* TODO: Create a flag in `DRW_manager` because the drawing is no longer
   *       made on the backbuffer in this case. */
  v3d->flag &= ~V3D_INVALID_BACKBUF;
}
Ejemplo n.º 2
0
void ED_view3d_backbuf_depth_validate(ViewContext *vc)
{
  if (vc->v3d->flag & V3D_INVALID_BACKBUF) {
    ARegion *ar = vc->ar;
    Object *obact_eval = DEG_get_evaluated_object(vc->depsgraph, vc->obact);

    if (obact_eval && ((obact_eval->base_flag & BASE_VISIBLE) != 0)) {
      GPUViewport *viewport = WM_draw_region_get_viewport(ar, 0);
      DRW_draw_depth_object(vc->ar, viewport, obact_eval);
    }

    vc->v3d->flag &= ~V3D_INVALID_BACKBUF;
  }
}
Ejemplo n.º 3
0
static void vpaint_proj_dm_map_cosnos_init(struct Depsgraph *depsgraph,
                                           Scene *UNUSED(scene),
                                           Object *ob,
                                           struct VertProjHandle *vp_handle)
{
  Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
  Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
  Mesh *me = ob->data;

  CustomData_MeshMasks cddata_masks = CD_MASK_BAREMESH_ORIGINDEX;
  Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &cddata_masks);

  memset(vp_handle->vcosnos, 0, sizeof(*vp_handle->vcosnos) * me->totvert);
  BKE_mesh_foreach_mapped_vert(
      me_eval, vpaint_proj_dm_map_cosnos_init__map_cb, vp_handle, MESH_FOREACH_USE_NORMAL);
}
Ejemplo n.º 4
0
static Subdiv *multires_create_subdiv_for_reshape(struct Depsgraph *depsgraph,
                                                  /*const*/ Object *object,
                                                  const MultiresModifierData *mmd)
{
  Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
  Object *object_eval = DEG_get_evaluated_object(depsgraph, object);
  Mesh *deformed_mesh = mesh_get_eval_deform(
      depsgraph, scene_eval, object_eval, &CD_MASK_BAREMESH);
  SubdivSettings subdiv_settings;
  BKE_multires_subdiv_settings_init(&subdiv_settings, mmd);
  Subdiv *subdiv = BKE_subdiv_new_from_mesh(&subdiv_settings, deformed_mesh);
  if (!BKE_subdiv_eval_update_from_mesh(subdiv, deformed_mesh)) {
    BKE_subdiv_free(subdiv);
    return NULL;
  }
  return subdiv;
}
Ejemplo n.º 5
0
static void rna_Object_calc_matrix_camera(Object *ob,
                                          Depsgraph *depsgraph,
                                          float mat_ret[16],
                                          int width,
                                          int height,
                                          float scalex,
                                          float scaley)
{
  const Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
  CameraParams params;

  /* setup parameters */
  BKE_camera_params_init(&params);
  BKE_camera_params_from_object(&params, ob_eval);

  /* compute matrix, viewplane, .. */
  BKE_camera_params_compute_viewplane(&params, width, height, scalex, scaley);
  BKE_camera_params_compute_matrix(&params);

  copy_m4_m4((float(*)[4])mat_ret, params.winmat);
}
Ejemplo n.º 6
0
static Object *eval_object_ensure(Object *ob,
                                  bContext *C,
                                  ReportList *reports,
                                  PointerRNA *rnaptr_depsgraph)
{
  if (ob->runtime.mesh_eval == NULL) {
    Object *ob_orig = ob;
    Depsgraph *depsgraph = rnaptr_depsgraph != NULL ? rnaptr_depsgraph->data : NULL;
    if (depsgraph == NULL) {
      depsgraph = CTX_data_depsgraph(C);
    }
    if (depsgraph != NULL) {
      ob = DEG_get_evaluated_object(depsgraph, ob);
    }
    if (ob == NULL || ob->runtime.mesh_eval == NULL) {
      BKE_reportf(
          reports, RPT_ERROR, "Object '%s' has no evaluated mesh data", ob_orig->id.name + 2);
      return NULL;
    }
  }
  return ob;
}
Ejemplo n.º 7
0
static void vpaint_proj_dm_map_cosnos_update(struct Depsgraph *depsgraph,
                                             struct VertProjHandle *vp_handle,
                                             ARegion *ar,
                                             const float mval_fl[2])
{
  struct VertProjUpdate vp_update = {vp_handle, ar, mval_fl};

  Object *ob = vp_handle->ob;
  Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
  Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
  Mesh *me = ob->data;

  CustomData_MeshMasks cddata_masks = CD_MASK_BAREMESH_ORIGINDEX;
  Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &cddata_masks);

  /* quick sanity check - we shouldn't have to run this if there are no modifiers */
  BLI_assert(BLI_listbase_is_empty(&ob->modifiers) == false);

  copy_vn_fl(vp_handle->dists_sq, me->totvert, FLT_MAX);
  BKE_mesh_foreach_mapped_vert(
      me_eval, vpaint_proj_dm_map_cosnos_update__map_cb, &vp_update, MESH_FOREACH_USE_NORMAL);
}
Ejemplo n.º 8
0
void BKE_mesh_to_curve(Main *bmain, Depsgraph *depsgraph, Scene *UNUSED(scene), Object *ob)
{
  /* make new mesh data from the original copy */
  Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
  Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
  Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &CD_MASK_MESH);
  ListBase nurblist = {NULL, NULL};

  BKE_mesh_to_curve_nurblist(me_eval, &nurblist, 0);
  BKE_mesh_to_curve_nurblist(me_eval, &nurblist, 1);

  if (nurblist.first) {
    Curve *cu = BKE_curve_add(bmain, ob->id.name + 2, OB_CURVE);
    cu->flag |= CU_3D;

    cu->nurb = nurblist;

    id_us_min(&((Mesh *)ob->data)->id);
    ob->data = cu;
    ob->type = OB_CURVE;

    BKE_object_free_derived_caches(ob);
  }
}
Ejemplo n.º 9
0
/* copy the face flags, most importantly selection from the mesh to the final derived mesh,
 * use in object mode when selecting faces (while painting) */
void paintface_flush_flags(struct bContext *C, Object *ob, short flag)
{
  Mesh *me = BKE_mesh_from_object(ob);
  MPoly *polys, *mp_orig;
  const int *index_array = NULL;
  int totpoly;
  int i;

  BLI_assert((flag & ~(SELECT | ME_HIDE)) == 0);

  if (me == NULL) {
    return;
  }

  /* note, call #BKE_mesh_flush_hidden_from_verts_ex first when changing hidden flags */

  /* we could call this directly in all areas that change selection,
   * since this could become slow for realtime updates (circle-select for eg) */
  if (flag & SELECT) {
    BKE_mesh_flush_select_from_polys(me);
  }

  Depsgraph *depsgraph = CTX_data_depsgraph(C);
  Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);

  if (ob_eval == NULL) {
    return;
  }

  Mesh *me_orig = ob_eval->runtime.mesh_orig;
  Mesh *me_eval = ob_eval->runtime.mesh_eval;
  bool updated = false;

  if (me_orig != NULL && me_eval != NULL && me_orig->totpoly == me->totpoly) {
    /* Update the COW copy of the mesh. */
    for (i = 0; i < me->totpoly; i++) {
      me_orig->mpoly[i].flag = me->mpoly[i].flag;
    }

    /* If the mesh has only deform modifiers, the evaluated mesh shares arrays. */
    if (me_eval->mpoly == me_orig->mpoly) {
      updated = true;
    }
    /* Mesh polys => Final derived polys */
    else if ((index_array = CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX))) {
      polys = me_eval->mpoly;
      totpoly = me_eval->totpoly;

      /* loop over final derived polys */
      for (i = 0; i < totpoly; i++) {
        if (index_array[i] != ORIGINDEX_NONE) {
          /* Copy flags onto the final derived poly from the original mesh poly */
          mp_orig = me->mpoly + index_array[i];
          polys[i].flag = mp_orig->flag;
        }
      }

      updated = true;
    }
  }

  if (updated) {
    if (flag & ME_HIDE) {
      BKE_mesh_batch_cache_dirty_tag(me_eval, BKE_MESH_BATCH_DIRTY_ALL);
    }
    else {
      BKE_mesh_batch_cache_dirty_tag(me_eval, BKE_MESH_BATCH_DIRTY_SELECT_PAINT);
    }

    DEG_id_tag_update(ob->data, ID_RECALC_SELECT);
  }
  else {
    DEG_id_tag_update(ob->data, ID_RECALC_COPY_ON_WRITE | ID_RECALC_SELECT);
  }

  WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data);
}
Ejemplo n.º 10
0
/* settings: 1 - preview, 2 - render
 *
 * The convention goes as following:
 *
 * - Passing original object with apply_modifiers=false will give a
 *   non-modified non-deformed mesh.
 *   The result mesh will point to datablocks from the original "domain". For
 *   example, materials will be original.
 *
 * - Passing original object with apply_modifiers=true will give a mesh which
 *   has all modifiers applied.
 *   The result mesh will point to datablocks from the original "domain". For
 *   example, materials will be original.
 *
 * - Passing evaluated object will ignore apply_modifiers argument, and the
 *   result always contains all modifiers applied.
 *   The result mesh will point to an evaluated datablocks. For example,
 *   materials will be an evaluated IDs from the dependency graph.
 */
Mesh *BKE_mesh_new_from_object(Depsgraph *depsgraph,
                               Main *bmain,
                               Scene *sce,
                               Object *ob,
                               const bool apply_modifiers,
                               const bool calc_undeformed)
{
  Mesh *tmpmesh;
  Curve *tmpcu = NULL, *copycu;
  int i;
  const bool render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
  bool effective_apply_modifiers = apply_modifiers;
  bool do_mat_id_data_us = true;

  Object *object_input = ob;
  Object *object_eval = DEG_get_evaluated_object(depsgraph, object_input);
  Object object_for_eval;

  if (object_eval == object_input) {
    /* Evaluated mesh contains all modifiers applied already.
     * The other types of object has them applied, but are stored in other
     * data structures than a mesh. So need to apply modifiers again on a
     * temporary copy before converting result to mesh. */
    if (object_input->type == OB_MESH) {
      effective_apply_modifiers = false;
    }
    else {
      effective_apply_modifiers = true;
    }
    object_for_eval = *object_eval;
  }
  else {
    if (apply_modifiers) {
      object_for_eval = *object_eval;
      if (object_for_eval.runtime.mesh_orig != NULL) {
        object_for_eval.data = object_for_eval.runtime.mesh_orig;
      }
    }
    else {
      object_for_eval = *object_input;
    }
  }

  const bool cage = !effective_apply_modifiers;

  /* perform the mesh extraction based on type */
  switch (object_for_eval.type) {
    case OB_FONT:
    case OB_CURVE:
    case OB_SURF: {
      ListBase dispbase = {NULL, NULL};
      Mesh *me_eval_final = NULL;
      int uv_from_orco;

      /* copies object and modifiers (but not the data) */
      Object *tmpobj;
      BKE_id_copy_ex(NULL, &object_for_eval.id, (ID **)&tmpobj, LIB_ID_COPY_LOCALIZE);
      tmpcu = (Curve *)tmpobj->data;

      /* Copy cached display list, it might be needed by the stack evaluation.
       * Ideally stack should be able to use render-time display list, but doing
       * so is quite tricky and not safe so close to the release.
       *
       * TODO(sergey): Look into more proper solution.
       */
      if (object_for_eval.runtime.curve_cache != NULL) {
        if (tmpobj->runtime.curve_cache == NULL) {
          tmpobj->runtime.curve_cache = MEM_callocN(sizeof(CurveCache),
                                                    "CurveCache for curve types");
        }
        BKE_displist_copy(&tmpobj->runtime.curve_cache->disp,
                          &object_for_eval.runtime.curve_cache->disp);
      }

      /* if getting the original caged mesh, delete object modifiers */
      if (cage) {
        BKE_object_free_modifiers(tmpobj, LIB_ID_CREATE_NO_USER_REFCOUNT);
      }

      /* copies the data, but *not* the shapekeys. */
      BKE_id_copy_ex(NULL, object_for_eval.data, (ID **)&copycu, LIB_ID_COPY_LOCALIZE);
      tmpobj->data = copycu;

      /* make sure texture space is calculated for a copy of curve,
       * it will be used for the final result.
       */
      BKE_curve_texspace_calc(copycu);

      /* temporarily set edit so we get updates from edit mode, but
       * also because for text datablocks copying it while in edit
       * mode gives invalid data structures */
      copycu->editfont = tmpcu->editfont;
      copycu->editnurb = tmpcu->editnurb;

      /* get updated display list, and convert to a mesh */
      BKE_displist_make_curveTypes_forRender(
          depsgraph, sce, tmpobj, &dispbase, &me_eval_final, false, NULL);

      copycu->editfont = NULL;
      copycu->editnurb = NULL;

      tmpobj->runtime.mesh_eval = me_eval_final;

      /* convert object type to mesh */
      uv_from_orco = (tmpcu->flag & CU_UV_ORCO) != 0;
      BKE_mesh_from_nurbs_displist(
          bmain, tmpobj, &dispbase, uv_from_orco, tmpcu->id.name + 2, true);
      /* Function above also frees copycu (aka tmpobj->data), make this obvious here. */
      copycu = NULL;

      tmpmesh = tmpobj->data;
      id_us_min(
          &tmpmesh->id); /* Gets one user from its creation in BKE_mesh_from_nurbs_displist(). */

      BKE_displist_free(&dispbase);

      /* BKE_mesh_from_nurbs changes the type to a mesh, check it worked.
       * if it didn't the curve did not have any segments or otherwise
       * would have generated an empty mesh */
      if (tmpobj->type != OB_MESH) {
        BKE_id_free(NULL, tmpobj);
        return NULL;
      }

      BKE_id_free(NULL, tmpobj);

      /* XXX The curve to mesh conversion is convoluted...
       *     But essentially, BKE_mesh_from_nurbs_displist()
       *     already transfers the ownership of materials from the temp copy of the Curve ID to the
       *     new Mesh ID, so we do not want to increase materials' usercount later. */
      do_mat_id_data_us = false;

      break;
    }

    case OB_MBALL: {
      /* metaballs don't have modifiers, so just convert to mesh */
      Object *basis_ob = BKE_mball_basis_find(sce, object_input);
      /* todo, re-generatre for render-res */
      /* metaball_polygonize(scene, ob) */

      if (basis_ob != object_input) {
        /* Only do basis metaball. */
        return NULL;
      }

      tmpmesh = BKE_mesh_add(bmain, ((ID *)object_for_eval.data)->name + 2);
      /* BKE_mesh_add gives us a user count we don't need */
      id_us_min(&tmpmesh->id);

      if (render) {
        ListBase disp = {NULL, NULL};
        BKE_displist_make_mball_forRender(depsgraph, sce, &object_for_eval, &disp);
        BKE_mesh_from_metaball(&disp, tmpmesh);
        BKE_displist_free(&disp);
      }
      else {
        ListBase disp = {NULL, NULL};
        if (object_for_eval.runtime.curve_cache) {
          disp = object_for_eval.runtime.curve_cache->disp;
        }
        BKE_mesh_from_metaball(&disp, tmpmesh);
      }

      BKE_mesh_texspace_copy_from_object(tmpmesh, &object_for_eval);

      break;
    }
    case OB_MESH:
      /* copies object and modifiers (but not the data) */
      if (cage) {
        /* copies the data (but *not* the shapekeys). */
        Mesh *mesh = object_for_eval.data;
        BKE_id_copy_ex(bmain, &mesh->id, (ID **)&tmpmesh, 0);
        /* XXX BKE_mesh_copy() already handles materials usercount. */
        do_mat_id_data_us = false;
      }
      /* if not getting the original caged mesh, get final derived mesh */
      else {
        /* Make a dummy mesh, saves copying */
        Mesh *me_eval;
        CustomData_MeshMasks mask = CD_MASK_MESH; /* this seems more suitable, exporter,
                                                   * for example, needs CD_MASK_MDEFORMVERT */

        if (calc_undeformed) {
          mask.vmask |= CD_MASK_ORCO;
        }

        if (render) {
          me_eval = mesh_create_eval_final_render(depsgraph, sce, &object_for_eval, &mask);
        }
        else {
          me_eval = mesh_create_eval_final_view(depsgraph, sce, &object_for_eval, &mask);
        }

        tmpmesh = BKE_mesh_add(bmain, ((ID *)object_for_eval.data)->name + 2);
        BKE_mesh_nomain_to_mesh(me_eval, tmpmesh, &object_for_eval, &mask, true);

        /* Copy autosmooth settings from original mesh. */
        Mesh *me = (Mesh *)object_for_eval.data;
        tmpmesh->flag |= (me->flag & ME_AUTOSMOOTH);
        tmpmesh->smoothresh = me->smoothresh;
      }

      /* BKE_mesh_add/copy gives us a user count we don't need */
      id_us_min(&tmpmesh->id);

      break;
    default:
      /* "Object does not have geometry data") */
      return NULL;
  }

  /* Copy materials to new mesh */
  switch (object_for_eval.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] = give_current_material(object_input, i + 1);

          if (((object_for_eval.matbits && object_for_eval.matbits[i]) || do_mat_id_data_us) &&
              tmpmesh->mat[i]) {
            id_us_plus(&tmpmesh->mat[i]->id);
          }
        }
      }
      break;

    case OB_MBALL: {
      MetaBall *tmpmb = (MetaBall *)object_for_eval.data;
      tmpmesh->mat = MEM_dupallocN(tmpmb->mat);
      tmpmesh->totcol = tmpmb->totcol;

      /* free old material list (if it exists) and adjust user counts */
      if (tmpmb->mat) {
        for (i = tmpmb->totcol; i-- > 0;) {
          /* are we an object material or data based? */
          tmpmesh->mat[i] = give_current_material(object_input, i + 1);

          if (((object_for_eval.matbits && object_for_eval.matbits[i]) || do_mat_id_data_us) &&
              tmpmesh->mat[i]) {
            id_us_plus(&tmpmesh->mat[i]->id);
          }
        }
      }
      break;
    }

    case OB_MESH:
      if (!cage) {
        Mesh *origmesh = object_for_eval.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] = give_current_material(object_input, i + 1);

            if (((object_for_eval.matbits && object_for_eval.matbits[i]) || do_mat_id_data_us) &&
                tmpmesh->mat[i]) {
              id_us_plus(&tmpmesh->mat[i]->id);
            }
          }
        }
      }
      break;
  } /* end copy materials */

  return tmpmesh;
}