973c2be1 |
1 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
2 | // |
973c2be1 |
3 | // This file is part of Open CASCADE Technology software library. |
b311480e |
4 | // |
d5f74e42 |
5 | // This library is free software; you can redistribute it and/or modify it under |
6 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
7 | // by the Free Software Foundation, with special exception defined in the file |
8 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
9 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
10 | // |
973c2be1 |
11 | // Alternatively, this file may be used under the terms of Open CASCADE |
12 | // commercial license or contractual agreement. |
b311480e |
13 | |
42cf5bc1 |
14 | |
7fd59977 |
15 | #include <Geom_BSplineCurve.hxx> |
42cf5bc1 |
16 | #include <Geom_Curve.hxx> |
17 | #include <ShapeAnalysis_Curve.hxx> |
18 | #include <ShapeCustom_Curve.hxx> |
7fd59977 |
19 | #include <TColgp_Array1OfPnt.hxx> |
20 | #include <TColStd_Array1OfInteger.hxx> |
42cf5bc1 |
21 | #include <TColStd_Array1OfReal.hxx> |
7fd59977 |
22 | |
23 | ShapeCustom_Curve::ShapeCustom_Curve() |
24 | { |
25 | } |
26 | |
27 | //======================================================================= |
28 | //function : ShapeCustom_Curve |
29 | //purpose : |
30 | //======================================================================= |
31 | |
32 | ShapeCustom_Curve::ShapeCustom_Curve (const Handle(Geom_Curve)& C) |
33 | { |
34 | Init ( C ); |
35 | } |
36 | |
37 | //======================================================================= |
38 | //function : Init |
39 | //purpose : |
40 | //======================================================================= |
41 | |
42 | void ShapeCustom_Curve::Init (const Handle(Geom_Curve)& C) |
43 | { |
44 | myCurve = C; |
45 | } |
46 | |
47 | //======================================================================= |
48 | //function : ConvertToPeriodic |
49 | //purpose : |
50 | //======================================================================= |
51 | |
52 | Handle(Geom_Curve) ShapeCustom_Curve::ConvertToPeriodic (const Standard_Boolean substitute, |
53 | const Standard_Real preci) |
54 | { |
55 | Handle(Geom_Curve) newCurve; |
56 | Handle(Geom_BSplineCurve) BSpl = Handle(Geom_BSplineCurve)::DownCast(myCurve); |
57 | if (BSpl.IsNull()) return newCurve; |
58 | |
59 | // PTV 13.02.02: check if curve closed with tolerance |
60 | Standard_Boolean closed = ShapeAnalysis_Curve::IsClosed(myCurve, preci); |
61 | |
62 | if ( ! closed ) return newCurve; |
63 | |
64 | Standard_Boolean converted = Standard_False; //:p6 |
65 | |
66 | if ( closed && ! BSpl->IsPeriodic() && BSpl->NbPoles() >3 ) { |
67 | Standard_Boolean set = Standard_True; |
68 | // if degree+1 at ends, first change it to 1 by rearranging knots |
69 | if ( BSpl->Multiplicity(1) == BSpl->Degree() + 1 && |
70 | BSpl->Multiplicity(BSpl->NbKnots()) == BSpl->Degree() + 1 ) { |
71 | Standard_Integer nbPoles = BSpl->NbPoles(); |
72 | TColgp_Array1OfPnt oldPoles(1,nbPoles); |
73 | TColStd_Array1OfReal oldWeights(1,nbPoles); |
74 | Standard_Integer nbKnots = BSpl->NbKnots(); |
75 | TColStd_Array1OfReal oldKnots(1,nbKnots); |
76 | TColStd_Array1OfInteger oldMults(1,nbKnots); |
77 | |
78 | BSpl->Poles(oldPoles); |
79 | BSpl->Weights(oldWeights); |
80 | BSpl->Knots(oldKnots); |
81 | BSpl->Multiplicities(oldMults); |
82 | |
83 | TColStd_Array1OfReal newKnots (1,nbKnots+2); |
84 | TColStd_Array1OfInteger newMults(1,nbKnots+2); |
85 | Standard_Real a = 0.5 * ( BSpl->Knot(2) - BSpl->Knot(1) + |
86 | BSpl->Knot(nbKnots) - BSpl->Knot(nbKnots-1) ); |
87 | |
88 | newKnots(1) = oldKnots(1) - a; |
89 | newKnots(nbKnots+2) = oldKnots(nbKnots) + a; |
90 | newMults(1) = newMults(nbKnots+2) = 1; |
91 | for (Standard_Integer i = 2; i<=nbKnots+1; i++) { |
92 | newKnots(i) = oldKnots(i-1); |
93 | newMults(i) = oldMults(i-1); |
94 | } |
95 | newMults(2) = newMults(nbKnots+1) = BSpl->Degree(); |
96 | Handle(Geom_BSplineCurve) res = new Geom_BSplineCurve(oldPoles, oldWeights, |
97 | newKnots,newMults, |
98 | BSpl->Degree(),BSpl->IsPeriodic()); |
99 | BSpl = res; |
100 | } |
101 | else if ( BSpl->Multiplicity(1) > BSpl->Degree() || |
102 | BSpl->Multiplicity(BSpl->NbKnots()) > BSpl->Degree() + 1 ) set = Standard_False; |
103 | if ( set ) { |
104 | BSpl->SetPeriodic(); // make periodic |
105 | converted = Standard_True; |
106 | } |
107 | } |
0797d9d3 |
108 | #ifdef OCCT_DEBUG |
7fd59977 |
109 | cout << "Warning: ShapeCustom_Surface: Closed BSplineSurface is caused to be periodic" << endl; |
110 | #endif |
111 | if ( ! converted ) return newCurve; |
112 | newCurve = BSpl; |
113 | if ( substitute ) myCurve = newCurve; |
114 | return newCurve; |
115 | } |