0030686: Visualization, SelectMgr_ViewerSelector - sorting issues of transformation...
[occt.git] / src / Geom / Geom_OffsetCurve.cxx
CommitLineData
b311480e 1// Created on: 1991-06-25
2// Created by: JCV
3// Copyright (c) 1991-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
7fd59977 17// 24-Aug-95 : xab removed C1 and C2 test : appeller D1 et D2
18// avec discernement !
19// 19-09-97 : JPI correction derivee seconde
7fd59977 20
42cf5bc1 21#include <Geom_BezierCurve.hxx>
22#include <Geom_BSplineCurve.hxx>
7fd59977 23#include <Geom_Circle.hxx>
42cf5bc1 24#include <Geom_Curve.hxx>
7fd59977 25#include <Geom_Ellipse.hxx>
42cf5bc1 26#include <Geom_Geometry.hxx>
7fd59977 27#include <Geom_Hyperbola.hxx>
42cf5bc1 28#include <Geom_Line.hxx>
29#include <Geom_OffsetCurve.hxx>
7fd59977 30#include <Geom_Parabola.hxx>
7fd59977 31#include <Geom_TrimmedCurve.hxx>
7fd59977 32#include <Geom_UndefinedDerivative.hxx>
33#include <Geom_UndefinedValue.hxx>
42cf5bc1 34#include <gp.hxx>
35#include <gp_Dir.hxx>
36#include <gp_Pnt.hxx>
37#include <gp_Trsf.hxx>
38#include <gp_Vec.hxx>
39#include <gp_XYZ.hxx>
7fd59977 40#include <Standard_ConstructionError.hxx>
42cf5bc1 41#include <Standard_NoSuchObject.hxx>
7fd59977 42#include <Standard_NotImplemented.hxx>
42cf5bc1 43#include <Standard_RangeError.hxx>
44#include <Standard_Type.hxx>
7fd59977 45
f5f4ebd0 46IMPLEMENT_STANDARD_RTTIEXT(Geom_OffsetCurve,Geom_Curve)
94f71cad 47
d660a72a 48static const Standard_Real MyAngularToleranceForG1 = Precision::Angular();
7fd59977 49
50
51//=======================================================================
52//function : Copy
53//purpose :
54//=======================================================================
55
56Handle(Geom_Geometry) Geom_OffsetCurve::Copy () const {
57
c04c30b3 58 Handle(Geom_OffsetCurve) C;
d660a72a 59 C = new Geom_OffsetCurve (basisCurve, offsetValue, direction);
7fd59977 60 return C;
61}
62
63
64
65//=======================================================================
66//function : Geom_OffsetCurve
3d58dc49 67//purpose : Basis curve cannot be an Offset curve or trimmed from
68// offset curve.
7fd59977 69//=======================================================================
70
3d58dc49 71Geom_OffsetCurve::Geom_OffsetCurve (const Handle(Geom_Curve)& theCurve,
72 const Standard_Real theOffset,
73 const gp_Dir& theDir,
74 const Standard_Boolean isTheNotCheckC0)
75 : direction(theDir), offsetValue(theOffset)
06be28a4 76{
3d58dc49 77 SetBasisCurve (theCurve, isTheNotCheckC0);
7fd59977 78}
79
80
81//=======================================================================
82//function : Reverse
83//purpose :
84//=======================================================================
85
86void Geom_OffsetCurve::Reverse ()
87{
88 basisCurve->Reverse();
89 offsetValue = -offsetValue;
d660a72a 90 myEvaluator->SetOffsetValue(offsetValue);
7fd59977 91}
92
93
94//=======================================================================
95//function : ReversedParameter
96//purpose :
97//=======================================================================
98
99Standard_Real Geom_OffsetCurve::ReversedParameter( const Standard_Real U) const
100{
101 return basisCurve->ReversedParameter( U);
102}
103
104//=======================================================================
105//function : Direction
106//purpose :
107//=======================================================================
108
109const gp_Dir& Geom_OffsetCurve::Direction () const
110 { return direction; }
111
112//=======================================================================
113//function : SetDirection
114//purpose :
115//=======================================================================
116
d660a72a 117void Geom_OffsetCurve::SetDirection (const gp_Dir& V)
118{
119 direction = V;
120 myEvaluator->SetOffsetDirection(direction);
121}
7fd59977 122
123//=======================================================================
124//function : SetOffsetValue
125//purpose :
126//=======================================================================
127
128void Geom_OffsetCurve::SetOffsetValue (const Standard_Real D)
d660a72a 129{
130 offsetValue = D;
131 myEvaluator->SetOffsetValue(offsetValue);
132}
7fd59977 133
134
135//=======================================================================
136//function : IsPeriodic
137//purpose :
138//=======================================================================
139
140Standard_Boolean Geom_OffsetCurve::IsPeriodic () const
141{
142 return basisCurve->IsPeriodic();
143}
144
145//=======================================================================
146//function : Period
147//purpose :
148//=======================================================================
149
150Standard_Real Geom_OffsetCurve::Period () const
151{
152 return basisCurve->Period();
153}
154
155//=======================================================================
156//function : SetBasisCurve
157//purpose :
158//=======================================================================
159
c04c30b3 160void Geom_OffsetCurve::SetBasisCurve (const Handle(Geom_Curve)& C,
3d58dc49 161 const Standard_Boolean isNotCheckC0)
06be28a4 162{
3d58dc49 163 const Standard_Real aUf = C->FirstParameter(),
164 aUl = C->LastParameter();
c04c30b3 165 Handle(Geom_Curve) aCheckingCurve = Handle(Geom_Curve)::DownCast(C->Copy());
3d58dc49 166 Standard_Boolean isTrimmed = Standard_False;
06be28a4 167
3d58dc49 168 while(aCheckingCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)) ||
169 aCheckingCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve)))
06be28a4 170 {
3d58dc49 171 if (aCheckingCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
172 {
173 Handle(Geom_TrimmedCurve) aTrimC =
174 Handle(Geom_TrimmedCurve)::DownCast(aCheckingCurve);
175 aCheckingCurve = aTrimC->BasisCurve();
176 isTrimmed = Standard_True;
177 }
178
179 if (aCheckingCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve)))
06be28a4 180 {
3d58dc49 181 Handle(Geom_OffsetCurve) aOC =
182 Handle(Geom_OffsetCurve)::DownCast(aCheckingCurve);
183 aCheckingCurve = aOC->BasisCurve();
184 Standard_Real PrevOff = aOC->Offset();
185 gp_Vec V1(aOC->Direction());
186 gp_Vec V2(direction);
187 gp_Vec Vdir(PrevOff*V1 + offsetValue*V2);
188
189 if (offsetValue >= 0.)
06be28a4 190 {
3d58dc49 191 offsetValue = Vdir.Magnitude();
192 direction.SetXYZ(Vdir.XYZ());
193 }
194 else
195 {
196 offsetValue = -Vdir.Magnitude();
197 direction.SetXYZ((-Vdir).XYZ());
06be28a4
RL
198 }
199 }
3d58dc49 200 }
201
202 myBasisCurveContinuity = aCheckingCurve->Continuity();
203
204 Standard_Boolean isC0 = !isNotCheckC0 &&
205 (myBasisCurveContinuity == GeomAbs_C0);
206
207 // Basis curve must be at least C1
208 if (isC0 && aCheckingCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
209 {
210 Handle(Geom_BSplineCurve) aBC = Handle(Geom_BSplineCurve)::DownCast(aCheckingCurve);
211 if(aBC->IsG1(aUf, aUl, MyAngularToleranceForG1))
212 {
213 //Checking if basis curve has more smooth (C1, G2 and above) is not done.
214 //It can be done in case of need.
215 myBasisCurveContinuity = GeomAbs_G1;
216 isC0 = Standard_False;
217 }
06be28a4
RL
218
219 // Raise exception if still C0
3d58dc49 220 if (isC0)
9775fa61 221 throw Standard_ConstructionError("Offset on C0 curve");
06be28a4 222 }
3d58dc49 223 //
224 if(isTrimmed)
225 {
226 basisCurve = new Geom_TrimmedCurve(aCheckingCurve, aUf, aUl);
227 }
228 else
229 {
230 basisCurve = aCheckingCurve;
231 }
d660a72a 232
233 myEvaluator = new GeomEvaluator_OffsetCurve(basisCurve, offsetValue, direction);
7fd59977 234}
235
236
237
238//=======================================================================
239//function : BasisCurve
240//purpose :
241//=======================================================================
242
c04c30b3 243Handle(Geom_Curve) Geom_OffsetCurve::BasisCurve () const
7fd59977 244{
245 return basisCurve;
246}
247
248
249//=======================================================================
250//function : Continuity
251//purpose :
252//=======================================================================
253
254GeomAbs_Shape Geom_OffsetCurve::Continuity () const {
255
256 GeomAbs_Shape OffsetShape=GeomAbs_C0;
3d58dc49 257 switch (myBasisCurveContinuity) {
7fd59977 258 case GeomAbs_C0 : OffsetShape = GeomAbs_C0; break;
259 case GeomAbs_C1 : OffsetShape = GeomAbs_C0; break;
260 case GeomAbs_C2 : OffsetShape = GeomAbs_C1; break;
261 case GeomAbs_C3 : OffsetShape = GeomAbs_C2; break;
262 case GeomAbs_CN : OffsetShape = GeomAbs_CN; break;
263 case GeomAbs_G1 : OffsetShape = GeomAbs_G1; break;
264 case GeomAbs_G2 : OffsetShape = GeomAbs_G2; break;
265 }
266 return OffsetShape;
267}
268
269
270//=======================================================================
271//function : D0
272//purpose :
273//=======================================================================
274
d660a72a 275void Geom_OffsetCurve::D0 (const Standard_Real U, gp_Pnt& P) const
7fd59977 276{
d660a72a 277 myEvaluator->D0(U, P);
7fd59977 278}
279
7fd59977 280//=======================================================================
281//function : D1
282//purpose :
283//=======================================================================
284
d660a72a 285void Geom_OffsetCurve::D1 (const Standard_Real U, gp_Pnt& P, gp_Vec& V1) const
7fd59977 286{
d660a72a 287 myEvaluator->D1(U, P, V1);
7fd59977 288}
289
7fd59977 290//=======================================================================
291//function : D2
292//purpose :
293//=======================================================================
294
d660a72a 295void Geom_OffsetCurve::D2 (const Standard_Real U, gp_Pnt& P, gp_Vec& V1, gp_Vec& V2) const
7fd59977 296{
d660a72a 297 myEvaluator->D2(U, P, V1, V2);
7fd59977 298}
299
7fd59977 300//=======================================================================
301//function : D3
302//purpose :
303//=======================================================================
304
d660a72a 305void Geom_OffsetCurve::D3 (const Standard_Real theU, gp_Pnt& theP,
306 gp_Vec& theV1, gp_Vec& theV2, gp_Vec& theV3) const
94f71cad 307{
d660a72a 308 myEvaluator->D3(theU, theP, theV1, theV2, theV3);
7fd59977 309}
310
311
312//=======================================================================
313//function : DN
314//purpose :
315//=======================================================================
316
d660a72a 317gp_Vec Geom_OffsetCurve::DN (const Standard_Real U, const Standard_Integer N) const
318{
32ca7a51 319 Standard_RangeError_Raise_if (N < 1, "Exception: "
320 "Geom_OffsetCurve::DN(...). N<1.");
7fd59977 321
32ca7a51 322 gp_Vec VN, Vtemp;
323 gp_Pnt Ptemp;
324 switch (N)
325 {
326 case 1:
327 D1( U, Ptemp, VN);
328 break;
329 case 2:
330 D2( U, Ptemp, Vtemp, VN);
331 break;
332 case 3:
333 D3( U, Ptemp, Vtemp, Vtemp, VN);
334 break;
335 default:
9775fa61 336 throw Standard_NotImplemented("Exception: "
32ca7a51 337 "Derivative order is greater than 3. Cannot compute of derivative.");
7fd59977 338 }
32ca7a51 339
340 return VN;
7fd59977 341}
342
7fd59977 343
344//=======================================================================
345//function : FirstParameter
346//purpose :
347//=======================================================================
348
d660a72a 349Standard_Real Geom_OffsetCurve::FirstParameter () const
350{
7fd59977 351 return basisCurve->FirstParameter();
352}
353
354
355//=======================================================================
356//function : LastParameter
357//purpose :
358//=======================================================================
359
d660a72a 360Standard_Real Geom_OffsetCurve::LastParameter () const
361{
7fd59977 362 return basisCurve->LastParameter();
363}
364
365
366//=======================================================================
367//function : Offset
368//purpose :
369//=======================================================================
370
d660a72a 371Standard_Real Geom_OffsetCurve::Offset () const
372{ return offsetValue; }
7fd59977 373
374
375//=======================================================================
376//function : IsClosed
377//purpose :
378//=======================================================================
379
380Standard_Boolean Geom_OffsetCurve::IsClosed () const
381{
382 gp_Pnt PF,PL;
383 D0(FirstParameter(),PF);
384 D0(LastParameter(),PL);
385 return ( PF.Distance(PL) <= gp::Resolution());
386}
387
388
389
390//=======================================================================
391//function : IsCN
392//purpose :
393//=======================================================================
394
395Standard_Boolean Geom_OffsetCurve::IsCN (const Standard_Integer N) const {
396
397 Standard_RangeError_Raise_if (N < 0, " ");
398 return basisCurve->IsCN (N + 1);
399}
400
401
402//=======================================================================
403//function : Transform
404//purpose :
405//=======================================================================
406
d660a72a 407void Geom_OffsetCurve::Transform (const gp_Trsf& T)
408{
7fd59977 409 basisCurve->Transform (T);
410 direction.Transform(T);
411 offsetValue *= T.ScaleFactor();
d660a72a 412
413 myEvaluator->SetOffsetValue(offsetValue);
414 myEvaluator->SetOffsetDirection(direction);
7fd59977 415}
416
417//=======================================================================
418//function : TransformedParameter
419//purpose :
420//=======================================================================
421
422Standard_Real Geom_OffsetCurve::TransformedParameter(const Standard_Real U,
423 const gp_Trsf& T) const
424{
425 return basisCurve->TransformedParameter(U,T);
426}
427
428//=======================================================================
429//function : ParametricTransformation
430//purpose :
431//=======================================================================
432
433Standard_Real Geom_OffsetCurve::ParametricTransformation(const gp_Trsf& T)
434const
435{
436 return basisCurve->ParametricTransformation(T);
437}
3d58dc49 438
439//=======================================================================
440//function : GetBasisCurveContinuity
441//purpose :
442//=======================================================================
443GeomAbs_Shape Geom_OffsetCurve::GetBasisCurveContinuity() const
444{
445 return myBasisCurveContinuity;
446}