0024947: Redesign OCCT legacy type system -- automatic
[occt.git] / src / ShapeUpgrade / ShapeUpgrade_ConvertCurve3dToBezier.cxx
CommitLineData
b311480e 1// Created on: 1999-05-13
2// Created by: data exchange team
3// Copyright (c) 1999-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
17#include <ShapeUpgrade_ConvertCurve3dToBezier.ixx>
18#include <Precision.hxx>
19#include <Geom_TrimmedCurve.hxx>
20#include <Geom_BezierCurve.hxx>
21#include <ShapeExtend.hxx>
22#include <Geom_Line.hxx>
23#include <TColgp_Array1OfPnt.hxx>
24#include <Geom_BSplineCurve.hxx>
25#include <Geom_Conic.hxx>
26#include <GeomConvert_ApproxCurve.hxx>
27#include <GeomConvert.hxx>
28#include <GeomConvert_BSplineCurveToBezierCurve.hxx>
29#include <TColStd_Array1OfReal.hxx>
30#include <TColGeom_HArray1OfCurve.hxx>
31#include <Geom_Circle.hxx>
ec357c5c 32#include <Geom_Curve.hxx>
7fd59977 33
34ShapeUpgrade_ConvertCurve3dToBezier::ShapeUpgrade_ConvertCurve3dToBezier()
35{
36 mySegments = new TColGeom_HSequenceOfCurve;
37 mySplitParams = new TColStd_HSequenceOfReal;
38 myLineMode = Standard_True;
39 myCircleMode = Standard_True;
40 myConicMode = Standard_True;
41}
42
43//=======================================================================
44//function : Compute
45//purpose :
46//=======================================================================
47
48void ShapeUpgrade_ConvertCurve3dToBezier::Compute()
49{
50 mySegments->Clear();
51 mySplitParams->Clear();
52 Standard_Real precision = Precision::PConfusion();
53 Standard_Real First = mySplitValues->Value(1);
54 Standard_Real Last = mySplitValues->Value(mySplitValues->Length());
55 if(myCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
56 Handle(Geom_TrimmedCurve) tmp = Handle(Geom_TrimmedCurve)::DownCast (myCurve);
57 Handle(Geom_Curve) BasCurve = tmp->BasisCurve();
58 ShapeUpgrade_ConvertCurve3dToBezier converter;
59 converter.Init(BasCurve,First,Last);
60 converter.SetSplitValues(mySplitValues);
61 converter.Compute();
62 mySplitValues->ChangeSequence() = converter.SplitValues()->Sequence();
63 myNbCurves = mySplitValues->Length()-1;
64 myStatus |= converter.myStatus;
65 mySegments->ChangeSequence() = converter.Segments()->Sequence();
66 mySplitParams->ChangeSequence() = converter.SplitParams()->Sequence();
67 return;
68 }
69 else if(myCurve->IsKind(STANDARD_TYPE(Geom_BezierCurve))) {
70 Handle(Geom_BezierCurve) bezier = Handle(Geom_BezierCurve)::DownCast (myCurve);
71 myNbCurves = mySplitValues->Length()-1;
72 mySplitParams->Append(First);
73 mySplitParams->Append(Last);
74 if(First < precision && Last > 1 - precision) {
75 mySegments->Append(bezier);
76 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
77 } else {
78 Handle(Geom_BezierCurve) besNew = Handle(Geom_BezierCurve)::DownCast(bezier->Copy());
79 besNew->Segment(First,Last);
80 mySegments->Append(besNew);
81 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE2);
82 }
83 return;
84 }
85 else if(myCurve->IsKind(STANDARD_TYPE(Geom_Line))) {
86 Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast(myCurve);
87 myNbCurves = mySplitValues->Length()-1;
88 mySplitParams->Append(First);
89 mySplitParams->Append(Last);
90 if(!myLineMode) {
91 mySegments->Append(aLine);
92 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
93 return;
94 }
95 TColgp_Array1OfPnt poles(1,2);
96 poles(1) = aLine->Value(First);
97 poles(2) = aLine->Value(Last);
98 Handle(Geom_BezierCurve) bezier = new Geom_BezierCurve(poles);
99 mySegments->Append(bezier);
100 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE1);
101 return;
102 }
103 else if((myCurve->IsKind(STANDARD_TYPE(Geom_Conic))&&!myConicMode)||
104 (myCurve->IsKind(STANDARD_TYPE(Geom_Circle))&&!myCircleMode)) {
105 myNbCurves = mySplitValues->Length()-1;
106 mySplitParams->Append(First);
107 mySplitParams->Append(Last);
108 mySegments->Append(myCurve);
109 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
110 return;
111 }
112 else {
113 Handle(Geom_BSplineCurve) aBSpline;
114 Standard_Real Shift = 0.;
115 if(myCurve->IsKind(STANDARD_TYPE(Geom_Conic))) {
116 Handle(Geom_TrimmedCurve) tcurve = new Geom_TrimmedCurve(myCurve,First,Last); //protection agains parabols ets
117 GeomConvert_ApproxCurve approx (tcurve, Precision::Approximation(),
118 GeomAbs_C1, 100, 6 );
119 if ( approx.HasResult() )
120 aBSpline = Handle(Geom_BSplineCurve)::DownCast(approx.Curve());
121 else {
122 Handle(Geom_TrimmedCurve) t3d = new Geom_TrimmedCurve(myCurve,First,Last);
123 aBSpline = GeomConvert::CurveToBSplineCurve(t3d,Convert_QuasiAngular);
124 }
125 Shift = First - aBSpline->FirstParameter();
126 First = aBSpline->FirstParameter();
127 Last = aBSpline->LastParameter();
128 }
129 else if(!myCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) {
130 aBSpline = GeomConvert::CurveToBSplineCurve(myCurve,Convert_QuasiAngular);
131 }
132 else
133 aBSpline = Handle(Geom_BSplineCurve)::DownCast(myCurve);
134
135 Standard_Real bf = aBSpline->FirstParameter();
136 Standard_Real bl = aBSpline->LastParameter();
137 if(Abs(First-bf) < precision)
138 First = bf;
139 if(Abs(Last-bl) < precision)
140 Last = bl;
141 if(First < bf){
0797d9d3 142#ifdef OCCT_DEBUG
7fd59977 143 cout <<"Warning: The range of the edge exceeds the curve domain" <<endl;
144#endif
145 First = bf;
146 mySplitValues->SetValue(1,First);
147 }
148 if(Last > bl){
0797d9d3 149#ifdef OCCT_DEBUG
7fd59977 150 cout <<"Warning: The range of the edge exceeds the curve domain" <<endl;
151#endif
152 Last = bl;
153 mySplitValues->SetValue(mySplitValues->Length(),Last);
154 }
155
156 GeomConvert_BSplineCurveToBezierCurve tool(aBSpline,First,Last,precision);
157 Standard_Integer nbArcs = tool.NbArcs();
158 TColStd_Array1OfReal knots(1,nbArcs+1);
159 tool.Knots(knots);
160 mySplitParams->Append(First+Shift);
161 Standard_Integer j; // svv Jan 10 2000 : porting on DEC
162 for(j = 1; j <=nbArcs; j++) {
163 Standard_Real nextKnot = knots(j+1)+Shift;
164 if(nextKnot - mySplitParams->Value(mySplitParams->Length()) > precision) {
165 mySegments->Append(tool.Arc(j));
166 mySplitParams->Append(knots(j+1)+Shift);
167 }
168 }
169
170 First = mySplitValues->Value(1);
171 for(j = 2; j <= mySplitValues->Length(); j++) {
172 Last = mySplitValues->Value(j);
173 for(Standard_Integer i = 2; i <= nbArcs+1; i++) {
174 Standard_Real valknot = knots(i)+Shift;
175 if(valknot <= First + precision) continue;
176 if(valknot >= Last - precision) break;
177 mySplitValues->InsertBefore(j++,valknot);
178 }
179 First = Last;
180 }
181 myNbCurves = mySplitValues->Length()-1;
182 }
183 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE1);
184}
185
186//=======================================================================
187//function : Build
188//purpose :
189//=======================================================================
190
191void ShapeUpgrade_ConvertCurve3dToBezier::Build(const Standard_Boolean /*Segment*/)
192{
193 Standard_Real prec = Precision::PConfusion();
194 Standard_Integer nb = mySplitValues->Length();
195 myResultingCurves = new TColGeom_HArray1OfCurve (1,nb-1);
196 Standard_Real prevPar = 0.;
197 Standard_Integer j=2;
198 for(Standard_Integer i = 2; i <= nb; i++) {
199 Standard_Real par = mySplitValues->Value(i);
200 for(; j<= mySplitParams->Length(); j++)
201 if(mySplitParams->Value(j)+prec > par)
202 break;
203 else
204 prevPar = 0.;
205
206 Handle(Geom_Curve) crv = Handle(Geom_Curve)::DownCast(mySegments->Value(j-1)->Copy());
207 if(crv->IsKind(STANDARD_TYPE(Geom_BezierCurve))) {
208 Handle(Geom_BezierCurve) bes = Handle(Geom_BezierCurve)::DownCast(crv);
209 Standard_Real uFact = mySplitParams->Value(j) - mySplitParams->Value(j-1);
210 Standard_Real pp = mySplitValues->Value(i-1);
211 Standard_Real length = (par - pp)/uFact;
212 bes->Segment(prevPar, prevPar+length);
213 prevPar += length;
214 myResultingCurves->SetValue(i-1,bes);
215 }
216 else
217 myResultingCurves->SetValue(i-1,crv);
218 }
219}
220
221//=======================================================================
222//function : Segments
223//purpose :
224//=======================================================================
225
226Handle(TColGeom_HSequenceOfCurve) ShapeUpgrade_ConvertCurve3dToBezier::Segments() const
227{
228 return mySegments;
229}
230
231//=======================================================================
232//function : SplitParams
233//purpose :
234//=======================================================================
235
236Handle(TColStd_HSequenceOfReal) ShapeUpgrade_ConvertCurve3dToBezier::SplitParams() const
237{
238 return mySplitParams;
239}