mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-09 18:50:54 +03:00
test bugs modalg_7 bug22821 failed on fillet shape with 5-th edge. Experimentally has been found that reducing of parameter ChFi3d_Builder::tolesp for this task solves the issue. So, as soluton it is proposed to link parameter toleps with parameter range of spine curve. So, production coefficient has been set to pass all tests and 2 teset was extended: tests/blend/complex/A6, tests/bugs/modalg_7/bug22821 first has been extended to test different scaling factors, second has been extended to make fillet on all edges from 12. Additionally: - fixed misusage of tolesp in contexts where tolerance of point in 3d is excepted; In some context usage of tol_esp is irrelevant, because its essentiality - tolerance of the parameter on the 3d curve. So, in such context it has been replaced with new parameter tol3d (with fix value 1.0e-4). Get rid of tolapp3d duplication constant - tol_3d - tolesp = 5.0e-5 * (umax - umin) - tolesp replaced by tolpoint2d/tolpoint3d in several classes. Blend_Walking BRepBlend_SurfRstLineBuilder BRepBlend_RstRstLineBuilder Blend_CSWalking Instead `tolesp` - `tolgui` is employed in contexts where tolerance of guide curve parameter is excepted. Instead `tolesp` - `tolpoint2d` or `tolpoint3d` is employed in contexts where tolerance of point in 2d or 3d space is excepted. - Replace tolesp with tolpoint2d/tolpoint3d in BBPP function argument. - Use tolapp3d instead tolesp in BonVoisin function,
1594 lines
43 KiB
C++
1594 lines
43 KiB
C++
// Created on: 1997-01-24
|
|
// Created by: Laurent BOURESCHE
|
|
// 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 <Adaptor3d_TopolTool.hxx>
|
|
#include <Blend_FuncInv.hxx>
|
|
#include <Blend_SurfCurvFuncInv.hxx>
|
|
#include <Blend_SurfPointFuncInv.hxx>
|
|
#include <Blend_SurfRstFunction.hxx>
|
|
#include <BRepBlend_BlendTool.hxx>
|
|
#include <BRepBlend_Line.hxx>
|
|
#include <BRepBlend_SurfRstLineBuilder.hxx>
|
|
#include <gp_Pnt.hxx>
|
|
#include <gp_Pnt2d.hxx>
|
|
#include <gp_Vec.hxx>
|
|
#include <gp_Vec2d.hxx>
|
|
#include <IntSurf.hxx>
|
|
#include <IntSurf_Transition.hxx>
|
|
#include <math_FunctionSetRoot.hxx>
|
|
#include <TopAbs.hxx>
|
|
|
|
#include <stdio.h>
|
|
#ifdef OCCT_DEBUG
|
|
#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();
|
|
#ifdef OCCT_DEBUG_BBPP_N_TRDERIV
|
|
// for debug : visualisation of the section
|
|
static Standard_Boolean BBPP(const Standard_Real param,
|
|
Blend_SurfRstFunction& Func,
|
|
const math_Vector& sol,
|
|
const Standard_Real tol,
|
|
Blend_Point& BP)
|
|
{
|
|
if(!Func.IsSolution(sol,tol)) return 0;
|
|
gp_Pnt pnts = Func.PointOnS();
|
|
gp_Pnt pntrst = Func.PointOnRst();
|
|
gp_Pnt2d p2ds = Func.Pnt2dOnS();
|
|
gp_Pnt2d p2drst = Func.Pnt2dOnRst();
|
|
Standard_Real w = Func.ParameterOnRst();
|
|
BP = Blend_Point(pnts,pntrst,param,
|
|
p2ds.X(),p2ds.Y(),
|
|
p2drst.X(),p2drst.Y(),w);
|
|
return 1;
|
|
}
|
|
static void tracederiv(Blend_SurfRstFunction& 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);
|
|
|
|
std::cout<<std::endl;
|
|
std::cout<<"control derivatives at point : "<<param1<<std::endl;
|
|
|
|
for(i = 1; i <= hp; i++){
|
|
std::cout<<std::endl;
|
|
std::cout<<"point : "<<i<<std::endl;
|
|
std::cout<<"dx calculated : "<<TDP1(i).X()<<std::endl;
|
|
std::cout<<"dx estimated : "<<scal*(TP1(i).X()-TP2(i).X())<<std::endl;
|
|
std::cout<<"dy calculated : "<<TDP1(i).Y()<<std::endl;
|
|
std::cout<<"dy estimated : "<<scal*(TP1(i).Y()-TP2(i).Y())<<std::endl;
|
|
std::cout<<"dz calculated : "<<TDP1(i).Z()<<std::endl;
|
|
std::cout<<"dz estimated : "<<scal*(TP1(i).Z()-TP2(i).Z())<<std::endl;
|
|
std::cout<<"dw calculated : "<<TDW1(i)<<std::endl;
|
|
std::cout<<"dw estimated : "<<scal*(TW1(i)-TW2(i))<<std::endl;
|
|
}
|
|
for(i = 1; i <= hp2d; i++){
|
|
std::cout<<std::endl;
|
|
std::cout<<"point 2d : "<<i<<std::endl;
|
|
std::cout<<"dx calculated : "<<TDP2d1(i).X()<<std::endl;
|
|
std::cout<<"dx estimated : "<<scal*(TP2d1(i).X()-TP2d2(i).X())<<std::endl;
|
|
std::cout<<"dy calculated : "<<TDP2d1(i).Y()<<std::endl;
|
|
std::cout<<"dy estimated : "<<scal*(TP2d1(i).Y()-TP2d2(i).Y())<<std::endl;
|
|
}
|
|
}
|
|
#endif
|
|
static void Drawsect(const Standard_Real param,
|
|
Blend_SurfRstFunction& Func)
|
|
{
|
|
gp_Pnt pnts = Func.PointOnS();
|
|
gp_Pnt pntrst = Func.PointOnRst();
|
|
gp_Pnt2d p2ds = Func.Pnt2dOnS();
|
|
gp_Pnt2d p2drst = Func.Pnt2dOnRst();
|
|
Standard_Real w = Func.ParameterOnRst();
|
|
Blend_Point BP(pnts,pntrst,param,
|
|
p2ds.X(),p2ds.Y(),
|
|
p2drst.X(),p2drst.Y(),w);
|
|
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 : ArcToRecadre
|
|
//purpose : Find a suitable arc
|
|
// PrevIndex is used to reject an already tested arc
|
|
//=======================================================================
|
|
|
|
Standard_Integer BRepBlend_SurfRstLineBuilder::
|
|
ArcToRecadre(const math_Vector& theSol,
|
|
const Standard_Integer PrevIndex,
|
|
gp_Pnt2d& lastpt2d,
|
|
gp_Pnt2d& pt2d,
|
|
Standard_Real& ponarc)
|
|
{
|
|
Standard_Integer IndexSol = 0, nbarc = 0;
|
|
Standard_Boolean ok = Standard_False;
|
|
Standard_Boolean byinter = (line->NbPoints() != 0), okinter = 0;
|
|
Standard_Real distmin = RealLast();
|
|
Standard_Real uprev = 0.,vprev = 0., prm = 0., dist = 0.;
|
|
|
|
if(byinter) previousP.ParametersOnS(uprev,vprev);
|
|
pt2d.SetCoord(theSol(1),theSol(2));
|
|
lastpt2d.SetCoord(uprev,vprev);
|
|
domain1->Init();
|
|
|
|
while (domain1->More()) {
|
|
nbarc++; ok = 0;
|
|
if(byinter) {
|
|
ok = okinter = BRepBlend_BlendTool::Inters(pt2d,lastpt2d,
|
|
surf1,
|
|
domain1->Value(),prm,dist);
|
|
}
|
|
if(!ok) ok = BRepBlend_BlendTool::Project(pt2d,surf1,
|
|
domain1->Value(),prm,dist);
|
|
|
|
if (ok && (nbarc != PrevIndex) ) {
|
|
if (dist<distmin || okinter) {
|
|
distmin = dist;
|
|
ponarc = prm;
|
|
IndexSol = nbarc;
|
|
if(okinter && (PrevIndex==0) ) break;
|
|
}
|
|
}
|
|
domain1->Next();
|
|
}
|
|
return IndexSol;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : BRepBlend_SurfRstLineBuilder
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
BRepBlend_SurfRstLineBuilder::BRepBlend_SurfRstLineBuilder
|
|
(const Handle(Adaptor3d_Surface)& Surf1,
|
|
const Handle(Adaptor3d_TopolTool)& Domain1,
|
|
const Handle(Adaptor3d_Surface)& Surf2,
|
|
const Handle(Adaptor2d_Curve2d)& Rst,
|
|
const Handle(Adaptor3d_TopolTool)& Domain2):
|
|
done(Standard_False), sol(1, 3), surf1(Surf1),
|
|
domain1(Domain1), surf2(Surf2), rst(Rst),
|
|
domain2(Domain2), tolpoint3d(0.0), tolpoint2d(0.0), tolgui(0.0),
|
|
pasmax(0.0), fleche(0.0), param(0.0),
|
|
rebrou(Standard_False), iscomplete(Standard_False),
|
|
comptra(Standard_False), sens(0.0),
|
|
decrochdeb(Standard_False), decrochfin(Standard_False)
|
|
{
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Perform
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BRepBlend_SurfRstLineBuilder::Perform(Blend_SurfRstFunction& Func,
|
|
Blend_FuncInv& Finv,
|
|
Blend_SurfPointFuncInv& FinvP,
|
|
Blend_SurfCurvFuncInv& FinvC,
|
|
const Standard_Real Pdep,
|
|
const Standard_Real Pmax,
|
|
const Standard_Real MaxStep,
|
|
const Standard_Real Tol3d,
|
|
const Standard_Real Tol2d,
|
|
const Standard_Real TolGuide,
|
|
const math_Vector& ParDep,
|
|
const Standard_Real Fleche,
|
|
const Standard_Boolean Appro)
|
|
{
|
|
done = Standard_False;
|
|
iscomplete = Standard_False;
|
|
comptra = Standard_False;
|
|
line = new BRepBlend_Line();
|
|
tolpoint3d = Tol3d;
|
|
tolpoint2d = Tol2d;
|
|
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 siturst,situs;
|
|
Standard_Boolean decroch;
|
|
math_Vector tolerance(1,3),infbound(1,3),supbound(1,3);
|
|
Func.GetTolerance(tolerance,tolpoint3d);
|
|
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,siturst,situs,decroch)) {
|
|
return;
|
|
}
|
|
}
|
|
else {
|
|
sol = ParDep;
|
|
}
|
|
|
|
State = TestArret(Func,Standard_False,Blend_OK);
|
|
if (State!=Blend_OK) {
|
|
return;
|
|
}
|
|
#ifdef OCCT_DEBUG
|
|
if (Blend_GettraceDRAWSECT()){
|
|
Drawsect(param,Func);
|
|
}
|
|
#endif
|
|
// Update the line.
|
|
line->Append(previousP);
|
|
Standard_Real U,V;
|
|
previousP.ParametersOnS(U,V);
|
|
// W = previousP.ParameterOnC();
|
|
|
|
BRepBlend_Extremity ptf1(previousP.PointOnS(),
|
|
U,V,previousP.Parameter(),tolpoint3d);
|
|
BRepBlend_Extremity ptf2(previousP.PointOnC(),
|
|
U,V,previousP.Parameter(),tolpoint3d);
|
|
if (!previousP.IsTangencyPoint()) {
|
|
ptf1.SetTangent(previousP.TangentOnS());
|
|
ptf2.SetTangent(previousP.TangentOnC());
|
|
}
|
|
if (sens>0.) {
|
|
line->SetStartPoints(ptf1, ptf2);
|
|
}
|
|
else {
|
|
line->SetEndPoints(ptf1, ptf2);
|
|
|
|
}
|
|
InternalPerform(Func,Finv,FinvP,FinvC,Pmax);
|
|
done = Standard_True;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : PerformFirstSection
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean BRepBlend_SurfRstLineBuilder::PerformFirstSection
|
|
(Blend_SurfRstFunction& Func,
|
|
Blend_FuncInv& Finv,
|
|
Blend_SurfPointFuncInv& FinvP,
|
|
Blend_SurfCurvFuncInv& FinvC,
|
|
const Standard_Real Pdep,
|
|
const Standard_Real Pmax,
|
|
const math_Vector& ParDep,
|
|
const Standard_Real Tol3d,
|
|
const Standard_Real Tol2d,
|
|
const Standard_Real TolGuide,
|
|
const Standard_Boolean RecRst,
|
|
const Standard_Boolean RecP,
|
|
const Standard_Boolean RecS,
|
|
Standard_Real& Psol,
|
|
math_Vector& ParSol)
|
|
{
|
|
done = Standard_False;
|
|
iscomplete = Standard_False;
|
|
comptra = Standard_False;
|
|
line = new BRepBlend_Line();
|
|
tolpoint3d = Tol3d;
|
|
tolpoint2d = Tol2d;
|
|
tolgui = Abs(TolGuide);
|
|
rebrou = Standard_False;
|
|
|
|
if (Pmax-Pdep >= 0.) {
|
|
sens = 1.;
|
|
}
|
|
else {
|
|
sens = -1.;
|
|
}
|
|
Blend_Status State = Blend_OnRst12;
|
|
Standard_Real trst = 0.;
|
|
Standard_Boolean recadp,recadrst,recads;
|
|
Standard_Real wp,wrst,ws;
|
|
Standard_Real U = 0.,V = 0.;
|
|
math_Vector infbound(1,3),supbound(1,3),tolerance(1,3);
|
|
math_Vector solinvp(1,3),solinvrst(1,4),solinvs(1,3);
|
|
Handle(Adaptor3d_HVertex) Vtxp,Vtxrst,Vtxs,Vtxc;
|
|
Standard_Boolean IsVtxp = 0,IsVtxrst = 0,IsVtxs = 0;
|
|
Handle(Adaptor2d_Curve2d) Arc;
|
|
wp = wrst = ws = Pmax;
|
|
param = Pdep;
|
|
Func.Set(param);
|
|
Func.GetTolerance(tolerance,tolpoint3d);
|
|
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);
|
|
|
|
recads = RecS && Recadre(FinvC,solinvs,Arc,IsVtxs,Vtxs);
|
|
if (recads) {
|
|
ws = solinvs(1);
|
|
}
|
|
recadp = RecP && Recadre(FinvP,solinvp,IsVtxp,Vtxp);
|
|
if (recadp) {
|
|
wp = solinvp(1);
|
|
}
|
|
recadrst = RecRst && Recadre(Func,Finv,solinvrst,IsVtxrst,Vtxrst);
|
|
if (recadrst) {
|
|
wrst = solinvrst(2);
|
|
}
|
|
if (!recads && !recadp && !recadrst) return Standard_False;
|
|
if (recadp && recadrst) {
|
|
if(sens*(wrst-wp) > tolgui){ //first one leaves the domain
|
|
wrst = wp;
|
|
U = solinvp(2);
|
|
V = solinvp(3);
|
|
trst = BRepBlend_BlendTool::Parameter(Vtxp,rst);
|
|
IsVtxrst = IsVtxp;
|
|
Vtxrst = Vtxp;
|
|
}
|
|
else{
|
|
U = solinvrst(3);
|
|
V = solinvrst(4);
|
|
trst = solinvrst(1);
|
|
}
|
|
}
|
|
else if(recadp){
|
|
wrst = wp;
|
|
U = solinvp(2);
|
|
V = solinvp(3);
|
|
trst = BRepBlend_BlendTool::Parameter(Vtxp,rst);
|
|
IsVtxrst = IsVtxp;
|
|
Vtxrst = Vtxp;
|
|
recadrst = Standard_True;
|
|
}
|
|
else if(recadrst){
|
|
U = solinvrst(3);
|
|
V = solinvrst(4);
|
|
trst = solinvrst(1);
|
|
}
|
|
if(recads && recadrst){
|
|
if(Abs(ws - wrst) < tolgui){
|
|
State = Blend_OnRst12;
|
|
param = 0.5*(ws+wrst);
|
|
sol(1) = U;
|
|
sol(2) = V;
|
|
sol(3) = solinvs(2);
|
|
}
|
|
else if(sens*(ws-wrst)<0){
|
|
// ground on surf
|
|
State = Blend_OnRst1;
|
|
param = ws;
|
|
Arc->Value(solinvs(3)).Coord(U,V);
|
|
sol(1) = U;
|
|
sol(2) = V;
|
|
sol(3) = solinvs(2);
|
|
}
|
|
else{
|
|
// ground on rst
|
|
State = Blend_OnRst2;
|
|
param = wrst;
|
|
sol(1) = U;
|
|
sol(2) = V;
|
|
sol(3) = trst;
|
|
}
|
|
Func.Set(param);
|
|
}
|
|
else if(recads){
|
|
// ground on surf
|
|
State = Blend_OnRst1;
|
|
param = ws;
|
|
Arc->Value(solinvs(3)).Coord(U,V);
|
|
sol(1) = U;
|
|
sol(2) = V;
|
|
sol(3) = solinvs(2);
|
|
Func.Set(param);
|
|
}
|
|
else if(recadrst){
|
|
// ground on rst
|
|
State = Blend_OnRst2;
|
|
param = wrst;
|
|
sol(1) = U;
|
|
sol(2) = V;
|
|
sol(3) = trst;
|
|
Func.Set(param);
|
|
}
|
|
State = TestArret(Func,Standard_False,State);
|
|
Psol = param;
|
|
ParSol = sol;
|
|
return Standard_True;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Complete
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean BRepBlend_SurfRstLineBuilder::Complete(Blend_SurfRstFunction& Func,
|
|
Blend_FuncInv& Finv,
|
|
Blend_SurfPointFuncInv& FinvP,
|
|
Blend_SurfCurvFuncInv& FinvC,
|
|
const Standard_Real Pmin)
|
|
{
|
|
if (!done) {throw StdFail_NotDone();}
|
|
if (iscomplete) {return Standard_True;}
|
|
if (sens >0.) {
|
|
previousP = line->Point(1);
|
|
}
|
|
else {
|
|
previousP = line->Point(line->NbPoints());
|
|
}
|
|
sens = -sens;
|
|
param = previousP.Parameter();
|
|
previousP.ParametersOnS(sol(1),sol(2));
|
|
sol(3) = previousP.ParameterOnC();
|
|
|
|
InternalPerform(Func,Finv,FinvP,FinvC,Pmin);
|
|
iscomplete = Standard_True;
|
|
return Standard_True;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : InternalPerform
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BRepBlend_SurfRstLineBuilder::InternalPerform(Blend_SurfRstFunction& Func,
|
|
Blend_FuncInv& Finv,
|
|
Blend_SurfPointFuncInv& FinvP,
|
|
Blend_SurfCurvFuncInv& FinvC,
|
|
const Standard_Real Bound)
|
|
{
|
|
Standard_Real stepw = pasmax;
|
|
Standard_Integer nbp = line->NbPoints();
|
|
if(nbp >= 2){ //The last step is reproduced if it is not too small.
|
|
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;
|
|
}
|
|
Blend_Status State = Blend_OnRst12;
|
|
TopAbs_State situonc = TopAbs_UNKNOWN, situons = TopAbs_UNKNOWN;
|
|
Standard_Boolean decroch = Standard_False;
|
|
Standard_Boolean Arrive,recadp,recadrst,recads,echecrecad;
|
|
Standard_Real wp,wrst,ws;
|
|
Standard_Real U = 0.,V = 0.;
|
|
Standard_Real trst = 0.;
|
|
math_Vector infbound(1,3),supbound(1,3);
|
|
math_Vector parinit(1,3),tolerance(1,3);
|
|
math_Vector solinvp(1,3),solinvrst(1,4),solinvs(1,3);
|
|
Handle(Adaptor3d_HVertex) Vtxp,Vtxrst,Vtxs,Vtxc;
|
|
Standard_Boolean IsVtxp = 0,IsVtxrst = 0,IsVtxs = 0;
|
|
BRepBlend_Extremity Extrst,Exts;
|
|
Handle(Adaptor2d_Curve2d) Arc;
|
|
|
|
//IntSurf_Transition Tline,Tarc;
|
|
|
|
Func.GetTolerance(tolerance,tolpoint3d);
|
|
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;
|
|
#ifdef OCCT_DEBUG_BBPP_N_TRDERIV
|
|
//debdebdebdebdebdeb
|
|
Func.Set(param);
|
|
rsnld.Perform(Func,parinit,infbound,supbound);
|
|
if (rsnld.IsDone()) {
|
|
rsnld.Root(sol);
|
|
Blend_Point bp1;
|
|
if(BBPP(param,Func,sol,tolpoint3d,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,tolpoint3d,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,situonc,situons,decroch) && line->NbPoints() == 1){
|
|
State = Blend_StepTooLarge;
|
|
bonpoint = 0;
|
|
}
|
|
}
|
|
else {
|
|
State = Blend_StepTooLarge;
|
|
bonpoint = 0;
|
|
}
|
|
if(bonpoint){
|
|
wp = wrst = ws = Bound;
|
|
recadp = recadrst = recads = Standard_False;
|
|
echecrecad = Standard_False;
|
|
if (situons == TopAbs_OUT || situons == TopAbs_ON) {
|
|
// pb inverse rst/rst
|
|
recads = Recadre(FinvC,solinvs,Arc,IsVtxs,Vtxs);
|
|
if (recads) {
|
|
ws = solinvs(1);
|
|
// It is necessary to reevaluate the deviation (BUC60360)
|
|
gp_Vec t, n;
|
|
Func.Set(ws);
|
|
Arc->Value(solinvs(3)).Coord(U,V);
|
|
sol(1) = U;
|
|
sol(2) = V;
|
|
sol(3) = solinvs(2);
|
|
decroch = Func.Decroch(sol, t, n);
|
|
}
|
|
else {
|
|
echecrecad = Standard_True;
|
|
}
|
|
}
|
|
if (situonc == TopAbs_OUT || situonc == TopAbs_ON) {
|
|
// pb inverse point/surf
|
|
recadp = Recadre(FinvP,solinvp,IsVtxp,Vtxp);
|
|
if (recadp) {
|
|
wp = solinvp(1);
|
|
}
|
|
else {
|
|
echecrecad = Standard_True;
|
|
}
|
|
}
|
|
if (decroch) {
|
|
// pb inverse rst/surf
|
|
recadrst = Recadre(Func,Finv,solinvrst,IsVtxrst,Vtxrst);
|
|
if (recadrst) {
|
|
wrst = solinvrst(2);
|
|
}
|
|
else {
|
|
echecrecad = Standard_True;
|
|
}
|
|
}
|
|
decroch = 0;
|
|
if(recadp || recads || recadrst) echecrecad = Standard_False;
|
|
if (!echecrecad) {
|
|
if (recadp && recadrst) {
|
|
if(sens*(wrst-wp) > tolgui){ //first one leaves the domain
|
|
wrst = wp;
|
|
U = solinvp(2);
|
|
V = solinvp(3);
|
|
trst = BRepBlend_BlendTool::Parameter(Vtxp,rst);
|
|
IsVtxrst = IsVtxp;
|
|
Vtxrst = Vtxp;
|
|
}
|
|
else{
|
|
decroch = 1;
|
|
U = solinvrst(3);
|
|
V = solinvrst(4);
|
|
trst = solinvrst(1);
|
|
}
|
|
}
|
|
else if(recadp){
|
|
wrst = wp;
|
|
U = solinvp(2);
|
|
V = solinvp(3);
|
|
trst = BRepBlend_BlendTool::Parameter(Vtxp,rst);
|
|
IsVtxrst = IsVtxp;
|
|
Vtxrst = Vtxp;
|
|
recadrst = Standard_True;
|
|
}
|
|
else if(recadrst){
|
|
decroch = 1;
|
|
U = solinvrst(3);
|
|
V = solinvrst(4);
|
|
trst = solinvrst(1);
|
|
}
|
|
if(recads && recadrst){
|
|
if(Abs(ws - wrst) < tolgui){
|
|
State = Blend_OnRst12;
|
|
param = 0.5*(ws+wrst);
|
|
sol(1) = U;
|
|
sol(2) = V;
|
|
sol(3) = solinvs(3);
|
|
}
|
|
else if(sens*(ws-wrst)<0){
|
|
// ground on surf
|
|
decroch = 0;
|
|
State = Blend_OnRst1;
|
|
param = ws;
|
|
Arc->Value(solinvs(3)).Coord(U,V);
|
|
sol(1) = U;
|
|
sol(2) = V;
|
|
sol(3) = solinvs(2);
|
|
}
|
|
else{
|
|
// ground on rst
|
|
State = Blend_OnRst2;
|
|
param = wrst;
|
|
sol(1) = U;
|
|
sol(2) = V;
|
|
sol(3) = trst;
|
|
}
|
|
Func.Set(param);
|
|
}
|
|
else if(recads){
|
|
// ground on surf
|
|
State = Blend_OnRst1;
|
|
param = ws;
|
|
Arc->Value(solinvs(3)).Coord(U,V);
|
|
sol(1) = U;
|
|
sol(2) = V;
|
|
sol(3) = solinvs(2);
|
|
Func.Set(param);
|
|
}
|
|
else if(recadrst){
|
|
// ground on rst
|
|
State = Blend_OnRst2;
|
|
param = wrst;
|
|
sol(1) = U;
|
|
sol(2) = V;
|
|
sol(3) = trst;
|
|
Func.Set(param);
|
|
}
|
|
else {
|
|
State = Blend_OK;
|
|
}
|
|
State = TestArret(Func,Standard_True,State);
|
|
}
|
|
else{
|
|
// Failed reframing. Leave with PointsConfondus
|
|
#ifdef OCCT_DEBUG
|
|
std::cout<<"SurfRstLineBuilder : failed reframing"<<std::endl;
|
|
#endif
|
|
State = Blend_SamePoints;
|
|
}
|
|
}
|
|
|
|
switch (State) {
|
|
case Blend_OK :
|
|
{
|
|
#ifdef OCCT_DEBUG
|
|
if (Blend_GettraceDRAWSECT()){
|
|
Drawsect(param,Func);
|
|
}
|
|
#endif
|
|
// Update the line.
|
|
if (sens>0.) {
|
|
line->Append(previousP);
|
|
}
|
|
else {
|
|
line->Prepend(previousP);
|
|
}
|
|
parinit = sol;
|
|
parprec = param;
|
|
|
|
if (param == Bound) {
|
|
Arrive = Standard_True;
|
|
Exts.SetValue(previousP.PointOnS(),
|
|
sol(1),sol(2),
|
|
previousP.Parameter(),tolpoint3d);
|
|
MakeExtremity(Extrst,Standard_False,rst,sol(3),IsVtxrst,Vtxrst);
|
|
// Indicate end on Bound.
|
|
}
|
|
else {
|
|
param = param + sens*stepw;
|
|
if (sens*(param - Bound) > - tolgui) {
|
|
param = Bound;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case Blend_StepTooLarge :
|
|
{
|
|
stepw = stepw/2.;
|
|
if (Abs(stepw) < tolgui) {
|
|
previousP.ParametersOnS(U,V);
|
|
Exts.SetValue(previousP.PointOnS(),U,V,
|
|
previousP.Parameter(),tolpoint3d);
|
|
Extrst.SetValue(previousP.PointOnC(),
|
|
previousP.ParameterOnC(),
|
|
previousP.Parameter(),tolpoint3d);
|
|
Arrive = Standard_True;
|
|
if (line->NbPoints()>=2) {
|
|
// Indicate that one stops during the processing
|
|
#ifdef OCCT_DEBUG
|
|
std::cout<<"SurfRstLineBuilder : No advancement in the processing"<<std::endl;
|
|
#endif
|
|
}
|
|
}
|
|
else {
|
|
param = parprec + sens*stepw; // no risk to exceed Bound.
|
|
}
|
|
}
|
|
break;
|
|
|
|
case Blend_StepTooSmall :
|
|
{
|
|
#ifdef OCCT_DEBUG
|
|
if (Blend_GettraceDRAWSECT()){
|
|
Drawsect(param,Func);
|
|
}
|
|
#endif
|
|
// Update the line.
|
|
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;
|
|
Exts.SetValue(previousP.PointOnS(),sol(1),sol(2),
|
|
previousP.Parameter(),tolpoint3d);
|
|
MakeExtremity(Extrst,Standard_False,rst,sol(3),IsVtxrst,Vtxrst);
|
|
// Indicate end on Bound.
|
|
}
|
|
else {
|
|
param = param + sens*stepw;
|
|
if (sens*(param - Bound) > - tolgui) {
|
|
param = Bound;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case Blend_OnRst1 :
|
|
{
|
|
#ifdef OCCT_DEBUG
|
|
if (Blend_GettraceDRAWSECT()){
|
|
Drawsect(param,Func);
|
|
}
|
|
#endif
|
|
if (sens>0.) {
|
|
line->Append(previousP);
|
|
}
|
|
else {
|
|
line->Prepend(previousP);
|
|
}
|
|
MakeExtremity(Exts,Standard_True,Arc,solinvs(3),IsVtxs,Vtxs);
|
|
MakeExtremity(Extrst,Standard_False,rst,sol(3),IsVtxrst,Vtxrst);
|
|
Arrive = Standard_True;
|
|
}
|
|
break;
|
|
|
|
case Blend_OnRst2 :
|
|
{
|
|
#ifdef OCCT_DEBUG
|
|
if (Blend_GettraceDRAWSECT()){
|
|
Drawsect(param,Func);
|
|
}
|
|
#endif
|
|
if (sens>0.) {
|
|
line->Append(previousP);
|
|
}
|
|
else {
|
|
line->Prepend(previousP);
|
|
}
|
|
Exts.SetValue(previousP.PointOnS(),sol(1),sol(2),
|
|
previousP.Parameter(),tolpoint3d);
|
|
MakeExtremity(Extrst,Standard_False,rst,sol(3),IsVtxrst,Vtxrst);
|
|
Arrive = Standard_True;
|
|
}
|
|
break;
|
|
|
|
case Blend_OnRst12 :
|
|
{
|
|
#ifdef OCCT_DEBUG
|
|
if (Blend_GettraceDRAWSECT()){
|
|
Drawsect(param,Func);
|
|
}
|
|
#endif
|
|
if (sens>0.) {
|
|
line->Append(previousP);
|
|
}
|
|
else {
|
|
line->Prepend(previousP);
|
|
}
|
|
MakeExtremity(Exts,Standard_True,Arc,solinvs(1),IsVtxs,Vtxs);
|
|
MakeExtremity(Extrst,Standard_False,rst,sol(3),IsVtxrst,Vtxrst);
|
|
Arrive = Standard_True;
|
|
}
|
|
break;
|
|
|
|
case Blend_SamePoints :
|
|
{
|
|
// Stop
|
|
#ifdef OCCT_DEBUG
|
|
std::cout << "SurfRstLineBuilder Points mixed in the processing" << std::endl;
|
|
#endif
|
|
previousP.ParametersOnS(U,V);
|
|
Exts.SetValue(previousP.PointOnS(),U,V,
|
|
previousP.Parameter(),tolpoint3d);
|
|
Extrst.SetValue(previousP.PointOnC(),
|
|
previousP.ParameterOnC(),
|
|
previousP.Parameter(),tolpoint3d);
|
|
Arrive = Standard_True;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (Arrive) {
|
|
if (sens > 0.) {
|
|
line->SetEndPoints(Exts,Extrst);
|
|
decrochfin = decroch;
|
|
}
|
|
else {
|
|
line->SetStartPoints(Exts,Extrst);
|
|
decrochdeb = decroch;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Recadre
|
|
//purpose : Reframe section Surface / Restriction
|
|
//=======================================================================
|
|
|
|
Standard_Boolean BRepBlend_SurfRstLineBuilder::Recadre(Blend_SurfCurvFuncInv& FinvC,
|
|
math_Vector& Solinv,
|
|
Handle(Adaptor2d_Curve2d)& Arc,
|
|
Standard_Boolean& IsVtx,
|
|
Handle(Adaptor3d_HVertex)& Vtx)
|
|
{
|
|
Standard_Boolean recadre = Standard_False;
|
|
|
|
gp_Pnt2d pt2d, lastpt2d;
|
|
Standard_Integer IndexSol, nbarc;
|
|
Standard_Real pmin;
|
|
|
|
IndexSol = ArcToRecadre(sol, 0, lastpt2d, pt2d, pmin);
|
|
|
|
IsVtx = Standard_False;
|
|
if (IndexSol == 0) {
|
|
return Standard_False;
|
|
}
|
|
|
|
domain1->Init();
|
|
nbarc = 1;
|
|
while (nbarc < IndexSol) {
|
|
nbarc++;
|
|
domain1->Next();
|
|
}
|
|
Arc = domain1->Value();
|
|
|
|
FinvC.Set(Arc);
|
|
|
|
math_Vector toler(1,3),infb(1,3),supb(1,3);
|
|
// use reduced Tol argument value to pass testcase
|
|
// blend complex A6 with scale factor of model 0.1 (base scale = 1000)
|
|
// So, here we using 1.0e-5 rather than 1.0e-4 of tolerance of point in 3d
|
|
FinvC.GetTolerance(toler,0.1 * tolpoint3d);
|
|
FinvC.GetBounds(infb,supb);
|
|
Solinv(1) = param;
|
|
Solinv(2) = sol(3);
|
|
Solinv(3) = pmin;
|
|
|
|
math_FunctionSetRoot rsnld(FinvC,toler,30);
|
|
rsnld.Perform(FinvC,Solinv,infb,supb);
|
|
|
|
if (!rsnld.IsDone()) {
|
|
#ifdef OCCT_DEBUG
|
|
std::cout << "SurfRstLineBuilder : RSNLD not done "<< std::endl << std::endl;
|
|
#endif
|
|
}
|
|
else {
|
|
// It is necessary to check the value of the function
|
|
rsnld.Root(Solinv);
|
|
recadre = FinvC.IsSolution(Solinv,tolpoint3d);
|
|
}
|
|
|
|
// In case of fail, it is checked if another arc
|
|
// can be useful (case of output at the proximity of a vertex)
|
|
if (!recadre) {
|
|
|
|
IndexSol = ArcToRecadre(sol, IndexSol,
|
|
lastpt2d, pt2d, pmin);
|
|
if (IndexSol == 0) {
|
|
return Standard_False; // No other solution
|
|
}
|
|
|
|
domain1->Init();
|
|
nbarc = 1;
|
|
while (nbarc < IndexSol) {
|
|
nbarc++;
|
|
domain1->Next();
|
|
}
|
|
|
|
Arc = domain1->Value();
|
|
FinvC.Set(Arc);
|
|
|
|
FinvC.GetTolerance(toler,tolpoint3d);
|
|
FinvC.GetBounds(infb,supb);
|
|
|
|
Solinv(3) = pmin;
|
|
|
|
math_FunctionSetRoot aRsnld(FinvC,toler,30);
|
|
aRsnld.Perform(FinvC,Solinv,infb,supb);
|
|
|
|
if (!aRsnld.IsDone()) {
|
|
#ifdef OCCT_DEBUG
|
|
std::cout << "SurfRstLineBuilder : RSNLD not done "<< std::endl << std::endl;
|
|
#endif
|
|
}
|
|
else {
|
|
// It is necessary to check the value of the function
|
|
aRsnld.Root(Solinv);
|
|
recadre = FinvC.IsSolution(Solinv,tolpoint3d);
|
|
}
|
|
}
|
|
|
|
if (recadre) {
|
|
Standard_Real w = Solinv(2);
|
|
if(w < rst->FirstParameter() - toler(2)||
|
|
w > rst->LastParameter() + toler(2)){
|
|
return Standard_False;
|
|
}
|
|
domain1->Initialize(Arc);
|
|
domain1->InitVertexIterator();
|
|
IsVtx = !domain1->MoreVertex();
|
|
while (!IsVtx) {
|
|
Vtx = domain1->Vertex();
|
|
if (Abs(BRepBlend_BlendTool::Parameter(Vtx,Arc)-Solinv(3)) <=
|
|
BRepBlend_BlendTool::Tolerance(Vtx,Arc)) {
|
|
IsVtx = Standard_True;
|
|
}
|
|
else {
|
|
domain1->NextVertex();
|
|
IsVtx = !domain1->MoreVertex();
|
|
}
|
|
}
|
|
if (!domain1->MoreVertex()) {
|
|
IsVtx = Standard_False;
|
|
}
|
|
return Standard_True;
|
|
}
|
|
return Standard_False;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Recadre
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean BRepBlend_SurfRstLineBuilder::Recadre(Blend_SurfRstFunction& Func,
|
|
Blend_FuncInv& Finv,
|
|
math_Vector& Solinv,
|
|
Standard_Boolean& IsVtx,
|
|
Handle(Adaptor3d_HVertex)& Vtx)
|
|
{
|
|
math_Vector toler(1,4),infb(1,4),supb(1,4);
|
|
Finv.GetTolerance(toler,tolpoint3d);
|
|
Finv.GetBounds(infb,supb);
|
|
Solinv(1) = sol(3);
|
|
Solinv(2) = param;
|
|
Solinv(3) = sol(1);
|
|
Solinv(4) = sol(2);
|
|
|
|
math_FunctionSetRoot rsnld(Finv,toler,30);
|
|
rsnld.Perform(Finv,Solinv,infb,supb);
|
|
if (!rsnld.IsDone()) {
|
|
#ifdef OCCT_DEBUG
|
|
std::cout << "SurfRstLineBuilder :RSNLD not done "<< std::endl;
|
|
#endif
|
|
return Standard_False;
|
|
}
|
|
rsnld.Root(Solinv);
|
|
|
|
if(Finv.IsSolution(Solinv,tolpoint3d)){
|
|
gp_Pnt2d p2d(Solinv(3),Solinv(4));
|
|
TopAbs_State situ = domain1->Classify(p2d,tolpoint2d,0);
|
|
if ((situ != TopAbs_IN) && (situ != TopAbs_ON)) {
|
|
return Standard_False;
|
|
}
|
|
domain2->Initialize(rst);
|
|
domain2->InitVertexIterator();
|
|
IsVtx = !domain2->MoreVertex();
|
|
while (!IsVtx) {
|
|
Vtx = domain2->Vertex();
|
|
if (Abs(BRepBlend_BlendTool::Parameter(Vtx,rst)-Solinv(1)) <=
|
|
BRepBlend_BlendTool::Tolerance(Vtx,rst)) {
|
|
IsVtx = Standard_True;
|
|
}
|
|
else {
|
|
domain2->NextVertex();
|
|
IsVtx = !domain2->MoreVertex();
|
|
}
|
|
}
|
|
if (!domain2->MoreVertex()) {
|
|
IsVtx = Standard_False;
|
|
}
|
|
// The section is recalculated by direct resolution, otherwise
|
|
// incoherences between the parameter and the ground caused by yawn are returned.
|
|
|
|
math_Vector infbound(1,3),supbound(1,3);
|
|
math_Vector parinit(1,3),tolerance(1,3);
|
|
Func.GetTolerance(tolerance,tolpoint3d);
|
|
Func.GetBounds(infbound,supbound);
|
|
|
|
math_FunctionSetRoot rsnld2(Func,tolerance,30);
|
|
parinit(1) = Solinv(3);
|
|
parinit(2) = Solinv(4);
|
|
parinit(3) = Solinv(1);
|
|
Func.Set(Solinv(2));
|
|
rsnld2.Perform(Func,parinit,infbound,supbound);
|
|
if(!rsnld2.IsDone()) return Standard_False;
|
|
rsnld2.Root(parinit);
|
|
Solinv(3) = parinit(1);
|
|
Solinv(4) = parinit(2);
|
|
Solinv(1) = parinit(3);
|
|
return Standard_True;
|
|
}
|
|
return Standard_False;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Recadre
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean BRepBlend_SurfRstLineBuilder::Recadre(Blend_SurfPointFuncInv& FinvP,
|
|
math_Vector& Solinv,
|
|
Standard_Boolean& IsVtx,
|
|
Handle(Adaptor3d_HVertex)& Vtx)
|
|
{
|
|
// Le point.
|
|
gp_Pnt2d p2drst;
|
|
Standard_Real firstrst = rst->FirstParameter();
|
|
Standard_Real lastrst = rst->LastParameter();
|
|
Standard_Real wpoint = firstrst;
|
|
if((sol(3) - firstrst) > (lastrst - sol(3))) wpoint = lastrst;
|
|
p2drst = rst->Value(wpoint);
|
|
gp_Pnt thepoint = surf2->Value(p2drst.X(),p2drst.Y());
|
|
|
|
FinvP.Set(thepoint);
|
|
math_Vector toler(1,3),infb(1,3),supb(1,3);
|
|
FinvP.GetTolerance(toler,tolpoint3d);
|
|
FinvP.GetBounds(infb,supb);
|
|
Solinv(1) = param;
|
|
Solinv(2) = sol(1);
|
|
Solinv(3) = sol(2);
|
|
|
|
math_FunctionSetRoot rsnld(FinvP,toler,30);
|
|
rsnld.Perform(FinvP,Solinv,infb,supb);
|
|
if (!rsnld.IsDone()) {
|
|
#ifdef OCCT_DEBUG
|
|
std::cout << "SurfRstLineBuilder :RSNLD not done "<< std::endl;
|
|
#endif
|
|
return Standard_False;
|
|
}
|
|
rsnld.Root(Solinv);
|
|
|
|
if(FinvP.IsSolution(Solinv,tolpoint3d)){
|
|
gp_Pnt2d p2d(Solinv(2),Solinv(3));
|
|
TopAbs_State situ = domain1->Classify(p2d,tolpoint2d,0);
|
|
if ((situ != TopAbs_IN) && (situ != TopAbs_ON)) {
|
|
return Standard_False;
|
|
}
|
|
domain2->Initialize(rst);
|
|
domain2->InitVertexIterator();
|
|
IsVtx = !domain2->MoreVertex();
|
|
while (!IsVtx) {
|
|
Vtx = domain2->Vertex();
|
|
if (Abs(BRepBlend_BlendTool::Parameter(Vtx,rst)-wpoint) <=
|
|
BRepBlend_BlendTool::Tolerance(Vtx,rst)) {
|
|
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_SurfRstLineBuilder::Transition(const Standard_Boolean OnFirst,
|
|
const Handle(Adaptor2d_Curve2d)& 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.TangentOnS1();
|
|
else tgline = gp_Vec(prevprev.PointOnS(),previousP.PointOnS());
|
|
}
|
|
else {
|
|
surf2->D1(p2d.X(),p2d.Y(),pbid,d1u,d1v);
|
|
if(!computetranstionaveclacorde) tgline = previousP.TangentOnS2();
|
|
else tgline = gp_Vec(prevprev.PointOnC(),previousP.PointOnC());
|
|
}
|
|
|
|
tgrst.SetLinearForm(dp2d.X(),d1u,dp2d.Y(),d1v);
|
|
normale = d1u.Crossed(d1v);
|
|
|
|
IntSurf::MakeTransition(tgline,tgrst,normale,TLine,TArc);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : MakeExtremity
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BRepBlend_SurfRstLineBuilder::MakeExtremity(BRepBlend_Extremity& Extrem,
|
|
const Standard_Boolean OnFirst,
|
|
const Handle(Adaptor2d_Curve2d)& 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.PointOnS(),
|
|
sol(1),sol(2),
|
|
previousP.Parameter(),tolpoint3d);
|
|
if (!previousP.IsTangencyPoint())
|
|
Extrem.SetTangent(previousP.TangentOnS());
|
|
Iter = domain1;
|
|
}
|
|
else {
|
|
Extrem.SetValue(previousP.PointOnC(),
|
|
sol(3),
|
|
previousP.Parameter(),tolpoint3d);
|
|
if (!previousP.IsTangencyPoint())
|
|
Extrem.SetTangent(previousP.TangentOnC());
|
|
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()) {
|
|
Handle(Adaptor2d_Curve2d) arc = Iter->Value();
|
|
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 : CheckDeflectionOnSurf
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Blend_Status BRepBlend_SurfRstLineBuilder::CheckDeflectionOnSurf(const Blend_Point& CurPoint)
|
|
{
|
|
//Controls 3d of Blend_CSWalking.
|
|
|
|
//rule by tests in U4 corresponds to 11.478 d
|
|
const Standard_Real CosRef3D = 0.98;
|
|
Standard_Real Cosi=0, Cosi2=0;
|
|
Standard_Boolean curpointistangent = CurPoint.IsTangencyPoint();
|
|
Standard_Boolean prevpointistangent = previousP.IsTangencyPoint();
|
|
|
|
gp_Pnt Psurf = CurPoint.PointOnS();
|
|
gp_Vec Tgsurf;
|
|
if(!curpointistangent){
|
|
Tgsurf = CurPoint.TangentOnS();
|
|
}
|
|
gp_Pnt prevP = previousP.PointOnS();
|
|
gp_Vec prevTg;
|
|
if(!prevpointistangent){
|
|
prevTg = previousP.TangentOnS();
|
|
}
|
|
Standard_Real Norme,prevNorme = 0.;
|
|
gp_Vec Corde(prevP,Psurf);
|
|
Norme = Corde.SquareMagnitude();
|
|
// if(!curpointistangent) curNorme = Tgsurf.SquareMagnitude();
|
|
if(!prevpointistangent) prevNorme = prevTg.SquareMagnitude();
|
|
|
|
const Standard_Real toler3d = 0.01 * tolpoint3d;
|
|
if (Norme <= toler3d * toler3d){
|
|
// it can be necessary to force same point
|
|
return Blend_SamePoints;
|
|
}
|
|
if(!prevpointistangent){
|
|
if(prevNorme <= toler3d * toler3d) {
|
|
return Blend_SamePoints;
|
|
}
|
|
Cosi = sens*Corde*prevTg;
|
|
if (Cosi <0.) { // angle 3d>pi/2. --> return back
|
|
return Blend_Backward;
|
|
}
|
|
|
|
Cosi2 = Cosi * Cosi / prevNorme / Norme;
|
|
if (Cosi2 < CosRef3D) {
|
|
return Blend_StepTooLarge;
|
|
}
|
|
}
|
|
|
|
if(!curpointistangent){
|
|
// Check if it is necessary to control the sign of prevtg*Tgsurf
|
|
Cosi = sens*Corde*Tgsurf;
|
|
Cosi2 = Cosi * Cosi / Tgsurf.SquareMagnitude() / Norme;
|
|
if (Cosi2 < CosRef3D || Cosi < 0.) {
|
|
return Blend_StepTooLarge;
|
|
}
|
|
}
|
|
|
|
if(!curpointistangent && !prevpointistangent){
|
|
// Estimation of the current arrow
|
|
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) {
|
|
// not too great :
|
|
return Blend_StepTooLarge;
|
|
}
|
|
}
|
|
return Blend_OK;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : CheckDeflectionOnRst
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Blend_Status BRepBlend_SurfRstLineBuilder::CheckDeflectionOnRst(const Blend_Point& CurPoint)
|
|
{
|
|
//Controls 3D of Blend_CSWalking.
|
|
|
|
// rule by tests in U4 corresponds to 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.PointOnC();
|
|
gp_Vec Tgsurf;
|
|
if(!curpointistangent){
|
|
Tgsurf = CurPoint.TangentOnC();
|
|
}
|
|
gp_Pnt prevP = previousP.PointOnC();
|
|
gp_Vec prevTg;
|
|
if(!prevpointistangent){
|
|
prevTg = previousP.TangentOnC();
|
|
}
|
|
Standard_Real Norme,prevNorme = 0.;
|
|
gp_Vec Corde(prevP,Psurf);
|
|
Norme = Corde.SquareMagnitude();
|
|
// if(!curpointistangent) curNorme = Tgsurf.SquareMagnitude();
|
|
if(!prevpointistangent) prevNorme = prevTg.SquareMagnitude();
|
|
|
|
const Standard_Real toler3d = 0.01 * tolpoint3d;
|
|
if (Norme <= toler3d * toler3d){
|
|
// it can be necessary to force same point
|
|
return Blend_SamePoints;
|
|
}
|
|
if(!prevpointistangent){
|
|
if(prevNorme <= toler3d * toler3d) {
|
|
return Blend_SamePoints;
|
|
}
|
|
Cosi = sens*Corde*prevTg;
|
|
if (Cosi <0.) { // angle 3d>pi/2. --> return back
|
|
return Blend_Backward;
|
|
}
|
|
|
|
Cosi2 = Cosi * Cosi / prevNorme / Norme;
|
|
if (Cosi2 < CosRef3D) {
|
|
return Blend_StepTooLarge;
|
|
}
|
|
}
|
|
|
|
if(!curpointistangent){
|
|
// Check if it is necessary to control the sign of prevtg*Tgsurf
|
|
Cosi = sens*Corde*Tgsurf;
|
|
Cosi2 = Cosi * Cosi / Tgsurf.SquareMagnitude() / Norme;
|
|
if (Cosi2 < CosRef3D || Cosi < 0.) {
|
|
return Blend_StepTooLarge;
|
|
}
|
|
}
|
|
|
|
if(!curpointistangent && !prevpointistangent){
|
|
// Estimation of the current arrow
|
|
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) {
|
|
// not too great
|
|
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_SurfRstLineBuilder::TestArret(Blend_SurfRstFunction& Func,
|
|
const Standard_Boolean TestDeflection,
|
|
const Blend_Status State)
|
|
{
|
|
gp_Pnt pts,ptrst;
|
|
gp_Pnt2d pt2drst;
|
|
gp_Vec tgs,tgrst;
|
|
gp_Vec2d tg2ds,tg2drst;
|
|
Blend_Status StateS,StateRst;
|
|
IntSurf_TypeTrans tras = IntSurf_Undecided, trarst = IntSurf_Undecided;
|
|
Blend_Point curpoint;
|
|
|
|
if (Func.IsSolution(sol,tolpoint3d)) {
|
|
Standard_Boolean curpointistangent = Func.IsTangencyPoint();
|
|
pts = Func.PointOnS();
|
|
ptrst = Func.PointOnRst();
|
|
pt2drst = Func.Pnt2dOnRst();
|
|
if(curpointistangent){
|
|
curpoint.SetValue(pts,ptrst,param,sol(1),sol(2),
|
|
pt2drst.X(),pt2drst.Y(),sol(3));
|
|
}
|
|
else{
|
|
tgs = Func.TangentOnS();
|
|
tgrst = Func.TangentOnRst();
|
|
tg2ds = Func.Tangent2dOnS();
|
|
tg2drst = Func.Tangent2dOnRst();
|
|
|
|
curpoint.SetValue(pts,ptrst,param,sol(1),sol(2),
|
|
pt2drst.X(),pt2drst.Y(),sol(3),
|
|
tgs,tgrst,tg2ds,tg2drst);
|
|
}
|
|
if (TestDeflection) {
|
|
StateS = CheckDeflectionOnSurf(curpoint);
|
|
StateRst = CheckDeflectionOnRst(curpoint);
|
|
}
|
|
else {
|
|
StateS = StateRst = Blend_OK;
|
|
}
|
|
if (StateS == Blend_Backward) {
|
|
StateS = Blend_StepTooLarge;
|
|
rebrou= Standard_True;
|
|
}
|
|
if (StateRst == Blend_Backward) {
|
|
StateRst = Blend_StepTooLarge;
|
|
rebrou = Standard_True;
|
|
}
|
|
if (StateS == Blend_StepTooLarge ||
|
|
StateRst == Blend_StepTooLarge) {
|
|
return Blend_StepTooLarge;
|
|
}
|
|
|
|
if (!comptra && !curpointistangent) {
|
|
gp_Vec tgsecs,nors;
|
|
Func.Decroch(sol,nors,tgsecs);
|
|
nors.Normalize();
|
|
Standard_Real testra = tgsecs.Dot(nors.Crossed(tgs));
|
|
if (Abs(testra) > tolpoint3d) {
|
|
if (testra < 0.) {
|
|
tras = IntSurf_In;
|
|
}
|
|
else if (testra >0.) {
|
|
tras = IntSurf_Out;
|
|
}
|
|
gp_Pnt2d p2drstref; gp_Vec2d tg2drstref;
|
|
rst->D1(sol(3),p2drstref,tg2drstref);
|
|
testra = tg2drst.Dot(tg2drstref);
|
|
TopAbs_Orientation Or = domain2->Orientation(rst);
|
|
if (Abs(testra) > 1.e-8) {
|
|
if (testra < 0.) {
|
|
trarst = ConvOrToTra(TopAbs::Reverse(Or));
|
|
}
|
|
else if (testra >0.) {
|
|
trarst = ConvOrToTra(Or);
|
|
}
|
|
comptra = Standard_True;
|
|
line->Set(tras,trarst);
|
|
}
|
|
}
|
|
}
|
|
if (StateS == Blend_OK ||
|
|
StateRst == Blend_OK ) {
|
|
previousP = curpoint;
|
|
return State;
|
|
}
|
|
if (StateS == Blend_StepTooSmall &&
|
|
StateRst == 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_SurfRstLineBuilder::CheckInside(Blend_SurfRstFunction& Func,
|
|
TopAbs_State& SituOnC,
|
|
TopAbs_State& SituOnS,
|
|
Standard_Boolean& Decroch)
|
|
{
|
|
math_Vector tolerance(1,3);
|
|
Func.GetTolerance(tolerance,tolpoint3d);
|
|
//face pcurve.
|
|
Standard_Real w = sol(3);
|
|
if(w < rst->FirstParameter() - tolerance(3)||
|
|
w > rst->LastParameter() + tolerance(3)){
|
|
SituOnC = TopAbs_OUT;
|
|
}
|
|
else if (w > rst->FirstParameter() &&
|
|
w < rst->LastParameter()){
|
|
SituOnC = TopAbs_IN;
|
|
}
|
|
else SituOnC = TopAbs_ON;
|
|
|
|
//face surface
|
|
gp_Pnt2d p2d(sol(1),sol(2));
|
|
SituOnS = domain1->Classify(p2d,tolpoint2d,0);
|
|
|
|
//lost contact
|
|
gp_Vec tgs,nors;
|
|
Decroch = Func.Decroch(sol,tgs,nors);
|
|
|
|
return (SituOnC == TopAbs_IN && SituOnS == TopAbs_IN && !Decroch);
|
|
}
|
|
|