Loading files
// 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_CurvPointFuncInv.hxx>
#include <Blend_RstRstFunction.hxx>
#include <Blend_SurfCurvFuncInv.hxx>
#include <BRepBlend_BlendTool.hxx>
#include <BRepBlend_Line.hxx>
#include <BRepBlend_RstRstLineBuilder.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>
//=================================================================================================
BRepBlend_RstRstLineBuilder::BRepBlend_RstRstLineBuilder(
const occ::handle<Adaptor3d_Surface>& Surf1,
const occ::handle<Adaptor2d_Curve2d>& Rst1,
const occ::handle<Adaptor3d_TopolTool>& Domain1,
const occ::handle<Adaptor3d_Surface>& Surf2,
const occ::handle<Adaptor2d_Curve2d>& Rst2,
const occ::handle<Adaptor3d_TopolTool>& Domain2)
: done(false),
sol(1, 2),
surf1(Surf1),
domain1(Domain1),
surf2(Surf2),
domain2(Domain2),
rst1(Rst1),
rst2(Rst2),
tolpoint3d(0.0),
tolgui(0.0),
pasmax(0.0),
fleche(0.0),
param(0.0),
rebrou(false),
iscomplete(false),
comptra(false),
sens(0.0),
decrochdeb(Blend_NoDecroch),
decrochfin(Blend_NoDecroch)
{
}
//=================================================================================================
void BRepBlend_RstRstLineBuilder::Perform(Blend_RstRstFunction& Func,
Blend_SurfCurvFuncInv& Finv1,
Blend_CurvPointFuncInv& FinvP1,
Blend_SurfCurvFuncInv& Finv2,
Blend_CurvPointFuncInv& FinvP2,
const double Pdep,
const double Pmax,
const double MaxStep,
const double Tol3d,
const double TolGuide,
const math_Vector& ParDep,
const double Fleche,
const bool Appro)
{
done = false;
iscomplete = false;
comptra = false;
line = new BRepBlend_Line();
tolpoint3d = Tol3d;
tolgui = std::abs(TolGuide);
fleche = std::abs(Fleche);
rebrou = false;
pasmax = std::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, 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, siturst1, siturst2, decroch))
{
return;
}
}
else
{
sol = ParDep;
}
State = TestArret(Func, false, Blend_OK);
if (State != Blend_OK)
{
return;
}
// Update the line.
line->Append(previousP);
double U, V;
U = previousP.ParameterOnC1();
V = previousP.ParameterOnC2();
BRepBlend_Extremity ptf1(previousP.PointOnC1(), U, previousP.Parameter(), tolpoint3d);
BRepBlend_Extremity ptf2(previousP.PointOnC2(), V, previousP.Parameter(), tolpoint3d);
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 = true;
}
//=================================================================================================
bool BRepBlend_RstRstLineBuilder::PerformFirstSection(Blend_RstRstFunction& Func,
Blend_SurfCurvFuncInv& Finv1,
Blend_CurvPointFuncInv& FinvP1,
Blend_SurfCurvFuncInv& Finv2,
Blend_CurvPointFuncInv& FinvP2,
const double Pdep,
const double Pmax,
const math_Vector& ParDep,
const double Tol3d,
const double TolGuide,
const bool RecRst1,
const bool RecP1,
const bool RecRst2,
const bool RecP2,
double& Psol,
math_Vector& ParSol)
{
done = false;
iscomplete = false;
comptra = false;
line = new BRepBlend_Line();
tolpoint3d = Tol3d;
tolgui = std::abs(TolGuide);
rebrou = false;
if (Pmax - Pdep >= 0.)
{
sens = 1.;
}
else
{
sens = -1.;
}
bool recadp1, recadp2, recadrst1, recadrst2;
double wp1, wp2, wrst1, wrst2;
Blend_Status State = Blend_OnRst12;
double trst11 = 0., trst12 = 0., trst21 = 0., trst22 = 0.;
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);
occ::handle<Adaptor3d_HVertex> Vtxp1, Vtxp2, Vtxrst1, Vtxrst2, Vtxc;
bool IsVtxp1 = false, IsVtxp2 = false, IsVtxrst1 = false, IsVtxrst2 = false;
occ::handle<Adaptor2d_Curve2d> Arc;
wp1 = wp2 = wrst1 = wrst2 = 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 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 false;
}
// it is checked if the contact was lost or domain 1 was left
if (recadp1 && recadrst1)
{
if (sens * (wrst1 - wp1) > tolgui)
{ // at first one leaves the domain
wrst1 = wp1;
trst12 = solinvp1(2);
trst11 = BRepBlend_BlendTool::Parameter(Vtxp1, rst1);
IsVtxrst2 = IsVtxp1;
Vtxrst2 = Vtxp1;
recadrst1 = false;
}
else
{ // the contact is lost
trst11 = solinvrst1(3);
trst12 = solinvrst1(2);
recadp1 = 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);
}
// it is checked if the contact was lost or domain 2 was left
if (recadp2 && recadrst2)
{
if (sens * (wrst2 - wp2) > tolgui)
{ // at first one leaves the domain
wrst2 = wp2;
trst21 = solinvp2(2);
trst22 = BRepBlend_BlendTool::Parameter(Vtxp2, rst2);
IsVtxrst2 = IsVtxp2;
Vtxrst2 = Vtxp2;
recadrst2 = false;
}
else
{
trst22 = solinvrst2(3);
trst21 = solinvrst2(2);
recadp2 = 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);
}
// it is checked on which curve the contact is lost earlier
if (recadrst1 && recadrst2)
{
if (std::abs(wrst1 - wrst2) < tolgui)
{
State = Blend_OnRst12;
param = 0.5 * (wrst1 + wrst2);
sol(1) = trst11;
sol(2) = trst22;
}
else if (sens * (wrst1 - wrst2) < 0)
{
// contact lost on Rst1
State = Blend_OnRst1;
param = wrst1;
sol(1) = trst11;
sol(2) = trst12;
}
else
{
// contact lost on rst2
State = Blend_OnRst2;
param = wrst2;
sol(1) = trst21;
sol(2) = trst22;
}
Func.Set(param);
}
else if (recadrst1)
{
// ground on rst1
State = Blend_OnRst1;
param = wrst1;
sol(1) = trst11;
sol(2) = trst12;
Func.Set(param);
}
else if (recadrst2)
{
// ground on rst2
State = Blend_OnRst2;
param = wrst2;
sol(1) = trst21;
sol(2) = trst22;
Func.Set(param);
}
// it is checked on which curves one leaves first
else if (recadp1 && recadp2)
{
if (std::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 on Rst1
State = Blend_OnRst1;
param = wrst1;
sol(1) = trst11;
sol(2) = trst12;
}
else
{
// ground on rst2
State = Blend_OnRst2;
param = wrst2;
sol(1) = trst21;
sol(2) = trst22;
}
Func.Set(param);
}
else if (recadp1)
{
// ground on rst1
State = Blend_OnRst1;
param = wrst1;
sol(1) = trst11;
sol(2) = trst12;
Func.Set(param);
}
else if (recadp2)
{
// ground on rst2
State = Blend_OnRst2;
param = wrst2;
sol(1) = trst21;
sol(2) = trst22;
Func.Set(param);
}
State = TestArret(Func, false, State);
Psol = param;
ParSol = sol;
return true;
}
//=================================================================================================
bool BRepBlend_RstRstLineBuilder::Complete(Blend_RstRstFunction& Func,
Blend_SurfCurvFuncInv& Finv1,
Blend_CurvPointFuncInv& FinvP1,
Blend_SurfCurvFuncInv& Finv2,
Blend_CurvPointFuncInv& FinvP2,
const double Pmin)
{
if (!done)
{
throw StdFail_NotDone();
}
if (iscomplete)
{
return 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 = true;
return true;
}
//=======================================================================
// function : InternalPerform
// purpose : algorithm of processing without extremities
//=======================================================================
void BRepBlend_RstRstLineBuilder::InternalPerform(Blend_RstRstFunction& Func,
Blend_SurfCurvFuncInv& Finv1,
Blend_CurvPointFuncInv& FinvP1,
Blend_SurfCurvFuncInv& Finv2,
Blend_CurvPointFuncInv& FinvP2,
const double Bound)
{
double stepw = pasmax;
int nbp = line->NbPoints();
if (nbp >= 2)
{ // The last step is redone 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 = std::max(stepw, 100. * tolgui);
}
double parprec = param;
if (sens * (parprec - Bound) >= -tolgui)
{
return;
}
Blend_Status State = Blend_OnRst12;
double trst11 = 0., trst12 = 0., trst21 = 0., trst22 = 0.;
TopAbs_State situonc1 = TopAbs_UNKNOWN, situonc2 = TopAbs_UNKNOWN;
Blend_DecrochStatus decroch = Blend_NoDecroch;
bool Arrive, recadp1, recadp2, recadrst1, recadrst2, echecrecad;
double 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);
occ::handle<Adaptor3d_HVertex> Vtxp1, Vtxp2, Vtxrst1, Vtxrst2;
bool IsVtxp1 = false, IsVtxp2 = false, IsVtxrst1 = false, IsVtxrst2 = false;
BRepBlend_Extremity Extrst1, Extrst2;
// IntSurf_Transition Tline, Tarc;
Func.GetTolerance(tolerance, tolpoint3d);
Func.GetBounds(infbound, supbound);
math_FunctionSetRoot rsnld(Func, tolerance, 30);
parinit = sol;
Arrive = false;
param = parprec + sens * stepw;
if (sens * (param - Bound) > 0.)
{
stepw = sens * (Bound - parprec) * 0.5;
param = parprec + sens * stepw;
}
while (!Arrive)
{
bool bonpoint = true;
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 = false;
}
}
else
{
State = Blend_StepTooLarge;
bonpoint = false;
}
if (bonpoint)
{
wp1 = wp2 = wrst1 = wrst2 = Bound;
recadp1 = recadp2 = recadrst1 = recadrst2 = false;
echecrecad = false;
if (situonc1 != TopAbs_IN)
{
// pb inversion rst/rst
recadp1 = Recadre1(FinvP1, solinvp1, IsVtxp1, Vtxp1);
if (recadp1)
{
wp1 = solinvp1(1);
}
else
{
echecrecad = true;
}
}
if (situonc2 != TopAbs_IN)
{
// pb inversion point/surf
recadp2 = Recadre2(FinvP2, solinvp2, IsVtxp2, Vtxp2);
if (recadp2)
{
wp2 = solinvp2(1);
}
else
{
echecrecad = true;
}
}
if (decroch == Blend_DecrochRst1 || decroch == Blend_DecrochBoth)
{
// pb inversion rst1/surf1
recadrst1 = Recadre1(Func, Finv1, solinvrst1, IsVtxrst1, Vtxrst1);
if (recadrst1)
{
wrst1 = solinvrst1(1);
}
else
{
echecrecad = 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 = true;
}
}
decroch = Blend_NoDecroch;
if (recadp1 || recadp2 || recadrst1 || recadrst2)
{
echecrecad = false;
}
if (!echecrecad)
{
// it is checked if the contact was lost or domain 1 was left
if (recadp1 && recadrst1)
{
if (sens * (wrst1 - wp1) > tolgui)
{ // first one leaves the domain
wrst1 = wp1;
trst12 = solinvp1(2);
trst11 = BRepBlend_BlendTool::Parameter(Vtxp1, rst1);
IsVtxrst2 = IsVtxp1;
Vtxrst2 = Vtxp1;
recadrst1 = false;
}
else
{ // contact is lost
trst11 = solinvrst1(3);
trst12 = solinvrst1(2);
recadp1 = 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);
}
// it is checked if the contact was lost or domain 2 was left
if (recadp2 && recadrst2)
{
if (sens * (wrst2 - wp2) > tolgui)
{ // first one leaves the domain
wrst2 = wp2;
trst21 = solinvp2(2);
trst22 = BRepBlend_BlendTool::Parameter(Vtxp2, rst2);
IsVtxrst2 = IsVtxp2;
Vtxrst2 = Vtxp2;
recadrst2 = false;
}
else
{
trst22 = solinvrst2(3);
trst21 = solinvrst2(2);
recadp2 = 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);
}
// it is checked on which curve the contact is lost earlier
if (recadrst1 && recadrst2)
{
if (std::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)
{
// contact is lost on Rst1
State = Blend_OnRst1;
decroch = Blend_DecrochRst1;
param = wrst1;
sol(1) = trst11;
sol(2) = trst12;
}
else
{
// contact is lost on rst2
State = Blend_OnRst2;
decroch = Blend_DecrochRst2;
param = wrst2;
sol(1) = trst21;
sol(2) = trst22;
}
Func.Set(param);
}
else if (recadrst1)
{
// ground on rst1
State = Blend_OnRst1;
decroch = Blend_DecrochRst1;
param = wrst1;
sol(1) = trst11;
sol(2) = trst12;
Func.Set(param);
}
else if (recadrst2)
{
// ground on rst2
State = Blend_OnRst2;
decroch = Blend_DecrochRst2;
param = wrst2;
sol(1) = trst21;
sol(2) = trst22;
Func.Set(param);
}
// it is checked on which curve the contact is lost earlier
else if (recadp1 && recadp2)
{
if (std::abs(wrst1 - wrst2) < tolgui)
{
State = Blend_OnRst12;
param = 0.5 * (wrst1 + wrst2);
sol(1) = trst11;
sol(2) = trst22;
}
else if (sens * (wrst1 - wrst2) < 0)
{
// ground on Rst1
State = Blend_OnRst1;
param = wrst1;
sol(1) = trst11;
sol(2) = trst12;
}
else
{
// ground on rst2
State = Blend_OnRst2;
param = wrst2;
sol(1) = trst21;
sol(2) = trst22;
}
Func.Set(param);
}
else if (recadp1)
{
// ground on rst1
State = Blend_OnRst1;
param = wrst1;
sol(1) = trst11;
sol(2) = trst12;
Func.Set(param);
}
else if (recadp2)
{
// ground on rst2
State = Blend_OnRst2;
param = wrst2;
sol(1) = trst21;
sol(2) = trst22;
Func.Set(param);
}
else
{
State = Blend_OK;
}
State = TestArret(Func, true, State);
}
else
{
// reframing failed. Leave with PointsConfondus
#ifdef OCCT_DEBUG
std::cout << "reframing failed" << std::endl;
#endif
State = Blend_SamePoints;
}
}
switch (State)
{
case Blend_OK: {
// Update the line.
if (sens > 0.)
{
line->Append(previousP);
}
else
{
line->Prepend(previousP);
}
parinit = sol;
parprec = param;
if (param == Bound)
{
Arrive = true;
Extrst1.SetValue(previousP.PointOnC1(),
previousP.ParameterOnC1(),
previousP.Parameter(),
tolpoint3d);
MakeExtremity(Extrst2, false, rst2, sol(2), IsVtxrst2, Vtxrst2);
// Show that end is on Bound.
}
else
{
param = param + sens * stepw;
if (sens * (param - Bound) > -tolgui)
{
param = Bound;
}
}
}
break;
case Blend_StepTooLarge: {
stepw = stepw / 2.;
if (std::abs(stepw) < tolgui)
{
Extrst1.SetValue(previousP.PointOnC1(),
previousP.ParameterOnC1(),
previousP.Parameter(),
tolpoint3d);
Extrst2.SetValue(previousP.PointOnC2(),
previousP.ParameterOnC2(),
previousP.Parameter(),
tolpoint3d);
Arrive = true;
#ifdef OCCT_DEBUG
if (line->NbPoints() >= 2)
{
// Show that there is a stop during processing
std::cout << "No more advancement in the processing" << std::endl;
}
#endif
}
else
{
param = parprec + sens * stepw; // there is no risk to exceed Bound.
}
}
break;
case Blend_StepTooSmall: {
// Update the line.
if (sens > 0.)
{
line->Append(previousP);
}
else
{
line->Prepend(previousP);
}
parinit = sol;
parprec = param;
stepw = std::min(1.5 * stepw, pasmax);
if (param == Bound)
{
Arrive = true;
Extrst1.SetValue(previousP.PointOnC1(),
previousP.ParameterOnC1(),
previousP.Parameter(),
tolpoint3d);
MakeExtremity(Extrst2, false, rst2, sol(2), IsVtxrst2, Vtxrst2);
// Indicate that end is on Bound.
}
else
{
param = param + sens * stepw;
if (sens * (param - Bound) > -tolgui)
{
param = Bound;
}
}
}
break;
case Blend_OnRst1: {
if (sens > 0.)
{
line->Append(previousP);
}
else
{
line->Prepend(previousP);
}
MakeExtremity(Extrst1, true, rst1, sol(1), IsVtxrst1, Vtxrst1);
MakeExtremity(Extrst2, false, rst2, sol(2), IsVtxrst2, Vtxrst2);
Arrive = true;
}
break;
case Blend_OnRst2: {
if (sens > 0.)
{
line->Append(previousP);
}
else
{
line->Prepend(previousP);
}
MakeExtremity(Extrst1, true, rst1, sol(1), IsVtxrst1, Vtxrst1);
MakeExtremity(Extrst2, false, rst2, sol(2), IsVtxrst2, Vtxrst2);
Arrive = true;
}
break;
case Blend_OnRst12: {
if (sens > 0.)
{
line->Append(previousP);
}
else
{
line->Prepend(previousP);
}
MakeExtremity(Extrst1, true, rst1, sol(1), IsVtxrst1, Vtxrst1);
MakeExtremity(Extrst2, false, rst2, sol(2), IsVtxrst2, Vtxrst2);
Arrive = true;
}
break;
case Blend_SamePoints: {
// Stop
#ifdef OCCT_DEBUG
std::cout << " Mixed points in the processing" << std::endl;
#endif
Extrst1.SetValue(previousP.PointOnC1(),
previousP.ParameterOnC1(),
previousP.Parameter(),
tolpoint3d);
Extrst2.SetValue(previousP.PointOnC2(),
previousP.ParameterOnC2(),
previousP.Parameter(),
tolpoint3d);
Arrive = true;
}
break;
default:
break;
}
if (Arrive)
{
if (sens > 0.)
{
line->SetEndPoints(Extrst1, Extrst2);
decrochfin = decroch;
}
else
{
line->SetStartPoints(Extrst1, Extrst2);
decrochdeb = decroch;
}
}
}
}
//=================================================================================================
bool BRepBlend_RstRstLineBuilder::Recadre1(Blend_RstRstFunction& Func,
Blend_SurfCurvFuncInv& Finv,
math_Vector& Solinv,
bool& IsVtx,
occ::handle<Adaptor3d_HVertex>& Vtx)
{
math_Vector toler(1, 3), infb(1, 3), supb(1, 3);
Finv.GetTolerance(toler, tolpoint3d);
Finv.GetBounds(infb, supb);
Solinv(1) = param;
Solinv(2) = sol(2);
Solinv(3) = sol(1);
// The point where contact is not lost is found
math_FunctionSetRoot rsnld(Finv, toler, 30);
rsnld.Perform(Finv, Solinv, infb, supb);
if (!rsnld.IsDone())
{
#ifdef OCCT_DEBUG
std::cout << "RSNLD not done " << std::endl << std::endl;
#endif
return false;
}
rsnld.Root(Solinv);
// It is necessary to check if the function value meets the
// second restriction
if (Finv.IsSolution(Solinv, tolpoint3d))
{
double w = Solinv(2);
if (w < rst2->FirstParameter() - toler(2) || w > rst2->LastParameter() + toler(2))
{
return false;
}
// it is checked if it is on a Vertex
domain1->Initialize(rst1);
domain1->InitVertexIterator();
IsVtx = !domain1->MoreVertex();
while (!IsVtx)
{
Vtx = domain1->Vertex();
if (std::abs(BRepBlend_BlendTool::Parameter(Vtx, rst1) - Solinv(3))
<= BRepBlend_BlendTool::Tolerance(Vtx, rst1))
{
IsVtx = true;
}
else
{
domain1->NextVertex();
IsVtx = !domain1->MoreVertex();
}
}
if (!domain1->MoreVertex())
{
IsVtx = false;
}
// The section is recalculated by direct solution, otherwise return
// incoherences between the parameter and the ground caused by yawn.
math_Vector infbound(1, 2), supbound(1, 2);
math_Vector parinit(1, 2), tolerance(1, 2);
Func.GetTolerance(tolerance, tolpoint3d);
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 false;
}
rsnld2.Root(parinit);
Solinv(2) = parinit(2);
Solinv(3) = parinit(1);
return true;
}
return false;
}
//=================================================================================================
bool BRepBlend_RstRstLineBuilder::Recadre2(Blend_RstRstFunction& Func,
Blend_SurfCurvFuncInv& Finv,
math_Vector& Solinv,
bool& IsVtx,
occ::handle<Adaptor3d_HVertex>& Vtx)
{
math_Vector toler(1, 3), infb(1, 3), supb(1, 3);
Finv.GetTolerance(toler, tolpoint3d);
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())
{
#ifdef OCCT_DEBUG
std::cout << "RSNLD not done " << std::endl << std::endl;
#endif
return false;
}
rsnld.Root(Solinv);
// It is necessary to check the value of the function
if (Finv.IsSolution(Solinv, tolpoint3d))
{
double w = Solinv(2);
if (w < rst1->FirstParameter() - toler(2) || w > rst1->LastParameter() + toler(2))
{
return false;
}
domain2->Initialize(rst2);
domain2->InitVertexIterator();
IsVtx = !domain2->MoreVertex();
while (!IsVtx)
{
Vtx = domain2->Vertex();
if (std::abs(BRepBlend_BlendTool::Parameter(Vtx, rst2) - Solinv(3))
<= BRepBlend_BlendTool::Tolerance(Vtx, rst2))
{
IsVtx = true;
}
else
{
domain2->NextVertex();
IsVtx = !domain2->MoreVertex();
}
}
if (!domain2->MoreVertex())
{
IsVtx = false;
}
// The section is recalculated by direct solution, otherwise return
// incoherences between the parameter and the ground caused by yawn.
math_Vector infbound(1, 2), supbound(1, 2);
math_Vector parinit(1, 2), tolerance(1, 2);
Func.GetTolerance(tolerance, tolpoint3d);
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 false;
}
rsnld2.Root(parinit);
Solinv(2) = parinit(1);
Solinv(3) = parinit(2);
return true;
}
return false;
}
//=================================================================================================
bool BRepBlend_RstRstLineBuilder::Recadre1(Blend_CurvPointFuncInv& FinvP,
math_Vector& Solinv,
bool& IsVtx,
occ::handle<Adaptor3d_HVertex>& Vtx)
{
// One is located on the last or the first point, following the
// direction of processing.
gp_Pnt2d p2drst1;
double firstrst1 = rst1->FirstParameter();
double lastrst1 = rst1->LastParameter();
double 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, tolpoint3d);
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())
{
#ifdef OCCT_DEBUG
std::cout << "RSNLD not done " << std::endl << std::endl;
#endif
return false;
}
rsnld.Root(Solinv);
if (FinvP.IsSolution(Solinv, tolpoint3d))
{
gp_Pnt2d p2drst2 = rst2->Value(Solinv(2));
TopAbs_State situ = domain2->Classify(p2drst2, toler(2), false);
if ((situ != TopAbs_IN) && (situ != TopAbs_ON))
{
return false;
}
domain1->Initialize(rst1);
domain1->InitVertexIterator();
IsVtx = !domain1->MoreVertex();
while (!IsVtx)
{
Vtx = domain1->Vertex();
if (std::abs(BRepBlend_BlendTool::Parameter(Vtx, rst1) - upoint)
<= BRepBlend_BlendTool::Tolerance(Vtx, rst1))
{
IsVtx = true;
}
else
{
domain1->NextVertex();
IsVtx = !domain1->MoreVertex();
}
}
if (!domain1->MoreVertex())
{
IsVtx = false;
}
return true;
}
return false;
}
//=================================================================================================
bool BRepBlend_RstRstLineBuilder::Recadre2(Blend_CurvPointFuncInv& FinvP,
math_Vector& Solinv,
bool& IsVtx,
occ::handle<Adaptor3d_HVertex>& Vtx)
{
// One is located on the last or the first point, following the
// direction of processing.
gp_Pnt2d p2drst2;
double firstrst2 = rst2->FirstParameter();
double lastrst2 = rst2->LastParameter();
double 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, tolpoint3d);
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())
{
#ifdef OCCT_DEBUG
std::cout << "RSNLD not done " << std::endl << std::endl;
#endif
return false;
}
rsnld.Root(Solinv);
if (FinvP.IsSolution(Solinv, tolpoint3d))
{
gp_Pnt2d p2drst1 = rst1->Value(Solinv(2));
TopAbs_State situ = domain1->Classify(p2drst1, toler(2), false);
if ((situ != TopAbs_IN) && (situ != TopAbs_ON))
{
return false;
}
domain2->Initialize(rst2);
domain2->InitVertexIterator();
IsVtx = !domain2->MoreVertex();
while (!IsVtx)
{
Vtx = domain2->Vertex();
if (std::abs(BRepBlend_BlendTool::Parameter(Vtx, rst2) - vpoint)
<= BRepBlend_BlendTool::Tolerance(Vtx, rst2))
{
IsVtx = true;
}
else
{
domain2->NextVertex();
IsVtx = !domain2->MoreVertex();
}
}
if (!domain2->MoreVertex())
{
IsVtx = false;
}
return true;
}
return false;
}
//=================================================================================================
void BRepBlend_RstRstLineBuilder::Transition(const bool OnFirst,
const occ::handle<Adaptor2d_Curve2d>& Arc,
const double Param,
IntSurf_Transition& TLine,
IntSurf_Transition& TArc)
{
bool computetranstionaveclacorde = false;
gp_Vec tgline;
Blend_Point prevprev;
if (previousP.IsTangencyPoint())
{
if (line->NbPoints() < 2)
{
return;
}
computetranstionaveclacorde = true;
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 : produce the extremity of a curve
//=======================================================================
void BRepBlend_RstRstLineBuilder::MakeExtremity(BRepBlend_Extremity& Extrem,
const bool OnFirst,
const occ::handle<Adaptor2d_Curve2d>& Arc,
const double Param,
const bool IsVtx,
const occ::handle<Adaptor3d_HVertex>& Vtx)
{
IntSurf_Transition Tline, Tarc;
double prm;
occ::handle<Adaptor3d_TopolTool> Iter;
if (OnFirst)
{
Extrem.SetValue(previousP.PointOnC1(), sol(1), previousP.Parameter(), tolpoint3d);
if (!previousP.IsTangencyPoint())
{
Extrem.SetTangent(previousP.TangentOnC1());
}
Iter = domain1;
}
else
{
Extrem.SetValue(previousP.PointOnC2(), sol(2), previousP.Parameter(), tolpoint3d);
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())
{
occ::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();
}
}
}
//=================================================================================================
Blend_Status BRepBlend_RstRstLineBuilder::CheckDeflectionOnRst1(const Blend_Point& CurPoint)
{
// Controls 3d of Blend_CSWalking.
// rule by tests in U4 corresponds to 11.478
const double CosRef3D = 0.98;
double Cosi, Cosi2;
bool curpointistangent = CurPoint.IsTangencyPoint();
bool 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();
}
double Norme;
double prevNorme = 0.;
gp_Vec Corde(prevP, Psurf);
Norme = Corde.SquareMagnitude();
if (!prevpointistangent)
{
prevNorme = prevTg.SquareMagnitude();
}
const double toler3d = 0.01 * tolpoint3d;
if (Norme <= toler3d * toler3d)
{
// it can be necessary to force the 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
double 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;
}
//=================================================================================================
Blend_Status BRepBlend_RstRstLineBuilder::CheckDeflectionOnRst2(const Blend_Point& CurPoint)
{
// 3D Controls of Blend_CSWalking.
// rule by tests in U4 corresponding to 11.478 d
const double CosRef3D = 0.98;
double Cosi, Cosi2;
bool curpointistangent = CurPoint.IsTangencyPoint();
bool 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();
}
double Norme;
double prevNorme = 0.;
gp_Vec Corde(prevP, Psurf);
Norme = Corde.SquareMagnitude();
if (!prevpointistangent)
{
prevNorme = prevTg.SquareMagnitude();
}
const double toler3d = 0.01 * tolpoint3d;
if (Norme <= toler3d * toler3d)
{
// it can be necessary to force the 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
double 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;
}
//=================================================================================================
Blend_Status BRepBlend_RstRstLineBuilder::TestArret(Blend_RstRstFunction& Func,
const bool 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;
IntSurf_TypeTrans trarst1 = IntSurf_Undecided, trarst2 = IntSurf_Undecided;
Blend_Point curpoint;
if (Func.IsSolution(sol, tolpoint3d))
{
bool 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 = true;
}
if (StateRst2 == Blend_Backward)
{
StateRst2 = Blend_StepTooLarge;
rebrou = 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);
double testra = tg2drst1.Dot(tg2drstref);
TopAbs_Orientation Or = domain1->Orientation(rst1);
if (std::abs(testra) > tolpoint3d)
{
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 (std::abs(testra) > tolpoint3d)
{
if (testra < 0.)
{
trarst2 = ConvOrToTra(TopAbs::Reverse(Or));
}
else if (testra > 0.)
{
trarst2 = ConvOrToTra(Or);
}
comptra = 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;
}
//=================================================================================================
bool BRepBlend_RstRstLineBuilder::CheckInside(Blend_RstRstFunction& Func,
TopAbs_State& SituOnC1,
TopAbs_State& SituOnC2,
Blend_DecrochStatus& Decroch)
{
// bool inside = true;
math_Vector tolerance(1, 2);
Func.GetTolerance(tolerance, tolpoint3d);
// face pcurve 1.
double 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;
}
// face 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;
}
// lost contact
gp_Vec tgrst1, norst1, tgrst2, norst2;
Decroch = Func.Decroch(sol, tgrst1, norst1, tgrst2, norst2);
return (SituOnC1 == TopAbs_IN && SituOnC2 == TopAbs_IN && Decroch == Blend_NoDecroch);
}
f2929057eThis file is pinned to the selected release. Download the original to open it in your design tool.