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:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2013-11-28 03:13:32 +0400
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2013-11-28 05:11:42 +0400
commit731ffd3cd4c1d578fb02d39dc512bace850c2e8b (patch)
tree63cced11229d028a2d8a7e5b6c9600e4e0fa6351 /intern/cycles/subd/subd_mesh.cpp
parentaf7a2a3b6a08bdbe99d295e593e770af165eb0e6 (diff)
Cycles: remove approximate subdivision surface with gregory patches code.
It was never fully implemented and will be replaced by OpenSubdiv. Only linear subdivision remains now. Also includes some refactoring in the split/dice code, adding a SubdParams struct to pass around parameters more easily.
Diffstat (limited to 'intern/cycles/subd/subd_mesh.cpp')
-rw-r--r--intern/cycles/subd/subd_mesh.cpp270
1 files changed, 66 insertions, 204 deletions
diff --git a/intern/cycles/subd/subd_mesh.cpp b/intern/cycles/subd/subd_mesh.cpp
index becd5b9b5ec..29e487cd5d9 100644
--- a/intern/cycles/subd/subd_mesh.cpp
+++ b/intern/cycles/subd/subd_mesh.cpp
@@ -28,37 +28,60 @@
#include <stdio.h>
-#include "subd_build.h"
-#include "subd_edge.h"
-#include "subd_face.h"
#include "subd_mesh.h"
#include "subd_patch.h"
#include "subd_split.h"
-#include "subd_vert.h"
#include "util_debug.h"
#include "util_foreach.h"
CCL_NAMESPACE_BEGIN
+/* Subd Vertex */
+
+class SubdVert
+{
+public:
+ int id;
+ float3 co;
+
+ SubdVert(int id_)
+ {
+ id = id_;
+ co = make_float3(0.0f, 0.0f, 0.0f);
+ }
+};
+
+/* Subd Face */
+
+class SubdFace
+{
+public:
+ int id;
+ int numverts;
+ int verts[4];
+
+ SubdFace(int id_)
+ {
+ id = id_;
+ numverts = 0;
+ }
+};
+
+/* Subd Mesh */
+
SubdMesh::SubdMesh()
{
}
SubdMesh::~SubdMesh()
{
- pair<Key, SubdEdge*> em;
-
foreach(SubdVert *vertex, verts)
delete vertex;
- foreach(em, edge_map)
- delete em.second;
foreach(SubdFace *face, faces)
delete face;
verts.clear();
- edges.clear();
- edge_map.clear();
faces.clear();
}
@@ -85,224 +108,63 @@ SubdFace *SubdMesh::add_face(int v0, int v1, int v2, int v3)
SubdFace *SubdMesh::add_face(int *index, int num)
{
- /* test non-manifold cases */
- if(!can_add_face(index, num)) {
- /* we could try to add face in opposite winding instead .. */
- fprintf(stderr, "Warning: non manifold mesh, invalid face '%lu'.\n", (unsigned long)faces.size());
+ /* skip ngons */
+ if(num < 3 || num > 4)
return NULL;
- }
-
- SubdFace *f = new SubdFace(faces.size());
-
- SubdEdge *first_edge = NULL;
- SubdEdge *last = NULL;
- SubdEdge *current = NULL;
-
- /* add edges */
- for(int i = 0; i < num-1; i++) {
- current = add_edge(index[i], index[i+1]);
- assert(current != NULL);
-
- current->face = f;
-
- if(last != NULL) {
- last->next = current;
- current->prev = last;
- }
- else
- first_edge = current;
-
- last = current;
- }
-
- current = add_edge(index[num-1], index[0]);
- assert(current != NULL);
-
- current->face = f;
- last->next = current;
- current->prev = last;
+ SubdFace *f = new SubdFace(faces.size());
- current->next = first_edge;
- first_edge->prev = current;
+ for(int i = 0; i < num; i++)
+ f->verts[i] = index[i];
- f->edge = first_edge;
+ f->numverts = num;
faces.push_back(f);
return f;
}
-bool SubdMesh::can_add_face(int *index, int num)
-{
- /* manifold check */
- for(int i = 0; i < num-1; i++)
- if(!can_add_edge(index[i], index[i+1]))
- return false;
-
- return can_add_edge(index[num-1], index[0]);
-}
-
-bool SubdMesh::can_add_edge(int i, int j)
-{
- /* check for degenerate edge */
- if(i == j)
- return false;
-
- /* make sure edge has not been added yet. */
- return find_edge(i, j) == NULL;
-}
-
-SubdEdge *SubdMesh::add_edge(int i, int j)
-{
- SubdEdge *edge;
-
- /* find pair */
- SubdEdge *pair = find_edge(j, i);
-
- if(pair != NULL) {
- /* create edge with same id */
- edge = new SubdEdge(pair->id + 1);
-
- /* link edge pairs */
- edge->pair = pair;
- pair->pair = edge;
-
- /* not sure this is necessary? */
- pair->vert->edge = pair;
- }
- else {
- /* create edge */
- edge = new SubdEdge(2*edges.size());
-
- /* add only unpaired edges */
- edges.push_back(edge);
- }
-
- /* assign vertex and put into map */
- edge->vert = verts[i];
- edge_map[Key(i, j)] = edge;
-
- /* face and next are set by add_face */
-
- return edge;
-}
-
-SubdEdge *SubdMesh::find_edge(int i, int j)
+bool SubdMesh::finish()
{
- map<Key, SubdEdge*>::const_iterator it = edge_map.find(Key(i, j));
-
- return (it == edge_map.end())? NULL: it->second;
-}
-
-bool SubdMesh::link_boundary()
-{
- /* link boundary edges once the mesh has been created */
- int num = 0;
-
- /* create boundary edges */
- int num_edges = edges.size();
-
- for(int e = 0; e < num_edges; e++) {
- SubdEdge *edge = edges[e];
-
- if(edge->pair == NULL) {
- SubdEdge *pair = new SubdEdge(edge->id + 1);
-
- int i = edge->from()->id;
- int j = edge->to()->id;
-
- assert(edge_map.find(Key(j, i)) == edge_map.end());
-
- pair->vert = verts[j];
- edge_map[Key(j, i)] = pair;
-
- edge->pair = pair;
- pair->pair = edge;
-
- num++;
- }
- }
-
- /* link boundary edges */
- for(int e = 0; e < num_edges; e++) {
- SubdEdge *edge = edges[e];
-
- if(edge->pair->face == NULL)
- link_boundary_edge(edge->pair);
- }
-
- /* detect boundary intersections */
- int boundaryIntersections = 0;
- int num_verts = verts.size();
-
- for(int v = 0; v < num_verts; v++) {
- SubdVert *vertex = verts[v];
-
- int boundarySubdEdges = 0;
- for(SubdVert::EdgeIterator it(vertex->edges()); !it.isDone(); it.advance())
- if(it.current()->is_boundary())
- boundarySubdEdges++;
-
- if(boundarySubdEdges > 2) {
- assert((boundarySubdEdges & 1) == 0);
- boundaryIntersections++;
- }
- }
-
- if(boundaryIntersections != 0) {
- fprintf(stderr, "Invalid mesh, boundary intersections found!\n");
- return false;
- }
-
return true;
}
-void SubdMesh::link_boundary_edge(SubdEdge *edge)
-{
- /* link this boundary edge. */
-
- /* make sure next pointer has not been set. */
- assert(edge->face == NULL);
- assert(edge->next == NULL);
-
- SubdEdge *next = edge;
-
- while(next->pair->face != NULL) {
- /* get pair prev */
- SubdEdge *e = next->pair->next;
-
- while(e->next != next->pair)
- e = e->next;
-
- next = e;
- }
-
- edge->next = next->pair;
- next->pair->prev = edge;
-
- /* adjust vertex edge, so that it's the boundary edge. (required for is_boundary()) */
- if(edge->vert->edge != edge)
- edge->vert->edge = edge;
-}
-
-void SubdMesh::tessellate(DiagSplit *split, bool linear, Mesh *mesh, int shader, bool smooth)
+void SubdMesh::tessellate(DiagSplit *split)
{
- SubdBuilder *builder = SubdBuilder::create(linear);
int num_faces = faces.size();
for(int f = 0; f < num_faces; f++) {
SubdFace *face = faces[f];
- Patch *patch = builder->run(face);
+ Patch *patch;
+ float3 *hull;
+
+ if(face->numverts == 3) {
+ LinearTrianglePatch *lpatch = new LinearTrianglePatch();
+ hull = lpatch->hull;
+ patch = lpatch;
+ }
+ else if(face->numverts == 4) {
+ LinearQuadPatch *lpatch = new LinearQuadPatch();
+ hull = lpatch->hull;
+ patch = lpatch;
+ }
+ else {
+ assert(0); /* n-gons should have been split already */
+ continue;
+ }
+
+ for(int i = 0; i < face->numverts; i++)
+ hull[i] = verts[face->verts[i]]->co;
+
+ if(face->numverts == 4)
+ swap(hull[2], hull[3]);
if(patch->is_triangle())
- split->split_triangle(mesh, patch, shader, smooth);
+ split->split_triangle(patch);
else
- split->split_quad(mesh, patch, shader, smooth);
+ split->split_quad(patch);
delete patch;
}
-
- delete builder;
}
CCL_NAMESPACE_END