0026937: Eliminate NO_CXX_EXCEPTION macro support
[occt.git] / src / IntPatch / IntPatch_PolyArc.cxx
CommitLineData
b311480e 1// Created on: 1993-01-27
2// Created by: Isabelle GRIGNON
3// Copyright (c) 1993-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
7fd59977 17
42cf5bc1 18#include <Adaptor2d_HCurve2d.hxx>
19#include <Bnd_Box2d.hxx>
20#include <gp_Pnt2d.hxx>
21#include <IntPatch_PolyArc.hxx>
7fd59977 22#include <Standard_ConstructionError.hxx>
23
24inline void MinMax (const Standard_Real a1, const Standard_Real a2,
25 Standard_Real& amin, Standard_Real& amax)
26{
27 if (a1 < a2) {
28 amin = a1; amax = a2;
29 }
30 else {
31 amin = a2; amax = a1;
32 }
33}
34
35IntPatch_PolyArc::IntPatch_PolyArc(const Handle(Adaptor2d_HCurve2d)& Line ,
36 const Standard_Integer NbSample,
37 const Standard_Real aPdeb,
38 const Standard_Real aPfin,
39 const Bnd_Box2d& BoxOtherPolygon):
40 brise(1,Max(1,NbSample)),
41 param(1,Max(1,NbSample)),
42 offsetx(0.0),
43 offsety(0.0)
44{
45 Standard_Real Pdeb = aPdeb;
46 Standard_Real Pfin = aPfin;
47 gp_Pnt2d p2d;
48
49 if (Pdeb == RealFirst() || Pfin == RealLast() || NbSample <= 1) {
9775fa61 50 throw Standard_ConstructionError();
7fd59977 51 }
52 //----------------------------------------------------------------------
53 //-- On veut eviter les cas ou le present polygone est beaucoup plus
54 //-- grand que l objet en second.
55 //--
56 //-- Par exemple lorsque l objet en second est une ligne de cheminement
57 //-- qui contient de nombreux segments (>>100), une fleche nulle
58 //-- et ce polygone quelques segments et une fleche qui contient
59 //-- toute la ligne de cheminement.
60 //--
61 //-- Dans ce cas (tout un polygone compris dans la zone d influence)
62 //-- les calculs deviennent tres longs (N2)
63 //----------------------------------------------------------------------
64 Standard_Integer IndexInf = NbSample+1;
65 Standard_Integer IndexSup = 0;
66
67 Standard_Real bx0,by0,bxmin,bxmax,bymin,bymax,r,r2;
68
69 BoxOtherPolygon.Get(bxmin,bymin,bxmax,bymax);
70 r=(bxmax-bxmin)+(bymax-bymin);
71 bx0=(bxmax+bxmin)*0.5;
72 by0=(bymax+bymin)*0.5;
73
74 Standard_Real Pas;
75 Standard_Real X,Y,Xs,Ys,Xm,Ym,XXs,YYs;
76
77 r*=0.8;
78 r2 = r*r*49.;
79 Standard_Integer nbloop=0;
80
81 do {
82 nbloop++;
83 Pas = (Pfin-Pdeb)/(NbSample-1);
84 param(1) = Pdeb;
85 Line->D0(Pdeb,p2d);
86 Xs = p2d.X(); Ys = p2d.Y();
87 brise(1).SetCoord(Xs,Ys);
88
9530af27 89 myBox.SetVoid();
7fd59977 90
9530af27 91 myBox.Add(brise(1));
92 myError =0.;
7fd59977 93
94 for (Standard_Integer i =2; i<=NbSample;i++) {
95 param(i) = Pdeb + (i-1)*Pas;
96 Line->D0(param(i),p2d);
97 X = p2d.X(); Y = p2d.Y();
98 brise(i).SetCoord(X,Y);
99 XXs = 0.5*(Xs+X);
100 YYs = 0.5*(Ys+Y);
101 //------------------------------------------------------------
102 //-- On recherche le debut et la fin de la zone significative
103 //------------------------------------------------------------
104 // MSV: (see cda 002 H2) if segment is too large (>>r) we have
105 // a risk to jump through BoxOtherPolygon, therefore we should
106 // check this condition if the first one is failure.
107 Standard_Boolean isMidPtInBox = (Abs(bx0-XXs) + Abs(by0-YYs)) < r;
108 Standard_Boolean isSegOut = Standard_True;
109 if(!isMidPtInBox) {
110 Standard_Real d = (X-Xs)*(X-Xs)+(Y-Ys)*(Y-Ys);
111 if (d > r2) {
112 Standard_Real xmin,xmax,ymin,ymax;
113 MinMax (Xs,X, xmin,xmax);
114 MinMax (Ys,Y, ymin,ymax);
115 isSegOut = (xmax < bxmin || xmin > bxmax ||
116 ymax < bymin || ymin > bymax);
117 }
118 }
119 if(isMidPtInBox || !isSegOut) {
120 // MSV: take the previous and the next segments too, because of
121 // we check only the middle point (see BUC60946)
122 //if(IndexInf>i) IndexInf=i-1;
123 //if(IndexSup<i) IndexSup=i;
124 if(IndexInf>i) IndexInf=Max(i-2,1);
125 if(IndexSup<i) IndexSup=Min(i+1,NbSample);
126 }
127
9530af27 128 myBox.Add(brise(i));
7fd59977 129 Line->D0(param(i)-Pas*0.5,p2d);
130 Xm = p2d.X() - XXs;
131 Ym = p2d.Y() - YYs;
132 Xm = Sqrt(Xm*Xm+Ym*Ym);
9530af27 133 myError =Max (myError , Xm);
7fd59977 134 Xs = X;
135 Ys = Y;
136 }
137 if(IndexInf > IndexSup) {
138 r+=r;
139 r2 = r*r*49.;
140 //-- cout<<" Le rayon : "<<r<<" est insuffisant "<<endl;
141 }
142 else {
143 //----------------------------------------------
144 //-- Si le nombre de points significatifs est
145 //-- insuffisant, on reechantillonne une fois
146 //-- encore
147 //----------------------------------------------
148 if((IndexSup-IndexInf)<(NbSample/2)) {
149 //-- cout<<" --- On remet ca entre les index "<<IndexInf<<" et "<<IndexSup<<endl;
150 nbloop = 10;
151 //if(IndexInf>1) IndexInf--;
152 //if(IndexSup<NbSample) IndexSup++;
153 Pdeb = param(IndexInf);
154 Pfin = param(IndexSup);
155 //IndexInf = IndexSup+1;
156 IndexInf = NbSample+1;
157 IndexSup = 0;
158 }
159 }
160 }
161 while((IndexInf > IndexSup) && nbloop<=10);
9530af27 162 myError*=1.2;
163 if(myError<0.00000001)
164 myError = 0.00000001;
165 myBox.Enlarge(myError);
7fd59977 166
9530af27 167 ferme = (Line->Value(aPdeb).Distance(Line->Value(aPfin)) <= 1e-7);
7fd59977 168}
169
7fd59977 170Standard_Boolean IntPatch_PolyArc::Closed() const { return ferme;}
171
172Standard_Integer IntPatch_PolyArc::NbPoints() const {return brise.Length();}
173
174gp_Pnt2d IntPatch_PolyArc::Point(const Standard_Integer Index ) const
175{
176 if(offsetx == 0.0 && offsety==0.0)
177 return(brise(Index));
178
179 const gp_Pnt2d& P = brise(Index);
180 return (gp_Pnt2d(P.X()+offsetx,P.Y()+offsety));
181}
182
183Standard_Real IntPatch_PolyArc::Parameter(const Standard_Integer Index ) const
184{ return param(Index);}
185
186
187void IntPatch_PolyArc::SetOffset(const Standard_Real ox,const Standard_Real oy) {
188 Standard_Real xmin,ymin,xmax,ymax,g;
9530af27 189 myBox.Get(xmin,ymin,xmax,ymax);
190 g = myBox.GetGap();
7fd59977 191
9530af27 192 myBox.SetVoid();
7fd59977 193
9530af27 194 myBox.Update(xmin-offsetx,ymin-offsety,
7fd59977 195 xmax-offsetx,ymax-offsety);
196 offsetx = ox;
197 offsety = oy;
9530af27 198 myBox.Update(xmin+offsetx,ymin+offsety,
7fd59977 199 xmax+offsetx,ymax+offsety);
9530af27 200 myBox.SetGap(g);
7fd59977 201}