mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-05 18:16:23 +03:00
0028652: Improve performance of the 3D offset algorithm for the planar cases
Perform intersection of the planar untrimmed faces using IntTools_FaceFace algorithm directly.
This commit is contained in:
parent
2d2b3d53b7
commit
501d0d386a
@ -97,6 +97,7 @@
|
||||
#include <gp_Vec.hxx>
|
||||
#include <IntRes2d_IntersectionPoint.hxx>
|
||||
#include <IntRes2d_IntersectionSegment.hxx>
|
||||
#include <IntTools_FaceFace.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <ProjLib_HProjectedCurve.hxx>
|
||||
#include <ProjLib_ProjectedCurve.hxx>
|
||||
@ -119,6 +120,19 @@
|
||||
#include <TopTools_SequenceOfShape.hxx>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
// The constant defines the maximal value to enlarge surfaces.
|
||||
// It is limited to 1.e+7. This limitation is justified by the
|
||||
// floating point format. As we can have only 15
|
||||
// valuable decimal numbers, then during intersection of surfaces with
|
||||
// bounds of 1.e+8 the possible inaccuracy might appear already in seventh
|
||||
// decimal place which will be more than Precision::Confusion value -
|
||||
// 1.e-7, default tolerance value for the section curves.
|
||||
// By decreasing the max enlarge value to 1.e+7 the inaccuracy will be
|
||||
// shifted to eighth decimal place, i.e. the inaccuracy will be
|
||||
// decreased to values less than 1.e-7.
|
||||
const Standard_Real TheInfini = 1.e+7;
|
||||
|
||||
//tma: for new boolean operation
|
||||
#ifdef DRAW
|
||||
#include <DBRep.hxx>
|
||||
@ -137,6 +151,16 @@ static Standard_Integer NbExtE = 1;
|
||||
static Standard_Boolean AffichExtent = Standard_False;
|
||||
#endif
|
||||
|
||||
static
|
||||
void PerformPlanes(const TopoDS_Face& theFace1,
|
||||
const TopoDS_Face& theFace2,
|
||||
const TopAbs_State theState,
|
||||
TopTools_ListOfShape& theL1,
|
||||
TopTools_ListOfShape& theL2);
|
||||
|
||||
inline
|
||||
Standard_Boolean IsInf(const Standard_Real theVal);
|
||||
|
||||
//=======================================================================
|
||||
//function : EdgeVertices
|
||||
//purpose :
|
||||
@ -1571,6 +1595,22 @@ void BRepOffset_Tool::Inter3D(const TopoDS_Face& F1,
|
||||
}
|
||||
#endif
|
||||
|
||||
// Check if the faces are planar and not trimmed - in this case
|
||||
// the IntTools_FaceFace intersection algorithm will be used directly.
|
||||
BRepAdaptor_Surface aBAS1(F1, Standard_False), aBAS2(F2, Standard_False);
|
||||
if (aBAS1.GetType() == GeomAbs_Plane &&
|
||||
aBAS2.GetType() == GeomAbs_Plane) {
|
||||
aBAS1.Initialize(F1, Standard_True);
|
||||
if (IsInf(aBAS1.LastUParameter()) && IsInf(aBAS1.LastVParameter())) {
|
||||
aBAS2.Initialize(F2, Standard_True);
|
||||
if (IsInf(aBAS2.LastUParameter()) && IsInf(aBAS2.LastVParameter())) {
|
||||
// Intersect the planes without pave filler
|
||||
PerformPlanes(F1, F2, Side, L1, L2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
TopoDS_Face cpF1=F1;
|
||||
TopoDS_Face cpF2=F2;
|
||||
// create 3D curves on faces
|
||||
@ -3219,16 +3259,6 @@ Standard_Boolean BRepOffset_Tool::EnLargeFace
|
||||
Standard_Boolean isVV1degen = Standard_False, isVV2degen = Standard_False;
|
||||
Standard_Real US1,VS1,US2,VS2;
|
||||
Standard_Real UF1,VF1,UF2,VF2;
|
||||
// The maximal value to enlarge surfaces is decreased to 1.e+7.
|
||||
// It is justified by the floating point format. As we can have only 15
|
||||
// valuable decimal numbers, then during intersection of surfaces with
|
||||
// bounds of 1.e+8 the possible inaccuracy might appear already in seventh
|
||||
// decimal place which will be more than Precision::Confusion value -
|
||||
// 1.e-7, default tolerance value for the section curves.
|
||||
// By decreasing the max enlarge value to 1.e+7 the inaccuracy will be
|
||||
// shifted to eighth decimal place, i.e. the inaccuracy will be
|
||||
// decreased to values less than 1.e-7.
|
||||
Standard_Real infini = 1.e7;//1.e8;
|
||||
Standard_Boolean SurfaceChange = Standard_False;
|
||||
|
||||
if (S->IsUPeriodic() || S->IsVPeriodic()) {
|
||||
@ -3240,8 +3270,8 @@ Standard_Boolean BRepOffset_Tool::EnLargeFace
|
||||
}
|
||||
|
||||
S->Bounds (US1,US2,VS1,VS2);
|
||||
UU1 = VV1 = - infini;
|
||||
UU2 = VV2 = infini;
|
||||
UU1 = VV1 = - TheInfini;
|
||||
UU2 = VV2 = TheInfini;
|
||||
|
||||
if (CanExtentSurface) {
|
||||
SurfaceChange = EnlargeGeometry( S, UU1, UU2, VV1, VV2, isVV1degen, isVV2degen, UF1, UF2, VF1, VF2,
|
||||
@ -4042,3 +4072,80 @@ Standard_Boolean BRepOffset_Tool::CheckPlanesNormals(const TopoDS_Face& theFace1
|
||||
Standard_Real anAngle = aDN1.Angle(aDN2);
|
||||
return (anAngle < theTolAng);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : PerformPlanes
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void PerformPlanes(const TopoDS_Face& theFace1,
|
||||
const TopoDS_Face& theFace2,
|
||||
const TopAbs_State theSide,
|
||||
TopTools_ListOfShape& theL1,
|
||||
TopTools_ListOfShape& theL2)
|
||||
{
|
||||
theL1.Clear();
|
||||
theL2.Clear();
|
||||
// Intersect the planes using IntTools_FaceFace directly
|
||||
IntTools_FaceFace aFF;
|
||||
aFF.SetParameters(Standard_True, Standard_True, Standard_True, Precision::Confusion());
|
||||
aFF.Perform(theFace1, theFace2);
|
||||
//
|
||||
if (!aFF.IsDone()) {
|
||||
return;
|
||||
}
|
||||
//
|
||||
const IntTools_SequenceOfCurves& aSC = aFF.Lines();
|
||||
if (aSC.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
//
|
||||
// In Plane/Plane intersection only one curve is always produced.
|
||||
// Make the edge from this section curve.
|
||||
TopoDS_Edge aE;
|
||||
{
|
||||
BRep_Builder aBB;
|
||||
const IntTools_Curve& aIC = aSC(1);
|
||||
const Handle(Geom_Curve)& aC3D = aIC.Curve();
|
||||
aBB.MakeEdge(aE, aC3D, aIC.Tolerance());
|
||||
// Get bounds of the curve
|
||||
Standard_Real aTF, aTL;
|
||||
gp_Pnt aPF, aPL;
|
||||
aIC.Bounds(aTF, aTL, aPF, aPL);
|
||||
// Make the bounding vertices
|
||||
TopoDS_Vertex aVF, aVL;
|
||||
aBB.MakeVertex(aVF, aPF, aIC.Tolerance());
|
||||
aBB.MakeVertex(aVL, aPL, aIC.Tolerance());
|
||||
aVL.Orientation(TopAbs_REVERSED);
|
||||
// Add vertices to the edge
|
||||
aBB.Add(aE, aVF);
|
||||
aBB.Add(aE, aVL);
|
||||
// Add 2D curves to the edge
|
||||
aBB.UpdateEdge(aE, aIC.FirstCurve2d(), theFace1, aIC.Tolerance());
|
||||
aBB.UpdateEdge(aE, aIC.SecondCurve2d(), theFace2, aIC.Tolerance());
|
||||
// Update range of the new edge
|
||||
aBB.Range(aE, aTF, aTL);
|
||||
}
|
||||
//
|
||||
// Orient section
|
||||
TopAbs_Orientation O1, O2;
|
||||
BRepOffset_Tool::OrientSection(aE, theFace1, theFace2, O1, O2);
|
||||
if (theSide == TopAbs_OUT) {
|
||||
O1 = TopAbs::Reverse(O1);
|
||||
O2 = TopAbs::Reverse(O2);
|
||||
}
|
||||
//
|
||||
BRepLib::SameParameter(aE, Precision::Confusion(), Standard_True);
|
||||
//
|
||||
// Add edge to result
|
||||
theL1.Append(aE.Oriented(O1));
|
||||
theL2.Append(aE.Oriented(O2));
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IsInf
|
||||
//purpose : Checks if the given value is close to infinite (TheInfini)
|
||||
//=======================================================================
|
||||
Standard_Boolean IsInf(const Standard_Real theVal)
|
||||
{
|
||||
return (theVal > TheInfini*0.9);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user