0024411: SplitShape produces shape with incorrectly parameterized periodic 3D curve
[occt.git] / src / Geom2d / Geom2d_TrimmedCurve.cxx
1 // Created on: 1993-03-24
2 // Created by: JCV
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <Geom2d_TrimmedCurve.ixx>
18 #include <gp.hxx>
19 #include <Geom2d_Geometry.hxx>
20 #include <Geom2d_BSplineCurve.hxx>
21 #include <Geom2d_BezierCurve.hxx>
22 #include <Geom2d_OffsetCurve.hxx>
23 #include <Geom2d_Line.hxx>
24 #include <Geom2d_Circle.hxx>
25 #include <Geom2d_Ellipse.hxx>
26 #include <Geom2d_Hyperbola.hxx>
27 #include <Geom2d_Parabola.hxx>
28 #include <Standard_ConstructionError.hxx>
29 #include <Standard_RangeError.hxx>
30 #include <ElCLib.hxx>
31 #include <Precision.hxx>
32
33
34 typedef Handle(Geom2d_TrimmedCurve) Handle(TrimmedCurve);
35 typedef Geom2d_TrimmedCurve         TrimmedCurve;
36 typedef Handle(Geom2d_Curve)        Handle(Curve);
37 typedef Handle(Geom2d_Geometry)     Handle(Geometry);
38 typedef gp_Ax2d   Ax2d;
39 typedef gp_Pnt2d  Pnt2d;
40 typedef gp_Trsf2d Trsf2d;
41 typedef gp_Vec2d  Vec2d;
42
43
44
45
46
47 //=======================================================================
48 //function : Copy
49 //purpose  : 
50 //=======================================================================
51
52 Handle(Geom2d_Geometry) Geom2d_TrimmedCurve::Copy () const 
53 {
54   Handle(TrimmedCurve) Tc;
55   Tc = new TrimmedCurve (basisCurve, uTrim1, uTrim2);
56   return Tc;
57 }
58
59 //=======================================================================
60 //function : Geom2d_TrimmedCurve
61 //purpose  : 
62 //=======================================================================
63
64 Geom2d_TrimmedCurve::Geom2d_TrimmedCurve (const Handle(Geom2d_Curve)& C, 
65                                           const Standard_Real U1, 
66                                           const Standard_Real U2,
67                                           const Standard_Boolean Sense,
68                                           const Standard_Boolean theAdjustPeriodic) :
69      uTrim1 (U1),
70      uTrim2 (U2)
71 {
72   if(C.IsNull()) Standard_ConstructionError::Raise("Geom2d_TrimmedCurve:: C is null");
73   // kill trimmed basis curves
74   Handle(Geom2d_TrimmedCurve) T = Handle(Geom2d_TrimmedCurve)::DownCast(C);
75   if (!T.IsNull())
76     basisCurve = Handle(Curve)::DownCast(T->BasisCurve()->Copy());
77   else
78     basisCurve = Handle(Curve)::DownCast(C->Copy());
79
80   SetTrim(U1, U2, Sense, theAdjustPeriodic);
81 }
82
83 //=======================================================================
84 //function : Reverse
85 //purpose  : 
86 //=======================================================================
87
88 void Geom2d_TrimmedCurve::Reverse () 
89 {
90   Standard_Real U1 = basisCurve->ReversedParameter(uTrim2);
91   Standard_Real U2 = basisCurve->ReversedParameter(uTrim1);
92   basisCurve->Reverse();
93   SetTrim(U1, U2, Standard_True, Standard_False);
94 }
95
96 //=======================================================================
97 //function : ReversedParamater
98 //purpose  : 
99 //=======================================================================
100
101 Standard_Real Geom2d_TrimmedCurve::ReversedParameter( const Standard_Real U) const
102 {
103   return basisCurve->ReversedParameter(U);
104 }
105
106 //=======================================================================
107 //function : SetTrim
108 //purpose  : 
109 //=======================================================================
110
111 void Geom2d_TrimmedCurve::SetTrim (const Standard_Real U1,
112                                    const Standard_Real U2,
113                                    const Standard_Boolean Sense,
114                                    const Standard_Boolean theAdjustPeriodic) 
115 {
116   Standard_Boolean sameSense = Standard_True;
117   if (U1 == U2)
118     Standard_ConstructionError::Raise("Geom2d_TrimmedCurve::U1 == U2");
119
120   Standard_Real Udeb = basisCurve->FirstParameter();
121   Standard_Real Ufin = basisCurve->LastParameter();
122   
123   if (basisCurve->IsPeriodic())  {
124      sameSense = Sense;
125       
126      // set uTrim1 in the range Udeb , Ufin
127      // set uTrim2 in the range uTrim1 , uTrim1 + Period()
128      uTrim1 = U1;
129      uTrim2 = U2;
130      if (theAdjustPeriodic)
131        ElCLib::AdjustPeriodic(Udeb, Ufin,
132                               Min(Abs(uTrim2-uTrim1)/2,Precision::PConfusion()),
133                               uTrim1, uTrim2);
134   }
135   else { 
136     if (U1 < U2) {
137       sameSense = Sense;
138       uTrim1 = U1;
139       uTrim2 = U2;
140     }
141     else {
142       sameSense = !Sense;
143       uTrim1 = U2;
144       uTrim2 = U1;
145     }
146
147     if ((Udeb - uTrim1 > Precision::PConfusion()) ||
148         (uTrim2 - Ufin > Precision::PConfusion()))   {
149       Standard_ConstructionError::Raise
150         ("Geom_TrimmedCurve::parameters out of range");
151     }
152   }    
153
154   if (!sameSense)
155     Reverse();
156 }
157
158 //=======================================================================
159 //function : BasisCurve
160 //purpose  : 
161 //=======================================================================
162
163 Handle(Curve) Geom2d_TrimmedCurve::BasisCurve () const 
164
165   return basisCurve;
166 }
167
168 //=======================================================================
169 //function : Continuity
170 //purpose  : 
171 //=======================================================================
172
173 GeomAbs_Shape Geom2d_TrimmedCurve::Continuity () const
174
175   return basisCurve->Continuity(); 
176 }
177
178 //=======================================================================
179 //function : IsCN
180 //purpose  : 
181 //=======================================================================
182
183 Standard_Boolean Geom2d_TrimmedCurve::IsCN (const Standard_Integer N) const 
184 {
185   Standard_RangeError_Raise_if (N < 0, " ");
186   return basisCurve->IsCN (N);
187 }
188
189 //=======================================================================
190 //function : EndPoint
191 //purpose  : 
192 //=======================================================================
193
194 Pnt2d Geom2d_TrimmedCurve::EndPoint () const 
195
196   return  basisCurve->Value(uTrim2);
197 }
198
199 //=======================================================================
200 //function : FirstParameter
201 //purpose  : 
202 //=======================================================================
203
204 Standard_Real Geom2d_TrimmedCurve::FirstParameter () const       { return uTrim1; }
205
206 //=======================================================================
207 //function : IsClosed
208 //purpose  : 
209 //=======================================================================
210
211 Standard_Boolean Geom2d_TrimmedCurve::IsClosed () const          
212 {
213   Standard_Real Dist = 
214     Value(FirstParameter()).Distance(Value(LastParameter()));
215   return ( Dist <= gp::Resolution());
216 }
217
218 //=======================================================================
219 //function : IsPeriodic
220 //purpose  : 
221 //=======================================================================
222
223 Standard_Boolean Geom2d_TrimmedCurve::IsPeriodic () const        
224 {
225   //return basisCurve->IsPeriodic();
226   return Standard_False;
227 }
228
229 //=======================================================================
230 //function : Period
231 //purpose  : 
232 //=======================================================================
233
234 Standard_Real Geom2d_TrimmedCurve::Period () const
235 {
236   return basisCurve->Period();
237 }
238
239 //=======================================================================
240 //function : LastParameter
241 //purpose  : 
242 //=======================================================================
243
244 Standard_Real Geom2d_TrimmedCurve::LastParameter () const        { return uTrim2; }
245
246 //=======================================================================
247 //function : StartPoint
248 //purpose  : 
249 //=======================================================================
250
251 Pnt2d Geom2d_TrimmedCurve::StartPoint () const 
252 {
253   gp_Pnt2d P;
254     P = basisCurve->Value(uTrim1);
255   return P;
256 }
257
258 //=======================================================================
259 //function : D0
260 //purpose  : 
261 //=======================================================================
262
263 void Geom2d_TrimmedCurve::D0 (const Standard_Real   U,
264                                     Pnt2d& P ) const {
265   basisCurve->D0(U, P);
266 }
267
268 //=======================================================================
269 //function : D1
270 //purpose  : 
271 //=======================================================================
272
273 void Geom2d_TrimmedCurve::D1 (const Standard_Real U, Pnt2d& P, Vec2d& V1) const 
274 {
275    basisCurve->D1 (U, P, V1);
276 }
277
278 //=======================================================================
279 //function : D2
280 //purpose  : 
281 //=======================================================================
282
283 void Geom2d_TrimmedCurve::D2 (const Standard_Real U, 
284                                     Pnt2d& P, 
285                                     Vec2d& V1, Vec2d& V2) const 
286 {
287    basisCurve->D2 (U, P, V1, V2);
288 }
289
290 //=======================================================================
291 //function : D3
292 //purpose  : 
293 //=======================================================================
294
295 void Geom2d_TrimmedCurve::D3 (const Standard_Real U, 
296                                     Pnt2d& P, 
297                                     Vec2d& V1, Vec2d& V2, Vec2d& V3) const 
298 {
299    basisCurve->D3 (U, P, V1, V2, V3);
300 }
301
302 //=======================================================================
303 //function : DN
304 //purpose  : 
305 //=======================================================================
306
307 Vec2d Geom2d_TrimmedCurve::DN (const Standard_Real U, const Standard_Integer N) const 
308 {
309   return  basisCurve->DN(U, N);
310 }
311
312 //=======================================================================
313 //function : Transform
314 //purpose  : 
315 //=======================================================================
316
317 void Geom2d_TrimmedCurve::Transform (const Trsf2d& T) 
318 {
319   basisCurve->Transform (T);
320   Standard_Real U1 = basisCurve->TransformedParameter(uTrim1,T);
321   Standard_Real U2 = basisCurve->TransformedParameter(uTrim2,T);
322   SetTrim(U1, U2, Standard_True, Standard_False);
323 }
324
325 //=======================================================================
326 //function : TransformedParameter
327 //purpose  : 
328 //=======================================================================
329
330 Standard_Real Geom2d_TrimmedCurve::TransformedParameter(const Standard_Real U,
331                                                         const gp_Trsf2d& T) const
332 {
333   return basisCurve->TransformedParameter(U,T);
334 }
335
336 //=======================================================================
337 //function : ParametricTransformation
338 //purpose  : 
339 //=======================================================================
340
341 Standard_Real Geom2d_TrimmedCurve::ParametricTransformation(const gp_Trsf2d& T) const
342 {
343   return basisCurve->ParametricTransformation(T);
344 }
345