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 |
36 | IMPLEMENT_STANDARD_RTTIEXT(ShapeUpgrade_ConvertCurve3dToBezier,ShapeUpgrade_SplitCurve3d) |
37 | |
7fd59977 |
38 | ShapeUpgrade_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 | |
52 | void 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))) { |
316ea293 |
120 | Handle(Geom_Curve) tcurve = new Geom_TrimmedCurve(myCurve,First,Last); //protection against 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 | |
195 | void 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 | |
230 | Handle(TColGeom_HSequenceOfCurve) ShapeUpgrade_ConvertCurve3dToBezier::Segments() const |
231 | { |
232 | return mySegments; |
233 | } |
234 | |
235 | //======================================================================= |
236 | //function : SplitParams |
237 | //purpose : |
238 | //======================================================================= |
239 | |
240 | Handle(TColStd_HSequenceOfReal) ShapeUpgrade_ConvertCurve3dToBezier::SplitParams() const |
241 | { |
242 | return mySplitParams; |
243 | } |