1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-03 17:56:21 +03:00
occt/src/BRepBlend/BRepBlend_SurfRstEvolRad.cxx
dpasukhi a5a7b3185b Coding - Apply .clang-format formatting #286
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.
2025-01-26 00:43:57 +00:00

1162 lines
34 KiB
C++

// Created on: 1997-07-28
// Created by: Jerome LEMONIER
// Copyright (c) 1997-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 <Adaptor2d_Curve2d.hxx>
#include <Blend_Point.hxx>
#include <BlendFunc.hxx>
#include <BRepBlend_SurfRstEvolRad.hxx>
#include <ElCLib.hxx>
#include <GeomFill.hxx>
#include <gp_Circ.hxx>
#include <gp_Pnt.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Vec.hxx>
#include <gp_Vec2d.hxx>
#include <Law_Function.hxx>
#include <math_Gauss.hxx>
#include <math_Matrix.hxx>
#include <math_SVD.hxx>
#include <Precision.hxx>
#include <Standard_DomainError.hxx>
#include <Standard_NotImplemented.hxx>
#include <TColStd_SequenceOfReal.hxx>
#define Eps 1.e-15
static void t3dto2d(Standard_Real& a,
Standard_Real& b,
const gp_Vec& A,
const gp_Vec& B,
const gp_Vec& C)
{
Standard_Real AB = A.Dot(B);
Standard_Real AC = A.Dot(C);
Standard_Real BC = B.Dot(C);
Standard_Real BB = B.Dot(B);
Standard_Real CC = C.Dot(C);
Standard_Real deno = (BB * CC - BC * BC);
a = (AB * CC - AC * BC) / deno;
b = (AC * BB - AB * BC) / deno;
}
static void FusionneIntervalles(const TColStd_Array1OfReal& I1,
const TColStd_Array1OfReal& I2,
TColStd_SequenceOfReal& Seq)
{
Standard_Integer ind1 = 1, ind2 = 1;
Standard_Real Epspar = Precision::PConfusion() * 0.99;
// it is supposed that positioning works with PConfusion()/2
Standard_Real v1, v2;
// Initialisation : IND1 and IND2 point at the first element
// of each of 2 tables to be processed. INDS points at the last
// element created by TABSOR
//--- TABSOR is filled by parsing TABLE1 and TABLE2 simultaneously ---
//------------------ and eliminating multiple occurrences ------------
while ((ind1 <= I1.Upper()) && (ind2 <= I2.Upper()))
{
v1 = I1(ind1);
v2 = I2(ind2);
if (Abs(v1 - v2) <= Epspar)
{
// Here the elements of I1 and I2 fit.
Seq.Append((v1 + v2) / 2);
ind1++;
ind2++;
}
else if (v1 < v2)
{
// Here the element of I1 fits.
Seq.Append(v1);
ind1++;
}
else
{
// Here the element of TABLE2 fits.
Seq.Append(v2);
ind2++;
}
}
if (ind1 > I1.Upper())
{
//----- Here I1 is exhausted, completed with the end of TABLE2 -------
for (; ind2 <= I2.Upper(); ind2++)
{
Seq.Append(I2(ind2));
}
}
if (ind2 > I2.Upper())
{
//----- Here I2 is exhausted, completed with the end of I1 -------
for (; ind1 <= I1.Upper(); ind1++)
{
Seq.Append(I1(ind1));
}
}
}
//=================================================================================================
BRepBlend_SurfRstEvolRad::BRepBlend_SurfRstEvolRad(const Handle(Adaptor3d_Surface)& Surf,
const Handle(Adaptor3d_Surface)& SurfRst,
const Handle(Adaptor2d_Curve2d)& Rst,
const Handle(Adaptor3d_Curve)& CGuide,
const Handle(Law_Function)& Evol)
: surf(Surf),
surfrst(SurfRst),
rst(Rst),
cons(Rst, SurfRst),
guide(CGuide),
tguide(CGuide),
istangent(Standard_True),
maxang(RealFirst()),
minang(RealLast()),
distmin(RealLast()),
mySShape(BlendFunc_Rational)
{
tevol = Evol;
fevol = Evol;
}
//=================================================================================================
Standard_Integer BRepBlend_SurfRstEvolRad::NbVariables() const
{
return 3;
}
//=================================================================================================
Standard_Integer BRepBlend_SurfRstEvolRad::NbEquations() const
{
return 3;
}
//=================================================================================================
Standard_Boolean BRepBlend_SurfRstEvolRad::Value(const math_Vector& X, math_Vector& F)
{
gp_Vec d1u1, d1v1, ns, vref;
Standard_Real norm;
surf->D1(X(1), X(2), pts, d1u1, d1v1);
ptrst = cons.Value(X(3));
F(1) = nplan.XYZ().Dot(pts.XYZ()) + theD;
F(2) = nplan.XYZ().Dot(ptrst.XYZ()) + theD;
ns = d1u1.Crossed(d1v1);
norm = nplan.Crossed(ns).Magnitude();
ns.SetLinearForm(nplan.Dot(ns) / norm, nplan, -1. / norm, ns);
vref.SetLinearForm(ray, ns, gp_Vec(ptrst, pts));
F(3) = vref.SquareMagnitude() - ray * ray;
return Standard_True;
}
//=================================================================================================
Standard_Boolean BRepBlend_SurfRstEvolRad::Derivatives(const math_Vector& X, math_Matrix& D)
{
gp_Vec d1u1, d1v1, d2u1, d2v1, d2uv1, d1;
gp_Vec ns, ncrossns, resul, temp, vref;
Standard_Real norm, ndotns, grosterme;
surf->D2(X(1), X(2), pts, d1u1, d1v1, d2u1, d2v1, d2uv1);
cons.D1(X(3), ptrst, d1);
D(1, 1) = nplan.Dot(d1u1);
D(1, 2) = nplan.Dot(d1v1);
D(1, 3) = 0.;
D(2, 1) = 0.;
D(2, 2) = 0.;
D(2, 3) = nplan.Dot(d1);
ns = d1u1.Crossed(d1v1);
ncrossns = nplan.Crossed(ns);
norm = ncrossns.Magnitude();
ndotns = nplan.Dot(ns);
vref.SetLinearForm(ndotns, nplan, -1., ns);
vref.Divide(norm);
vref.SetLinearForm(ray, vref, gp_Vec(ptrst, pts));
// Derivative corresponding to u1
temp = d2u1.Crossed(d1v1).Added(d1u1.Crossed(d2uv1));
grosterme = ncrossns.Dot(nplan.Crossed(temp)) / norm / norm;
resul.SetLinearForm(-ray / norm * (grosterme * ndotns - nplan.Dot(temp)),
nplan,
ray * grosterme / norm,
ns,
-ray / norm,
temp,
d1u1);
D(3, 1) = 2. * (resul.Dot(vref));
// Derivative corresponding to v1
temp = d2uv1.Crossed(d1v1).Added(d1u1.Crossed(d2v1));
grosterme = ncrossns.Dot(nplan.Crossed(temp)) / norm / norm;
resul.SetLinearForm(-ray / norm * (grosterme * ndotns - nplan.Dot(temp)),
nplan,
ray * grosterme / norm,
ns,
-ray / norm,
temp,
d1v1);
D(3, 2) = 2. * (resul.Dot(vref));
D(3, 3) = -2. * (d1.Dot(vref));
return Standard_True;
}
//=================================================================================================
Standard_Boolean BRepBlend_SurfRstEvolRad::Values(const math_Vector& X,
math_Vector& F,
math_Matrix& D)
{
gp_Vec d1u1, d1v1, d1;
gp_Vec d2u1, d2v1, d2uv1;
gp_Vec ns, ncrossns, resul, temp, vref;
Standard_Real norm, ndotns, grosterme;
surf->D2(X(1), X(2), pts, d1u1, d1v1, d2u1, d2v1, d2uv1);
cons.D1(X(3), ptrst, d1);
F(1) = nplan.XYZ().Dot(pts.XYZ()) + theD;
F(2) = nplan.XYZ().Dot(ptrst.XYZ()) + theD;
D(1, 1) = nplan.Dot(d1u1);
D(1, 2) = nplan.Dot(d1v1);
D(1, 3) = 0.;
D(2, 1) = 0.;
D(2, 2) = 0.;
D(2, 3) = nplan.Dot(d1);
ns = d1u1.Crossed(d1v1);
ncrossns = nplan.Crossed(ns);
norm = ncrossns.Magnitude();
ndotns = nplan.Dot(ns);
vref.SetLinearForm(ndotns, nplan, -1., ns);
vref.Divide(norm);
vref.SetLinearForm(ray, vref, gp_Vec(ptrst, pts));
F(3) = vref.SquareMagnitude() - ray * ray;
// Derivative corresponding to u1
temp = d2u1.Crossed(d1v1).Added(d1u1.Crossed(d2uv1));
grosterme = ncrossns.Dot(nplan.Crossed(temp)) / norm / norm;
resul.SetLinearForm(-ray / norm * (grosterme * ndotns - nplan.Dot(temp)),
nplan,
ray * grosterme / norm,
ns,
-ray / norm,
temp,
d1u1);
D(3, 1) = 2. * (resul.Dot(vref));
// Derivative corresponding to v1
temp = d2uv1.Crossed(d1v1).Added(d1u1.Crossed(d2v1));
grosterme = ncrossns.Dot(nplan.Crossed(temp)) / norm / norm;
resul.SetLinearForm(-ray / norm * (grosterme * ndotns - nplan.Dot(temp)),
nplan,
ray * grosterme / norm,
ns,
-ray / norm,
temp,
d1v1);
D(3, 2) = 2. * (resul.Dot(vref));
D(3, 3) = -2. * (d1.Dot(vref));
return Standard_True;
}
//=================================================================================================
void BRepBlend_SurfRstEvolRad::Set(const Handle(Adaptor3d_Surface)& SurfRef,
const Handle(Adaptor2d_Curve2d)& RstRef)
{
surfref = SurfRef;
rstref = RstRef;
}
//=================================================================================================
void BRepBlend_SurfRstEvolRad::Set(const Standard_Real Param)
{
d1gui = gp_Vec(0., 0., 0.);
nplan = gp_Vec(0., 0., 0.);
tguide->D2(Param, ptgui, d1gui, d2gui);
normtg = d1gui.Magnitude();
nplan.SetXYZ(d1gui.Normalized().XYZ());
gp_XYZ nplanXYZ(nplan.XYZ());
gp_XYZ ptguiXYZ(ptgui.XYZ());
theD = nplanXYZ.Dot(ptguiXYZ);
theD = theD * (-1.);
tevol->D1(Param, ray, dray);
ray = sg1 * ray;
dray = sg1 * dray;
}
//=======================================================================
// function :
// purpose : Segments the curve in its useful part.
// Precision is taken arbitrary small !?
//=======================================================================
void BRepBlend_SurfRstEvolRad::Set(const Standard_Real First, const Standard_Real Last)
{
tguide = guide->Trim(First, Last, 1.e-12);
tevol = fevol->Trim(First, Last, 1.e-12);
}
//=================================================================================================
void BRepBlend_SurfRstEvolRad::GetTolerance(math_Vector& Tolerance, const Standard_Real Tol) const
{
Tolerance(1) = surf->UResolution(Tol);
Tolerance(2) = surf->VResolution(Tol);
Tolerance(3) = cons.Resolution(Tol);
}
//=================================================================================================
void BRepBlend_SurfRstEvolRad::GetBounds(math_Vector& InfBound, math_Vector& SupBound) const
{
InfBound(1) = surf->FirstUParameter();
InfBound(2) = surf->FirstVParameter();
InfBound(3) = cons.FirstParameter();
SupBound(1) = surf->LastUParameter();
SupBound(2) = surf->LastVParameter();
SupBound(3) = cons.LastParameter();
if (!Precision::IsInfinite(InfBound(1)) && !Precision::IsInfinite(SupBound(1)))
{
Standard_Real range = (SupBound(1) - InfBound(1));
InfBound(1) -= range;
SupBound(1) += range;
}
if (!Precision::IsInfinite(InfBound(2)) && !Precision::IsInfinite(SupBound(2)))
{
Standard_Real range = (SupBound(2) - InfBound(2));
InfBound(2) -= range;
SupBound(2) += range;
}
}
//=================================================================================================
Standard_Boolean BRepBlend_SurfRstEvolRad::IsSolution(const math_Vector& Sol,
const Standard_Real Tol)
{
math_Vector valsol(1, 3), secmember(1, 3);
math_Matrix gradsol(1, 3, 1, 3);
gp_Vec dnplan, d1u1, d1v1, d1urst, d1vrst, d1, temp, ns, ns2, ncrossns, resul;
gp_Pnt bid;
Standard_Real norm, ndotns, grosterme;
Standard_Real Cosa, Sina, Angle;
Values(Sol, valsol, gradsol);
if (Abs(valsol(1)) <= Tol && Abs(valsol(2)) <= Tol && Abs(valsol(3)) <= 2 * Tol * Abs(ray))
{
// Calculation of tangents
pt2ds = gp_Pnt2d(Sol(1), Sol(2));
prmrst = Sol(3);
pt2drst = rst->Value(prmrst);
surf->D1(Sol(1), Sol(2), pts, d1u1, d1v1);
cons.D1(Sol(3), ptrst, d1);
dnplan.SetLinearForm(1. / normtg, d2gui, -1. / normtg * (nplan.Dot(d2gui)), nplan);
temp.SetXYZ(pts.XYZ() - ptgui.XYZ());
secmember(1) = normtg - dnplan.Dot(temp);
temp.SetXYZ(ptrst.XYZ() - ptgui.XYZ());
secmember(2) = normtg - dnplan.Dot(temp);
ns = d1u1.Crossed(d1v1);
ncrossns = nplan.Crossed(ns);
ndotns = nplan.Dot(ns);
norm = ncrossns.Magnitude();
grosterme = ncrossns.Dot(dnplan.Crossed(ns)) / norm / norm;
gp_Vec dnw;
dnw.SetLinearForm((dnplan.Dot(ns) - grosterme * ndotns) / norm,
nplan,
ndotns / norm,
dnplan,
grosterme / norm,
ns);
ns.SetLinearForm(ndotns / norm, nplan, -1. / norm, ns);
resul.SetLinearForm(ray, ns, gp_Vec(ptrst, pts));
secmember(3) = -2. * ray * (dnw.Dot(resul)) - 2. * dray * (ns.Dot(resul)) + 2. * ray * dray;
math_Gauss Resol(gradsol);
if (Resol.IsDone())
{
Resol.Solve(secmember);
istangent = Standard_False;
}
else
{
math_SVD SingRS(gradsol);
if (SingRS.IsDone())
{
math_Vector DEDT(1, 3);
DEDT = secmember;
SingRS.Solve(DEDT, secmember, 1.e-6);
istangent = Standard_False;
}
else
istangent = Standard_True;
}
if (!istangent)
{
tgs.SetLinearForm(secmember(1), d1u1, secmember(2), d1v1);
tgrst = secmember(3) * d1;
tg2ds.SetCoord(secmember(1), secmember(2));
surfrst->D1(pt2drst.X(), pt2drst.Y(), bid, d1urst, d1vrst);
Standard_Real a, b;
t3dto2d(a, b, tgrst, d1urst, d1vrst);
tg2drst.SetCoord(a, b);
istangent = Standard_False;
}
else
{
istangent = Standard_True;
}
// update of maxang
if (ray > 0.)
ns.Reverse();
ns2 = -resul.Normalized();
Cosa = ns.Dot(ns2);
Sina = nplan.Dot(ns.Crossed(ns2));
if (choix % 2 != 0)
{
Sina = -Sina; // nplan is changed into -nplan
}
Angle = ACos(Cosa);
if (Sina < 0.)
{
Angle = 2. * M_PI - Angle;
}
if (Angle > maxang)
{
maxang = Angle;
}
if (Angle < minang)
{
minang = Angle;
}
distmin = Min(distmin, pts.Distance(ptrst));
return Standard_True;
}
istangent = Standard_True;
return Standard_False;
}
//=================================================================================================
Standard_Real BRepBlend_SurfRstEvolRad::GetMinimalDistance() const
{
return distmin;
}
//=================================================================================================
const gp_Pnt& BRepBlend_SurfRstEvolRad::PointOnS() const
{
return pts;
}
//=================================================================================================
const gp_Pnt& BRepBlend_SurfRstEvolRad::PointOnRst() const
{
return ptrst;
}
//=================================================================================================
const gp_Pnt2d& BRepBlend_SurfRstEvolRad::Pnt2dOnS() const
{
return pt2ds;
}
//=================================================================================================
const gp_Pnt2d& BRepBlend_SurfRstEvolRad::Pnt2dOnRst() const
{
return pt2drst;
}
//=================================================================================================
Standard_Real BRepBlend_SurfRstEvolRad::ParameterOnRst() const
{
return prmrst;
}
//=================================================================================================
Standard_Boolean BRepBlend_SurfRstEvolRad::IsTangencyPoint() const
{
return istangent;
}
//=================================================================================================
const gp_Vec& BRepBlend_SurfRstEvolRad::TangentOnS() const
{
if (istangent)
{
throw Standard_DomainError();
}
return tgs;
}
//=================================================================================================
const gp_Vec2d& BRepBlend_SurfRstEvolRad::Tangent2dOnS() const
{
if (istangent)
{
throw Standard_DomainError();
}
return tg2ds;
}
//=================================================================================================
const gp_Vec& BRepBlend_SurfRstEvolRad::TangentOnRst() const
{
if (istangent)
{
throw Standard_DomainError();
}
return tgrst;
}
//=================================================================================================
const gp_Vec2d& BRepBlend_SurfRstEvolRad::Tangent2dOnRst() const
{
if (istangent)
{
throw Standard_DomainError();
}
return tg2drst;
}
//=================================================================================================
Standard_Boolean BRepBlend_SurfRstEvolRad::Decroch(const math_Vector& Sol,
gp_Vec& NS,
gp_Vec& TgS) const
{
gp_Vec TgRst, NRst, NRstInPlane, NSInPlane;
gp_Pnt bid, Center;
gp_Vec d1u, d1v;
Standard_Real norm, unsurnorm;
surf->D1(Sol(1), Sol(2), bid, d1u, d1v);
NS = NSInPlane = d1u.Crossed(d1v);
norm = nplan.Crossed(NS).Magnitude();
unsurnorm = 1. / norm;
NSInPlane.SetLinearForm(nplan.Dot(NS) * unsurnorm, nplan, -unsurnorm, NS);
Center.SetXYZ(bid.XYZ() + ray * NSInPlane.XYZ());
if (choix > 2)
NSInPlane.Reverse();
TgS = nplan.Crossed(gp_Vec(Center, bid));
if (choix % 2 == 1)
{
TgS.Reverse();
}
Standard_Real u, v;
rstref->Value(Sol(3)).Coord(u, v);
surfref->D1(u, v, bid, d1u, d1v);
NRst = d1u.Crossed(d1v);
norm = nplan.Crossed(NRst).Magnitude();
unsurnorm = 1. / norm;
NRstInPlane.SetLinearForm(nplan.Dot(NRst) * unsurnorm, nplan, -unsurnorm, NRst);
gp_Vec centptrst(Center, bid);
if (centptrst.Dot(NRstInPlane) < 0.)
NRstInPlane.Reverse();
TgRst = nplan.Crossed(centptrst);
if (choix % 2 == 1)
{
TgRst.Reverse();
}
Standard_Real dot, NT = NRstInPlane.Magnitude();
NT *= TgRst.Magnitude();
if (Abs(NT) < 1.e-7)
{
return Standard_False; // Singularity or Incoherence.
}
dot = NRstInPlane.Dot(TgRst);
dot /= NT;
return (dot < 1.e-10);
}
//=================================================================================================
void BRepBlend_SurfRstEvolRad::Set(const Standard_Integer Choix)
{
choix = Choix;
switch (choix)
{
case 1:
case 2:
sg1 = -1;
break;
case 3:
case 4:
sg1 = 1;
break;
default:
sg1 = -1;
break;
}
}
//=================================================================================================
void BRepBlend_SurfRstEvolRad::Set(const BlendFunc_SectionShape TypeSection)
{
mySShape = TypeSection;
}
//=================================================================================================
void BRepBlend_SurfRstEvolRad::Section(const Standard_Real Param,
const Standard_Real U,
const Standard_Real V,
const Standard_Real W,
Standard_Real& Pdeb,
Standard_Real& Pfin,
gp_Circ& C)
{
gp_Vec d1u1, d1v1;
gp_Vec ns, np;
Standard_Real norm;
gp_Pnt Center;
tguide->D1(Param, ptgui, d1gui);
np = d1gui.Normalized();
ray = sg1 * tevol->Value(Param);
surf->D1(U, V, pts, d1u1, d1v1);
ptrst = cons.Value(W);
ns = d1u1.Crossed(d1v1);
norm = nplan.Crossed(ns).Magnitude();
ns.SetLinearForm(nplan.Dot(ns) / norm, nplan, -1. / norm, ns);
Center.SetXYZ(pts.XYZ() + ray * ns.XYZ());
C.SetRadius(Abs(ray));
if (ray > 0)
{
ns.Reverse();
}
if (choix % 2 != 0)
{
np.Reverse();
}
C.SetPosition(gp_Ax2(Center, np, ns));
Pdeb = 0.; // ElCLib::Parameter(C,pts);
Pfin = ElCLib::Parameter(C, ptrst);
// Test negative and almost null angles : Single Case
if (Pfin > 1.5 * M_PI)
{
np.Reverse();
C.SetPosition(gp_Ax2(Center, np, ns));
Pfin = ElCLib::Parameter(C, ptrst);
}
if (Pfin < Precision::PConfusion())
Pfin += Precision::PConfusion();
}
//=================================================================================================
Standard_Boolean BRepBlend_SurfRstEvolRad::IsRational() const
{
return (mySShape == BlendFunc_Rational || mySShape == BlendFunc_QuasiAngular);
}
//=================================================================================================
Standard_Real BRepBlend_SurfRstEvolRad::GetSectionSize() const
{
return maxang * Abs(ray);
}
//=================================================================================================
void BRepBlend_SurfRstEvolRad::GetMinimalWeight(TColStd_Array1OfReal& Weigths) const
{
BlendFunc::GetMinimalWeights(mySShape, myTConv, minang, maxang, Weigths);
// It is supposed that it does not depend on the Radius!
}
//=================================================================================================
Standard_Integer BRepBlend_SurfRstEvolRad::NbIntervals(const GeomAbs_Shape S) const
{
Standard_Integer Nb_Int_Courbe, Nb_Int_Loi;
Nb_Int_Courbe = guide->NbIntervals(BlendFunc::NextShape(S));
Nb_Int_Loi = fevol->NbIntervals(S);
if (Nb_Int_Loi == 1)
{
return Nb_Int_Courbe;
}
TColStd_Array1OfReal IntC(1, Nb_Int_Courbe + 1);
TColStd_Array1OfReal IntL(1, Nb_Int_Loi + 1);
TColStd_SequenceOfReal Inter;
guide->Intervals(IntC, BlendFunc::NextShape(S));
fevol->Intervals(IntL, S);
FusionneIntervalles(IntC, IntL, Inter);
return Inter.Length() - 1;
}
//=================================================================================================
void BRepBlend_SurfRstEvolRad::Intervals(TColStd_Array1OfReal& T, const GeomAbs_Shape S) const
{
Standard_Integer Nb_Int_Courbe, Nb_Int_Loi;
Nb_Int_Courbe = guide->NbIntervals(BlendFunc::NextShape(S));
Nb_Int_Loi = fevol->NbIntervals(S);
if (Nb_Int_Loi == 1)
{
guide->Intervals(T, BlendFunc::NextShape(S));
}
else
{
TColStd_Array1OfReal IntC(1, Nb_Int_Courbe + 1);
TColStd_Array1OfReal IntL(1, Nb_Int_Loi + 1);
TColStd_SequenceOfReal Inter;
guide->Intervals(IntC, BlendFunc::NextShape(S));
fevol->Intervals(IntL, S);
FusionneIntervalles(IntC, IntL, Inter);
for (Standard_Integer ii = 1; ii <= Inter.Length(); ii++)
{
T(ii) = Inter(ii);
}
}
}
//=================================================================================================
void BRepBlend_SurfRstEvolRad::GetShape(Standard_Integer& NbPoles,
Standard_Integer& NbKnots,
Standard_Integer& Degree,
Standard_Integer& NbPoles2d)
{
NbPoles2d = 2;
BlendFunc::GetShape(mySShape, maxang, NbPoles, NbKnots, Degree, myTConv);
}
//=================================================================================================
void BRepBlend_SurfRstEvolRad::GetTolerance(const Standard_Real BoundTol,
const Standard_Real SurfTol,
const Standard_Real AngleTol,
math_Vector& Tol3d,
math_Vector& Tol1d) const
{
Standard_Integer low = Tol3d.Lower(), up = Tol3d.Upper();
Standard_Real Tol;
Tol = GeomFill::GetTolerance(myTConv, minang, Abs(ray), AngleTol, SurfTol);
Tol1d.Init(SurfTol);
Tol3d.Init(SurfTol);
Tol3d(low + 1) = Tol3d(up - 1) = Min(Tol, SurfTol);
Tol3d(low) = Tol3d(up) = Min(Tol, BoundTol);
}
//=================================================================================================
void BRepBlend_SurfRstEvolRad::Knots(TColStd_Array1OfReal& TKnots)
{
GeomFill::Knots(myTConv, TKnots);
}
//=================================================================================================
void BRepBlend_SurfRstEvolRad::Mults(TColStd_Array1OfInteger& TMults)
{
GeomFill::Mults(myTConv, TMults);
}
//=================================================================================================
Standard_Boolean BRepBlend_SurfRstEvolRad::Section(const Blend_Point& P,
TColgp_Array1OfPnt& Poles,
TColgp_Array1OfVec& DPoles,
TColgp_Array1OfPnt2d& Poles2d,
TColgp_Array1OfVec2d& DPoles2d,
TColStd_Array1OfReal& Weigths,
TColStd_Array1OfReal& DWeigths)
{
gp_Vec d1u1, d1v1, d2u1, d2v1, d2uv1, d1;
gp_Vec ns, ns2, dnplan, dnw, dn2w; //,np2,dnp2;
gp_Vec ncrossns;
gp_Vec resulu, resulv, temp, tgct, resul;
gp_Vec d1urst, d1vrst;
gp_Pnt Center, bid;
Standard_Real norm, ndotns, grosterme, aDray;
math_Vector sol(1, 3), valsol(1, 3), secmember(1, 3);
math_Matrix gradsol(1, 3, 1, 3);
Standard_Real prm = P.Parameter(), rayprim;
Standard_Integer low = Poles.Lower();
Standard_Integer upp = Poles.Upper();
Standard_Boolean istgt;
tguide->D2(prm, ptgui, d1gui, d2gui);
tevol->D1(prm, ray, aDray);
ray = sg1 * ray;
aDray = sg1 * aDray;
normtg = d1gui.Magnitude();
nplan = d1gui.Normalized();
dnplan.SetLinearForm(1. / normtg, d2gui, -1. / normtg * (nplan.Dot(d2gui)), nplan);
P.ParametersOnS(sol(1), sol(2));
sol(3) = prmrst = P.ParameterOnC();
pt2drst = rst->Value(prmrst);
Values(sol, valsol, gradsol);
surf->D2(sol(1), sol(2), pts, d1u1, d1v1, d2u1, d2v1, d2uv1);
cons.D1(sol(3), ptrst, d1);
temp.SetXYZ(pts.XYZ() - ptgui.XYZ());
secmember(1) = normtg - dnplan.Dot(temp);
temp.SetXYZ(ptrst.XYZ() - ptgui.XYZ());
secmember(2) = normtg - dnplan.Dot(temp);
ns = d1u1.Crossed(d1v1);
ncrossns = nplan.Crossed(ns);
ndotns = nplan.Dot(ns);
norm = ncrossns.Magnitude();
if (norm < Eps)
{
norm = 1; // Not enough, but it is not necessary to stop
#ifdef OCCT_DEBUG
std::cout << " SurfRstEvolRad : Surface single " << std::endl;
#endif
}
// Derivative of n1 corresponding to w
grosterme = ncrossns.Dot(dnplan.Crossed(ns)) / norm / norm;
dnw.SetLinearForm((dnplan.Dot(ns) - grosterme * ndotns) / norm,
nplan,
ndotns / norm,
dnplan,
grosterme / norm,
ns);
temp.SetLinearForm(ndotns / norm, nplan, -1. / norm, ns);
resul.SetLinearForm(ray, temp, gp_Vec(ptrst, pts));
// secmember(3) = -2.*ray*(dnw.Dot(resul)); // jag 950105 il manquait ray
secmember(3) = -2. * ray * (dnw.Dot(resul)) - 2. * aDray * (temp.Dot(resul)) + 2. * ray * aDray;
math_Gauss Resol(gradsol);
if (Resol.IsDone())
{
Resol.Solve(secmember);
istgt = Standard_False;
}
else
{
math_SVD SingRS(gradsol);
if (SingRS.IsDone())
{
math_Vector DEDT(1, 3);
DEDT = secmember;
SingRS.Solve(DEDT, secmember, 1.e-6);
istgt = Standard_False;
}
else
istgt = Standard_True;
}
if (!istgt)
{
tgs.SetLinearForm(secmember(1), d1u1, secmember(2), d1v1);
tgrst = secmember(3) * d1;
// Derivative of n1 corresponding to u1
temp = d2u1.Crossed(d1v1).Added(d1u1.Crossed(d2uv1));
grosterme = ncrossns.Dot(nplan.Crossed(temp)) / norm / norm;
resulu.SetLinearForm(-(grosterme * ndotns - nplan.Dot(temp)) / norm,
nplan,
grosterme / norm,
ns,
-1. / norm,
temp);
// Derivative of n1 corresponding to v1
temp = d2uv1.Crossed(d1v1).Added(d1u1.Crossed(d2v1));
grosterme = ncrossns.Dot(nplan.Crossed(temp)) / norm / norm;
resulv.SetLinearForm(-(grosterme * ndotns - nplan.Dot(temp)) / norm,
nplan,
grosterme / norm,
ns,
-1. / norm,
temp);
dnw.SetLinearForm(secmember(1), resulu, secmember(2), resulv, dnw);
ns.SetLinearForm(ndotns / norm, nplan, -1. / norm, ns);
dn2w.SetLinearForm(ray, dnw, -1., tgrst, tgs);
dn2w.SetLinearForm(aDray, ns, dn2w);
norm = resul.Magnitude();
dn2w.Divide(norm);
ns2 = -resul.Normalized();
dn2w.SetLinearForm(ns2.Dot(dn2w), ns2, -1., dn2w);
istgt = Standard_False;
}
else
{
ns.SetLinearForm(ndotns / norm, nplan, -1. / norm, ns);
ns2 = -resul.Normalized();
istgt = Standard_True;
}
// Tops 2D
Poles2d(Poles2d.Lower()).SetCoord(sol(1), sol(2));
Poles2d(Poles2d.Upper()).SetCoord(pt2drst.X(), pt2drst.Y());
if (!istgt)
{
DPoles2d(Poles2d.Lower()).SetCoord(secmember(1), secmember(2));
surfrst->D1(pt2drst.X(), pt2drst.Y(), bid, d1urst, d1vrst);
Standard_Real a, b;
t3dto2d(a, b, tgrst, d1urst, d1vrst);
DPoles2d(Poles2d.Upper()).SetCoord(a, b);
}
// Linear Case
if (mySShape == BlendFunc_Linear)
{
Poles(low) = pts;
Poles(upp) = ptrst;
Weigths(low) = 1.0;
Weigths(upp) = 1.0;
if (!istgt)
{
DPoles(low) = tgs;
DPoles(upp) = tgrst;
DWeigths(low) = 0.0;
DWeigths(upp) = 0.0;
}
return (!istgt);
}
// Case of the circle
Center.SetXYZ(pts.XYZ() + ray * ns.XYZ());
if (!istgt)
{
tgct.SetLinearForm(ray, dnw, aDray, ns, tgs);
}
if (ray > 0.)
{
ns.Reverse();
if (!istgt)
{
dnw.Reverse();
}
}
if (choix % 2 != 0)
{
nplan.Reverse();
dnplan.Reverse();
}
if (!istgt)
{
if (ray < 0.)
{ // to avoid Abs(dray) some lines below
rayprim = -aDray;
}
else
rayprim = aDray;
return GeomFill::GetCircle(myTConv,
ns,
ns2,
dnw,
dn2w,
nplan,
dnplan,
pts,
ptrst,
tgs,
tgrst,
Abs(ray),
rayprim,
Center,
tgct,
Poles,
DPoles,
Weigths,
DWeigths);
}
else
{
GeomFill::GetCircle(myTConv, ns, ns2, nplan, pts, ptrst, Abs(ray), Center, Poles, Weigths);
return Standard_False;
}
}
//=================================================================================================
Standard_Boolean BRepBlend_SurfRstEvolRad::Section(const Blend_Point& /*P*/,
TColgp_Array1OfPnt& /*Poles*/,
TColgp_Array1OfVec& /*DPoles*/,
TColgp_Array1OfVec& /*D2Poles*/,
TColgp_Array1OfPnt2d& /*Poles2d*/,
TColgp_Array1OfVec2d& /*DPoles2d*/,
TColgp_Array1OfVec2d& /*D2Poles2d*/,
TColStd_Array1OfReal& /*Weigths*/,
TColStd_Array1OfReal& /*DWeigths*/,
TColStd_Array1OfReal& /*D2Weigths*/)
{
return Standard_False;
}
//=================================================================================================
void BRepBlend_SurfRstEvolRad::Section(const Blend_Point& P,
TColgp_Array1OfPnt& Poles,
TColgp_Array1OfPnt2d& Poles2d,
TColStd_Array1OfReal& Weigths)
{
gp_Vec d1u1, d1v1; //,d1;
gp_Vec ns, ns2; //,temp,np2;
gp_Pnt Center;
Standard_Real norm, u1, v1, w;
Standard_Real prm = P.Parameter();
Standard_Integer low = Poles.Lower();
Standard_Integer upp = Poles.Upper();
tguide->D1(prm, ptgui, d1gui);
ray = tevol->Value(prm);
ray = sg1 * ray;
nplan = d1gui.Normalized();
P.ParametersOnS(u1, v1);
w = P.ParameterOnC(); // jlr : point on curve not on surface
gp_Pnt2d pt2d = rst->Value(w);
surf->D1(u1, v1, pts, d1u1, d1v1);
ptrst = cons.Value(w);
distmin = Min(distmin, pts.Distance(ptrst));
Poles2d(Poles2d.Lower()).SetCoord(u1, v1);
Poles2d(Poles2d.Upper()).SetCoord(pt2d.X(), pt2d.Y());
// Linear case
if (mySShape == BlendFunc_Linear)
{
Poles(low) = pts;
Poles(upp) = ptrst;
Weigths(low) = 1.0;
Weigths(upp) = 1.0;
return;
}
ns = d1u1.Crossed(d1v1);
norm = nplan.Crossed(ns).Magnitude();
ns.SetLinearForm(nplan.Dot(ns) / norm, nplan, -1. / norm, ns);
Center.SetXYZ(pts.XYZ() + ray * ns.XYZ());
ns2 = gp_Vec(Center, ptrst).Normalized();
if (ray > 0)
ns.Reverse();
if (choix % 2 != 0)
{
nplan.Reverse();
}
GeomFill::GetCircle(myTConv, ns, ns2, nplan, pts, ptrst, Abs(ray), Center, Poles, Weigths);
}
void BRepBlend_SurfRstEvolRad::Resolution(const Standard_Integer IC2d,
const Standard_Real Tol,
Standard_Real& TolU,
Standard_Real& TolV) const
{
if (IC2d == 1)
{
TolU = surf->UResolution(Tol);
TolV = surf->VResolution(Tol);
}
else
{
TolU = surfrst->UResolution(Tol);
TolV = surfrst->VResolution(Tol);
}
}