mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-09-08 14:17:06 +03:00
0030559: BOP Fuse: result is inconsistent
Implement alternative approach for making the edge seam (closed) on the face. This approach is useful for non-periodic surfaces (e.g. tore-like surface of revolution is periodic in U direction only). Avoid internal faces in the affected solids of the result of BOP Fuse.
This commit is contained in:
@@ -39,6 +39,7 @@
|
||||
#include <Geom_RectangularTrimmedSurface.hxx>
|
||||
#include <Geom_Surface.hxx>
|
||||
#include <GeomAdaptor_Surface.hxx>
|
||||
#include <Geom2dAPI_ProjectPointOnCurve.hxx>
|
||||
#include <gp_Cylinder.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
#include <gp_Dir2d.hxx>
|
||||
@@ -72,8 +73,8 @@ static
|
||||
//function : DoSplitSEAMOnFace
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BOPTools_AlgoTools3D::DoSplitSEAMOnFace (const TopoDS_Edge& aSplit,
|
||||
const TopoDS_Face& aF)
|
||||
Standard_Boolean BOPTools_AlgoTools3D::DoSplitSEAMOnFace (const TopoDS_Edge& aSplit,
|
||||
const TopoDS_Face& aF)
|
||||
{
|
||||
Standard_Boolean bIsUPeriodic, bIsVPeriodic, bIsLeft;
|
||||
Standard_Real aTol, a, b, anUPeriod, anVPeriod, aT, anU, dU, anU1;
|
||||
@@ -131,7 +132,7 @@ void BOPTools_AlgoTools3D::DoSplitSEAMOnFace (const TopoDS_Edge& aSplit,
|
||||
bIsVPeriodic=aSB->IsVPeriodic();
|
||||
//
|
||||
if (!(bIsUPeriodic || bIsVPeriodic)) {
|
||||
return;
|
||||
return Standard_False;
|
||||
}
|
||||
anUPeriod = bIsUPeriodic ? aSB->UPeriod() : 0.;
|
||||
anVPeriod = bIsVPeriodic ? aSB->VPeriod() : 0.;
|
||||
@@ -139,7 +140,7 @@ void BOPTools_AlgoTools3D::DoSplitSEAMOnFace (const TopoDS_Edge& aSplit,
|
||||
//
|
||||
if (aRTS.IsNull()) {
|
||||
if (!bIsUClosed && !bIsVClosed) {
|
||||
return;
|
||||
return Standard_False;
|
||||
}
|
||||
//
|
||||
if (bIsUClosed) {
|
||||
@@ -191,7 +192,7 @@ void BOPTools_AlgoTools3D::DoSplitSEAMOnFace (const TopoDS_Edge& aSplit,
|
||||
}
|
||||
//
|
||||
if (anU1==anU && anV1==anV) {
|
||||
return;
|
||||
return Standard_False;
|
||||
}
|
||||
//
|
||||
aScPr = (anU1==anU) ? aDir2D1*aDOX : aDir2D1*aDOY;
|
||||
@@ -222,7 +223,96 @@ void BOPTools_AlgoTools3D::DoSplitSEAMOnFace (const TopoDS_Edge& aSplit,
|
||||
BB.UpdateEdge(aSp, aC2, aC1, aF, aTol);
|
||||
}
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : DoSplitSEAMOnFace
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean BOPTools_AlgoTools3D::DoSplitSEAMOnFace (const TopoDS_Edge& theEOrigin,
|
||||
const TopoDS_Edge& theESplit,
|
||||
const TopoDS_Face& theFace)
|
||||
{
|
||||
if (!BRep_Tool::IsClosed (theEOrigin, theFace))
|
||||
return Standard_False;
|
||||
|
||||
if (BRep_Tool::IsClosed (theESplit, theFace))
|
||||
return Standard_True;
|
||||
|
||||
TopoDS_Edge aESplit = theESplit;
|
||||
aESplit.Orientation (TopAbs_FORWARD);
|
||||
|
||||
TopoDS_Face aFace = theFace;
|
||||
aFace.Orientation (TopAbs_FORWARD);
|
||||
|
||||
Standard_Real aTS1, aTS2;
|
||||
Handle(Geom2d_Curve) aC2DSplit = BRep_Tool::CurveOnSurface (aESplit, aFace, aTS1, aTS2);
|
||||
if (aC2DSplit.IsNull())
|
||||
return Standard_False;
|
||||
|
||||
Standard_Real aT1, aT2;
|
||||
Handle(Geom2d_Curve) aC2D1 = BRep_Tool::CurveOnSurface (
|
||||
TopoDS::Edge (theEOrigin.Oriented (TopAbs_FORWARD)), aFace, aT1, aT2);
|
||||
Handle(Geom2d_Curve) aC2D2 = BRep_Tool::CurveOnSurface (
|
||||
TopoDS::Edge (theEOrigin.Oriented (TopAbs_REVERSED)), aFace, aT1, aT2);
|
||||
|
||||
Standard_Real aT = BOPTools_AlgoTools2D::IntermediatePoint (aTS1, aTS2);
|
||||
gp_Pnt2d aPMid;
|
||||
gp_Vec2d aVTgt;
|
||||
aC2DSplit->D1 (aT, aPMid, aVTgt);
|
||||
|
||||
// project on original 2d curves
|
||||
Geom2dAPI_ProjectPointOnCurve aProjPC1, aProjPC2;
|
||||
aProjPC1.Init (aPMid, aC2D1, aT1, aT2);
|
||||
aProjPC2.Init (aPMid, aC2D2, aT1, aT2);
|
||||
|
||||
if (!aProjPC1.NbPoints() && !aProjPC2.NbPoints())
|
||||
return Standard_False;
|
||||
|
||||
Standard_Real aDist1 = aProjPC1.NbPoints() ? aProjPC1.LowerDistance() : RealLast();
|
||||
Standard_Real aDist2 = aProjPC2.NbPoints() ? aProjPC2.LowerDistance() : RealLast();
|
||||
|
||||
if (aDist1 > Precision::PConfusion() && aDist2 > Precision::PConfusion())
|
||||
return Standard_False;
|
||||
|
||||
// choose the closest and take corresponding point from the opposite
|
||||
gp_Pnt2d aNewPnt = aDist1 < aDist2 ? aC2D2->Value (aProjPC1.LowerDistanceParameter()) :
|
||||
aC2D1->Value (aProjPC2.LowerDistanceParameter());
|
||||
|
||||
Handle (Geom2d_Curve) aTmpC1 = Handle (Geom2d_Curve)::DownCast (aC2DSplit->Copy());
|
||||
Handle (Geom2d_Curve) aTmpC2 = Handle (Geom2d_Curve)::DownCast (aC2DSplit->Copy());
|
||||
|
||||
Handle (Geom2d_TrimmedCurve) aC1 = new Geom2d_TrimmedCurve (aTmpC1, aTS1, aTS2);
|
||||
Handle (Geom2d_TrimmedCurve) aC2 = new Geom2d_TrimmedCurve (aTmpC2, aTS1, aTS2);
|
||||
|
||||
gp_Vec2d aTrVec (aPMid, aNewPnt);
|
||||
aC2->Translate (aTrVec);
|
||||
|
||||
gp_Pnt2d aPProj;
|
||||
gp_Vec2d aVTgtOrigin;
|
||||
if (aDist1 < aDist2)
|
||||
{
|
||||
aC2D1->D1 (aProjPC1.LowerDistanceParameter(), aPProj, aVTgtOrigin);
|
||||
}
|
||||
else
|
||||
{
|
||||
aC2D2->D1 (aProjPC2.LowerDistanceParameter(), aPProj, aVTgtOrigin);
|
||||
}
|
||||
|
||||
Standard_Real aDot = aVTgt.Dot (aVTgtOrigin);
|
||||
|
||||
if ((aDist1 < aDist2) == (aDot > 0))
|
||||
{
|
||||
BRep_Builder().UpdateEdge (aESplit, aC1, aC2, aFace, BRep_Tool::Tolerance (aESplit));
|
||||
}
|
||||
else
|
||||
{
|
||||
BRep_Builder().UpdateEdge (aESplit, aC2, aC1, aFace, BRep_Tool::Tolerance (aESplit));
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : GetNormalToFaceOnEdge
|
||||
//purpose :
|
||||
|
@@ -43,11 +43,15 @@ public:
|
||||
|
||||
DEFINE_STANDARD_ALLOC
|
||||
|
||||
|
||||
//! Makes the edge <theESplit> seam edge for the face <theFace> basing on the surface properties (U and V periods)
|
||||
Standard_EXPORT static Standard_Boolean DoSplitSEAMOnFace (const TopoDS_Edge& theESplit,
|
||||
const TopoDS_Face& theFace);
|
||||
|
||||
//! Make the edge <aSp> seam edge for the face <aF>
|
||||
Standard_EXPORT static void DoSplitSEAMOnFace (const TopoDS_Edge& aSp,
|
||||
const TopoDS_Face& aF);
|
||||
//! Makes the split edge <theESplit> seam edge for the face <theFace> basing on the positions
|
||||
//! of 2d curves of the original edge <theEOrigin>.
|
||||
Standard_EXPORT static Standard_Boolean DoSplitSEAMOnFace (const TopoDS_Edge& theEOrigin,
|
||||
const TopoDS_Edge& theESplit,
|
||||
const TopoDS_Face& theFace);
|
||||
|
||||
//! Computes normal to the face <aF> for the point on the edge <aE>
|
||||
//! at parameter <aT>.<br>
|
||||
|
Reference in New Issue
Block a user