From 9e4f9977e0e50f38293436d753279d17c1815c2d Mon Sep 17 00:00:00 2001 From: Tyler Fox Date: Fri, 16 Aug 2024 17:03:38 -0700 Subject: [PATCH] Add the closed attribute --- src/twistMultiTangentNode.cpp | 55 ++++++++++++++++++++++++++++------- src/twistMultiTangentNode.h | 1 + 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/src/twistMultiTangentNode.cpp b/src/twistMultiTangentNode.cpp index 933e495..ca94d1a 100644 --- a/src/twistMultiTangentNode.cpp +++ b/src/twistMultiTangentNode.cpp @@ -69,6 +69,7 @@ MObject TwistMultiTangentNode::aVertData; MObject TwistMultiTangentNode::aStartTension; MObject TwistMultiTangentNode::aEndTension; MObject TwistMultiTangentNode::aMaxVertices; +MObject TwistMultiTangentNode::aClosed; // outputs MObject TwistMultiTangentNode::aInTanX; @@ -203,9 +204,14 @@ MStatus TwistMultiTangentNode::initialize() num_attr.setKeyable(true); num_attr.setStorable(true); num_attr.setMin(2); - addAttribute(aMaxVertices); + aClosed = num_attr.create("closed", "cl", MFnNumericData::kBoolean, false, &status); + num_attr.setKeyable(true); + num_attr.setStorable(true); + num_attr.setMin(2); + addAttribute(aClosed); + aInTanX = unit_attr.create("inVertTanX", "ivx", MFnUnitAttribute::kDistance, 0.0, &status); unit_attr.setKeyable(false); @@ -305,6 +311,7 @@ MStatus TwistMultiTangentNode::initialize() ins.push_back(&aStartTension); ins.push_back(&aEndTension); ins.push_back(&aMaxVertices); + ins.push_back(&aClosed); ins.push_back(&aVertMat); ins.push_back(&aInParentInv); ins.push_back(&aOutParentInv); @@ -435,7 +442,7 @@ buildVertMatTangent(double nextLegLen, double preLegLen, MVector &nextLegNrm, MV return ((bin ^ preLegNrm) + (bin ^ nextLegNrm)).normal(); } -void buildSmoothMats(std::vector &dat, double startTension, double endTension) +void buildSmoothMats(std::vector &dat, double startTension, double endTension, bool closed) { for (size_t i = 1; i + 1 < dat.size(); ++i) { auto &cur = dat[i]; @@ -449,16 +456,34 @@ void buildSmoothMats(std::vector &dat, double startTension, double endT cur.inTan.smoothTan = -tan * preLegLen; cur.outTan.smoothTan = tan * nextLegLen; } - dat[0].outTan.smoothTan = (dat[1].tfm + dat[1].inTan.smoothTan * startTension - dat[0].tfm) * - (dat[0].outTan.weight / 2); - dat[0].smoothMat = buildMat(dat[0].tfm, dat[0].norm, dat[0].outTan.smoothTan.normal()); - size_t s = dat.size(); - dat[s - 1].inTan.smoothTan = - (dat[s - 2].tfm + dat[s - 2].outTan.smoothTan * startTension - dat[s - 1].tfm) * - (dat[s - 1].inTan.weight / 2); + if (closed){ + auto &start = dat[0]; + auto &end = dat[dat.size() - 1]; - dat[s - 1].smoothMat = buildMat(dat[s - 1].tfm, dat[s - 1].norm, -dat[s - 1].inTan.smoothTan.normal()); + MVector tan = buildVertMatTangent( + start.outTan.legLen, end.inTan.legLen, start.outTan.normLeg, end.inTan.normLeg + ); + start.smoothMat = buildMat(start.tfm, start.norm, tan); + end.smoothMat = start.smoothMat; + double preLegLen = end.inTan.legLen * end.inTan.weight / 3; + double nextLegLen = start.outTan.legLen * start.outTan.weight / 3; + + end.inTan.smoothTan = -tan * preLegLen; + start.outTan.smoothTan = tan * nextLegLen; + } + else{ + dat[0].outTan.smoothTan = (dat[1].tfm + dat[1].inTan.smoothTan * startTension - dat[0].tfm) * + (dat[0].outTan.weight / 2); + dat[0].smoothMat = buildMat(dat[0].tfm, dat[0].norm, dat[0].outTan.smoothTan.normal()); + + size_t s = dat.size(); + dat[s - 1].inTan.smoothTan = + (dat[s - 2].tfm + dat[s - 2].outTan.smoothTan * startTension - dat[s - 1].tfm) * + (dat[s - 1].inTan.weight / 2); + + dat[s - 1].smoothMat = buildMat(dat[s - 1].tfm, dat[s - 1].norm, -dat[s - 1].inTan.smoothTan.normal()); + } } void buildLinearTangents(std::vector &dat) @@ -521,6 +546,7 @@ MStatus TwistMultiTangentNode::compute(const MPlug &plug, MDataBlock &data) double startTension = data.inputValue(aStartTension).asDouble(); double endTension = data.inputValue(aEndTension).asDouble(); int maxVertices = data.inputValue(aMaxVertices).asInt(); + bool closed = data.inputValue(aClosed).asBool(); icount = (icount < maxVertices) ? icount : (unsigned int)maxVertices; if (icount < 2) { @@ -576,6 +602,13 @@ MStatus TwistMultiTangentNode::compute(const MPlug &plug, MDataBlock &data) tanData.push_back(std::move(dat)); } + if (closed){ + auto &start = tanData[0]; + auto &end = tanData[tanData.size() - 1]; + start.inTan = end.inTan; + end.outTan = start.outTan; + } + for (size_t i = 1; i < tanData.size(); ++i) { auto &prev = tanData[i - 1]; auto &cur = tanData[i]; @@ -592,7 +625,7 @@ MStatus TwistMultiTangentNode::compute(const MPlug &plug, MDataBlock &data) tanData[0].inTan.legLen = 0.0; tanData[tanData.size() - 1].outTan.legLen = 0.0; - buildSmoothMats(tanData, startTension, endTension); + buildSmoothMats(tanData, startTension, endTension, closed); buildLinearTangents(tanData); buildDoneTangents(tanData); diff --git a/src/twistMultiTangentNode.h b/src/twistMultiTangentNode.h index 931c989..0fd3451 100644 --- a/src/twistMultiTangentNode.h +++ b/src/twistMultiTangentNode.h @@ -57,6 +57,7 @@ class TwistMultiTangentNode : public MPxNode { static MObject aStartTension; static MObject aEndTension; static MObject aMaxVertices; + static MObject aClosed; // outputs static MObject aInTanX;