Loading files
3d097a032This file is pinned to the selected release. Download the original to open it in your design tool.
// Created on: 1994-03-29
// Created by: Isabelle GRIGNON
// 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 <Adaptor3d_CurveOnSurface.hxx>
#include <BRep_Tool.hxx>
#include <BRepBlend_Line.hxx>
#include <BRepLProp_CLProps.hxx>
#include <BRepTopAdaptor_TopolTool.hxx>
#include <BSplCLib.hxx>
#include <ChFi3d.hxx>
#include <ChFi3d_Builder_0.hxx>
#include <ChFi3d_FilBuilder.hxx>
#include <ChFiDS_CommonPoint.hxx>
#include <ChFiDS_FaceInterference.hxx>
#include <ChFiDS_FilSpine.hxx>
#include <ChFiDS_SurfData.hxx>
#include <NCollection_Sequence.hxx>
#include <NCollection_HSequence.hxx>
#include <ChFiDS_Regul.hxx>
#include <ChFiDS_Spine.hxx>
#include <ChFiDS_State.hxx>
#include <ChFiDS_Stripe.hxx>
#include <ChFiKPart_ComputeData.hxx>
#include <Geom_BSplineSurface.hxx>
#include <Geom2d_TrimmedCurve.hxx>
#include <Geom2dAdaptor_Curve.hxx>
#include <Geom2dConvert.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <GeomAdaptor_Surface.hxx>
#include <GeomFill_ConstrainedFilling.hxx>
#include <GeomFill_SimpleBound.hxx>
#include <gp_Ax3.hxx>
#include <gp_Dir.hxx>
#include <gp_Pln.hxx>
#include <gp_Pnt.hxx>
#include <gp_Pnt2d.hxx>
#include <Standard_ErrorHandler.hxx>
#include <Standard_NotImplemented.hxx>
#include <StdFail_NotDone.hxx>
#include <NCollection_Array1.hxx>
#include <Standard_Integer.hxx>
#include <NCollection_List.hxx>
#include <TopAbs.hxx>
#include <TopAbs_Orientation.hxx>
#include <TopExp.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopOpeBRepDS_DataStructure.hxx>
#include <TopOpeBRepDS_HDataStructure.hxx>
//=======================================================================
// function : ToricRotule
// purpose : Test if it is a particular case of torus routine.
// Three planes with two constant incident fillets
// of the same radius and the third face perpendicular to
// two others are required.
//=======================================================================
static bool ToricRotule(const BRepAdaptor_Surface& fac,
const BRepAdaptor_Surface& s1,
const BRepAdaptor_Surface& s2,
const occ::handle<ChFiDS_Stripe>& c1,
const occ::handle<ChFiDS_Stripe>& c2)
{
double tolesp = 1.e-7;
occ::handle<ChFiDS_FilSpine> sp1 = occ::down_cast<ChFiDS_FilSpine>(c1->Spine());
occ::handle<ChFiDS_FilSpine> sp2 = occ::down_cast<ChFiDS_FilSpine>(c2->Spine());
if (sp1.IsNull() || sp2.IsNull())
{
return false;
}
if (!sp1->IsConstant() || !sp2->IsConstant())
{
return false;
}
if ((fac.GetType() != GeomAbs_Plane) || (s1.GetType() != GeomAbs_Plane)
|| (s2.GetType() != GeomAbs_Plane))
{
return false;
}
gp_Dir df = fac.Plane().Position().Direction();
gp_Dir ds1 = s1.Plane().Position().Direction();
gp_Dir ds2 = s2.Plane().Position().Direction();
if (std::abs(df.Dot(ds1)) >= tolesp || std::abs(df.Dot(ds2)) >= tolesp)
{
return false;
}
double r1 = sp1->Radius();
double r2 = sp2->Radius();
return std::abs(r1 - r2) < tolesp;
}
static void RemoveSD(occ::handle<ChFiDS_Stripe>& Stripe, const int num1, const int num2)
{
NCollection_Sequence<occ::handle<ChFiDS_SurfData>>& Seq =
Stripe->ChangeSetOfSurfData()->ChangeSequence();
if (Seq.IsEmpty())
{
return;
}
if (num1 == num2)
{
Seq.Remove(num1);
}
else
{
Seq.Remove(num1, num2);
}
}
//=================================================================================================
void ChFi3d_FilBuilder::PerformTwoCorner(const int Index)
{
done = false;
const TopoDS_Vertex& Vtx = myVDataMap.FindKey(Index);
TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
NCollection_List<occ::handle<ChFiDS_Stripe>>::Iterator It;
It.Initialize(myVDataMap(Index));
occ::handle<ChFiDS_Stripe> st1, st2;
int Sens1, Sens2;
int Isd1, Isd2, i1, i2;
occ::handle<ChFiDS_SurfData> sd1, sd2;
NCollection_Sequence<occ::handle<ChFiDS_SurfData>> SeqFil1, SeqFil2;
occ::handle<Geom_Surface> surf1, surf2;
bool OkinterCC, Okvisavis, SameSide;
int IFaCo1, IFaCo2;
double UIntPC1, UIntPC2;
TopoDS_Face FaCo;
TopoDS_Edge E1, E2, E;
TopoDS_Vertex V1, V2;
// gp_Pnt P1,P2;
int nbsurf1, nbsurf2, deb1, fin1, deb2, fin2;
double parE1, parE2;
// Necessary information on fillets is extracted
//------------------------------------------------------
// the first
//----------
st1 = It.Value();
Isd1 = ChFi3d_IndexOfSurfData(Vtx, st1, Sens1);
// the second
//----------
It.Next();
st2 = It.Value();
if (st2 == st1)
{
Sens2 = -1;
Isd2 = st2->SetOfSurfData()->Length();
}
else
{
Isd2 = ChFi3d_IndexOfSurfData(Vtx, st2, Sens2);
}
// If two edges to rounded are tangent GeomPlate is called
if (Sens1 == 1)
{
E1 = st1->Spine()->Edges(1);
}
else
{
E1 = st1->Spine()->Edges(st1->Spine()->NbEdges());
}
if (Sens2 == 1)
{
E2 = st2->Spine()->Edges(1);
}
else
{
E2 = st2->Spine()->Edges(st2->Spine()->NbEdges());
}
BRepAdaptor_Curve BCurv1(E1);
BRepAdaptor_Curve BCurv2(E2);
parE1 = BRep_Tool::Parameter(Vtx, E1);
parE2 = BRep_Tool::Parameter(Vtx, E2);
BRepLProp_CLProps CL1(BCurv1, parE1, 1, 1.e-4);
BRepLProp_CLProps CL2(BCurv2, parE2, 1, 1.e-4);
gp_Dir dir1, dir2;
CL1.Tangent(dir1);
CL2.Tangent(dir2);
if (Sens1 == -1)
{
dir1.Reverse();
}
if (Sens2 == -1)
{
dir2.Reverse();
}
double ang1;
ang1 = std::abs(dir1.Angle(dir2));
if (ang1 < M_PI / 180.)
{
PerformMoreThreeCorner(Index, 2);
done = true;
return;
}
OkinterCC = ChFi3d_IsInFront(DStr,
st1,
st2,
Isd1,
Isd2,
Sens1,
Sens2,
UIntPC1,
UIntPC2,
FaCo,
SameSide,
IFaCo1,
IFaCo2,
Okvisavis,
Vtx,
true);
bool trouve = false;
if (!Okvisavis)
{
// one is not limited to the first or the last surfdata
// to find the opposing data
nbsurf1 = st1->SetOfSurfData()->Length();
nbsurf2 = st2->SetOfSurfData()->Length();
deb1 = 1;
deb2 = 1;
fin1 = 1;
fin2 = 1;
if (nbsurf1 != 1)
{
if (Sens1 == 1)
{
deb1 = 1;
fin1 = 2;
}
else
{
deb1 = nbsurf1 - 1;
fin1 = nbsurf1;
}
}
if (nbsurf2 != 1)
{
if (Sens2 == 1)
{
deb2 = 1;
fin2 = 2;
}
else
{
deb2 = nbsurf2 - 1;
fin2 = nbsurf2;
}
}
for (i1 = deb1; i1 <= fin1 && !trouve; i1++)
{
Isd1 = i1;
for (i2 = deb2; i2 <= fin2 && !trouve; i2++)
{
Isd2 = i2;
OkinterCC = ChFi3d_IsInFront(DStr,
st1,
st2,
Isd1,
Isd2,
Sens1,
Sens2,
UIntPC1,
UIntPC2,
FaCo,
SameSide,
IFaCo1,
IFaCo2,
Okvisavis,
Vtx,
true);
trouve = Okvisavis;
}
}
if (!trouve)
{
PerformMoreThreeCorner(Index, 2);
done = true;
return;
}
else
{
if (Sens1 == 1 && Isd1 != 1)
{
RemoveSD(st1, 1, 1);
}
if (Sens1 != 1 && Isd1 != nbsurf1)
{
RemoveSD(st1, fin1, fin1);
}
if (Sens2 == 1 && Isd2 != 1)
{
RemoveSD(st2, 1, 1);
}
if (Sens2 != 1 && Isd2 != nbsurf2)
{
RemoveSD(st2, fin2, fin2);
}
}
Isd1 = ChFi3d_IndexOfSurfData(Vtx, st1, Sens1);
Isd2 = ChFi3d_IndexOfSurfData(Vtx, st2, Sens2);
}
// throw StdFail_NotDone("TwoCorner : no common face");
int IFaArc1 = 3 - IFaCo1, IFaArc2 = 3 - IFaCo2;
SeqFil1 = st1->ChangeSetOfSurfData()->ChangeSequence();
SeqFil2 = st2->ChangeSetOfSurfData()->ChangeSequence();
sd1 = SeqFil1.ChangeValue(Isd1);
surf1 = DStr.Surface(sd1->Surf()).Surface();
sd2 = SeqFil2.ChangeValue(Isd2);
surf2 = DStr.Surface(sd2->Surf()).Surface();
TopAbs_Orientation OFaCo = FaCo.Orientation();
// The concavities are analyzed and the opposite face and the
// eventual intersection of 2 pcurves on this face are found.
ChFiDS_State Stat1, Stat2;
bool isfirst1 = (Sens1 == 1);
bool isfirst2 = (Sens2 == 1);
Stat1 = st1->Spine()->Status(isfirst1);
Stat2 = st2->Spine()->Status(isfirst2);
bool c1biseau = (Stat1 == ChFiDS_AllSame);
bool c1rotule = (Stat1 == ChFiDS_OnSame && Stat2 == ChFiDS_OnSame);
// It is checked if the fillets have a commonpoint on a common arc.
// This edge is the pivot of the bevel or the knee.
ChFiDS_CommonPoint& CP1 = sd1->ChangeVertex(isfirst1, IFaArc1);
ChFiDS_CommonPoint& CP2 = sd2->ChangeVertex(isfirst2, IFaArc2);
bool resetcp1 = false;
bool resetcp2 = false;
TopoDS_Edge pivot;
bool yapiv = false;
if (CP1.IsOnArc())
{
pivot = CP1.Arc();
}
else
{
PerformMoreThreeCorner(Index, 2);
done = true;
return;
}
if (CP1.IsOnArc() && CP2.IsOnArc())
{
yapiv = (pivot.IsSame(CP2.Arc()));
}
occ::handle<BRepAdaptor_Curve> Hpivot;
bool sameparam = false;
double parCP1 = 0., parCP2 = 0.;
if (yapiv)
{
Hpivot = new BRepAdaptor_Curve(pivot);
parCP1 = CP1.ParameterOnArc();
parCP2 = CP2.ParameterOnArc();
gp_Pnt tst1 = Hpivot->Value(parCP1);
gp_Pnt tst2 = Hpivot->Value(parCP2);
sameparam = tst1.Distance(tst2) <= tolapp3d;
}
occ::handle<BRepAdaptor_Surface> HFaCo = new BRepAdaptor_Surface();
occ::handle<BRepAdaptor_Surface> HFaPiv;
occ::handle<BRepAdaptor_Surface> HBRS1 = new BRepAdaptor_Surface();
occ::handle<BRepAdaptor_Surface> HBRS2 = new BRepAdaptor_Surface();
BRepAdaptor_Surface& BRS1 = *HBRS1;
BRepAdaptor_Surface& BRS2 = *HBRS2;
BRepAdaptor_Surface& BRFaCo = *HFaCo;
BRFaCo.Initialize(FaCo);
TopoDS_Face FF1, FF2, F, FaPiv;
TopAbs_Orientation pctrans = TopAbs_FORWARD;
occ::handle<Geom2d_BSplineCurve> PCurveOnPiv;
FF1 = TopoDS::Face(DStr.Shape(sd1->Index(IFaArc1)));
FF2 = TopoDS::Face(DStr.Shape(sd2->Index(IFaArc2)));
if (FF1.IsNull() || FF2.IsNull())
{
PerformMoreThreeCorner(Index, 2);
done = true;
return;
}
BRS1.Initialize(FF1);
BRS2.Initialize(FF2);
if (yapiv)
{
NCollection_List<TopoDS_Shape>::Iterator Kt;
bool ok1 = false, ok2 = false;
for (Kt.Initialize(myEFMap(pivot)); Kt.More(); Kt.Next())
{
F = TopoDS::Face(Kt.Value());
if (!ok1 && FF1.IsSame(F))
{
ok1 = true;
}
if (!ok2 && FF2.IsSame(F))
{
ok2 = true;
}
}
if (!ok1 || !ok2)
{
PerformMoreThreeCorner(Index, 2);
done = true;
return;
}
}
// bevel
//------
ChFiDS_CommonPoint cp11, cp12, cp21, cp22;
ChFiDS_FaceInterference intf11, intf12, intf21, intf22;
if (c1biseau)
{
done = PerformTwoCornerbyInter(Index);
if (!done)
{
PerformMoreThreeCorner(Index, 2);
done = true;
return;
}
}
else if (c1rotule)
{ // save.
cp11 = sd1->Vertex(isfirst1, 1);
cp12 = sd1->Vertex(isfirst1, 2);
cp21 = sd2->Vertex(isfirst2, 1);
cp22 = sd2->Vertex(isfirst2, 2);
intf11 = sd1->InterferenceOnS1();
intf12 = sd1->InterferenceOnS2();
intf21 = sd2->InterferenceOnS1();
intf22 = sd2->InterferenceOnS2();
done = PerformTwoCornerbyInter(Index);
if (!done)
{
// restore
sd1->ChangeVertex(isfirst1, 1) = cp11;
sd1->ChangeVertex(isfirst1, 2) = cp12;
sd2->ChangeVertex(isfirst2, 1) = cp21;
sd2->ChangeVertex(isfirst2, 2) = cp22;
sd1->ChangeInterferenceOnS1() = intf11;
sd1->ChangeInterferenceOnS2() = intf12;
sd2->ChangeInterferenceOnS1() = intf21;
sd2->ChangeInterferenceOnS2() = intf22;
done = false;
}
}
if (!c1biseau && !done)
{
// new cornerdata is created
//-------------------------------
occ::handle<ChFiDS_Stripe> corner = new ChFiDS_Stripe();
occ::handle<NCollection_HSequence<occ::handle<ChFiDS_SurfData>>>& cornerset =
corner->ChangeSetOfSurfData();
cornerset = new NCollection_HSequence<occ::handle<ChFiDS_SurfData>>();
occ::handle<ChFiDS_SurfData> coin = new ChFiDS_SurfData();
cornerset->Append(coin);
if (SameSide)
{
if (ToricRotule(BRFaCo, BRS1, BRS2, st1, st2))
{
// Direct construction.
// ---------------------
int bid;
TopAbs_Orientation ori = OFaCo;
TopAbs_Orientation oriS = st1->Orientation(IFaCo1);
TopAbs_Orientation OFF1 = FF1.Orientation();
TopAbs_Orientation oriSFF1 = st1->Orientation(IFaArc1);
bid = 1;
bid = ChFi3d::NextSide(ori, OFF1, oriS, oriSFF1, bid);
TopAbs_Orientation op1 = TopAbs_FORWARD, op2 = TopAbs_FORWARD;
if (yapiv)
{
bid = ChFi3d::ConcaveSide(BRS1, BRS2, pivot, op1, op2);
}
op1 = TopAbs::Reverse(op1);
op2 = TopAbs::Reverse(op2);
double radius = occ::down_cast<ChFiDS_FilSpine>(st1->Spine())->Radius();
done = ChFiKPart_ComputeData::ComputeCorner(DStr,
coin,
HFaCo,
HBRS1,
HBRS2,
OFaCo,
ori,
op1,
op2,
radius);
}
else
{
// Construction by filling remplissage
// ----------------------------
double uPCArc1, uPCArc2;
gp_Pnt2d p2da1, p2df1, p2da2, p2df2, p2dfac1, p2dfac2;
gp_Vec2d v2dfac1, v2dfac2;
occ::handle<GeomFill_Boundary> B1, B2, Bpiv, Bfac;
uPCArc1 = sd1->Interference(IFaArc1).Parameter(isfirst1);
p2da1 = sd1->Interference(IFaArc1).PCurveOnSurf()->Value(uPCArc1);
p2df1 = sd1->Interference(IFaCo1).PCurveOnSurf()->Value(uPCArc1);
sd1->Interference(IFaCo1).PCurveOnFace()->D1(uPCArc1, p2dfac1, v2dfac1);
uPCArc2 = sd2->Interference(IFaArc2).Parameter(isfirst2);
p2da2 = sd2->Interference(IFaArc2).PCurveOnSurf()->Value(uPCArc2);
p2df2 = sd2->Interference(IFaCo2).PCurveOnSurf()->Value(uPCArc2);
sd2->Interference(IFaCo2).PCurveOnFace()->D1(uPCArc2, p2dfac2, v2dfac2);
B1 = ChFi3d_mkbound(surf1, p2df1, p2da1, tolapp3d, 2.e-4);
B2 = ChFi3d_mkbound(surf2, p2df2, p2da2, tolapp3d, 2.e-4);
occ::handle<Geom2d_Curve> PCurveOnFace;
Bfac = ChFi3d_mkbound(HFaCo,
PCurveOnFace,
Sens1,
p2dfac1,
v2dfac1,
Sens2,
p2dfac2,
v2dfac2,
tolapp3d,
2.e-4);
GeomFill_ConstrainedFilling fil(8, 20);
if (sameparam)
{
fil.Init(Bfac, B2, B1, true);
}
else
{
occ::handle<Adaptor3d_Curve> HPivTrim =
Hpivot->Trim(std::min(parCP1, parCP2), std::max(parCP1, parCP2), tolesp);
Bpiv = new GeomFill_SimpleBound(HPivTrim, tolapp3d, 2.e-4);
fil.Init(Bfac, B2, Bpiv, B1, true);
BRepAdaptor_Curve2d pcpivot;
gp_Vec dArc, dcf;
gp_Pnt bidon;
Hpivot->D1(parCP1, bidon, dArc);
double fb1, lb1;
B1->Bounds(fb1, lb1);
B1->D1(lb1, bidon, dcf);
bool pivotverslebas = dArc.Dot(dcf) <= 0.;
bool pcfalenvers = (parCP1 > parCP2);
if ((pivotverslebas && !pcfalenvers) || (!pivotverslebas && pcfalenvers))
{
FaPiv = FF2;
HFaPiv = HBRS2;
resetcp2 = true;
}
else
{
FaPiv = FF1;
HFaPiv = HBRS1;
resetcp1 = true;
}
FaPiv.Orientation(TopAbs_FORWARD);
pcpivot.Initialize(pivot, FaPiv);
TopExp_Explorer Expl;
for (Expl.Init(FaPiv, TopAbs_EDGE); Expl.More(); Expl.Next())
{
if (Expl.Current().IsSame(pivot))
{
pctrans = Expl.Current().Orientation();
break;
}
}
if (pcpivot.GetType() != GeomAbs_BSplineCurve)
{
occ::handle<Geom2d_TrimmedCurve> trc =
new Geom2d_TrimmedCurve(pcpivot.Curve(),
std::min(parCP1, parCP2),
std::max(parCP1, parCP2));
PCurveOnPiv = Geom2dConvert::CurveToBSplineCurve(trc);
}
else
{
PCurveOnPiv =
Geom2dConvert::SplitBSplineCurve(occ::down_cast<Geom2d_BSplineCurve>(pcpivot.Curve()),
std::min(parCP1, parCP2),
std::max(parCP1, parCP2),
tol2d);
}
NCollection_Array1<double> kk(PCurveOnPiv->Knots());
BSplCLib::Reparametrize(0., 1., kk);
PCurveOnPiv->SetKnots(kk);
if (pcfalenvers)
{
PCurveOnPiv->Reverse();
pctrans = TopAbs::Reverse(pctrans);
}
}
occ::handle<Geom_Surface> Surfcoin = fil.Surface();
done = CompleteData(coin,
Surfcoin,
HFaCo,
PCurveOnFace,
HFaPiv,
PCurveOnPiv,
OFaCo,
true,
false,
false,
false,
false);
}
if (done)
{
// Update 3 CornerData and the DS
// ----------------------------------------
if (resetcp1)
{
gp_Pnt pjyl = CP1.Point();
double tolsav = CP1.Tolerance();
CP1.Reset();
CP1.SetPoint(pjyl);
CP1.SetTolerance(tolsav);
}
else if (resetcp2)
{
gp_Pnt pjyl = CP2.Point();
double tolsav = CP2.Tolerance();
CP2.Reset();
CP2.SetPoint(pjyl);
CP2.SetTolerance(tolsav);
}
double P1deb, P2deb, P1fin, P2fin;
int If1, If2, Il1, Il2, Icf, Icl;
const ChFiDS_CommonPoint& Pf1 = coin->VertexFirstOnS1();
ChFiDS_CommonPoint& Pf2 = coin->ChangeVertexFirstOnS2();
const ChFiDS_CommonPoint& Pl1 = coin->VertexLastOnS1();
ChFiDS_CommonPoint& Pl2 = coin->ChangeVertexLastOnS2();
Pf2 = CP1;
Pl2 = CP2;
// the corner to start,
// -----------------------
ChFiDS_Regul regdeb, regfin;
If1 = ChFi3d_IndexPointInDS(Pf1, DStr);
If2 = ChFi3d_IndexPointInDS(Pf2, DStr);
Il1 = ChFi3d_IndexPointInDS(Pl1, DStr);
if (sameparam)
{
Il2 = If2;
}
else
{
Il2 = ChFi3d_IndexPointInDS(Pl2, DStr);
}
gp_Pnt2d pp1, pp2;
pp1 =
coin->InterferenceOnS1().PCurveOnSurf()->Value(coin->InterferenceOnS1().FirstParameter());
pp2 =
coin->InterferenceOnS2().PCurveOnSurf()->Value(coin->InterferenceOnS2().FirstParameter());
occ::handle<Geom_Curve> C3d;
double tolreached;
ChFi3d_ComputeArete(Pf1,
pp1,
Pf2,
pp2,
DStr.Surface(coin->Surf()).Surface(),
C3d,
corner->ChangeFirstPCurve(),
P1deb,
P2deb,
tolapp3d,
tol2d,
tolreached,
0);
double par1 = sd1->Interference(IFaArc1).Parameter(isfirst1);
pp1 = sd1->Interference(IFaCo1).PCurveOnSurf()->Value(par1);
pp2 = sd1->Interference(IFaArc1).PCurveOnSurf()->Value(par1);
double tolr1;
ChFi3d_ComputePCurv(C3d,
pp1,
pp2,
st1->ChangePCurve(isfirst1),
DStr.Surface(sd1->Surf()).Surface(),
P1deb,
P2deb,
tolapp3d,
tolr1);
tolreached = std::max(tolreached, tolr1);
TopOpeBRepDS_Curve Tcurv1(C3d, tolreached);
Icf = DStr.AddCurve(Tcurv1);
regdeb.SetCurve(Icf);
regdeb.SetS1(coin->Surf(), false);
regdeb.SetS2(sd1->Surf(), false);
myRegul.Append(regdeb);
corner->ChangeFirstCurve(Icf);
corner->ChangeFirstParameters(P1deb, P2deb);
corner->ChangeIndexFirstPointOnS1(If1);
corner->ChangeIndexFirstPointOnS2(If2);
pp1 =
coin->InterferenceOnS1().PCurveOnSurf()->Value(coin->InterferenceOnS1().LastParameter());
pp2 =
coin->InterferenceOnS2().PCurveOnSurf()->Value(coin->InterferenceOnS2().LastParameter());
ChFi3d_ComputeArete(Pl1,
pp1,
Pl2,
pp2,
DStr.Surface(coin->Surf()).Surface(),
C3d,
corner->ChangeLastPCurve(),
P1fin,
P2fin,
tolapp3d,
tol2d,
tolreached,
0);
double par2 = sd2->Interference(IFaArc2).Parameter(isfirst2);
pp1 = sd2->Interference(IFaCo2).PCurveOnSurf()->Value(par2);
pp2 = sd2->Interference(IFaArc2).PCurveOnSurf()->Value(par2);
double tolr2;
ChFi3d_ComputePCurv(C3d,
pp1,
pp2,
st2->ChangePCurve(isfirst2),
DStr.Surface(sd2->Surf()).Surface(),
P1deb,
P2deb,
tolapp3d,
tolr2);
tolreached = std::max(tolreached, tolr2);
TopOpeBRepDS_Curve Tcurv2(C3d, tolreached);
Icl = DStr.AddCurve(Tcurv2);
regfin.SetCurve(Icl);
regfin.SetS1(coin->Surf(), false);
regfin.SetS2(sd2->Surf(), false);
myRegul.Append(regfin);
corner->ChangeLastCurve(Icl);
corner->ChangeLastParameters(P1fin, P2fin);
corner->ChangeIndexLastPointOnS1(Il1);
corner->ChangeIndexLastPointOnS2(Il2);
coin->ChangeIndexOfS1(DStr.AddShape(FaCo));
if (sameparam)
{
coin->ChangeIndexOfS2(0);
}
else
{
coin->ChangeIndexOfS2(DStr.AddShape(FaPiv));
coin->ChangeInterferenceOnS2().SetTransition(pctrans);
}
corner->SetSolidIndex(st1->SolidIndex());
// then the starting Stripe,
// ------------------------
st1->SetCurve(Icf, isfirst1);
st1->SetIndexPoint(If1, isfirst1, IFaCo1);
st1->SetIndexPoint(If2, isfirst1, IFaArc1);
st1->SetParameters(isfirst1, P1deb, P2deb);
sd1->ChangeVertex(isfirst1, IFaCo1) = Pf1;
sd1->ChangeVertex(isfirst1, IFaArc1) = Pf2;
sd1->ChangeInterference(IFaCo1).SetParameter(par1, isfirst1);
if (IFaCo1 == 2)
{
st1->SetOrientation(TopAbs_REVERSED, isfirst1);
}
// then the end Stripe,
// -------------------------
st2->SetCurve(Icl, isfirst2);
st2->SetIndexPoint(Il1, isfirst2, IFaCo2);
st2->SetIndexPoint(Il2, isfirst2, IFaArc2);
st2->SetParameters(isfirst2, P1fin, P2fin);
sd2->ChangeVertex(isfirst2, IFaCo2) = Pl1;
sd2->ChangeVertex(isfirst2, IFaArc2) = Pl2;
sd2->ChangeInterference(IFaCo2).SetParameter(par2, isfirst2);
if (IFaCo2 == 2)
{
st2->SetOrientation(TopAbs_REVERSED, isfirst2);
}
}
}
else
{
// it is necessary to make difference with
if (!OkinterCC)
{
throw Standard_Failure("TwoCorner : No intersection pc pc");
}
occ::handle<ChFiDS_Stripe> stsam, stdif;
occ::handle<ChFiDS_SurfData> sdsam, sddif;
double uintpcsam = 0., uintpcdif = 0.;
int ifacosam = 0, ifacodif = 0, ifaopsam = 0, ifaopdif = 0;
bool isfirstsam = false, isfirstdif = false;
if (Stat1 == ChFiDS_OnSame && Stat2 == ChFiDS_OnDiff)
{
stsam = st1;
sdsam = sd1;
uintpcsam = UIntPC1;
ifacosam = IFaCo1;
ifaopsam = IFaArc1;
isfirstsam = isfirst1;
stdif = st2;
sddif = sd2;
uintpcdif = UIntPC2;
ifacodif = IFaCo2;
ifaopdif = IFaArc2;
isfirstdif = isfirst2;
}
else if (Stat1 == ChFiDS_OnDiff && Stat2 == ChFiDS_OnSame)
{
stsam = st2;
sdsam = sd2;
uintpcsam = UIntPC2;
ifacosam = IFaCo2;
ifaopsam = IFaArc2;
isfirstsam = isfirst2;
stdif = st1;
sddif = sd1;
uintpcdif = UIntPC1;
ifacodif = IFaCo1;
ifaopdif = IFaArc1;
isfirstdif = isfirst1;
}
else
{
throw Standard_Failure("TwoCorner : Config unknown");
}
// It is checked if surface ondiff has a point on arc from the side opposed
// to the common face and if this arc is connected to the base face
// opposed to common face of the surface onsame.
ChFiDS_CommonPoint& cpopdif = sddif->ChangeVertex(isfirstdif, ifaopdif);
if (!cpopdif.IsOnArc())
{
throw Standard_Failure("TwoCorner : No point on restriction on surface OnDiff");
}
const TopoDS_Edge& Arcopdif = cpopdif.Arc();
const TopoDS_Face& Fopsam = TopoDS::Face(DStr.Shape(sdsam->Index(ifaopsam)));
TopExp_Explorer ex;
for (ex.Init(Fopsam, TopAbs_EDGE); ex.More(); ex.Next())
{
if (ex.Current().IsSame(Arcopdif))
{
break;
}
else if (!ex.More())
{
throw Standard_Failure("TwoCorner : No common face to loop the contour");
}
}
occ::handle<GeomFill_Boundary> Bsam, Bdif, Bfac;
gp_Pnt2d ppopsam = sdsam->Interference(ifaopsam).PCurveOnSurf()->Value(uintpcsam);
gp_Pnt2d ppcosam = sdsam->Interference(ifacosam).PCurveOnSurf()->Value(uintpcsam);
occ::handle<Geom_Surface> surfsam = DStr.Surface(sdsam->Surf()).Surface();
occ::handle<GeomAdaptor_Surface> Hsurfsam = new GeomAdaptor_Surface(surfsam);
occ::handle<Geom2d_Curve> pcsurfsam;
Bsam = ChFi3d_mkbound(Hsurfsam, pcsurfsam, ppopsam, ppcosam, tolapp3d, 2.e-4);
double upcopdif = sddif->Interference(ifaopdif).Parameter(isfirstdif);
gp_Pnt2d ppopdif = sddif->Interference(ifaopdif).PCurveOnSurf()->Value(upcopdif);
gp_Pnt2d ppcodif = sddif->Interference(ifacodif).PCurveOnSurf()->Value(uintpcdif);
occ::handle<Geom_Surface> surfdif = DStr.Surface(sddif->Surf()).Surface();
occ::handle<GeomAdaptor_Surface> Hsurfdif = new GeomAdaptor_Surface(surfdif);
occ::handle<Geom2d_Curve> pcsurfdif;
Bdif = ChFi3d_mkbound(Hsurfdif, pcsurfdif, ppcodif, ppopdif, tolapp3d, 2.e-4);
gp_Pnt2d ppfacsam, ppfacdif;
gp_Pnt PPfacsam, PPfacdif;
gp_Vec VVfacsam, VVfacdif;
sdsam->Interference(ifaopsam).PCurveOnFace()->D0(uintpcsam, ppfacsam);
const occ::handle<Geom_Curve>& curvopsam =
DStr.Curve(sdsam->Interference(ifaopsam).LineIndex()).Curve();
curvopsam->D1(uintpcsam, PPfacsam, VVfacsam);
BRepAdaptor_Curve2d PCArcFac(Arcopdif, Fopsam);
PCArcFac.D0(cpopdif.ParameterOnArc(), ppfacdif);
// jgv for OCC26173
BRepAdaptor_Surface SurFopsam(Fopsam);
if (SurFopsam.IsUClosed())
{
double Uperiod = SurFopsam.LastUParameter() - SurFopsam.FirstUParameter();
if (std::abs(ppfacsam.X() - ppfacdif.X()) > Uperiod / 2)
{
if (ppfacdif.X() < ppfacsam.X())
{
ppfacdif.SetX(ppfacdif.X() + Uperiod);
}
else
{
ppfacdif.SetX(ppfacdif.X() - Uperiod);
}
}
}
//////////////////
BRepAdaptor_Curve CArcFac(Arcopdif);
CArcFac.D1(cpopdif.ParameterOnArc(), PPfacdif, VVfacdif);
occ::handle<BRepAdaptor_Surface> HBRFopsam = new BRepAdaptor_Surface();
BRepAdaptor_Surface& BRFopsam = *HBRFopsam;
BRFopsam.Initialize(Fopsam, false);
occ::handle<Geom2d_Curve> pcFopsam =
ChFi3d_BuildPCurve(HBRFopsam, ppfacsam, VVfacsam, ppfacdif, VVfacdif, true);
Bfac = ChFi3d_mkbound(HBRFopsam, pcFopsam, tolapp3d, 2.e-4);
GeomFill_ConstrainedFilling fil(8, 20);
fil.Init(Bsam, Bdif, Bfac, true);
occ::handle<Geom_Surface> Surfcoin = fil.Surface();
TopAbs_Orientation Osurfsam = sdsam->Orientation();
occ::handle<Geom2d_Curve> pcnul;
done = CompleteData(coin,
Surfcoin,
Hsurfsam,
pcsurfsam,
HBRFopsam,
pcnul,
Osurfsam,
true,
false,
false,
false,
false);
if (!done)
{
throw Standard_Failure("concavites inverted : fail");
}
// Update 3 CornerData and the DS
// ----------------------------------------
// the corner to start,
// -----------------------
double P1deb, P2deb, P1fin, P2fin;
int If1, If2, Il1, Il2, Icf, Icl;
const ChFiDS_CommonPoint& Pf1 = coin->VertexFirstOnS1();
ChFiDS_CommonPoint& Pf2 = coin->ChangeVertexFirstOnS2();
const ChFiDS_CommonPoint& Pl1 = coin->VertexLastOnS1();
ChFiDS_CommonPoint& Pl2 = coin->ChangeVertexLastOnS2();
Pf2 = Pl2 = cpopdif;
ChFiDS_Regul regdeb, regfin;
If1 = ChFi3d_IndexPointInDS(Pf1, DStr);
If2 = ChFi3d_IndexPointInDS(Pf2, DStr);
Il1 = ChFi3d_IndexPointInDS(Pl1, DStr);
Il2 = If2;
gp_Pnt2d pp1, pp2;
pp1 =
coin->InterferenceOnS1().PCurveOnSurf()->Value(coin->InterferenceOnS1().FirstParameter());
pp2 =
coin->InterferenceOnS2().PCurveOnSurf()->Value(coin->InterferenceOnS2().FirstParameter());
occ::handle<Geom_Curve> C3d;
double tolreached;
ChFi3d_ComputeArete(Pf1,
pp1,
Pf2,
pp2,
DStr.Surface(coin->Surf()).Surface(),
C3d,
corner->ChangeFirstPCurve(),
P1deb,
P2deb,
tolapp3d,
tol2d,
tolreached,
0);
double tolr1;
occ::handle<GeomAdaptor_Curve> HC3d = new GeomAdaptor_Curve(C3d);
ChFi3d_SameParameter(HC3d, pcFopsam, HBRFopsam, tolapp3d, tolr1);
tolreached = std::max(tolreached, tolr1);
TopOpeBRepDS_Curve Tcurv1(C3d, tolreached);
Icf = DStr.AddCurve(Tcurv1);
// place the pcurve on face in the DS
TopAbs_Orientation OpcFopsam = sdsam->Interference(ifaopsam).Transition();
int IFopsam = sdsam->Index(ifaopsam);
if (isfirstsam)
{
OpcFopsam = TopAbs::Reverse(OpcFopsam);
}
occ::handle<TopOpeBRepDS_SurfaceCurveInterference> interf =
ChFi3d_FilCurveInDS(Icf, IFopsam, pcFopsam, OpcFopsam);
DStr.ChangeShapeInterferences(IFopsam).Append(interf);
regdeb.SetCurve(Icf);
regdeb.SetS1(coin->Surf(), false);
regdeb.SetS2(IFopsam, true);
myRegul.Append(regdeb);
corner->ChangeFirstCurve(Icf);
corner->ChangeFirstParameters(P1deb, P2deb);
corner->ChangeIndexFirstPointOnS1(If1);
corner->ChangeIndexFirstPointOnS2(If2);
pp1 =
coin->InterferenceOnS1().PCurveOnSurf()->Value(coin->InterferenceOnS1().LastParameter());
pp2 =
coin->InterferenceOnS2().PCurveOnSurf()->Value(coin->InterferenceOnS2().LastParameter());
ChFi3d_ComputeArete(Pl1,
pp1,
Pl2,
pp2,
DStr.Surface(coin->Surf()).Surface(),
C3d,
corner->ChangeLastPCurve(),
P1fin,
P2fin,
tolapp3d,
tol2d,
tolreached,
0);
double tolr2;
HC3d->Load(C3d);
ChFi3d_SameParameter(HC3d, pcsurfdif, Hsurfdif, tolapp3d, tolr2);
tolreached = std::max(tolreached, tolr2);
TopOpeBRepDS_Curve Tcurv2(C3d, tolreached);
Icl = DStr.AddCurve(Tcurv2);
regfin.SetCurve(Icl);
regfin.SetS1(coin->Surf(), false);
regfin.SetS2(sddif->Surf(), false);
myRegul.Append(regfin);
corner->ChangeLastCurve(Icl);
corner->ChangeLastParameters(P1fin, P2fin);
corner->ChangeIndexLastPointOnS1(Il1);
corner->ChangeIndexLastPointOnS2(Il2);
coin->ChangeIndexOfS1(-sdsam->Surf());
coin->ChangeIndexOfS2(0);
corner->SetSolidIndex(stsam->SolidIndex());
// then Stripe OnSame
// ---------------------
const ChFiDS_FaceInterference& intcoin1 = coin->InterferenceOnS1();
stsam->SetCurve(intcoin1.LineIndex(), isfirstsam);
stsam->InDS(isfirstsam); // filDS already works from the corner.
stsam->ChangePCurve(isfirstsam) = coin->InterferenceOnS1().PCurveOnFace();
stsam->SetIndexPoint(If1, isfirstsam, ifaopsam);
stsam->SetIndexPoint(Il1, isfirstsam, ifacosam);
stsam->SetParameters(isfirstsam, intcoin1.FirstParameter(), intcoin1.LastParameter());
sdsam->ChangeVertex(isfirstsam, ifaopsam) = Pf1;
sdsam->ChangeVertex(isfirstsam, ifacosam) = Pl1;
sdsam->ChangeInterferenceOnS1().SetParameter(uintpcsam, isfirstsam);
sdsam->ChangeInterferenceOnS2().SetParameter(uintpcsam, isfirstsam);
if (ifaopsam == 2)
{
stsam->SetOrientation(TopAbs_REVERSED, isfirstsam);
}
// then Stripe OnDiff
// ---------------------
stdif->SetCurve(Icl, isfirstdif);
stdif->ChangePCurve(isfirstdif) = pcsurfdif;
stdif->SetIndexPoint(Il2, isfirstdif, ifaopdif);
stdif->SetIndexPoint(Il1, isfirstdif, ifacodif);
stdif->SetParameters(isfirstdif, P1fin, P2fin);
sddif->ChangeVertex(isfirstdif, ifaopdif) = Pl2;
sddif->ChangeVertex(isfirstdif, ifacodif) = Pl1;
sddif->ChangeInterference(ifacodif).SetParameter(uintpcdif, isfirstdif);
if (ifaopdif == 1)
{
stdif->SetOrientation(TopAbs_REVERSED, isfirstdif);
}
}
if (!myEVIMap.IsBound(Vtx))
{
NCollection_List<int> li;
myEVIMap.Bind(Vtx, li);
}
myEVIMap.ChangeFind(Vtx).Append(coin->Surf());
myListStripe.Append(corner);
}
}