Loading files
// Created on: 1993-01-27
// Created by: Isabelle GRIGNON
// Copyright (c) 1993-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 <gp_Pnt2d.hxx>
#include <IntPatch_PolyArc.hxx>
#include <Standard_ConstructionError.hxx>
inline void MinMax(const double a1, const double a2, double& amin, double& amax)
{
if (a1 < a2)
{
amin = a1;
amax = a2;
}
else
{
amin = a2;
amax = a1;
}
}
IntPatch_PolyArc::IntPatch_PolyArc(const occ::handle<Adaptor2d_Curve2d>& Line,
const int NbSample,
const double aPdeb,
const double aPfin,
const Bnd_Box2d& BoxOtherPolygon)
: brise(1, std::max(1, NbSample)),
param(1, std::max(1, NbSample)),
offsetx(0.0),
offsety(0.0)
{
double Pdeb = aPdeb;
double Pfin = aPfin;
gp_Pnt2d p2d;
if (Pdeb == RealFirst() || Pfin == RealLast() || NbSample <= 1)
{
throw Standard_ConstructionError();
}
//----------------------------------------------------------------------
//-- On veut eviter les cas ou le present polygone est beaucoup plus
//-- grand que l objet en second.
//--
//-- Par exemple lorsque l objet en second est une ligne de cheminement
//-- qui contient de nombreux segments (>>100), une fleche nulle
//-- et ce polygone quelques segments et une fleche qui contient
//-- toute la ligne de cheminement.
//--
//-- Dans ce cas (tout un polygone compris dans la zone d influence)
//-- les calculs deviennent tres longs (N2)
//----------------------------------------------------------------------
int IndexInf = NbSample + 1;
int IndexSup = 0;
double bx0, by0, bxmin, bxmax, bymin, bymax, r, r2;
BoxOtherPolygon.Get(bxmin, bymin, bxmax, bymax);
r = (bxmax - bxmin) + (bymax - bymin);
bx0 = (bxmax + bxmin) * 0.5;
by0 = (bymax + bymin) * 0.5;
double Pas;
double X, Y, Xs, Ys, Xm, Ym, XXs, YYs;
r *= 0.8;
r2 = r * r * 49.;
int nbloop = 0;
do
{
nbloop++;
Pas = (Pfin - Pdeb) / (NbSample - 1);
param(1) = Pdeb;
Line->D0(Pdeb, p2d);
Xs = p2d.X();
Ys = p2d.Y();
brise(1).SetCoord(Xs, Ys);
myBox.SetVoid();
myBox.Add(brise(1));
myError = 0.;
for (int i = 2; i <= NbSample; i++)
{
param(i) = Pdeb + (i - 1) * Pas;
Line->D0(param(i), p2d);
X = p2d.X();
Y = p2d.Y();
brise(i).SetCoord(X, Y);
XXs = 0.5 * (Xs + X);
YYs = 0.5 * (Ys + Y);
//------------------------------------------------------------
//-- On recherche le debut et la fin de la zone significative
//------------------------------------------------------------
// MSV: (see cda 002 H2) if segment is too large (>>r) we have
// a risk to jump through BoxOtherPolygon, therefore we should
// check this condition if the first one is failure.
bool isMidPtInBox = (std::abs(bx0 - XXs) + std::abs(by0 - YYs)) < r;
bool isSegOut = true;
if (!isMidPtInBox)
{
double d = (X - Xs) * (X - Xs) + (Y - Ys) * (Y - Ys);
if (d > r2)
{
double xmin, xmax, ymin, ymax;
MinMax(Xs, X, xmin, xmax);
MinMax(Ys, Y, ymin, ymax);
isSegOut = (xmax < bxmin || xmin > bxmax || ymax < bymin || ymin > bymax);
}
}
if (isMidPtInBox || !isSegOut)
{
// MSV: take the previous and the next segments too, because of
// we check only the middle point (see BUC60946)
// if(IndexInf>i) IndexInf=i-1;
// if(IndexSup<i) IndexSup=i;
if (IndexInf > i)
{
IndexInf = std::max(i - 2, 1);
}
if (IndexSup < i)
{
IndexSup = std::min(i + 1, NbSample);
}
}
myBox.Add(brise(i));
Line->D0(param(i) - Pas * 0.5, p2d);
Xm = p2d.X() - XXs;
Ym = p2d.Y() - YYs;
Xm = std::sqrt(Xm * Xm + Ym * Ym);
myError = std::max(myError, Xm);
Xs = X;
Ys = Y;
}
if (IndexInf > IndexSup)
{
r += r;
r2 = r * r * 49.;
//-- std::cout<<" Le rayon : "<<r<<" est insuffisant "<<std::endl;
}
else
{
//----------------------------------------------
//-- Si le nombre de points significatifs est
//-- insuffisant, on reechantillonne une fois
//-- encore
//----------------------------------------------
if ((IndexSup - IndexInf) < (NbSample / 2))
{
//-- std::cout<<" --- On remet ca entre les index "<<IndexInf<<" et "<<IndexSup<<std::endl;
nbloop = 10;
// if(IndexInf>1) IndexInf--;
// if(IndexSup<NbSample) IndexSup++;
Pdeb = param(IndexInf);
Pfin = param(IndexSup);
// IndexInf = IndexSup+1;
IndexInf = NbSample + 1;
IndexSup = 0;
}
}
} while ((IndexInf > IndexSup) && nbloop <= 10);
myError *= 1.2;
if (myError < 0.00000001)
{
myError = 0.00000001;
}
myBox.Enlarge(myError);
ferme = (Line->Value(aPdeb).Distance(Line->Value(aPfin)) <= 1e-7);
}
bool IntPatch_PolyArc::Closed() const
{
return ferme;
}
int IntPatch_PolyArc::NbPoints() const
{
return brise.Length();
}
gp_Pnt2d IntPatch_PolyArc::Point(const int Index) const
{
if (offsetx == 0.0 && offsety == 0.0)
{
return (brise(Index));
}
const gp_Pnt2d& P = brise(Index);
return (gp_Pnt2d(P.X() + offsetx, P.Y() + offsety));
}
double IntPatch_PolyArc::Parameter(const int Index) const
{
return param(Index);
}
void IntPatch_PolyArc::SetOffset(const double ox, const double oy)
{
double xmin, ymin, xmax, ymax, g;
myBox.Get(xmin, ymin, xmax, ymax);
g = myBox.GetGap();
myBox.SetVoid();
myBox.Update(xmin - offsetx, ymin - offsety, xmax - offsetx, ymax - offsety);
offsetx = ox;
offsety = oy;
myBox.Update(xmin + offsetx, ymin + offsety, xmax + offsetx, ymax + offsety);
myBox.SetGap(g);
}
f2929057eThis file is pinned to the selected release. Download the original to open it in your design tool.