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>2017-02-13 14:00:10 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2017-02-13 14:00:10 +0300
commit37afa965a4a1cb8053d449f72cb533a441279af2 (patch)
treea179bb9fe1c06ffa6b7af1de9f081b45acb186ca /intern/cycles/blender
parent594015fb7e00ce48dee0412f581b0283ff57b46b (diff)
Fix T50655: Pointiness is too slow to calculate
Optimize vertex de-duplication the same way as we do doe Remove Doubles.
Diffstat (limited to 'intern/cycles/blender')
-rw-r--r--intern/cycles/blender/blender_mesh.cpp76
1 files changed, 63 insertions, 13 deletions
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index a87f1724e81..e269be61791 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -27,6 +27,7 @@
#include "subd_patch.h"
#include "subd_split.h"
+#include "util_algorithm.h"
#include "util_foreach.h"
#include "util_logging.h"
#include "util_math.h"
@@ -525,6 +526,31 @@ static void attr_create_uv_map(Scene *scene,
}
/* Create vertex pointiness attributes. */
+
+/* Compare vertices by sum of their coordinates. */
+class VertexAverageComparator {
+public:
+ VertexAverageComparator(const array<float3>& verts)
+ : verts_(verts) {
+ }
+
+ bool operator()(const int& vert_idx_a, const int& vert_idx_b)
+ {
+ const float3 &vert_a = verts_[vert_idx_a];
+ const float3 &vert_b = verts_[vert_idx_b];
+ if(vert_a == vert_b) {
+ /* Special case for doubles, so we ensure ordering. */
+ return vert_idx_a > vert_idx_b;
+ }
+ const float x1 = vert_a.x + vert_a.y + vert_a.z;
+ const float x2 = vert_b.x + vert_b.y + vert_b.z;
+ return x1 < x2;
+ }
+
+protected:
+ const array<float3>& verts_;
+};
+
static void attr_create_pointiness(Scene *scene,
Mesh *mesh,
BL::Mesh& b_mesh,
@@ -534,37 +560,59 @@ static void attr_create_pointiness(Scene *scene,
return;
}
const int num_verts = b_mesh.vertices.length();
- AttributeSet& attributes = (subdivision)? mesh->subd_attributes: mesh->attributes;
- Attribute *attr = attributes.add(ATTR_STD_POINTINESS);
- float *data = attr->data_float();
/* STEP 1: Find out duplicated vertices and point duplicates to a single
* original vertex.
*/
+ vector<int> sorted_vert_indeices(num_verts);
+ for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
+ sorted_vert_indeices[vert_index] = vert_index;
+ }
+ VertexAverageComparator compare(mesh->verts);
+ sort(sorted_vert_indeices.begin(), sorted_vert_indeices.end(), compare);
/* This array stores index of the original vertex for the given vertex
* index.
*/
vector<int> vert_orig_index(num_verts);
- for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
+ for (int sorted_vert_index = 0;
+ sorted_vert_index < num_verts;
+ ++sorted_vert_index)
+ {
+ const int vert_index = sorted_vert_indeices[sorted_vert_index];
const float3 &vert_co = mesh->verts[vert_index];
bool found = false;
- int other_vert_index;
- for(other_vert_index = 0;
- other_vert_index < vert_index;
- ++other_vert_index)
+ for(int other_sorted_vert_index = sorted_vert_index + 1;
+ other_sorted_vert_index < num_verts;
+ ++other_sorted_vert_index)
{
+ const int other_vert_index =
+ sorted_vert_indeices[other_sorted_vert_index];
const float3 &other_vert_co = mesh->verts[other_vert_index];
+ /* We are too far away now, we wouldn't have duplicate. */
+ if ((other_vert_co.x + other_vert_co.y + other_vert_co.z) -
+ (vert_co.x + vert_co.y + vert_co.z) > 0.0f)
+ {
+ break;
+ }
+ /* Found duplicate. */
if(other_vert_co == vert_co) {
found = true;
+ vert_orig_index[vert_index] = other_vert_index;
break;
}
}
- if(found) {
- vert_orig_index[vert_index] = other_vert_index;
- }
- else {
+ if(!found) {
vert_orig_index[vert_index] = vert_index;
}
}
+ /* Make sure we always points to the very first orig vertex. */
+ for(int vert_index = 0; vert_index < num_verts; ++vert_index) {
+ int orig_index = vert_orig_index[vert_index];
+ while(orig_index != vert_orig_index[orig_index]) {
+ orig_index = vert_orig_index[orig_index];
+ }
+ vert_orig_index[vert_index] = orig_index;
+ }
+ sorted_vert_indeices.free_memory();
/* STEP 2: Calculate vertex normals taking into account their possible
* duplicates which gets "welded" together.
*/
@@ -623,6 +671,9 @@ static void attr_create_pointiness(Scene *scene,
}
}
/* STEP 3: Blur vertices to approximate 2 ring neighborhood. */
+ AttributeSet& attributes = (subdivision)? mesh->subd_attributes: mesh->attributes;
+ Attribute *attr = attributes.add(ATTR_STD_POINTINESS);
+ float *data = attr->data_float();
memcpy(data, &raw_data[0], sizeof(float) * raw_data.size());
memset(&counter[0], 0, sizeof(int) * counter.size());
edge_index = 0;
@@ -1234,4 +1285,3 @@ void BlenderSync::sync_mesh_motion(BL::Object& b_ob,
}
CCL_NAMESPACE_END
-