[Bf-blender-cvs] [8449cfdca21] temp-lineart-contained: LineArt: Properly working threaded geometry loading.

YimingWu noreply at git.blender.org
Wed Mar 24 03:31:21 CET 2021


Commit: 8449cfdca214c1aa6d6e0f5c5ffa64d90c501a31
Author: YimingWu
Date:   Tue Mar 23 22:09:57 2021 +0800
Branches: temp-lineart-contained
https://developer.blender.org/rB8449cfdca214c1aa6d6e0f5c5ffa64d90c501a31

LineArt: Properly working threaded geometry loading.

===================================================================

M	source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
M	source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c

===================================================================

diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
index 30003d8ed5a..8edcbd6d2b3 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
+++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
@@ -351,9 +351,15 @@ typedef struct LineartRenderTaskInfo {
 
 } LineartRenderTaskInfo;
 
+struct BMesh;
+
 typedef struct LineartObjectInfo {
   struct LineartObjectInfo *next;
-  struct Object *ob;
+  struct Object *original_ob;
+  struct BMesh *original_bm;
+  double new_mvp[4][4];
+  double new_mv[4][4];
+  double normal[4][4];
   LineartElementLinkNode *v_reln;
   int override_usage;
   int global_i_offset;
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
index d216940d014..b5efe1659bf 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
@@ -1523,9 +1523,7 @@ static void lineart_triangle_adjacent_assign(LineartTriangle *rt,
   }
 }
 
-static void lineart_geometry_object_load(Depsgraph *dg,
-                                         LineartObjectInfo *obi,
-                                         LineartRenderBuffer *rb)
+static void lineart_geometry_object_load(LineartObjectInfo *obi, LineartRenderBuffer *rb)
 {
   BMesh *bm;
   BMVert *v;
@@ -1536,8 +1534,7 @@ static void lineart_geometry_object_load(Depsgraph *dg,
   LineartLineSegment *la_s;
   LineartTriangle *rt;
   LineartTriangleAdjacent *orta;
-  double new_mvp[4][4], new_mv[4][4], normal[4][4];
-  float imat[4][4];
+  double(*new_mvp)[4] = obi->new_mvp, (*new_mv)[4] = obi->new_mv, (*normal)[4] = obi->normal;
   LineartElementLinkNode *reln;
   LineartVert *orv;
   LineartEdge *o_la_e;
@@ -1545,252 +1542,200 @@ static void lineart_geometry_object_load(Depsgraph *dg,
   LineartTriangle *ort;
   Object *orig_ob;
   int CanFindFreestyle = 0;
-  Object *ob = obi->ob;
   int i;
   Mesh *use_mesh;
   float use_crease = 0;
 
-  int usage = obi->override_usage ? obi->override_usage : ob->lineart.usage;
+  int usage = obi->override_usage;
 
-#define LRT_MESH_FINISH \
-  BM_mesh_free(bm); \
-  if (ob->type != OB_MESH) { \
-    BKE_mesh_free(use_mesh); \
-    MEM_freeN(use_mesh); \
-  }
+  bm = obi->original_bm;
 
-  if (usage == OBJECT_LRT_EXCLUDE) {
-    return;
-  }
+  if (rb->remove_doubles) {
+    BMEditMesh *em = BKE_editmesh_create(bm, false);
+    BMOperator findop, weldop;
 
-  if (ob->type == OB_MESH || ob->type == OB_MBALL || ob->type == OB_CURVE || ob->type == OB_SURF ||
-      ob->type == OB_FONT) {
+    /* See bmesh_opdefines.c and bmesh_operators.c for op names and argument formatting. */
+    BMO_op_initf(bm, &findop, BMO_FLAG_DEFAULTS, "find_doubles verts=%av dist=%f", 0.0001);
 
-    if (ob->type == OB_MESH) {
-      use_mesh = ob->data;
-    }
-    else {
-      use_mesh = BKE_mesh_new_from_object(NULL, ob, false);
-    }
+    BMO_op_exec(bm, &findop);
 
-    /* In case we can not get any mesh geometry data from the object */
-    if (!use_mesh) {
-      return;
-    }
+    /* Weld the vertices. */
+    BMO_op_init(bm, &weldop, BMO_FLAG_DEFAULTS, "weld_verts");
+    BMO_slot_copy(&findop, slots_out, "targetmap.out", &weldop, slots_in, "targetmap");
+    BMO_op_exec(bm, &weldop);
 
-    /* First we need to prepare the matrix used for transforming this specific object.  */
-    mul_m4db_m4db_m4fl_uniq(new_mvp, rb->view_projection, ob->obmat);
-    mul_m4db_m4db_m4fl_uniq(new_mv, rb->view, ob->obmat);
+    BMO_op_finish(bm, &findop);
+    BMO_op_finish(bm, &weldop);
 
-    invert_m4_m4(imat, ob->obmat);
-    transpose_m4(imat);
-    copy_m4d_m4(normal, imat);
+    MEM_freeN(em);
+  }
 
-    if (use_mesh->edit_mesh) {
-      /* Do not use edit_mesh directly because we will modify it, so create a copy. */
-      bm = BM_mesh_copy(use_mesh->edit_mesh->bm);
-    }
-    else {
-      const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(((Mesh *)(use_mesh)));
-      bm = BM_mesh_create(&allocsize,
-                          &((struct BMeshCreateParams){
-                              .use_toolflags = true,
-                          }));
-      BM_mesh_bm_from_me(bm,
-                         use_mesh,
-                         &((struct BMeshFromMeshParams){
-                             .calc_face_normal = true,
-                         }));
-    }
+  BM_mesh_elem_hflag_disable_all(bm, BM_FACE | BM_EDGE, BM_ELEM_TAG, false);
+  BM_mesh_triangulate(
+      bm, MOD_TRIANGULATE_QUAD_FIXED, MOD_TRIANGULATE_NGON_BEAUTY, 4, false, NULL, NULL, NULL);
+  BM_mesh_normals_update(bm);
+  BM_mesh_elem_table_ensure(bm, BM_VERT | BM_EDGE | BM_FACE);
+  BM_mesh_elem_index_ensure(bm, BM_VERT | BM_EDGE | BM_FACE);
 
-    if (rb->remove_doubles) {
-      BMEditMesh *em = BKE_editmesh_create(bm, false);
-      BMOperator findop, weldop;
+  if (CustomData_has_layer(&bm->edata, CD_FREESTYLE_EDGE)) {
+    CanFindFreestyle = 1;
+  }
 
-      /* See bmesh_opdefines.c and bmesh_operators.c for op names and argument formatting. */
-      BMO_op_initf(bm, &findop, BMO_FLAG_DEFAULTS, "find_doubles verts=%av dist=%f", 0.0001);
+  /* Only allocate memory for verts and tris as we don't know how many lines we will generate
+   * yet. */
+  orv = lineart_mem_aquire_thread(&rb->render_data_pool, sizeof(LineartVert) * bm->totvert);
+  ort = lineart_mem_aquire_thread(&rb->render_data_pool, bm->totface * rb->triangle_size);
 
-      BMO_op_exec(bm, &findop);
+  orig_ob = obi->original_ob;
 
-      /* Weld the vertices. */
-      BMO_op_init(bm, &weldop, BMO_FLAG_DEFAULTS, "weld_verts");
-      BMO_slot_copy(&findop, slots_out, "targetmap.out", &weldop, slots_in, "targetmap");
-      BMO_op_exec(bm, &weldop);
+  BLI_spin_lock(&rb->lock_task);
+  reln = lineart_list_append_pointer_pool_sized(
+      &rb->vertex_buffer_pointers, &rb->render_data_pool, orv, sizeof(LineartElementLinkNode));
+  BLI_spin_unlock(&rb->lock_task);
 
-      BMO_op_finish(bm, &findop);
-      BMO_op_finish(bm, &weldop);
+  reln->element_count = bm->totvert;
+  reln->object_ref = orig_ob;
+  obi->v_reln = reln;
 
-      MEM_freeN(em);
-    }
+  if (orig_ob->lineart.flags & OBJECT_LRT_OWN_CREASE) {
+    use_crease = cosf(M_PI - orig_ob->lineart.crease_threshold);
+  }
+  else {
+    use_crease = rb->crease_threshold;
+  }
 
-    BM_mesh_elem_hflag_disable_all(bm, BM_FACE | BM_EDGE, BM_ELEM_TAG, false);
-    BM_mesh_triangulate(
-        bm, MOD_TRIANGULATE_QUAD_FIXED, MOD_TRIANGULATE_NGON_BEAUTY, 4, false, NULL, NULL, NULL);
-    BM_mesh_normals_update(bm);
-    BM_mesh_elem_table_ensure(bm, BM_VERT | BM_EDGE | BM_FACE);
-    BM_mesh_elem_index_ensure(bm, BM_VERT | BM_EDGE | BM_FACE);
+  /* FIXME(Yiming): Hack for getting clean 3D text, the seam that extruded text object creates
+   * erroneous detection on creases. Future configuration should allow options. */
+  if (orig_ob->type == OB_FONT) {
+    reln->flags |= LRT_ELEMENT_BORDER_ONLY;
+  }
 
-    if (CustomData_has_layer(&bm->edata, CD_FREESTYLE_EDGE)) {
-      CanFindFreestyle = 1;
-    }
+  BLI_spin_lock(&rb->lock_task);
+  reln = lineart_list_append_pointer_pool_sized(
+      &rb->triangle_buffer_pointers, &rb->render_data_pool, ort, sizeof(LineartElementLinkNode));
+  BLI_spin_unlock(&rb->lock_task);
+  reln->element_count = bm->totface;
+  reln->object_ref = orig_ob;
+  reln->flags |= (usage == OBJECT_LRT_NO_INTERSECTION ? LRT_ELEMENT_NO_INTERSECTION : 0);
+
+  /* Note this memory is not from pool, will be deleted after culling. */
+  orta = MEM_callocN(sizeof(LineartTriangleAdjacent) * bm->totface, "LineartTriangleAdjacent");
+  /* Link is minimal so we use pool anyway. */
+  lineart_list_append_pointer_pool(&rb->triangle_adjacent_pointers, &rb->render_data_pool, orta);
+
+  for (i = 0; i < bm->totvert; i++) {
+    v = BM_vert_at_index(bm, i);
+    lineart_vert_transform(v, i, orv, new_mv, new_mvp);
+    orv[i].index = i;
+  }
+  /* Register a global index increment. See #lineart_triangle_share_edge() and
+   * #lineart_main_load_geometries() for detailed. It's okay that global_vindex might eventually
+   * overflow, in such large scene it's virtually impossible for two vertex of the same numeric
+   * index to come close together. */
+  obi->global_i_offset = bm->totvert;
 
-    /* Only allocate memory for verts and tris as we don't know how many lines we will generate
-     * yet. */
-    orv = lineart_mem_aquire_thread(&rb->render_data_pool, sizeof(LineartVert) * bm->totvert);
-    ort = lineart_mem_aquire_thread(&rb->render_data_pool, bm->totface * rb->triangle_size);
+  rt = ort;
+  for (i = 0; i < bm->totface; i++) {
+    f = BM_face_at_index(bm, i);
 
-    orig_ob = ob->id.orig_id ? (Object *)ob->id.orig_id : ob;
+    loop = f->l_first;
+    rt->v[0] = &orv[BM_elem_index_get(loop->v)];
+    loop = loop->next;
+    rt->v[1] = &orv[BM_elem_index_get(loop->v)];
+    loop = loop->next;
+    rt->v[2] = &orv[BM_elem_index_get(loop->v)];
 
-    BLI_spin_lock(&rb->lock_task);
-    reln = lineart_list_append_pointer_pool_sized(
-        &rb->vertex_buffer_pointers, &rb->render_data_pool, orv, sizeof(LineartElementLinkNode));
-    BLI_spin_unlock(&rb->lock_task);
+    /* Transparency bit assignment. */
+    Material *mat = BKE_object_material_get(orig_ob, f->mat_nr + 1);
+    rt->transparency_mask = ((mat && (mat->lineart.flags & LRT_MATERIAL_TRANSPARENCY_ENABLED)) ?
+                                 mat->lineart.transparency_mask :
+                                 0);
 
-    reln->element_count = bm->totvert;
-    reln->object_ref = orig_ob;
-    obi->v_reln = reln;
+    double gn[3];
+    copy_v3db_v3fl(gn, f->no);
+    mul_v3_mat3_m4v3_db(rt->gn, normal, gn);
+    normalize_v3_db(rt->gn);
 
-    if (ob->lineart.flags & OBJECT_LRT_OWN_CREASE) {
-      use_crease = cosf(M_PI - ob->lineart.crease_threshold);
+    if (usage == OBJECT_LRT_INTERSECTION_ONLY) {
+      rt->flags |= LRT_TRIANGLE_INTERSECTION_ONLY;
+    }
+    else if (usage == OBJECT_LRT_NO_INTERSECTION || usage == OBJECT_LRT_OCCLUSION_ONLY) {
+      rt->flags |= LRT_TRIANGLE_NO_INTERSECTION;
     }
-    else {
-      use_crease = rb->cr

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list