Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2018-07-31 16:09:29 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2018-08-01 19:42:59 +0300
commit08e6bccdf4a2114847194fbe8adcb1fc83a1746f (patch)
tree757f36fc7cf376288e0301cdbd9bc9ad50824b1e /source/blender/blenkernel/intern/subdiv_eval.c
parent9e2f678ba25cb292257fc9949373917ec48a6d46 (diff)
Subsurf: Support subdivision of loose elements
Applies to vertices and edges. Biggest annoyance here is that OpenSubdiv's topology converter expects that there is no loose geometry, otherwise it is getting confused. For now solution is to create some sort of mapping from real Mesh vertex and edge index to a non-loose-index. Now the annoying part is that this is an extra step to calculate before we can compare topology, meaning FPS will not be as great as if we knew for sure that topology didn't change. Loose edges subdivision is different from what it used to be with old subdivision code, but probably nice feature now is that endpoints of loose edges are stay at the coarse vertex locations. This allows to have things like plane with hair strands, without need to duplicate edge vertices at endpoints. All this required some re-work of topology refiner creation, which is now only passing edges and vertices which are adjacent to face. This is how topology refiner is supposed to be used, and this is how its validator also works. Vertices which are adjacent to loose edges are marked as infinite sharp. This seems to be good-enough approximation for now. In the future we might tweaks things a bit and push such vertices in average direction of loose edges, to match old subdivision code closer.
Diffstat (limited to 'source/blender/blenkernel/intern/subdiv_eval.c')
-rw-r--r--source/blender/blenkernel/intern/subdiv_eval.c46
1 files changed, 40 insertions, 6 deletions
diff --git a/source/blender/blenkernel/intern/subdiv_eval.c b/source/blender/blenkernel/intern/subdiv_eval.c
index 4c2ed07cdfa..7c90a2a25cd 100644
--- a/source/blender/blenkernel/intern/subdiv_eval.c
+++ b/source/blender/blenkernel/intern/subdiv_eval.c
@@ -33,10 +33,13 @@
#include "DNA_meshdata_types.h"
#include "BLI_utildefines.h"
+#include "BLI_bitmap.h"
#include "BLI_math_vector.h"
#include "BKE_customdata.h"
+#include "MEM_guardedalloc.h"
+
#ifdef WITH_OPENSUBDIV
# include "opensubdiv_evaluator_capi.h"
# include "opensubdiv_topology_refiner_capi.h"
@@ -60,6 +63,42 @@ void BKE_subdiv_eval_begin(Subdiv *subdiv)
}
#ifdef WITH_OPENSUBDIV
+static void set_coarse_positions(Subdiv *subdiv, const Mesh *mesh)
+{
+ const MVert *mvert = mesh->mvert;
+ const MLoop *mloop = mesh->mloop;
+ const MPoly *mpoly = mesh->mpoly;
+ /* Mark vertices which needs new coordinates. */
+ /* TODO(sergey): This is annoying to calculate this on every update,
+ * maybe it's better to cache this mapping. Or make it possible to have
+ * OpenSubdiv's vertices match mesh ones?
+ */
+ BLI_bitmap *vertex_used_map =
+ BLI_BITMAP_NEW(mesh->totvert, "vert used map");
+ for (int poly_index = 0; poly_index < mesh->totpoly; poly_index++) {
+ const MPoly *poly = &mpoly[poly_index];
+ for (int corner = 0; corner < poly->totloop; corner++) {
+ const MLoop *loop = &mloop[poly->loopstart + corner];
+ BLI_BITMAP_ENABLE(vertex_used_map, loop->v);
+ }
+ }
+ for (int vertex_index = 0, manifold_veretx_index = 0;
+ vertex_index < mesh->totvert;
+ vertex_index++)
+ {
+ if (!BLI_BITMAP_TEST_BOOL(vertex_used_map, vertex_index)) {
+ continue;
+ }
+ const MVert *vertex = &mvert[vertex_index];
+ subdiv->evaluator->setCoarsePositions(
+ subdiv->evaluator,
+ vertex->co,
+ manifold_veretx_index, 1);
+ manifold_veretx_index++;
+ }
+ MEM_freeN(vertex_used_map);
+}
+
static void set_face_varying_data_from_uv(Subdiv *subdiv,
const MLoopUV *mloopuv,
const int layer_index)
@@ -94,12 +133,7 @@ void BKE_subdiv_eval_update_from_mesh(Subdiv *subdiv, const Mesh *mesh)
#ifdef WITH_OPENSUBDIV
BKE_subdiv_eval_begin(subdiv);
/* Set coordinates of base mesh vertices. */
- subdiv->evaluator->setCoarsePositionsFromBuffer(
- subdiv->evaluator,
- mesh->mvert,
- offsetof(MVert, co),
- sizeof(MVert),
- 0, mesh->totvert);
+ set_coarse_positions(subdiv, mesh);
/* Set face-varyign data to UV maps. */
const int num_uv_layers =
CustomData_number_of_layers(&mesh->ldata, CD_MLOOPUV);