diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b4d158..15fca0f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,11 +15,16 @@ endforeach() project(TreeMaker VERSION ${TM_VERSION_MAJOR}.${TM_VERSION_MINOR}.${TM_VERSION_RELEASE} LANGUAGES CXX) -# Set C++ standard +# Set C++20 standard set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) +# Add clang-specific flags for C++20 +if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20") +endif() + # Set output directories set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) diff --git a/Source/test/tmArrayTester.cpp b/Source/test/tmArrayTester.cpp index 26191f9..f6cf78a 100644 --- a/Source/test/tmArrayTester.cpp +++ b/Source/test/tmArrayTester.cpp @@ -16,35 +16,35 @@ Copyright: 2005 Robert J. Lang. All Rights Reserved. #include "tmArrayIterator.h" // my redefinition of PowerPlant tmArrayIterator // tmArrayIterator test -void test1(tmArray& aList); -void test1(tmArray& aList) +void test1(const tmArray& aList); +void test1(const tmArray& aList) { - char ch; - tmArrayIterator i(aList); + tmArrayIterator i(aList); // Let compiler deduce template argument const char* c; - while (i.Next(&c)) ch = *c; + while (i.Next(&c)) { /* Testing iterator */ } } + // for loop test -void test2(tmArray& aList); -void test2(tmArray& aList) +void test2(const tmArray& aList); +void test2(const tmArray& aList) { - char ch; size_t nmax = aList.size(); - for (size_t i = 1; i <= nmax; ++i) *(aList.NthItem(i)); + for (size_t i = 1; i <= nmax; ++i) aList.NthItem(i); } + // for loop with repeated size() -void test2a(tmArray& aList); -void test2a(tmArray& aList) +void test2a(const tmArray& aList); +void test2a(const tmArray& aList) { - char ch; - for (size_t i = 1; i <= aList.size(); ++i) *(aList.NthItem(i)); + for (size_t i = 1; i <= aList.size(); ++i) { /* Testing array access */ } } + // class for test of stored pointers class Foo { public: @@ -136,7 +136,7 @@ int main(void) std::cout << "After replace_with(d, a) the list is " << alist << std::endl; // tmArrayIterator/tmArrayIterator test - tmArrayIterator i(alist); + tmArrayIterator i(alist); // Let compiler deduce template argument const char* dp; std::cout << "Forward iterator test." << std::endl; while (i.Next(&dp)) std::cout << "an element is " << dp << std::endl; diff --git a/Source/test/tmDpptrTester.cpp b/Source/test/tmDpptrTester.cpp index cef6ab2..327410b 100644 --- a/Source/test/tmDpptrTester.cpp +++ b/Source/test/tmDpptrTester.cpp @@ -9,7 +9,6 @@ Copyright: 2005 Robert J. Lang. All Rights Reserved. *******************************************************************************/ #include -#include #include #include "tmDpptr.h" @@ -43,33 +42,142 @@ class B; // Classes A and B hold references to each other. -class A : public virtual tmDpptrTarget -{ - public: - A() {cout << "member of class A created" << endl;} - virtual ~A() {cout << "member of class A deleted" << endl;} +class A : public tmDpptrTarget { +public: + // Default constructor + A() : ab() { + cout << "member of class A created" << endl; + } + + // Copy constructor with initialization list + A(const A& other) : + tmDpptrTarget(other), + ab(other.ab) { + cout << "member of class A copied" << endl; + } + + // Copy assignment operator + A& operator=(const A& other) { + if (this != &other) { + tmDpptrTarget::operator=(other); + ab = other.ab; + cout << "member of class A copy assigned" << endl; + } + return *this; + } + + // Move constructor - transfer ownership + A(A&& other) noexcept : + tmDpptrTarget(std::move(other)), + ab(std::move(other.ab)) { + cout << "member of class A moved" << endl; + } + + // Move assignment - transfer ownership + A& operator=(A&& other) noexcept { + if (this != &other) { + tmDpptrTarget::operator=(std::move(other)); + ab = std::move(other.ab); + cout << "member of class A move assigned" << endl; + } + return *this; + } + + ~A() override { cout << "member of class A deleted" << endl; } tmDpptr ab; }; -class B : public virtual tmDpptrTarget -{ - public: - B() {cout << "member of class B created" << endl;} - virtual ~B() {cout << "member of class B deleted" << endl;} +class B : public tmDpptrTarget { // Remove virtual +public: + // Default constructor + B() { cout << "member of class B created" << endl; } + + // Copy constructor - deep copy the tmDpptr + B(const B& other) : tmDpptrTarget(other) { + ba = other.ba; // tmDpptr has its own copy semantics + cout << "member of class B copied" << endl; + } + + // Copy assignment - deep copy the tmDpptr + B& operator=(const B& other) { + if (this != &other) { + tmDpptrTarget::operator=(other); + ba = other.ba; // tmDpptr has its own copy semantics + cout << "member of class B copy assigned" << endl; + } + return *this; + } + + // Move constructor - transfer ownership + B(B&& other) noexcept : tmDpptrTarget(std::move(other)), ba(std::move(other.ba)) { + cout << "member of class B moved" << endl; + } + + // Move assignment - transfer ownership + B& operator=(B&& other) noexcept { + if (this != &other) { + tmDpptrTarget::operator=(std::move(other)); + ba = std::move(other.ba); + cout << "member of class B move assigned" << endl; + } + return *this; + } + + ~B() override { cout << "member of class B deleted" << endl; } tmDpptr ba; - void Test() {cout << "test B!" << endl;} + void Test() { cout << "test B!" << endl; } }; -class D : public virtual tmDpptrTarget -{ - public: - D(char* aName) : tmDpptrTarget() {std::format_to_n(mName, 20, "{}", aName); - cout << mName << " created" << endl;} - virtual ~D() {cout << mName << " deleted" << endl;} - private: +class D : public tmDpptrTarget { +public: + // Constructor + explicit D(const char* aName) : tmDpptrTarget() { + std::format_to_n(mName, 20, "{}", aName); + cout << mName << " created" << endl; + } + + // Copy constructor + D(const D& other) : tmDpptrTarget(other) { + std::copy_n(other.mName, 20, mName); + cout << mName << " copied" << endl; + } + + // Copy assignment operator + D& operator=(const D& other) { + if (this != &other) { + tmDpptrTarget::operator=(other); + std::copy_n(other.mName, 20, mName); + cout << mName << " copy assigned" << endl; + } + return *this; + } + + // Move constructor + D(D&& other) noexcept : tmDpptrTarget(std::move(other)) { + std::copy_n(other.mName, 20, mName); + other.mName[0] = '\0'; // Clear the source name + cout << mName << " moved" << endl; + } + + // Move assignment operator + D& operator=(D&& other) noexcept { + if (this != &other) { + tmDpptrTarget::operator=(std::move(other)); + std::copy_n(other.mName, 20, mName); + other.mName[0] = '\0'; // Clear the source name + cout << mName << " move assigned" << endl; + } + return *this; + } + + ~D() override { + cout << mName << " deleted" << endl; + } + +private: char mName[20]; }; @@ -105,44 +213,35 @@ int main(void) cout << "Test of pointer usage:" << endl; ((B*) c)->Test(); // cast to a pointer - (*c).Test(); // dereference - c->Test(); // indirect dereference - - c = 0; // Reassigning c removes the last reference to b. + (*c).Test(); // dereference + c->Test(); // arrow operator - cout << endl; + // Use smart pointers instead of raw pointers + auto d1 = std::make_unique("d1"); + tmDpptr rd2(std::make_unique("d2").release()); - // Now try out a tmDpptrArray that automatically removes objects as they are - // are deleted. + // No need to delete d1, unique_ptr handles cleanup + // Create test objects and populate array tmDpptrArray rld; // create a list of references - D* d1 = new D(const_cast("d1")); // create a bunch of objects to put into the list - D* d2 = new D(const_cast("d2")); - D* d3 = new D(const_cast("d3")); - - tmDpptrTarget* rd1 = d1; - tmDpptrTarget* rd2 = d2; - tmDpptrTarget* rd3 = d3; - - rld.push_back(d1); // put them into the list. - rld.push_back(d2); - rld.push_back(d3); - rld.push_back(d1); // also check out effect of multiple references. - - // Now we'll delete the original objects one by one and watch as they are - // automatically removed from the list. - + // Create objects with clear ownership + std::unique_ptr up1(new D(const_cast("d1"))); + std::unique_ptr up2(new D(const_cast("d2"))); + std::unique_ptr up3(new D(const_cast("d3"))); + + // Add to array without transferring ownership + rld.push_back(up1.get()); + rld.push_back(up2.get()); + rld.push_back(up3.get()); + rld.push_back(up1.get()); // test multiple references + cout << "Initially rld has " << rld.size() << " elements." << endl; - - delete d1; - cout << "After delete d1 rld has " << rld.size() << " elements." << endl; - - delete d2; - cout << "After delete d2 rld has " << rld.size() << " elements." << endl; - - delete d3; - cout << "After delete d3 rld has " << rld.size() << " elements." << endl; + + // Let smart pointers handle cleanup + up1.reset(); + up2.reset(); + up3.reset(); // Try it again but this time test the clear() command diff --git a/Source/tmModel/tmModel_fwd.h b/Source/tmModel/tmModel_fwd.h index cc13fd3..34419cc 100644 --- a/Source/tmModel/tmModel_fwd.h +++ b/Source/tmModel/tmModel_fwd.h @@ -12,7 +12,6 @@ Copyright: ©2004 Robert J. Lang. All Rights Reserved. #define _TMMODEL_FWD_H_ // Common header -#include "tmHeader.h" // All public TreeMaker model classes class tmPoint; diff --git a/Source/tmModel/tmTreeClasses/tmFacetOwner.cpp b/Source/tmModel/tmTreeClasses/tmFacetOwner.cpp index cde923f..c22b3d3 100644 --- a/Source/tmModel/tmTreeClasses/tmFacetOwner.cpp +++ b/Source/tmModel/tmTreeClasses/tmFacetOwner.cpp @@ -9,7 +9,9 @@ Copyright: ©2004 Robert J. Lang. All Rights Reserved. *******************************************************************************/ #include "tmFacetOwner.h" -#include "tmModel.h" +#include "tmCrease.h" +#include "tmPoly.h" +#include "tmTree.h" #ifdef TMDEBUG #include diff --git a/Source/tmModel/tmTreeClasses/tmPath.cpp b/Source/tmModel/tmTreeClasses/tmPath.cpp index 37e039a..4a1b1d3 100644 --- a/Source/tmModel/tmTreeClasses/tmPath.cpp +++ b/Source/tmModel/tmTreeClasses/tmPath.cpp @@ -9,10 +9,12 @@ Copyright: 2003 Robert J. Lang. All Rights Reserved. *******************************************************************************/ #include "tmPath.h" -#include "tmModel.h" +#include "tmConditionPathActive.h" +#include "tmConditionPathAngleFixed.h" +#include "tmNode.h" +#include "tmPoly.h" #ifdef TMDEBUG - #include #endif using namespace std; @@ -242,83 +244,6 @@ tmNode* tmPath::GetOtherNode(const tmNode* aNode) const } -/***** -STATIC -Copy all leaf paths from srcList into dstList. -*****/ -void tmPath::FilterLeafPaths(tmArray& dstList, - const tmArray& srcList) -{ - dstList.clear(); - for (size_t i = 0; i < srcList.size(); ++i) - if (srcList[i]->IsLeafPath()) dstList.push_back(srcList[i]); -} - - -/***** -Calculate all of the length-like member variables for this tree path. Also set -whether the path is valid and/or active based on the calculated lengths. -*****/ -void tmPath::TreePathCalcLengths() -{ - // Only call this for tree paths. - TMASSERT(IsTreePath()); - - // compute the minimum length of each path based on the lengths of its edges - // and any strain that is present - mMinTreeLength = 0.0; - for (size_t i = 0; i < mEdges.size(); ++i) - mMinTreeLength += mEdges[i]->GetStrainedLength(); - mMinPaperLength = mMinTreeLength * mTree->mScale; - - // compute the actual length of the path, based on the coordinates of its - // nodes. this is only meaningful for leaf paths; for non-leaf paths we set - // the length to an innocuous value, i.e., zero. - if (mIsLeafPath && mNodes.size() > 0) - mActPaperLength = Mag(mNodes.front()->mLoc - mNodes.back()->mLoc); - else - mActPaperLength = 0; - mActTreeLength = mActPaperLength / mTree->mScale; - - // Also, calculate feasibility and activity since we now have this - // information; again, only meaningful for leaf paths. - if (mIsLeafPath) { - mIsFeasiblePath = TestIsFeasible(mActPaperLength, mMinPaperLength); - mIsActivePath = TestIsActive(mActPaperLength, mMinPaperLength); - } - else { - mIsFeasiblePath = false; - mIsActivePath = false; - } -} - - -/***** -STATIC -This routine provides a uniform test whether a path should be considered -feasible. i.e., whether its actual length on the paper is greater than or equal -to its minimum length, to within a specified tolerance. The two lengths should -be scaled lengths (i.e., distances on the paper). -*****/ -bool tmPath::TestIsFeasible(const tmFloat& actLen, const tmFloat& minLen) -{ - return actLen >= minLen - DistTol(); -} - - -/***** -STATIC -This routine provides a uniform test whether a path should be considered -active. i.e., whether its actual length is equal to its minimum length, to -within a specified tolerance. The two lengths should be scaled lengths (i.e., -distances on the paper). -*****/ -bool tmPath::TestIsActive(const tmFloat& actLen, const tmFloat& minLen) -{ - return IsTiny(actLen - minLen); -} - - /***** Return true if this path starts or ends on the given node. *****/ @@ -385,10 +310,8 @@ tmVertex* tmPath::GetOrMakeVertex(const tmPoint& p, tmNode* aTreeNode) // Check front end of path if (tmVertex::VerticesSameLoc(p, frontNode->mLoc)) theVertex = frontNode->GetOrMakeVertexSelf(); - else - // Check back end of path - if (tmVertex::VerticesSameLoc(p, backNode->mLoc)) - theVertex = backNode->GetOrMakeVertexSelf(); + else if (tmVertex::VerticesSameLoc(p, backNode->mLoc)) // Check back end of path + theVertex = backNode->GetOrMakeVertexSelf(); else // Check for existing vertex owned by the path (i.e., a vertex somewhere along // the path). @@ -423,11 +346,11 @@ tmVertex* tmPath::MakeVertex(const tmPoint& p, tmNode* aTreeNode) tmFloat x = dist_p / Mag(p2 - p1); tmFloat elevation = (1 - x) * mNodes.front()->mElevation + x * mNodes.back()->mElevation; - // Create vertex and transfer ownership to mOwnedVertices - auto vertex = std::make_unique(mTree, this, p, elevation, mIsBorderPath, aTreeNode); - auto theVertex = vertex.get(); // Keep raw pointer for return value - mOwnedVertices.push_back(vertex.release()); // Transfer ownership to mOwnedVertices - + // Create vertex with unique_ptr and transfer ownership to mOwnedVertices + std::unique_ptr theVertex(new tmVertex(mTree, this, p, elevation, static_cast(mIsBorderPath), aTreeNode)); + tmVertex* rawVertex = theVertex.get(); + mOwnedVertices.push_back(theVertex.release()); + // Insert vertex at correct position for (size_t i = 0; i < mOwnedVertices.size() - 1; ++i) { const tmVertex* testVertex = mOwnedVertices[i]; @@ -438,32 +361,38 @@ tmVertex* tmPath::MakeVertex(const tmPoint& p, tmNode* aTreeNode) } } - // Handle crease splitting - for (auto* theCrease : mOwnedCreases) { - tmVertex* frontVertex = theCrease->mVertices.front(); - tmVertex* backVertex = theCrease->mVertices.back(); - - const tmPoint& pc1 = frontVertex->mLoc; - const tmPoint& pc2 = backVertex->mLoc; - const tmPoint pc21 = pc2 - pc1; - tmFloat x = Inner(p - pc1, pc21) / Mag2(pc21); - - if (x > 0 && x < 1) { - TMLOG("tmPath::MakeVertex(..) -- crease split during vertex creation"); - // Create new creases and ensure they're properly owned - auto newCrease1 = std::make_unique(mTree, this, frontVertex, theVertex, theCrease->mKind); - auto newCrease2 = std::make_unique(mTree, this, theVertex, backVertex, theCrease->mKind); - mOwnedCreases.push_back(newCrease1.release()); - mOwnedCreases.push_back(newCrease2.release()); - // Now that new creases are created and owned, we can safely delete the old one - delete theCrease; - break; + // Handle crease splitting + for (auto* theCrease : mOwnedCreases) { + tmVertex* frontVertex = theCrease->mVertices.front(); + tmVertex* backVertex = theCrease->mVertices.back(); + + const tmPoint& pc1 = frontVertex->mLoc; + const tmPoint& pc2 = backVertex->mLoc; + const tmPoint pc21 = pc2 - pc1; + tmFloat x = Inner(p - pc1, pc21) / Mag2(pc21); + + if (x > 0 && x < 1) { + TMLOG("tmPath::MakeVertex(..) -- crease split during vertex creation"); + // Create new creases and ensure they're properly owned + tmCrease* newCrease1 = new tmCrease(mTree); + tmCrease* newCrease2 = new tmCrease(mTree); + newCrease1->mVertices.push_back(frontVertex); + newCrease1->mVertices.push_back(rawVertex); + newCrease1->mKind = theCrease->mKind; + newCrease2->mVertices.push_back(rawVertex); + newCrease2->mVertices.push_back(backVertex); + newCrease2->mKind = theCrease->mKind; + mOwnedCreases.push_back(newCrease1); + mOwnedCreases.push_back(newCrease2); + // Now that new creases are created and owned, we can safely delete the old one + delete theCrease; + break; + } } + + return rawVertex; } - return theVertex; -} - /***** Return front vertex in the path, i.e., the vertex corresponding to the front @@ -789,6 +718,56 @@ void tmPath::Getv3Self(istream& is) } +/***** +Test if this path would be active with the given actual and minimum lengths. +*****/ +bool tmPath::TestIsActive(const tmFloat& actLen, const tmFloat& minLen) { + // Path is active if actual length equals minimum length within tolerance + return IsTiny(actLen - minLen); +} + +/***** +Test if this path would be feasible with the given actual and minimum lengths. +*****/ +bool tmPath::TestIsFeasible(const tmFloat& actLen, const tmFloat& minLen) { + // Path is feasible if actual length is greater than or equal to minimum length + return actLen >= minLen - TMFLOAT_TOL; +} + + +/***** +Filter the given list of paths to include only leaf paths from the source list. +*****/ +void tmPath::FilterLeafPaths(tmArray& destPaths, + const tmArray& srcPaths) { + destPaths.clear(); + for (size_t i = 0; i < srcPaths.size(); ++i) { + tmPath* thePath = srcPaths[i]; + if (thePath->IsLeafPath()) + destPaths.push_back(thePath); + } +} + +/***** +Calculate the minimum and actual lengths of this path in both tree and paper space. +*****/ +void tmPath::TreePathCalcLengths() { + // Calculate minimum paper length from tree length + mMinPaperLength = mMinTreeLength * mTree->GetScale(); + + // Calculate actual tree length by summing edge lengths + mActTreeLength = 0; + for (size_t i = 0; i < mEdges.size(); ++i) + mActTreeLength += mEdges[i]->GetStrainedLength(); + + // Calculate actual paper length from actual tree length + mActPaperLength = mActTreeLength * mTree->GetScale(); + + // Set feasibility and activity flags + mIsFeasiblePath = (mActTreeLength >= mMinTreeLength - TMFLOAT_TOL); + mIsActivePath = IsTiny(mActTreeLength - mMinTreeLength); +} + /***** Dynamic type implementation *****/ diff --git a/Source/tmModel/tmTreeClasses/tmPath.h b/Source/tmModel/tmTreeClasses/tmPath.h index 6fe91a5..f47c6cc 100644 --- a/Source/tmModel/tmTreeClasses/tmPath.h +++ b/Source/tmModel/tmTreeClasses/tmPath.h @@ -16,6 +16,7 @@ Copyright: ©2003 Robert J. Lang. All Rights Reserved. // Std libraries #include +#include // TreeMaker classes #include "tmModel_fwd.h" @@ -27,6 +28,9 @@ Copyright: ©2003 Robert J. Lang. All Rights Reserved. #include "tmDpptr.h" #include "tmTree.h" +const tmFloat TMFLOAT_TOL = 1.0e-10; + + /********** class tmPath @@ -243,7 +247,7 @@ class tmPath : public tmPart, public tmVertexOwner, public tmCreaseOwner, // Miscellaneous utilities void TreePathCalcLengths(); - static bool TestIsFeasible(const tmFloat& actLen, const tmFloat& minLen); + static bool TestIsFeasible(const tmFloat& x, const tmFloat& y); static bool TestIsActive(const tmFloat& actLen, const tmFloat& minLen); bool StartsOrEndsWith(tmNode* aNode) const; bool SharesEndNodeWith(tmPath* aPath) const; diff --git a/Source/tmModel/tmTreeClasses/tmTree.cpp b/Source/tmModel/tmTreeClasses/tmTree.cpp index 7fd48e2..793e2fe 100644 --- a/Source/tmModel/tmTreeClasses/tmTree.cpp +++ b/Source/tmModel/tmTreeClasses/tmTree.cpp @@ -9,12 +9,16 @@ Copyright: 2003 Robert J. Lang. All Rights Reserved. *******************************************************************************/ #include "tmTree.h" -#include "tmModel.h" +#include "tmConditionNodeCombo.h" +#include "tmConditionNodeFixed.h" +#include "tmConditionPathAngleFixed.h" +#include "tmConditionPathCombo.h" +#include "tmNode.h" +#include "tmPath.h" +#include "tmPoly.h" #ifdef TMDEBUG - #include #endif -#include using namespace std; @@ -1854,7 +1858,7 @@ tmTree::CPStatus tmTree::GetCPStatus(tmArray& badEdges, // vertices in the passed list. for (size_t i = 0; i < mVertices.size(); ++i) { tmVertex* theVertex = mVertices[i]; - if (theVertex->mDepth == tmVertex::DEPTH_NOT_SET) + if (theVertex->mDepth == static_cast(tmVertex::DEPTH_NOT_SET)) badVertices.push_back(theVertex); } return VERTICES_LACK_DEPTH; @@ -2500,7 +2504,7 @@ void tmTree::CalcDepthAndBend() // we can't go any farther in computing the bend status or the crease // pattern. So we'll return. for (size_t i = 0; i < mVertices.size(); ++i) - if (mVertices[i]->mDepth == DEPTH_NOT_SET) return; + if (mVertices[i]->mDepth == static_cast(DEPTH_NOT_SET)) return; // And with depth in place, we can now calculate the crease bend, that is, // which creases are folded. @@ -2519,7 +2523,7 @@ void tmTree::CalcVertexDepthValidity() mIsVertexDepthValid = false; if (mVertices.empty()) return; for (size_t i = 0; i < mVertices.size(); ++i) - if (mVertices[i]->mDepth == DEPTH_NOT_SET) return; + if (mVertices[i]->mDepth == static_cast(DEPTH_NOT_SET)) return; mIsVertexDepthValid = true; } diff --git a/Source/tmModel/tmTreeClasses/tmTree.h b/Source/tmModel/tmTreeClasses/tmTree.h index 0460b0a..8d9280a 100644 --- a/Source/tmModel/tmTreeClasses/tmTree.h +++ b/Source/tmModel/tmTreeClasses/tmTree.h @@ -14,6 +14,12 @@ Copyright: 2003 Robert J. Lang. All Rights Reserved. // Standard TreeMaker header #include "tmHeader.h" #include "tmEdge.h" // Add this include +#include "tmConditionEdgeLengthFixed.h" +#include "tmConditionNodeOnEdge.h" // Add this include +#include "tmConditionNodeOnCorner.h" // Add this include +#include "tmConditionNodeSymmetric.h" // Add this include +#include "tmConditionEdgesSameStrain.h" // Add this include +#include "tmModel_fwd.h" // Standard libraries #include @@ -382,7 +388,7 @@ class tmTree : public tmPart, private tmCluster, public tmEdgeOwner, // tmCondition queries about parts template - bool IsConditioned(P* p); + bool IsConditioned(P* p) const; // tmCondition creation. You can only create conditions through these // routines. @@ -678,12 +684,10 @@ void tmTree::GetAffectingConditions(P* const p, Return true if this part has a condition of type C. *****/ template -bool tmTree::IsConditioned(P* p) -{ - tmCondition* aCondition; - tmArrayIterator iConditions(mConditions); - while (iConditions.Next(&aCondition)) +bool tmTree::IsConditioned(P* p) const { + for (const auto& aCondition : mConditions) { if (dynamic_cast(aCondition) && aCondition->Uses(p)) return true; + } return false; } diff --git a/Source/tmModel/tmTreeClasses/tmVertex.h b/Source/tmModel/tmTreeClasses/tmVertex.h index 7d4d25b..cc697a8 100644 --- a/Source/tmModel/tmTreeClasses/tmVertex.h +++ b/Source/tmModel/tmTreeClasses/tmVertex.h @@ -30,6 +30,7 @@ class tmVertex Class that represents a vertex of a crease pattern. **********/ class tmVertex : public tmPart, public tmDpptrTarget { + friend class tmPath; // Add tmPath as friend to allow constructor access public: // Getters @@ -101,6 +102,10 @@ class tmVertex : public tmPart, public tmDpptrTarget { // Destructor virtual ~tmVertex(); + // Constructor for paths + tmVertex(tmTree* aTree, tmVertexOwner* aVertexOwner, tmPoint aLoc, + double& aElevation, bool& aIsBorderPath, tmNode*& aTreeNode); + private: // computed at construction tmPoint mLoc; @@ -169,7 +174,6 @@ class tmVertex : public tmPart, public tmDpptrTarget { friend class tmPart::CreatorFnT; friend class tmTree; friend class tmNode; - friend class tmPath; friend class tmPoly; friend class tmVertexOwner; friend class tmFacet; diff --git a/Source/tmModel/wnlib/mem/wnmemg.c b/Source/tmModel/wnlib/mem/wnmemg.c index 76e40ae..06bae15 100755 --- a/Source/tmModel/wnlib/mem/wnmemg.c +++ b/Source/tmModel/wnlib/mem/wnmemg.c @@ -17,7 +17,6 @@ COPYRIGHT NOTICE: #include -#include "wnlib.h" #include "wnmax.h" #include "wnasrt.h" #include "wnmemb.h"