[Bf-blender-cvs] [e477676] temp-cycles-microdisplacement: Subdivide flagged attributes
Mai Lavelle
noreply at git.blender.org
Sun Jul 10 05:31:25 CEST 2016
Commit: e4776760f5f17f5a17224f7fae7b9ea6b87ab78c
Author: Mai Lavelle
Date: Mon Jul 4 01:57:25 2016 -0400
Branches: temp-cycles-microdisplacement
https://developer.blender.org/rBe4776760f5f17f5a17224f7fae7b9ea6b87ab78c
Subdivide flagged attributes
Attribute data is now subdivided when requested, tho the subdivided data is
not accessed yet.
===================================================================
M intern/cycles/render/mesh_subdivision.cpp
===================================================================
diff --git a/intern/cycles/render/mesh_subdivision.cpp b/intern/cycles/render/mesh_subdivision.cpp
index 180d7bd..7ef51b3 100644
--- a/intern/cycles/render/mesh_subdivision.cpp
+++ b/intern/cycles/render/mesh_subdivision.cpp
@@ -108,25 +108,34 @@ using namespace OpenSubdiv;
/* struct that implements OpenSubdiv's vertex interface */
-struct OsdVertex {
- float3 v;
+template<typename T>
+struct OsdValue {
+ T value;
- OsdVertex() {}
+ OsdValue() {}
void Clear(void* = 0) {
- v = make_float3(0.0f, 0.0f, 0.0f);
+ memset(&value, 0, sizeof(T));
}
- void AddWithWeight(OsdVertex const& src, float weight) {
- v += src.v * weight;
+ void AddWithWeight(OsdValue<T> const& src, float weight) {
+ value += src.value * weight;
}
};
+template<>
+void OsdValue<uchar4>::AddWithWeight(OsdValue<uchar4> const& src, float weight)
+{
+ for(int i = 0; i < 4; i++) {
+ value[i] += (uchar)(src.value[i] * weight);
+ }
+}
+
/* class for holding OpenSubdiv data used during tessellation */
class OsdData {
Mesh* mesh;
- vector<OsdVertex> verts;
+ vector<OsdValue<float3> > verts;
Far::TopologyRefiner* refiner;
Far::PatchTable* patch_table;
Far::PatchMap* patch_map;
@@ -171,12 +180,12 @@ public:
verts.resize(num_refiner_verts + num_local_points);
for(int i = 0; i < mesh->verts.size(); i++) {
- verts[i].v = mesh->verts[i];
+ verts[i].value = mesh->verts[i];
}
- OsdVertex* src = &verts[0];
+ OsdValue<float3>* src = &verts[0];
for(int i = 0; i < refiner->GetMaxLevel(); i++) {
- OsdVertex* dest = src + refiner->GetLevel(i).GetNumVertices();
+ OsdValue<float3>* dest = src + refiner->GetLevel(i).GetNumVertices();
Far::PrimvarRefiner(*refiner).Interpolate(i+1, src, dest);
src = dest;
}
@@ -187,6 +196,46 @@ public:
patch_map = new Far::PatchMap(*patch_table);
}
+ void subdivide_attribute(Attribute& attr)
+ {
+ Far::PrimvarRefiner primvar_refiner(*refiner);
+
+ if(attr.element == ATTR_ELEMENT_VERTEX) {
+ int num_refiner_verts = refiner->GetNumVerticesTotal();
+ int num_local_points = patch_table->GetNumLocalPoints();
+
+ attr.resize(num_refiner_verts + num_local_points);
+ attr.flags |= ATTR_FINAL_SIZE;
+
+ char* src = &attr.buffer[0];
+
+ for(int i = 0; i < refiner->GetMaxLevel(); i++) {
+ char* dest = src + refiner->GetLevel(i).GetNumVertices() * attr.data_sizeof();
+
+ if(attr.same_storage(attr.type, TypeDesc::TypeFloat)) {
+ primvar_refiner.Interpolate(i+1, (OsdValue<float>*)src, (OsdValue<float>*&)dest);
+ }
+ else {
+ primvar_refiner.Interpolate(i+1, (OsdValue<float4>*)src, (OsdValue<float4>*&)dest);
+ }
+
+ src = dest;
+ }
+
+ if(attr.same_storage(attr.type, TypeDesc::TypeFloat)) {
+ patch_table->ComputeLocalPointValues((OsdValue<float>*)&attr.buffer[0],
+ (OsdValue<float>*)&attr.buffer[num_refiner_verts * attr.data_sizeof()]);
+ }
+ else {
+ patch_table->ComputeLocalPointValues((OsdValue<float4>*)&attr.buffer[0],
+ (OsdValue<float4>*)&attr.buffer[num_refiner_verts * attr.data_sizeof()]);
+ }
+ }
+ else if(attr.element == ATTR_ELEMENT_CORNER || attr.element == ATTR_ELEMENT_CORNER_BYTE) {
+ // TODO(mai): fvar interpolation
+ }
+ }
+
friend struct OsdPatch;
};
@@ -213,7 +262,7 @@ struct OsdPatch : Patch {
dv = make_float3(0.0f, 0.0f, 0.0f);
for(int i = 0; i < cv.size(); i++) {
- float3 p = osd_data->verts[cv[i]].v;
+ float3 p = osd_data->verts[cv[i]].value;
if(P) *P += p * p_weights[i];
du += p * du_weights[i];
@@ -381,6 +430,20 @@ void Mesh::tessellate(DiagSplit *split)
/* interpolate center points for attributes */
foreach(Attribute& attr, subd_attributes.attributes) {
+#ifdef WITH_OPENSUBDIV
+ if(subdivision_type == SUBDIVISION_CATMULL_CLARK && attr.flags & ATTR_SUBDIVIDED) {
+ if(attr.element == ATTR_ELEMENT_CORNER || attr.element == ATTR_ELEMENT_CORNER_BYTE) {
+ /* keep subdivision for corner attributes disabled for now */
+ attr.flags &= ~ATTR_SUBDIVIDED;
+ }
+ else {
+ osd_data.subdivide_attribute(attr);
+
+ continue;
+ }
+ }
+#endif
+
char* data = attr.data();
size_t stride = attr.data_sizeof();
int ngons = 0;
More information about the Bf-blender-cvs
mailing list