0024157: Parallelization of assembly part of BO
[occt.git] / src / ShapeUpgrade / ShapeUpgrade_ConvertCurve2dToBezier.cxx
CommitLineData
b311480e 1// Created on: 1999-05-13
2// Created by: data exchange team
3// Copyright (c) 1999-1999 Matra Datavision
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
7fd59977 21
22
23#include <ShapeUpgrade_ConvertCurve2dToBezier.ixx>
24#include <Precision.hxx>
25#include <Geom2d_TrimmedCurve.hxx>
26#include <Geom2d_BezierCurve.hxx>
27#include <ShapeExtend.hxx>
28#include <Geom2d_Line.hxx>
29#include <TColgp_Array1OfPnt2d.hxx>
30#include <Geom2d_BSplineCurve.hxx>
31#include <Geom2d_Conic.hxx>
32#include <Geom_Curve.hxx>
33#include <Geom2dConvert_ApproxCurve.hxx>
34#include <Geom2dConvert.hxx>
35#include <Geom2dConvert_BSplineCurveToBezierCurve.hxx>
36#include <TColStd_Array1OfReal.hxx>
37#include <TColGeom2d_HArray1OfCurve.hxx>
38#include <GeomTools.hxx>
39#include <ShapeCustom_Curve2d.hxx>
40
41ShapeUpgrade_ConvertCurve2dToBezier::ShapeUpgrade_ConvertCurve2dToBezier()
42{
43 mySegments = new TColGeom2d_HSequenceOfCurve;
44 mySplitParams = new TColStd_HSequenceOfReal;
45}
46
47static Handle(Geom2d_BezierCurve) MakeBezier2d(const Handle(Geom2d_Curve)& theCurve2d,
48 const Standard_Real theFirst,
49 const Standard_Real theLast)
50{
51 TColgp_Array1OfPnt2d poles(1,2);
52 poles(1) = theCurve2d->Value(theFirst);
53 poles(2) = theCurve2d->Value(theLast);
54 Handle(Geom2d_BezierCurve) bezier = new Geom2d_BezierCurve(poles);
55 return bezier;
56}
57
58
59//=======================================================================
60//function : Compute
61//purpose :
62//=======================================================================
63
64void ShapeUpgrade_ConvertCurve2dToBezier::Compute()
65{
66 mySegments->Clear();
67 mySplitParams->Clear();
68 Standard_Real precision = Precision::PConfusion();
69 Standard_Real First = mySplitValues->Value(1);
70 Standard_Real Last = mySplitValues->Value(mySplitValues->Length());
71
72 // PTV Try to create line2d from myCurve
73 if ( myCurve->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve)) ||
74 myCurve->IsKind(STANDARD_TYPE(Geom2d_BezierCurve)) )
75 {
76 // static function`s code getted from ShapeConvert
77 Standard_Real tmpF, tmpL, aDeviation;
78 Handle(Geom2d_Line) aTmpLine2d =
79 ShapeCustom_Curve2d::ConvertToLine2d(myCurve, First, Last, Precision::Approximation(),
80 tmpF, tmpL, aDeviation);
81 if (!aTmpLine2d.IsNull() && (aDeviation <= Precision::Approximation()) )
82 {
83 Handle(Geom2d_BezierCurve) bezier = MakeBezier2d(aTmpLine2d, tmpF, tmpL);
84 mySegments->Append(bezier);
85 mySplitParams->Append(First);
86 mySplitParams->Append(Last);
87 myNbCurves = mySplitValues->Length()-1;
88 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE1);
89 return;
90 }
91 }
92
93 if(myCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) {
94 Handle(Geom2d_TrimmedCurve) tmp = Handle(Geom2d_TrimmedCurve)::DownCast (myCurve);
95 Handle(Geom2d_Curve) BasCurve = tmp->BasisCurve();
96 ShapeUpgrade_ConvertCurve2dToBezier converter;
97 //converter.Init(BasCurve,Max(First,BasCurve->FirstParameter()),Min(Last,BasCurve->LastParameter())); //???
98 converter.Init(BasCurve,First,Last);
99 converter.SetSplitValues(mySplitValues);
100 converter.Compute();
101 mySplitValues->Clear();
102 mySplitValues->ChangeSequence() = converter.SplitValues()->Sequence();
103 myNbCurves = mySplitValues->Length()-1;
104 myStatus |= converter.myStatus;
105 mySegments->ChangeSequence() = converter.Segments()->Sequence();
106 mySplitParams->ChangeSequence() = converter.SplitParams()->Sequence();
107 return;
108 }
109 else if(myCurve->IsKind(STANDARD_TYPE(Geom2d_BezierCurve))) {
110 Handle(Geom2d_BezierCurve) bezier = Handle(Geom2d_BezierCurve)::DownCast (myCurve);
111 myNbCurves = mySplitValues->Length()-1;
112 mySplitParams->Append(First);
113 mySplitParams->Append(Last);
114 if(First < precision && Last > 1 - precision) {
115 mySegments->Append(bezier);
116 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
117 } else {
118 Handle(Geom2d_BezierCurve) besNew = Handle(Geom2d_BezierCurve)::DownCast(bezier->Copy());
119 besNew->Segment(First,Last);
120 mySegments->Append(besNew);
121 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE2);
122 }
123 return;
124 }
125 else if(myCurve->IsKind(STANDARD_TYPE(Geom2d_Line))) {
126 Handle(Geom2d_Line) aLine2d = Handle(Geom2d_Line)::DownCast(myCurve);
127 Handle(Geom2d_BezierCurve) bezier = MakeBezier2d(aLine2d, First, Last);
128 mySegments->Append(bezier);
129 mySplitParams->Append(First);
130 mySplitParams->Append(Last);
131 myNbCurves = mySplitValues->Length()-1;
132 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE1);
133 return;
134 }
135 else {
136 Handle(Geom2d_BSplineCurve) aBSpline2d;
137 Standard_Real Shift = 0.;
138 if(myCurve->IsKind(STANDARD_TYPE(Geom2d_Conic))) {
139 Handle(Geom2d_TrimmedCurve) tcurve = new Geom2d_TrimmedCurve(myCurve,First,Last); //protection agains parabols ets
140 Geom2dConvert_ApproxCurve approx (tcurve, Precision::Approximation(),
141 GeomAbs_C1, 100, 6 );
142 if ( approx.HasResult() )
143 aBSpline2d = Handle(Geom2d_BSplineCurve)::DownCast(approx.Curve());
144 else
145 aBSpline2d = Geom2dConvert::CurveToBSplineCurve(tcurve,Convert_QuasiAngular);
146
147 Shift = First - aBSpline2d->FirstParameter();
148 First = aBSpline2d->FirstParameter();
149 Last = aBSpline2d->LastParameter();
150 }
151 else if(!myCurve->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) {
152 aBSpline2d = Geom2dConvert::CurveToBSplineCurve(myCurve,Convert_QuasiAngular);
153 }
154 else
155 aBSpline2d = Handle(Geom2d_BSplineCurve)::DownCast(myCurve);
156
157 Standard_Real bf = aBSpline2d->FirstParameter();
158 Standard_Real bl = aBSpline2d->LastParameter();
159 if(Abs(First-bf) < precision)
160 First = bf;
161 if(Abs(Last-bl) < precision)
162 Last = bl;
163 if(First < bf){
164#ifdef DEB
165 cout <<"Warning: The range of the edge exceeds the pcurve domain" <<endl;
166#endif
167 First = bf;
168 mySplitValues->SetValue(1,First);
169 }
170 if(Last > bl){
171#ifdef DEB
172 cout <<"Warning: The range of the edge exceeds the pcurve domain" <<endl;
173#endif
174 Last = bl;
175 mySplitValues->SetValue(mySplitValues->Length(),Last);
176 }
177
178 // PTV 20.12.2001 Try to simpify BSpline Curve
179 ShapeCustom_Curve2d::SimplifyBSpline2d (aBSpline2d, Precision::Approximation());
180
181 Geom2dConvert_BSplineCurveToBezierCurve tool(aBSpline2d,First,Last,precision);
182 Standard_Integer nbArcs = tool.NbArcs();
183 TColStd_Array1OfReal knots(1,nbArcs+1);
184 tool.Knots(knots);
185 mySplitParams->Append(First+Shift);
186 Standard_Integer j; // svv Jan 10 2000 : porting on DEC
187
188 Standard_Real newFirst = First+Shift;
189 Standard_Real newLast = First+Shift;
190
191 for(j = 1; j <=nbArcs; j++) {
192 Standard_Real nextKnot = knots(j+1)+Shift;
193 if(nextKnot - mySplitParams->Value(mySplitParams->Length()) > precision) {
194 Handle(Geom2d_Curve) aCrv2d = tool.Arc(j);
195 if ( aCrv2d->IsKind(STANDARD_TYPE(Geom2d_BezierCurve)) )
196 {
197 newFirst = newLast;
198 newLast = nextKnot;
199 Standard_Real tmpF, tmpL, aDeviation;
200 Handle(Geom2d_Line) aTmpLine2d =
201 ShapeCustom_Curve2d::ConvertToLine2d(aCrv2d, newFirst, newLast, Precision::Approximation(),
202 tmpF, tmpL, aDeviation);
203 if (!aTmpLine2d.IsNull() && (aDeviation <= Precision::Approximation()) )
204 {
205 Handle(Geom2d_BezierCurve) bezier = MakeBezier2d(aBSpline2d, newFirst, newLast);
206 mySegments->Append(bezier);
207 mySplitParams->Append(newLast);
208 continue;
209 }
210 }
211 mySegments->Append(aCrv2d);
212 mySplitParams->Append(nextKnot);
213 }
214 }
215
216 First = mySplitValues->Value(1);
217 for(j = 2; j <= mySplitValues->Length(); j++) {
218 Last = mySplitValues->Value(j);
219 for(Standard_Integer i = 2; i <= nbArcs+1; i++) {
220 Standard_Real valknot = knots(i)+Shift;
221 if(valknot <= First + precision) continue;
222 if(valknot >= Last - precision) break;
223 mySplitValues->InsertBefore(j++,valknot);
224 }
225 First = Last;
226 }
227 myNbCurves = mySplitValues->Length()-1;
228 }
229 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE1);
230}
231
232//=======================================================================
233//function : Build
234//purpose :
235//=======================================================================
236
237void ShapeUpgrade_ConvertCurve2dToBezier::Build(const Standard_Boolean /*Segment*/)
238{
239 Standard_Real prec = Precision::PConfusion();
240 Standard_Integer nb = mySplitValues->Length();
241 myResultingCurves = new TColGeom2d_HArray1OfCurve (1,nb-1);
242 Standard_Real prevPar =0.;
243 Standard_Integer j=2;
244 for(Standard_Integer i = 2; i <= nb; i++) {
245 Standard_Real par = mySplitValues->Value(i);
246 for(; j<= mySplitParams->Length(); j++)
247 if(mySplitParams->Value(j)+prec > par)
248 break;
249 else
250 prevPar = 0.;
251
252 Handle(Geom2d_BezierCurve) bes = Handle(Geom2d_BezierCurve)
253 ::DownCast(mySegments->Value(j-1)->Copy());
254 Standard_Real uFact = mySplitParams->Value(j) - mySplitParams->Value(j-1);
255 Standard_Real pp = mySplitValues->Value(i-1);
256 Standard_Real length = (par - pp)/uFact;
257 bes->Segment(prevPar, prevPar+length);
258 prevPar += length;
259 myResultingCurves->SetValue(i-1,bes);
260 }
261}
262
263//=======================================================================
264//function : Segments
265//purpose :
266//=======================================================================
267
268Handle(TColGeom2d_HSequenceOfCurve) ShapeUpgrade_ConvertCurve2dToBezier::Segments() const
269{
270 return mySegments;
271}
272
273//=======================================================================
274//function : SplitParams
275//purpose :
276//=======================================================================
277
278Handle(TColStd_HSequenceOfReal) ShapeUpgrade_ConvertCurve2dToBezier::SplitParams() const
279{
280 return mySplitParams;
281}