File indexing completed on 2025-01-18 10:04:38
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef Poly_MakeLoops_HeaderFile
0017 #define Poly_MakeLoops_HeaderFile
0018
0019 #include <NCollection_Sequence.hxx>
0020 #include <NCollection_IndexedMap.hxx>
0021 #include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
0022 #include <NCollection_IncAllocator.hxx>
0023 #include <NCollection_List.hxx>
0024 #include <NCollection_OccAllocator.hxx>
0025 #include <Standard_HashUtils.hxx>
0026
0027
0028
0029
0030
0031
0032 class Poly_MakeLoops
0033 {
0034 public:
0035
0036 enum LinkFlag {
0037 LF_None = 0,
0038 LF_Fwd = 1,
0039 LF_Rev = 2,
0040 LF_Both = 3,
0041 LF_Reversed = 4
0042 };
0043
0044
0045 struct Link
0046 {
0047 Standard_Integer node1, node2;
0048 Standard_Integer flags;
0049
0050 Link()
0051 : node1(0), node2(0), flags(0) {}
0052
0053 Link(Standard_Integer theNode1, Standard_Integer theNode2)
0054 : node1(theNode1), node2(theNode2), flags(1) {}
0055
0056 void Reverse()
0057 {
0058 flags ^= Poly_MakeLoops::LF_Reversed;
0059 }
0060
0061 Standard_Boolean IsReversed() const
0062 {
0063 return (flags & Poly_MakeLoops::LF_Reversed) != 0;
0064 }
0065
0066 void Nullify()
0067 {
0068 node1 = node2 = 0;
0069 }
0070
0071 Standard_Boolean IsNull() const
0072 {
0073 return node1 == 0 || node2 == 0;
0074 }
0075
0076 bool operator==(const Link& theOther) const
0077 {
0078 return (theOther.node1 == node1 && theOther.node2 == node2) ||
0079 (theOther.node1 == node2 && theOther.node2 == node1);
0080 }
0081 };
0082
0083 struct Hasher
0084 {
0085 size_t operator()(const Poly_MakeLoops::Link& theLink) const noexcept
0086 {
0087
0088 int aCombination[2]{ theLink.node1, theLink.node2 };
0089 if (aCombination[0] > aCombination[1])
0090 {
0091 std::swap(aCombination[0], aCombination[1]);
0092 }
0093 return opencascade::hashBytes(aCombination, sizeof(aCombination));
0094 }
0095
0096 bool operator()(const Poly_MakeLoops::Link& theLink1, const Poly_MakeLoops::Link& theLink2) const noexcept
0097 {
0098 return theLink1 == theLink2;
0099 }
0100 };
0101
0102
0103 typedef NCollection_List<Link> ListOfLink;
0104 typedef ListOfLink Loop;
0105
0106
0107 class Helper
0108 {
0109 public:
0110
0111 virtual const ListOfLink& GetAdjacentLinks (Standard_Integer theNode) const = 0;
0112
0113 virtual void OnAddLink (Standard_Integer , const Link& ) const {}
0114 };
0115
0116
0117
0118
0119 class HeapOfInteger
0120 {
0121 public:
0122 HeapOfInteger (const Standard_Integer theNbPreAllocated = 1)
0123 : myMap (theNbPreAllocated),
0124 myIterReady (Standard_False) {}
0125
0126 void Clear()
0127 {
0128 myMap.Clear();
0129 myIterReady = Standard_False;
0130 }
0131
0132 void Add (const Standard_Integer theValue)
0133 {
0134 myMap.Add (theValue);
0135 myIterReady = Standard_False;
0136 }
0137
0138 Standard_Integer Top()
0139 {
0140 if (!myIterReady)
0141 {
0142 myIter.Initialize (myMap);
0143 myIterReady = Standard_True;
0144 }
0145 return myIter.Key();
0146 }
0147
0148 Standard_Boolean Contains (const Standard_Integer theValue) const
0149 {
0150 return myMap.Contains (theValue);
0151 }
0152
0153 void Remove (const Standard_Integer theValue)
0154 {
0155 if (myIterReady && myIter.More() && myIter.Key() == theValue)
0156 myIter.Next();
0157 myMap.Remove (theValue);
0158 }
0159
0160 Standard_Boolean IsEmpty()
0161 {
0162 if (!myIterReady)
0163 {
0164 myIter.Initialize (myMap);
0165 myIterReady = Standard_True;
0166 }
0167 return !myIter.More();
0168 }
0169
0170 private:
0171 TColStd_PackedMapOfInteger myMap;
0172 TColStd_MapIteratorOfPackedMapOfInteger myIter;
0173 Standard_Boolean myIterReady;
0174 };
0175
0176 public:
0177
0178
0179
0180
0181 Standard_EXPORT Poly_MakeLoops(const Helper* theHelper,
0182 const Handle(NCollection_BaseAllocator)& theAlloc = 0L);
0183
0184
0185 Standard_EXPORT void Reset
0186 (const Helper* theHelper,
0187 const Handle(NCollection_BaseAllocator)& theAlloc = 0L);
0188
0189
0190
0191 Standard_EXPORT void AddLink(const Link& theLink);
0192
0193
0194 Standard_EXPORT void ReplaceLink(const Link& theLink, const Link& theNewLink);
0195
0196
0197
0198
0199 Standard_EXPORT LinkFlag SetLinkOrientation
0200 (const Link& theLink,
0201 const LinkFlag theOrient);
0202
0203
0204 Standard_EXPORT Link FindLink(const Link& theLink) const;
0205
0206 enum ResultCode
0207 {
0208 RC_LoopsDone = 1,
0209 RC_HangingLinks = 2,
0210 RC_Failure = 4
0211 };
0212
0213
0214 Standard_EXPORT Standard_Integer Perform();
0215
0216
0217 Standard_Integer GetNbLoops() const
0218 {
0219 return myLoops.Length();
0220 }
0221
0222
0223 const Loop& GetLoop(Standard_Integer theIndex) const
0224 {
0225 return myLoops.Value(theIndex);
0226 }
0227
0228
0229 Standard_Integer GetNbHanging() const
0230 {
0231 return myHangIndices.Extent();
0232 }
0233
0234
0235 Standard_EXPORT void GetHangingLinks(ListOfLink& theLinks) const;
0236
0237 protected:
0238 virtual Standard_Integer chooseLeftWay
0239 (const Standard_Integer theNode,
0240 const Standard_Integer theSegIndex,
0241 const NCollection_List<Standard_Integer>& theLstIndS) const = 0;
0242
0243 const Helper* getHelper () const
0244 {
0245 return myHelper;
0246 }
0247
0248 Link getLink (const Standard_Integer theSegIndex) const
0249 {
0250 Link aLink = myMapLink(Abs(theSegIndex));
0251 if (theSegIndex < 0)
0252 aLink.Reverse();
0253 return aLink;
0254 }
0255 #ifdef OCCT_DEBUG
0256 void showBoundaryBreaks() const;
0257 #endif
0258
0259 private:
0260 int findContour(Standard_Integer theIndexS, NCollection_IndexedMap<Standard_Integer>& theContour,
0261 const Handle(NCollection_BaseAllocator)& theTempAlloc,
0262 const Handle(NCollection_IncAllocator)& theTempAlloc1) const;
0263 void acceptContour(const NCollection_IndexedMap<Standard_Integer>& theContour,
0264 Standard_Integer theStartNumber);
0265 Standard_Integer getFirstNode(Standard_Integer theIndexS) const;
0266 Standard_Integer getLastNode(Standard_Integer theIndexS) const;
0267 void markHangChain(Standard_Integer theNode, Standard_Integer theIndexS);
0268 Standard_Boolean canLinkBeTaken(Standard_Integer theIndexS) const;
0269
0270
0271 const Helper* myHelper;
0272 Handle(NCollection_BaseAllocator) myAlloc;
0273 NCollection_IndexedMap<Link, Hasher> myMapLink;
0274 NCollection_Sequence<Loop> myLoops;
0275 HeapOfInteger myStartIndices;
0276 TColStd_PackedMapOfInteger myHangIndices;
0277 };
0278
0279
0280
0281
0282 class gp_Dir;
0283 class Poly_MakeLoops3D: public Poly_MakeLoops
0284 {
0285 public:
0286
0287 class Helper: public Poly_MakeLoops::Helper
0288 {
0289 public:
0290
0291
0292
0293
0294 virtual Standard_Boolean GetFirstTangent(const Link& theLink,
0295 gp_Dir& theDir) const = 0;
0296
0297
0298 virtual Standard_Boolean GetLastTangent(const Link& theLink,
0299 gp_Dir& theDir) const = 0;
0300
0301
0302 virtual Standard_Boolean GetNormal(Standard_Integer theNode,
0303 gp_Dir& theDir) const = 0;
0304 };
0305
0306
0307
0308 Standard_EXPORT Poly_MakeLoops3D(const Helper* theHelper,
0309 const Handle(NCollection_BaseAllocator)& theAlloc);
0310
0311 protected:
0312 Standard_EXPORT virtual Standard_Integer chooseLeftWay
0313 (const Standard_Integer theNode,
0314 const Standard_Integer theSegIndex,
0315 const NCollection_List<Standard_Integer>& theLstIndS) const;
0316 const Helper* getHelper () const
0317 {
0318 return static_cast<const Poly_MakeLoops3D::Helper*>
0319 (Poly_MakeLoops::getHelper());
0320 }
0321 };
0322
0323
0324
0325
0326 class gp_Dir2d;
0327 class Poly_MakeLoops2D: public Poly_MakeLoops
0328 {
0329 public:
0330
0331 class Helper: public Poly_MakeLoops::Helper
0332 {
0333 public:
0334
0335
0336
0337
0338 virtual Standard_Boolean GetFirstTangent(const Link& theLink,
0339 gp_Dir2d& theDir) const = 0;
0340
0341
0342 virtual Standard_Boolean GetLastTangent(const Link& theLink,
0343 gp_Dir2d& theDir) const = 0;
0344 };
0345
0346
0347
0348 Standard_EXPORT Poly_MakeLoops2D(const Standard_Boolean theLeftWay,
0349 const Helper* theHelper,
0350 const Handle(NCollection_BaseAllocator)& theAlloc);
0351
0352 protected:
0353 Standard_EXPORT virtual Standard_Integer chooseLeftWay
0354 (const Standard_Integer theNode,
0355 const Standard_Integer theSegIndex,
0356 const NCollection_List<Standard_Integer>& theLstIndS) const;
0357 const Helper* getHelper () const
0358 {
0359 return static_cast<const Poly_MakeLoops2D::Helper*>
0360 (Poly_MakeLoops::getHelper());
0361 }
0362
0363 private:
0364
0365 Standard_Boolean myRightWay;
0366 };
0367
0368
0369 namespace std
0370 {
0371 template <>
0372 struct hash<Poly_MakeLoops::Link>
0373 {
0374 size_t operator()(const Poly_MakeLoops::Link& theLink) const noexcept
0375 {
0376 return Poly_MakeLoops::Hasher{}(theLink);
0377 }
0378 };
0379
0380 template<>
0381 struct equal_to<Poly_MakeLoops::Link>
0382 {
0383 bool operator()(const Poly_MakeLoops::Link& theLink1,
0384 const Poly_MakeLoops::Link& theLink2) const noexcept
0385 {
0386 return theLink1 == theLink2;
0387 }
0388 };
0389 }
0390
0391 #endif