mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-05-01 10:26:12 +03:00
1737 lines
47 KiB
C++
Executable File
1737 lines
47 KiB
C++
Executable File
// File: BRepBlend_RstRstLineBuilder.cxx
|
|
// Created: Fri Jan 24 10:39:44 1997
|
|
// Author: Jacques GOUSSARD
|
|
// Author: Laurent BOURESCHE
|
|
// <lbo@pomalox.paris1.matra-dtv.fr>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <BRepBlend_RstRstLineBuilder.ixx>
|
|
#include <BRepBlend_BlendTool.hxx>
|
|
#include <TopAbs.hxx>
|
|
#include <IntSurf.hxx>
|
|
#include <math_FunctionSetRoot.hxx>
|
|
#include <gp_Pnt2d.hxx>
|
|
#include <gp_Pnt.hxx>
|
|
#include <gp_Vec2d.hxx>
|
|
#include <gp_Vec.hxx>
|
|
|
|
#ifdef DEB
|
|
#include <TColStd_Array1OfInteger.hxx>
|
|
#include <TColStd_Array1OfReal.hxx>
|
|
#include <TColgp_Array1OfPnt2d.hxx>
|
|
#include <TColgp_Array1OfVec.hxx>
|
|
#include <TColgp_Array1OfVec2d.hxx>
|
|
#include <TColgp_Array1OfPnt.hxx>
|
|
#include <Geom_BSplineCurve.hxx>
|
|
#ifdef DRAW
|
|
#include <DrawTrSurf.hxx>
|
|
#endif
|
|
static Standard_Integer IndexOfSection = 0;
|
|
extern Standard_Boolean Blend_GettraceDRAWSECT();
|
|
|
|
//-----------------------------------------------------
|
|
// Pour debug : visualisation de la section
|
|
static Standard_Boolean BBPP(const Standard_Real param,
|
|
Blend_RstRstFunction& Func,
|
|
const math_Vector& sol,
|
|
const Standard_Real tol,
|
|
Blend_Point& BP)
|
|
{
|
|
if(!Func.IsSolution(sol,tol)) return 0;
|
|
gp_Pnt pntrst1 = Func.PointOnRst1();
|
|
gp_Pnt pntrst2 = Func.PointOnRst2();
|
|
gp_Pnt2d p2drst1 = Func.Pnt2dOnRst1();
|
|
gp_Pnt2d p2drst2 = Func.Pnt2dOnRst2();
|
|
Standard_Real w1 = Func.ParameterOnRst1();
|
|
Standard_Real w2 = Func.ParameterOnRst2();
|
|
BP = Blend_Point(pntrst1, pntrst2, param,
|
|
p2drst1.X(), p2drst1.Y(),
|
|
p2drst2.X(), p2drst2.Y(), w1, w2);
|
|
return 1;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------
|
|
static void tracederiv(Blend_RstRstFunction& Func,
|
|
const Blend_Point& BP1,
|
|
const Blend_Point& BP2)
|
|
{
|
|
Standard_Integer hp,hk,hd,hp2d,i;
|
|
Func.GetShape(hp,hk,hd,hp2d);
|
|
TColgp_Array1OfPnt TP1(1,hp);
|
|
TColgp_Array1OfVec TDP1(1,hp);
|
|
TColgp_Array1OfPnt2d TP2d1(1,hp2d);
|
|
TColgp_Array1OfVec2d TDP2d1(1,hp2d);
|
|
TColStd_Array1OfReal TW1(1,hp);
|
|
TColStd_Array1OfReal TDW1(1,hp);
|
|
Func.Section(BP1, TP1,TDP1,TP2d1,TDP2d1,TW1,TDW1);
|
|
|
|
TColgp_Array1OfPnt TP2(1,hp);
|
|
TColgp_Array1OfVec TDP2(1,hp);
|
|
TColgp_Array1OfPnt2d TP2d2(1,hp2d);
|
|
TColgp_Array1OfVec2d TDP2d2(1,hp2d);
|
|
TColStd_Array1OfReal TW2(1,hp);
|
|
TColStd_Array1OfReal TDW2(1,hp);
|
|
Func.Section(BP2,TP2,TDP2,TP2d2,TDP2d2,TW2,TDW2);
|
|
|
|
Standard_Real param1 = BP1.Parameter();
|
|
Standard_Real param2 = BP2.Parameter();
|
|
Standard_Real scal = 1./ (param1 - param2);
|
|
|
|
cout<<endl;
|
|
cout<<"controle des derivees au point : "<<param1<<endl;
|
|
|
|
for(i = 1; i <= hp; i++){
|
|
cout<<endl;
|
|
cout<<"point : "<<i<<endl;
|
|
cout<<"dx calcule : "<<TDP1(i).X()<<endl;
|
|
cout<<"dx estime : "<<scal*(TP1(i).X()-TP2(i).X())<<endl;
|
|
cout<<"dy calcule : "<<TDP1(i).Y()<<endl;
|
|
cout<<"dy estime : "<<scal*(TP1(i).Y()-TP2(i).Y())<<endl;
|
|
cout<<"dz calcule : "<<TDP1(i).Z()<<endl;
|
|
cout<<"dz estime : "<<scal*(TP1(i).Z()-TP2(i).Z())<<endl;
|
|
cout<<"dw calcule : "<<TDW1(i)<<endl;
|
|
cout<<"dw estime : "<<scal*(TW1(i)-TW2(i))<<endl;
|
|
}
|
|
for(i = 1; i <= hp2d; i++){
|
|
cout<<endl;
|
|
cout<<"point 2d : "<<i<<endl;
|
|
cout<<"dx calcule : "<<TDP2d1(i).X()<<endl;
|
|
cout<<"dx estime : "<<scal*(TP2d1(i).X()-TP2d2(i).X())<<endl;
|
|
cout<<"dy calcule : "<<TDP2d1(i).Y()<<endl;
|
|
cout<<"dy estime : "<<scal*(TP2d1(i).Y()-TP2d2(i).Y())<<endl;
|
|
}
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------
|
|
static void Drawsect(const Standard_Real param,
|
|
Blend_RstRstFunction& Func)
|
|
{
|
|
gp_Pnt pntrst1 = Func.PointOnRst1();
|
|
gp_Pnt pntrst2 = Func.PointOnRst2();
|
|
gp_Pnt2d p2drst1 = Func.Pnt2dOnRst1();
|
|
gp_Pnt2d p2drst2 = Func.Pnt2dOnRst2();
|
|
Standard_Real u = Func.ParameterOnRst1();
|
|
Standard_Real v = Func.ParameterOnRst2();
|
|
Blend_Point BP(pntrst1, pntrst2, param,
|
|
p2drst1.X(), p2drst1.Y(),
|
|
p2drst2.X(), p2drst2.Y(), u, v);
|
|
Standard_Integer hp,hk,hd,hp2d;
|
|
Func.GetShape(hp,hk,hd,hp2d);
|
|
TColStd_Array1OfReal TK(1,hk);
|
|
Func.Knots(TK);
|
|
TColStd_Array1OfInteger TMul(1,hk);
|
|
Func.Mults(TMul);
|
|
TColgp_Array1OfPnt TP(1,hp);
|
|
TColgp_Array1OfPnt2d TP2d(1,hp2d);
|
|
TColStd_Array1OfReal TW(1,hp);
|
|
Func.Section(BP,TP,TP2d,TW);
|
|
Handle(Geom_BSplineCurve) sect = new Geom_BSplineCurve
|
|
(TP,TW,TK,TMul,hd);
|
|
IndexOfSection++;
|
|
#ifdef DRAW
|
|
char tname[100];
|
|
Standard_CString name = tname ;
|
|
sprintf(name,"%s_%d","Section",IndexOfSection);
|
|
DrawTrSurf::Set(name,sect);
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
//=======================================================================
|
|
//function : BRepBlend_RstRstLineBuilder
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
BRepBlend_RstRstLineBuilder::BRepBlend_RstRstLineBuilder
|
|
(const Handle(Adaptor3d_HSurface)& Surf1,
|
|
const Handle(Adaptor2d_HCurve2d)& Rst1,
|
|
const Handle(Adaptor3d_TopolTool)& Domain1,
|
|
const Handle(Adaptor3d_HSurface)& Surf2,
|
|
const Handle(Adaptor2d_HCurve2d)& Rst2,
|
|
const Handle(Adaptor3d_TopolTool)& Domain2):
|
|
sol(1,2), surf1(Surf1), domain1(Domain1),
|
|
surf2(Surf2), domain2(Domain2), rst1(Rst1), rst2(Rst2)
|
|
{
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Perform
|
|
//purpose : lance le processus de cheminement
|
|
//=======================================================================
|
|
|
|
void BRepBlend_RstRstLineBuilder::Perform(Blend_RstRstFunction& Func,
|
|
Blend_SurfCurvFuncInv& Finv1,
|
|
Blend_CurvPointFuncInv& FinvP1,
|
|
Blend_SurfCurvFuncInv& Finv2,
|
|
Blend_CurvPointFuncInv& FinvP2,
|
|
const Standard_Real Pdep,
|
|
const Standard_Real Pmax,
|
|
const Standard_Real MaxStep,
|
|
const Standard_Real TolGuide,
|
|
const math_Vector& ParDep,
|
|
const Standard_Real Tolesp,
|
|
const Standard_Real Fleche,
|
|
const Standard_Boolean Appro)
|
|
{
|
|
done = Standard_False;
|
|
iscomplete = Standard_False;
|
|
comptra = Standard_False;
|
|
line = new BRepBlend_Line();
|
|
tolesp = Abs(Tolesp);
|
|
tolgui = Abs(TolGuide);
|
|
fleche = Abs(Fleche);
|
|
rebrou = Standard_False;
|
|
pasmax = Abs(MaxStep);
|
|
|
|
if (Pmax - Pdep >= 0.) {
|
|
sens = 1.;
|
|
}
|
|
else {
|
|
sens = -1.;
|
|
}
|
|
|
|
Blend_Status State;
|
|
|
|
param = Pdep;
|
|
Func.Set(param);
|
|
|
|
if (Appro) {
|
|
TopAbs_State siturst1, siturst2;
|
|
Blend_DecrochStatus decroch;
|
|
math_Vector tolerance(1, 2), infbound(1, 2), supbound(1, 2);
|
|
Func.GetTolerance(tolerance, tolesp);
|
|
Func.GetBounds(infbound, supbound);
|
|
math_FunctionSetRoot rsnld(Func, tolerance, 30);
|
|
|
|
rsnld.Perform(Func, ParDep, infbound, supbound);
|
|
|
|
if (!rsnld.IsDone()) {
|
|
return;
|
|
}
|
|
rsnld.Root(sol);
|
|
if (!CheckInside(Func, siturst1, siturst2, decroch)) {
|
|
return;
|
|
}
|
|
}
|
|
else {
|
|
sol = ParDep;
|
|
}
|
|
|
|
State = TestArret(Func, Standard_False, Blend_OK);
|
|
if (State != Blend_OK) {
|
|
return;
|
|
}
|
|
#ifdef DEB
|
|
if (Blend_GettraceDRAWSECT()){
|
|
Drawsect(param, Func);
|
|
}
|
|
#endif
|
|
// Mettre a jour la ligne.
|
|
line->Append(previousP);
|
|
Standard_Real U, V;
|
|
U = previousP.ParameterOnC1();
|
|
V = previousP.ParameterOnC2();
|
|
BRepBlend_Extremity ptf1 (previousP.PointOnC1(),
|
|
U, previousP.Parameter(),tolesp);
|
|
BRepBlend_Extremity ptf2 (previousP.PointOnC2(),
|
|
V, previousP.Parameter(),tolesp);
|
|
if (!previousP.IsTangencyPoint()) {
|
|
ptf1.SetTangent(previousP.TangentOnC1());
|
|
ptf2.SetTangent(previousP.TangentOnC2());
|
|
}
|
|
|
|
if (sens > 0.) {
|
|
line->SetStartPoints(ptf1, ptf2);
|
|
}
|
|
else {
|
|
line->SetEndPoints(ptf1, ptf2);
|
|
}
|
|
|
|
InternalPerform(Func, Finv1, FinvP1, Finv2, FinvP2, Pmax);
|
|
done = Standard_True;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : PerformFirstSection
|
|
//purpose : Creation de la premiere section
|
|
//=======================================================================
|
|
|
|
Standard_Boolean BRepBlend_RstRstLineBuilder::PerformFirstSection
|
|
(Blend_RstRstFunction& Func,
|
|
Blend_SurfCurvFuncInv& Finv1,
|
|
Blend_CurvPointFuncInv& FinvP1,
|
|
Blend_SurfCurvFuncInv& Finv2,
|
|
Blend_CurvPointFuncInv& FinvP2,
|
|
const Standard_Real Pdep,
|
|
const Standard_Real Pmax,
|
|
const math_Vector& ParDep,
|
|
const Standard_Real Tolesp,
|
|
const Standard_Real TolGuide,
|
|
const Standard_Boolean RecRst1,
|
|
const Standard_Boolean RecP1,
|
|
const Standard_Boolean RecRst2,
|
|
const Standard_Boolean RecP2,
|
|
Standard_Real& Psol,
|
|
math_Vector& ParSol)
|
|
{
|
|
done = Standard_False;
|
|
iscomplete = Standard_False;
|
|
comptra = Standard_False;
|
|
line = new BRepBlend_Line();
|
|
tolesp = Abs(Tolesp);
|
|
tolgui = Abs(TolGuide);
|
|
rebrou = Standard_False;
|
|
|
|
if (Pmax - Pdep >= 0.) {
|
|
sens = 1.;
|
|
}
|
|
else {
|
|
sens = -1.;
|
|
}
|
|
|
|
Standard_Boolean recadp1, recadp2, recadrst1, recadrst2;
|
|
Standard_Real wp1, wp2, wrst1, wrst2;
|
|
#ifndef DEB
|
|
Blend_Status State = Blend_OnRst12;
|
|
Standard_Real trst11 = 0., trst12 = 0., trst21 = 0., trst22 = 0.;
|
|
#else
|
|
Blend_Status State;
|
|
Standard_Real trst11, trst12, trst21, trst22;
|
|
#endif
|
|
math_Vector infbound(1, 2), supbound(1, 2), tolerance(1, 2);
|
|
math_Vector solinvp1(1, 2), solinvp2(1, 2), solinvrst1(1, 3), solinvrst2(1, 3);
|
|
Handle(Adaptor3d_HVertex) Vtxp1, Vtxp2, Vtxrst1, Vtxrst2, Vtxc;
|
|
Standard_Boolean IsVtxp1 = 0, IsVtxp2 = 0, IsVtxrst1 = 0, IsVtxrst2 = 0;
|
|
Handle(Adaptor2d_HCurve2d) Arc;
|
|
wp1 = wp2 = wrst1 = wrst2 = Pmax;
|
|
param = Pdep;
|
|
Func.Set(param);
|
|
Func.GetTolerance(tolerance, tolesp);
|
|
Func.GetBounds(infbound, supbound);
|
|
|
|
math_FunctionSetRoot rsnld(Func, tolerance, 30);
|
|
rsnld.Perform(Func, ParDep, infbound, supbound);
|
|
if (!rsnld.IsDone()) return Standard_False;
|
|
rsnld.Root(sol);
|
|
|
|
recadrst1 = RecRst1 && Recadre1(Func, Finv1, solinvrst1, IsVtxrst1, Vtxrst1);
|
|
if (recadrst1) {
|
|
wrst1 = solinvrst1(1);
|
|
}
|
|
|
|
recadp1 = RecP1 && Recadre1(FinvP1, solinvp1, IsVtxp1, Vtxp1);
|
|
if (recadp1) {
|
|
wp1 = solinvp1(1);
|
|
}
|
|
|
|
recadrst2 = RecRst2 && Recadre2(Func, Finv2, solinvrst2, IsVtxrst2, Vtxrst2);
|
|
if (recadrst2) {
|
|
wrst2 = solinvrst2(1);
|
|
}
|
|
|
|
recadp2 = RecP2 && Recadre2(FinvP2, solinvp2, IsVtxp2, Vtxp2);
|
|
if (recadp2) {
|
|
wp2 = solinvp2(1);
|
|
}
|
|
|
|
if (!recadrst1 && !recadp1 && !recadrst2 && !recadp2) return Standard_False;
|
|
|
|
|
|
// on regarde si on a decroche ou sorti du domaine 1
|
|
if (recadp1 && recadrst1) {
|
|
if (sens * (wrst1 - wp1) > tolgui){ //on sort du domaine d abord
|
|
wrst1 = wp1;
|
|
trst12 = solinvp1(2);
|
|
trst11 = BRepBlend_BlendTool::Parameter(Vtxp1, rst1);
|
|
IsVtxrst2 = IsVtxp1;
|
|
Vtxrst2 = Vtxp1;
|
|
recadrst1 = Standard_False;
|
|
}
|
|
else { // on a decroche
|
|
trst11 = solinvrst1(3);
|
|
trst12 = solinvrst1(2);
|
|
recadp1 = Standard_False;
|
|
}
|
|
}
|
|
else if (recadp1) {
|
|
wrst1 = wp1;
|
|
trst12 = solinvp1(2);
|
|
trst11 = BRepBlend_BlendTool::Parameter(Vtxp1, rst1);
|
|
IsVtxrst1 = IsVtxp1;
|
|
Vtxrst1 = Vtxp1;
|
|
}
|
|
else if (recadrst1) {
|
|
trst11 = solinvrst1(3);
|
|
trst12 = solinvrst1(2);
|
|
}
|
|
|
|
// on regarde si on a decrocher ou sortie du domaine 2
|
|
if (recadp2 && recadrst2) {
|
|
if (sens * (wrst2 - wp2) > tolgui) { //on sort du domaine d abord
|
|
wrst2 = wp2;
|
|
trst21 = solinvp2(2);
|
|
trst22 = BRepBlend_BlendTool::Parameter(Vtxp2, rst2);
|
|
IsVtxrst2 = IsVtxp2;
|
|
Vtxrst2 = Vtxp2;
|
|
recadrst2 = Standard_False;
|
|
}
|
|
else {
|
|
trst22 = solinvrst2(3);
|
|
trst21 = solinvrst2(2);
|
|
recadp2 = Standard_False;
|
|
}
|
|
}
|
|
else if (recadp2) {
|
|
wrst2 = wp2;
|
|
trst21 = solinvp2(2);
|
|
trst22 = BRepBlend_BlendTool::Parameter(Vtxp2, rst2);
|
|
IsVtxrst2 = IsVtxp2;
|
|
Vtxrst2 = Vtxp2;
|
|
}
|
|
else if (recadrst2) {
|
|
trst22 = solinvrst2(3);
|
|
trst21 = solinvrst2(2);
|
|
}
|
|
|
|
// on regarde sur laquelle des courbes on decroche en premier
|
|
if (recadrst1 && recadrst2) {
|
|
if (Abs(wrst1 - wrst2) < tolgui) {
|
|
State = Blend_OnRst12;
|
|
param = 0.5 * (wrst1 + wrst2);
|
|
sol(1) = trst11;
|
|
sol(2) = trst22;
|
|
}
|
|
else if (sens * (wrst1 - wrst2) < 0) {
|
|
// on decroche sur Rst1
|
|
State = Blend_OnRst1;
|
|
param = wrst1;
|
|
sol(1) = trst11;
|
|
sol(2) = trst12;
|
|
}
|
|
else {
|
|
// on decroche sur rst2
|
|
State = Blend_OnRst2;
|
|
param = wrst2;
|
|
sol(1) = trst21;
|
|
sol(2) = trst22;
|
|
}
|
|
Func.Set(param);
|
|
}
|
|
else if (recadrst1) {
|
|
// sol sur rst1
|
|
State = Blend_OnRst1;
|
|
param = wrst1;
|
|
sol(1) = trst11;
|
|
sol(2) = trst12;
|
|
Func.Set(param);
|
|
}
|
|
else if (recadrst2) {
|
|
// sol sur rst2
|
|
State = Blend_OnRst2;
|
|
param = wrst2;
|
|
sol(1) = trst21;
|
|
sol(2) = trst22;
|
|
Func.Set(param);
|
|
}
|
|
// on regarde sur laquelle des courbes on sort en premier
|
|
else if (recadp1 && recadp2) {
|
|
if (Abs(wrst1 - wrst2) < tolgui) {
|
|
State = Blend_OnRst12;
|
|
param = 0.5 * (wrst1 + wrst2);
|
|
sol(1) = trst11;
|
|
sol(2) = trst22;
|
|
}
|
|
else if (sens * (wrst1 - wrst2) < 0) {
|
|
// sol sur Rst1
|
|
State = Blend_OnRst1;
|
|
param = wrst1;
|
|
sol(1) = trst11;
|
|
sol(2) = trst12;
|
|
}
|
|
else {
|
|
// sol sur rst2
|
|
State = Blend_OnRst2;
|
|
param = wrst2;
|
|
sol(1) = trst21;
|
|
sol(2) = trst22;
|
|
}
|
|
Func.Set(param);
|
|
}
|
|
else if (recadp1) {
|
|
// sol sur rst1
|
|
State = Blend_OnRst1;
|
|
param = wrst1;
|
|
sol(1) = trst11;
|
|
sol(2) = trst12;
|
|
Func.Set(param);
|
|
}
|
|
else if (recadp2) {
|
|
// sol sur rst2
|
|
State = Blend_OnRst2;
|
|
param = wrst2;
|
|
sol(1) = trst21;
|
|
sol(2) = trst22;
|
|
Func.Set(param);
|
|
}
|
|
|
|
State = TestArret(Func, Standard_False, State);
|
|
Psol = param;
|
|
ParSol = sol;
|
|
return Standard_True;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Complete
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean BRepBlend_RstRstLineBuilder::Complete(Blend_RstRstFunction& Func,
|
|
Blend_SurfCurvFuncInv& Finv1,
|
|
Blend_CurvPointFuncInv& FinvP1,
|
|
Blend_SurfCurvFuncInv& Finv2,
|
|
Blend_CurvPointFuncInv& FinvP2,
|
|
const Standard_Real Pmin)
|
|
{
|
|
if (!done) {StdFail_NotDone::Raise();}
|
|
if (iscomplete) {return Standard_True;}
|
|
if (sens >0.) {
|
|
previousP = line->Point(1);
|
|
}
|
|
else {
|
|
previousP = line->Point(line->NbPoints());
|
|
}
|
|
sens = -sens;
|
|
param = previousP.Parameter();
|
|
sol(1) = previousP.ParameterOnC1();
|
|
sol(2) = previousP.ParameterOnC2();
|
|
|
|
InternalPerform(Func, Finv1, FinvP1, Finv2, FinvP2, Pmin);
|
|
iscomplete = Standard_True;
|
|
return Standard_True;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : InternalPerform
|
|
//purpose : algorithme de cheminement sauf aux extremites
|
|
//=======================================================================
|
|
|
|
void BRepBlend_RstRstLineBuilder::InternalPerform(Blend_RstRstFunction& Func,
|
|
Blend_SurfCurvFuncInv& Finv1,
|
|
Blend_CurvPointFuncInv& FinvP1,
|
|
Blend_SurfCurvFuncInv& Finv2,
|
|
Blend_CurvPointFuncInv& FinvP2,
|
|
const Standard_Real Bound)
|
|
{
|
|
Standard_Real stepw = pasmax;
|
|
Standard_Integer nbp = line->NbPoints();
|
|
if(nbp >= 2){ //On reprend le dernier step s il n est pas trop petit.
|
|
if(sens < 0.){
|
|
stepw = (line->Point(2).Parameter() - line->Point(1).Parameter());
|
|
}
|
|
else{
|
|
stepw = (line->Point(nbp).Parameter() - line->Point(nbp - 1).Parameter());
|
|
}
|
|
stepw = Max(stepw, 100. * tolgui);
|
|
}
|
|
Standard_Real parprec = param;
|
|
if (sens* (parprec - Bound) >= -tolgui) {
|
|
return;
|
|
}
|
|
#ifndef DEB
|
|
Blend_Status State = Blend_OnRst12;
|
|
Standard_Real trst11 = 0., trst12 = 0., trst21 = 0., trst22 = 0.;
|
|
#else
|
|
Blend_Status State;
|
|
Standard_Real trst11, trst12, trst21, trst22;
|
|
#endif
|
|
TopAbs_State situonc1, situonc2;
|
|
Blend_DecrochStatus decroch;
|
|
Standard_Boolean Arrive, recadp1, recadp2, recadrst1, recadrst2, echecrecad;
|
|
Standard_Real wp1, wp2, wrst1, wrst2;
|
|
math_Vector infbound(1, 2), supbound(1, 2);
|
|
math_Vector parinit(1, 2), tolerance(1, 2);
|
|
math_Vector solinvp1(1, 2), solinvp2(1, 2), solinvrst1(1, 3), solinvrst2(1, 3);
|
|
Handle(Adaptor3d_HVertex) Vtxp1, Vtxp2, Vtxrst1, Vtxrst2;
|
|
Standard_Boolean IsVtxp1 = 0, IsVtxp2 = 0, IsVtxrst1 = 0, IsVtxrst2 = 0;
|
|
BRepBlend_Extremity Extrst1, Extrst2;
|
|
|
|
//IntSurf_Transition Tline, Tarc;
|
|
|
|
Func.GetTolerance(tolerance, tolesp);
|
|
Func.GetBounds(infbound, supbound);
|
|
|
|
math_FunctionSetRoot rsnld(Func, tolerance, 30);
|
|
parinit = sol;
|
|
|
|
Arrive = Standard_False;
|
|
param = parprec + sens * stepw;
|
|
if (sens * (param - Bound) > 0.) {
|
|
stepw = sens * (Bound - parprec) * 0.5;
|
|
param = parprec + sens * stepw;
|
|
}
|
|
|
|
while (!Arrive) {
|
|
Standard_Boolean bonpoint = 1;
|
|
#if 0
|
|
//debdebdebdebdebdeb
|
|
Func.Set(param);
|
|
rsnld.Perform(Func, parinit, infbound, supbound);
|
|
if (rsnld.IsDone()) {
|
|
rsnld.Root(sol);
|
|
Blend_Point bp1;
|
|
if(BBPP(param, Func, sol, tolesp, bp1)){
|
|
Standard_Real dw = 1.e-10;
|
|
Func.Set(param + dw);
|
|
rsnld.Perform(Func, parinit, infbound, supbound);
|
|
if (rsnld.IsDone()) {
|
|
rsnld.Root(sol);
|
|
Blend_Point bp2;
|
|
if(BBPP(param + dw, Func, sol, tolesp, bp2)){
|
|
tracederiv(Func, bp1, bp2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//debdebdebdebdebdeb
|
|
#endif
|
|
Func.Set(param);
|
|
rsnld.Perform(Func, parinit, infbound, supbound);
|
|
|
|
if (rsnld.IsDone()) {
|
|
rsnld.Root(sol);
|
|
if(!CheckInside(Func, situonc1, situonc2, decroch) && line->NbPoints() == 1){
|
|
State = Blend_StepTooLarge;
|
|
bonpoint = 0;
|
|
}
|
|
}
|
|
else {
|
|
State = Blend_StepTooLarge;
|
|
bonpoint = 0;
|
|
}
|
|
if(bonpoint){
|
|
wp1 = wp2 = wrst1 = wrst2 = Bound;
|
|
recadp1 = recadp2 = recadrst1 = recadrst2 = Standard_False;
|
|
echecrecad = Standard_False;
|
|
if (situonc1 != TopAbs_IN) {
|
|
// pb inverse rst/rst
|
|
recadp1 = Recadre1(FinvP1, solinvp1, IsVtxp1, Vtxp1);
|
|
if (recadp1) {
|
|
wp1 = solinvp1(1);
|
|
}
|
|
else {
|
|
echecrecad = Standard_True;
|
|
}
|
|
}
|
|
|
|
if (situonc2 != TopAbs_IN) {
|
|
// pb inverse point/surf
|
|
recadp2 = Recadre2(FinvP2, solinvp2, IsVtxp2, Vtxp2);
|
|
if (recadp2) {
|
|
wp2 = solinvp2(1);
|
|
}
|
|
else {
|
|
echecrecad = Standard_True;
|
|
}
|
|
}
|
|
|
|
if (decroch == Blend_DecrochRst1 || decroch == Blend_DecrochBoth) {
|
|
// pb inverse rst1/surf1
|
|
recadrst1 = Recadre1(Func, Finv1, solinvrst1, IsVtxrst1, Vtxrst1);
|
|
if (recadrst1) {
|
|
wrst1 = solinvrst1(1);
|
|
}
|
|
else {
|
|
echecrecad = Standard_True;
|
|
}
|
|
}
|
|
|
|
if (decroch == Blend_DecrochRst2 || decroch == Blend_DecrochBoth) {
|
|
// pb inverse rst2/surf2
|
|
recadrst2 = Recadre2(Func, Finv2, solinvrst2, IsVtxrst2, Vtxrst2);
|
|
if (recadrst2) {
|
|
wrst2 = solinvrst2(1);
|
|
}
|
|
else {
|
|
echecrecad = Standard_True;
|
|
}
|
|
}
|
|
|
|
decroch = Blend_NoDecroch;
|
|
if (recadp1 || recadp2 || recadrst1 || recadrst2) echecrecad = Standard_False;
|
|
|
|
if (!echecrecad) {
|
|
// on regarde si on a decroche ou sorti du domaine 1
|
|
if (recadp1 && recadrst1) {
|
|
if (sens * (wrst1 - wp1) > tolgui){ //on sort du domaine d abord
|
|
wrst1 = wp1;
|
|
trst12 = solinvp1(2);
|
|
trst11 = BRepBlend_BlendTool::Parameter(Vtxp1, rst1);
|
|
IsVtxrst2 = IsVtxp1;
|
|
Vtxrst2 = Vtxp1;
|
|
recadrst1 = Standard_False;
|
|
}
|
|
else { // on a decroche
|
|
trst11 = solinvrst1(3);
|
|
trst12 = solinvrst1(2);
|
|
recadp1 = Standard_False;
|
|
}
|
|
}
|
|
else if (recadp1) {
|
|
wrst1 = wp1;
|
|
trst12 = solinvp1(2);
|
|
trst11 = BRepBlend_BlendTool::Parameter(Vtxp1, rst1);
|
|
IsVtxrst1 = IsVtxp1;
|
|
Vtxrst1 = Vtxp1;
|
|
}
|
|
else if (recadrst1) {
|
|
trst11 = solinvrst1(3);
|
|
trst12 = solinvrst1(2);
|
|
}
|
|
|
|
// on regarde si on a decrocher ou sortie du domaine 2
|
|
if (recadp2 && recadrst2) {
|
|
if (sens * (wrst2 - wp2) > tolgui) { //on sort du domaine d abord
|
|
wrst2 = wp2;
|
|
trst21 = solinvp2(2);
|
|
trst22 = BRepBlend_BlendTool::Parameter(Vtxp2, rst2);
|
|
IsVtxrst2 = IsVtxp2;
|
|
Vtxrst2 = Vtxp2;
|
|
recadrst2 = Standard_False;
|
|
}
|
|
else {
|
|
trst22 = solinvrst2(3);
|
|
trst21 = solinvrst2(2);
|
|
recadp2 = Standard_False;
|
|
}
|
|
}
|
|
else if (recadp2) {
|
|
wrst2 = wp2;
|
|
trst21 = solinvp2(2);
|
|
trst22 = BRepBlend_BlendTool::Parameter(Vtxp2, rst2);
|
|
IsVtxrst2 = IsVtxp2;
|
|
Vtxrst2 = Vtxp2;
|
|
}
|
|
else if (recadrst2) {
|
|
trst22 = solinvrst2(3);
|
|
trst21 = solinvrst2(2);
|
|
}
|
|
|
|
// on regarde sur laquelle des courbes on decroche en premier
|
|
if (recadrst1 && recadrst2) {
|
|
if (Abs(wrst1 - wrst2) < tolgui) {
|
|
State = Blend_OnRst12;
|
|
decroch = Blend_DecrochBoth;
|
|
param = 0.5 * (wrst1 + wrst2);
|
|
sol(1) = trst11;
|
|
sol(2) = trst22;
|
|
}
|
|
else if (sens * (wrst1 - wrst2) < 0) {
|
|
// on decroche sur Rst1
|
|
State = Blend_OnRst1;
|
|
decroch = Blend_DecrochRst1;
|
|
param = wrst1;
|
|
sol(1) = trst11;
|
|
sol(2) = trst12;
|
|
}
|
|
else {
|
|
// on decroche sur rst2
|
|
State = Blend_OnRst2;
|
|
decroch = Blend_DecrochRst2;
|
|
param = wrst2;
|
|
sol(1) = trst21;
|
|
sol(2) = trst22;
|
|
}
|
|
Func.Set(param);
|
|
}
|
|
else if (recadrst1) {
|
|
// sol sur rst1
|
|
State = Blend_OnRst1;
|
|
decroch = Blend_DecrochRst1;
|
|
param = wrst1;
|
|
sol(1) = trst11;
|
|
sol(2) = trst12;
|
|
Func.Set(param);
|
|
}
|
|
else if (recadrst2) {
|
|
// sol sur rst2
|
|
State = Blend_OnRst2;
|
|
decroch = Blend_DecrochRst2;
|
|
param = wrst2;
|
|
sol(1) = trst21;
|
|
sol(2) = trst22;
|
|
Func.Set(param);
|
|
}
|
|
// on regarde sur laquelle des courbes on sort en premier
|
|
else if (recadp1 && recadp2) {
|
|
if (Abs(wrst1 - wrst2) < tolgui) {
|
|
State = Blend_OnRst12;
|
|
param = 0.5 * (wrst1 + wrst2);
|
|
sol(1) = trst11;
|
|
sol(2) = trst22;
|
|
}
|
|
else if (sens * (wrst1 - wrst2) < 0) {
|
|
// sol sur Rst1
|
|
State = Blend_OnRst1;
|
|
param = wrst1;
|
|
sol(1) = trst11;
|
|
sol(2) = trst12;
|
|
}
|
|
else {
|
|
// sol sur rst2
|
|
State = Blend_OnRst2;
|
|
param = wrst2;
|
|
sol(1) = trst21;
|
|
sol(2) = trst22;
|
|
}
|
|
Func.Set(param);
|
|
}
|
|
else if (recadp1) {
|
|
// sol sur rst1
|
|
State = Blend_OnRst1;
|
|
param = wrst1;
|
|
sol(1) = trst11;
|
|
sol(2) = trst12;
|
|
Func.Set(param);
|
|
}
|
|
else if (recadp2) {
|
|
// sol sur rst2
|
|
State = Blend_OnRst2;
|
|
param = wrst2;
|
|
sol(1) = trst21;
|
|
sol(2) = trst22;
|
|
Func.Set(param);
|
|
}
|
|
else {
|
|
State = Blend_OK;
|
|
}
|
|
|
|
State = TestArret(Func, Standard_True, State);
|
|
}
|
|
else{
|
|
// echec recadrage. On sort avec PointsConfondus
|
|
cout<<"echec recadrage"<<endl;
|
|
State = Blend_SamePoints;
|
|
}
|
|
}
|
|
|
|
switch (State) {
|
|
case Blend_OK :
|
|
{
|
|
#ifdef DEB
|
|
if (Blend_GettraceDRAWSECT()){
|
|
Drawsect(param, Func);
|
|
}
|
|
#endif
|
|
// Mettre a jour la ligne.
|
|
if (sens > 0.) {
|
|
line->Append(previousP);
|
|
}
|
|
else {
|
|
line->Prepend(previousP);
|
|
}
|
|
parinit = sol;
|
|
parprec = param;
|
|
|
|
if (param == Bound) {
|
|
Arrive = Standard_True;
|
|
Extrst1.SetValue(previousP.PointOnC1(),
|
|
previousP.ParameterOnC1(),
|
|
previousP.Parameter(), tolesp);
|
|
MakeExtremity(Extrst2, Standard_False, rst2, sol(2), IsVtxrst2, Vtxrst2);
|
|
// Indiquer que fin sur Bound.
|
|
}
|
|
else {
|
|
param = param + sens * stepw;
|
|
if (sens * (param - Bound) > - tolgui) {
|
|
param = Bound;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case Blend_StepTooLarge :
|
|
{
|
|
stepw = stepw / 2.;
|
|
if (Abs(stepw) < tolgui) {
|
|
Extrst1.SetValue(previousP.PointOnC1(),
|
|
previousP.ParameterOnC1(),
|
|
previousP.Parameter(), tolesp);
|
|
Extrst2.SetValue(previousP.PointOnC2(),
|
|
previousP.ParameterOnC2(),
|
|
previousP.Parameter(), tolesp);
|
|
Arrive = Standard_True;
|
|
if (line->NbPoints()>=2) {
|
|
// Indiquer qu on s arrete en cours de cheminement
|
|
cout<<"On n avance plus dans le cheminement"<<endl;
|
|
}
|
|
}
|
|
else {
|
|
param = parprec + sens * stepw; // on ne risque pas de depasser Bound.
|
|
}
|
|
}
|
|
break;
|
|
|
|
case Blend_StepTooSmall :
|
|
{
|
|
#ifdef DEB
|
|
if (Blend_GettraceDRAWSECT()){
|
|
Drawsect(param,Func);
|
|
}
|
|
#endif
|
|
// Mettre a jour la ligne.
|
|
if (sens > 0.) {
|
|
line->Append(previousP);
|
|
}
|
|
else {
|
|
line->Prepend(previousP);
|
|
}
|
|
parinit = sol;
|
|
parprec = param;
|
|
|
|
stepw = Min(1.5 * stepw, pasmax);
|
|
if (param == Bound) {
|
|
Arrive = Standard_True;
|
|
Extrst1.SetValue(previousP.PointOnC1(),
|
|
previousP.ParameterOnC1(),
|
|
previousP.Parameter(), tolesp);
|
|
MakeExtremity(Extrst2, Standard_False, rst2, sol(2), IsVtxrst2, Vtxrst2);
|
|
// Indiquer que fin sur Bound.
|
|
}
|
|
else {
|
|
param = param + sens * stepw;
|
|
if (sens * (param - Bound) > - tolgui) {
|
|
param = Bound;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case Blend_OnRst1 :
|
|
{
|
|
#ifdef DEB
|
|
if (Blend_GettraceDRAWSECT()){
|
|
Drawsect(param, Func);
|
|
}
|
|
#endif
|
|
if (sens > 0.) {
|
|
line->Append(previousP);
|
|
}
|
|
else {
|
|
line->Prepend(previousP);
|
|
}
|
|
MakeExtremity(Extrst1, Standard_True, rst1, sol(1), IsVtxrst1, Vtxrst1);
|
|
MakeExtremity(Extrst2, Standard_False, rst2, sol(2), IsVtxrst2, Vtxrst2);
|
|
Arrive = Standard_True;
|
|
}
|
|
break;
|
|
|
|
case Blend_OnRst2 :
|
|
{
|
|
#ifdef DEB
|
|
if (Blend_GettraceDRAWSECT()){
|
|
Drawsect(param, Func);
|
|
}
|
|
#endif
|
|
if (sens>0.) {
|
|
line->Append(previousP);
|
|
}
|
|
else {
|
|
line->Prepend(previousP);
|
|
}
|
|
|
|
MakeExtremity(Extrst1, Standard_True, rst1, sol(1), IsVtxrst1, Vtxrst1);
|
|
MakeExtremity(Extrst2, Standard_False, rst2, sol(2), IsVtxrst2, Vtxrst2);
|
|
Arrive = Standard_True;
|
|
}
|
|
break;
|
|
|
|
case Blend_OnRst12 :
|
|
{
|
|
#ifdef DEB
|
|
if (Blend_GettraceDRAWSECT()){
|
|
Drawsect(param, Func);
|
|
}
|
|
#endif
|
|
if (sens > 0.) {
|
|
line->Append(previousP);
|
|
}
|
|
else {
|
|
line->Prepend(previousP);
|
|
}
|
|
|
|
MakeExtremity(Extrst1, Standard_True, rst1, sol(1), IsVtxrst1, Vtxrst1);
|
|
MakeExtremity(Extrst2, Standard_False, rst2, sol(2), IsVtxrst2, Vtxrst2);
|
|
Arrive = Standard_True;
|
|
}
|
|
break;
|
|
|
|
case Blend_SamePoints :
|
|
{
|
|
// On arrete
|
|
cout << " Points confondus dans le cheminement" << endl;
|
|
Extrst1.SetValue(previousP.PointOnC1(),
|
|
previousP.ParameterOnC1(),
|
|
previousP.Parameter(), tolesp);
|
|
Extrst2.SetValue(previousP.PointOnC2(),
|
|
previousP.ParameterOnC2(),
|
|
previousP.Parameter(), tolesp);
|
|
Arrive = Standard_True;
|
|
}
|
|
break;
|
|
#ifndef DEB
|
|
default:
|
|
break;
|
|
#endif
|
|
}
|
|
if (Arrive) {
|
|
if (sens > 0.) {
|
|
line->SetEndPoints(Extrst1, Extrst2);
|
|
decrochfin = decroch;
|
|
}
|
|
else {
|
|
line->SetStartPoints(Extrst1, Extrst2);
|
|
decrochdeb = decroch;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : Recadre1
|
|
//purpose : On a decroche en 1
|
|
//=======================================================================
|
|
|
|
Standard_Boolean BRepBlend_RstRstLineBuilder::Recadre1(Blend_RstRstFunction& Func,
|
|
Blend_SurfCurvFuncInv& Finv,
|
|
math_Vector& Solinv,
|
|
Standard_Boolean& IsVtx,
|
|
Handle(Adaptor3d_HVertex)& Vtx)
|
|
{
|
|
math_Vector toler(1, 3), infb(1, 3), supb(1, 3);
|
|
Finv.GetTolerance(toler, tolesp);
|
|
Finv.GetBounds(infb, supb);
|
|
Solinv(1) = param;
|
|
Solinv(2) = sol(2);
|
|
Solinv(3) = sol(1);
|
|
|
|
// On recherche le point de non decrochement
|
|
math_FunctionSetRoot rsnld(Finv, toler, 30);
|
|
rsnld.Perform(Finv, Solinv, infb, supb);
|
|
if (!rsnld.IsDone()) {
|
|
cout << "RSNLD not done "<< endl << endl;
|
|
return Standard_False;
|
|
}
|
|
|
|
rsnld.Root(Solinv);
|
|
|
|
// On doit verifier la valeur de la fonction est bien
|
|
// sur la seconde restriction
|
|
if (Finv.IsSolution(Solinv, tolesp)) {
|
|
Standard_Real w = Solinv(2);
|
|
if(w < rst2->FirstParameter() - toler(2)||
|
|
w > rst2->LastParameter() + toler(2)){
|
|
return Standard_False;
|
|
}
|
|
|
|
// on regarde si on n est pas sur un Vertex
|
|
domain1->Initialize(rst1);
|
|
domain1->InitVertexIterator();
|
|
IsVtx = !domain1->MoreVertex();
|
|
while (!IsVtx) {
|
|
Vtx = domain1->Vertex();
|
|
if (Abs(BRepBlend_BlendTool::Parameter(Vtx, rst1)-Solinv(3)) <=
|
|
BRepBlend_BlendTool::Tolerance(Vtx, rst1)) {
|
|
IsVtx = Standard_True;
|
|
}
|
|
else {
|
|
domain1->NextVertex();
|
|
IsVtx = !domain1->MoreVertex();
|
|
}
|
|
}
|
|
if (!domain1->MoreVertex()) {
|
|
IsVtx = Standard_False;
|
|
}
|
|
// On recalcule la section par resolution directe, sinon, on se recupere
|
|
// des incoherences entre le parametre et sol dues au baillement.
|
|
|
|
math_Vector infbound(1, 2), supbound(1, 2);
|
|
math_Vector parinit(1, 2), tolerance(1, 2);
|
|
Func.GetTolerance(tolerance, tolesp);
|
|
Func.GetBounds(infbound, supbound);
|
|
|
|
math_FunctionSetRoot rsnld2(Func, tolerance, 30);
|
|
parinit(1) = Solinv(3);
|
|
parinit(2) = Solinv(2);
|
|
Func.Set(Solinv(1));
|
|
rsnld2.Perform(Func, parinit, infbound, supbound);
|
|
if(!rsnld2.IsDone()) return Standard_False;
|
|
rsnld2.Root(parinit);
|
|
Solinv(2) = parinit(2);
|
|
Solinv(3) = parinit(1);
|
|
return Standard_True;
|
|
}
|
|
return Standard_False;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//=======================================================================
|
|
//function : Recadre2
|
|
//purpose : On a decroche sur Rst2
|
|
//=======================================================================
|
|
|
|
Standard_Boolean BRepBlend_RstRstLineBuilder::Recadre2(Blend_RstRstFunction& Func,
|
|
Blend_SurfCurvFuncInv& Finv,
|
|
math_Vector& Solinv,
|
|
Standard_Boolean& IsVtx,
|
|
Handle(Adaptor3d_HVertex)& Vtx)
|
|
{
|
|
math_Vector toler(1, 3), infb(1, 3), supb(1, 3);
|
|
Finv.GetTolerance(toler, tolesp);
|
|
Finv.GetBounds(infb, supb);
|
|
Solinv(1) = param;
|
|
Solinv(2) = sol(1);
|
|
Solinv(3) = sol(2);
|
|
|
|
math_FunctionSetRoot rsnld(Finv, toler, 30);
|
|
rsnld.Perform(Finv, Solinv, infb, supb);
|
|
if (!rsnld.IsDone()) {
|
|
cout << "RSNLD not done "<< endl << endl;
|
|
return Standard_False;
|
|
}
|
|
|
|
rsnld.Root(Solinv);
|
|
|
|
// On doit verifier la valeur de la fonction
|
|
if (Finv.IsSolution(Solinv, tolesp)) {
|
|
Standard_Real w = Solinv(2);
|
|
if(w < rst1->FirstParameter() - toler(2)||
|
|
w > rst1->LastParameter() + toler(2)){
|
|
return Standard_False;
|
|
}
|
|
|
|
domain2->Initialize(rst2);
|
|
domain2->InitVertexIterator();
|
|
IsVtx = !domain2->MoreVertex();
|
|
while (!IsVtx) {
|
|
Vtx = domain2->Vertex();
|
|
if (Abs(BRepBlend_BlendTool::Parameter(Vtx, rst2)-Solinv(3)) <=
|
|
BRepBlend_BlendTool::Tolerance(Vtx, rst2)) {
|
|
IsVtx = Standard_True;
|
|
}
|
|
else {
|
|
domain2->NextVertex();
|
|
IsVtx = !domain2->MoreVertex();
|
|
}
|
|
}
|
|
if (!domain2->MoreVertex()) {
|
|
IsVtx = Standard_False;
|
|
}
|
|
// On recalcule la section par resolution directe, sinon, on se recupere
|
|
// des incoherences entre le parametre et sol dues au baillement.
|
|
|
|
math_Vector infbound(1, 2), supbound(1, 2);
|
|
math_Vector parinit(1,2), tolerance(1,2);
|
|
Func.GetTolerance(tolerance, tolesp);
|
|
Func.GetBounds(infbound, supbound);
|
|
|
|
math_FunctionSetRoot rsnld2(Func, tolerance, 30);
|
|
parinit(1) = Solinv(2);
|
|
parinit(2) = Solinv(3);
|
|
Func.Set(Solinv(1));
|
|
rsnld2.Perform(Func, parinit, infbound, supbound);
|
|
if(!rsnld2.IsDone()) return Standard_False;
|
|
rsnld2.Root(parinit);
|
|
Solinv(2) = parinit(1);
|
|
Solinv(3) = parinit(2);
|
|
return Standard_True;
|
|
}
|
|
return Standard_False;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Recadre
|
|
//purpose : On est en fin de la courbe rst1
|
|
//=======================================================================
|
|
|
|
Standard_Boolean BRepBlend_RstRstLineBuilder::Recadre1(Blend_CurvPointFuncInv& FinvP,
|
|
math_Vector& Solinv,
|
|
Standard_Boolean& IsVtx,
|
|
Handle(Adaptor3d_HVertex)& Vtx)
|
|
{
|
|
// On se place sur le dernier ou le premier point, suivant le
|
|
// sens de cheminement.
|
|
gp_Pnt2d p2drst1;
|
|
Standard_Real firstrst1 = rst1->FirstParameter();
|
|
Standard_Real lastrst1 = rst1->LastParameter();
|
|
Standard_Real upoint = firstrst1;
|
|
|
|
if((sol(1) - firstrst1) > (lastrst1 - sol(1))) upoint = lastrst1;
|
|
p2drst1 = rst1->Value(upoint);
|
|
gp_Pnt thepoint = surf1->Value(p2drst1.X(), p2drst1.Y());
|
|
|
|
FinvP.Set(thepoint);
|
|
math_Vector toler(1,2), infb(1, 2), supb(1, 2);
|
|
FinvP.GetTolerance(toler, tolesp);
|
|
FinvP.GetBounds(infb, supb);
|
|
Solinv(1) = param;
|
|
Solinv(2) = sol(2);
|
|
|
|
math_FunctionSetRoot rsnld(FinvP, toler, 30);
|
|
rsnld.Perform(FinvP, Solinv, infb, supb);
|
|
if (!rsnld.IsDone()) {
|
|
cout << "RSNLD not done "<< endl << endl;
|
|
return Standard_False;
|
|
}
|
|
rsnld.Root(Solinv);
|
|
|
|
if(FinvP.IsSolution(Solinv, tolesp)){
|
|
gp_Pnt2d p2drst2 = rst2->Value(Solinv(2));
|
|
TopAbs_State situ = domain2->Classify(p2drst2, toler(2), 0);
|
|
if ((situ != TopAbs_IN) && (situ != TopAbs_ON)) {
|
|
return Standard_False;
|
|
}
|
|
domain1->Initialize(rst1);
|
|
domain1->InitVertexIterator();
|
|
IsVtx = !domain1->MoreVertex();
|
|
while (!IsVtx) {
|
|
Vtx = domain1->Vertex();
|
|
if (Abs(BRepBlend_BlendTool::Parameter(Vtx, rst1) - upoint) <=
|
|
BRepBlend_BlendTool::Tolerance(Vtx, rst1)) {
|
|
IsVtx = Standard_True;
|
|
}
|
|
else {
|
|
domain1->NextVertex();
|
|
IsVtx = !domain1->MoreVertex();
|
|
}
|
|
}
|
|
if (!domain1->MoreVertex()) {
|
|
IsVtx = Standard_False;
|
|
}
|
|
return Standard_True;
|
|
}
|
|
return Standard_False;
|
|
}
|
|
|
|
|
|
|
|
//=======================================================================
|
|
//function : Recadre2
|
|
//purpose : On est en fin de la courbe rst2
|
|
//=======================================================================
|
|
|
|
Standard_Boolean BRepBlend_RstRstLineBuilder::Recadre2(Blend_CurvPointFuncInv& FinvP,
|
|
math_Vector& Solinv,
|
|
Standard_Boolean& IsVtx,
|
|
Handle(Adaptor3d_HVertex)& Vtx)
|
|
{
|
|
// On se place sur le dernier ou le premier point, suivant le
|
|
// sens de cheminement.
|
|
gp_Pnt2d p2drst2;
|
|
Standard_Real firstrst2 = rst2->FirstParameter();
|
|
Standard_Real lastrst2 = rst2->LastParameter();
|
|
Standard_Real vpoint = firstrst2;
|
|
|
|
if((sol(2) - firstrst2) > (lastrst2 - sol(2))) vpoint = lastrst2;
|
|
p2drst2 = rst2->Value(vpoint);
|
|
gp_Pnt thepoint = surf2->Value(p2drst2.X(), p2drst2.Y());
|
|
|
|
FinvP.Set(thepoint);
|
|
math_Vector toler(1,2), infb(1, 2), supb(1, 2);
|
|
FinvP.GetTolerance(toler, tolesp);
|
|
FinvP.GetBounds(infb, supb);
|
|
Solinv(1) = param;
|
|
Solinv(2) = sol(1);
|
|
|
|
math_FunctionSetRoot rsnld(FinvP, toler, 30);
|
|
rsnld.Perform(FinvP, Solinv, infb, supb);
|
|
if (!rsnld.IsDone()) {
|
|
cout << "RSNLD not done "<< endl << endl;
|
|
return Standard_False;
|
|
}
|
|
rsnld.Root(Solinv);
|
|
|
|
if(FinvP.IsSolution(Solinv, tolesp)){
|
|
gp_Pnt2d p2drst1 = rst1->Value(Solinv(2));
|
|
TopAbs_State situ = domain1->Classify(p2drst1, toler(2), 0);
|
|
if ((situ != TopAbs_IN) && (situ != TopAbs_ON)) {
|
|
return Standard_False;
|
|
}
|
|
domain2->Initialize(rst2);
|
|
domain2->InitVertexIterator();
|
|
IsVtx = !domain2->MoreVertex();
|
|
while (!IsVtx) {
|
|
Vtx = domain2->Vertex();
|
|
if (Abs(BRepBlend_BlendTool::Parameter(Vtx, rst2) - vpoint) <=
|
|
BRepBlend_BlendTool::Tolerance(Vtx, rst2)) {
|
|
IsVtx = Standard_True;
|
|
}
|
|
else {
|
|
domain2->NextVertex();
|
|
IsVtx = !domain2->MoreVertex();
|
|
}
|
|
}
|
|
if (!domain2->MoreVertex()) {
|
|
IsVtx = Standard_False;
|
|
}
|
|
return Standard_True;
|
|
}
|
|
return Standard_False;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : Transition
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BRepBlend_RstRstLineBuilder::Transition(const Standard_Boolean OnFirst,
|
|
const Handle(Adaptor2d_HCurve2d)& Arc,
|
|
const Standard_Real Param,
|
|
IntSurf_Transition& TLine,
|
|
IntSurf_Transition& TArc)
|
|
{
|
|
Standard_Boolean computetranstionaveclacorde = 0;
|
|
gp_Vec tgline;
|
|
Blend_Point prevprev;
|
|
|
|
if(previousP.IsTangencyPoint()){
|
|
if(line->NbPoints() < 2) return;
|
|
computetranstionaveclacorde = 1;
|
|
if(sens < 0){
|
|
prevprev = line->Point(2);
|
|
}
|
|
else {
|
|
prevprev = line->Point(line->NbPoints() - 1);
|
|
}
|
|
}
|
|
gp_Pnt2d p2d;
|
|
gp_Vec2d dp2d;
|
|
|
|
gp_Pnt pbid;
|
|
gp_Vec d1u, d1v, normale, tgrst;
|
|
|
|
Arc->D1(Param, p2d, dp2d);
|
|
if (OnFirst) {
|
|
surf1->D1(p2d.X(), p2d.Y(), pbid, d1u, d1v);
|
|
if(!computetranstionaveclacorde) tgline = previousP.TangentOnC1();
|
|
else tgline = gp_Vec(prevprev.PointOnC1(), previousP.PointOnC1());
|
|
}
|
|
else {
|
|
surf2->D1(p2d.X(), p2d.Y(), pbid, d1u, d1v);
|
|
if(!computetranstionaveclacorde) tgline = previousP.TangentOnC2();
|
|
else tgline = gp_Vec(prevprev.PointOnC2(), previousP.PointOnC2());
|
|
}
|
|
|
|
tgrst.SetLinearForm(dp2d.X(), d1u, dp2d.Y(), d1v);
|
|
normale = d1u.Crossed(d1v);
|
|
|
|
IntSurf::MakeTransition(tgline, tgrst, normale, TLine, TArc);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : MakeExtremity
|
|
//purpose : fabrique l extremite d une courbe
|
|
//=======================================================================
|
|
|
|
void BRepBlend_RstRstLineBuilder::MakeExtremity(BRepBlend_Extremity& Extrem,
|
|
const Standard_Boolean OnFirst,
|
|
const Handle(Adaptor2d_HCurve2d)& Arc,
|
|
const Standard_Real Param,
|
|
const Standard_Boolean IsVtx,
|
|
const Handle(Adaptor3d_HVertex)& Vtx)
|
|
{
|
|
IntSurf_Transition Tline, Tarc;
|
|
Standard_Real prm;
|
|
Handle(Adaptor3d_TopolTool) Iter;
|
|
if (OnFirst) {
|
|
Extrem.SetValue(previousP.PointOnC1(),
|
|
sol(1),
|
|
previousP.Parameter(), tolesp);
|
|
if (!previousP.IsTangencyPoint())
|
|
Extrem.SetTangent(previousP.TangentOnC1());
|
|
Iter = domain1;
|
|
}
|
|
else {
|
|
Extrem.SetValue(previousP.PointOnC2(),
|
|
sol(2),
|
|
previousP.Parameter(), tolesp);
|
|
if (!previousP.IsTangencyPoint())
|
|
Extrem.SetTangent(previousP.TangentOnC1());
|
|
Iter = domain2;
|
|
}
|
|
|
|
Iter->Init();
|
|
if (!IsVtx) {
|
|
Transition(OnFirst, Arc, Param, Tline, Tarc);
|
|
Extrem.AddArc(Arc, Param, Tline, Tarc);
|
|
}
|
|
else {
|
|
Extrem.SetVertex(Vtx);
|
|
while (Iter->More()) {
|
|
//#ifndef DEB
|
|
Handle(Adaptor2d_HCurve2d) arc = Iter->Value();
|
|
//#else
|
|
// Handle(Adaptor2d_HCurve2d)& arc = Iter->Value();
|
|
//#endif
|
|
if (arc != Arc) {
|
|
Iter->Initialize(arc);
|
|
Iter->InitVertexIterator();
|
|
while (Iter->MoreVertex()) {
|
|
if (Iter->Identical(Vtx, Iter->Vertex())) {
|
|
prm = BRepBlend_BlendTool::Parameter(Vtx, arc);
|
|
Transition(OnFirst, arc, prm, Tline, Tarc);
|
|
Extrem.AddArc(arc, prm, Tline, Tarc);
|
|
}
|
|
Iter->NextVertex();
|
|
}
|
|
}
|
|
else {
|
|
Transition(OnFirst, arc, Param, Tline, Tarc);
|
|
Extrem.AddArc(arc, Param, Tline, Tarc);
|
|
}
|
|
Iter->Next();
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : CheckDeflectionOnRst1
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Blend_Status BRepBlend_RstRstLineBuilder::CheckDeflectionOnRst1(const Blend_Point& CurPoint)
|
|
{
|
|
//Controles 3d du Blend_CSWalking.
|
|
|
|
// regle par tests dans U4 correspond a 11.478 d
|
|
const Standard_Real CosRef3D = 0.98;
|
|
Standard_Real Cosi, Cosi2;
|
|
Standard_Boolean curpointistangent = CurPoint.IsTangencyPoint();
|
|
Standard_Boolean prevpointistangent = previousP.IsTangencyPoint();
|
|
|
|
gp_Pnt Psurf = CurPoint.PointOnC1();
|
|
gp_Vec Tgsurf;
|
|
if(!curpointistangent){
|
|
Tgsurf = CurPoint.TangentOnC1();
|
|
}
|
|
gp_Pnt prevP = previousP.PointOnC1();
|
|
gp_Vec prevTg;
|
|
if(!prevpointistangent){
|
|
prevTg = previousP.TangentOnC1();
|
|
}
|
|
Standard_Real Norme, curNorme;
|
|
#ifndef DEB
|
|
Standard_Real prevNorme = 0.;
|
|
#else
|
|
Standard_Real prevNorme;
|
|
#endif
|
|
gp_Vec Corde(prevP, Psurf);
|
|
Norme = Corde.SquareMagnitude();
|
|
if (!curpointistangent) curNorme = Tgsurf.SquareMagnitude();
|
|
if (!prevpointistangent) prevNorme = prevTg.SquareMagnitude();
|
|
|
|
if (Norme <= tolesp * tolesp) {
|
|
// il faudra peut etre forcer meme point
|
|
return Blend_SamePoints;
|
|
}
|
|
if(!prevpointistangent){
|
|
if (prevNorme <= tolesp * tolesp) {
|
|
return Blend_SamePoints;
|
|
}
|
|
Cosi = sens * Corde * prevTg;
|
|
if (Cosi < 0.) { // angle 3d>pi/2. --> retour arriere
|
|
return Blend_Backward;
|
|
}
|
|
|
|
Cosi2 = Cosi * Cosi / prevNorme / Norme;
|
|
if (Cosi2 < CosRef3D) {
|
|
return Blend_StepTooLarge;
|
|
}
|
|
}
|
|
|
|
if(!curpointistangent){
|
|
// Voir s il faut faire le controle sur le signe de prevtg*Tgsurf
|
|
Cosi = sens * Corde * Tgsurf;
|
|
Cosi2 = Cosi * Cosi / Tgsurf.SquareMagnitude() / Norme;
|
|
if (Cosi2 < CosRef3D || Cosi < 0.) {
|
|
return Blend_StepTooLarge;
|
|
}
|
|
}
|
|
|
|
if (!curpointistangent && !prevpointistangent) {
|
|
// Estimation de la fleche courante
|
|
Standard_Real FlecheCourante =
|
|
(prevTg.Normalized().XYZ() - Tgsurf.Normalized().XYZ()).SquareModulus() * Norme / 64.;
|
|
|
|
if (FlecheCourante <= 0.25 * fleche * fleche) {
|
|
return Blend_StepTooSmall;
|
|
}
|
|
if (FlecheCourante > fleche * fleche) {
|
|
// pas trop grand : commentaire interessant
|
|
return Blend_StepTooLarge;
|
|
}
|
|
}
|
|
return Blend_OK;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : CheckDeflectionOnRst2
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Blend_Status BRepBlend_RstRstLineBuilder::CheckDeflectionOnRst2(const Blend_Point& CurPoint)
|
|
{
|
|
//Controles 3d du Blend_CSWalking.
|
|
|
|
// regle par tests dans U4 correspond a 11.478 d
|
|
const Standard_Real CosRef3D = 0.98;
|
|
Standard_Real Cosi, Cosi2;
|
|
Standard_Boolean curpointistangent = CurPoint.IsTangencyPoint();
|
|
Standard_Boolean prevpointistangent = previousP.IsTangencyPoint();
|
|
|
|
gp_Pnt Psurf = CurPoint.PointOnC2();
|
|
gp_Vec Tgsurf;
|
|
|
|
if (!curpointistangent) {
|
|
Tgsurf = CurPoint.TangentOnC2();
|
|
}
|
|
gp_Pnt prevP = previousP.PointOnC2();
|
|
gp_Vec prevTg;
|
|
if (!prevpointistangent) {
|
|
prevTg = previousP.TangentOnC2();
|
|
}
|
|
Standard_Real Norme, curNorme;
|
|
#ifndef DEB
|
|
Standard_Real prevNorme = 0.;
|
|
#else
|
|
Standard_Real prevNorme;
|
|
#endif
|
|
gp_Vec Corde(prevP, Psurf);
|
|
Norme = Corde.SquareMagnitude();
|
|
if (!curpointistangent) curNorme = Tgsurf.SquareMagnitude();
|
|
if (!prevpointistangent) prevNorme = prevTg.SquareMagnitude();
|
|
|
|
if (Norme <= tolesp * tolesp){
|
|
// il faudra peut etre forcer meme point
|
|
return Blend_SamePoints;
|
|
}
|
|
if (!prevpointistangent) {
|
|
if (prevNorme <= tolesp * tolesp) {
|
|
return Blend_SamePoints;
|
|
}
|
|
Cosi = sens * Corde * prevTg;
|
|
if (Cosi < 0.) { // angle 3d>pi/2. --> retour arriere
|
|
return Blend_Backward;
|
|
}
|
|
|
|
Cosi2 = Cosi * Cosi / prevNorme / Norme;
|
|
if (Cosi2 < CosRef3D) {
|
|
return Blend_StepTooLarge;
|
|
}
|
|
}
|
|
|
|
if (!curpointistangent) {
|
|
// Voir s il faut faire le controle sur le signe de prevtg*Tgsurf
|
|
Cosi = sens * Corde * Tgsurf;
|
|
Cosi2 = Cosi * Cosi / Tgsurf.SquareMagnitude() / Norme;
|
|
if (Cosi2 < CosRef3D || Cosi < 0.) {
|
|
return Blend_StepTooLarge;
|
|
}
|
|
}
|
|
|
|
if(!curpointistangent && !prevpointistangent){
|
|
// Estimation de la fleche courante
|
|
Standard_Real FlecheCourante =
|
|
(prevTg.Normalized().XYZ() - Tgsurf.Normalized().XYZ()).SquareModulus() * Norme/64.;
|
|
|
|
if (FlecheCourante <= 0.25 * fleche * fleche) {
|
|
return Blend_StepTooSmall;
|
|
}
|
|
if (FlecheCourante > fleche * fleche) {
|
|
// pas trop grand : commentaire interessant
|
|
return Blend_StepTooLarge;
|
|
}
|
|
}
|
|
return Blend_OK;
|
|
}
|
|
|
|
static IntSurf_TypeTrans ConvOrToTra(const TopAbs_Orientation O)
|
|
{
|
|
if(O == TopAbs_FORWARD) return IntSurf_In;
|
|
return IntSurf_Out;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : TestArret
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Blend_Status BRepBlend_RstRstLineBuilder::TestArret(Blend_RstRstFunction& Func,
|
|
const Standard_Boolean TestDeflection,
|
|
const Blend_Status State)
|
|
{
|
|
gp_Pnt ptrst1, ptrst2;
|
|
gp_Pnt2d pt2drst1, pt2drst2;
|
|
gp_Vec tgrst1, tgrst2;
|
|
gp_Vec2d tg2drst1, tg2drst2;
|
|
Blend_Status StateRst1, StateRst2;
|
|
#ifndef DEB
|
|
IntSurf_TypeTrans trarst1 = IntSurf_Undecided, trarst2 = IntSurf_Undecided;
|
|
#else
|
|
IntSurf_TypeTrans trarst1, trarst2;
|
|
#endif
|
|
Blend_Point curpoint;
|
|
|
|
if (Func.IsSolution(sol, tolesp)) {
|
|
Standard_Boolean curpointistangent = Func.IsTangencyPoint();
|
|
ptrst1 = Func.PointOnRst1();
|
|
ptrst2 = Func.PointOnRst2();
|
|
pt2drst1 = Func.Pnt2dOnRst1();
|
|
pt2drst2 = Func.Pnt2dOnRst2();
|
|
|
|
if(curpointistangent){
|
|
curpoint.SetValue(ptrst1, ptrst2, param, pt2drst1.X(), pt2drst1.Y(),
|
|
pt2drst2.X(), pt2drst2.Y(), sol(1), sol(2));
|
|
}
|
|
else{
|
|
tgrst1 = Func.TangentOnRst1();
|
|
tgrst2 = Func.TangentOnRst2();
|
|
tg2drst1 = Func.Tangent2dOnRst1();
|
|
tg2drst2 = Func.Tangent2dOnRst2();
|
|
curpoint.SetValue(ptrst1, ptrst2, param, pt2drst1.X(), pt2drst1.Y(),
|
|
pt2drst2.X(), pt2drst2.Y(), sol(1), sol(2),
|
|
tgrst1, tgrst2, tg2drst1, tg2drst2);
|
|
}
|
|
if (TestDeflection) {
|
|
StateRst1 = CheckDeflectionOnRst1(curpoint);
|
|
StateRst2 = CheckDeflectionOnRst2(curpoint);
|
|
}
|
|
else {
|
|
StateRst1 = StateRst2 = Blend_OK;
|
|
}
|
|
if (StateRst1 == Blend_Backward) {
|
|
StateRst1 = Blend_StepTooLarge;
|
|
rebrou = Standard_True;
|
|
}
|
|
if (StateRst2 == Blend_Backward) {
|
|
StateRst2 = Blend_StepTooLarge;
|
|
rebrou = Standard_True;
|
|
}
|
|
if (StateRst1 == Blend_StepTooLarge ||
|
|
StateRst2 == Blend_StepTooLarge) {
|
|
return Blend_StepTooLarge;
|
|
}
|
|
|
|
if (!comptra && !curpointistangent) {
|
|
gp_Pnt2d p2drstref;
|
|
gp_Vec2d tg2drstref;
|
|
rst1->D1(sol(1), p2drstref, tg2drstref);
|
|
Standard_Real testra = tg2drst1.Dot(tg2drstref);
|
|
TopAbs_Orientation Or = domain1->Orientation(rst1);
|
|
|
|
if (Abs(testra) > tolesp) {
|
|
if (testra < 0.) {
|
|
trarst1 = ConvOrToTra(TopAbs::Reverse(Or));
|
|
}
|
|
else if (testra >0.) {
|
|
trarst1 = ConvOrToTra(Or);
|
|
}
|
|
|
|
rst2->D1(sol(2), p2drstref, tg2drstref);
|
|
testra = tg2drst2.Dot(tg2drstref);
|
|
|
|
Or = domain2->Orientation(rst2);
|
|
if (Abs(testra) > tolesp) {
|
|
if (testra < 0.) {
|
|
trarst2 = ConvOrToTra(TopAbs::Reverse(Or));
|
|
}
|
|
else if (testra >0.) {
|
|
trarst2 = ConvOrToTra(Or);
|
|
}
|
|
comptra = Standard_True;
|
|
line->Set(trarst1, trarst2);
|
|
}
|
|
}
|
|
}
|
|
if (StateRst1 == Blend_OK ||
|
|
StateRst2 == Blend_OK ) {
|
|
previousP = curpoint;
|
|
return State;
|
|
}
|
|
if (StateRst1 == Blend_StepTooSmall &&
|
|
StateRst2 == Blend_StepTooSmall) {
|
|
previousP = curpoint;
|
|
if (State == Blend_OK) {
|
|
return Blend_StepTooSmall;
|
|
}
|
|
else {
|
|
return State;
|
|
}
|
|
}
|
|
if (State == Blend_OK) {
|
|
return Blend_SamePoints;
|
|
}
|
|
else {
|
|
return State;
|
|
}
|
|
}
|
|
return Blend_StepTooLarge;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : CheckInside
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean BRepBlend_RstRstLineBuilder::CheckInside(Blend_RstRstFunction& Func,
|
|
TopAbs_State& SituOnC1,
|
|
TopAbs_State& SituOnC2,
|
|
Blend_DecrochStatus & Decroch)
|
|
{
|
|
// Standard_Boolean inside = Standard_True;
|
|
math_Vector tolerance(1, 2);
|
|
Func.GetTolerance(tolerance, tolesp);
|
|
|
|
//cote pcurve 1.
|
|
Standard_Real v = sol(1);
|
|
if(v < rst1->FirstParameter() - tolerance(2)||
|
|
v > rst1->LastParameter() + tolerance(2)){
|
|
SituOnC1 = TopAbs_OUT;
|
|
}
|
|
else if (v > rst1->FirstParameter() &&
|
|
v < rst1->LastParameter()){
|
|
SituOnC1 = TopAbs_IN;
|
|
}
|
|
else SituOnC1 = TopAbs_ON;
|
|
|
|
//cote pcurve 2.
|
|
v = sol(2);
|
|
if(v < rst2->FirstParameter() - tolerance(2)||
|
|
v > rst2->LastParameter() + tolerance(2)){
|
|
SituOnC2 = TopAbs_OUT;
|
|
}
|
|
else if (v > rst2->FirstParameter() &&
|
|
v < rst2->LastParameter()){
|
|
SituOnC2 = TopAbs_IN;
|
|
}
|
|
else SituOnC2 = TopAbs_ON;
|
|
|
|
|
|
//decrochage
|
|
gp_Vec tgrst1, norst1, tgrst2, norst2;
|
|
Decroch = Func.Decroch(sol,tgrst1, norst1, tgrst2, norst2);
|
|
|
|
return (SituOnC1 == TopAbs_IN && SituOnC2 == TopAbs_IN && Decroch == Blend_NoDecroch);
|
|
}
|
|
|
|
|
|
|