0024171: Eliminate CLang compiler warning -Wreorder
[occt.git] / src / ShapeCustom / ShapeCustom_Curve2d.cxx
CommitLineData
b311480e 1// Created on: 2001-12-20
2// Created by: Pavel TELKOV
3// Copyright (c) 2001-2012 OPEN CASCADE SAS
4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
7fd59977 20
21// Last modification:
22
23#include <ShapeCustom_Curve2d.ixx>
24
25#include <Standard_ErrorHandler.hxx>
26#include <gp_Vec2d.hxx>
27#include <gp_Dir2d.hxx>
28#include <gp_Lin2d.hxx>
29#include <gp_Pnt2d.hxx>
30#include <ElCLib.hxx>
31#include <Precision.hxx>
32#include <Geom2d_BSplineCurve.hxx>
33#include <Geom2d_BezierCurve.hxx>
34
35
36//=======================================================================
37//function : GetLine
38//purpose : static
39//=======================================================================
40static gp_Lin2d GetLine (const gp_Pnt2d& P1, const gp_Pnt2d& P2,
41 const Standard_Real c1, Standard_Real& cf, Standard_Real& cl)
42{
43 gp_Vec2d avec (P1,P2);
44 gp_Dir2d adir (avec);
45 gp_Lin2d alin (P1,adir);
46 alin.SetLocation (ElCLib::Value (c1, alin));
47 cf = ElCLib::Parameter (alin, P1);
48 cl = ElCLib::Parameter (alin, P2);
49 return alin;
50}
51
52
53//=======================================================================
54//function : IsLinear
55//purpose : static
56//=======================================================================
57
58Standard_Boolean ShapeCustom_Curve2d::IsLinear(const TColgp_Array1OfPnt2d& thePoles,
59 const Standard_Real tolerance,
60 Standard_Real& Deviation)
61{
62 Standard_Integer nbPoles = thePoles.Length();
63 if(nbPoles < 2)
64 return Standard_False;
65
66 Standard_Real dMax = 0;
67 Standard_Integer iMax1=0,iMax2=0;
68
69 Standard_Integer i;
70 for(i = 1; i < nbPoles; i++)
71 for(Standard_Integer j = i+1; j <= nbPoles; j++) {
72 Standard_Real dist = thePoles(i).SquareDistance(thePoles(j));
73 if(dist > dMax) {
74 dMax = dist;
75 iMax1 = i;
76 iMax2 = j;
77 }
78 }
79
80 Standard_Real dPreci = Precision::PConfusion()*Precision::PConfusion();
81 if(dMax < dPreci)
82 return Standard_False;
83
84 Standard_Real tol2 = tolerance*tolerance;
85 gp_Vec2d avec (thePoles(iMax1),thePoles(iMax2));
86 gp_Dir2d adir (avec);
87 gp_Lin2d alin (thePoles(iMax1),adir);
88
89 Standard_Real aMax = 0.;
90 for(i = 1; i <= nbPoles; i++) {
91 Standard_Real dist = alin.SquareDistance(thePoles(i));
92 if(dist > tol2)
93 return Standard_False;
94 if(dist > aMax)
95 aMax = dist;
96 }
97 Deviation = sqrt(aMax);
98
99 return Standard_True;
100}
101
102//=======================================================================
103//function : ConvertToLine2d
104//purpose : static
105//=======================================================================
106
107Handle(Geom2d_Line) ShapeCustom_Curve2d::ConvertToLine2d (const Handle(Geom2d_Curve)& theCurve,
108 const Standard_Real c1,
109 const Standard_Real c2,
110 const Standard_Real theTolerance,
111 Standard_Real& cf,
112 Standard_Real& cl,
113 Standard_Real& theDeviation)
114{
115 Handle(Geom2d_Line) aLine2d;
116 gp_Pnt2d P1 = theCurve->Value(c1);
117 gp_Pnt2d P2 = theCurve->Value(c2);
118 Standard_Real dPreci = theTolerance*theTolerance;
119 if(P1.SquareDistance(P2) < dPreci)
120 return aLine2d; // it is not a line
121
122 Handle(Geom2d_BSplineCurve) bsc = Handle(Geom2d_BSplineCurve)::DownCast(theCurve);
123 if (!bsc.IsNull()) {
124 Standard_Integer nbPoles = bsc->NbPoles();
125 TColgp_Array1OfPnt2d Poles(1,nbPoles);
126 bsc->Poles(Poles);
127 if(!ShapeCustom_Curve2d::IsLinear(Poles,theTolerance,theDeviation))
128 return aLine2d; // non
129 gp_Lin2d alin = GetLine (P1,P2,c1,cf,cl);
130 aLine2d = new Geom2d_Line (alin);
131 return aLine2d;
132 }
133
134 Handle(Geom2d_BezierCurve) bzc = Handle(Geom2d_BezierCurve)::DownCast(theCurve);
135 if (!bzc.IsNull()) {
136 Standard_Integer nbPoles = bzc->NbPoles();
137 TColgp_Array1OfPnt2d Poles(1,nbPoles);
138 bzc->Poles(Poles);
139 if(!ShapeCustom_Curve2d::IsLinear(Poles,theTolerance,theDeviation))
140 return aLine2d; // non
141 gp_Lin2d alin = GetLine (P1,P2,c1,cf,cl);
142 aLine2d = new Geom2d_Line (alin);
143 return aLine2d;
144 }
145
146 return aLine2d;
147}
148
149//=======================================================================
150//function : SimplifyBSpline2d
151//purpose :
152//=======================================================================
153
154Standard_Boolean ShapeCustom_Curve2d::SimplifyBSpline2d (Handle(Geom2d_BSplineCurve)& theBSpline2d,
155 const Standard_Real theTolerance)
156{
157 Standard_Integer aInitNbK;
158 Standard_Integer NbK = aInitNbK = theBSpline2d->NbKnots();
159 // search knot to remove
160 Standard_Boolean IsToRemove = Standard_True;
161 Standard_Integer aKnotIndx = NbK-1;
162 while (IsToRemove && NbK > 2)
163 {
164 Standard_Integer aMult = theBSpline2d->Multiplicity(aKnotIndx);
165 Standard_Integer DegMult = theBSpline2d->Degree() - aMult;
166 if ((DegMult > 1) && theBSpline2d->IsCN(DegMult))
167 {
168 Standard_Real U = theBSpline2d->Knot(aKnotIndx);
169 gp_Vec2d aVec1 = theBSpline2d->LocalDN(U, aKnotIndx-1, aKnotIndx, DegMult);
170 gp_Vec2d aVec2 = theBSpline2d->LocalDN(U, aKnotIndx, aKnotIndx+1, DegMult);
171 // check the derivations are have the "same" angle
172 if (aVec1.IsParallel(aVec2, Precision::Angular()))
173 {
174 // remove knot
175 try
176 {
177 OCC_CATCH_SIGNALS
178 theBSpline2d->RemoveKnot(aKnotIndx,
179 aMult-1,
180 theTolerance);
181 }
182 catch(Standard_Failure)
183 {
184 }
185 }
186 }
187 aKnotIndx--;
188
189 NbK = theBSpline2d->NbKnots();
190 if (aKnotIndx == 1 || aKnotIndx == NbK)
191 IsToRemove = Standard_False;
192 }
193 return (aInitNbK > NbK);
194}