Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/render/mesh_subdivision.cpp
| Show First 20 Lines • Show All 222 Lines • ▼ Show 20 Lines | void build_from_mesh(Mesh *mesh_) | ||||
| /* create patch map */ | /* create patch map */ | ||||
| patch_map = new Far::PatchMap(*patch_table); | patch_map = new Far::PatchMap(*patch_table); | ||||
| } | } | ||||
| void subdivide_attribute(Attribute &attr) | void subdivide_attribute(Attribute &attr) | ||||
| { | { | ||||
| Far::PrimvarRefiner primvar_refiner(*refiner); | Far::PrimvarRefiner primvar_refiner(*refiner); | ||||
| if (attr.element == ATTR_ELEMENT_VERTEX) { | if (attr.get_element() == ATTR_ELEMENT_VERTEX) { | ||||
| int num_refiner_verts = refiner->GetNumVerticesTotal(); | int num_refiner_verts = refiner->GetNumVerticesTotal(); | ||||
| int num_local_points = patch_table->GetNumLocalPoints(); | int num_local_points = patch_table->GetNumLocalPoints(); | ||||
| attr.resize(num_refiner_verts + num_local_points); | attr.resize(num_refiner_verts + num_local_points); | ||||
| attr.flags |= ATTR_FINAL_SIZE; | attr.get_flags() |= ATTR_FINAL_SIZE; | ||||
| char *src = attr.buffer.data(); | char *src = attr.get_buffer().data(); | ||||
| for (int i = 0; i < refiner->GetMaxLevel(); i++) { | for (int i = 0; i < refiner->GetMaxLevel(); i++) { | ||||
| char *dest = src + refiner->GetLevel(i).GetNumVertices() * attr.data_sizeof(); | char *dest = src + refiner->GetLevel(i).GetNumVertices() * attr.data_sizeof(); | ||||
| if (attr.same_storage(attr.type, TypeDesc::TypeFloat)) { | if (attr.same_storage(attr.get_type(), TypeDesc::TypeFloat)) { | ||||
| primvar_refiner.Interpolate(i + 1, (OsdValue<float> *)src, (OsdValue<float> *&)dest); | primvar_refiner.Interpolate(i + 1, (OsdValue<float> *)src, (OsdValue<float> *&)dest); | ||||
| } | } | ||||
| else if (attr.same_storage(attr.type, TypeFloat2)) { | else if (attr.same_storage(attr.get_type(), TypeFloat2)) { | ||||
| primvar_refiner.Interpolate(i + 1, (OsdValue<float2> *)src, (OsdValue<float2> *&)dest); | primvar_refiner.Interpolate(i + 1, (OsdValue<float2> *)src, (OsdValue<float2> *&)dest); | ||||
| } | } | ||||
| else { | else { | ||||
| primvar_refiner.Interpolate(i + 1, (OsdValue<float4> *)src, (OsdValue<float4> *&)dest); | primvar_refiner.Interpolate(i + 1, (OsdValue<float4> *)src, (OsdValue<float4> *&)dest); | ||||
| } | } | ||||
| src = dest; | src = dest; | ||||
| } | } | ||||
| if (num_local_points) { | if (num_local_points) { | ||||
| if (attr.same_storage(attr.type, TypeDesc::TypeFloat)) { | if (attr.same_storage(attr.get_type(), TypeDesc::TypeFloat)) { | ||||
| patch_table->ComputeLocalPointValues( | patch_table->ComputeLocalPointValues( | ||||
| (OsdValue<float> *)&attr.buffer[0], | (OsdValue<float> *)&attr.get_buffer()[0], | ||||
| (OsdValue<float> *)&attr.buffer[num_refiner_verts * attr.data_sizeof()]); | (OsdValue<float> *)&attr.get_buffer()[num_refiner_verts * attr.data_sizeof()]); | ||||
| } | } | ||||
| else if (attr.same_storage(attr.type, TypeFloat2)) { | else if (attr.same_storage(attr.get_type(), TypeFloat2)) { | ||||
| patch_table->ComputeLocalPointValues( | patch_table->ComputeLocalPointValues( | ||||
| (OsdValue<float2> *)&attr.buffer[0], | (OsdValue<float2> *)&attr.get_buffer()[0], | ||||
| (OsdValue<float2> *)&attr.buffer[num_refiner_verts * attr.data_sizeof()]); | (OsdValue<float2> *)&attr.get_buffer()[num_refiner_verts * attr.data_sizeof()]); | ||||
| } | } | ||||
| else { | else { | ||||
| patch_table->ComputeLocalPointValues( | patch_table->ComputeLocalPointValues( | ||||
| (OsdValue<float4> *)&attr.buffer[0], | (OsdValue<float4> *)&attr.get_buffer()[0], | ||||
| (OsdValue<float4> *)&attr.buffer[num_refiner_verts * attr.data_sizeof()]); | (OsdValue<float4> *)&attr.get_buffer()[num_refiner_verts * attr.data_sizeof()]); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else if (attr.element == ATTR_ELEMENT_CORNER || attr.element == ATTR_ELEMENT_CORNER_BYTE) { | else if (attr.get_element() == ATTR_ELEMENT_CORNER || | ||||
| attr.get_element() == ATTR_ELEMENT_CORNER_BYTE) { | |||||
| // TODO(mai): fvar interpolation | // TODO(mai): fvar interpolation | ||||
| } | } | ||||
| } | } | ||||
| int calculate_max_isolation() | int calculate_max_isolation() | ||||
| { | { | ||||
| /* loop over all edges to find longest in screen space */ | /* loop over all edges to find longest in screen space */ | ||||
| const Far::TopologyLevel &level = refiner->GetLevel(0); | const Far::TopologyLevel &level = refiner->GetLevel(0); | ||||
| ▲ Show 20 Lines • Show All 105 Lines • ▼ Show 20 Lines | |||||
| #endif | #endif | ||||
| { | { | ||||
| /* force linear subdivision if OpenSubdiv is unavailable to avoid | /* force linear subdivision if OpenSubdiv is unavailable to avoid | ||||
| * falling into catmull-clark code paths by accident | * falling into catmull-clark code paths by accident | ||||
| */ | */ | ||||
| subdivision_type = SUBDIVISION_LINEAR; | subdivision_type = SUBDIVISION_LINEAR; | ||||
| /* force disable attribute subdivision for same reason as above */ | /* force disable attribute subdivision for same reason as above */ | ||||
| foreach (Attribute &attr, subd_attributes.attributes) { | foreach (Attribute &attr, subd_attributes.get_attributes()) { | ||||
| attr.flags &= ~ATTR_SUBDIVIDED; | attr.get_flags() &= ~ATTR_SUBDIVIDED; | ||||
| } | } | ||||
| } | } | ||||
| int num_faces = get_num_subd_faces(); | int num_faces = get_num_subd_faces(); | ||||
| Attribute *attr_vN = subd_attributes.find(ATTR_STD_VERTEX_NORMAL); | Attribute *attr_vN = subd_attributes.find(ATTR_STD_VERTEX_NORMAL); | ||||
| float3 *vN = (attr_vN) ? attr_vN->data_float3() : NULL; | float3 *vN = (attr_vN) ? attr_vN->data_float3() : NULL; | ||||
| ▲ Show 20 Lines • Show All 131 Lines • ▼ Show 20 Lines | for (int f = 0; f < num_faces; f++) { | ||||
| } | } | ||||
| } | } | ||||
| /* split patches */ | /* split patches */ | ||||
| split->split_patches(linear_patches.data(), sizeof(LinearQuadPatch)); | split->split_patches(linear_patches.data(), sizeof(LinearQuadPatch)); | ||||
| } | } | ||||
| /* interpolate center points for attributes */ | /* interpolate center points for attributes */ | ||||
| foreach (Attribute &attr, subd_attributes.attributes) { | foreach (Attribute &attr, subd_attributes.get_attributes()) { | ||||
| #ifdef WITH_OPENSUBDIV | #ifdef WITH_OPENSUBDIV | ||||
| if (subdivision_type == SUBDIVISION_CATMULL_CLARK && attr.flags & ATTR_SUBDIVIDED) { | if (subdivision_type == SUBDIVISION_CATMULL_CLARK && attr.get_flags() & ATTR_SUBDIVIDED) { | ||||
| if (attr.element == ATTR_ELEMENT_CORNER || attr.element == ATTR_ELEMENT_CORNER_BYTE) { | if (attr.get_element() == ATTR_ELEMENT_CORNER || | ||||
| attr.get_element() == ATTR_ELEMENT_CORNER_BYTE) { | |||||
| /* keep subdivision for corner attributes disabled for now */ | /* keep subdivision for corner attributes disabled for now */ | ||||
| attr.flags &= ~ATTR_SUBDIVIDED; | attr.get_flags() &= ~ATTR_SUBDIVIDED; | ||||
| } | } | ||||
| else if (get_num_subd_faces()) { | else if (get_num_subd_faces()) { | ||||
| osd_data.subdivide_attribute(attr); | osd_data.subdivide_attribute(attr); | ||||
| need_packed_patch_table = true; | need_packed_patch_table = true; | ||||
| continue; | continue; | ||||
| } | } | ||||
| } | } | ||||
| #endif | #endif | ||||
| char *data = attr.data(); | char *data = attr.data(); | ||||
| size_t stride = attr.data_sizeof(); | size_t stride = attr.data_sizeof(); | ||||
| int ngons = 0; | int ngons = 0; | ||||
| switch (attr.element) { | switch (attr.get_element()) { | ||||
| case ATTR_ELEMENT_VERTEX: { | case ATTR_ELEMENT_VERTEX: { | ||||
| for (int f = 0; f < num_faces; f++) { | for (int f = 0; f < num_faces; f++) { | ||||
| SubdFace face = get_subd_face(f); | SubdFace face = get_subd_face(f); | ||||
| if (!face.is_quad()) { | if (!face.is_quad()) { | ||||
| char *center = data + (verts.size() - num_subd_verts + ngons) * stride; | char *center = data + (verts.size() - num_subd_verts + ngons) * stride; | ||||
| attr.zero_data(center); | attr.zero_data(center); | ||||
| ▲ Show 20 Lines • Show All 75 Lines • Show Last 20 Lines | |||||