Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
c5f20409cThis file is pinned to the selected release. Download the original to open it in your design tool.
// Created on: 1994-03-07
// Created by: Bruno DUMORTIER
// Copyright (c) 1994-1999 Matra Datavision
// 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 <BRep_Builder.hxx>
#include <BRep_Tool.hxx>
#include <BRepFill_Generator.hxx>
#include <BRepLib.hxx>
#include <BRepTools.hxx>
#include <BRepTools_WireExplorer.hxx>
#include <Geom2d_BezierCurve.hxx>
#include <Geom2d_Line.hxx>
#include <Geom_BezierCurve.hxx>
#include <Geom_ConicalSurface.hxx>
#include <Geom_Curve.hxx>
#include <Geom_CylindricalSurface.hxx>
#include <Geom_Plane.hxx>
#include <Geom_RectangularTrimmedSurface.hxx>
#include <Geom_Surface.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <GeomConvert.hxx>
#include <GeomFill_Generator.hxx>
#include <gp_Ax1.hxx>
#include <gp_Ax3.hxx>
#include <gp_Circ.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Lin.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Vec.hxx>
#include <Precision.hxx>
#include <Standard_NullObject.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
#include <TopExp.hxx>
#include <TopLoc_Location.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Shell.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Wire.hxx>
#include <TopTools_DataMapOfShapeShape.hxx>
//=================================================================================================
Standard_Integer DetectKPart(const TopoDS_Edge& Edge1, const TopoDS_Edge& Edge2)
{
// initializations
// !Note if IType set as -1 it means that occurs error with null 3d curve for the edge
Standard_Integer IType = 0;
// characteristics of the first edge
Standard_Real first1 = 0., last1 = 0., first2, last2, ff, ll;
TopLoc_Location loc;
TopoDS_Vertex V1, V2;
Handle(Geom_Curve) curv1, curv;
GeomAdaptor_Curve AdC1;
Standard_Boolean degen1 = BRep_Tool::Degenerated(Edge1);
// find the particular case
gp_Pnt pos1, pos;
Standard_Real dist;
Standard_Real dist1 = 0.;
gp_Ax1 axe1, axe;
if (degen1)
{
IType = -2;
TopExp::Vertices(Edge1, V1, V2);
pos1 = BRep_Tool::Pnt(V1);
}
else
{
curv1 = BRep_Tool::Curve(Edge1, loc, first1, last1);
if (curv1.IsNull())
{
return -1;
}
curv1 = Handle(Geom_Curve)::DownCast(curv1->Transformed(loc.Transformation()));
ff = first1;
ll = last1;
if (Edge1.Orientation() == TopAbs_REVERSED)
{
curv1->Reverse();
first1 = curv1->ReversedParameter(ll);
last1 = curv1->ReversedParameter(ff);
}
AdC1.Load(curv1);
if (AdC1.GetType() == GeomAbs_Circle)
{
// first circular section
IType = 1;
pos1 = AdC1.Circle().Location();
dist1 = AdC1.Circle().Radius();
axe1 = AdC1.Circle().Axis();
}
else if (AdC1.GetType() == GeomAbs_Line)
{
// first straight line section
IType = 4;
pos1 = AdC1.Line().Location();
dist1 = AdC1.Value(first1).Distance(AdC1.Value(last1));
gp_Vec vec(AdC1.Value(first1), AdC1.Value(last1));
gp_Dir dir(vec);
axe1 = gp_Ax1(AdC1.Value(first1), dir);
}
else
{
// first section of any type
IType = 0;
}
}
if (IType != 0)
{
Standard_Boolean degen2 = BRep_Tool::Degenerated(Edge2);
if (degen2)
{
TopExp::Vertices(Edge2, V1, V2);
pos = BRep_Tool::Pnt(V1);
if (IType == 1)
{
// the only particular case with degenerated edge at end : the cone
if (pos.IsEqual(pos1, Precision::Confusion()))
{
// the top is mixed with the center of the circle
IType = 0;
}
else
{
gp_Vec vec(pos1, pos);
gp_Dir dir(vec);
axe = gp_Ax1(pos1, dir);
if (axe.IsParallel(axe1, Precision::Angular()))
{
// the top is on the axis of the circle
IType = 2;
}
else
{
// incorrect top --> no particular case
IType = 0;
}
}
}
else if (IType != 4)
{ // not a plane
// no particular case
IType = 0;
}
}
else
{
curv = BRep_Tool::Curve(Edge2, loc, first2, last2);
if (curv.IsNull())
{
return -1;
}
curv = Handle(Geom_Curve)::DownCast(curv->Transformed(loc.Transformation()));
ff = first2;
ll = last2;
if (Edge2.Orientation() == TopAbs_REVERSED)
{
curv->Reverse();
first2 = curv->ReversedParameter(ll);
last2 = curv->ReversedParameter(ff);
}
GeomAdaptor_Curve AdC(curv);
if (IType > 0 && IType < 4)
{
if (AdC.GetType() != GeomAbs_Circle)
{
// section not circular --> no particular case
IType = 0;
}
else
{
if (AdC.Circle().Axis().IsCoaxial(axe1, Precision::Angular(), Precision::Confusion()))
{
// same axis
if (Abs(AdC.Circle().Radius() - dist1) < Precision::Confusion())
{
// possibility of cylinder or a piece of cylinder
Standard_Real h1 = Abs(last1 - first1), h2 = Abs(last2 - first2);
Standard_Boolean Same,
SameParametricLength = (Abs(h1 - h2) < Precision::PConfusion());
Standard_Real m1 = (first1 + last1) / 2., m2 = (first2 + last2) / 2.;
gp_Pnt P1, P2;
gp_Vec DU;
AdC1.D1(m1, P1, DU);
AdC.D0(m2, P2);
Same = SameParametricLength && (gp_Vec(P1, P2).IsNormal(DU, Precision::Angular()));
if (Same)
{
// cylinder or piece of cylinder
IType = 1;
}
else
{
// the interval of definition is not correct
IType = 0;
}
}
else
{
// possibility of cone truncation
Standard_Real h1 = Abs(last1 - first1), h2 = Abs(last2 - first2);
Standard_Boolean Same,
SameParametricLength = (Abs(h1 - h2) < Precision::PConfusion());
Standard_Real m1 = (first1 + last1) / 2., m2 = (first2 + last2) / 2.;
gp_Pnt P1, P2;
gp_Vec DU;
AdC1.D1(m1, P1, DU);
AdC.D0(m2, P2);
Same = SameParametricLength && (gp_Vec(P1, P2).IsNormal(DU, Precision::Angular()));
if (Same)
{
// truncation of cone
IType = 2;
}
else
{
// the interval of definition is not correct
IType = 0;
}
}
if (AdC.Circle().Location().IsEqual(pos1, Precision::Confusion()))
{
// the centers are mixed
IType = 0;
}
}
else
{
// different axis
if (AdC.Circle().Radius() == dist1)
{
// torus ?
IType = 3;
}
else
{
// different radius --> no particular case
IType = 0;
}
}
}
}
else if (IType >= 4)
{
if (AdC.GetType() != GeomAbs_Line)
{
// not a straight line section --> no particular case
IType = 0;
}
else
{
pos = AdC.Line().Location();
dist = AdC.Value(first2).Distance(AdC.Value(last2));
gp_Vec vec(AdC.Value(first2), AdC.Value(last2));
gp_Dir aDir(vec);
axe = gp_Ax1(AdC.Value(first2), aDir);
if (axe.IsParallel(axe1, Precision::Angular()))
{
// parallel straight line
if (Abs(dist - dist1) < Precision::Confusion())
{
gp_Dir dir(gp_Vec(AdC1.Value(first1), AdC.Value(first2)));
if (dir.IsNormal(gp_Dir(vec), Precision::Angular()))
{
// plane
IType = 4;
}
else
{
// extrusion ?
IType = 5;
}
}
else
{
// different length --> no particular case
IType = 0;
}
}
else
{
// not parallel straight line --> no particular case
IType = 0;
}
}
}
else if (IType == -2)
{
if (AdC.GetType() == GeomAbs_Line)
IType = 4; // plane
else if (AdC.GetType() == GeomAbs_Circle)
{
// the only particular case with degenerated edge at the beginning the cone
pos = AdC.Circle().Location();
axe = AdC.Circle().Axis();
if (pos1.IsEqual(pos, Precision::Confusion()))
{
// the top is mixed with the center of the circle
IType = 0;
}
else
{
gp_Vec vec(pos1, pos);
gp_Dir dir(vec);
axe1 = gp_Ax1(pos1, dir);
if (axe.IsParallel(axe1, Precision::Angular()))
{
// the top is on the axis of the circle
IType = -2;
}
else
{
// incorrect top --> no particular case
IType = 0;
}
}
}
else
IType = 0;
}
}
}
// torus and extrusion are not particular cases.
if (IType == 3 || IType == 5)
IType = 0;
return IType;
}
//=======================================================================
// function : CreateKPart
// purpose : Returns true if there is no errors occur
//=======================================================================
Standard_Boolean CreateKPart(const TopoDS_Edge& Edge1,
const TopoDS_Edge& Edge2,
const Standard_Integer IType,
Handle(Geom_Surface)& Surf)
{
// find the dimension
TopoDS_Vertex V1, V2;
TopLoc_Location loc;
Standard_Real a1, b1, aa = 0., bb = 0.;
TopoDS_Vertex v1f, v1l, v2f, v2l;
Standard_Boolean isDone = Standard_True;
// find characteristics of the first edge
Handle(Geom_Curve) C1;
Standard_Boolean degen1 = BRep_Tool::Degenerated(Edge1);
if (degen1)
{
// cone with degenerated edge at the top
TopExp::Vertices(Edge1, v1f, v1l);
}
else
{
C1 = BRep_Tool::Curve(Edge1, loc, a1, b1);
if (C1.IsNull())
{
return Standard_False;
}
C1 = Handle(Geom_Curve)::DownCast(C1->Transformed(loc.Transformation()));
aa = a1;
bb = b1;
if (Edge1.Orientation() == TopAbs_REVERSED)
{
C1->Reverse();
aa = C1->ReversedParameter(b1);
bb = C1->ReversedParameter(a1);
TopExp::Vertices(Edge1, v1l, v1f);
}
else
{
TopExp::Vertices(Edge1, v1f, v1l);
}
}
// find characteristics of the second edge
Handle(Geom_Curve) C2;
Standard_Boolean degen2 = BRep_Tool::Degenerated(Edge2);
if (degen2)
{
// cone with degenerated edge at the top
TopExp::Vertices(Edge2, v2f, v2l);
}
else
{
C2 = BRep_Tool::Curve(Edge2, loc, a1, b1);
if (C2.IsNull())
{
return Standard_False;
}
C2 = Handle(Geom_Curve)::DownCast(C2->Transformed(loc.Transformation()));
if (Edge2.Orientation() == TopAbs_REVERSED)
{
C2->Reverse();
if (degen1)
{
aa = a1;
bb = b1;
}
TopExp::Vertices(Edge2, v2l, v2f);
}
else
{
if (degen1)
{
aa = a1; // C2->ReversedParameter(b1);
bb = b1; // C2->ReversedParameter(a1);
}
TopExp::Vertices(Edge2, v2f, v2l);
}
}
// create the new surface
TopoDS_Face face;
TopoDS_Wire W;
TopoDS_Edge edge1, edge2, edge3, edge4, couture;
TopoDS_Wire newW1, newW2;
BRep_Builder BW1, BW2;
BW1.MakeWire(newW1);
BW2.MakeWire(newW2);
GeomAdaptor_Curve aC1Adaptor;
if (!C1.IsNull())
aC1Adaptor.Load(C1);
GeomAdaptor_Curve aC2Adaptor;
if (!C2.IsNull())
aC2Adaptor.Load(C2);
// calculate the surface
Handle(Geom_Surface) surface;
Standard_Real V, Rad;
if (IType == 1)
{
// cylindrical surface
gp_Circ c1 = aC1Adaptor.Circle();
gp_Circ c2 = aC2Adaptor.Circle();
gp_Ax3 Ac1 = c1.Position();
V = gp_Vec(c1.Location(), c2.Location()).Dot(gp_Vec(Ac1.Direction()));
if (V < 0.)
{
Ac1.ZReverse();
V = -V;
}
Handle(Geom_CylindricalSurface) Cyl = new Geom_CylindricalSurface(Ac1, c1.Radius());
surface = new Geom_RectangularTrimmedSurface(Cyl, aa, bb, Min(0., V), Max(0., V));
}
else if (IType == 2)
{
// conical surface
gp_Circ k1 = aC1Adaptor.Circle();
gp_Ax3 Ak1 = k1.Position();
if (degen2)
{
V = gp_Vec(k1.Location(), BRep_Tool::Pnt(v2f)).Dot(gp_Vec(Ak1.Direction()));
Rad = -k1.Radius();
}
else
{
gp_Circ k2 = aC2Adaptor.Circle();
V = gp_Vec(k1.Location(), k2.Location()).Dot(gp_Vec(Ak1.Direction()));
Rad = k2.Radius() - k1.Radius();
}
if (V < 0.)
{
Ak1.ZReverse();
V = -V;
}
Standard_Real Ang = ATan(Rad / V);
Handle(Geom_ConicalSurface) Cone = new Geom_ConicalSurface(Ak1, Ang, k1.Radius());
V /= Cos(Ang);
surface = new Geom_RectangularTrimmedSurface(Cone, aa, bb, Min(0., V), Max(0., V));
}
else if (IType == -2)
{
// conical surface with the top at the beginning (degen1 is true)
gp_Circ k2 = aC2Adaptor.Circle();
gp_Ax3 Ak2 = k2.Position();
Ak2.SetLocation(BRep_Tool::Pnt(v1f));
V = gp_Vec(BRep_Tool::Pnt(v1f), k2.Location()).Dot(gp_Vec(Ak2.Direction()));
Rad = k2.Radius(); // - k2.Radius();
if (V < 0.)
{
Ak2.ZReverse();
V = -V;
}
Standard_Real Ang = ATan(Rad / V);
Handle(Geom_ConicalSurface) Cone = new Geom_ConicalSurface(Ak2, Ang, 0.);
V /= Cos(Ang);
surface = new Geom_RectangularTrimmedSurface(Cone, aa, bb, Min(0., V), Max(0., V));
}
else if (IType == 3)
{
// torus surface ?
}
else if (IType == 4)
{
// surface plane
gp_Lin L1, L2, aLine;
if (!degen1)
{
L1 = aC1Adaptor.Line();
aLine = L1;
}
if (!degen2)
{
L2 = aC2Adaptor.Line();
aLine = L2;
}
gp_Pnt P1 = (degen1) ? BRep_Tool::Pnt(v1f) : L1.Location();
gp_Pnt P2 = (degen2) ? BRep_Tool::Pnt(v2f) : L2.Location();
gp_Vec P1P2(P1, P2);
gp_Dir D1 = aLine.Direction();
gp_Ax3 Ax(aLine.Location(), gp_Dir(D1.Crossed(P1P2)), D1);
Handle(Geom_Plane) Plan = new Geom_Plane(Ax);
V = P1P2.Dot(Ax.YDirection());
surface = Plan;
// surface = new Geom_RectangularTrimmedSurface
//( Plan, aa, bb, Min(0.,V), Max(0.,V) );
}
else if (IType == 5)
{
// surface of extrusion ?
}
else
{
// IType incorrect
}
Surf = surface;
return isDone;
}
//=================================================================================================
static TopoDS_Edge CreateNewEdge(const TopoDS_Edge& theEdge,
TopTools_DataMapOfShapeShape& theCopiedEdges,
const TopoDS_Wire& theWire,
TopTools_IndexedMapOfShape& theModifWires)
{
BRep_Builder aBuilder;
TopoDS_Edge aNewEdge;
aNewEdge = TopoDS::Edge(theEdge.EmptyCopied());
TopoDS_Iterator anIterator(theEdge);
for (; anIterator.More(); anIterator.Next())
{
aBuilder.Add(aNewEdge, anIterator.Value());
}
theCopiedEdges.Bind(theEdge, aNewEdge);
if (!theModifWires.Contains(theWire))
{
theModifWires.Add(theWire);
}
return aNewEdge;
}
//=================================================================================================
BRepFill_Generator::BRepFill_Generator()
: myMutableInput(Standard_True),
myStatus(BRepFill_ThruSectionErrorStatus_NotDone)
{
}
//=================================================================================================
void BRepFill_Generator::AddWire(const TopoDS_Wire& Wire)
{
myWires.Append(Wire);
}
//=================================================================================================
void BRepFill_Generator::Perform()
{
myStatus = BRepFill_ThruSectionErrorStatus_Done;
TopoDS_Shell Shell;
TopoDS_Face Face;
TopoDS_Shape S1, S2;
TopoDS_Edge Edge1, Edge2, Edge3, Edge4, Couture;
BRep_Builder B;
B.MakeShell(myShell);
Standard_Integer Nb = myWires.Length();
TopTools_IndexedMapOfShape aModifWires; // indexed map for debugging
BRepTools_WireExplorer ex1, ex2;
Standard_Boolean aFirstWire = Standard_True;
Standard_Boolean wPoint1, wPoint2, uClosed = Standard_False, DegenFirst = Standard_False,
DegenLast = Standard_False;
for (Standard_Integer i = 1; i <= Nb - 1; i++)
{
TopoDS_Wire Wire1 = TopoDS::Wire(myWires(i));
TopoDS_Wire Wire2 = TopoDS::Wire(myWires(i + 1));
wPoint1 = Standard_False;
if (i == 1)
{
wPoint1 = Standard_True;
for (ex1.Init(Wire1); ex1.More(); ex1.Next())
{
wPoint1 = wPoint1 && (BRep_Tool::Degenerated(ex1.Current()));
}
DegenFirst = wPoint1;
TopoDS_Vertex V1, V2;
TopExp::Vertices(Wire1, V1, V2);
uClosed = V1.IsSame(V2);
}
wPoint2 = Standard_False;
if (i == Nb - 1)
{
wPoint2 = Standard_True;
for (ex2.Init(Wire2); ex2.More(); ex2.Next())
{
wPoint2 = wPoint2 && (BRep_Tool::Degenerated(ex2.Current()));
}
DegenLast = wPoint2;
}
ex1.Init(Wire1);
ex2.Init(Wire2);
TopTools_DataMapOfShapeShape Map;
Standard_Boolean tantque = ex1.More() && ex2.More();
while (tantque)
{
TopoDS_Vertex V1f, V1l, V2f, V2l, Vf_toMap, Vl_toMap;
const TopoDS_Edge& anOrEdge1 = TopoDS::Edge(ex1.Current());
const TopoDS_Edge& anOrEdge2 = TopoDS::Edge(ex2.Current());
Standard_Boolean degen1 = BRep_Tool::Degenerated(anOrEdge1);
Standard_Boolean degen2 = BRep_Tool::Degenerated(anOrEdge2);
if (degen1)
{
TopoDS_Shape aLocalShape = anOrEdge1.EmptyCopied();
Edge1 = TopoDS::Edge(aLocalShape);
// Edge1 = TopoDS::Edge(ex1.Current().EmptyCopied());
// aLocalShape = ex1.Current();
// TopExp::Vertices(TopoDS::Edge(aLocalShape),V1f,V1l);
TopExp::Vertices(anOrEdge1, V1f, V1l);
V1f.Orientation(TopAbs_FORWARD);
B.Add(Edge1, V1f);
V1l.Orientation(TopAbs_REVERSED);
B.Add(Edge1, V1l);
B.Range(Edge1, 0, 1);
myOldNewShapes.Bind(anOrEdge1, Edge1);
}
else
{
Edge1 = anOrEdge1;
}
if (degen2)
{
TopoDS_Shape aLocalShape = anOrEdge2.EmptyCopied();
Edge2 = TopoDS::Edge(aLocalShape);
// Edge2 = TopoDS::Edge(ex2.Current().EmptyCopied());
TopExp::Vertices(anOrEdge2, V2f, V2l);
V2f.Orientation(TopAbs_FORWARD);
B.Add(Edge2, V2f);
V2l.Orientation(TopAbs_REVERSED);
B.Add(Edge2, V2l);
B.Range(Edge2, 0, 1);
myOldNewShapes.Bind(anOrEdge2, Edge2);
}
else
{
Edge2 = anOrEdge2;
}
Standard_Boolean Periodic =
(BRep_Tool::IsClosed(Edge1) || degen1) && (BRep_Tool::IsClosed(Edge2) || degen2);
// ATTENTION : a non-punctual wire should not
// contain a punctual edge
if (!wPoint1)
ex1.Next();
if (!wPoint2)
ex2.Next();
// initialization of vertices
Handle(Geom_Surface) Surf;
Standard_Real f1 = 0, l1 = 1, f2 = 0, l2 = 1;
if (Edge1.Orientation() == TopAbs_REVERSED)
TopExp::Vertices(Edge1, V1l, V1f);
else
TopExp::Vertices(Edge1, V1f, V1l);
if (Edge2.Orientation() == TopAbs_REVERSED)
TopExp::Vertices(Edge2, V2l, V2f);
else
TopExp::Vertices(Edge2, V2f, V2l);
if (degen1)
{
Vf_toMap = V2f;
Vl_toMap = V2l;
}
else
{
Vf_toMap = V1f;
Vl_toMap = V1l;
}
// processing of KPart
Standard_Integer IType = DetectKPart(Edge1, Edge2);
if (IType == -1)
{
myStatus = BRepFill_ThruSectionErrorStatus_Null3DCurve;
return;
}
if (IType == 0)
{
// no part cases
TopLoc_Location L, L1, L2;
Handle(Geom_Curve) C1, C2;
TColgp_Array1OfPnt Extremities(1, 2);
if (degen1)
{
Extremities(1) = BRep_Tool::Pnt(V1f);
Extremities(2) = BRep_Tool::Pnt(V1l);
C1 = new Geom_BezierCurve(Extremities);
}
else
{
C1 = BRep_Tool::Curve(Edge1, L1, f1, l1);
if (C1.IsNull())
{
myStatus = BRepFill_ThruSectionErrorStatus_Null3DCurve;
return;
}
}
if (degen2)
{
Extremities(1) = BRep_Tool::Pnt(V2l);
Extremities(2) = BRep_Tool::Pnt(V2f);
C2 = new Geom_BezierCurve(Extremities);
}
else
{
C2 = BRep_Tool::Curve(Edge2, L2, f2, l2);
if (C2.IsNull())
{
myStatus = BRepFill_ThruSectionErrorStatus_Null3DCurve;
return;
}
}
// compute the location
Standard_Boolean SameLoc = Standard_False;
// transform and trim the curves
if (Abs(f1 - C1->FirstParameter()) > Precision::PConfusion()
|| Abs(l1 - C1->LastParameter()) > Precision::PConfusion())
{
C1 = new Geom_TrimmedCurve(C1, f1, l1);
}
else
{
C1 = Handle(Geom_Curve)::DownCast(C1->Copy());
}
if (!SameLoc)
C1->Transform(L1.Transformation());
if (Edge1.Orientation() == TopAbs_REVERSED)
{
C1->Reverse();
}
if (Abs(f2 - C2->FirstParameter()) > Precision::PConfusion()
|| Abs(l2 - C2->LastParameter()) > Precision::PConfusion())
{
C2 = new Geom_TrimmedCurve(C2, f2, l2);
}
else
{
C2 = Handle(Geom_Curve)::DownCast(C2->Copy());
}
if (!SameLoc)
C2->Transform(L2.Transformation());
if (Edge2.Orientation() == TopAbs_REVERSED)
{
C2->Reverse();
}
GeomFill_Generator Generator;
Generator.AddCurve(C1);
Generator.AddCurve(C2);
Generator.Perform(Precision::PConfusion());
Surf = Generator.Surface();
B.MakeFace(Face, Surf, Precision::Confusion());
}
else
{
// particular case
if (!CreateKPart(Edge1, Edge2, IType, Surf))
{
myStatus = BRepFill_ThruSectionErrorStatus_Null3DCurve;
return;
}
B.MakeFace(Face, Surf, Precision::Confusion());
}
// make the missing edges
Standard_Real first, last;
Surf->Bounds(f1, l1, f2, l2);
if (IType == 0)
{
first = f2;
last = l2;
}
else
{
first = 0.;
last = 1.;
}
if (Map.IsBound(Vf_toMap))
{
TopoDS_Shape aLocalShape = Map(Vf_toMap).Reversed();
Edge3 = TopoDS::Edge(aLocalShape);
// Edge3 = TopoDS::Edge(Map(V1f).Reversed());
}
else
{
if (V1f.IsSame(V2f))
{
B.MakeEdge(Edge3);
B.Degenerated(Edge3, Standard_True);
}
else
{
Handle(Geom_Curve) CC;
TColgp_Array1OfPnt Extremities(1, 2);
if (IType == 0)
{
// general case : Edge3 corresponds to iso U=f1
CC = Surf->UIso(f1);
}
else
{
// particular case : it is required to calculate the curve 3d
Extremities(1) = BRep_Tool::Pnt(V1f);
Extremities(2) = BRep_Tool::Pnt(V2f);
CC = new Geom_BezierCurve(Extremities);
}
B.MakeEdge(Edge3, CC, Precision::Confusion());
}
V1f.Orientation(TopAbs_FORWARD);
B.Add(Edge3, V1f);
V2f.Orientation(TopAbs_REVERSED);
B.Add(Edge3, V2f);
B.Range(Edge3, first, last);
Edge3.Reverse();
Map.Bind(Vf_toMap, Edge3);
}
Standard_Boolean CommonEdge = Standard_False;
if (Map.IsBound(Vl_toMap))
{
TopoDS_Shape aLocalShape = Map(Vl_toMap).Reversed();
const TopoDS_Edge CommonE = TopoDS::Edge(aLocalShape);
// const TopoDS_Edge CommonE = TopoDS::Edge(Map(V1l).Reversed());
TopoDS_Vertex V1, V2;
TopExp::Vertices(CommonE, V1, V2);
CommonEdge = V1.IsSame(V1l) && V2.IsSame(V2l);
}
if (CommonEdge)
{
TopoDS_Shape aLocalShape = Map(Vl_toMap).Reversed();
Edge4 = TopoDS::Edge(aLocalShape);
// Edge4 = TopoDS::Edge(Map(V1l).Reversed());
}
else
{
if (V1l.IsSame(V2l))
{
B.MakeEdge(Edge4);
B.Degenerated(Edge4, Standard_True);
}
else
{
Handle(Geom_Curve) CC;
TColgp_Array1OfPnt Extremities(1, 2);
if (IType == 0)
{
// general case : Edge4 corresponds to iso U=l1
CC = Surf->UIso(l1);
}
else
{
// particular case : it is required to calculate the curve 3d
Extremities(1) = BRep_Tool::Pnt(V1l);
Extremities(2) = BRep_Tool::Pnt(V2l);
CC = new Geom_BezierCurve(Extremities);
}
B.MakeEdge(Edge4, CC, Precision::Confusion());
}
V1l.Orientation(TopAbs_FORWARD);
B.Add(Edge4, V1l);
V2l.Orientation(TopAbs_REVERSED);
B.Add(Edge4, V2l);
B.Range(Edge4, first, last);
Map.Bind(Vl_toMap, Edge4);
}
if (!myMutableInput)
{
if (!degen1) // if true=>already empty-copied
{
const TopoDS_Shape* aNewEd1 = myOldNewShapes.Seek(Edge1);
if (aNewEd1)
{
Edge1 = TopoDS::Edge(*aNewEd1);
}
else if (aFirstWire
&& (IType != 4 || BRep_Tool::SameParameter(Edge1)
|| BRep_Tool::SameRange(Edge1)))
{
// if such expression is true and mutableInput is false => pre-copy the edge to prevent
// a following modifying (see code below)
Edge1 = CreateNewEdge(Edge1, myOldNewShapes, Wire1, aModifWires);
}
}
if (!degen2)
{
const TopoDS_Shape* aNewEd2 = myOldNewShapes.Seek(Edge2);
if (aNewEd2)
{
Edge2 = TopoDS::Edge(*aNewEd2);
}
else if (IType != 4 || BRep_Tool::SameParameter(Edge2) || BRep_Tool::SameRange(Edge2))
{
Edge2 = CreateNewEdge(Edge2, myOldNewShapes, Wire2, aModifWires);
}
}
}
// set the pcurves
constexpr Standard_Real T = Precision::Confusion();
if (IType != 4) // not plane
{
if (Edge1.Orientation() == TopAbs_REVERSED)
{
B.UpdateEdge(Edge1, new Geom2d_Line(gp_Pnt2d(0, f2), gp_Dir2d(-1, 0)), Face, T);
B.Range(Edge1, Face, -l1, -f1);
}
else
{
B.UpdateEdge(Edge1, new Geom2d_Line(gp_Pnt2d(0, f2), gp_Dir2d(1, 0)), Face, T);
B.Range(Edge1, Face, f1, l1);
}
if (Edge2.Orientation() == TopAbs_REVERSED)
{
B.UpdateEdge(Edge2, new Geom2d_Line(gp_Pnt2d(0, l2), gp_Dir2d(-1, 0)), Face, T);
B.Range(Edge2, Face, -l1, -f1);
}
else
{
B.UpdateEdge(Edge2, new Geom2d_Line(gp_Pnt2d(0, l2), gp_Dir2d(1, 0)), Face, T);
B.Range(Edge2, Face, f1, l1);
}
}
if (IType == 0)
{
if (Periodic)
{
B.UpdateEdge(Edge3,
new Geom2d_Line(gp_Pnt2d(l1, 0), gp_Dir2d(0, 1)),
new Geom2d_Line(gp_Pnt2d(f1, 0), gp_Dir2d(0, 1)),
Face,
T);
}
else
{
B.UpdateEdge(Edge3, new Geom2d_Line(gp_Pnt2d(f1, 0), gp_Dir2d(0, 1)), Face, T);
B.UpdateEdge(Edge4, new Geom2d_Line(gp_Pnt2d(l1, 0), gp_Dir2d(0, 1)), Face, T);
}
}
else
{
// KPart
if (Periodic)
{
TColgp_Array1OfPnt2d Extrem1(1, 2);
Extrem1(1).SetCoord(l1, f2);
Extrem1(2).SetCoord(l1, l2);
TColgp_Array1OfPnt2d Extrem2(1, 2);
Extrem2(1).SetCoord(f1, f2);
Extrem2(2).SetCoord(f1, l2);
B.UpdateEdge(Edge3,
new Geom2d_BezierCurve(Extrem1),
new Geom2d_BezierCurve(Extrem2),
Face,
T);
}
else if (IType != 4)
{ // not plane
TColgp_Array1OfPnt2d Extrem2(1, 2);
Extrem2(1).SetCoord(f1, f2);
Extrem2(2).SetCoord(f1, l2);
B.UpdateEdge(Edge3, new Geom2d_BezierCurve(Extrem2), Face, T);
TColgp_Array1OfPnt2d Extrem1(1, 2);
Extrem1(1).SetCoord(l1, f2);
Extrem1(2).SetCoord(l1, l2);
B.UpdateEdge(Edge4, new Geom2d_BezierCurve(Extrem1), Face, T);
}
}
// Set the non parameter flag;
B.SameParameter(Edge1, Standard_False);
B.SameParameter(Edge2, Standard_False);
B.SameParameter(Edge3, Standard_False);
B.SameParameter(Edge4, Standard_False);
B.SameRange(Edge1, Standard_False);
B.SameRange(Edge2, Standard_False);
B.SameRange(Edge3, Standard_False);
B.SameRange(Edge4, Standard_False);
// make the wire
TopoDS_Wire aWire;
B.MakeWire(aWire);
if (!(degen1 && IType == 4))
{
B.Add(aWire, Edge1);
}
B.Add(aWire, Edge4);
if (!(degen2 && IType == 4))
{
B.Add(aWire, Edge2.Reversed());
}
B.Add(aWire, Edge3);
B.Add(Face, aWire);
B.Add(myShell, Face);
// complete myMap for edge1
if (!(degen1 && IType == 4))
{
TopoDS_Edge aREd = anOrEdge1;
if (degen1)
{
aREd = Edge1;
}
if (!myMap.IsBound(aREd))
{
TopTools_ListOfShape Empty;
myMap.Bind(aREd, Empty);
}
myMap(aREd).Append(Face);
}
tantque = ex1.More() && ex2.More();
if (wPoint1)
tantque = ex2.More();
if (wPoint2)
tantque = ex1.More();
}
aFirstWire = Standard_False;
}
// all vertices from myShell are the part of orig. section wires
if (myMutableInput)
{
BRepLib::SameParameter(myShell);
}
else
{
TopTools_DataMapIteratorOfDataMapOfShapeShape aMapIt(myOldNewShapes);
for (; aMapIt.More(); aMapIt.Next())
{
const TopoDS_Shape& aK = aMapIt.Key();
const TopoDS_Shape& aVal = aMapIt.Value();
myReshaper.Replace(aK, aVal);
}
BRepLib::SameParameter(myShell, myReshaper);
myShell = TopoDS::Shell(myReshaper.Apply(myShell));
}
if (uClosed && DegenFirst && DegenLast)
{
myShell.Closed(Standard_True);
}
// update wire's history
TopoDS_Iterator anItEdge;
for (int i = 1; i <= aModifWires.Extent(); i++)
{
const TopoDS_Shape& aCurWire = aModifWires(i);
TopoDS_Wire aNewWire;
B.MakeWire(aNewWire);
anItEdge.Initialize(aCurWire);
for (; anItEdge.More(); anItEdge.Next())
{
const TopoDS_Shape& aCurEdge = anItEdge.Value(); // edges only
const TopoDS_Shape& aNewEdge = ResultShape(aCurEdge);
B.Add(aNewWire, aNewEdge);
}
aNewWire.Free(aCurWire.Free());
aNewWire.Modified(aCurWire.Modified());
aNewWire.Checked(aCurWire.Checked());
aNewWire.Orientable(aCurWire.Orientable());
aNewWire.Closed(aCurWire.Closed());
aNewWire.Infinite(aCurWire.Infinite());
aNewWire.Convex(aCurWire.Convex());
myOldNewShapes.Bind(aCurWire, aNewWire);
}
}
//=================================================================================================
const TopTools_ListOfShape& BRepFill_Generator::GeneratedShapes(const TopoDS_Shape& SSection) const
{
if (myMap.IsBound(SSection))
{
return myMap(SSection);
}
else
{
static TopTools_ListOfShape Empty;
return Empty;
}
}
//=================================================================================================
const TopTools_DataMapOfShapeListOfShape& BRepFill_Generator::Generated() const
{
return myMap;
}
//=================================================================================================
TopoDS_Shape BRepFill_Generator::ResultShape(const TopoDS_Shape& theShape) const
{
const TopoDS_Shape* aShape = myOldNewShapes.Seek(theShape);
TopoDS_Shape aNewShape = aShape ? *aShape : theShape;
TopoDS_Shape aPrevShape;
do
{
aPrevShape = aNewShape;
aNewShape = myReshaper.Value(aNewShape);
} while (aNewShape != aPrevShape);
return aNewShape;
}
//=================================================================================================
void BRepFill_Generator::SetMutableInput(const Standard_Boolean theIsMutableInput)
{
myMutableInput = theIsMutableInput;
}
//=================================================================================================
Standard_Boolean BRepFill_Generator::IsMutableInput() const
{
return myMutableInput;
}