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