Commit: bb22c6f3cf7e16e0be753e9b54299e7b6b05127a
Author: Sergey Sharybin
Date:   Tue Jul 14 18:44:08 2015 +0200
Branches: opensubdiv-modifier
https://developer.blender.org/rBbb22c6f3cf7e16e0be753e9b54299e7b6b05127a

OpenSubdiv: Implement topology refiner converter from Blender side

This way it's possible to avoid having bad level calls to DM code from
intern/opensubdiv and also makes it possible to create topology refiner
from CCGSubSurf structure in the future.

===================================================================

M       intern/opensubdiv/opensubdiv_capi.cc
M       intern/opensubdiv/opensubdiv_capi.h
M       intern/opensubdiv/opensubdiv_converter.cc
A       intern/opensubdiv/opensubdiv_converter_capi.h
M       intern/opensubdiv/opensubdiv_evaluator_capi.cc
M       source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c

===================================================================

diff --git a/intern/opensubdiv/opensubdiv_capi.cc 
b/intern/opensubdiv/opensubdiv_capi.cc
index 683dde4..0ecac20 100644
--- a/intern/opensubdiv/opensubdiv_capi.cc
+++ b/intern/opensubdiv/opensubdiv_capi.cc
@@ -210,14 +210,15 @@ static void get_partition_per_face(OsdHbrMesh &hmesh,
 }
 #endif
 
-struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromEvaluator(
-        //OpenSubdiv_EvaluatorDescr * /*evaluator_descr*/,
-        DerivedMesh *dm,
+struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromTopologyRefiner(
+        OpenSubdiv_TopologyRefinerDescr *topology_refiner,
         int evaluator_type,
         int level,
         int /*scheme*/,
         int /*subdivide_uvs*/)
 {
+       using OpenSubdiv::Far::TopologyRefiner;
+
        MeshBitset bits;
        /* TODO(sergey): Adaptive subdivisions are not currently
         * possible because of the lack of tessellation shader.
@@ -234,7 +235,7 @@ struct OpenSubdiv_GLMesh 
*openSubdiv_createOsdGLMeshFromEvaluator(
        const int num_varying_elements = 0;
 
        GLMeshInterface *mesh = NULL;
-       OpenSubdiv::Far::TopologyRefiner *refiner = 
openSubdiv_topologyRefinerFromDM(dm);
+       TopologyRefiner *refiner = (TopologyRefiner*)topology_refiner;
 
        switch(evaluator_type) {
 #define CHECK_EVALUATOR_TYPE(type, class) \
diff --git a/intern/opensubdiv/opensubdiv_capi.h 
b/intern/opensubdiv/opensubdiv_capi.h
index eb273c1..184c9d7 100644
--- a/intern/opensubdiv/opensubdiv_capi.h
+++ b/intern/opensubdiv/opensubdiv_capi.h
@@ -32,6 +32,7 @@ extern "C" {
 
 // Types declaration.
 struct OpenSubdiv_GLMesh;
+struct OpenSubdiv_TopologyRefinerDescr;
 
 typedef struct OpenSubdiv_GLMesh OpenSubdiv_GLMesh;
 
@@ -62,9 +63,8 @@ enum {
 };
 
 /* TODO(sergey): Re-name and avoid bad level data access. */
-struct DerivedMesh;
-OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromEvaluator(
-    DerivedMesh *dm,
+OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromTopologyRefiner(
+    struct OpenSubdiv_TopologyRefinerDescr *topology_refiner,
     int evaluator_type,
     int level,
     int scheme,
@@ -92,8 +92,9 @@ struct OpenSubdiv_EvaluatorDescr;
 typedef struct OpenSubdiv_EvaluatorDescr OpenSubdiv_EvaluatorDescr;
 
 /* TODO(sergey): Avoid bad-level data access, */
-OpenSubdiv_EvaluatorDescr *openSubdiv_createEvaluatorDescr(DerivedMesh *dm,
-                                                           int subsurf_level);
+OpenSubdiv_EvaluatorDescr *openSubdiv_createEvaluatorDescr(
+        struct OpenSubdiv_TopologyRefinerDescr *topology_refiner,
+        int subsurf_level);
 
 void openSubdiv_deleteEvaluatorDescr(OpenSubdiv_EvaluatorDescr 
*evaluator_descr);
 
diff --git a/intern/opensubdiv/opensubdiv_converter.cc 
b/intern/opensubdiv/opensubdiv_converter.cc
index b9d6760..6b60e2a 100644
--- a/intern/opensubdiv/opensubdiv_converter.cc
+++ b/intern/opensubdiv/opensubdiv_converter.cc
@@ -27,6 +27,7 @@
 
 #include <opensubdiv/far/topologyRefinerFactory.h>
 
+#include "opensubdiv_converter_capi.h"
 #include "opensubdiv_intern.h"
 
 extern "C" {
@@ -219,7 +220,176 @@ OpenSubdiv::Far::TopologyRefiner 
*openSubdiv_topologyRefinerFromDM(DerivedMesh *
        TopologyRefinerFactory<OsdBlenderConverter>::Options
                topology_options(conv.get_type(), conv.get_options());
 #ifdef OPENSUBDIV_VALIDATE_TOPOLOGY
-       topology_options.validateFullTopology = true;
+       topology_options.validateFullTopology = true;
 #endif
        return TopologyRefinerFactory<OsdBlenderConverter>::Create(conv, 
topology_options);
 }
+
+/* *********************************************************** */
+
+namespace OpenSubdiv {
+namespace OPENSUBDIV_VERSION {
+namespace Far {
+
+template <>
+inline bool 
TopologyRefinerFactory<OpenSubdiv_Converter>::resizeComponentTopology(
+        TopologyRefiner& refiner,
+        const OpenSubdiv_Converter& conv)
+{
+       /* Faces and face-verts */
+       const int num_faces = conv.get_num_faces(&conv);
+       setNumBaseFaces(refiner, num_faces);
+       for (int face = 0; face < num_faces; ++face) {
+               const int num_verts = conv.get_num_face_verts(&conv, face);
+               setNumBaseFaceVertices(refiner, face, num_verts);
+       }
+       /* Edges and edge-faces. */
+       const int num_edges = conv.get_num_edges(&conv);
+       setNumBaseEdges(refiner, num_edges);
+       for (int edge = 0; edge < num_edges; ++edge) {
+               const int num_edge_faces = conv.get_num_edge_faces(&conv, edge);
+               setNumBaseEdgeFaces(refiner, edge, num_edge_faces);
+       }
+       /* Vertices and vert-faces and vert-edges/ */
+       const int num_verts = conv.get_num_verts(&conv);
+       setNumBaseVertices(refiner, num_verts);
+       for (int vert = 0; vert < num_verts; ++vert) {
+               const int num_vert_edges = conv.get_num_vert_edges(&conv, vert),
+                         num_vert_faces = conv.get_num_vert_faces(&conv, vert);
+               setNumBaseVertexEdges(refiner, vert, num_vert_edges);
+               setNumBaseVertexFaces(refiner, vert, num_vert_faces);
+       }
+       return true;
+}
+
+template <>
+inline bool 
TopologyRefinerFactory<OpenSubdiv_Converter>::assignComponentTopology(
+         TopologyRefiner& refiner,
+        const OpenSubdiv_Converter& conv)
+{
+       using Far::IndexArray;
+       /* Face relations. */
+       const int num_faces = conv.get_num_faces(&conv);
+       for (int face = 0; face < num_faces; ++face) {
+               IndexArray dst_face_verts = getBaseFaceVertices(refiner, face);
+               conv.get_face_verts(&conv, face, &dst_face_verts[0]);
+               IndexArray dst_face_edges = getBaseFaceEdges(refiner, face);
+               conv.get_face_edges(&conv, face, &dst_face_edges[0]);
+       }
+       /* Edge relations. */
+       const int num_edges = conv.get_num_edges(&conv);
+       for (int edge = 0; edge < num_edges; ++edge) {
+               /* Edge-vertices */
+               IndexArray dst_edge_verts = getBaseEdgeVertices(refiner, edge);
+               conv.get_edge_verts(&conv, edge, &dst_edge_verts[0]);
+               /* Edge-faces */
+               IndexArray dst_edge_faces = getBaseEdgeFaces(refiner, edge);
+               conv.get_edge_faces(&conv, edge, &dst_edge_faces[0]);
+       }
+       /* Vertex relations */
+       const int num_verts = conv.get_num_verts(&conv);
+       for (int vert = 0; vert < num_verts; ++vert) {
+               /* Vert-Faces */
+               IndexArray dst_vert_faces = getBaseVertexFaces(refiner, vert);
+               int num_vert_edges = conv.get_num_vert_edges(&conv, vert);
+               int *vert_edges = new int[num_vert_edges];
+               conv.get_vert_edges(&conv, vert, vert_edges);
+               /* Vert-Edges */
+               IndexArray dst_vert_edges = getBaseVertexEdges(refiner, vert);
+               int num_vert_faces = conv.get_num_vert_faces(&conv, vert);
+               int *vert_faces = new int[num_vert_faces];
+               conv.get_vert_faces(&conv, vert, vert_faces);
+               /* Order vertex edges and faces in a CCW order. */
+               Index face_start = INDEX_INVALID;
+               Index edge_start = INDEX_INVALID;
+               int face_vert_start = 0;
+               if (num_vert_edges == num_vert_faces) {
+                       face_start  = vert_faces[0];
+                       face_vert_start = 
findInArray(getBaseFaceVertices(refiner, face_start), vert);
+                       edge_start = getBaseFaceEdges(refiner, 
face_start)[face_vert_start];
+               } else {
+                       for (int i = 0; i < num_vert_edges; ++i) {
+                               IndexArray edge_faces = 
getBaseEdgeFaces(refiner, vert_edges[i]);
+                               if (edge_faces.size() == 1) {
+                                       edge_start = vert_edges[i];
+                                       face_start = edge_faces[0];
+                                       face_vert_start = 
findInArray(getBaseFaceVertices(refiner, face_start), vert);
+                                       if (edge_start == 
(getBaseFaceEdges(refiner, face_start)[face_vert_start])) {
+                                               break;
+                                       }
+                               }
+                       }
+               }
+               int edge_count_ordered = 1;
+               int face_count_ordered = 1;
+               dst_vert_faces[0] = face_start;
+               dst_vert_edges[0] = edge_start;
+               while (edge_count_ordered < num_vert_edges) {
+                       IndexArray fVerts = getBaseFaceVertices(refiner, 
face_start);
+                       IndexArray fEdges = getBaseFaceEdges(refiner, 
face_start);
+                       int feStart = face_vert_start;
+                       int feNext = feStart ? (feStart - 1) : (fVerts.size() - 
1);
+                       Index eNext = fEdges[feNext];
+                       dst_vert_edges[edge_count_ordered++] = eNext;
+                       if (face_count_ordered < num_vert_faces) {
+                               IndexArray edge_faces = 
getBaseEdgeFaces(refiner, eNext);
+                               face_start = edge_faces[edge_faces[0] == 
face_start];
+                               face_vert_start = 
findInArray(getBaseFaceEdges(refiner, face_start), eNext);
+                               dst_vert_faces[face_count_ordered++] = 
face_start;
+                       }
+                       edge_start = eNext;
+               }
+
+               delete [] vert_edges;
+               delete [] vert_faces;
+       }
+       populateBaseLocalIndices(refiner);
+       return true;
+};
+
+template <>
+inline bool TopologyRefinerFactory<OpenSubdiv_Converter>::assignComponentTags(
+        TopologyRefiner& refiner,
+        const OpenSubdiv_Converter& conv)
+{
+       /* TODO(sergey): Use real sharpness. */
+       int num_edges = conv.get_num_edges(&conv);
+       for (int edge = 0; edge < num_edges; ++edge) {
+               setBaseEdgeSharpness(refiner, edge, 0.0f);
+       }
+       return true;
+}
+
+template <>
+inline void 
TopologyRefinerFactory<OpenSubdiv_Converter>::reportInvalidTopology(
+        TopologyError /*errCode*/,
+        const char *msg,
+        const OpenSubdiv_Converter& /*mesh*/)
+{
+       printf("OpenSubdiv Error: %s\n", msg);
+}
+
+}  /* namespace Far */
+}  /* namespace OPENSUBDIV_VERSION */
+}  /* namespace OpenSubdiv */
+
+
+struct OpenSubdiv_TopologyRefinerDescr *openSubdiv_createTopologyRefinerDescr(
+        OpenSubdiv_Converter *converter)
+{
+       using OpenSubdiv::Far::TopologyRefinerFactory;
+       OpenSubdiv::Sdc::SchemeType scheme_type = 
OpenSubdiv::Sdc::SCHEME_CATMARK;
+       OpenSubdiv::Sdc::Options options;
+       
options.SetVtxBoundaryInterpolation(OpenSubdiv::Sdc::Options::VTX_BOUNDARY_EDGE_ONLY);
+       
options.SetFVarLinearInterpolation(OpenSubdiv::Sdc::Options::FVAR_LINEAR_ALL);
+
+       TopologyRefinerFactory<OpenSubdiv_Converter>::Options
+               topology_options(scheme_type, options);
+#ifdef OPENSUBDIV_VALIDATE_TOPOLOGY
+       topology_options.validateFullTopology = true;
+#endif
+       return (struct OpenSubdiv_TopologyRefinerDescr*)
+               TopologyRefinerFactory<OpenSubdiv_Converter>::Create(
+                       *converter,
+                       topology_options);
+}
diff --git a/intern/opensubdiv/opensubdiv_converter_capi.h 
b/intern/opensubdiv/opensubdiv_converter_capi.h
new file mode 100644
index 0000000..cff1fff
--- /dev/null
+++ b/intern/opensubdiv/opensubdiv_converter_capi.h
@@ -0,0 +1,87 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to