Cycles: Initial Support For Local View
authorJeroen Bakker <j.bakker@atmind.nl>
Wed, 11 Sep 2019 06:22:53 +0000 (08:22 +0200)
committerJeroen Bakker <j.bakker@atmind.nl>
Thu, 12 Sep 2019 07:08:22 +0000 (09:08 +0200)
This diff will add support for local view to Cycles rendered preview mode.

Currently the implementation shows same results as EEVEE does. This entails
a difference with Blender 2.79, where lights were automatically added to the
local view. {T69780} describes this should be solved before the next release.

This patch also solves missing `owner_id` issues when using the RNA CPP Api
from Cycles. Cycles didn't provide the `owner_id` making some functionality
fail, what then was worked around in Blender. It also fixes an issue in
`makesrna` where incorrect CPP code was generated when only `PARM_RNAPTR`
was provided.

An optional `view_layer` parameter is added to the `Object.local_view_get`
method to reduce lookups.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D5753

intern/cycles/blender/addon/engine.py
intern/cycles/blender/blender_object.cpp
intern/cycles/blender/blender_python.cpp
source/blender/makesrna/intern/makesrna.c
source/blender/makesrna/intern/rna_object_api.c
source/blender/makesrna/intern/rna_space.c

index b8bc74f9e355b70442550e05450e4538cc038c18..0e3de6d806649c0d4a2a2ef594ac29ab20b8986e 100644 (file)
@@ -139,15 +139,19 @@ def create(engine, data, region=None, v3d=None, rv3d=None, preview_osl=False):
 
     data = data.as_pointer()
     prefs = bpy.context.preferences.as_pointer()
+    screen = None
     if region:
+        screen = region.id_data.as_pointer()
         region = region.as_pointer()
     if v3d:
+        screen = screen or v3d.id_data.as_pointer()
         v3d = v3d.as_pointer()
     if rv3d:
+        screen = screen or rv3d.id_data.as_pointer()
         rv3d = rv3d.as_pointer()
 
     engine.session = _cycles.create(
-            engine.as_pointer(), prefs, data, region, v3d, rv3d, preview_osl)
+            engine.as_pointer(), prefs, data, screen, region, v3d, rv3d, preview_osl)
 
 
 def free(engine):
index b0599546244c03cc8b7f189e539baf5ea0d13c80..082fff0c528cb4ce3983c44162af3985523d1655 100644 (file)
@@ -541,6 +541,7 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph,
   const bool show_lights = BlenderViewportParameters(b_v3d).use_scene_lights;
 
   BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
+  const bool has_local_view = b_v3d && b_v3d.local_view();
 
   BL::Depsgraph::object_instances_iterator b_instance_iter;
   for (b_depsgraph.object_instances.begin(b_instance_iter);
@@ -554,9 +555,10 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph,
 
     /* test if object needs to be hidden */
     const bool show_self = b_instance.show_self();
+    const bool show_local_view = !has_local_view || b_ob.local_view_get(b_v3d, b_view_layer);
     const bool show_particles = b_instance.show_particles();
 
-    if (show_self || show_particles) {
+    if (show_local_view && (show_self || show_particles)) {
       /* object itself */
       sync_object(b_depsgraph,
                   b_view_layer,
index 9753da71eb4a03f0e8d7acd7b85172951a14c865..2bea6b347728565988598c28cbd9e01e3a8ba0a9 100644 (file)
@@ -194,14 +194,15 @@ static PyObject *exit_func(PyObject * /*self*/, PyObject * /*args*/)
 
 static PyObject *create_func(PyObject * /*self*/, PyObject *args)
 {
-  PyObject *pyengine, *pypreferences, *pydata, *pyregion, *pyv3d, *pyrv3d;
+  PyObject *pyengine, *pypreferences, *pydata, *pyscreen, *pyregion, *pyv3d, *pyrv3d;
   int preview_osl;
 
   if (!PyArg_ParseTuple(args,
-                        "OOOOOOi",
+                        "OOOOOOOi",
                         &pyengine,
                         &pypreferences,
                         &pydata,
+                        &pyscreen,
                         &pyregion,
                         &pyv3d,
                         &pyrv3d,
@@ -210,6 +211,8 @@ static PyObject *create_func(PyObject * /*self*/, PyObject *args)
   }
 
   /* RNA */
+  ID *bScreen = (ID *)PyLong_AsVoidPtr(pyscreen);
+
   PointerRNA engineptr;
   RNA_pointer_create(NULL, &RNA_RenderEngine, (void *)PyLong_AsVoidPtr(pyengine), &engineptr);
   BL::RenderEngine engine(engineptr);
@@ -224,15 +227,15 @@ static PyObject *create_func(PyObject * /*self*/, PyObject *args)
   BL::BlendData data(dataptr);
 
   PointerRNA regionptr;
-  RNA_pointer_create(NULL, &RNA_Region, pylong_as_voidptr_typesafe(pyregion), &regionptr);
+  RNA_pointer_create(bScreen, &RNA_Region, pylong_as_voidptr_typesafe(pyregion), &regionptr);
   BL::Region region(regionptr);
 
   PointerRNA v3dptr;
-  RNA_pointer_create(NULL, &RNA_SpaceView3D, pylong_as_voidptr_typesafe(pyv3d), &v3dptr);
+  RNA_pointer_create(bScreen, &RNA_SpaceView3D, pylong_as_voidptr_typesafe(pyv3d), &v3dptr);
   BL::SpaceView3D v3d(v3dptr);
 
   PointerRNA rv3dptr;
-  RNA_pointer_create(NULL, &RNA_RegionView3D, pylong_as_voidptr_typesafe(pyrv3d), &rv3dptr);
+  RNA_pointer_create(bScreen, &RNA_RegionView3D, pylong_as_voidptr_typesafe(pyrv3d), &rv3dptr);
   BL::RegionView3D rv3d(rv3dptr);
 
   /* create session */
index 968baca3517a20398433d030c0192defa1a12b7a..f531eb7f494e4e662fed03f33341705f4f41b94a 100644 (file)
@@ -2539,6 +2539,12 @@ static void rna_def_struct_function_call_impl_cpp(FILE *f, StructRNA *srna, Func
                   rna_safe_id(dp->prop->identifier));
         }
       }
+      else if (dp->prop->flag_parameter & PARM_RNAPTR) {
+        fprintf(f,
+                "(::%s *) &%s",
+                rna_parameter_type_name(dp->prop),
+                rna_safe_id(dp->prop->identifier));
+      }
       else {
         fprintf(f,
                 "(::%s *) %s.ptr.data",
index 5bec6f0c7d3b6f8b93546fa2cb2ecb4f84acc192..e26c430eb1611bd05d6db9e35ba6c57cdcde5718 100644 (file)
@@ -221,32 +221,43 @@ static bool rna_Object_indirect_only_get(Object *ob, bContext *C, ViewLayer *vie
   return ((base->flag & BASE_INDIRECT_ONLY) != 0);
 }
 
-static Base *rna_Object_local_view_property_helper(
-    bScreen *sc, View3D *v3d, Object *ob, ReportList *reports, Scene **r_scene)
+static Base *rna_Object_local_view_property_helper(bScreen *sc,
+                                                   View3D *v3d,
+                                                   ViewLayer *view_layer,
+                                                   Object *ob,
+                                                   ReportList *reports,
+                                                   Scene **r_scene)
 {
+  wmWindow *win = NULL;
   if (v3d->localvd == NULL) {
     BKE_report(reports, RPT_ERROR, "Viewport not in local view");
     return NULL;
   }
 
-  wmWindow *win = ED_screen_window_find(sc, G_MAIN->wm.first);
-  ViewLayer *view_layer = WM_window_get_active_view_layer(win);
+  if (view_layer == NULL) {
+    win = ED_screen_window_find(sc, G_MAIN->wm.first);
+    view_layer = WM_window_get_active_view_layer(win);
+  }
+
   Base *base = BKE_view_layer_base_find(view_layer, ob);
   if (base == NULL) {
     BKE_reportf(
         reports, RPT_WARNING, "Object %s not in view layer %s", ob->id.name + 2, view_layer->name);
   }
-  if (r_scene) {
+  if (r_scene != NULL && win != NULL) {
     *r_scene = win->scene;
   }
   return base;
 }
 
-static bool rna_Object_local_view_get(Object *ob, ReportList *reports, PointerRNA *v3d_ptr)
+static bool rna_Object_local_view_get(Object *ob,
+                                      ReportList *reports,
+                                      PointerRNA *v3d_ptr,
+                                      ViewLayer *view_layer)
 {
   bScreen *sc = (bScreen *)v3d_ptr->owner_id;
   View3D *v3d = v3d_ptr->data;
-  Base *base = rna_Object_local_view_property_helper(sc, v3d, ob, reports, NULL);
+  Base *base = rna_Object_local_view_property_helper(sc, v3d, view_layer, ob, reports, NULL);
   if (base == NULL) {
     return false; /* Error reported. */
   }
@@ -261,7 +272,7 @@ static void rna_Object_local_view_set(Object *ob,
   bScreen *sc = (bScreen *)v3d_ptr->owner_id;
   View3D *v3d = v3d_ptr->data;
   Scene *scene;
-  Base *base = rna_Object_local_view_property_helper(sc, v3d, ob, reports, &scene);
+  Base *base = rna_Object_local_view_property_helper(sc, v3d, NULL, ob, reports, &scene);
   if (base == NULL) {
     return; /* Error reported. */
   }
@@ -276,7 +287,8 @@ static void rna_Object_local_view_set(Object *ob,
   }
 }
 
-/* Convert a given matrix from a space to another (using the object and/or a bone as reference). */
+/* Convert a given matrix from a space to another (using the object and/or a bone as
+ * reference). */
 static void rna_Object_mat_convert_space(Object *ob,
                                          ReportList *reports,
                                          bPoseChannel *pchan,
@@ -466,8 +478,8 @@ static int mesh_looptri_to_poly_index(Mesh *me_eval, const MLoopTri *lt)
   return index_mp_to_orig ? index_mp_to_orig[lt->poly] : lt->poly;
 }
 
-/* TOOD(sergey): Make the Python API more clear that evaluation might happen, or requite passing
- * fully evaluated depsgraph. */
+/* TOOD(sergey): Make the Python API more clear that evaluation might happen, or requite
+ * passing fully evaluated depsgraph. */
 static Object *eval_object_ensure(Object *ob,
                                   bContext *C,
                                   ReportList *reports,
@@ -505,8 +517,8 @@ static void rna_Object_ray_cast(Object *ob,
 {
   bool success = false;
 
-  /* TODO(sergey): This isn't very reliable check. It is possible to have non-NULL pointer but
-   * which is out of date, and possibly dangling one. */
+  /* TODO(sergey): This isn't very reliable check. It is possible to have non-NULL pointer
+   * but which is out of date, and possibly dangling one. */
   if (ob->runtime.mesh_eval == NULL &&
       (ob = eval_object_ensure(ob, C, reports, rnaptr_depsgraph)) == NULL) {
     return;
@@ -806,6 +818,11 @@ void RNA_api_object(StructRNA *srna)
   RNA_def_function_flag(func, FUNC_USE_REPORTS);
   parm = RNA_def_pointer(func, "viewport", "SpaceView3D", "", "Viewport in local view");
   RNA_def_parameter_flags(parm, 0, PARM_RNAPTR | PARM_REQUIRED);
+  parm = RNA_def_pointer(func,
+                         "view_layer",
+                         "ViewLayer",
+                         "",
+                         "Optional ViewLayer. Preferably passed for additional performance");
   parm = RNA_def_boolean(func, "result", 0, "", "Object local view state");
   RNA_def_function_return(func, parm);
 
index da30abb6e7a61a087dba3c69ad0f53be16c9f5b4..718b34e5570e3ccb664566c6bf47df304b3bfb6d 100644 (file)
@@ -988,11 +988,6 @@ static Scene *rna_3DViewShading_scene(PointerRNA *ptr)
 {
   /* Get scene, depends if using 3D view or OpenGL render settings. */
   ID *id = ptr->owner_id;
-  if (!id) {
-    /* When accessed from an external render engine the id.data is NULL
-     * This might be missing from the RNA CPP Api */
-    return NULL;
-  }
   if (GS(id->name) == ID_SCE) {
     return (Scene *)id;
   }