diff --git a/opensubdiv/far/gregoryBasis.cpp b/opensubdiv/far/gregoryBasis.cpp index 15f1cb59..64849a42 100644 --- a/opensubdiv/far/gregoryBasis.cpp +++ b/opensubdiv/far/gregoryBasis.cpp @@ -237,7 +237,19 @@ GregoryBasis::ProtoBasis::ProtoBasis( // results as the Ep and Em can be computed more directly from the limit // masks for the tangent vectors. // - if (! cornerBoundary[corner]) { + if (cornerSpans[corner]._sharp) { + P[corner].Clear(stencilCapacity); + P[corner].AddWithWeight(vCorner, 1.0f); + + // Approximating these for now, pending future investigation... + e0[corner].Clear(stencilCapacity); + e0[corner].AddWithWeight(facePoints[corner], 2.0f / 3.0f); + e0[corner].AddWithWeight(facePoints[(corner+1)%4], 1.0f / 3.0f); + + e1[corner].Clear(stencilCapacity); + e1[corner].AddWithWeight(facePoints[corner], 2.0f / 3.0f); + e1[corner].AddWithWeight(facePoints[(corner+3)%4], 1.0f / 3.0f); + } else if (! cornerBoundary[corner]) { float theta = cornerFaceAngle[corner]; float posScale = 1.0f / float(cornerValence); float tanScale = computeCoefficient(cornerValence); @@ -331,7 +343,10 @@ GregoryBasis::ProtoBasis::ProtoBasis( float faceAngleNext = faceAngle * float(iEdgeNext); float faceAnglePrev = faceAngle * float(iEdgePrev); - if (! cornerBoundary[corner]) { + if (cornerSpans[corner]._sharp) { + Ep[corner] = e0[corner]; + Em[corner] = e1[corner]; + } else if (! cornerBoundary[corner]) { Ep[corner] = P[corner]; Ep[corner].AddWithWeight(e0[corner], cosf(faceAngleNext)); Ep[corner].AddWithWeight(e1[corner], sinf(faceAngleNext)); diff --git a/opensubdiv/far/patchTableFactory.cpp b/opensubdiv/far/patchTableFactory.cpp index d74cd785..9ca5dde0 100644 --- a/opensubdiv/far/patchTableFactory.cpp +++ b/opensubdiv/far/patchTableFactory.cpp @@ -313,7 +313,6 @@ public: // Additional options eventually to be made public in Options above: bool options_approxSmoothCornerWithSharp; - bool options_useInfinitelySharpPatches; PtexIndices const ptexIndices; @@ -342,7 +341,6 @@ PatchTableFactory::BuilderContext::BuilderContext( // Eventually to be passed in as Options and assigned to member... options_approxSmoothCornerWithSharp = true; - options_useInfinitelySharpPatches = false; if (options.generateFVarTables) { // If client-code does not select specific channels, default to all @@ -564,12 +562,14 @@ PatchTableFactory::BuilderContext::IsPatchRegular( // bool isRegular = ! fCompVTag._xordinary || fCompVTag._nonManifold; + + // Reconsider when using inf-sharp patches in presence of inf-sharp features: - if (options_useInfinitelySharpPatches && fCompVTag._infSharpEdges) { - if (fCompVTag._nonManifold) { - isRegular = true; - } else if (!fCompVTag._infIrregular) { + if (options.useInfSharpPatch && (fCompVTag._infSharp || fCompVTag._infSharpEdges)) { + if (fCompVTag._nonManifold || !fCompVTag._infIrregular) { isRegular = true; + } else if (!fCompVTag._infSharpEdges) { + isRegular = false; } else { // // This is unfortunately a relatively complex case to determine... if a corner @@ -650,7 +650,7 @@ PatchTableFactory::BuilderContext::GetRegularPatchBoundaryMask( // int vBoundaryMask = 0; if (fTag._infSharpEdges) { - if (options_useInfinitelySharpPatches) { + if (options.useInfSharpPatch) { vBoundaryMask |= (vTags[0]._infSharpEdges << 0) | (vTags[1]._infSharpEdges << 1) | (vTags[2]._infSharpEdges << 2) | @@ -716,11 +716,11 @@ PatchTableFactory::BuilderContext::GetIrregularPatchCornerSpans( // ConstIndexArray fVerts = level.getFaceVertices(faceIndex); - Level::ETag singularEdgeMask = getSingularEdgeMask(options_useInfinitelySharpPatches); + Level::ETag singularEdgeMask = getSingularEdgeMask(options.useInfSharpPatch); for (int i = 0; i < fVerts.size(); ++i) { bool noFVarMisMatch = (fvcRefiner < 0) || !fvarTags[i]._mismatch; - bool testInfSharp = options_useInfinitelySharpPatches && + bool testInfSharp = options.useInfSharpPatch && (vTags[i]._infSharpEdges && (vTags[i]._rule != Sdc::Crease::RULE_DART)); if (noFVarMisMatch && !testInfSharp) { @@ -733,7 +733,9 @@ PatchTableFactory::BuilderContext::GetIrregularPatchCornerSpans( identifyNonManifoldCornerSpan( level, faceIndex, i, singularEdgeMask, cornerSpans[i], fvcRefiner); } - cornerSpans[i]._sharp = testInfSharp && (vTags[i]._rule == Sdc::Crease::RULE_CORNER); + } + if (options.useInfSharpPatch) { + cornerSpans[i]._sharp = vTags[i]._infIrregular && (vTags[i]._rule == Sdc::Crease::RULE_CORNER); } } } @@ -1386,7 +1388,7 @@ PatchTableFactory::populateAdaptivePatches( // Leaving the corner span "size" to zero, as constructed, indicates to use the full // neighborhood -- we only need to identify a subset when using inf-sharp patches - if (context.options_useInfinitelySharpPatches) { + if (context.options.useInfSharpPatch) { context.GetIrregularPatchCornerSpans( patch.levelIndex, patch.faceIndex, irregCornerSpans); } diff --git a/opensubdiv/far/patchTableFactory.h b/opensubdiv/far/patchTableFactory.h index b6fd9f4c..821535c2 100644 --- a/opensubdiv/far/patchTableFactory.h +++ b/opensubdiv/far/patchTableFactory.h @@ -57,6 +57,7 @@ public: generateAllLevels(false), triangulateQuads(false), useSingleCreasePatch(false), + useInfSharpPatch(false), maxIsolationLevel(maxIsolation), endCapType(ENDCAP_GREGORY_BASIS), shareEndCapPatchPoints(true), @@ -75,6 +76,7 @@ public: unsigned int generateAllLevels : 1, ///< Include levels from 'firstLevel' to 'maxLevel' (Uniform mode only) triangulateQuads : 1, ///< Triangulate 'QUADS' primitives (Uniform mode only) useSingleCreasePatch : 1, ///< Use single crease patch + useInfSharpPatch : 1, ///< Use infinitely-sharp patch maxIsolationLevel : 4, ///< Cap adaptive feature isolation to the given level (max. 10) // end-capping