7fd59977 |
1 | #include <ShapeCustom_Curve.ixx> |
2 | #include <Geom_BSplineCurve.hxx> |
3 | #include <TColStd_Array1OfReal.hxx> |
4 | #include <TColgp_Array1OfPnt.hxx> |
5 | #include <TColStd_Array1OfInteger.hxx> |
6 | #include <ShapeAnalysis_Curve.hxx> |
7 | |
8 | |
9 | ShapeCustom_Curve::ShapeCustom_Curve() |
10 | { |
11 | } |
12 | |
13 | //======================================================================= |
14 | //function : ShapeCustom_Curve |
15 | //purpose : |
16 | //======================================================================= |
17 | |
18 | ShapeCustom_Curve::ShapeCustom_Curve (const Handle(Geom_Curve)& C) |
19 | { |
20 | Init ( C ); |
21 | } |
22 | |
23 | //======================================================================= |
24 | //function : Init |
25 | //purpose : |
26 | //======================================================================= |
27 | |
28 | void ShapeCustom_Curve::Init (const Handle(Geom_Curve)& C) |
29 | { |
30 | myCurve = C; |
31 | } |
32 | |
33 | //======================================================================= |
34 | //function : ConvertToPeriodic |
35 | //purpose : |
36 | //======================================================================= |
37 | |
38 | Handle(Geom_Curve) ShapeCustom_Curve::ConvertToPeriodic (const Standard_Boolean substitute, |
39 | const Standard_Real preci) |
40 | { |
41 | Handle(Geom_Curve) newCurve; |
42 | Handle(Geom_BSplineCurve) BSpl = Handle(Geom_BSplineCurve)::DownCast(myCurve); |
43 | if (BSpl.IsNull()) return newCurve; |
44 | |
45 | // PTV 13.02.02: check if curve closed with tolerance |
46 | Standard_Boolean closed = ShapeAnalysis_Curve::IsClosed(myCurve, preci); |
47 | |
48 | if ( ! closed ) return newCurve; |
49 | |
50 | Standard_Boolean converted = Standard_False; //:p6 |
51 | |
52 | if ( closed && ! BSpl->IsPeriodic() && BSpl->NbPoles() >3 ) { |
53 | Standard_Boolean set = Standard_True; |
54 | // if degree+1 at ends, first change it to 1 by rearranging knots |
55 | if ( BSpl->Multiplicity(1) == BSpl->Degree() + 1 && |
56 | BSpl->Multiplicity(BSpl->NbKnots()) == BSpl->Degree() + 1 ) { |
57 | Standard_Integer nbPoles = BSpl->NbPoles(); |
58 | TColgp_Array1OfPnt oldPoles(1,nbPoles); |
59 | TColStd_Array1OfReal oldWeights(1,nbPoles); |
60 | Standard_Integer nbKnots = BSpl->NbKnots(); |
61 | TColStd_Array1OfReal oldKnots(1,nbKnots); |
62 | TColStd_Array1OfInteger oldMults(1,nbKnots); |
63 | |
64 | BSpl->Poles(oldPoles); |
65 | BSpl->Weights(oldWeights); |
66 | BSpl->Knots(oldKnots); |
67 | BSpl->Multiplicities(oldMults); |
68 | |
69 | TColStd_Array1OfReal newKnots (1,nbKnots+2); |
70 | TColStd_Array1OfInteger newMults(1,nbKnots+2); |
71 | Standard_Real a = 0.5 * ( BSpl->Knot(2) - BSpl->Knot(1) + |
72 | BSpl->Knot(nbKnots) - BSpl->Knot(nbKnots-1) ); |
73 | |
74 | newKnots(1) = oldKnots(1) - a; |
75 | newKnots(nbKnots+2) = oldKnots(nbKnots) + a; |
76 | newMults(1) = newMults(nbKnots+2) = 1; |
77 | for (Standard_Integer i = 2; i<=nbKnots+1; i++) { |
78 | newKnots(i) = oldKnots(i-1); |
79 | newMults(i) = oldMults(i-1); |
80 | } |
81 | newMults(2) = newMults(nbKnots+1) = BSpl->Degree(); |
82 | Handle(Geom_BSplineCurve) res = new Geom_BSplineCurve(oldPoles, oldWeights, |
83 | newKnots,newMults, |
84 | BSpl->Degree(),BSpl->IsPeriodic()); |
85 | BSpl = res; |
86 | } |
87 | else if ( BSpl->Multiplicity(1) > BSpl->Degree() || |
88 | BSpl->Multiplicity(BSpl->NbKnots()) > BSpl->Degree() + 1 ) set = Standard_False; |
89 | if ( set ) { |
90 | BSpl->SetPeriodic(); // make periodic |
91 | converted = Standard_True; |
92 | } |
93 | } |
94 | #ifdef DEBUG |
95 | cout << "Warning: ShapeCustom_Surface: Closed BSplineSurface is caused to be periodic" << endl; |
96 | #endif |
97 | if ( ! converted ) return newCurve; |
98 | newCurve = BSpl; |
99 | if ( substitute ) myCurve = newCurve; |
100 | return newCurve; |
101 | } |