File indexing completed on 2025-01-18 10:03:14
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
0038 BRepMesh_NodeInsertionMeshAlgo()
0039 {
0040 }
0041
0042
0043 virtual ~BRepMesh_NodeInsertionMeshAlgo()
0044 {
0045 }
0046
0047
0048 virtual void Perform(
0049 const IMeshData::IFaceHandle& theDFace,
0050 const IMeshTools_Parameters& theParameters,
0051 const Message_ProgressRange& theRange) Standard_OVERRIDE
0052 {
0053 myRangeSplitter.Reset(theDFace, theParameters);
0054 myClassifier = new BRepMesh_Classifier;
0055 if (!theRange.More())
0056 {
0057 return;
0058 }
0059 BaseAlgo::Perform(theDFace, theParameters, theRange);
0060 myClassifier.Nullify();
0061 }
0062
0063 protected:
0064
0065 typedef NCollection_Shared<NCollection_Sequence<const gp_Pnt2d*> > SequenceOfPnt2d;
0066
0067
0068 virtual Standard_Boolean initDataStructure() Standard_OVERRIDE
0069 {
0070 Handle(NCollection_IncAllocator) aTmpAlloc = new NCollection_IncAllocator;
0071
0072 const IMeshData::IFaceHandle& aDFace = this->getDFace();
0073 NCollection_Array1<Handle(SequenceOfPnt2d)> aWires(0, aDFace->WiresNb() - 1);
0074 for (Standard_Integer aWireIt = 0; aWireIt < aDFace->WiresNb(); ++aWireIt)
0075 {
0076 const IMeshData::IWireHandle& aDWire = aDFace->GetWire(aWireIt);
0077 if (aDWire->IsSet(IMeshData_SelfIntersectingWire) ||
0078 (aDWire->IsSet(IMeshData_OpenWire) && aWireIt != 0))
0079 {
0080 continue;
0081 }
0082
0083 aWires(aWireIt) = collectWirePoints(aDWire, aTmpAlloc);
0084 }
0085
0086 myRangeSplitter.AdjustRange();
0087 if (!myRangeSplitter.IsValid())
0088 {
0089 aDFace->SetStatus(IMeshData_Failure);
0090 return Standard_False;
0091 }
0092
0093 const std::pair<Standard_Real, Standard_Real>& aDelta = myRangeSplitter.GetDelta();
0094 const std::pair<Standard_Real, Standard_Real>& aTolUV = myRangeSplitter.GetToleranceUV();
0095 const Standard_Real uCellSize = 14.0 * aTolUV.first;
0096 const Standard_Real vCellSize = 14.0 * aTolUV.second;
0097
0098 this->getStructure()->Data()->SetCellSize (uCellSize / aDelta.first, vCellSize / aDelta.second);
0099 this->getStructure()->Data()->SetTolerance(aTolUV.first / aDelta.first, aTolUV.second / aDelta.second);
0100
0101 for (Standard_Integer aWireIt = 0; aWireIt < aDFace->WiresNb(); ++aWireIt)
0102 {
0103 const Handle(SequenceOfPnt2d)& aWire = aWires(aWireIt);
0104 if (!aWire.IsNull() && !aWire->IsEmpty())
0105 {
0106 myClassifier->RegisterWire(*aWire, aTolUV,
0107 myRangeSplitter.GetRangeU(),
0108 myRangeSplitter.GetRangeV());
0109 }
0110 }
0111
0112 if (this->getParameters().InternalVerticesMode)
0113 {
0114 insertInternalVertices();
0115 }
0116
0117 return BaseAlgo::initDataStructure();
0118 }
0119
0120
0121
0122 virtual Standard_Integer addNodeToStructure(
0123 const gp_Pnt2d& thePoint,
0124 const Standard_Integer theLocation3d,
0125 const BRepMesh_DegreeOfFreedom theMovability,
0126 const Standard_Boolean isForceAdd) Standard_OVERRIDE
0127 {
0128 return BaseAlgo::addNodeToStructure(
0129 myRangeSplitter.Scale(thePoint, Standard_True),
0130 theLocation3d, theMovability, isForceAdd);
0131 }
0132
0133
0134 virtual gp_Pnt2d getNodePoint2d(
0135 const BRepMesh_Vertex& theVertex) const Standard_OVERRIDE
0136 {
0137 return myRangeSplitter.Scale(theVertex.Coord(), Standard_False);
0138 }
0139
0140
0141 const RangeSplitter& getRangeSplitter() const
0142 {
0143 return myRangeSplitter;
0144 }
0145
0146
0147 const Handle(BRepMesh_Classifier)& getClassifier() const
0148 {
0149 return myClassifier;
0150 }
0151
0152 private:
0153
0154
0155 Handle(SequenceOfPnt2d) collectWirePoints(
0156 const IMeshData::IWireHandle& theDWire,
0157 const Handle(NCollection_IncAllocator)& theAllocator)
0158 {
0159 Handle(SequenceOfPnt2d) aWirePoints = new SequenceOfPnt2d(theAllocator);
0160 for (Standard_Integer aEdgeIt = 0; aEdgeIt < theDWire->EdgesNb(); ++aEdgeIt)
0161 {
0162 const IMeshData::IEdgeHandle aDEdge = theDWire->GetEdge(aEdgeIt);
0163 const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve(
0164 this->getDFace().get(), theDWire->GetEdgeOrientation(aEdgeIt));
0165
0166 Standard_Integer aPointIt, aEndIndex, aInc;
0167 if (aPCurve->IsForward())
0168 {
0169
0170
0171
0172 aEndIndex = aPCurve->ParametersNb() - 1;
0173 aPointIt = Min(0, aEndIndex);
0174 aInc = 1;
0175 }
0176 else
0177 {
0178
0179
0180
0181 aPointIt = aPCurve->ParametersNb() - 1;
0182 aEndIndex = Min(0, aPointIt);
0183 aInc = -1;
0184 }
0185
0186
0187
0188 for (; aPointIt != aEndIndex; aPointIt += aInc)
0189 {
0190 const gp_Pnt2d& aPnt2d = aPCurve->GetPoint(aPointIt);
0191 aWirePoints->Append(&aPnt2d);
0192 myRangeSplitter.AddPoint(aPnt2d);
0193 }
0194 }
0195
0196 return aWirePoints;
0197 }
0198
0199
0200
0201 void insertInternalVertices()
0202 {
0203 TopExp_Explorer aExplorer(this->getDFace()->GetFace(), TopAbs_VERTEX, TopAbs_EDGE);
0204 for (; aExplorer.More(); aExplorer.Next())
0205 {
0206 const TopoDS_Vertex& aVertex = TopoDS::Vertex(aExplorer.Current());
0207 if (aVertex.Orientation() != TopAbs_INTERNAL)
0208 {
0209 continue;
0210 }
0211
0212 insertInternalVertex(aVertex);
0213 }
0214 }
0215
0216
0217 void insertInternalVertex(const TopoDS_Vertex& theVertex)
0218 {
0219 try
0220 {
0221 OCC_CATCH_SIGNALS
0222
0223 gp_Pnt2d aPnt2d = BRep_Tool::Parameters(theVertex, this->getDFace()->GetFace());
0224
0225 if (myClassifier->Perform(aPnt2d) != TopAbs_IN)
0226 return;
0227
0228 this->registerNode(BRep_Tool::Pnt(theVertex), aPnt2d,
0229 BRepMesh_Fixed, Standard_False);
0230 }
0231 catch (Standard_Failure const&)
0232 {
0233 }
0234 }
0235
0236 private:
0237
0238 RangeSplitter myRangeSplitter;
0239 Handle(BRepMesh_Classifier) myClassifier;
0240 };
0241
0242 #endif