Loading files
f2929057eThis file is pinned to the selected release. Download the original to open it in your design tool.
// Created on: 1995-04-26
// Created by: Modelistation
// Copyright (c) 1995-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 <BRepBlend_ConstRad.hxx>
#include <BRepBlend_ConstRadInv.hxx>
#include <BRepBlend_EvolRad.hxx>
#include <BRepBlend_EvolRadInv.hxx>
#include <BRepBlend_Line.hxx>
#include <BRepTopAdaptor_TopolTool.hxx>
#include <ChFi3d.hxx>
#include <ChFi3d_Builder_0.hxx>
#include <ChFi3d_FilBuilder.hxx>
#include <ChFiDS_CommonPoint.hxx>
#include <ChFiDS_FaceInterference.hxx>
#include <ChFiDS_SurfData.hxx>
#include <NCollection_Sequence.hxx>
#include <NCollection_HSequence.hxx>
#include <ChFiDS_ElSpine.hxx>
#include <ChFiDS_Regul.hxx>
#include <ChFiDS_Spine.hxx>
#include <ChFiDS_Stripe.hxx>
#include <ChFiKPart_ComputeData.hxx>
#include <ElSLib.hxx>
#include <Geom2d_Curve.hxx>
#include <Geom_BSplineSurface.hxx>
#include <GeomAdaptor_Surface.hxx>
#include <GeomFill_ConstrainedFilling.hxx>
#include <gp_Ax3.hxx>
#include <gp_Dir.hxx>
#include <gp_Pnt.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Vec.hxx>
#include <Law_S.hxx>
#include <math_Vector.hxx>
#include <Precision.hxx>
#include <Standard_NotImplemented.hxx>
#include <Standard_Integer.hxx>
#include <NCollection_List.hxx>
#include <TopAbs_Orientation.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopOpeBRepDS_Curve.hxx>
#include <TopOpeBRepDS_DataStructure.hxx>
#include <TopOpeBRepDS_HDataStructure.hxx>
#include <TopOpeBRepDS_Surface.hxx>
//=================================================================================================
static int SearchPivot(int* s, double u[3][3], const double t)
{
bool bondeb, bonfin;
for (int i = 0; i <= 2; i++)
{
if (s[(i + 1) % 3] == 1)
{
bondeb = (u[(i + 1) % 3][i] - u[(i + 1) % 3][(i + 2) % 3] >= -t);
}
else
{
bondeb = (u[(i + 1) % 3][i] - u[(i + 1) % 3][(i + 2) % 3] <= t);
}
if (s[(i + 2) % 3] == 1)
{
bonfin = (u[(i + 2) % 3][i] - u[(i + 2) % 3][(i + 1) % 3] >= -t);
}
else
{
bonfin = (u[(i + 2) % 3][i] - u[(i + 2) % 3][(i + 1) % 3] <= t);
}
if (bondeb && bonfin)
{
return i;
}
}
return -1;
}
//=================================================================================================
static bool SearchFD(TopOpeBRepDS_DataStructure& DStr,
const occ::handle<ChFiDS_Stripe>& cd1,
const occ::handle<ChFiDS_Stripe>& cd2,
const int sens1,
const int sens2,
int& i1,
int& i2,
double& p1,
double& p2,
const int ind1,
const int ind2,
TopoDS_Face& face,
bool& sameside,
int& jf1,
int& jf2)
{
bool found = false;
int id1 = ind1, id2 = ind2;
int if1 = ind1, if2 = ind2;
int l1 = cd1->SetOfSurfData()->Length();
int l2 = cd2->SetOfSurfData()->Length();
int i;
bool fini1 = false, fini2 = false;
bool visavis;
TopoDS_Vertex Vtx;
while (!found)
{
for (i = id1; (i * sens1) <= (if1 * sens1) && !found && !fini2; i = i + sens1)
{
if (ChFi3d_IsInFront(DStr,
cd1,
cd2,
i,
if2,
sens1,
sens2,
p1,
p2,
face,
sameside,
jf1,
jf2,
visavis,
Vtx,
false,
false))
{
i1 = i;
i2 = if2;
found = true;
}
}
if (!fini1)
{
if1 = if1 + sens1;
if (if1 < 1 || if1 > l1)
{
if1 = if1 - sens1;
fini1 = true;
}
}
for (i = id2; (i * sens2) <= (if2 * sens2) && !found && !fini1; i = i + sens2)
{
if (ChFi3d_IsInFront(DStr,
cd1,
cd2,
if1,
i,
sens1,
sens2,
p1,
p2,
face,
sameside,
jf1,
jf2,
visavis,
Vtx,
false,
false))
{
i1 = if1;
i2 = i;
found = true;
}
}
if (!fini2)
{
if2 = if2 + sens2;
if (if2 < 1 || if2 > l2)
{
if2 = if2 - sens2;
fini2 = true;
}
}
if (fini1 && fini2)
{
break;
}
}
return found;
}
//=======================================================================
// function : ToricCorner
// purpose : Test if this is a particular case of a torus corner
// (or spherical limited by isos).
//=======================================================================
static bool ToricCorner(const TopoDS_Face& F, const double rd, const double rf, const gp_Vec& v)
{
if (std::abs(rd - rf) > Precision::Confusion())
{
return false;
}
BRepAdaptor_Surface bs(F);
if (bs.GetType() != GeomAbs_Plane)
{
return false;
}
double scal1 = std::abs(bs.Plane().Position().XDirection().Dot(v));
double scal2 = std::abs(bs.Plane().Position().YDirection().Dot(v));
return (scal1 <= Precision::Confusion() && scal2 <= Precision::Confusion());
}
//=======================================================================
// function : PerformThreeCorner
// purpose : Calculate fillet on a top with three edges
// incident carrying each edge.
//=======================================================================
void ChFi3d_FilBuilder::PerformThreeCorner(const int Jndex)
{
TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
const TopoDS_Vertex& Vtx = myVDataMap.FindKey(Jndex);
NCollection_List<occ::handle<ChFiDS_Stripe>>::Iterator It;
int Index[3], pivot, deb, fin, ii, jj, kk;
// double R = 0.;
bool pivdif = true;
bool c1pointu = false;
bool c1toric = false;
bool c1spheric = false;
occ::handle<ChFiDS_Stripe> CD[3];
TopoDS_Face face[3];
int jf[3][3];
bool sameside[3], oksea[3];
for (int g = 0; g <= 2; g++)
{
oksea[g] = false;
}
int i[3][3];
int sens[3];
double p[3][3];
bool filling = false;
for (It.Initialize(myVDataMap(Jndex)), ii = 0; It.More() && ii < 3; It.Next(), ii++)
{
Index[ii] = ChFi3d_IndexOfSurfData(Vtx, It.Value(), sens[ii]);
CD[ii] = It.Value();
}
// It is checked if one of CD is not present twice in which
// case it is necessary to modify the return of IndexOfSurfData
// that takes the first solution.
if (CD[0] == CD[1])
{
Index[1] = CD[1]->SetOfSurfData()->Length();
sens[1] = -1;
}
else if (CD[1] == CD[2])
{
Index[2] = CD[2]->SetOfSurfData()->Length();
sens[2] = -1;
}
else if (CD[0] == CD[2])
{
Index[2] = CD[2]->SetOfSurfData()->Length();
sens[2] = -1;
}
oksea[2] = SearchFD(DStr,
CD[0],
CD[1],
sens[0],
sens[1],
i[0][1],
i[1][0],
p[0][1],
p[1][0],
Index[0],
Index[1],
face[2],
sameside[2],
jf[0][1],
jf[1][0]);
oksea[1] = SearchFD(DStr,
CD[0],
CD[2],
sens[0],
sens[2],
i[0][2],
i[2][0],
p[0][2],
p[2][0],
Index[0],
Index[2],
face[1],
sameside[1],
jf[0][2],
jf[2][0]);
oksea[0] = SearchFD(DStr,
CD[1],
CD[2],
sens[1],
sens[2],
i[1][2],
i[2][1],
p[1][2],
p[2][1],
Index[1],
Index[2],
face[0],
sameside[0],
jf[1][2],
jf[2][1]);
//
// Analyze concavities of 3 fillets :
// - 2 concavities identic and 1 inverted.
// - 3 concavities identic
//
if (oksea[2] && oksea[1] && !sameside[2] && !sameside[1])
{
pivot = 0;
deb = 1;
fin = 2;
}
else if (oksea[2] && oksea[0] && !sameside[2] && !sameside[0])
{
pivot = 1;
deb = 2;
fin = 0;
}
else if (oksea[1] && oksea[0] && !sameside[1] && !sameside[0])
{
pivot = 2;
deb = 0;
fin = 1;
}
else if (oksea[0] && oksea[1] && oksea[2])
{
// 3 concavities identic.
pivot = SearchPivot(sens, p, tol2d);
if (pivot < 0)
{
#ifdef OCCT_DEBUG
std::cout << "pivot not found, plate is called" << std::endl;
#endif
PerformMoreThreeCorner(Jndex, 3);
return;
}
else
{
deb = (pivot + 1) % 3;
fin = (pivot + 2) % 3;
}
pivdif = false;
if (std::abs(p[0][1] - p[0][2]) <= tol2d && std::abs(p[1][0] - p[1][2]) <= tol2d
&& std::abs(p[2][0] - p[2][1]) <= tol2d)
{
c1pointu = true;
}
}
else
{
PerformMoreThreeCorner(Jndex, 3);
return;
}
int ifacdeb, ifacfin;
ifacdeb = CD[deb]->ChangeSetOfSurfData()->Value(i[deb][pivot])->Index(3 - jf[deb][pivot]);
ifacfin = CD[fin]->ChangeSetOfSurfData()->Value(i[fin][pivot])->Index(3 - jf[fin][pivot]);
if (ifacfin != ifacdeb)
{
#ifdef OCCT_DEBUG
std::cout << "several base faces, plate is called" << std::endl;
#endif
PerformMoreThreeCorner(Jndex, 3);
return;
}
if (i[pivot][deb] != i[pivot][fin])
{
#ifdef OCCT_DEBUG
std::cout << "load surfdata on the pivot, plate is called" << std::endl;
#endif
PerformMoreThreeCorner(Jndex, 3);
return;
}
double Rdeb, Rfin, Rdp, Rfp;
gp_Pnt Pdeb, Pfin, Pdp, Pfp;
gp_Vec Vdeb, Vfin, Vdp, Vfp;
if (c1pointu)
{
gp_Pnt pbid;
gp_Vec qv[3];
double qr[3];
for (ii = 0; ii <= 2; ii++)
{
jj = (ii + 1) % 3;
kk = (ii + 2) % 3;
ChFi3d_ExtrSpineCarac(DStr, CD[jj], i[jj][ii], p[jj][ii], 1, sens[jj], pbid, qv[jj], qr[jj]);
}
for (ii = 0; ii <= 2 && !c1toric; ii++)
{
jj = (ii + 1) % 3;
kk = (ii + 2) % 3;
if (ToricCorner(face[ii], qr[jj], qr[kk], qv[ii]))
{
c1toric = true;
pivot = ii;
deb = jj;
fin = kk;
}
}
if (!c1toric)
{
c1spheric = (std::abs(qr[0] - qr[1]) < tolapp3d && std::abs(qr[0] - qr[2]) < tolapp3d);
}
}
// Previously to avoid loops the points were always located
// inside, which could impede the construction of the
// guideline of the corner which now is a circle.
// int jjjd = jf[deb][fin], jjjf = jf[fin][deb];
// if (pivdif) jjjd = jf[deb][pivot], jjjf = jf[fin][pivot];
int jjjd = jf[deb][pivot], jjjf = jf[fin][pivot];
ChFi3d_ExtrSpineCarac(DStr,
CD[deb],
i[deb][pivot],
p[deb][pivot],
jjjd,
sens[deb],
Pdeb,
Vdeb,
Rdeb);
ChFi3d_ExtrSpineCarac(DStr,
CD[fin],
i[fin][pivot],
p[fin][pivot],
jjjf,
sens[fin],
Pfin,
Vfin,
Rfin);
ChFi3d_ExtrSpineCarac(DStr,
CD[pivot],
i[pivot][deb],
p[pivot][deb],
0,
sens[pivot],
Pdp,
Vdp,
Rdp);
ChFi3d_ExtrSpineCarac(DStr,
CD[pivot],
i[pivot][fin],
p[pivot][fin],
0,
sens[pivot],
Pfp,
Vfp,
Rfp);
// in cas of allsame it is checked that points on the face are not
// too close, which can stop the work.
if (!pivdif)
{
gp_Pnt ptestdeb, ptestfin;
gp_Vec bidvec;
double bidr;
ChFi3d_ExtrSpineCarac(DStr,
CD[deb],
i[deb][pivot],
p[deb][pivot],
jf[deb][fin],
sens[deb],
ptestdeb,
bidvec,
bidr);
ChFi3d_ExtrSpineCarac(DStr,
CD[fin],
i[fin][pivot],
p[fin][pivot],
jf[fin][deb],
sens[fin],
ptestfin,
bidvec,
bidr);
double distest = ptestdeb.Distance(ptestfin);
if (distest < (Rdp + Rfp) * 0.05)
{
filling = true;
}
if (distest < (Rdp + Rfp) * 0.005)
{
c1pointu = true;
}
}
if (!c1pointu)
{
if (!pivdif)
{
c1pointu = (std::abs(p[deb][pivot] - p[deb][fin]) <= tol2d
&& std::abs(p[fin][pivot] - p[fin][deb]) <= tol2d);
}
if (std::abs(p[pivot][deb] - p[pivot][fin]) <= tol2d)
{
c1toric = ToricCorner(face[pivot], Rdeb, Rfin, Vdp);
}
}
// there is a pivot, the start and the end CD (finally !?!) :
// -------------------------------------------------------------
// the criterions determining if the corner is a torus or a sphere
// are based only on the configuration of sections at end and the
// nature of faces, it is necessary to make tests to
// determine if a more detailed analysis of incident fillets
// is necessare to provide tangency between them and
// the corner (in particular in the case with variable radius).
occ::handle<ChFiDS_SurfData>& fddeb = CD[deb]->ChangeSetOfSurfData()->ChangeValue(i[deb][pivot]);
occ::handle<ChFiDS_SurfData>& fdfin = CD[fin]->ChangeSetOfSurfData()->ChangeValue(i[fin][pivot]);
occ::handle<ChFiDS_SurfData>& fdpiv =
CD[pivot]->ChangeSetOfSurfData()->ChangeValue(i[pivot][deb]);
// HSurfaces and other suitable tools are constructed.
// ----------------------------------------------------------
TopAbs_Orientation OFac = face[pivot].Orientation();
occ::handle<BRepAdaptor_Surface> Fac = new BRepAdaptor_Surface(face[pivot]);
gp_Pnt2d ppp1, ppp2;
const ChFiDS_FaceInterference& bid1 =
CD[pivot]->SetOfSurfData()->Value(i[pivot][deb])->InterferenceOnS1();
ppp1 = bid1.PCurveOnSurf()->Value(bid1.FirstParameter());
const ChFiDS_FaceInterference& bid2 =
CD[pivot]->SetOfSurfData()->Value(i[pivot][deb])->InterferenceOnS2();
ppp2 = bid2.PCurveOnSurf()->Value(bid2.LastParameter());
double uu1 = ppp1.X(), uu2 = ppp2.X(), vv1 = ppp1.Y(), vv2 = ppp2.Y();
GeomAdaptor_Surface gasurf(
(DStr.Surface(CD[pivot]->SetOfSurfData()->Value(i[pivot][deb])->Surf())).Surface(),
uu1,
uu2,
vv1,
vv2);
GeomAbs_SurfaceType styp = gasurf.GetType();
if (styp == GeomAbs_Cylinder)
{
double h = vv2 - vv1;
vv1 -= 0.5 * h;
vv2 += 0.5 * h;
gasurf.Load((DStr.Surface(CD[pivot]->SetOfSurfData()->Value(i[pivot][deb])->Surf())).Surface(),
uu1,
uu2,
vv1,
vv2);
}
else if (styp == GeomAbs_Torus)
{
double h = uu2 - uu1;
uu1 -= 0.1 * h;
uu2 += 0.1 * h;
gasurf.Load((DStr.Surface(CD[pivot]->SetOfSurfData()->Value(i[pivot][deb])->Surf())).Surface(),
uu1,
uu2,
vv1,
vv2);
}
else if (styp == GeomAbs_BezierSurface || styp == GeomAbs_BSplineSurface)
{
gasurf.Load((DStr.Surface(CD[pivot]->SetOfSurfData()->Value(i[pivot][deb])->Surf())).Surface());
}
occ::handle<GeomAdaptor_Surface> Surf = new GeomAdaptor_Surface(gasurf);
// occ::handle<BRepTopAdaptor_TopolTool> IFac = new BRepTopAdaptor_TopolTool(Fac);
// Try to not classify on the face for cases of reentering fillets which naturally depass
// the border.
occ::handle<GeomAdaptor_Surface> bidsurf = new GeomAdaptor_Surface(Fac->GeomSurfaceOriginal());
occ::handle<Adaptor3d_TopolTool> IFac = new Adaptor3d_TopolTool(bidsurf);
// end of the attempt.
occ::handle<Adaptor3d_TopolTool> ISurf = new Adaptor3d_TopolTool(Surf);
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);
TopAbs_Orientation o1, o2, os1, os2, oo1, oo2;
int choix = CD[deb]->Choix();
o1 = face[pivot].Orientation();
o2 = fdpiv->Orientation();
oo1 = o1;
oo2 = o2;
os1 = CD[deb]->OrientationOnFace1();
os2 = CD[deb]->OrientationOnFace2();
if (jf[deb][fin] == 1)
{
choix = ChFi3d::NextSide(o1, o2, os1, os2, choix);
if (sens[deb] == 1)
{
if (choix % 2 == 1)
{
choix++;
}
else
{
choix--;
}
}
}
else
{
choix = ChFi3d::NextSide(o2, o1, os1, os2, -choix);
if (sens[deb] == -1)
{
if (choix % 2 == 1)
{
choix++;
}
else
{
choix--;
}
}
}
gp_Pnt2d pfac1, pfac2, psurf1, psurf2;
gp_Vec2d vfac1, vfac2;
CD[deb]
->SetOfSurfData()
->Value(i[deb][pivot])
->Interference(jf[deb][fin])
.PCurveOnFace()
->D1(p[deb][pivot], pfac1, vfac1);
CD[fin]
->SetOfSurfData()
->Value(i[fin][pivot])
->Interference(jf[fin][deb])
.PCurveOnFace()
->D1(p[fin][pivot], pfac2, vfac2);
psurf1 = CD[pivot]
->SetOfSurfData()
->Value(i[pivot][deb])
->Interference(jf[pivot][deb])
.PCurveOnSurf()
->Value(p[pivot][deb]);
psurf2 = CD[pivot]
->SetOfSurfData()
->Value(i[pivot][fin])
->Interference(jf[pivot][fin])
.PCurveOnSurf()
->Value(p[pivot][fin]);
done = false;
if (c1toric)
{
// Direct Construction.
// ---------------------
done = ChFiKPart_ComputeData::ComputeCorner(DStr,
coin,
Fac,
Surf,
oo1,
oo2,
o1,
o2,
Rdeb,
Rdp,
pfac1,
pfac2,
psurf1,
psurf2);
}
else if (c1spheric)
{
done = ChFiKPart_ComputeData::ComputeCorner(DStr,
coin,
Fac,
Surf,
oo1,
oo2,
o1,
o2,
Rdp,
pfac1,
psurf1,
psurf2);
}
else if (c1pointu)
{
filling = true;
}
if (!done)
{
if (!filling)
{
// Calculate a guideline,
//------------------------------
// Numerous problems with loops and half-turns connected to
// the curvature of the guideline !!!!!!
// FOR CIRCLE.
// If the nature of guideline is changed it is necessary to
// reset points Pdeb and Pfin at the inside (see the
// comments about it in the calculation of Pdeb and Pfin).
double radpondere = (Rdp + Rfp) / 2.;
double locfleche = fleche;
double WFirst, WLast;
occ::handle<Geom_Curve> spinecoin =
ChFi3d_CircularSpine(WFirst, WLast, Pdeb, Vdeb, Pfin, Vfin, radpondere);
if (spinecoin.IsNull())
{
// This is a bad case when the intersection of
// section planes is done out of the sector.
spinecoin = ChFi3d_Spine(Pdeb, Vdeb, Pfin, Vfin, radpondere);
WFirst = 0.;
WLast = 1.;
}
else
{
locfleche = radpondere * (WLast - WFirst) * fleche;
}
double pasmax = (WLast - WFirst) * 0.05;
occ::handle<ChFiDS_ElSpine> cornerspine = new ChFiDS_ElSpine();
cornerspine->SetCurve(spinecoin);
cornerspine->FirstParameter(WFirst - pasmax);
cornerspine->LastParameter(WLast + pasmax);
// Just to confuse Compute that should not require this
// in this exact case ...
occ::handle<ChFiDS_Spine> NullSpine;
// The fillet is calculated - from beginning to end
// - from the face to the surface
//
math_Vector Soldep(1, 4);
Soldep(1) = pfac1.X();
Soldep(2) = pfac1.Y();
Soldep(3) = psurf1.X();
Soldep(4) = psurf1.Y();
bool Gd1, Gd2, Gf1, Gf2;
occ::handle<BRepBlend_Line> lin;
double ffi = WFirst, lla = WLast + pasmax;
if (std::abs(Rdeb - Rfin) <= tolapp3d)
{
BRepBlend_ConstRad func(Fac, Surf, cornerspine);
BRepBlend_ConstRadInv finv(Fac, Surf, cornerspine);
func.Set(Rdeb, choix);
func.Set(myShape);
finv.Set(Rdeb, choix);
double TolGuide = cornerspine->Resolution(tolapp3d);
int intf = 3, intl = 3;
done = ComputeData(coin,
cornerspine,
NullSpine,
lin,
Fac,
IFac,
Surf,
ISurf,
func,
finv,
ffi,
pasmax,
locfleche,
TolGuide,
ffi,
lla,
false,
false,
true,
Soldep,
intf,
intl,
Gd1,
Gd2,
Gf1,
Gf2,
false,
true);
if (done && Gf2)
{
done = CompleteData(coin, func, lin, Fac, Surf, OFac, Gd1, false, Gf1, false);
filling = !done;
}
else
{
filling = true;
}
}
else
{
occ::handle<Law_S> law = new Law_S();
law->Set(WFirst, Rdeb, WLast, Rfin);
BRepBlend_EvolRad func(Fac, Surf, cornerspine, law);
BRepBlend_EvolRadInv finv(Fac, Surf, cornerspine, law);
func.Set(choix);
func.Set(myShape);
finv.Set(choix);
double TolGuide = cornerspine->Resolution(tolapp3d);
int intf = 3, intl = 3;
done = ComputeData(coin,
cornerspine,
NullSpine,
lin,
Fac,
IFac,
Surf,
ISurf,
func,
finv,
ffi,
pasmax,
locfleche,
TolGuide,
ffi,
lla,
false,
false,
true,
Soldep,
intf,
intl,
Gd1,
Gd2,
Gf1,
Gf2,
false,
true);
if (done && Gf2)
{
done = CompleteData(coin, func, lin, Fac, Surf, OFac, Gd1, false, Gf1, false);
filling = !done;
}
else
{
filling = true;
}
}
}
if (filling)
{
// the contour to be fillet consists of straight lines uv in beginning and end
// of two pcurves (only one if c1pointu) calculated as possible
// on piv and the opposite face.
occ::handle<GeomFill_Boundary> Bdeb, Bfin, Bpiv, Bfac;
occ::handle<Geom2d_Curve> PCurveOnFace;
if (!c1pointu)
{
Bfac = ChFi3d_mkbound(Fac,
PCurveOnFace,
sens[deb],
pfac1,
vfac1,
sens[fin],
pfac2,
vfac2,
tolapp3d,
2.e-4);
}
int kkk;
gp_Pnt ppbid;
gp_Vec vp1, vp2;
kkk =
CD[deb]->SetOfSurfData()->Value(i[deb][pivot])->Interference(jf[deb][pivot]).LineIndex();
DStr.Curve(kkk).Curve()->D1(p[deb][pivot], ppbid, vp1);
kkk =
CD[fin]->SetOfSurfData()->Value(i[fin][pivot])->Interference(jf[fin][pivot]).LineIndex();
DStr.Curve(kkk).Curve()->D1(p[fin][pivot], ppbid, vp2);
occ::handle<Geom2d_Curve> PCurveOnPiv;
// Bpiv = ChFi3d_mkbound(Surf,PCurveOnPiv,sens[deb],psurf1,vp1,
// sens[fin],psurf2,vp2,tolesp,2.e-4);
Bpiv = ChFi3d_mkbound(Surf, PCurveOnPiv, psurf1, psurf2, tolapp3d, 2.e-4, false);
double pardeb2 = p[deb][pivot];
double parfin2 = p[fin][pivot];
if (c1pointu)
{
pardeb2 = p[deb][fin];
parfin2 = p[fin][deb];
}
gp_Pnt2d pdeb1 = CD[deb]
->SetOfSurfData()
->Value(i[deb][pivot])
->Interference(jf[deb][pivot])
.PCurveOnSurf()
->Value(p[deb][pivot]);
gp_Pnt2d pdeb2 = CD[deb]
->SetOfSurfData()
->Value(i[deb][pivot])
->Interference(jf[deb][fin])
.PCurveOnSurf()
->Value(pardeb2);
gp_Pnt2d pfin1 = CD[fin]
->SetOfSurfData()
->Value(i[fin][pivot])
->Interference(jf[fin][pivot])
.PCurveOnSurf()
->Value(p[fin][pivot]);
gp_Pnt2d pfin2 = CD[fin]
->SetOfSurfData()
->Value(i[fin][pivot])
->Interference(jf[fin][deb])
.PCurveOnSurf()
->Value(parfin2);
occ::handle<Geom_Surface> sdeb =
DStr.Surface(CD[deb]->SetOfSurfData()->Value(i[deb][pivot])->Surf()).Surface();
occ::handle<Geom_Surface> sfin =
DStr.Surface(CD[fin]->SetOfSurfData()->Value(i[fin][pivot])->Surf()).Surface();
Bdeb = ChFi3d_mkbound(sdeb, pdeb1, pdeb2, tolapp3d, 2.e-4);
Bfin = ChFi3d_mkbound(sfin, pfin1, pfin2, tolapp3d, 2.e-4);
GeomFill_ConstrainedFilling fil(11, 20);
if (c1pointu)
{
fil.Init(Bpiv, Bfin, Bdeb, true);
}
else
{
fil.Init(Bpiv, Bfin, Bfac, Bdeb, true);
}
occ::handle<Geom_Surface> Surfcoin = fil.Surface();
Surfcoin->VReverse(); // revert to direction face surface;
done = CompleteData(coin,
Surfcoin,
Fac,
PCurveOnFace,
Surf,
PCurveOnPiv,
fdpiv->Orientation(),
false,
false,
false,
false,
false);
}
}
double P1deb, P2deb, P1fin, P2fin;
if (!c1pointu)
{
p[deb][fin] = p[deb][pivot];
p[fin][deb] = p[fin][pivot];
}
if (done)
{
// Update of 4 Stripes and the DS
// -------------------------------------
gp_Pnt2d pp1, pp2;
double parpp1, parpp2;
int If1, If2, Il1, Il2, Icf, Icl;
const ChFiDS_CommonPoint& Pf1 = coin->VertexFirstOnS1();
const ChFiDS_CommonPoint& Pf2 = coin->VertexFirstOnS2();
ChFiDS_CommonPoint& Pl1 = coin->ChangeVertexLastOnS1();
if (c1pointu)
{
Pl1 = coin->ChangeVertexFirstOnS1();
}
const ChFiDS_CommonPoint& Pl2 = coin->VertexLastOnS2();
Bnd_Box bf1, bl1, bf2, bl2;
Bnd_Box *pbf1 = &bf1, *pbl1 = &bl1, *pbf2 = &bf2, *pbl2 = &bl2;
if (c1pointu)
{
pbl1 = pbf1;
}
pbf1->Add(Pf1.Point());
pbf2->Add(Pf2.Point());
pbl1->Add(Pl1.Point());
pbl2->Add(Pl2.Point());
// the start corner,
// -----------------------
ChFiDS_Regul regdeb, regfin;
If1 = ChFi3d_IndexPointInDS(Pf1, DStr);
If2 = ChFi3d_IndexPointInDS(Pf2, DStr);
if (c1pointu)
{
Il1 = If1;
}
else
{
Il1 = ChFi3d_IndexPointInDS(Pl1, DStr);
}
Il2 = ChFi3d_IndexPointInDS(Pl2, DStr);
pp1 = coin->InterferenceOnS1().PCurveOnSurf()->Value(coin->InterferenceOnS1().FirstParameter());
pp2 = coin->InterferenceOnS2().PCurveOnSurf()->Value(coin->InterferenceOnS2().FirstParameter());
if (c1pointu)
{
coin->ChangeIndexOfS1(0);
}
else
{
coin->ChangeIndexOfS1(DStr.AddShape(face[pivot]));
}
coin->ChangeIndexOfS2(-fdpiv->Surf());
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);
TopOpeBRepDS_Curve Tcurv1(C3d, tolreached);
Icf = DStr.AddCurve(Tcurv1);
regdeb.SetCurve(Icf);
regdeb.SetS1(coin->Surf(), false);
regdeb.SetS2(fddeb->Surf(), false);
myRegul.Append(regdeb);
corner->ChangeFirstCurve(Icf);
corner->ChangeFirstParameters(P1deb, P2deb);
corner->ChangeIndexFirstPointOnS1(If1);
corner->ChangeIndexFirstPointOnS2(If2);
ChFi3d_EnlargeBox(DStr, corner, coin, *pbf1, *pbf2, true);
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);
TopOpeBRepDS_Curve Tcurv2(C3d, tolreached);
Icl = DStr.AddCurve(Tcurv2);
regfin.SetCurve(Icl);
regfin.SetS1(coin->Surf(), false);
regfin.SetS2(fdfin->Surf(), false);
myRegul.Append(regfin);
corner->ChangeLastCurve(Icl);
corner->ChangeLastParameters(P1fin, P2fin);
corner->ChangeIndexLastPointOnS1(Il1);
corner->ChangeIndexLastPointOnS2(Il2);
ChFi3d_EnlargeBox(DStr, corner, coin, *pbl1, *pbl2, false);
// then CornerData of the beginning,
// --------------------------------
bool isfirst = (sens[deb] == 1), rev = (jf[deb][fin] == 2);
int isurf1 = 1, isurf2 = 2;
parpp1 = p[deb][fin];
parpp2 = p[deb][pivot];
if (rev)
{
isurf1 = 2;
isurf2 = 1;
parpp1 = p[deb][pivot];
parpp2 = p[deb][fin];
CD[deb]->SetOrientation(TopAbs_REVERSED, isfirst);
}
pp1 = fddeb->InterferenceOnS1().PCurveOnSurf()->Value(parpp1);
pp2 = fddeb->InterferenceOnS2().PCurveOnSurf()->Value(parpp2);
CD[deb]->SetCurve(Icf, isfirst);
CD[deb]->SetIndexPoint(If1, isfirst, isurf1);
CD[deb]->SetIndexPoint(If2, isfirst, isurf2);
CD[deb]->SetParameters(isfirst, P1deb, P2deb);
fddeb->ChangeVertex(isfirst, isurf1) = Pf1;
fddeb->ChangeVertex(isfirst, isurf2) = Pf2;
fddeb->ChangeInterferenceOnS1().SetParameter(parpp1, isfirst);
fddeb->ChangeInterferenceOnS2().SetParameter(parpp2, isfirst);
TopOpeBRepDS_Curve& tcdeb = DStr.ChangeCurve(Icf);
occ::handle<Geom_Curve> crefdeb = tcdeb.Curve();
double tolrdeb;
ChFi3d_ComputePCurv(crefdeb,
pp1,
pp2,
CD[deb]->ChangePCurve(isfirst),
DStr.Surface(fddeb->Surf()).Surface(),
P1deb,
P2deb,
tolapp3d,
tolrdeb,
rev);
tcdeb.Tolerance(std::max(tolrdeb, tcdeb.Tolerance()));
if (rev)
{
ChFi3d_EnlargeBox(DStr, CD[deb], fddeb, *pbf2, *pbf1, isfirst);
}
else
{
ChFi3d_EnlargeBox(DStr, CD[deb], fddeb, *pbf1, *pbf2, isfirst);
}
// then the end CornerData,
// ------------------------
isfirst = (sens[fin] == 1);
rev = (jf[fin][deb] == 2);
isurf1 = 1;
isurf2 = 2;
parpp1 = p[fin][deb];
parpp2 = p[fin][pivot];
if (rev)
{
isurf1 = 2;
isurf2 = 1;
parpp1 = p[fin][pivot];
parpp2 = p[fin][deb];
CD[fin]->SetOrientation(TopAbs_REVERSED, isfirst);
}
pp1 = fdfin->InterferenceOnS1().PCurveOnSurf()->Value(parpp1);
pp2 = fdfin->InterferenceOnS2().PCurveOnSurf()->Value(parpp2);
CD[fin]->SetCurve(Icl, isfirst);
CD[fin]->SetIndexPoint(Il1, isfirst, isurf1);
CD[fin]->SetIndexPoint(Il2, isfirst, isurf2);
CD[fin]->SetParameters(isfirst, P1fin, P2fin);
fdfin->ChangeVertex(isfirst, isurf1) = Pl1;
fdfin->ChangeVertex(isfirst, isurf2) = Pl2;
fdfin->ChangeInterferenceOnS1().SetParameter(parpp1, isfirst);
fdfin->ChangeInterferenceOnS2().SetParameter(parpp2, isfirst);
TopOpeBRepDS_Curve& tcfin = DStr.ChangeCurve(Icl);
occ::handle<Geom_Curve> creffin = tcfin.Curve();
double tolrfin;
ChFi3d_ComputePCurv(creffin,
pp1,
pp2,
CD[fin]->ChangePCurve(isfirst),
DStr.Surface(fdfin->Surf()).Surface(),
P1fin,
P2fin,
tolapp3d,
tolrfin,
rev);
tcfin.Tolerance(std::max(tolrfin, tcfin.Tolerance()));
if (rev)
{
ChFi3d_EnlargeBox(DStr, CD[fin], fdfin, *pbl2, *pbl1, isfirst);
}
else
{
ChFi3d_EnlargeBox(DStr, CD[fin], fdfin, *pbl1, *pbl2, isfirst);
}
// anf finally the pivot.
// ------------------
ChFiDS_FaceInterference& fi = coin->ChangeInterferenceOnS2();
isfirst = (sens[pivot] == 1);
rev = (jf[pivot][deb] == 2);
isurf1 = 1;
isurf2 = 2;
if (rev)
{
isurf1 = 2;
isurf2 = 1;
CD[pivot]->SetOrientation(TopAbs_REVERSED, isfirst);
}
int ICcoinpiv = fi.LineIndex();
TopOpeBRepDS_Curve& TCcoinpiv = DStr.ChangeCurve(ICcoinpiv);
CD[pivot]->SetCurve(ICcoinpiv, isfirst);
occ::handle<Geom_Curve> Ccoinpiv = DStr.Curve(ICcoinpiv).Curve();
occ::handle<Geom2d_Curve>& C2dOnPiv = fi.ChangePCurveOnFace();
occ::handle<Geom_Surface> Spiv = DStr.Surface(fdpiv->Surf()).Surface();
double tolr;
ChFi3d_SameParameter(Ccoinpiv,
C2dOnPiv,
Spiv,
fi.FirstParameter(),
fi.LastParameter(),
tolapp3d,
tolr);
TCcoinpiv.Tolerance(std::max(TCcoinpiv.Tolerance(), tolr));
CD[pivot]->ChangePCurve(isfirst) = C2dOnPiv;
CD[pivot]->SetIndexPoint(If2, isfirst, isurf1);
CD[pivot]->SetIndexPoint(Il2, isfirst, isurf2);
CD[pivot]->SetParameters(isfirst, fi.FirstParameter(), fi.LastParameter());
fdpiv->ChangeVertex(isfirst, isurf1) = Pf2;
fdpiv->ChangeVertex(isfirst, isurf2) = Pl2;
fdpiv->ChangeInterference(isurf1).SetParameter(p[pivot][deb], isfirst);
fdpiv->ChangeInterference(isurf2).SetParameter(p[pivot][fin], isfirst);
CD[pivot]->InDS(isfirst); // filDS already does it from the corner.
if (rev)
{
ChFi3d_EnlargeBox(DStr, CD[pivot], fdpiv, *pbl2, *pbf2, isfirst);
}
else
{
ChFi3d_EnlargeBox(DStr, CD[pivot], fdpiv, *pbf2, *pbl2, isfirst);
}
// To end the tolerances of points are rescaled.
ChFi3d_SetPointTolerance(DStr, *pbf1, If1);
ChFi3d_SetPointTolerance(DStr, *pbf2, If2);
ChFi3d_SetPointTolerance(DStr, *pbl1, Il1);
ChFi3d_SetPointTolerance(DStr, *pbl2, Il2);
}
// The data corners are truncated and index is updated.
//----------------------------------------------------
if (i[deb][pivot] < Index[deb])
{
CD[deb]->ChangeSetOfSurfData()->Remove(i[deb][pivot] + 1, Index[deb]);
Index[deb] = i[deb][pivot];
}
else if (i[deb][pivot] > Index[deb])
{
CD[deb]->ChangeSetOfSurfData()->Remove(Index[deb], i[deb][pivot] - 1);
i[deb][pivot] = Index[deb];
}
if (i[fin][pivot] < Index[fin])
{
CD[fin]->ChangeSetOfSurfData()->Remove(i[fin][pivot] + 1, Index[fin]);
Index[fin] = i[fin][pivot];
}
else if (i[fin][pivot] > Index[fin])
{
CD[fin]->ChangeSetOfSurfData()->Remove(Index[fin], i[fin][pivot] - 1);
i[fin][pivot] = Index[fin];
}
// it is necessary to take into account mutant corners.
if (i[pivot][deb] < Index[pivot])
{
CD[pivot]->ChangeSetOfSurfData()->Remove(i[pivot][deb] + 1, Index[pivot]);
Index[pivot] = i[pivot][deb];
}
else if (i[pivot][deb] > Index[pivot])
{
CD[pivot]->ChangeSetOfSurfData()->Remove(Index[pivot], i[pivot][deb] - 1);
i[pivot][deb] = Index[pivot];
}
if (!myEVIMap.IsBound(Vtx))
{
NCollection_List<int> li;
myEVIMap.Bind(Vtx, li);
}
myEVIMap.ChangeFind(Vtx).Append(coin->Surf());
corner->SetSolidIndex(CD[pivot]->SolidIndex());
myListStripe.Append(corner);
}