File indexing completed on 2025-01-18 10:04:38
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef _Poly_MergeNodesTool_HeaderFile
0015 #define _Poly_MergeNodesTool_HeaderFile
0016
0017 #include <NCollection_Map.hxx>
0018 #include <Poly_Triangulation.hxx>
0019 #include <Standard_HashUtils.hxx>
0020
0021
0022
0023 class Poly_MergeNodesTool : public Standard_Transient
0024 {
0025 DEFINE_STANDARD_RTTIEXT(Poly_MergeNodesTool, Standard_Transient)
0026 public:
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 Standard_EXPORT static Handle(Poly_Triangulation) MergeNodes (const Handle(Poly_Triangulation)& theTris,
0037 const gp_Trsf& theTrsf,
0038 const Standard_Boolean theToReverse,
0039 const double theSmoothAngle,
0040 const double theMergeTolerance = 0.0,
0041 const bool theToForce = true);
0042
0043 public:
0044
0045
0046
0047
0048
0049 Standard_EXPORT Poly_MergeNodesTool (const double theSmoothAngle,
0050 const double theMergeTolerance = 0.0,
0051 const int theNbFacets = -1);
0052
0053
0054 double MergeTolerance() const { return myNodeIndexMap.MergeTolerance(); }
0055
0056
0057 void SetMergeTolerance (double theTolerance) { myNodeIndexMap.SetMergeTolerance (theTolerance); }
0058
0059
0060 double MergeAngle() const { return myNodeIndexMap.MergeAngle(); }
0061
0062
0063 void SetMergeAngle (double theAngleRad) { myNodeIndexMap.SetMergeAngle (theAngleRad); }
0064
0065
0066 bool ToMergeOpposite() const { return myNodeIndexMap.ToMergeOpposite(); }
0067
0068
0069 void SetMergeOpposite (bool theToMerge) { myNodeIndexMap.SetMergeOpposite (theToMerge); }
0070
0071
0072 void SetUnitFactor (double theUnitFactor) { myUnitFactor = theUnitFactor; }
0073
0074
0075 bool ToDropDegenerative() const { return myToDropDegenerative; }
0076
0077
0078 void SetDropDegenerative (bool theToDrop) { myToDropDegenerative = theToDrop; }
0079
0080
0081 bool ToMergeElems() const { return myToMergeElems; }
0082
0083
0084 void SetMergeElems (bool theToMerge) { myToMergeElems = theToMerge; }
0085
0086
0087 NCollection_Vec3<float> computeTriNormal() const
0088 {
0089 const gp_XYZ aVec01 = myPlaces[1] - myPlaces[0];
0090 const gp_XYZ aVec02 = myPlaces[2] - myPlaces[0];
0091 const gp_XYZ aCross = aVec01 ^ aVec02;
0092 NCollection_Vec3<float> aNorm ((float )aCross.X(), (float )aCross.Y(), (float )aCross.Z());
0093 return aNorm.Normalized();
0094 }
0095
0096 public:
0097
0098
0099
0100
0101
0102 Standard_EXPORT virtual void AddTriangulation (const Handle(Poly_Triangulation)& theTris,
0103 const gp_Trsf& theTrsf = gp_Trsf(),
0104 const Standard_Boolean theToReverse = false);
0105
0106
0107 Standard_EXPORT Handle(Poly_Triangulation) Result();
0108
0109 public:
0110
0111
0112
0113 void AddTriangle (const gp_XYZ theElemNodes[3])
0114 {
0115 AddElement (theElemNodes, 3);
0116 }
0117
0118
0119
0120 void AddQuad (const gp_XYZ theElemNodes[4])
0121 {
0122 AddElement (theElemNodes, 4);
0123 }
0124
0125
0126
0127
0128 Standard_EXPORT void AddElement (const gp_XYZ* theElemNodes,
0129 int theNbNodes);
0130
0131
0132
0133 gp_XYZ& ChangeElementNode (int theIndex) { return myPlaces[theIndex]; }
0134
0135
0136 Standard_EXPORT void PushLastElement (int theNbNodes);
0137
0138
0139 void PushLastTriangle() { PushLastElement (3); }
0140
0141
0142 void PushLastQuad() { PushLastElement (4); }
0143
0144
0145 Standard_Integer ElementNodeIndex (int theIndex) const { return myNodeInds[theIndex]; }
0146
0147
0148 int NbNodes() const { return myNbNodes; }
0149
0150
0151 int NbElements() const { return myNbElems; }
0152
0153
0154 int NbDegenerativeElems() const { return myNbDegenElems; }
0155
0156
0157 int NbMergedElems() const { return myNbMergedElems; }
0158
0159
0160
0161 Handle(Poly_Triangulation)& ChangeOutput() { return myPolyData; }
0162
0163 private:
0164
0165
0166 void pushNodeCheck (bool& theIsOpposite,
0167 const int theTriNode)
0168 {
0169 int aNodeIndex = myNbNodes;
0170 const gp_XYZ& aPlace = myPlaces[theTriNode];
0171 const NCollection_Vec3<float> aVec3 ((float )aPlace.X(), (float )aPlace.Y(), (float )aPlace.Z());
0172 if (myNodeIndexMap.Bind (aNodeIndex, theIsOpposite, aVec3, myTriNormal))
0173 {
0174 ++myNbNodes;
0175 if (!myPolyData.IsNull())
0176 {
0177 if (myPolyData->NbNodes() < myNbNodes)
0178 {
0179 myPolyData->ResizeNodes (myNbNodes * 2, true);
0180 }
0181 myPolyData->SetNode (myNbNodes, aPlace * myUnitFactor);
0182 }
0183 }
0184 myNodeInds[theTriNode] = aNodeIndex;
0185 }
0186
0187
0188 inline void pushNodeNoMerge (const int theTriNode)
0189 {
0190 int aNodeIndex = myNbNodes;
0191 const gp_XYZ aPlace = myPlaces[theTriNode] * myUnitFactor;
0192
0193 ++myNbNodes;
0194 if (!myPolyData.IsNull())
0195 {
0196 if (myPolyData->NbNodes() < myNbNodes)
0197 {
0198 myPolyData->ResizeNodes (myNbNodes * 2, true);
0199 }
0200 myPolyData->SetNode (myNbNodes, aPlace);
0201 }
0202
0203 myNodeInds[theTriNode] = aNodeIndex;
0204 }
0205
0206 private:
0207
0208
0209 struct Vec3AndNormal
0210 {
0211 NCollection_Vec3<float> Pos;
0212 NCollection_Vec3<float> Norm;
0213
0214 Vec3AndNormal (const NCollection_Vec3<float>& thePos,
0215 const NCollection_Vec3<float>& theNorm)
0216 : Pos (thePos), Norm (theNorm) {}
0217 };
0218
0219
0220
0221 class MergedNodesMap : public NCollection_BaseMap
0222 {
0223 public:
0224 typedef NCollection_Vec3<int64_t> CellVec3i;
0225 public:
0226
0227 Standard_EXPORT MergedNodesMap (const int theNbBuckets);
0228
0229
0230 double MergeAngle() const { return myAngle; }
0231
0232
0233 void SetMergeAngle (double theAngleRad)
0234 {
0235 myAngle = (float )theAngleRad;
0236 myAngleCos = (float )Cos (theAngleRad);
0237 }
0238
0239
0240
0241 bool HasMergeAngle() const { return myAngle > 0.0f; }
0242
0243
0244 bool ToMergeAnyAngle() const { return myAngleCos <= 0.01f; }
0245
0246
0247 bool ToMergeOpposite() const { return myToMergeOpposite; }
0248
0249
0250 void SetMergeOpposite (bool theToMerge) { myToMergeOpposite = theToMerge; }
0251
0252
0253 double MergeTolerance() const { return myTolerance; }
0254
0255
0256 Standard_EXPORT void SetMergeTolerance (double theTolerance);
0257
0258
0259 bool HasMergeTolerance() const { return myTolerance > 0.0f; }
0260
0261
0262
0263
0264
0265
0266
0267 Standard_EXPORT bool Bind (int& theIndex,
0268 bool& theIsOpposite,
0269 const NCollection_Vec3<float>& thePos,
0270 const NCollection_Vec3<float>& theNorm);
0271
0272
0273 Standard_EXPORT void ReSize (const int theSize);
0274
0275 private:
0276
0277
0278 CellVec3i vec3ToCell (const NCollection_Vec3<float>& thePnt) const
0279 {
0280 return CellVec3i (thePnt * myInvTol);
0281 }
0282
0283
0284 Standard_EXPORT static size_t vec3iHashCode (const Poly_MergeNodesTool::MergedNodesMap::CellVec3i& theVec,
0285 const int theUpper);
0286
0287
0288 Standard_EXPORT size_t hashCode (const NCollection_Vec3<float>& thePos,
0289 const NCollection_Vec3<float>& theNorm,
0290 const int theUpper) const;
0291
0292
0293 size_t hashCode (const Vec3AndNormal& theKey, const int theUpper) const
0294 {
0295 return hashCode (theKey.Pos, theKey.Norm, theUpper);
0296 }
0297
0298
0299 Standard_EXPORT bool vec3AreEqual (const NCollection_Vec3<float>& theKey1,
0300 const NCollection_Vec3<float>& theKey2) const;
0301
0302
0303 Standard_EXPORT bool isEqual (const Vec3AndNormal& theKey1,
0304 const NCollection_Vec3<float>& thePos2,
0305 const NCollection_Vec3<float>& theNorm2,
0306 bool& theIsOpposite) const;
0307 private:
0308
0309 class DataMapNode;
0310 private:
0311 float myTolerance;
0312 float myInvTol;
0313 float myAngle;
0314 float myAngleCos;
0315 bool myToMergeOpposite;
0316 };
0317
0318
0319 struct MergedElemHasher
0320 {
0321 size_t operator()(const NCollection_Vec4<int>& theVec) const
0322 {
0323 return opencascade::hashBytes(&theVec[0], 4 * sizeof(int));
0324 }
0325
0326 bool operator()(const NCollection_Vec4<int>& theKey1, const NCollection_Vec4<int>& theKey2) const
0327 {
0328 return theKey1.IsEqual (theKey2);
0329 }
0330 };
0331
0332 private:
0333
0334 Handle(Poly_Triangulation) myPolyData;
0335 MergedNodesMap myNodeIndexMap;
0336 NCollection_Map<NCollection_Vec4<int>, MergedElemHasher>
0337 myElemMap;
0338 NCollection_Vec4<int> myNodeInds;
0339 NCollection_Vec3<float> myTriNormal;
0340 gp_XYZ myPlaces[4];
0341
0342 Standard_Real myUnitFactor;
0343 Standard_Integer myNbNodes;
0344 Standard_Integer myNbElems;
0345 Standard_Integer myNbDegenElems;
0346 Standard_Integer myNbMergedElems;
0347 Standard_Boolean myToDropDegenerative;
0348 Standard_Boolean myToMergeElems;
0349
0350 };
0351
0352 #endif