mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
Automatic upgrade of OCCT code by command "occt_upgrade . -nocdl": - WOK-generated header files from inc and sources from drv are moved to src - CDL files removed - All packages are converted to nocdlpack
323 lines
9.6 KiB
C++
323 lines
9.6 KiB
C++
// Created on: 1995-11-20
|
|
// Created by: Laurent BOURESCHE
|
|
// 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_Curve.hxx>
|
|
#include <BSplCLib.hxx>
|
|
#include <gp_Pnt.hxx>
|
|
#include <Law.hxx>
|
|
#include <Law_BSpFunc.hxx>
|
|
#include <Law_BSpline.hxx>
|
|
#include <Law_Interpolate.hxx>
|
|
#include <Law_Linear.hxx>
|
|
#include <TColStd_Array1OfBoolean.hxx>
|
|
#include <TColStd_Array1OfReal.hxx>
|
|
#include <TColStd_HArray1OfBoolean.hxx>
|
|
#include <TColStd_HArray1OfReal.hxx>
|
|
|
|
Handle(Law_BSpFunc) Law::MixBnd(const Handle(Law_Linear)& Lin)
|
|
{
|
|
Standard_Real f,l;
|
|
Lin->Bounds(f,l);
|
|
TColStd_Array1OfReal Knots(1,4);
|
|
TColStd_Array1OfInteger Mults(1,4);
|
|
Knots(1) = f; Knots(4) = l;
|
|
Knots(2) = 0.75*f + 0.25*l; Knots(3) = 0.25*f + 0.75*l;
|
|
Mults(1) = Mults(4) = 4;
|
|
Mults(2) = Mults(3) = 1;
|
|
Handle(TColStd_HArray1OfReal) pol = Law::MixBnd(3,Knots,Mults,Lin);
|
|
Handle(Law_BSpline) bs = new Law_BSpline(pol->Array1(),Knots,Mults,3);
|
|
Handle(Law_BSpFunc) bsf = new Law_BSpFunc();
|
|
bsf->SetCurve(bs);
|
|
return bsf;
|
|
}
|
|
|
|
Handle(TColStd_HArray1OfReal) Law::MixBnd
|
|
(const Standard_Integer Degree,
|
|
const TColStd_Array1OfReal& Knots,
|
|
const TColStd_Array1OfInteger& Mults,
|
|
const Handle(Law_Linear)& Lin)
|
|
{
|
|
Standard_Integer nbpol = 0, nbfk = 0, i, j, k = 0;
|
|
for(i = Mults.Lower(); i <= Mults.Upper(); i++){
|
|
nbfk += Mults(i);
|
|
}
|
|
TColStd_Array1OfReal fk(1,nbfk);
|
|
for(i = Mults.Lower(); i <= Mults.Upper(); i++){
|
|
for(j = 1; j <= Mults(i); j++){
|
|
fk(++k) = Knots(i);
|
|
}
|
|
}
|
|
nbpol = nbfk - Degree - 1;
|
|
TColStd_Array1OfReal par(1,nbpol);
|
|
BSplCLib::BuildSchoenbergPoints(Degree,fk,par);
|
|
Handle(TColStd_HArray1OfReal) res = new TColStd_HArray1OfReal(1,nbpol);
|
|
TColStd_Array1OfReal& pol = res->ChangeArray1();
|
|
for(i = 1; i <= nbpol; i++){
|
|
pol(i) = Lin->Value(par(i));
|
|
}
|
|
TColStd_Array1OfInteger ord(1,nbpol);
|
|
ord.Init(0);
|
|
BSplCLib::Interpolate(Degree,fk,par,ord,1,pol(1),i);
|
|
if(nbpol >= 4){
|
|
pol(2) = pol(1);
|
|
pol(nbpol - 1) = pol(nbpol);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
static Standard_Real eval1(const Standard_Real p,
|
|
const Standard_Real first,
|
|
const Standard_Real last,
|
|
const Standard_Real piv,
|
|
const Standard_Boolean nulr)
|
|
{
|
|
if((nulr && p >= piv) || (!nulr && p <= piv)) return 0.;
|
|
else if(nulr){
|
|
Standard_Real a = piv - first;
|
|
a *= a;
|
|
a = 1./a;
|
|
Standard_Real b = p - first;
|
|
a *= b;
|
|
b = piv - p;
|
|
a *= b;
|
|
a *= b;
|
|
return a;
|
|
}
|
|
else{
|
|
Standard_Real a = last - piv;
|
|
a *= a;
|
|
a = 1./a;
|
|
Standard_Real b = last - p;
|
|
a *= b;
|
|
b = p - piv;
|
|
a *= b;
|
|
a *= b;
|
|
return a;
|
|
}
|
|
}
|
|
|
|
Handle(TColStd_HArray1OfReal) Law::MixTgt
|
|
(const Standard_Integer Degree,
|
|
const TColStd_Array1OfReal& Knots,
|
|
const TColStd_Array1OfInteger& Mults,
|
|
const Standard_Boolean NulOnTheRight,
|
|
const Standard_Integer Index)
|
|
{
|
|
Standard_Real first = Knots(Knots.Lower());
|
|
Standard_Real last = Knots(Knots.Upper());
|
|
Standard_Real piv = Knots(Index);
|
|
Standard_Integer nbpol = 0, nbfk = 0, i, j, k = 0;
|
|
for(i = Mults.Lower(); i <= Mults.Upper(); i++){
|
|
nbfk += Mults(i);
|
|
}
|
|
TColStd_Array1OfReal fk(1,nbfk);
|
|
for(i = Mults.Lower(); i <= Mults.Upper(); i++){
|
|
for(j = 1; j <= Mults(i); j++){
|
|
fk(++k) = Knots(i);
|
|
}
|
|
}
|
|
nbpol = nbfk - Degree - 1;
|
|
TColStd_Array1OfReal par(1,nbpol);
|
|
BSplCLib::BuildSchoenbergPoints(Degree,fk,par);
|
|
Handle(TColStd_HArray1OfReal) res = new TColStd_HArray1OfReal(1,nbpol);
|
|
TColStd_Array1OfReal& pol = res->ChangeArray1();
|
|
for(i = 1; i <= nbpol; i++){
|
|
pol(i) = eval1(par(i),first,last,piv,NulOnTheRight);
|
|
}
|
|
TColStd_Array1OfInteger ord(1,nbpol);
|
|
ord.Init(0);
|
|
BSplCLib::Interpolate(Degree,fk,par,ord,1,pol(1),i);
|
|
return res;
|
|
}
|
|
|
|
Handle(Law_BSpline) Law::Reparametrize(const Adaptor3d_Curve& Curve,
|
|
const Standard_Real First,
|
|
const Standard_Real Last,
|
|
const Standard_Boolean HasDF,
|
|
const Standard_Boolean HasDL,
|
|
const Standard_Real DFirst,
|
|
const Standard_Real DLast,
|
|
const Standard_Boolean Rev,
|
|
const Standard_Integer NbPoints)
|
|
{
|
|
// On evalue la longeur approximative de la courbe.
|
|
|
|
Standard_Integer i;
|
|
Standard_Real DDFirst = DFirst, DDLast = DLast;
|
|
if(HasDF && Rev) DDFirst = -DFirst;
|
|
if(HasDL && Rev) DDLast = -DLast;
|
|
TColStd_Array1OfReal cumdist(1,2*NbPoints);
|
|
TColStd_Array1OfReal ucourbe(1,2*NbPoints);
|
|
gp_Pnt P1,P2;
|
|
Standard_Real U1 = Curve.FirstParameter();
|
|
Standard_Real U2 = Curve.LastParameter();
|
|
Standard_Real U, DU, Length = 0.;
|
|
if(!Rev){
|
|
P1 = Curve.Value(U1);
|
|
U = U1;
|
|
DU = (U2 - U1) / ( 2*NbPoints - 1);
|
|
}
|
|
else{
|
|
P1 = Curve.Value(U2);
|
|
U = U2;
|
|
DU = (U1 - U2) / ( 2*NbPoints - 1);
|
|
}
|
|
for ( i = 1; i <= 2*NbPoints ; i ++) {
|
|
P2 = Curve.Value(U);
|
|
Length += P2.Distance(P1);
|
|
cumdist(i) = Length;
|
|
ucourbe(i) = U;
|
|
U += DU;
|
|
P1 = P2;
|
|
}
|
|
if(Rev) ucourbe(2*NbPoints) = U1;
|
|
else ucourbe(2*NbPoints) = U2;
|
|
|
|
Handle(TColStd_HArray1OfReal) point = new TColStd_HArray1OfReal(1,NbPoints);
|
|
Handle(TColStd_HArray1OfReal) param = new TColStd_HArray1OfReal(1,NbPoints);
|
|
|
|
Standard_Real DCorde = Length / ( NbPoints - 1);
|
|
Standard_Real Corde = DCorde;
|
|
Standard_Integer Index = 1;
|
|
Standard_Real Alpha;
|
|
Standard_Real fac = 1./(NbPoints-1);
|
|
|
|
point->SetValue(1,ucourbe(1));
|
|
param->SetValue(1,First);
|
|
point->SetValue(NbPoints,ucourbe(2*NbPoints));
|
|
param->SetValue(NbPoints,Last);
|
|
|
|
for ( i = 2; i < NbPoints; i++) {
|
|
while (cumdist(Index) < Corde) Index ++;
|
|
|
|
Alpha = (Corde - cumdist(Index - 1)) / (cumdist(Index) -cumdist(Index - 1));
|
|
U = ucourbe(Index-1) + Alpha * (ucourbe(Index) - ucourbe(Index-1));
|
|
point->SetValue(i,U);
|
|
param->SetValue(i,((NbPoints-i)*First+(i-1)*Last)*fac);
|
|
Corde = i*DCorde;
|
|
}
|
|
Law_Interpolate inter(point,param,0,1.e-9);
|
|
if(HasDF || HasDL){
|
|
TColStd_Array1OfReal tgt(1,NbPoints);
|
|
Handle(TColStd_HArray1OfBoolean)
|
|
flag = new TColStd_HArray1OfBoolean(1,NbPoints);
|
|
flag->ChangeArray1().Init(0);
|
|
if(HasDF){ flag->SetValue(1,1); tgt.SetValue(1,DDFirst); }
|
|
if(HasDL){ flag->SetValue(NbPoints,1); tgt.SetValue(NbPoints,DDLast); }
|
|
inter.Load(tgt,flag);
|
|
}
|
|
inter.Perform();
|
|
if(!inter.IsDone())
|
|
Standard_Failure::Raise
|
|
("Law::Reparametrize echec interpolation");
|
|
Handle(Law_BSpline) bs = inter.Curve();
|
|
return bs;
|
|
}
|
|
|
|
static Standard_Real eval2(const Standard_Real p,
|
|
// const Standard_Real first,
|
|
const Standard_Real ,
|
|
// const Standard_Real last,
|
|
const Standard_Real ,
|
|
const Standard_Real mil,
|
|
const Standard_Boolean hasfirst,
|
|
const Standard_Boolean haslast,
|
|
const Handle(Law_BSpline)& bs1,
|
|
const Handle(Law_BSpline)& bs2)
|
|
{
|
|
if(hasfirst && p < mil) return bs1->Value(p);
|
|
else if(haslast && p > mil) return bs2->Value(p);
|
|
else return 1.;
|
|
}
|
|
|
|
Handle(Law_BSpline) Law::Scale(const Standard_Real First,
|
|
const Standard_Real Last,
|
|
const Standard_Boolean HasF,
|
|
const Standard_Boolean HasL,
|
|
const Standard_Real VFirst,
|
|
const Standard_Real VLast)
|
|
{
|
|
Standard_Integer i;
|
|
Standard_Real Milieu = 0.5*(First+Last);
|
|
TColStd_Array1OfReal knot(1,3);
|
|
TColStd_Array1OfReal fknot(1,10);
|
|
TColStd_Array1OfInteger mult(1,3);
|
|
knot(1) = First; knot(2) = Milieu; knot(3) = Last;
|
|
fknot(1) = fknot(2) = fknot(3) = fknot(4) = First;
|
|
fknot(10) = fknot(9) = fknot(8) = fknot(7) = Last;
|
|
fknot(5) = fknot(6) = Milieu;
|
|
mult(1) = 4; mult(3) = 4; mult(2) = 2;
|
|
|
|
TColStd_Array1OfReal pbs(1,4);
|
|
TColStd_Array1OfReal kbs(1,2);
|
|
TColStd_Array1OfInteger mbs(1,2);
|
|
mbs(1) = mbs(2) = 4;
|
|
Handle(Law_BSpline) bs1,bs2;
|
|
if(HasF){
|
|
pbs(1) = pbs(2) = VFirst;
|
|
pbs(3) = pbs(4) = 1.;
|
|
kbs(1) = First; kbs(2) = Milieu;
|
|
bs1 = new Law_BSpline(pbs,kbs,mbs,3);
|
|
}
|
|
if(HasL){
|
|
pbs(1) = pbs(2) = 1.;
|
|
pbs(3) = pbs(4) = VLast;
|
|
kbs(1) = Milieu; kbs(2) = Last;
|
|
bs2 = new Law_BSpline(pbs,kbs,mbs,3);
|
|
}
|
|
|
|
TColStd_Array1OfReal pol(1,6);
|
|
TColStd_Array1OfReal par(1,6);
|
|
BSplCLib::BuildSchoenbergPoints(3,fknot,par);
|
|
for(i = 1; i <= 6; i++){
|
|
pol(i) = eval2(par(i),First,Last,Milieu,HasF,HasL,bs1,bs2);
|
|
}
|
|
TColStd_Array1OfInteger ord(1,6);
|
|
ord.Init(0);
|
|
BSplCLib::Interpolate(3,fknot,par,ord,1,pol(1),i);
|
|
bs1 = new Law_BSpline(pol,knot,mult,3);
|
|
return bs1;
|
|
}
|
|
|
|
|
|
Handle(Law_BSpline) Law::ScaleCub(const Standard_Real First,
|
|
const Standard_Real Last,
|
|
const Standard_Boolean HasF,
|
|
const Standard_Boolean HasL,
|
|
const Standard_Real VFirst,
|
|
const Standard_Real VLast)
|
|
{
|
|
//Standard_Integer i;
|
|
Standard_Real Milieu = 0.5*(First+Last);
|
|
TColStd_Array1OfReal pol(1,5);
|
|
TColStd_Array1OfReal knot(1,3);
|
|
TColStd_Array1OfInteger mult(1,3);
|
|
knot(1) = First; knot(2) = Milieu; knot(3) = Last;
|
|
mult(1) = 4; mult(3) = 4; mult(2) = 1;
|
|
|
|
Handle(Law_BSpline) bs;
|
|
if(HasF){ pol(1) = pol(2) = VFirst;}
|
|
else { pol(1) = pol(2) = 1.; }
|
|
if(HasL){ pol(4) = pol(5) = VLast;}
|
|
else { pol(4) = pol(5) = 1.; }
|
|
|
|
pol(3) = 1.;
|
|
|
|
bs = new Law_BSpline(pol,knot,mult,3);
|
|
return bs;
|
|
}
|