File indexing completed on 2026-09-21 09:16:37
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef _BRepMesh_NodeInsertionMeshAlgo_HeaderFile
0017 #define _BRepMesh_NodeInsertionMeshAlgo_HeaderFile
0018
0019 #include <BRepMesh_Classifier.hxx>
0020 #include <IMeshData_Wire.hxx>
0021 #include <IMeshData_Edge.hxx>
0022 #include <IMeshData_PCurve.hxx>
0023 #include <BRepMesh_Vertex.hxx>
0024 #include <TopExp_Explorer.hxx>
0025 #include <TopoDS_Vertex.hxx>
0026 #include <BRep_Tool.hxx>
0027 #include <Standard_ErrorHandler.hxx>
0028 #include <BRepMesh_Delaun.hxx>
0029
0030
0031
0032 template <class RangeSplitter, class BaseAlgo>
0033 class BRepMesh_NodeInsertionMeshAlgo : public BaseAlgo
0034 {
0035 public:
0036
0037 BRepMesh_NodeInsertionMeshAlgo() = default;
0038
0039
0040 ~BRepMesh_NodeInsertionMeshAlgo() override = default;
0041
0042
0043 void Perform(const IMeshData::IFaceHandle& theDFace,
0044 const IMeshTools_Parameters& theParameters,
0045 const Message_ProgressRange& theRange) override
0046 {
0047 myRangeSplitter.Reset(theDFace, theParameters);
0048 myClassifier = new BRepMesh_Classifier;
0049 if (!theRange.More())
0050 {
0051 return;
0052 }
0053 BaseAlgo::Perform(theDFace, theParameters, theRange);
0054 myClassifier.Nullify();
0055 }
0056
0057 protected:
0058 typedef NCollection_Shared<NCollection_Sequence<const gp_Pnt2d*>> SequenceOfPnt2d;
0059
0060
0061 bool initDataStructure() override
0062 {
0063 occ::handle<NCollection_IncAllocator> aTmpAlloc = new NCollection_IncAllocator;
0064
0065 const IMeshData::IFaceHandle& aDFace = this->getDFace();
0066 NCollection_Array1<occ::handle<SequenceOfPnt2d>> aWires(0, aDFace->WiresNb() - 1);
0067 for (int aWireIt = 0; aWireIt < aDFace->WiresNb(); ++aWireIt)
0068 {
0069 const IMeshData::IWireHandle& aDWire = aDFace->GetWire(aWireIt);
0070 if (aDWire->IsSet(IMeshData_SelfIntersectingWire)
0071 || (aDWire->IsSet(IMeshData_OpenWire) && aWireIt != 0))
0072 {
0073 continue;
0074 }
0075
0076 aWires(aWireIt) = collectWirePoints(aDWire, aTmpAlloc);
0077 }
0078
0079 myRangeSplitter.AdjustRange();
0080 if (!myRangeSplitter.IsValid())
0081 {
0082 aDFace->SetStatus(IMeshData_Failure);
0083 return false;
0084 }
0085
0086 const std::pair<double, double>& aDelta = myRangeSplitter.GetDelta();
0087 const std::pair<double, double>& aTolUV = myRangeSplitter.GetToleranceUV();
0088 const double uCellSize = 14.0 * aTolUV.first;
0089 const double vCellSize = 14.0 * aTolUV.second;
0090
0091 this->getStructure()->Data()->SetCellSize(uCellSize / aDelta.first, vCellSize / aDelta.second);
0092 this->getStructure()->Data()->SetTolerance(aTolUV.first / aDelta.first,
0093 aTolUV.second / aDelta.second);
0094
0095 for (int aWireIt = 0; aWireIt < aDFace->WiresNb(); ++aWireIt)
0096 {
0097 const occ::handle<SequenceOfPnt2d>& aWire = aWires(aWireIt);
0098 if (!aWire.IsNull() && !aWire->IsEmpty())
0099 {
0100 myClassifier->RegisterWire(*aWire,
0101 aTolUV,
0102 myRangeSplitter.GetRangeU(),
0103 myRangeSplitter.GetRangeV());
0104 }
0105 }
0106
0107 if (this->getParameters().InternalVerticesMode)
0108 {
0109 insertInternalVertices();
0110 }
0111
0112 return BaseAlgo::initDataStructure();
0113 }
0114
0115
0116
0117 int addNodeToStructure(const gp_Pnt2d& thePoint,
0118 const int theLocation3d,
0119 const BRepMesh_DegreeOfFreedom theMovability,
0120 const bool isForceAdd) override
0121 {
0122 return BaseAlgo::addNodeToStructure(myRangeSplitter.Scale(thePoint, true),
0123 theLocation3d,
0124 theMovability,
0125 isForceAdd);
0126 }
0127
0128
0129 gp_Pnt2d getNodePoint2d(const BRepMesh_Vertex& theVertex) const override
0130 {
0131 return myRangeSplitter.Scale(theVertex.Coord(), false);
0132 }
0133
0134
0135 const RangeSplitter& getRangeSplitter() const { return myRangeSplitter; }
0136
0137
0138 const occ::handle<BRepMesh_Classifier>& getClassifier() const { return myClassifier; }
0139
0140 private:
0141
0142 occ::handle<SequenceOfPnt2d> collectWirePoints(
0143 const IMeshData::IWireHandle& theDWire,
0144 const occ::handle<NCollection_IncAllocator>& theAllocator)
0145 {
0146 occ::handle<SequenceOfPnt2d> aWirePoints = new SequenceOfPnt2d(theAllocator);
0147 for (int aEdgeIt = 0; aEdgeIt < theDWire->EdgesNb(); ++aEdgeIt)
0148 {
0149 const IMeshData::IEdgeHandle aDEdge = theDWire->GetEdge(aEdgeIt);
0150 const IMeshData::IPCurveHandle& aPCurve =
0151 aDEdge->GetPCurve(this->getDFace().get(), theDWire->GetEdgeOrientation(aEdgeIt));
0152
0153 int aPointIt, aEndIndex, aInc;
0154 if (aPCurve->IsForward())
0155 {
0156
0157
0158
0159 aEndIndex = aPCurve->ParametersNb() - 1;
0160 aPointIt = (std::min)(0, aEndIndex);
0161 aInc = 1;
0162 }
0163 else
0164 {
0165
0166
0167
0168 aPointIt = aPCurve->ParametersNb() - 1;
0169 aEndIndex = (std::min)(0, aPointIt);
0170 aInc = -1;
0171 }
0172
0173
0174
0175 for (; aPointIt != aEndIndex; aPointIt += aInc)
0176 {
0177 const gp_Pnt2d& aPnt2d = aPCurve->GetPoint(aPointIt);
0178 aWirePoints->Append(&aPnt2d);
0179 myRangeSplitter.AddPoint(aPnt2d);
0180 }
0181 }
0182
0183 return aWirePoints;
0184 }
0185
0186
0187
0188 void insertInternalVertices()
0189 {
0190 TopExp_Explorer aExplorer(this->getDFace()->GetFace(), TopAbs_VERTEX, TopAbs_EDGE);
0191 for (; aExplorer.More(); aExplorer.Next())
0192 {
0193 const TopoDS_Vertex& aVertex = TopoDS::Vertex(aExplorer.Current());
0194 if (aVertex.Orientation() != TopAbs_INTERNAL)
0195 {
0196 continue;
0197 }
0198
0199 insertInternalVertex(aVertex);
0200 }
0201 }
0202
0203
0204 void insertInternalVertex(const TopoDS_Vertex& theVertex)
0205 {
0206 try
0207 {
0208 OCC_CATCH_SIGNALS
0209
0210 gp_Pnt2d aPnt2d = BRep_Tool::Parameters(theVertex, this->getDFace()->GetFace());
0211
0212 if (myClassifier->Perform(aPnt2d) != TopAbs_IN)
0213 return;
0214
0215 this->registerNode(BRep_Tool::Pnt(theVertex), aPnt2d, BRepMesh_Fixed, false);
0216 }
0217 catch (Standard_Failure const&)
0218 {
0219 }
0220 }
0221
0222 private:
0223 RangeSplitter myRangeSplitter;
0224 occ::handle<BRepMesh_Classifier> myClassifier;
0225 };
0226
0227 #endif