1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-05-01 10:26:12 +03:00
occt/src/BRepBlend/BRepBlend_RstRstLineBuilder.cxx
2012-03-05 19:23:40 +04:00

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);
}