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