Loading files
f2929057eThis file is pinned to the selected release. Download the original to open it in your design tool.
// Created on: 1994-02-03
// 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_Surface.hxx>
#include <ChFiDS_SurfData.hxx>
#include <ChFiKPart_ComputeData.hxx>
#include <ChFiKPart_ComputeData_Fcts.hxx>
#include <ElCLib.hxx>
#include <ElSLib.hxx>
#include <Geom2d_Circle.hxx>
#include <Geom2d_Line.hxx>
#include <Geom_Circle.hxx>
#include <Geom_SphericalSurface.hxx>
#include <Geom_ToroidalSurface.hxx>
#include <gp.hxx>
#include <gp_Ax2.hxx>
#include <gp_Ax3.hxx>
#include <gp_Circ.hxx>
#include <gp_Cone.hxx>
#include <gp_Dir.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Lin2d.hxx>
#include <gp_Pln.hxx>
#include <gp_Pnt.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Vec.hxx>
#include <IntAna_QuadQuadGeo.hxx>
#include <Precision.hxx>
#include <TopOpeBRepDS_DataStructure.hxx>
//=======================================================================
// function : MakeFillet
// purpose : case cone/plane or plane/cone.
//=======================================================================
bool ChFiKPart_MakeFillet(TopOpeBRepDS_DataStructure& DStr,
const occ::handle<ChFiDS_SurfData>& Data,
const gp_Pln& Pln,
const gp_Cone& Con,
const double fu,
const double lu,
const TopAbs_Orientation Or1,
const TopAbs_Orientation Or2,
const double Radius,
const gp_Circ& Spine,
const double First,
const TopAbs_Orientation Ofpl,
const bool plandab)
{
// calculate the fillet (torus or sphere).
bool c1sphere = false;
gp_Ax3 PosPl = Pln.Position();
gp_Dir Dpnat = PosPl.XDirection().Crossed(PosPl.YDirection());
gp_Dir Dp = Dpnat;
gp_Dir Df = Dp;
if (Or1 == TopAbs_REVERSED)
{
Dp.Reverse();
}
if (Ofpl == TopAbs_REVERSED)
{
Df.Reverse();
}
gp_Pnt Or = Con.Location();
double u, v;
ElSLib::PlaneParameters(PosPl, Or, u, v);
gp_Pnt2d c2dPln(u, v);
ElSLib::PlaneD0(u, v, PosPl, Or);
gp_Pnt cPln = Or;
Or.SetCoord(Or.X() + Radius * Dp.X(), Or.Y() + Radius * Dp.Y(), Or.Z() + Radius * Dp.Z());
gp_Pnt PtSp;
gp_Vec DSp;
ElCLib::D1(First, Spine, PtSp, DSp);
IntAna_QuadQuadGeo CInt(Pln, Con, Precision::Angular(), Precision::Confusion());
gp_Pnt Pv;
if (CInt.IsDone())
{
// The origin of the fillet is set at the start point on the
// guideline.
Pv = ElCLib::Value(ElCLib::Parameter(CInt.Circle(1), PtSp), CInt.Circle(1));
}
else
{
return false;
}
gp_Dir Dx(gp_Vec(cPln, Pv));
gp_Dir Dy(DSp);
ElSLib::Parameters(Con, Pv, u, v);
gp_Pnt PtCon;
gp_Vec Vu, Vv;
ElSLib::D1(u, v, Con, PtCon, Vu, Vv);
gp_Dir Dc(Vu.Crossed(Vv));
if (Or2 == TopAbs_REVERSED)
{
Dc.Reverse();
}
gp_Dir Dz = Dp;
gp_Pnt pp(Pv.X() + Dc.X(), Pv.Y() + Dc.Y(), Pv.Z() + Dc.Z());
ElSLib::PlaneParameters(PosPl, pp, u, v);
ElSLib::PlaneD0(u, v, PosPl, pp);
gp_Dir ddp(gp_Vec(Pv, pp));
ElSLib::Parameters(Con, Pv, u, v);
gp_Vec dcu, dcv;
ElSLib::D1(u, v, Con, pp, dcu, dcv);
gp_Dir ddc(dcv);
if (ddc.Dot(Dp) < 0.)
{
ddc.Reverse();
}
double Ang = ddp.Angle(ddc);
double Rabio = Radius / std::tan(Ang / 2);
double Maxrad = cPln.Distance(Pv);
double Rad;
bool dedans = Dx.Dot(Dc) <= 0.;
if (dedans)
{
if (!plandab)
{
Dz.Reverse();
}
Rad = Maxrad - Rabio;
if (std::abs(Rad) <= Precision::Confusion())
{
c1sphere = true;
}
else if (Rad < 0)
{
#ifdef OCCT_DEBUG
std::cout << "the fillet does not pass" << std::endl;
#endif
return false;
}
}
else
{
if (plandab)
{
Dz.Reverse();
}
Rad = Maxrad + Rabio;
}
gp_Ax3 FilAx3(Or, Dz, Dx);
if (FilAx3.YDirection().Dot(Dy) <= 0.)
{
FilAx3.YReverse();
}
if (c1sphere)
{
occ::handle<Geom_SphericalSurface> gsph = new Geom_SphericalSurface(FilAx3, Radius);
Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(gsph, DStr));
}
else
{
occ::handle<Geom_ToroidalSurface> gtor = new Geom_ToroidalSurface(FilAx3, Rad, Radius);
Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(gtor, DStr));
}
// It is checked if the orientation of the fillet is the same
// as of the faces.
gp_Pnt P, PP;
gp_Vec deru, derv;
P.SetCoord(cPln.X() + Rad * Dx.X(), cPln.Y() + Rad * Dx.Y(), cPln.Z() + Rad * Dx.Z());
if (c1sphere)
{
ElSLib::SphereParameters(FilAx3, Rad, P, u, v);
ElSLib::SphereD1(u, v, FilAx3, Rad, PP, deru, derv);
}
else
{
ElSLib::TorusParameters(FilAx3, Rad, Radius, P, u, v);
ElSLib::TorusD1(u, v, FilAx3, Rad, Radius, PP, deru, derv);
if (!plandab && Ang < M_PI / 2 && dedans)
{
v = v + 2 * M_PI;
}
}
gp_Pnt2d p2dFil(0., v);
gp_Dir norFil(deru.Crossed(derv));
bool toreverse = (norFil.Dot(Df) <= 0.);
if (toreverse)
{
Data->ChangeOrientation() = TopAbs_REVERSED;
}
else
{
Data->ChangeOrientation() = TopAbs_FORWARD;
}
// FaceInterferences are loaded with pcurves and curves 3d.
// ---------------------------------------------------------------
// The plane face.
// --------------
occ::handle<Geom2d_Circle> GCirc2dPln;
occ::handle<Geom_Circle> GCircPln;
gp_Ax2 circAx2 = FilAx3.Ax2();
if (!c1sphere)
{
ElSLib::PlaneParameters(PosPl, P, u, v);
gp_Pnt2d p2dPln(u, v);
gp_Dir2d d2d(DSp.Dot(PosPl.XDirection()), DSp.Dot(PosPl.YDirection()));
gp_Ax22d ax2dPln(c2dPln, gp_Dir2d(gp_Vec2d(c2dPln, p2dPln)), d2d);
gp_Circ2d circ2dPln(ax2dPln, Rad);
GCirc2dPln = new Geom2d_Circle(circ2dPln);
circAx2.SetLocation(cPln);
gp_Circ circPln(circAx2, Rad);
GCircPln = new Geom_Circle(circPln);
}
gp_Lin2d lin2dFil(p2dFil, gp::DX2d());
occ::handle<Geom2d_Line> GLin2dFil1 = new Geom2d_Line(lin2dFil);
toreverse = (norFil.Dot(Dpnat) <= 0.);
TopAbs_Orientation trans;
if ((toreverse && plandab) || (!toreverse && !plandab))
{
trans = TopAbs_FORWARD;
}
else
{
trans = TopAbs_REVERSED;
}
if (plandab)
{
Data->ChangeInterferenceOnS1().SetInterference(ChFiKPart_IndexCurveInDS(GCircPln, DStr),
trans,
GCirc2dPln,
GLin2dFil1);
}
else
{
Data->ChangeInterferenceOnS2().SetInterference(ChFiKPart_IndexCurveInDS(GCircPln, DStr),
trans,
GCirc2dPln,
GLin2dFil1);
}
// The conic face.
// ----------------
P.SetCoord(Pv.X() + Rabio * ddc.X(), Pv.Y() + Rabio * ddc.Y(), Pv.Z() + Rabio * ddc.Z());
if (c1sphere)
{
ElSLib::SphereParameters(FilAx3, Radius, P, u, v);
ElSLib::SphereD1(u, v, FilAx3, Radius, PP, deru, derv);
}
else
{
ElSLib::TorusParameters(FilAx3, Rad, Radius, P, u, v);
ElSLib::TorusD1(u, v, FilAx3, Rad, Radius, PP, deru, derv);
if (plandab && Ang < M_PI / 2 && dedans)
{
v = v + 2 * M_PI;
}
}
norFil = deru.Crossed(derv);
p2dFil.SetCoord(0., v);
lin2dFil.SetLocation(p2dFil);
occ::handle<Geom2d_Line> GLin2dFil2 = new Geom2d_Line(lin2dFil);
ElSLib::Parameters(Con, P, u, v);
double tol = Precision::PConfusion();
bool careaboutsens = false;
if (std::abs(lu - fu - 2 * M_PI) < tol)
{
careaboutsens = true;
}
if (u >= fu - tol && u < fu)
{
u = fu;
}
if (u <= lu + tol && u > lu)
{
u = lu;
}
if (u < fu || u > lu)
{
u = ElCLib::InPeriod(u, fu, fu + 2 * M_PI);
}
ElSLib::D1(u, v, Con, PP, deru, derv);
gp_Dir norCon = deru.Crossed(derv);
gp_Dir2d d2dCon = gp::DX2d();
if (deru.Dot(Dy) < 0.)
{
d2dCon.Reverse();
if (careaboutsens && std::abs(fu - u) < tol)
{
u = lu;
}
}
else if (careaboutsens && std::abs(lu - u) < tol)
{
u = fu;
}
gp_Pnt2d p2dCon(u, v);
gp_Lin2d lin2dCon(p2dCon, d2dCon);
occ::handle<Geom2d_Line> GLin2dCon = new Geom2d_Line(lin2dCon);
double scal = gp_Vec(Dp).Dot(gp_Vec(Pv, P));
PP.SetCoord(cPln.X() + scal * Dp.X(), cPln.Y() + scal * Dp.Y(), cPln.Z() + scal * Dp.Z());
circAx2.SetLocation(PP);
gp_Circ circCon(circAx2, P.Distance(PP));
occ::handle<Geom_Circle> GCircCon = new Geom_Circle(circCon);
toreverse = (norFil.Dot(norCon) <= 0.);
if ((toreverse && plandab) || (!toreverse && !plandab))
{
trans = TopAbs_REVERSED;
}
else
{
trans = TopAbs_FORWARD;
}
if (plandab)
{
Data->ChangeInterferenceOnS2().SetInterference(ChFiKPart_IndexCurveInDS(GCircCon, DStr),
trans,
GLin2dCon,
GLin2dFil2);
}
else
{
Data->ChangeInterferenceOnS1().SetInterference(ChFiKPart_IndexCurveInDS(GCircCon, DStr),
trans,
GLin2dCon,
GLin2dFil2);
}
return true;
}