mirror of
https://github.com/Open-Cascade-SAS/OCCT.git
synced 2026-05-11 18:32:35 +08:00
Update empty method guards to new style with regex (see PR). Used clang-format 18.1.8. New actions to validate code formatting is added. Update .clang-format with disabling of include sorting. It is temporary changes, then include will be sorted. Apply formatting for /src and /tools folder. The files with .hxx,.cxx,.lxx,.h,.pxx,.hpp,*.cpp extensions.
2265 lines
89 KiB
C++
2265 lines
89 KiB
C++
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
|
//
|
|
// This file is part of Open CASCADE Technology software library.
|
|
//
|
|
// This library is free software; you can redistribute it and/or modify it under
|
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
|
// by the Free Software Foundation, with special exception defined in the file
|
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
|
// distribution for complete text of the license and disclaimer of any warranty.
|
|
//
|
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
|
// commercial license or contractual agreement.
|
|
|
|
#include <BndLib_Add2dCurve.hxx>
|
|
#include <BRep_Builder.hxx>
|
|
#include <BRep_Tool.hxx>
|
|
#include <BRepTools.hxx>
|
|
#include <Geom2d_BSplineCurve.hxx>
|
|
#include <Geom2d_Curve.hxx>
|
|
#include <Geom2d_Line.hxx>
|
|
#include <Geom2d_TrimmedCurve.hxx>
|
|
#include <Geom2dAdaptor_Curve.hxx>
|
|
#include <Geom2dInt_GInter.hxx>
|
|
#include <Geom_Curve.hxx>
|
|
#include <Geom_Surface.hxx>
|
|
#include <gp_Pnt.hxx>
|
|
#include <IntRes2d_Domain.hxx>
|
|
#include <IntRes2d_IntersectionPoint.hxx>
|
|
#include <IntRes2d_IntersectionSegment.hxx>
|
|
#include <IntRes2d_Position.hxx>
|
|
#include <NCollection_Sequence.hxx>
|
|
#include <ShapeAnalysis_Edge.hxx>
|
|
#include <ShapeAnalysis_Surface.hxx>
|
|
#include <ShapeAnalysis_TransferParametersProj.hxx>
|
|
#include <ShapeBuild_Edge.hxx>
|
|
#include <ShapeBuild_ReShape.hxx>
|
|
#include <ShapeExtend_WireData.hxx>
|
|
#include <ShapeFix_IntersectionTool.hxx>
|
|
#include <TopExp_Explorer.hxx>
|
|
#include <TopoDS.hxx>
|
|
#include <TopoDS_Edge.hxx>
|
|
#include <TopoDS_Face.hxx>
|
|
#include <TopoDS_Iterator.hxx>
|
|
#include <TopoDS_Vertex.hxx>
|
|
#include <TopoDS_Wire.hxx>
|
|
#include <TopTools_SequenceOfShape.hxx>
|
|
|
|
// gka 06.09.04 BUG 6555 shape is modified always independently either intersection was fixed or not
|
|
//=================================================================================================
|
|
|
|
ShapeFix_IntersectionTool::ShapeFix_IntersectionTool(const Handle(ShapeBuild_ReShape)& context,
|
|
const Standard_Real preci,
|
|
const Standard_Real maxtol)
|
|
{
|
|
myContext = context;
|
|
myPreci = preci;
|
|
myMaxTol = maxtol;
|
|
}
|
|
|
|
//=======================================================================
|
|
// function : GetPointOnEdge
|
|
// purpose : auxiliary
|
|
//: h0 abv 29 May 98: PRO10105 1949: like in BRepCheck, point is to be taken
|
|
// from 3d curve (but only if edge is SameParameter)
|
|
//=======================================================================
|
|
static gp_Pnt GetPointOnEdge(const TopoDS_Edge& edge,
|
|
const Handle(ShapeAnalysis_Surface)& surf,
|
|
const Geom2dAdaptor_Curve& Crv2d,
|
|
const Standard_Real param)
|
|
{
|
|
if (BRep_Tool::SameParameter(edge))
|
|
{
|
|
Standard_Real f, l;
|
|
TopLoc_Location L;
|
|
const Handle(Geom_Curve) ConS = BRep_Tool::Curve(edge, L, f, l);
|
|
if (!ConS.IsNull())
|
|
return ConS->Value(param).Transformed(L.Transformation());
|
|
}
|
|
gp_Pnt2d aP2d = Crv2d.Value(param);
|
|
return surf->Adaptor3d()->Value(aP2d.X(), aP2d.Y());
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeFix_IntersectionTool::SplitEdge(const TopoDS_Edge& edge,
|
|
const Standard_Real param,
|
|
const TopoDS_Vertex& vert,
|
|
const TopoDS_Face& face,
|
|
TopoDS_Edge& newE1,
|
|
TopoDS_Edge& newE2,
|
|
const Standard_Real preci) const
|
|
{
|
|
Standard_Real a, b;
|
|
ShapeAnalysis_Edge sae;
|
|
|
|
TopoDS_Vertex V1 = sae.FirstVertex(edge);
|
|
TopoDS_Vertex V2 = sae.LastVertex(edge);
|
|
if (V1.IsSame(vert) || V2.IsSame(vert))
|
|
return Standard_False;
|
|
|
|
Handle(Geom2d_Curve) c2d;
|
|
sae.PCurve(edge, face, c2d, a, b, Standard_True);
|
|
if (Abs(a - param) < 0.01 * preci || Abs(b - param) < 0.01 * preci)
|
|
return Standard_False;
|
|
// check distanse between edge and new vertex
|
|
gp_Pnt P1;
|
|
TopLoc_Location L;
|
|
if (BRep_Tool::SameParameter(edge) && !BRep_Tool::Degenerated(edge))
|
|
{
|
|
Standard_Real f, l;
|
|
const Handle(Geom_Curve) c3d = BRep_Tool::Curve(edge, L, f, l);
|
|
if (c3d.IsNull())
|
|
return Standard_False;
|
|
P1 = c3d->Value(param);
|
|
if (!L.IsIdentity())
|
|
P1 = P1.Transformed(L.Transformation());
|
|
}
|
|
else
|
|
{
|
|
Handle(Geom_Surface) surf = BRep_Tool::Surface(face, L);
|
|
Handle(ShapeAnalysis_Surface) sas = new ShapeAnalysis_Surface(surf);
|
|
P1 = sas->Value(c2d->Value(param));
|
|
if (!L.IsIdentity())
|
|
P1 = P1.Transformed(L.Transformation());
|
|
}
|
|
gp_Pnt P2 = BRep_Tool::Pnt(vert);
|
|
if (P1.Distance(P2) > preci)
|
|
{
|
|
// return Standard_False;
|
|
BRep_Builder B;
|
|
B.UpdateVertex(vert, P1.Distance(P2));
|
|
}
|
|
|
|
Handle(ShapeAnalysis_TransferParametersProj) transferParameters =
|
|
new ShapeAnalysis_TransferParametersProj;
|
|
transferParameters->SetMaxTolerance(preci);
|
|
transferParameters->Init(edge, face);
|
|
Standard_Real first, last;
|
|
if (a < b)
|
|
{
|
|
first = a;
|
|
last = b;
|
|
}
|
|
else
|
|
{
|
|
first = b;
|
|
last = a;
|
|
}
|
|
|
|
ShapeBuild_Edge sbe;
|
|
TopAbs_Orientation orient = edge.Orientation();
|
|
BRep_Builder B;
|
|
TopoDS_Edge wE = edge;
|
|
wE.Orientation(TopAbs_FORWARD);
|
|
TopoDS_Shape aTmpShape = vert.Oriented(TopAbs_REVERSED); // for porting
|
|
newE1 = sbe.CopyReplaceVertices(wE, sae.FirstVertex(wE), TopoDS::Vertex(aTmpShape));
|
|
sbe.CopyPCurves(newE1, wE);
|
|
transferParameters->TransferRange(newE1, first, param, Standard_True);
|
|
B.SameRange(newE1, Standard_False);
|
|
B.SameParameter(newE1, Standard_False);
|
|
aTmpShape = vert.Oriented(TopAbs_FORWARD);
|
|
newE2 = sbe.CopyReplaceVertices(wE, TopoDS::Vertex(aTmpShape), sae.LastVertex(wE));
|
|
sbe.CopyPCurves(newE2, wE);
|
|
transferParameters->TransferRange(newE2, param, last, Standard_True);
|
|
B.SameRange(newE2, Standard_False);
|
|
B.SameParameter(newE2, Standard_False);
|
|
|
|
newE1.Orientation(orient);
|
|
newE2.Orientation(orient);
|
|
if (orient == TopAbs_REVERSED)
|
|
{
|
|
TopoDS_Edge tmp = newE2;
|
|
newE2 = newE1;
|
|
newE1 = tmp;
|
|
}
|
|
|
|
return Standard_True;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeFix_IntersectionTool::CutEdge(const TopoDS_Edge& edge,
|
|
const Standard_Real pend,
|
|
const Standard_Real cut,
|
|
const TopoDS_Face& face,
|
|
Standard_Boolean& iscutline) const
|
|
{
|
|
if (Abs(cut - pend) < 10. * Precision::PConfusion())
|
|
return Standard_False;
|
|
Standard_Real aRange = Abs(cut - pend);
|
|
Standard_Real a, b;
|
|
BRep_Tool::Range(edge, a, b);
|
|
|
|
if (aRange < 10. * Precision::PConfusion())
|
|
return Standard_False;
|
|
|
|
// case pcurve is trimm of line
|
|
if (!BRep_Tool::SameParameter(edge))
|
|
{
|
|
ShapeAnalysis_Edge sae;
|
|
Handle(Geom2d_Curve) Crv;
|
|
Standard_Real fp, lp;
|
|
if (sae.PCurve(edge, face, Crv, fp, lp, Standard_False))
|
|
{
|
|
if (Crv->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)))
|
|
{
|
|
Handle(Geom2d_TrimmedCurve) tc = Handle(Geom2d_TrimmedCurve)::DownCast(Crv);
|
|
if (tc->BasisCurve()->IsKind(STANDARD_TYPE(Geom2d_Line)))
|
|
{
|
|
BRep_Builder B;
|
|
B.Range(edge, Min(pend, cut), Max(pend, cut));
|
|
if (Abs(pend - lp) < Precision::PConfusion())
|
|
{ // cut from the beginning
|
|
Standard_Real cut3d = (cut - fp) * (b - a) / (lp - fp);
|
|
B.Range(edge, a + cut3d, b, Standard_True);
|
|
iscutline = Standard_True;
|
|
}
|
|
else if (Abs(pend - fp) < Precision::PConfusion())
|
|
{ // cut from the end
|
|
Standard_Real cut3d = (lp - cut) * (b - a) / (lp - fp);
|
|
B.Range(edge, a, b - cut3d, Standard_True);
|
|
iscutline = Standard_True;
|
|
}
|
|
}
|
|
|
|
return Standard_True;
|
|
}
|
|
}
|
|
return Standard_False;
|
|
}
|
|
|
|
// det-study on 03/12/01 checking the old and new ranges
|
|
if (Abs(Abs(a - b) - aRange) < Precision::PConfusion())
|
|
return Standard_False;
|
|
if (aRange < 10. * Precision::PConfusion())
|
|
return Standard_False;
|
|
|
|
BRep_Builder B;
|
|
B.Range(edge, Min(pend, cut), Max(pend, cut));
|
|
|
|
return Standard_True;
|
|
}
|
|
|
|
//=======================================================================
|
|
// function : SplitEdge1
|
|
// purpose : split edge[a,b] om two part e1[a,param]
|
|
// and e2[param,b] using vertex vert
|
|
//=======================================================================
|
|
|
|
Standard_Boolean ShapeFix_IntersectionTool::SplitEdge1(const Handle(ShapeExtend_WireData)& sewd,
|
|
const TopoDS_Face& face,
|
|
const Standard_Integer num,
|
|
const Standard_Real param,
|
|
const TopoDS_Vertex& vert,
|
|
const Standard_Real preci,
|
|
ShapeFix_DataMapOfShapeBox2d& boxes) const
|
|
{
|
|
Standard_ASSERT_RETURN(num > 0 && num <= sewd->NbEdges(),
|
|
"Edge index out of range",
|
|
Standard_False);
|
|
|
|
TopoDS_Edge edge = sewd->Edge(num);
|
|
TopoDS_Edge newE1, newE2;
|
|
if (!SplitEdge(edge, param, vert, face, newE1, newE2, preci))
|
|
return Standard_False;
|
|
|
|
// change context
|
|
Handle(ShapeExtend_WireData) wd = new ShapeExtend_WireData;
|
|
wd->Add(newE1);
|
|
wd->Add(newE2);
|
|
if (!myContext.IsNull())
|
|
myContext->Replace(edge, wd->Wire());
|
|
for (TopExp_Explorer exp(wd->Wire(), TopAbs_EDGE); exp.More(); exp.Next())
|
|
{
|
|
TopoDS_Edge E = TopoDS::Edge(exp.Current());
|
|
BRepTools::Update(E);
|
|
}
|
|
|
|
// change sewd
|
|
sewd->Set(newE1, num);
|
|
if (num == sewd->NbEdges())
|
|
sewd->Add(newE2);
|
|
else
|
|
sewd->Add(newE2, num + 1);
|
|
|
|
// change boxes
|
|
boxes.UnBind(edge);
|
|
TopLoc_Location L;
|
|
const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
|
|
Handle(Geom2d_Curve) c2d;
|
|
Standard_Real cf, cl;
|
|
ShapeAnalysis_Edge sae;
|
|
if (sae.PCurve(newE1, S, L, c2d, cf, cl, Standard_False))
|
|
{
|
|
Bnd_Box2d box;
|
|
Geom2dAdaptor_Curve gac;
|
|
Standard_Real aFirst = c2d->FirstParameter();
|
|
Standard_Real aLast = c2d->LastParameter();
|
|
if (c2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve)) && (cf < aFirst || cl > aLast))
|
|
{
|
|
// pdn avoiding problems with segment in Bnd_Box
|
|
gac.Load(c2d);
|
|
}
|
|
else
|
|
gac.Load(c2d, cf, cl);
|
|
BndLib_Add2dCurve::Add(gac, ::Precision::Confusion(), box);
|
|
boxes.Bind(newE1, box);
|
|
}
|
|
if (sae.PCurve(newE2, S, L, c2d, cf, cl, Standard_False))
|
|
{
|
|
Bnd_Box2d box;
|
|
Geom2dAdaptor_Curve gac;
|
|
Standard_Real aFirst = c2d->FirstParameter();
|
|
Standard_Real aLast = c2d->LastParameter();
|
|
if (c2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve)) && (cf < aFirst || cl > aLast))
|
|
{
|
|
// pdn avoiding problems with segment in Bnd_Box
|
|
gac.Load(c2d);
|
|
}
|
|
else
|
|
gac.Load(c2d, cf, cl);
|
|
BndLib_Add2dCurve::Add(gac, ::Precision::Confusion(), box);
|
|
boxes.Bind(newE2, box);
|
|
}
|
|
|
|
return Standard_True;
|
|
}
|
|
|
|
//=======================================================================
|
|
// function : SplitEdge2
|
|
// purpose : auxiliary: split edge[a,b] om two part e1[a,param1]
|
|
// and e2[param2,b] using vertex vert
|
|
// (remove segment (param1,param2) from edge)
|
|
//=======================================================================
|
|
|
|
Standard_Boolean ShapeFix_IntersectionTool::SplitEdge2(const Handle(ShapeExtend_WireData)& sewd,
|
|
const TopoDS_Face& face,
|
|
const Standard_Integer num,
|
|
const Standard_Real param1,
|
|
const Standard_Real param2,
|
|
const TopoDS_Vertex& vert,
|
|
const Standard_Real preci,
|
|
ShapeFix_DataMapOfShapeBox2d& boxes) const
|
|
{
|
|
TopoDS_Edge edge = sewd->Edge(num);
|
|
TopoDS_Edge newE1, newE2;
|
|
Standard_Real param = (param1 + param2) / 2;
|
|
if (!SplitEdge(edge, param, vert, face, newE1, newE2, preci))
|
|
return Standard_False;
|
|
// cut new edges by param1 and param2
|
|
Standard_Boolean IsCutLine;
|
|
Handle(Geom2d_Curve) Crv1, Crv2;
|
|
Standard_Real fp1, lp1, fp2, lp2;
|
|
ShapeAnalysis_Edge sae;
|
|
if (sae.PCurve(newE1, face, Crv1, fp1, lp1, Standard_False))
|
|
{
|
|
if (sae.PCurve(newE2, face, Crv2, fp2, lp2, Standard_False))
|
|
{
|
|
if (lp1 == param)
|
|
{
|
|
if ((lp1 - fp1) * (lp1 - param1) > 0)
|
|
{
|
|
CutEdge(newE1, fp1, param1, face, IsCutLine);
|
|
CutEdge(newE2, lp2, param2, face, IsCutLine);
|
|
}
|
|
else
|
|
{
|
|
CutEdge(newE1, fp1, param2, face, IsCutLine);
|
|
CutEdge(newE2, lp2, param1, face, IsCutLine);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ((fp1 - lp1) * (fp1 - param1) > 0)
|
|
{
|
|
CutEdge(newE1, lp1, param1, face, IsCutLine);
|
|
CutEdge(newE2, fp2, param2, face, IsCutLine);
|
|
}
|
|
else
|
|
{
|
|
CutEdge(newE1, lp1, param2, face, IsCutLine);
|
|
CutEdge(newE2, fp2, param1, face, IsCutLine);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// change context
|
|
Handle(ShapeExtend_WireData) wd = new ShapeExtend_WireData;
|
|
wd->Add(newE1);
|
|
wd->Add(newE2);
|
|
if (!myContext.IsNull())
|
|
myContext->Replace(edge, wd->Wire());
|
|
for (TopExp_Explorer exp(wd->Wire(), TopAbs_EDGE); exp.More(); exp.Next())
|
|
{
|
|
TopoDS_Edge E = TopoDS::Edge(exp.Current());
|
|
BRepTools::Update(E);
|
|
}
|
|
|
|
// change sewd
|
|
sewd->Set(newE1, num);
|
|
if (num == sewd->NbEdges())
|
|
sewd->Add(newE2);
|
|
else
|
|
sewd->Add(newE2, num + 1);
|
|
|
|
// change boxes
|
|
boxes.UnBind(edge);
|
|
TopLoc_Location L;
|
|
const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
|
|
Handle(Geom2d_Curve) c2d;
|
|
Standard_Real cf, cl;
|
|
if (sae.PCurve(newE1, S, L, c2d, cf, cl, Standard_False))
|
|
{
|
|
Bnd_Box2d box;
|
|
Geom2dAdaptor_Curve gac;
|
|
Standard_Real aFirst = c2d->FirstParameter();
|
|
Standard_Real aLast = c2d->LastParameter();
|
|
if (c2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve)) && (cf < aFirst || cl > aLast))
|
|
{
|
|
// pdn avoiding problems with segment in Bnd_Box
|
|
gac.Load(c2d);
|
|
}
|
|
else
|
|
gac.Load(c2d, cf, cl);
|
|
BndLib_Add2dCurve::Add(gac, ::Precision::Confusion(), box);
|
|
boxes.Bind(newE1, box);
|
|
}
|
|
if (sae.PCurve(newE2, S, L, c2d, cf, cl, Standard_False))
|
|
{
|
|
Bnd_Box2d box;
|
|
Geom2dAdaptor_Curve gac;
|
|
Standard_Real aFirst = c2d->FirstParameter();
|
|
Standard_Real aLast = c2d->LastParameter();
|
|
if (c2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve)) && (cf < aFirst || cl > aLast))
|
|
{
|
|
// pdn avoiding problems with segment in Bnd_Box
|
|
gac.Load(c2d);
|
|
}
|
|
else
|
|
gac.Load(c2d, cf, cl);
|
|
BndLib_Add2dCurve::Add(gac, ::Precision::Confusion(), box);
|
|
boxes.Bind(newE2, box);
|
|
}
|
|
|
|
return Standard_True;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeFix_IntersectionTool::UnionVertexes(const Handle(ShapeExtend_WireData)& sewd,
|
|
TopoDS_Edge& edge1,
|
|
TopoDS_Edge& edge2,
|
|
const Standard_Integer num2,
|
|
ShapeFix_DataMapOfShapeBox2d& boxes,
|
|
const Bnd_Box2d& B2) const
|
|
{
|
|
// union vertexes
|
|
Standard_Boolean res = Standard_False;
|
|
ShapeBuild_Edge sbe;
|
|
ShapeAnalysis_Edge sae;
|
|
BRep_Builder B;
|
|
TopoDS_Vertex V;
|
|
TopoDS_Vertex V1F = sae.FirstVertex(edge1);
|
|
gp_Pnt PV1F = BRep_Tool::Pnt(V1F);
|
|
TopoDS_Vertex V1L = sae.LastVertex(edge1);
|
|
gp_Pnt PV1L = BRep_Tool::Pnt(V1L);
|
|
TopoDS_Vertex V2F = sae.FirstVertex(edge2);
|
|
gp_Pnt PV2F = BRep_Tool::Pnt(V2F);
|
|
TopoDS_Vertex V2L = sae.LastVertex(edge2);
|
|
gp_Pnt PV2L = BRep_Tool::Pnt(V2L);
|
|
Standard_Real d11 = PV1F.Distance(PV2F);
|
|
Standard_Real d12 = PV1F.Distance(PV2L);
|
|
Standard_Real d21 = PV1L.Distance(PV2F);
|
|
Standard_Real d22 = PV1L.Distance(PV2L);
|
|
if (d11 < d12 && d11 < d21 && d11 < d22)
|
|
{
|
|
Standard_Real tolv = Max(BRep_Tool::Tolerance(V1F), BRep_Tool::Tolerance(V2F));
|
|
if (!V2F.IsSame(V1F) && d11 < tolv)
|
|
{
|
|
// union vertexes V1F and V2F
|
|
B.UpdateVertex(V1F, tolv);
|
|
TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2, V1F, V2L);
|
|
// std::cout<<"union vertexes V1F and V2F"<<std::endl;
|
|
// gp_Pnt Ptmp = BRep_Tool::Pnt(V1F);
|
|
// B.MakeVertex(V,Ptmp,tolv);
|
|
// myContext->Replace(V1F,V);
|
|
// myContext->Replace(V2F,V);
|
|
// TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V,V2L);
|
|
myContext->Replace(edge2, NewE);
|
|
sewd->Set(NewE, num2);
|
|
edge2 = NewE;
|
|
boxes.Bind(NewE, B2); // update boxes
|
|
// replace vertex in other edge
|
|
Standard_Integer num21, num22;
|
|
if (num2 > 1)
|
|
num21 = num2 - 1;
|
|
else
|
|
num21 = sewd->NbEdges();
|
|
if (num2 < sewd->NbEdges())
|
|
num22 = num2 + 1;
|
|
else
|
|
num22 = 1;
|
|
TopoDS_Edge edge21 = sewd->Edge(num21);
|
|
TopoDS_Edge edge22 = sewd->Edge(num22);
|
|
TopoDS_Vertex V21F = sae.FirstVertex(edge21);
|
|
TopoDS_Vertex V21L = sae.LastVertex(edge21);
|
|
TopoDS_Vertex V22F = sae.FirstVertex(edge22);
|
|
TopoDS_Vertex V22L = sae.LastVertex(edge22);
|
|
if (V21F.IsSame(V2F))
|
|
{
|
|
NewE = sbe.CopyReplaceVertices(edge21, V1F, V21L);
|
|
// NewE = sbe.CopyReplaceVertices(edge21,V,V21L);
|
|
if (boxes.IsBound(edge21))
|
|
boxes.Bind(NewE, boxes.Find(edge21)); // update boxes
|
|
myContext->Replace(edge21, NewE);
|
|
sewd->Set(NewE, num21);
|
|
}
|
|
if (V21L.IsSame(V2F))
|
|
{
|
|
NewE = sbe.CopyReplaceVertices(edge21, V21F, V1F);
|
|
// NewE = sbe.CopyReplaceVertices(edge21,V21F,V);
|
|
if (boxes.IsBound(edge21))
|
|
boxes.Bind(NewE, boxes.Find(edge21)); // update boxes
|
|
myContext->Replace(edge21, NewE);
|
|
sewd->Set(NewE, num21);
|
|
}
|
|
if (V22F.IsSame(V2F))
|
|
{
|
|
NewE = sbe.CopyReplaceVertices(edge22, V1F, V22L);
|
|
// NewE = sbe.CopyReplaceVertices(edge22,V,V22L);
|
|
if (boxes.IsBound(edge22))
|
|
boxes.Bind(NewE, boxes.Find(edge22)); // update boxes
|
|
myContext->Replace(edge22, NewE);
|
|
sewd->Set(NewE, num22);
|
|
}
|
|
if (V22L.IsSame(V2F))
|
|
{
|
|
NewE = sbe.CopyReplaceVertices(edge22, V22F, V1F);
|
|
// NewE = sbe.CopyReplaceVertices(edge22,V22F,V);
|
|
if (boxes.IsBound(edge22))
|
|
boxes.Bind(NewE, boxes.Find(edge22)); // update boxes
|
|
myContext->Replace(edge22, NewE);
|
|
sewd->Set(NewE, num22);
|
|
}
|
|
res = Standard_True;
|
|
}
|
|
}
|
|
else if (d12 < d21 && d12 < d22)
|
|
{
|
|
Standard_Real tolv = Max(BRep_Tool::Tolerance(V1F), BRep_Tool::Tolerance(V2L));
|
|
if (!V2L.IsSame(V1F) && d12 < tolv)
|
|
{
|
|
// union vertexes V1F and V2L
|
|
B.UpdateVertex(V1F, tolv);
|
|
TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2, V2F, V1F);
|
|
// std::cout<<"union vertexes V1F and V2L"<<std::endl;
|
|
// gp_Pnt Ptmp = BRep_Tool::Pnt(V1F);
|
|
// B.MakeVertex(V,Ptmp,tolv);
|
|
// myContext->Replace(V1F,V);
|
|
// myContext->Replace(V2L,V);
|
|
// TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V2F,V);
|
|
myContext->Replace(edge2, NewE);
|
|
sewd->Set(NewE, num2);
|
|
edge2 = NewE;
|
|
// boxes.Bind(NewE,boxes.Find(edge2)); // update boxes
|
|
boxes.Bind(NewE, B2); // update boxes
|
|
// replace vertex in other edge
|
|
Standard_Integer num21, num22;
|
|
if (num2 > 1)
|
|
num21 = num2 - 1;
|
|
else
|
|
num21 = sewd->NbEdges();
|
|
if (num2 < sewd->NbEdges())
|
|
num22 = num2 + 1;
|
|
else
|
|
num22 = 1;
|
|
TopoDS_Edge edge21 = sewd->Edge(num21);
|
|
TopoDS_Edge edge22 = sewd->Edge(num22);
|
|
TopoDS_Vertex V21F = sae.FirstVertex(edge21);
|
|
TopoDS_Vertex V21L = sae.LastVertex(edge21);
|
|
TopoDS_Vertex V22F = sae.FirstVertex(edge22);
|
|
TopoDS_Vertex V22L = sae.LastVertex(edge22);
|
|
if (V21F.IsSame(V2L))
|
|
{
|
|
NewE = sbe.CopyReplaceVertices(edge21, V1F, V21L);
|
|
// NewE = sbe.CopyReplaceVertices(edge21,V,V21L);
|
|
if (boxes.IsBound(edge21))
|
|
boxes.Bind(NewE, boxes.Find(edge21)); // update boxes
|
|
myContext->Replace(edge21, NewE);
|
|
sewd->Set(NewE, num21);
|
|
}
|
|
if (V21L.IsSame(V2L))
|
|
{
|
|
NewE = sbe.CopyReplaceVertices(edge21, V21F, V1F);
|
|
// NewE = sbe.CopyReplaceVertices(edge21,V21F,V);
|
|
if (boxes.IsBound(edge21))
|
|
boxes.Bind(NewE, boxes.Find(edge21)); // update boxes
|
|
myContext->Replace(edge21, NewE);
|
|
sewd->Set(NewE, num21);
|
|
}
|
|
if (V22F.IsSame(V2L))
|
|
{
|
|
NewE = sbe.CopyReplaceVertices(edge22, V1F, V22L);
|
|
// NewE = sbe.CopyReplaceVertices(edge22,V,V22L);
|
|
if (boxes.IsBound(edge22))
|
|
boxes.Bind(NewE, boxes.Find(edge22)); // update boxes
|
|
myContext->Replace(edge22, NewE);
|
|
sewd->Set(NewE, num22);
|
|
}
|
|
if (V22L.IsSame(V2L))
|
|
{
|
|
NewE = sbe.CopyReplaceVertices(edge22, V22F, V1F);
|
|
// NewE = sbe.CopyReplaceVertices(edge22,V22F,V);
|
|
if (boxes.IsBound(edge22))
|
|
boxes.Bind(NewE, boxes.Find(edge22)); // update boxes
|
|
myContext->Replace(edge22, NewE);
|
|
sewd->Set(NewE, num22);
|
|
}
|
|
res = Standard_True;
|
|
}
|
|
}
|
|
else if (d21 < d22)
|
|
{
|
|
Standard_Real tolv = Max(BRep_Tool::Tolerance(V1L), BRep_Tool::Tolerance(V2F));
|
|
if (!V2F.IsSame(V1L) && d21 < tolv)
|
|
{
|
|
// union vertexes V1L and V2F
|
|
B.UpdateVertex(V1L, tolv);
|
|
TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2, V1L, V2L);
|
|
// std::cout<<"union vertexes V1L and V2F"<<std::endl;
|
|
// gp_Pnt Ptmp = BRep_Tool::Pnt(V1L);
|
|
// B.MakeVertex(V,Ptmp,tolv);
|
|
// myContext->Replace(V1L,V);
|
|
// myContext->Replace(V2F,V);
|
|
// TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V,V2L);
|
|
myContext->Replace(edge2, NewE);
|
|
sewd->Set(NewE, num2);
|
|
edge2 = NewE;
|
|
boxes.Bind(NewE, B2); // update boxes
|
|
// replace vertex in other edge
|
|
Standard_Integer num21, num22;
|
|
if (num2 > 1)
|
|
num21 = num2 - 1;
|
|
else
|
|
num21 = sewd->NbEdges();
|
|
if (num2 < sewd->NbEdges())
|
|
num22 = num2 + 1;
|
|
else
|
|
num22 = 1;
|
|
TopoDS_Edge edge21 = sewd->Edge(num21);
|
|
TopoDS_Edge edge22 = sewd->Edge(num22);
|
|
TopoDS_Vertex V21F = sae.FirstVertex(edge21);
|
|
TopoDS_Vertex V21L = sae.LastVertex(edge21);
|
|
TopoDS_Vertex V22F = sae.FirstVertex(edge22);
|
|
TopoDS_Vertex V22L = sae.LastVertex(edge22);
|
|
if (V21F.IsSame(V2F))
|
|
{
|
|
NewE = sbe.CopyReplaceVertices(edge21, V1L, V21L);
|
|
// NewE = sbe.CopyReplaceVertices(edge21,V,V21L);
|
|
if (boxes.IsBound(edge21))
|
|
boxes.Bind(NewE, boxes.Find(edge21)); // update boxes
|
|
myContext->Replace(edge21, NewE);
|
|
sewd->Set(NewE, num21);
|
|
}
|
|
if (V21L.IsSame(V2F))
|
|
{
|
|
NewE = sbe.CopyReplaceVertices(edge21, V21F, V1L);
|
|
// NewE = sbe.CopyReplaceVertices(edge21,V21F,V);
|
|
if (boxes.IsBound(edge21))
|
|
boxes.Bind(NewE, boxes.Find(edge21)); // update boxes
|
|
myContext->Replace(edge21, NewE);
|
|
sewd->Set(NewE, num21);
|
|
}
|
|
if (V22F.IsSame(V2F))
|
|
{
|
|
NewE = sbe.CopyReplaceVertices(edge22, V1L, V22L);
|
|
// NewE = sbe.CopyReplaceVertices(edge22,V,V22L);
|
|
if (boxes.IsBound(edge22))
|
|
boxes.Bind(NewE, boxes.Find(edge22)); // update boxes
|
|
myContext->Replace(edge22, NewE);
|
|
sewd->Set(NewE, num22);
|
|
}
|
|
if (V22L.IsSame(V2F))
|
|
{
|
|
NewE = sbe.CopyReplaceVertices(edge22, V22F, V1L);
|
|
// NewE = sbe.CopyReplaceVertices(edge22,V22F,V);
|
|
if (boxes.IsBound(edge22))
|
|
boxes.Bind(NewE, boxes.Find(edge22)); // update boxes
|
|
myContext->Replace(edge22, NewE);
|
|
sewd->Set(NewE, num22);
|
|
}
|
|
res = Standard_True;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Standard_Real tolv = Max(BRep_Tool::Tolerance(V1L), BRep_Tool::Tolerance(V2L));
|
|
if (!V2L.IsSame(V1L) && d22 < tolv)
|
|
{
|
|
// union vertexes V1L and V2L
|
|
B.UpdateVertex(V1L, tolv);
|
|
TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2, V2F, V1L);
|
|
// std::cout<<"union vertexes V1L and V2L"<<std::endl;
|
|
// gp_Pnt Ptmp = BRep_Tool::Pnt(V1L);
|
|
// B.MakeVertex(V,Ptmp,tolv);
|
|
// myContext->Replace(V1L,V);
|
|
// myContext->Replace(V2L,V);
|
|
// TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V2F,V);
|
|
myContext->Replace(edge2, NewE);
|
|
sewd->Set(NewE, num2);
|
|
edge2 = NewE;
|
|
boxes.Bind(NewE, B2); // update boxes
|
|
// replace vertex in other edge
|
|
Standard_Integer num21, num22;
|
|
if (num2 > 1)
|
|
num21 = num2 - 1;
|
|
else
|
|
num21 = sewd->NbEdges();
|
|
if (num2 < sewd->NbEdges())
|
|
num22 = num2 + 1;
|
|
else
|
|
num22 = 1;
|
|
TopoDS_Edge edge21 = sewd->Edge(num21);
|
|
TopoDS_Edge edge22 = sewd->Edge(num22);
|
|
TopoDS_Vertex V21F = sae.FirstVertex(edge21);
|
|
TopoDS_Vertex V21L = sae.LastVertex(edge21);
|
|
TopoDS_Vertex V22F = sae.FirstVertex(edge22);
|
|
TopoDS_Vertex V22L = sae.LastVertex(edge22);
|
|
if (V21F.IsSame(V2L))
|
|
{
|
|
NewE = sbe.CopyReplaceVertices(edge21, V1L, V21L);
|
|
// NewE = sbe.CopyReplaceVertices(edge21,V,V21L);
|
|
if (boxes.IsBound(edge21))
|
|
boxes.Bind(NewE, boxes.Find(edge21)); // update boxes
|
|
myContext->Replace(edge21, NewE);
|
|
sewd->Set(NewE, num21);
|
|
}
|
|
if (V21L.IsSame(V2L))
|
|
{
|
|
NewE = sbe.CopyReplaceVertices(edge21, V21F, V1L);
|
|
// NewE = sbe.CopyReplaceVertices(edge21,V21F,V);
|
|
if (boxes.IsBound(edge21))
|
|
boxes.Bind(NewE, boxes.Find(edge21)); // update boxes
|
|
myContext->Replace(edge21, NewE);
|
|
sewd->Set(NewE, num21);
|
|
}
|
|
if (V22F.IsSame(V2L))
|
|
{
|
|
NewE = sbe.CopyReplaceVertices(edge22, V1L, V22L);
|
|
// NewE = sbe.CopyReplaceVertices(edge22,V,V22L);
|
|
if (boxes.IsBound(edge22))
|
|
boxes.Bind(NewE, boxes.Find(edge22)); // update boxes
|
|
myContext->Replace(edge22, NewE);
|
|
sewd->Set(NewE, num22);
|
|
}
|
|
if (V22L.IsSame(V2L))
|
|
{
|
|
NewE = sbe.CopyReplaceVertices(edge22, V22F, V1L);
|
|
// NewE = sbe.CopyReplaceVertices(edge22,V22F,V);
|
|
if (boxes.IsBound(edge22))
|
|
boxes.Bind(NewE, boxes.Find(edge22)); // update boxes
|
|
myContext->Replace(edge22, NewE);
|
|
sewd->Set(NewE, num22);
|
|
}
|
|
res = Standard_True;
|
|
}
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
static Bnd_Box2d CreateBoxes2d(const Handle(ShapeExtend_WireData)& sewd,
|
|
const TopoDS_Face& face,
|
|
ShapeFix_DataMapOfShapeBox2d& boxes)
|
|
{
|
|
// create box2d for edges from wire
|
|
Bnd_Box2d aTotalBox;
|
|
TopLoc_Location L;
|
|
const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
|
|
Handle(Geom2d_Curve) c2d;
|
|
Standard_Real cf, cl;
|
|
ShapeAnalysis_Edge sae;
|
|
for (Standard_Integer i = 1; i <= sewd->NbEdges(); i++)
|
|
{
|
|
TopoDS_Edge E = sewd->Edge(i);
|
|
if (sae.PCurve(E, S, L, c2d, cf, cl, Standard_False))
|
|
{
|
|
Bnd_Box2d box;
|
|
Geom2dAdaptor_Curve gac;
|
|
Standard_Real aFirst = c2d->FirstParameter();
|
|
Standard_Real aLast = c2d->LastParameter();
|
|
if (c2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve)) && (cf < aFirst || cl > aLast))
|
|
{
|
|
// pdn avoiding problems with segment in Bnd_Box
|
|
gac.Load(c2d);
|
|
}
|
|
else
|
|
gac.Load(c2d, cf, cl);
|
|
BndLib_Add2dCurve::Add(gac, ::Precision::Confusion(), box);
|
|
boxes.Bind(E, box);
|
|
aTotalBox.Add(box);
|
|
}
|
|
}
|
|
return aTotalBox;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
static void SelectIntPnt(const Geom2dInt_GInter& Inter,
|
|
IntRes2d_IntersectionPoint& IP,
|
|
IntRes2d_Transition& Tr1,
|
|
IntRes2d_Transition& Tr2)
|
|
{
|
|
IP = Inter.Point(1);
|
|
Tr1 = IP.TransitionOfFirst();
|
|
Tr2 = IP.TransitionOfSecond();
|
|
if (Inter.NbPoints() == 2)
|
|
{
|
|
// possible second point is better?
|
|
Standard_Integer status1 = 0, status2 = 0;
|
|
if (Tr1.PositionOnCurve() == IntRes2d_Middle)
|
|
status1 += 1;
|
|
if (Tr2.PositionOnCurve() == IntRes2d_Middle)
|
|
status1 += 2;
|
|
IntRes2d_IntersectionPoint IP2;
|
|
IntRes2d_Transition Tr12, Tr22;
|
|
IP2 = Inter.Point(2);
|
|
Tr12 = IP2.TransitionOfFirst();
|
|
Tr22 = IP2.TransitionOfSecond();
|
|
if (Tr12.PositionOnCurve() == IntRes2d_Middle)
|
|
status2 += 1;
|
|
if (Tr22.PositionOnCurve() == IntRes2d_Middle)
|
|
status2 += 2;
|
|
if (status2 > status1)
|
|
{
|
|
IP = IP2;
|
|
Tr1 = Tr12;
|
|
Tr2 = Tr22;
|
|
}
|
|
}
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeFix_IntersectionTool::FindVertAndSplitEdge(
|
|
const Standard_Real param1,
|
|
const TopoDS_Edge& edge1,
|
|
const TopoDS_Edge& edge2,
|
|
const Handle(Geom2d_Curve)& Crv1,
|
|
Standard_Real& MaxTolVert,
|
|
Standard_Integer& num1,
|
|
const Handle(ShapeExtend_WireData)& sewd,
|
|
const TopoDS_Face& face,
|
|
ShapeFix_DataMapOfShapeBox2d& boxes,
|
|
const Standard_Boolean aTmpKey) const
|
|
{
|
|
// find needed vertex from edge2 and split edge1 using it
|
|
ShapeAnalysis_Edge sae;
|
|
Handle(ShapeAnalysis_Surface) sas = new ShapeAnalysis_Surface(BRep_Tool::Surface(face));
|
|
gp_Pnt pi1 = GetPointOnEdge(edge1, sas, Crv1, param1);
|
|
BRep_Builder B;
|
|
TopoDS_Vertex V;
|
|
Standard_Real tolV;
|
|
TopoDS_Vertex V1 = sae.FirstVertex(edge2);
|
|
gp_Pnt PV1 = BRep_Tool::Pnt(V1);
|
|
TopoDS_Vertex V2 = sae.LastVertex(edge2);
|
|
gp_Pnt PV2 = BRep_Tool::Pnt(V2);
|
|
TopoDS_Vertex V11 = sae.FirstVertex(edge1);
|
|
TopoDS_Vertex V12 = sae.LastVertex(edge1);
|
|
Standard_Boolean NeedSplit = Standard_True;
|
|
if (pi1.Distance(PV1) < pi1.Distance(PV2))
|
|
{
|
|
if (V1.IsSame(V11) || V1.IsSame(V12))
|
|
{
|
|
NeedSplit = Standard_False;
|
|
}
|
|
V = V1;
|
|
tolV = Max((pi1.Distance(PV1) / 2) * 1.00001, BRep_Tool::Tolerance(V1));
|
|
}
|
|
else
|
|
{
|
|
if (V2.IsSame(V11) || V2.IsSame(V12))
|
|
{
|
|
NeedSplit = Standard_False;
|
|
}
|
|
V = V2;
|
|
tolV = Max((pi1.Distance(PV2) / 2) * 1.00001, BRep_Tool::Tolerance(V2));
|
|
}
|
|
if (NeedSplit || aTmpKey)
|
|
{
|
|
if (SplitEdge1(sewd, face, num1, param1, V, tolV, boxes))
|
|
{
|
|
B.UpdateVertex(V, tolV);
|
|
MaxTolVert = Max(MaxTolVert, tolV);
|
|
// NbSplit++;
|
|
num1--;
|
|
return Standard_True;
|
|
// break;
|
|
}
|
|
}
|
|
return Standard_False;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeFix_IntersectionTool::FixSelfIntersectWire(Handle(ShapeExtend_WireData)& sewd,
|
|
const TopoDS_Face& face,
|
|
Standard_Integer& NbSplit,
|
|
Standard_Integer& NbCut,
|
|
Standard_Integer& NbRemoved) const
|
|
{
|
|
if (myContext.IsNull() || face.IsNull())
|
|
return Standard_False;
|
|
|
|
// Standard_Real area2d = ShapeAnalysis::TotCross2D(sewd,face);
|
|
// if(area2d<Precision::PConfusion()*Precision::PConfusion()) return Standard_False; //gka
|
|
// 06.09.04 BUG 6555
|
|
|
|
TopoDS_Shape SF = Context()->Apply(face);
|
|
Standard_Real MaxTolVert = 0.0;
|
|
for (TopExp_Explorer exp(SF, TopAbs_VERTEX); exp.More(); exp.Next())
|
|
{
|
|
Standard_Real tolV = BRep_Tool::Tolerance(TopoDS::Vertex(exp.Current()));
|
|
MaxTolVert = Max(MaxTolVert, tolV);
|
|
}
|
|
MaxTolVert = Min(MaxTolVert, myMaxTol);
|
|
ShapeAnalysis_Edge sae;
|
|
|
|
// step 1 : intersection of adjacent edges
|
|
|
|
// step 2 : intersection of non-adjacent edges
|
|
ShapeFix_DataMapOfShapeBox2d boxes;
|
|
(void)CreateBoxes2d(sewd, face, boxes);
|
|
Handle(ShapeAnalysis_Surface) sas = new ShapeAnalysis_Surface(BRep_Tool::Surface(face));
|
|
|
|
NbSplit = 0;
|
|
NbCut = 0;
|
|
Standard_Integer nbReplaced = 0;
|
|
Standard_Boolean isDone = Standard_False;
|
|
for (Standard_Integer num1 = 1; num1 < sewd->NbEdges() && NbSplit < 30; num1++)
|
|
{
|
|
// for each edge from first wire
|
|
for (Standard_Integer num2 = num1 + 2; num2 <= sewd->NbEdges() && NbSplit < 30; num2++)
|
|
{
|
|
// for each edge from second wire
|
|
if (num1 == 1 && num2 == sewd->NbEdges())
|
|
continue;
|
|
TopoDS_Edge edge1 = sewd->Edge(num1);
|
|
TopoDS_Edge edge2 = sewd->Edge(num2);
|
|
if (edge1.IsSame(edge2))
|
|
continue;
|
|
if (BRep_Tool::Degenerated(edge1) || BRep_Tool::Degenerated(edge2))
|
|
continue;
|
|
if (!boxes.IsBound(edge1) || !boxes.IsBound(edge2))
|
|
continue;
|
|
Bnd_Box2d B1 = boxes.Find(edge1);
|
|
Bnd_Box2d B2 = boxes.Find(edge2);
|
|
if (!B1.IsOut(B2))
|
|
{
|
|
// intersection is possible...
|
|
Standard_Real a1, b1, a2, b2;
|
|
Handle(Geom2d_Curve) Crv1, Crv2;
|
|
if (!sae.PCurve(edge1, face, Crv1, a1, b1, Standard_False))
|
|
return Standard_False;
|
|
if (!sae.PCurve(edge2, face, Crv2, a2, b2, Standard_False))
|
|
return Standard_False;
|
|
Standard_Real tolint = 1.0e-10;
|
|
Geom2dAdaptor_Curve C1(Crv1), C2(Crv2);
|
|
IntRes2d_Domain d1(C1.Value(a1), a1, tolint, C1.Value(b1), b1, tolint);
|
|
IntRes2d_Domain d2(C2.Value(a2), a2, tolint, C2.Value(b2), b2, tolint);
|
|
Geom2dInt_GInter Inter;
|
|
Inter.Perform(C1, d1, C2, d2, tolint, tolint);
|
|
if (!Inter.IsDone())
|
|
continue;
|
|
// intersection is point
|
|
if (Inter.NbPoints() > 0 && Inter.NbPoints() < 3)
|
|
{
|
|
IntRes2d_IntersectionPoint IP;
|
|
IntRes2d_Transition Tr1, Tr2;
|
|
SelectIntPnt(Inter, IP, Tr1, Tr2);
|
|
if (Tr1.PositionOnCurve() == IntRes2d_Middle && Tr2.PositionOnCurve() == IntRes2d_Middle)
|
|
{
|
|
Standard_Real param1 = IP.ParamOnFirst();
|
|
Standard_Real param2 = IP.ParamOnSecond();
|
|
gp_Pnt pi1 = GetPointOnEdge(edge1, sas, C1, param1);
|
|
gp_Pnt pi2 = GetPointOnEdge(edge2, sas, C2, param2);
|
|
BRep_Builder B;
|
|
TopoDS_Vertex V;
|
|
Standard_Real tolV = 0;
|
|
// analysis for edge1
|
|
Standard_Boolean ModifE1 = Standard_False;
|
|
TopoDS_Vertex VF1 = sae.FirstVertex(edge1);
|
|
gp_Pnt PVF1 = BRep_Tool::Pnt(VF1);
|
|
TopoDS_Vertex VL1 = sae.LastVertex(edge1);
|
|
gp_Pnt PVL1 = BRep_Tool::Pnt(VL1);
|
|
Standard_Real dist1 = pi1.Distance(PVF1);
|
|
Standard_Real dist2 = pi1.Distance(PVL1);
|
|
Standard_Real distmin = Min(dist1, dist2);
|
|
if (dist1 != dist2 && distmin < MaxTolVert)
|
|
{
|
|
if (dist1 < dist2)
|
|
{
|
|
tolV = Max(dist1 * 1.00001, BRep_Tool::Tolerance(VF1));
|
|
B.UpdateVertex(VF1, tolV);
|
|
V = VF1;
|
|
}
|
|
else
|
|
{
|
|
tolV = Max(dist2 * 1.00001, BRep_Tool::Tolerance(VL1));
|
|
B.UpdateVertex(VL1, tolV);
|
|
V = VL1;
|
|
}
|
|
|
|
Standard_Real dista = Abs(a1 - param1);
|
|
Standard_Real distb = Abs(b1 - param1);
|
|
Standard_Boolean IsCutLine;
|
|
ModifE1 = CutEdge(edge1, ((dista > distb) ? a1 : b1), param1, face, IsCutLine);
|
|
if (ModifE1)
|
|
NbCut++;
|
|
// not needed split edge, if one of parts is too small
|
|
ModifE1 = ModifE1 || distmin < Precision::Confusion();
|
|
}
|
|
// analysis for edge2
|
|
Standard_Boolean ModifE2 = Standard_False;
|
|
TopoDS_Vertex VF2 = sae.FirstVertex(edge2);
|
|
gp_Pnt PVF2 = BRep_Tool::Pnt(VF2);
|
|
TopoDS_Vertex VL2 = sae.LastVertex(edge2);
|
|
gp_Pnt PVL2 = BRep_Tool::Pnt(VL2);
|
|
dist1 = pi2.Distance(PVF2);
|
|
dist2 = pi2.Distance(PVL2);
|
|
distmin = Min(dist1, dist2);
|
|
if (dist1 != dist2 && distmin < MaxTolVert)
|
|
{
|
|
if (dist1 < dist2)
|
|
{
|
|
tolV = Max(dist1 * 1.00001, BRep_Tool::Tolerance(VF2));
|
|
B.UpdateVertex(VF2, tolV);
|
|
V = VF2;
|
|
}
|
|
else
|
|
{
|
|
tolV = Max(dist2 * 1.00001, BRep_Tool::Tolerance(VL2));
|
|
B.UpdateVertex(VL2, tolV);
|
|
V = VL2;
|
|
}
|
|
|
|
Standard_Real dista = Abs(a2 - param2);
|
|
Standard_Real distb = Abs(b2 - param2);
|
|
Standard_Boolean IsCutLine;
|
|
ModifE2 = CutEdge(edge2, ((dista > distb) ? a2 : b2), param2, face, IsCutLine);
|
|
if (ModifE2)
|
|
NbCut++;
|
|
// not needed split edge, if one of parts is too small
|
|
ModifE2 = ModifE2 || distmin < Precision::Confusion();
|
|
}
|
|
if (ModifE1 && !ModifE2)
|
|
{
|
|
if (SplitEdge1(sewd, face, num2, param2, V, tolV, boxes))
|
|
{
|
|
NbSplit++;
|
|
num2--;
|
|
continue;
|
|
}
|
|
}
|
|
if (!ModifE1 && ModifE2)
|
|
{
|
|
if (SplitEdge1(sewd, face, num1, param1, V, tolV, boxes))
|
|
{
|
|
NbSplit++;
|
|
num1--;
|
|
break;
|
|
}
|
|
}
|
|
if (!ModifE1 && !ModifE2)
|
|
{
|
|
gp_Pnt P0((pi1.X() + pi2.X()) / 2, (pi1.Y() + pi2.Y()) / 2, (pi1.Z() + pi2.Z()) / 2);
|
|
tolV = Max((pi1.Distance(pi2) / 2) * 1.00001, Precision::Confusion());
|
|
B.MakeVertex(V, P0, tolV);
|
|
MaxTolVert = Max(MaxTolVert, tolV);
|
|
Standard_Boolean isEdgeSplit2 = SplitEdge1(sewd, face, num2, param2, V, tolV, boxes);
|
|
if (isEdgeSplit2)
|
|
{
|
|
NbSplit++;
|
|
num2--;
|
|
}
|
|
if (SplitEdge1(sewd, face, num1, param1, V, tolV, boxes))
|
|
{
|
|
NbSplit++;
|
|
num1--;
|
|
break;
|
|
}
|
|
if (isEdgeSplit2)
|
|
continue;
|
|
}
|
|
}
|
|
if (Tr1.PositionOnCurve() == IntRes2d_Middle && Tr2.PositionOnCurve() != IntRes2d_Middle)
|
|
{
|
|
// find needed vertex from edge2 and split edge1 using it
|
|
Standard_Real param1 = IP.ParamOnFirst();
|
|
if (FindVertAndSplitEdge(param1,
|
|
edge1,
|
|
edge2,
|
|
Crv1,
|
|
MaxTolVert,
|
|
num1,
|
|
sewd,
|
|
face,
|
|
boxes,
|
|
Standard_False))
|
|
{
|
|
NbSplit++;
|
|
break;
|
|
}
|
|
}
|
|
if (Tr1.PositionOnCurve() != IntRes2d_Middle && Tr2.PositionOnCurve() == IntRes2d_Middle)
|
|
{
|
|
// find needed vertex from edge1 and split edge2 using it
|
|
Standard_Real param2 = IP.ParamOnSecond();
|
|
if (FindVertAndSplitEdge(param2,
|
|
edge2,
|
|
edge1,
|
|
Crv2,
|
|
MaxTolVert,
|
|
num2,
|
|
sewd,
|
|
face,
|
|
boxes,
|
|
Standard_False))
|
|
{
|
|
NbSplit++;
|
|
continue;
|
|
}
|
|
}
|
|
if (Tr1.PositionOnCurve() != IntRes2d_Middle && Tr2.PositionOnCurve() != IntRes2d_Middle)
|
|
{
|
|
// union vertexes
|
|
if (UnionVertexes(sewd, edge1, edge2, num2, boxes, B2))
|
|
nbReplaced++; // gka 06.09.04
|
|
}
|
|
}
|
|
// intersection is segment
|
|
if (Inter.NbSegments() == 1)
|
|
{
|
|
IntRes2d_IntersectionSegment IS = Inter.Segment(1);
|
|
if (IS.HasFirstPoint() && IS.HasLastPoint())
|
|
{
|
|
Standard_Boolean IsModified1 = Standard_False;
|
|
Standard_Boolean IsModified2 = Standard_False;
|
|
TopoDS_Vertex NewV;
|
|
BRep_Builder B;
|
|
Standard_Real newtol = 0.0;
|
|
IntRes2d_IntersectionPoint IPF = IS.FirstPoint();
|
|
Standard_Real p11 = IPF.ParamOnFirst();
|
|
Standard_Real p21 = IPF.ParamOnSecond();
|
|
IntRes2d_IntersectionPoint IPL = IS.LastPoint();
|
|
Standard_Real p12 = IPL.ParamOnFirst();
|
|
Standard_Real p22 = IPL.ParamOnSecond();
|
|
gp_Pnt Pnt11 = GetPointOnEdge(edge1, sas, C1, p11);
|
|
gp_Pnt Pnt12 = GetPointOnEdge(edge1, sas, C1, p12);
|
|
gp_Pnt Pnt21 = GetPointOnEdge(edge2, sas, C2, p21);
|
|
gp_Pnt Pnt22 = GetPointOnEdge(edge2, sas, C2, p22);
|
|
// next string commented by skl 29.12.2004 for OCC7624
|
|
// if( Pnt11.Distance(Pnt21)>myPreci || Pnt12.Distance(Pnt22)>myPreci ) continue;
|
|
if (Pnt11.Distance(Pnt21) > MaxTolVert || Pnt12.Distance(Pnt22) > MaxTolVert)
|
|
continue;
|
|
// analysis for edge1
|
|
TopoDS_Vertex V1 = sae.FirstVertex(edge1);
|
|
gp_Pnt PV1 = BRep_Tool::Pnt(V1);
|
|
TopoDS_Vertex V2 = sae.LastVertex(edge1);
|
|
gp_Pnt PV2 = BRep_Tool::Pnt(V2);
|
|
// Standard_Real tol1 = BRep_Tool::Tolerance(V1);
|
|
// Standard_Real tol2 = BRep_Tool::Tolerance(V2);
|
|
// Standard_Real maxtol = Max(tol1,tol2);
|
|
Standard_Real dist1 = Pnt11.Distance(PV1);
|
|
Standard_Real dist2 = Pnt12.Distance(PV1);
|
|
Standard_Real maxdist = Max(dist1, dist2);
|
|
Standard_Real pdist;
|
|
if (edge1.Orientation() == TopAbs_REVERSED)
|
|
pdist = Max(Abs(b1 - p11), Abs(b1 - p12));
|
|
else
|
|
pdist = Max(Abs(a1 - p11), Abs(a1 - p12));
|
|
if (maxdist < MaxTolVert || pdist < Abs(b1 - a1) * 0.01)
|
|
{
|
|
// if(maxdist<maxtol || pdist<Abs(b1-a1)*0.01) {
|
|
newtol = maxdist;
|
|
NewV = V1;
|
|
IsModified1 = Standard_True;
|
|
}
|
|
dist1 = Pnt11.Distance(PV2);
|
|
dist2 = Pnt12.Distance(PV2);
|
|
maxdist = Max(dist1, dist2);
|
|
if (edge1.Orientation() == TopAbs_REVERSED)
|
|
pdist = Max(Abs(a1 - p11), Abs(a1 - p12));
|
|
else
|
|
pdist = Max(Abs(b1 - p11), Abs(b1 - p12));
|
|
// if(maxdist<maxtol || pdist<Abs(b1-a1)*0.01) {
|
|
if (maxdist < MaxTolVert || pdist < Abs(b1 - a1) * 0.01)
|
|
{
|
|
if ((IsModified1 && maxdist < newtol) || !IsModified1)
|
|
{
|
|
newtol = maxdist;
|
|
NewV = V2;
|
|
IsModified1 = Standard_True;
|
|
}
|
|
}
|
|
if (IsModified1)
|
|
{
|
|
// cut edge1 and update tolerance NewV
|
|
Standard_Real dista = Abs(a1 - p11) + Abs(a1 - p12);
|
|
Standard_Real distb = Abs(b1 - p11) + Abs(b1 - p12);
|
|
Standard_Real pend, cut;
|
|
if (dista > distb)
|
|
pend = a1;
|
|
else
|
|
pend = b1;
|
|
if (Abs(pend - p11) > Abs(pend - p12))
|
|
cut = p12;
|
|
else
|
|
cut = p11;
|
|
Standard_Boolean IsCutLine;
|
|
if (CutEdge(edge1, pend, cut, face, IsCutLine))
|
|
NbCut++;
|
|
if (newtol > BRep_Tool::Tolerance(NewV))
|
|
{
|
|
B.UpdateVertex(NewV, newtol);
|
|
}
|
|
else
|
|
newtol = BRep_Tool::Tolerance(NewV);
|
|
}
|
|
// analysis for edge2
|
|
TopoDS_Vertex V12 = sae.FirstVertex(edge2);
|
|
gp_Pnt PV12 = BRep_Tool::Pnt(V12);
|
|
TopoDS_Vertex V22 = sae.LastVertex(edge2);
|
|
gp_Pnt PV22 = BRep_Tool::Pnt(V22);
|
|
// tol1 = BRep_Tool::Tolerance(V1);
|
|
// tol2 = BRep_Tool::Tolerance(V2);
|
|
// maxtol = Max(tol1,tol2);
|
|
dist1 = Pnt21.Distance(PV12);
|
|
dist2 = Pnt22.Distance(PV12);
|
|
maxdist = Max(dist1, dist2);
|
|
if (edge2.Orientation() == TopAbs_REVERSED)
|
|
pdist = Max(Abs(b2 - p21), Abs(b2 - p22));
|
|
else
|
|
pdist = Max(Abs(a2 - p21), Abs(a2 - p22));
|
|
// if(maxdist<maxtol || pdist<Abs(b2-a2)*0.01) {
|
|
if (maxdist < MaxTolVert || pdist < Abs(b2 - a2) * 0.01)
|
|
{
|
|
newtol = maxdist;
|
|
NewV = V12;
|
|
IsModified2 = Standard_True;
|
|
}
|
|
dist1 = Pnt21.Distance(PV22);
|
|
dist2 = Pnt22.Distance(PV22);
|
|
maxdist = Max(dist1, dist2);
|
|
if (edge2.Orientation() == TopAbs_REVERSED)
|
|
pdist = Max(Abs(a2 - p21), Abs(a2 - p22));
|
|
else
|
|
pdist = Max(Abs(b2 - p21), Abs(b2 - p22));
|
|
// if(maxdist<maxtol || pdist<Abs(b2-a2)*0.01) {
|
|
if (maxdist < MaxTolVert || pdist < Abs(b2 - a2) * 0.01)
|
|
{
|
|
if ((IsModified2 && maxdist < newtol) || !IsModified2)
|
|
{
|
|
newtol = maxdist;
|
|
NewV = V22;
|
|
IsModified2 = Standard_True;
|
|
}
|
|
}
|
|
if (IsModified2)
|
|
{
|
|
// cut edge1 and update tolerance NewV
|
|
Standard_Real dista = Abs(a2 - p21) + Abs(a2 - p22);
|
|
Standard_Real distb = Abs(b2 - p21) + Abs(b2 - p22);
|
|
Standard_Real pend, cut;
|
|
if (dista > distb)
|
|
pend = a2;
|
|
else
|
|
pend = b2;
|
|
if (Abs(pend - p21) > Abs(pend - p22))
|
|
cut = p22;
|
|
else
|
|
cut = p21;
|
|
Standard_Boolean IsCutLine;
|
|
if (CutEdge(edge2, pend, cut, face, IsCutLine))
|
|
NbCut++;
|
|
if (newtol > BRep_Tool::Tolerance(NewV))
|
|
{
|
|
B.UpdateVertex(NewV, newtol);
|
|
}
|
|
else
|
|
newtol = BRep_Tool::Tolerance(NewV);
|
|
}
|
|
|
|
if (IsModified1 && !IsModified2)
|
|
{
|
|
if (SplitEdge2(sewd, face, num2, p21, p22, NewV, newtol, boxes))
|
|
{
|
|
NbSplit++;
|
|
num2--;
|
|
continue;
|
|
}
|
|
}
|
|
if (!IsModified1 && IsModified2)
|
|
{
|
|
if (SplitEdge2(sewd, face, num1, p11, p12, NewV, newtol, boxes))
|
|
{
|
|
NbSplit++;
|
|
num1--;
|
|
break;
|
|
}
|
|
}
|
|
if (!IsModified1 && !IsModified2)
|
|
{
|
|
Standard_Real param1 = (p11 + p12) / 2;
|
|
Standard_Real param2 = (p21 + p22) / 2;
|
|
gp_Pnt Pnt10 = GetPointOnEdge(edge1, sas, C1, param1);
|
|
gp_Pnt Pnt20 = GetPointOnEdge(edge2, sas, C2, param2);
|
|
gp_Pnt P0((Pnt10.X() + Pnt20.X()) / 2,
|
|
(Pnt10.Y() + Pnt20.Y()) / 2,
|
|
(Pnt10.Z() + Pnt20.Z()) / 2);
|
|
dist1 = Max(Pnt11.Distance(P0), Pnt12.Distance(P0));
|
|
dist2 = Max(Pnt21.Distance(P0), Pnt22.Distance(P0));
|
|
Standard_Real tolV = Max(dist1, dist2);
|
|
tolV = Max(tolV, Pnt10.Distance(Pnt20)) * 1.00001;
|
|
Standard_Boolean FixSegment = Standard_True;
|
|
if (tolV < MaxTolVert)
|
|
{
|
|
// create new vertex and split each intersecting edge on two edges
|
|
B.MakeVertex(NewV, Pnt10, tolV);
|
|
if (SplitEdge2(sewd, face, num2, p21, p22, NewV, tolV, boxes))
|
|
{
|
|
NbSplit++;
|
|
num2--;
|
|
}
|
|
if (SplitEdge2(sewd, face, num1, p11, p12, NewV, tolV, boxes))
|
|
{
|
|
NbSplit++;
|
|
num1--;
|
|
break;
|
|
}
|
|
}
|
|
else if (FixSegment)
|
|
{
|
|
// if( Abs(p12-p11)>Abs(b1-a1)/2 || Abs(p22-p21)>Abs(b2-a2)/2 ) {
|
|
// segment is big and we have to split each intersecting edge
|
|
// on 3 edges --> middle edge - edge based on segment
|
|
// after we can remove edges maked from segment
|
|
gp_Pnt P01((Pnt11.X() + Pnt21.X()) / 2,
|
|
(Pnt11.Y() + Pnt21.Y()) / 2,
|
|
(Pnt11.Z() + Pnt21.Z()) / 2);
|
|
gp_Pnt P02((Pnt12.X() + Pnt22.X()) / 2,
|
|
(Pnt12.Y() + Pnt22.Y()) / 2,
|
|
(Pnt12.Z() + Pnt22.Z()) / 2);
|
|
Standard_Real tolV1 = Max(Pnt11.Distance(P01), Pnt21.Distance(P01));
|
|
tolV1 = Max(tolV1, Precision::Confusion()) * 1.00001;
|
|
Standard_Real tolV2 = Max(Pnt12.Distance(P02), Pnt22.Distance(P02));
|
|
tolV2 = Max(tolV2, Precision::Confusion()) * 1.00001;
|
|
if (tolV1 > MaxTolVert || tolV2 > MaxTolVert)
|
|
continue;
|
|
TopoDS_Vertex NewV1, NewV2;
|
|
/*
|
|
// parameters for splitting: a1..p11..p12..b1 and a2..p21..p22..b2
|
|
??? Standard_Integer nbseg1=3, nbseg2=3, kv1=0, kv2=0;
|
|
if(P01.Distance(PV1)<Max(tolV1,BRep_Tool::Tolerance(V1))) {
|
|
NewV1 = V1;
|
|
if(tolV1>BRep_Tool::Tolerance(V1))
|
|
B.UpdateVertex(NewV1,tolV1);
|
|
//akey1++;
|
|
nbseg1--;
|
|
kv1 = 1;
|
|
}
|
|
else if(P01.Distance(PV2)<Max(tolV1,BRep_Tool::Tolerance(V2))) {
|
|
NewV1 = V2;
|
|
if(tolV1>BRep_Tool::Tolerance(V2))
|
|
B.UpdateVertex(NewV1,tolV1);
|
|
//akey1++;
|
|
nbseg1--;
|
|
kv1 = 1;
|
|
}
|
|
*/
|
|
TopoDS_Edge tmpE, SegE;
|
|
// split edge1
|
|
Standard_Integer akey1 = 0, akey2 = 0;
|
|
Standard_Real newTolerance;
|
|
// analysis fo P01
|
|
newTolerance = Max(tolV1, BRep_Tool::Tolerance(V1));
|
|
if (P01.Distance(PV1) < newTolerance)
|
|
{
|
|
B.MakeVertex(NewV1, BRep_Tool::Pnt(V1), newTolerance);
|
|
NewV1.Orientation(V1.Orientation());
|
|
akey1++;
|
|
}
|
|
newTolerance = Max(tolV1, BRep_Tool::Tolerance(V2));
|
|
if (P01.Distance(PV2) < newTolerance)
|
|
{
|
|
B.MakeVertex(NewV1, BRep_Tool::Pnt(V2), newTolerance);
|
|
NewV1.Orientation(V2.Orientation());
|
|
akey1++;
|
|
}
|
|
// analysis fo P02
|
|
newTolerance = Max(tolV2, BRep_Tool::Tolerance(V1));
|
|
if (P02.Distance(PV1) < newTolerance)
|
|
{
|
|
B.MakeVertex(NewV2, BRep_Tool::Pnt(V1), newTolerance);
|
|
NewV2.Orientation(V1.Orientation());
|
|
akey2++;
|
|
}
|
|
newTolerance = Max(tolV2, BRep_Tool::Tolerance(V2));
|
|
if (P02.Distance(PV2) < newTolerance)
|
|
{
|
|
B.MakeVertex(NewV2, BRep_Tool::Pnt(V2), newTolerance);
|
|
NewV2.Orientation(V2.Orientation());
|
|
akey2++;
|
|
}
|
|
if (akey1 > 1 || akey2 > 1)
|
|
continue;
|
|
Standard_Integer dnum1 = 0, numseg1 = num1;
|
|
// prepare vertices
|
|
if (akey1 == 0)
|
|
B.MakeVertex(NewV1, P01, tolV1);
|
|
if (akey2 == 0)
|
|
B.MakeVertex(NewV2, P02, tolV2);
|
|
// split
|
|
if (akey1 == 0 && akey2 > 0)
|
|
{
|
|
if (SplitEdge1(sewd, face, num1, p11, NewV1, tolV1, boxes))
|
|
{
|
|
NbSplit++;
|
|
dnum1 = 1;
|
|
numseg1 = num1 + 1;
|
|
}
|
|
}
|
|
if (akey1 > 0 && akey2 == 0)
|
|
{
|
|
if (SplitEdge1(sewd, face, num1, p12, NewV2, tolV2, boxes))
|
|
{
|
|
NbSplit++;
|
|
dnum1 = 1;
|
|
numseg1 = num1;
|
|
}
|
|
}
|
|
if (akey1 == 0 && akey2 == 0)
|
|
{
|
|
if (SplitEdge1(sewd, face, num1, p11, NewV1, tolV1, boxes))
|
|
{
|
|
NbSplit++;
|
|
dnum1 = 1;
|
|
}
|
|
tmpE = sewd->Edge(num1);
|
|
Standard_Real a, b;
|
|
Handle(Geom2d_Curve) c2d;
|
|
sae.PCurve(tmpE, face, c2d, a, b, Standard_False);
|
|
if ((a - p12) * (b - p12) > 0)
|
|
{ // p12 - external for [a,b] => split next edge
|
|
if (SplitEdge1(sewd, face, num1 + 1, p12, NewV2, tolV2, boxes))
|
|
{
|
|
NbSplit++;
|
|
dnum1++;
|
|
numseg1 = num1 + 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (SplitEdge1(sewd, face, num1, p12, NewV2, tolV2, boxes))
|
|
{
|
|
NbSplit++;
|
|
dnum1++;
|
|
numseg1 = num1 + 1;
|
|
}
|
|
}
|
|
}
|
|
// SegE = sewd->Edge(numseg1); // get edge from segment
|
|
// split edge2
|
|
// replace vertices if it is necessary
|
|
ShapeBuild_Edge sbe;
|
|
akey1 = 0, akey2 = 0;
|
|
|
|
if (P01.Distance(PV12) < tolV1)
|
|
{
|
|
tolV1 += P01.Distance(PV12);
|
|
B.UpdateVertex(NewV1, tolV1);
|
|
if (V12.Orientation() == NewV1.Orientation())
|
|
{
|
|
myContext->Replace(V12, NewV1);
|
|
V12 = NewV1;
|
|
}
|
|
else
|
|
{
|
|
myContext->Replace(V12, NewV1.Reversed());
|
|
V12 = TopoDS::Vertex(NewV1.Reversed());
|
|
}
|
|
nbReplaced++; // gka 06.09.04
|
|
TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2, NewV1, V22);
|
|
myContext->Replace(edge2, NewE);
|
|
sewd->Set(NewE, num2 + dnum1);
|
|
boxes.Bind(NewE, B2); // update boxes
|
|
edge2 = NewE;
|
|
akey1 = 1;
|
|
}
|
|
if (P01.Distance(PV22) < tolV1)
|
|
{
|
|
tolV1 += P01.Distance(PV22);
|
|
B.UpdateVertex(NewV1, tolV1);
|
|
if (V22.Orientation() == NewV1.Orientation())
|
|
{
|
|
myContext->Replace(V22, NewV1);
|
|
V22 = NewV1;
|
|
}
|
|
else
|
|
{
|
|
myContext->Replace(V22, NewV1.Reversed());
|
|
V22 = TopoDS::Vertex(NewV1.Reversed());
|
|
}
|
|
nbReplaced++; // gka 06.09.04
|
|
TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2, V12, NewV1);
|
|
myContext->Replace(edge2, NewE);
|
|
sewd->Set(NewE, num2 + dnum1);
|
|
boxes.Bind(NewE, B2); // update boxes
|
|
edge2 = NewE;
|
|
akey1 = 2;
|
|
}
|
|
if (P02.Distance(PV12) < tolV2)
|
|
{
|
|
tolV2 += P02.Distance(PV12);
|
|
B.UpdateVertex(NewV2, tolV2);
|
|
if (V12.Orientation() == NewV2.Orientation())
|
|
{
|
|
myContext->Replace(V12, NewV2);
|
|
V12 = NewV2;
|
|
}
|
|
else
|
|
{
|
|
myContext->Replace(V12, NewV2.Reversed());
|
|
V12 = TopoDS::Vertex(NewV2.Reversed());
|
|
}
|
|
nbReplaced++; // gka 06.09.04
|
|
TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2, NewV2, V22);
|
|
myContext->Replace(edge2, NewE);
|
|
sewd->Set(NewE, num2 + dnum1);
|
|
boxes.Bind(NewE, B2); // update boxes
|
|
edge2 = NewE;
|
|
akey2 = 1;
|
|
}
|
|
if (P02.Distance(PV22) < tolV2)
|
|
{
|
|
tolV2 += P02.Distance(PV22);
|
|
B.UpdateVertex(NewV2, tolV2);
|
|
if (V22.Orientation() == NewV2.Orientation())
|
|
{
|
|
myContext->Replace(V22, NewV2);
|
|
V22 = NewV2;
|
|
}
|
|
else
|
|
{
|
|
myContext->Replace(V22, NewV2.Reversed());
|
|
V22 = TopoDS::Vertex(NewV2.Reversed());
|
|
}
|
|
nbReplaced++; // gka 06.09.04
|
|
TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2, V12, NewV2);
|
|
myContext->Replace(edge2, NewE);
|
|
sewd->Set(NewE, num2 + dnum1);
|
|
boxes.Bind(NewE, B2); // update boxes
|
|
edge2 = NewE;
|
|
akey2 = 2;
|
|
}
|
|
Standard_Integer dnum2 = 0, numseg2 = num2 + dnum1;
|
|
// split
|
|
if (akey1 == 0 && akey2 > 0)
|
|
{
|
|
if (SplitEdge1(sewd, face, num2 + dnum1, p21, NewV1, tolV1, boxes))
|
|
{
|
|
NbSplit++;
|
|
dnum2 = 1;
|
|
// numseg2=num2+dnum1+1;
|
|
numseg2 = num2 + dnum1;
|
|
}
|
|
}
|
|
if (akey1 > 0 && akey2 == 0)
|
|
{
|
|
if (SplitEdge1(sewd, face, num2 + dnum1, p22, NewV2, tolV2, boxes))
|
|
{
|
|
NbSplit++;
|
|
dnum2 = 1;
|
|
// numseg2=num2+dnum1;
|
|
numseg2 = num2 + dnum1 + 1;
|
|
}
|
|
}
|
|
if (akey1 == 0 && akey2 == 0)
|
|
{
|
|
if (SplitEdge1(sewd, face, num2 + dnum1, p21, NewV1, tolV1, boxes))
|
|
{
|
|
NbSplit++;
|
|
dnum2 = 1;
|
|
}
|
|
tmpE = sewd->Edge(num2 + dnum1);
|
|
Standard_Real a, b;
|
|
Handle(Geom2d_Curve) c2d;
|
|
sae.PCurve(tmpE, face, c2d, a, b, Standard_False);
|
|
if ((a - p22) * (b - p22) > 0)
|
|
{ // p22 - external for [a,b] => split next edge
|
|
if (SplitEdge1(sewd, face, num2 + dnum1 + dnum2, p22, NewV2, tolV2, boxes))
|
|
{
|
|
NbSplit++;
|
|
numseg2 = num2 + dnum1 + dnum2;
|
|
dnum2++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (SplitEdge1(sewd, face, num2 + dnum1, p22, NewV2, tolV2, boxes))
|
|
{
|
|
NbSplit++;
|
|
dnum2++;
|
|
numseg2 = num2 + dnum1 + 1;
|
|
}
|
|
}
|
|
}
|
|
// remove segment
|
|
sewd->Remove(numseg2);
|
|
sewd->Remove(numseg1);
|
|
NbRemoved = NbRemoved + 2;
|
|
// num1--;
|
|
// break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
isDone = (NbSplit || NbCut || nbReplaced || NbRemoved);
|
|
return isDone;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeFix_IntersectionTool::FixIntersectingWires(TopoDS_Face& face) const
|
|
{
|
|
if (myContext.IsNull() || face.IsNull())
|
|
return Standard_False;
|
|
// TopoDS_Shape S = context->Apply(face);
|
|
// TopoDS_Shape SF = TopoDS::Face(S);
|
|
TopoDS_Shape SF = face;
|
|
TopAbs_Orientation ori = face.Orientation();
|
|
TopTools_SequenceOfShape SeqWir;
|
|
TopTools_SequenceOfShape SeqNMShapes;
|
|
for (TopoDS_Iterator iter(SF, Standard_False); iter.More(); iter.Next())
|
|
{
|
|
if (iter.Value().ShapeType() != TopAbs_WIRE
|
|
|| (iter.Value().Orientation() != TopAbs_FORWARD
|
|
&& iter.Value().Orientation() != TopAbs_REVERSED))
|
|
{
|
|
SeqNMShapes.Append(iter.Value());
|
|
continue;
|
|
}
|
|
TopoDS_Wire wire = TopoDS::Wire(iter.Value());
|
|
SeqWir.Append(wire);
|
|
}
|
|
if (SeqWir.Length() < 2)
|
|
return Standard_False; // gka 06.09.04
|
|
|
|
Standard_Real MaxTolVert = 0.0;
|
|
for (TopExp_Explorer exp(SF, TopAbs_VERTEX); exp.More(); exp.Next())
|
|
{
|
|
Standard_Real tolV = BRep_Tool::Tolerance(TopoDS::Vertex(exp.Current()));
|
|
MaxTolVert = Max(MaxTolVert, tolV);
|
|
}
|
|
Standard_Boolean isDone = Standard_False; // gka 06.09.04
|
|
ShapeAnalysis_Edge sae;
|
|
Handle(ShapeAnalysis_Surface) sas = new ShapeAnalysis_Surface(BRep_Tool::Surface(face));
|
|
|
|
// precompute edge boxes for all wires
|
|
NCollection_Sequence<ShapeFix_DataMapOfShapeBox2d> aSeqWirEdgeBoxes;
|
|
NCollection_Sequence<Bnd_Box2d> aSeqWirBoxes;
|
|
for (Standard_Integer n = 1; n <= SeqWir.Length(); n++)
|
|
{
|
|
const TopoDS_Wire& aWire = TopoDS::Wire(SeqWir.Value(n));
|
|
Handle(ShapeExtend_WireData) aSewd = new ShapeExtend_WireData(aWire);
|
|
ShapeFix_DataMapOfShapeBox2d aBoxes;
|
|
Bnd_Box2d aTotalBox = CreateBoxes2d(aSewd, face, aBoxes);
|
|
aSeqWirEdgeBoxes.Append(aBoxes);
|
|
aSeqWirBoxes.Append(aTotalBox);
|
|
}
|
|
|
|
for (Standard_Integer n1 = 1; n1 <= SeqWir.Length() - 1; n1++)
|
|
{
|
|
TopoDS_Wire wire1 = TopoDS::Wire(SeqWir.Value(n1));
|
|
Handle(ShapeExtend_WireData) sewd1 = new ShapeExtend_WireData(wire1);
|
|
ShapeFix_DataMapOfShapeBox2d& boxes1 = aSeqWirEdgeBoxes.ChangeValue(n1);
|
|
Bnd_Box2d aBox1 = aSeqWirBoxes(n1);
|
|
for (Standard_Integer n2 = n1 + 1; n2 <= SeqWir.Length(); n2++)
|
|
{
|
|
TopoDS_Wire wire2 = TopoDS::Wire(SeqWir.Value(n2));
|
|
Handle(ShapeExtend_WireData) sewd2 = new ShapeExtend_WireData(wire2);
|
|
ShapeFix_DataMapOfShapeBox2d& boxes2 = aSeqWirEdgeBoxes.ChangeValue(n2);
|
|
Bnd_Box2d aBox2 = aSeqWirBoxes(n2);
|
|
if (!aBox1.IsVoid() && !aBox2.IsVoid() && aBox1.IsOut(aBox2))
|
|
{
|
|
continue;
|
|
}
|
|
// detect possible intersections:
|
|
Standard_Integer NbModif = 0;
|
|
Standard_Integer nbReplaced = 0; // gka 06.09.04
|
|
Standard_Boolean hasModifWire = Standard_False; // gka 06.09.04
|
|
for (Standard_Integer num1 = 1; num1 <= sewd1->NbEdges() && NbModif < 30; num1++)
|
|
{
|
|
// for each edge from first wire
|
|
TopoDS_Edge edge1 = sewd1->Edge(num1); // gka 06.09.04
|
|
|
|
for (Standard_Integer num2 = 1; num2 <= sewd2->NbEdges() && NbModif < 30; num2++)
|
|
{
|
|
// for each edge from second wire
|
|
TopoDS_Edge edge2 = sewd2->Edge(num2);
|
|
if (edge1.IsSame(edge2))
|
|
continue;
|
|
if (BRep_Tool::Degenerated(edge1) || BRep_Tool::Degenerated(edge2))
|
|
continue;
|
|
if (!boxes1.IsBound(edge1) || !boxes2.IsBound(edge2))
|
|
continue;
|
|
Bnd_Box2d B1 = boxes1.Find(edge1);
|
|
Bnd_Box2d B2 = boxes2.Find(edge2);
|
|
if (!B1.IsOut(B2))
|
|
{
|
|
// intersection is possible...
|
|
Standard_Real a1, b1, a2, b2;
|
|
Handle(Geom2d_Curve) Crv1, Crv2;
|
|
if (!sae.PCurve(edge1, face, Crv1, a1, b1, Standard_False))
|
|
continue; // return Standard_False; gka 06.09.04
|
|
if (!sae.PCurve(edge2, face, Crv2, a2, b2, Standard_False))
|
|
continue; // return Standard_False;gka 06.09.04
|
|
Standard_Real tolint = 1.0e-10;
|
|
Geom2dAdaptor_Curve C1(Crv1), C2(Crv2);
|
|
IntRes2d_Domain d1(C1.Value(a1), a1, tolint, C1.Value(b1), b1, tolint);
|
|
IntRes2d_Domain d2(C2.Value(a2), a2, tolint, C2.Value(b2), b2, tolint);
|
|
Geom2dInt_GInter Inter;
|
|
Inter.Perform(C1, d1, C2, d2, tolint, tolint);
|
|
if (!Inter.IsDone())
|
|
continue;
|
|
// intersection is point
|
|
if (Inter.NbPoints() > 0 && Inter.NbPoints() < 3)
|
|
{
|
|
IntRes2d_IntersectionPoint IP;
|
|
IntRes2d_Transition Tr1, Tr2;
|
|
SelectIntPnt(Inter, IP, Tr1, Tr2);
|
|
if (Tr1.PositionOnCurve() == IntRes2d_Middle
|
|
&& Tr2.PositionOnCurve() == IntRes2d_Middle)
|
|
{
|
|
// create new vertex and split both edges
|
|
Standard_Real param1 = IP.ParamOnFirst();
|
|
Standard_Real param2 = IP.ParamOnSecond();
|
|
gp_Pnt pi1 = GetPointOnEdge(edge1, sas, C1, param1);
|
|
gp_Pnt pi2 = GetPointOnEdge(edge2, sas, C2, param2);
|
|
gp_Pnt P0((pi1.X() + pi2.X()) / 2,
|
|
(pi1.Y() + pi2.Y()) / 2,
|
|
(pi1.Z() + pi2.Z()) / 2);
|
|
BRep_Builder B;
|
|
TopoDS_Vertex V;
|
|
Standard_Real tolV = Max((pi1.Distance(pi2) / 2) * 1.00001, Precision::Confusion());
|
|
B.MakeVertex(V, P0, tolV);
|
|
MaxTolVert = Max(MaxTolVert, tolV);
|
|
Standard_Boolean isSplitEdge2 =
|
|
SplitEdge1(sewd2, face, num2, param2, V, tolV, boxes2);
|
|
if (isSplitEdge2)
|
|
{
|
|
NbModif++;
|
|
num2--;
|
|
}
|
|
if (SplitEdge1(sewd1, face, num1, param1, V, tolV, boxes1))
|
|
{
|
|
NbModif++;
|
|
num1--;
|
|
break;
|
|
}
|
|
if (isSplitEdge2)
|
|
continue;
|
|
}
|
|
if (Tr1.PositionOnCurve() == IntRes2d_Middle
|
|
&& Tr2.PositionOnCurve() != IntRes2d_Middle)
|
|
{
|
|
// find needed vertex from edge2 and split edge1 using it
|
|
Standard_Real param1 = IP.ParamOnFirst();
|
|
if (FindVertAndSplitEdge(param1,
|
|
edge1,
|
|
edge2,
|
|
Crv1,
|
|
MaxTolVert,
|
|
num1,
|
|
sewd1,
|
|
face,
|
|
boxes1,
|
|
Standard_True))
|
|
{
|
|
NbModif++;
|
|
break;
|
|
}
|
|
}
|
|
if (Tr1.PositionOnCurve() != IntRes2d_Middle
|
|
&& Tr2.PositionOnCurve() == IntRes2d_Middle)
|
|
{
|
|
// find needed vertex from edge1 and split edge2 using it
|
|
Standard_Real param2 = IP.ParamOnSecond();
|
|
if (FindVertAndSplitEdge(param2,
|
|
edge2,
|
|
edge1,
|
|
Crv2,
|
|
MaxTolVert,
|
|
num2,
|
|
sewd2,
|
|
face,
|
|
boxes2,
|
|
Standard_True))
|
|
{
|
|
NbModif++;
|
|
continue;
|
|
}
|
|
}
|
|
if (Tr1.PositionOnCurve() != IntRes2d_Middle
|
|
&& Tr2.PositionOnCurve() != IntRes2d_Middle)
|
|
{
|
|
// union vertexes
|
|
if (UnionVertexes(sewd2, edge1, edge2, num2, boxes2, B2))
|
|
nbReplaced++; // gka 06.09.04
|
|
}
|
|
}
|
|
hasModifWire = (hasModifWire || NbModif || nbReplaced);
|
|
// intersection is segment
|
|
if (Inter.NbSegments() == 1)
|
|
{
|
|
IntRes2d_IntersectionSegment IS = Inter.Segment(1);
|
|
if (IS.HasFirstPoint() && IS.HasLastPoint())
|
|
{
|
|
Standard_Boolean IsModified1 = Standard_False;
|
|
Standard_Boolean IsModified2 = Standard_False;
|
|
TopoDS_Vertex NewV;
|
|
BRep_Builder B;
|
|
Standard_Real newtol = 0.0;
|
|
IntRes2d_IntersectionPoint IPF = IS.FirstPoint();
|
|
Standard_Real p11 = IPF.ParamOnFirst();
|
|
Standard_Real p21 = IPF.ParamOnSecond();
|
|
IntRes2d_IntersectionPoint IPL = IS.LastPoint();
|
|
Standard_Real p12 = IPL.ParamOnFirst();
|
|
Standard_Real p22 = IPL.ParamOnSecond();
|
|
gp_Pnt Pnt11 = GetPointOnEdge(edge1, sas, C1, p11);
|
|
gp_Pnt Pnt12 = GetPointOnEdge(edge1, sas, C1, p12);
|
|
gp_Pnt Pnt21 = GetPointOnEdge(edge2, sas, C2, p21);
|
|
gp_Pnt Pnt22 = GetPointOnEdge(edge2, sas, C2, p22);
|
|
|
|
// analysis for edge1
|
|
TopoDS_Vertex V1 = sae.FirstVertex(edge1);
|
|
gp_Pnt PV1 = BRep_Tool::Pnt(V1);
|
|
TopoDS_Vertex V2 = sae.LastVertex(edge1);
|
|
gp_Pnt PV2 = BRep_Tool::Pnt(V2);
|
|
Standard_Real dist1 = Pnt11.Distance(PV1);
|
|
Standard_Real dist2 = Pnt12.Distance(PV1);
|
|
Standard_Real maxdist = Max(dist1, dist2);
|
|
Standard_Real pdist;
|
|
if (edge1.Orientation() == TopAbs_REVERSED)
|
|
pdist = Max(Abs(b1 - p11), Abs(b1 - p12));
|
|
else
|
|
pdist = Max(Abs(a1 - p11), Abs(a1 - p12));
|
|
if (maxdist < MaxTolVert || pdist < Abs(b1 - a1) * 0.01)
|
|
{
|
|
newtol = maxdist;
|
|
NewV = V1;
|
|
IsModified1 = Standard_True;
|
|
}
|
|
dist1 = Pnt11.Distance(PV2);
|
|
dist2 = Pnt12.Distance(PV2);
|
|
maxdist = Max(dist1, dist2);
|
|
if (edge1.Orientation() == TopAbs_REVERSED)
|
|
pdist = Max(Abs(a1 - p11), Abs(a1 - p12));
|
|
else
|
|
pdist = Max(Abs(b1 - p11), Abs(b1 - p12));
|
|
if (maxdist < MaxTolVert || pdist < Abs(b1 - a1) * 0.01)
|
|
{
|
|
if ((IsModified1 && maxdist < newtol) || !IsModified1)
|
|
{
|
|
newtol = maxdist;
|
|
NewV = V2;
|
|
IsModified1 = Standard_True;
|
|
}
|
|
}
|
|
if (IsModified1)
|
|
{
|
|
// cut edge1 and update tolerance NewV
|
|
Standard_Real dista = Abs(a1 - p11) + Abs(a1 - p12);
|
|
Standard_Real distb = Abs(b1 - p11) + Abs(b1 - p12);
|
|
Standard_Real pend, cut;
|
|
if (dista > distb)
|
|
pend = a1;
|
|
else
|
|
pend = b1;
|
|
if (Abs(pend - p11) > Abs(pend - p12))
|
|
cut = p12;
|
|
else
|
|
cut = p11;
|
|
Standard_Boolean IsCutLine;
|
|
if (!CutEdge(edge1, pend, cut, face, IsCutLine))
|
|
{
|
|
IsModified1 = Standard_False;
|
|
continue;
|
|
}
|
|
if (newtol > BRep_Tool::Tolerance(NewV))
|
|
{
|
|
B.UpdateVertex(NewV, newtol * 1.00001);
|
|
}
|
|
}
|
|
|
|
// analysis for edge2
|
|
TopoDS_Vertex V12 = sae.FirstVertex(edge2);
|
|
gp_Pnt PV12 = BRep_Tool::Pnt(V12);
|
|
TopoDS_Vertex V22 = sae.LastVertex(edge2);
|
|
gp_Pnt PV22 = BRep_Tool::Pnt(V22);
|
|
dist1 = Pnt21.Distance(PV12);
|
|
dist2 = Pnt22.Distance(PV12);
|
|
maxdist = Max(dist1, dist2);
|
|
if (edge2.Orientation() == TopAbs_REVERSED)
|
|
pdist = Max(Abs(b2 - p21), Abs(b2 - p22));
|
|
else
|
|
pdist = Max(Abs(a2 - p21), Abs(a2 - p22));
|
|
if (maxdist < MaxTolVert || pdist < Abs(b2 - a2) * 0.01)
|
|
{
|
|
newtol = maxdist;
|
|
NewV = V12;
|
|
IsModified2 = Standard_True;
|
|
}
|
|
dist1 = Pnt21.Distance(PV22);
|
|
dist2 = Pnt22.Distance(PV22);
|
|
maxdist = Max(dist1, dist2);
|
|
if (edge2.Orientation() == TopAbs_REVERSED)
|
|
pdist = Max(Abs(a2 - p21), Abs(a2 - p22));
|
|
else
|
|
pdist = Max(Abs(b2 - p21), Abs(b2 - p22));
|
|
if (maxdist < MaxTolVert || pdist < Abs(b2 - a2) * 0.01)
|
|
{
|
|
if ((IsModified2 && maxdist < newtol) || !IsModified2)
|
|
{
|
|
newtol = maxdist;
|
|
NewV = V22;
|
|
IsModified2 = Standard_True;
|
|
}
|
|
}
|
|
if (IsModified2)
|
|
{
|
|
// cut edge1 and update tolerance NewV
|
|
Standard_Real dista = Abs(a2 - p21) + Abs(a2 - p22);
|
|
Standard_Real distb = Abs(b2 - p21) + Abs(b2 - p22);
|
|
Standard_Real pend, cut;
|
|
if (dista > distb)
|
|
pend = a2;
|
|
else
|
|
pend = b2;
|
|
if (Abs(pend - p21) > Abs(pend - p22))
|
|
cut = p22;
|
|
else
|
|
cut = p21;
|
|
Standard_Boolean IsCutLine;
|
|
if (!CutEdge(edge2, pend, cut, face, IsCutLine))
|
|
{
|
|
IsModified2 = Standard_False;
|
|
continue;
|
|
}
|
|
if (newtol > BRep_Tool::Tolerance(NewV))
|
|
{
|
|
B.UpdateVertex(NewV, newtol * 1.00001);
|
|
}
|
|
}
|
|
|
|
if (IsModified1 || IsModified2)
|
|
{
|
|
// necessary to make intersect with the same pair of the edges once again with
|
|
// modified ranges
|
|
num2--;
|
|
hasModifWire = Standard_True; // gka 06.09.04
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
// create new vertex and split edge1 and edge2 using it
|
|
if (Abs(p12 - p11) > Abs(b1 - a1) / 2 || Abs(p22 - p21) > Abs(b2 - a2) / 2)
|
|
{
|
|
// segment is big and we have to split each intersecting edge
|
|
// on 3 edges --> middle edge - edge based on segment
|
|
gp_Pnt P01((Pnt11.X() + Pnt21.X()) / 2,
|
|
(Pnt11.Y() + Pnt21.Y()) / 2,
|
|
(Pnt11.Z() + Pnt21.Z()) / 2);
|
|
gp_Pnt P02((Pnt12.X() + Pnt22.X()) / 2,
|
|
(Pnt12.Y() + Pnt22.Y()) / 2,
|
|
(Pnt12.Z() + Pnt22.Z()) / 2);
|
|
Standard_Real tolV1 = Max(Pnt11.Distance(P01), Pnt21.Distance(P01));
|
|
tolV1 = Max(tolV1, Precision::Confusion()) * 1.00001;
|
|
Standard_Real tolV2 = Max(Pnt12.Distance(P02), Pnt22.Distance(P02));
|
|
tolV2 = Max(tolV2, Precision::Confusion()) * 1.00001;
|
|
if (tolV1 > MaxTolVert || tolV2 > MaxTolVert)
|
|
continue;
|
|
|
|
hasModifWire = Standard_True; // gka 06.09.04
|
|
TopoDS_Vertex NewV1, NewV2;
|
|
TopoDS_Edge tmpE, SegE;
|
|
// split edge1
|
|
Standard_Integer akey1 = 0, akey2 = 0;
|
|
// analysis fo P01
|
|
if (P01.Distance(PV1) < Max(tolV1, BRep_Tool::Tolerance(V1)))
|
|
{
|
|
NewV1 = V1;
|
|
if (tolV1 > BRep_Tool::Tolerance(V1))
|
|
B.UpdateVertex(NewV1, tolV1);
|
|
akey1++;
|
|
}
|
|
if (P01.Distance(PV2) < Max(tolV1, BRep_Tool::Tolerance(V2)))
|
|
{
|
|
NewV1 = V2;
|
|
if (tolV1 > BRep_Tool::Tolerance(V2))
|
|
B.UpdateVertex(NewV1, tolV1);
|
|
akey1++;
|
|
}
|
|
// analysis fo P02
|
|
if (P02.Distance(PV1) < Max(tolV2, BRep_Tool::Tolerance(V1)))
|
|
{
|
|
NewV2 = V1;
|
|
if (tolV2 > BRep_Tool::Tolerance(V1))
|
|
B.UpdateVertex(NewV2, tolV2);
|
|
akey2++;
|
|
}
|
|
if (P02.Distance(PV2) < Max(tolV2, BRep_Tool::Tolerance(V2)))
|
|
{
|
|
NewV2 = V2;
|
|
if (tolV2 > BRep_Tool::Tolerance(V2))
|
|
B.UpdateVertex(NewV2, tolV2);
|
|
akey2++;
|
|
}
|
|
if (akey1 > 1 || akey2 > 1)
|
|
continue;
|
|
// prepare vertices
|
|
if (akey1 == 0)
|
|
B.MakeVertex(NewV1, P01, tolV1);
|
|
if (akey2 == 0)
|
|
B.MakeVertex(NewV2, P02, tolV2);
|
|
// split
|
|
Standard_Integer numseg1 = num1;
|
|
if (akey1 == 0 && akey2 > 0)
|
|
{
|
|
if (SplitEdge1(sewd1, face, num1, p11, NewV1, tolV1, boxes1))
|
|
{
|
|
NbModif++;
|
|
numseg1 = num1 + 1;
|
|
}
|
|
}
|
|
if (akey1 > 0 && akey2 == 0)
|
|
{
|
|
if (SplitEdge1(sewd1, face, num1, p12, NewV2, tolV2, boxes1))
|
|
{
|
|
NbModif++;
|
|
numseg1 = num1;
|
|
}
|
|
}
|
|
if (akey1 == 0 && akey2 == 0)
|
|
{
|
|
int num1split2 = num1; // what edge to split by point 2
|
|
if (SplitEdge1(sewd1, face, num1, p11, NewV1, tolV1, boxes1))
|
|
{
|
|
NbModif++;
|
|
tmpE = sewd1->Edge(num1);
|
|
Standard_Real a, b;
|
|
Handle(Geom2d_Curve) c2d;
|
|
sae.PCurve(tmpE, face, c2d, a, b, Standard_False);
|
|
if ((a - p12) * (b - p12) > 0)
|
|
{ // p12 - external for [a,b] => split next edge
|
|
num1split2++;
|
|
}
|
|
}
|
|
if (SplitEdge1(sewd1, face, num1split2, p12, NewV2, tolV2, boxes1))
|
|
{
|
|
NbModif++;
|
|
numseg1 = num1 + 1;
|
|
}
|
|
}
|
|
SegE = sewd1->Edge(numseg1); // get edge from segment
|
|
// split edge2
|
|
// replace vertices if it is necessary
|
|
ShapeBuild_Edge sbe;
|
|
akey1 = 0, akey2 = 0;
|
|
if (P01.Distance(PV12) < tolV1)
|
|
{
|
|
tolV1 += P01.Distance(PV12);
|
|
B.UpdateVertex(NewV1, tolV1);
|
|
V12 = NewV1;
|
|
TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2, NewV1, V22);
|
|
myContext->Replace(edge2, NewE);
|
|
sewd2->Set(NewE, num2);
|
|
boxes2.Bind(NewE, B2); // update boxes2
|
|
edge2 = NewE;
|
|
akey1 = 1;
|
|
}
|
|
if (P01.Distance(PV22) < tolV1)
|
|
{
|
|
tolV1 += P01.Distance(PV22);
|
|
B.UpdateVertex(NewV1, tolV1);
|
|
V22 = NewV1;
|
|
TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2, V12, NewV1);
|
|
myContext->Replace(edge2, NewE);
|
|
sewd2->Set(NewE, num2);
|
|
boxes2.Bind(NewE, B2); // update boxes2
|
|
edge2 = NewE;
|
|
akey1 = 2;
|
|
}
|
|
if (P02.Distance(PV12) < tolV2)
|
|
{
|
|
tolV2 += P02.Distance(PV12);
|
|
B.UpdateVertex(NewV2, tolV2);
|
|
V12 = NewV2;
|
|
TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2, NewV2, V22);
|
|
myContext->Replace(edge2, NewE);
|
|
sewd2->Set(NewE, num2);
|
|
boxes2.Bind(NewE, B2); // update boxes2
|
|
edge2 = NewE;
|
|
akey2 = 1;
|
|
}
|
|
if (P02.Distance(PV22) < tolV2)
|
|
{
|
|
tolV2 += P02.Distance(PV22);
|
|
B.UpdateVertex(NewV2, tolV2);
|
|
V22 = NewV2;
|
|
TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2, V12, NewV2);
|
|
myContext->Replace(edge2, NewE);
|
|
sewd2->Set(NewE, num2);
|
|
boxes2.Bind(NewE, B2); // update boxes2
|
|
edge2 = NewE;
|
|
akey2 = 2;
|
|
}
|
|
// split
|
|
Standard_Integer numseg2 = num2;
|
|
if (akey1 == 0 && akey2 > 0)
|
|
{
|
|
if (SplitEdge1(sewd2, face, num2, p21, NewV1, tolV1, boxes2))
|
|
{
|
|
NbModif++;
|
|
numseg2 = num2 + 1;
|
|
}
|
|
}
|
|
if (akey1 > 0 && akey2 == 0)
|
|
{
|
|
if (SplitEdge1(sewd2, face, num2, p22, NewV2, tolV2, boxes2))
|
|
{
|
|
NbModif++;
|
|
numseg2 = num2;
|
|
}
|
|
}
|
|
if (akey1 == 0 && akey2 == 0)
|
|
{
|
|
int num2split2 = num2;
|
|
if (SplitEdge1(sewd2, face, num2, p21, NewV1, tolV1, boxes2))
|
|
{
|
|
NbModif++;
|
|
numseg2 = num2 + 1;
|
|
tmpE = sewd2->Edge(num2);
|
|
Standard_Real a, b;
|
|
Handle(Geom2d_Curve) c2d;
|
|
sae.PCurve(tmpE, face, c2d, a, b, Standard_False);
|
|
if ((a - p22) * (b - p22) > 0)
|
|
{ // p22 - external for [a,b] => split next edge
|
|
num2split2++;
|
|
}
|
|
}
|
|
if (SplitEdge1(sewd2, face, num2split2, p22, NewV2, tolV2, boxes2))
|
|
{
|
|
NbModif++;
|
|
numseg2 = num2 + 1;
|
|
}
|
|
}
|
|
tmpE = sewd2->Edge(numseg2);
|
|
boxes2.Bind(tmpE, boxes1.Find(SegE)); // update boxes2
|
|
if (!sae.FirstVertex(SegE).IsSame(sae.FirstVertex(tmpE)))
|
|
{
|
|
SegE.Reverse();
|
|
}
|
|
myContext->Replace(tmpE, SegE);
|
|
sewd2->Set(SegE, numseg2);
|
|
num1--;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
// split each intersecting edge on two edges
|
|
gp_Pnt P0((Pnt11.X() + Pnt12.X()) / 2,
|
|
(Pnt11.Y() + Pnt12.Y()) / 2,
|
|
(Pnt11.Z() + Pnt12.Z()) / 2);
|
|
Standard_Real param1 = (p11 + p12) / 2;
|
|
Standard_Real param2 = (p21 + p22) / 2;
|
|
gp_Pnt Pnt10 = GetPointOnEdge(edge1, sas, C1, param1);
|
|
gp_Pnt Pnt20 = GetPointOnEdge(edge2, sas, C2, param2);
|
|
dist1 = Max(Pnt11.Distance(P0), Pnt12.Distance(Pnt10));
|
|
dist2 = Max(Pnt21.Distance(P0), Pnt22.Distance(Pnt10));
|
|
Standard_Real tolV = Max(dist1, dist2);
|
|
tolV = Max(tolV, Pnt10.Distance(Pnt20)) * 1.00001;
|
|
B.MakeVertex(NewV, Pnt10, tolV);
|
|
MaxTolVert = Max(MaxTolVert, tolV);
|
|
hasModifWire = Standard_True;
|
|
if (SplitEdge2(sewd2, face, num2, p21, p22, NewV, tolV, boxes2))
|
|
{
|
|
NbModif++;
|
|
num2--;
|
|
}
|
|
if (SplitEdge2(sewd1, face, num1, p11, p12, NewV, tolV, boxes1))
|
|
{
|
|
NbModif++;
|
|
num1--;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} // end if(Inter.NbSegments()==1)
|
|
}
|
|
}
|
|
}
|
|
if (hasModifWire)
|
|
{
|
|
isDone = Standard_True;
|
|
SeqWir.SetValue(n1, sewd1->Wire());
|
|
myContext->Replace(wire1, sewd1->Wire());
|
|
wire1 = sewd1->Wire();
|
|
// recompute boxes for wire1
|
|
boxes1.Clear();
|
|
Bnd_Box2d aNewBox1 = CreateBoxes2d(sewd1, face, boxes1);
|
|
aSeqWirBoxes.SetValue(n1, aNewBox1);
|
|
SeqWir.SetValue(n2, sewd2->Wire());
|
|
myContext->Replace(wire2, sewd2->Wire());
|
|
wire2 = sewd2->Wire();
|
|
// recompute boxes for wire2
|
|
boxes2.Clear();
|
|
Bnd_Box2d aNewBox2 = CreateBoxes2d(sewd2, face, boxes2);
|
|
aSeqWirBoxes.SetValue(n2, aNewBox2);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (isDone)
|
|
{
|
|
// update face
|
|
TopoDS_Shape emptyCopied = face.EmptyCopied();
|
|
TopoDS_Face newface = TopoDS::Face(emptyCopied);
|
|
newface.Orientation(TopAbs_FORWARD);
|
|
BRep_Builder B;
|
|
Standard_Integer i = 1;
|
|
for (i = 1; i <= SeqWir.Length(); i++)
|
|
{
|
|
TopoDS_Wire wire = TopoDS::Wire(SeqWir.Value(i));
|
|
B.Add(newface, wire);
|
|
}
|
|
for (i = 1; i <= SeqNMShapes.Length(); i++)
|
|
{
|
|
const TopoDS_Shape& aNMS = SeqNMShapes.Value(i);
|
|
B.Add(newface, aNMS);
|
|
}
|
|
newface.Orientation(ori);
|
|
myContext->Replace(face, newface);
|
|
face = newface;
|
|
}
|
|
return isDone;
|
|
}
|