[Bf-blender-cvs] [bb22c6f] opensubdiv-modifier: OpenSubdiv: Implement topology refiner converter from Blender side
Sergey Sharybin
noreply at git.blender.org
Tue Jul 14 18:54:28 CEST 2015
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. @@
More information about the Bf-blender-cvs
mailing list