[Bf-blender-cvs] [66518ce11b1] sybren-usd: USD: Write edge creases to USD mesh
Sybren A. Stüvel
noreply at git.blender.org
Fri Jul 12 14:16:27 CEST 2019
Commit: 66518ce11b1889fcde1df829cfab3605c023a447
Author: Sybren A. Stüvel
Date: Fri Jul 12 12:21:01 2019 +0200
Branches: sybren-usd
https://developer.blender.org/rB66518ce11b1889fcde1df829cfab3605c023a447
USD: Write edge creases to USD mesh
Only the crease is written to USD. The "Sharp" edge flag doesn't seem to
be supported by USD, or at least I couldn't find it in the API docs.
===================================================================
M source/blender/usd/intern/usd_writer_mesh.cc
===================================================================
diff --git a/source/blender/usd/intern/usd_writer_mesh.cc b/source/blender/usd/intern/usd_writer_mesh.cc
index c6c7f51c7c9..7ce3102d864 100644
--- a/source/blender/usd/intern/usd_writer_mesh.cc
+++ b/source/blender/usd/intern/usd_writer_mesh.cc
@@ -56,6 +56,22 @@ struct USDMeshData {
pxr::VtIntArray face_vertex_counts;
pxr::VtIntArray face_indices;
std::map<short, pxr::VtIntArray> face_groups;
+
+ /* The length of this array specifies the number of creases on the surface. Each element gives
+ * the number of (must be adjacent) vertices in each crease, whose indices are linearly laid out
+ * in the 'creaseIndices' attribute. Since each crease must be at least one edge long, each
+ * element of this array should be greater than one. */
+ pxr::VtIntArray crease_lengths;
+ /* The indices of all vertices forming creased edges. The size of this array must be equal to the
+ * sum of all elements of the 'creaseLengths' attribute. */
+ pxr::VtIntArray crease_vertex_indices;
+ /* The per-crease or per-edge sharpness for all creases (Usd.Mesh.SHARPNESS_INFINITE for a
+ * perfectly sharp crease). Since 'creaseLengths' encodes the number of vertices in each crease,
+ * the number of elements in this array will be either len(creaseLengths) or the sum over all X
+ * of (creaseLengths[X] - 1). Note that while the RI spec allows each crease to have either a
+ * single sharpness or a value per-edge, USD will encode either a single sharpness per crease on
+ * a mesh, or sharpnesses for all edges making up the creases on a mesh. */
+ pxr::VtFloatArray crease_sharpnesses;
};
void USDGenericMeshWriter::write_mesh(HierarchyContext &context, Mesh *mesh)
@@ -75,6 +91,12 @@ void USDGenericMeshWriter::write_mesh(HierarchyContext &context, Mesh *mesh)
usd_mesh.CreateFaceVertexCountsAttr().Set(usd_mesh_data.face_vertex_counts, timecode);
usd_mesh.CreateFaceVertexIndicesAttr().Set(usd_mesh_data.face_indices, timecode);
+ if (!usd_mesh_data.crease_lengths.empty()) {
+ usd_mesh.CreateCreaseLengthsAttr().Set(usd_mesh_data.crease_lengths, timecode);
+ usd_mesh.CreateCreaseIndicesAttr().Set(usd_mesh_data.crease_vertex_indices, timecode);
+ usd_mesh.CreateCreaseSharpnessesAttr().Set(usd_mesh_data.crease_sharpnesses, timecode);
+ }
+
// TODO(Sybren): figure out what happens when the face groups change.
if (frame_has_been_written_) {
return;
@@ -83,23 +105,24 @@ void USDGenericMeshWriter::write_mesh(HierarchyContext &context, Mesh *mesh)
assign_materials(context, usd_mesh, usd_mesh_data.face_groups);
}
-void USDGenericMeshWriter::get_geometry_data(const Mesh *mesh, struct USDMeshData &usd_mesh_data)
+static void get_vertices(const Mesh *mesh, struct USDMeshData &usd_mesh_data)
{
- /* Only construct face groups (a.k.a. geometry subsets) when we need them for material
- * assignments. */
- bool construct_face_groups = mesh->totcol > 1;
-
usd_mesh_data.points.reserve(mesh->totvert);
- usd_mesh_data.face_vertex_counts.reserve(mesh->totpoly);
- usd_mesh_data.face_indices.reserve(mesh->totloop);
- // TODO(Sybren): there is probably a more C++-y way to do this, which avoids copying the entire
- // mesh to a different structure. I haven't seen the approach below in the USD exporters for
- // Maya/Houdini, but it's simple and it works for now.
const MVert *verts = mesh->mvert;
for (int i = 0; i < mesh->totvert; ++i) {
usd_mesh_data.points.push_back(pxr::GfVec3f(verts[i].co));
}
+}
+
+static void get_loops_polys(const Mesh *mesh, struct USDMeshData &usd_mesh_data)
+{
+ /* Only construct face groups (a.k.a. geometry subsets) when we need them for material
+ * assignments. */
+ bool construct_face_groups = mesh->totcol > 1;
+
+ usd_mesh_data.face_vertex_counts.reserve(mesh->totpoly);
+ usd_mesh_data.face_indices.reserve(mesh->totloop);
MLoop *mloop = mesh->mloop;
MPoly *mpoly = mesh->mpoly;
@@ -116,6 +139,38 @@ void USDGenericMeshWriter::get_geometry_data(const Mesh *mesh, struct USDMeshDat
}
}
+static void get_creases(const Mesh *mesh, struct USDMeshData &usd_mesh_data)
+{
+ const float factor = 1.0f / 255.0f;
+
+ MEdge *edge = mesh->medge;
+ float sharpness;
+ for (int edge_idx = 0, totedge = mesh->totedge; edge_idx < totedge; ++edge_idx, ++edge) {
+ if (edge->crease == 0) {
+ continue;
+ }
+
+ if (edge->crease == 255) {
+ sharpness = pxr::UsdGeomMesh::SHARPNESS_INFINITE;
+ }
+ else {
+ sharpness = static_cast<float>(edge->crease) * factor;
+ }
+
+ usd_mesh_data.crease_vertex_indices.push_back(edge->v1);
+ usd_mesh_data.crease_vertex_indices.push_back(edge->v2);
+ usd_mesh_data.crease_lengths.push_back(2);
+ usd_mesh_data.crease_sharpnesses.push_back(sharpness);
+ }
+}
+
+void USDGenericMeshWriter::get_geometry_data(const Mesh *mesh, struct USDMeshData &usd_mesh_data)
+{
+ get_vertices(mesh, usd_mesh_data);
+ get_loops_polys(mesh, usd_mesh_data);
+ get_creases(mesh, usd_mesh_data);
+}
+
void USDGenericMeshWriter::assign_materials(
const HierarchyContext &context,
pxr::UsdGeomMesh usd_mesh,
More information about the Bf-blender-cvs
mailing list