#include <GCPnts_TangentialDeflection.hxx>
//=======================================================================
-// Function: GenerateSurfaceNodes
+// Function: GetSplitSteps
// Purpose :
//=======================================================================
-Handle(IMeshData::ListOfPnt2d) BRepMesh_ConeRangeSplitter::GenerateSurfaceNodes(
- const IMeshTools_Parameters& theParameters) const
+std::pair<Standard_Real, Standard_Real> BRepMesh_ConeRangeSplitter::GetSplitSteps(
+ const IMeshTools_Parameters& theParameters,
+ std::pair<Standard_Integer, Standard_Integer>& theStepsNb) const
{
const std::pair<Standard_Real, Standard_Real>& aRangeU = GetRangeU();
const std::pair<Standard_Real, Standard_Real>& aRangeV = GetRangeV();
Du = aDiffU / (nbU + 1);
Dv = aDiffV / (nbV + 1);
+ theStepsNb.first = nbU;
+ theStepsNb.second = nbV;
+ return std::make_pair (Du, Dv);
+}
+
+//=======================================================================
+// Function: GenerateSurfaceNodes
+// Purpose :
+//=======================================================================
+Handle(IMeshData::ListOfPnt2d) BRepMesh_ConeRangeSplitter::GenerateSurfaceNodes(
+ const IMeshTools_Parameters& theParameters) const
+{
+ const std::pair<Standard_Real, Standard_Real>& aRangeU = GetRangeU();
+ const std::pair<Standard_Real, Standard_Real>& aRangeV = GetRangeV();
+
+ std::pair<Standard_Integer, Standard_Integer> aStepsNb;
+ std::pair<Standard_Real, Standard_Real> aSteps = GetSplitSteps (theParameters, aStepsNb);
+
const Handle(NCollection_IncAllocator) aTmpAlloc =
new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
Handle(IMeshData::ListOfPnt2d) aNodes = new IMeshData::ListOfPnt2d(aTmpAlloc);
- const Standard_Real aPasMaxV = aRangeV.second - Dv*0.5;
- const Standard_Real aPasMaxU = aRangeU.second - Du*0.5;
- for (Standard_Real aPasV = aRangeV.first + Dv; aPasV < aPasMaxV; aPasV += Dv)
+ const Standard_Real aPasMaxV = aRangeV.second - aSteps.second*0.5;
+ const Standard_Real aPasMaxU = aRangeU.second - aSteps.first *0.5;
+ for (Standard_Real aPasV = aRangeV.first + aSteps.second; aPasV < aPasMaxV; aPasV += aSteps.second)
{
- for (Standard_Real aPasU = aRangeU.first + Du; aPasU < aPasMaxU; aPasU += Du)
+ for (Standard_Real aPasU = aRangeU.first + aSteps.first; aPasU < aPasMaxU; aPasU += aSteps.first)
{
aNodes->Append(gp_Pnt2d(aPasU, aPasV));
}
#include <IMeshData_Wire.hxx>
#include <IMeshData_PCurve.hxx>
#include <OSD_Parallel.hxx>
+#include <BRepMesh_ConeRangeSplitter.hxx>
namespace
{
Handle(IMeshData_Model) myModel;
};
+
+ //! Adds additional points to seam edges on specific surfaces.
+ class SeamEdgeAmplifier
+ {
+ public:
+ //! Constructor
+ SeamEdgeAmplifier(const Handle(IMeshData_Model)& theModel,
+ const IMeshTools_Parameters& theParameters)
+ : myModel (theModel)
+ , myParameters (theParameters)
+ {
+ }
+
+ //! Main functor.
+ void operator()(const Standard_Integer theFaceIndex) const
+ {
+ const IMeshData::IFaceHandle& aDFace = myModel->GetFace(theFaceIndex);
+ if (aDFace->GetSurface()->GetType() != GeomAbs_Cone)
+ {
+ return;
+ }
+
+ const IMeshData::IWireHandle& aDWire = aDFace->GetWire (0);
+ for (Standard_Integer aEdgeIdx = 0; aEdgeIdx < aDWire->EdgesNb() - 1; ++aEdgeIdx)
+ {
+ const IMeshData::IEdgePtr& aDEdge = aDWire->GetEdge (aEdgeIdx);
+
+ if (aDEdge->GetPCurve(aDFace.get(), TopAbs_FORWARD) != aDEdge->GetPCurve(aDFace.get(), TopAbs_REVERSED))
+ {
+ if (aDEdge->GetCurve()->ParametersNb() == 2)
+ {
+ if (splitEdge (aDEdge, Abs (getConeStep (aDFace))))
+ {
+ TopLoc_Location aLoc;
+ const Handle (Poly_Triangulation)& aTriangulation =
+ BRep_Tool::Triangulation (aDFace->GetFace (), aLoc);
+
+ if (!aTriangulation.IsNull ())
+ {
+ aDFace->SetStatus (IMeshData_Outdated);
+ }
+ }
+ }
+ return;
+ }
+ }
+ }
+
+ private:
+
+ //! Returns step for splitting seam edge of a cone.
+ Standard_Real getConeStep(const IMeshData::IFaceHandle& theDFace) const
+ {
+ BRepMesh_ConeRangeSplitter aSplitter;
+ aSplitter.Reset (theDFace, myParameters);
+
+ const IMeshData::IWireHandle& aDWire = theDFace->GetWire (0);
+ for (Standard_Integer aEdgeIt = 0; aEdgeIt < aDWire->EdgesNb(); ++aEdgeIt)
+ {
+ const IMeshData::IEdgeHandle aDEdge = aDWire->GetEdge(aEdgeIt);
+ const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve(
+ theDFace.get(), aDWire->GetEdgeOrientation(aEdgeIt));
+
+ for (Standard_Integer aPointIt = 0; aPointIt < aPCurve->ParametersNb(); ++aPointIt)
+ {
+ const gp_Pnt2d& aPnt2d = aPCurve->GetPoint(aPointIt);
+ aSplitter.AddPoint(aPnt2d);
+ }
+ }
+
+ std::pair<Standard_Integer, Standard_Integer> aStepsNb;
+ std::pair<Standard_Real, Standard_Real> aSteps = aSplitter.GetSplitSteps (myParameters, aStepsNb);
+ return aSteps.second;
+ }
+
+ //! Splits 3D and all pcurves accoring using the specified step.
+ Standard_Boolean splitEdge(const IMeshData::IEdgePtr& theDEdge,
+ const Standard_Real theDU) const
+ {
+ if (!splitCurve<gp_XYZ> (theDEdge->GetCurve (), theDU))
+ {
+ return Standard_False;
+ }
+
+ for (Standard_Integer aPCurveIdx = 0; aPCurveIdx < theDEdge->PCurvesNb(); ++aPCurveIdx)
+ {
+ splitCurve<gp_XY> (theDEdge->GetPCurve (aPCurveIdx), theDU);
+ }
+
+ return Standard_True;
+ }
+
+ //! Splits the given curve using the specified step.
+ template<class PointType, class Curve>
+ Standard_Boolean splitCurve(Curve& theCurve, const Standard_Real theDU) const
+ {
+ Standard_Boolean isUpdated = Standard_False;
+ PointType aDir = theCurve->GetPoint(theCurve->ParametersNb() - 1).Coord() - theCurve->GetPoint(0).Coord();
+ const Standard_Real aModulus = aDir.Modulus();
+ if (aModulus < gp::Resolution())
+ {
+ return isUpdated;
+ }
+ aDir /= aModulus;
+
+ const Standard_Real aLastParam = theCurve->GetParameter(theCurve->ParametersNb() - 1);
+ const Standard_Boolean isReversed = theCurve->GetParameter(0) > aLastParam;
+ for (Standard_Integer aPointIdx = 1; ; ++aPointIdx)
+ {
+ const Standard_Real aCurrParam = theCurve->GetParameter(0) + aPointIdx * theDU * (isReversed ? -1.0 : 1.0);
+ if (( isReversed && (aCurrParam < aLastParam)) ||
+ (!isReversed && !(aCurrParam < aLastParam)))
+ {
+ break;
+ }
+
+ theCurve->InsertPoint(theCurve->ParametersNb() - 1,
+ theCurve->GetPoint(0).Translated (aDir * aPointIdx * theDU),
+ aCurrParam);
+
+ isUpdated = Standard_True;
+ }
+
+ return isUpdated;
+ }
+
+ private:
+
+ Handle(IMeshData_Model) myModel;
+ IMeshTools_Parameters myParameters;
+ };
}
//=======================================================================
return Standard_False;
}
- OSD_Parallel::For(0, theModel->FacesNb(), TriangulationConsistency(theModel), !theParameters.InParallel);
+ OSD_Parallel::For(0, theModel->FacesNb(), SeamEdgeAmplifier(theModel, theParameters), !theParameters.InParallel);
+ OSD_Parallel::For(0, theModel->FacesNb(), TriangulationConsistency(theModel), !theParameters.InParallel);
// Clean edges and faces from outdated polygons.
Handle(NCollection_IncAllocator) aTmpAlloc(new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE));