0024135: Result of reading step file is invalid.
[occt.git] / src / StepToGeom / StepToGeom_MakeBSplineCurve.pxx
1 // Created on: 1993-07-02
2 // Created by: Martine LANGLOIS
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21
22 {
23   Handle(StepGeom_BSplineCurveWithKnots)   BSCW;
24   Handle(StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve) BSCWR;
25
26   if (SC->IsKind(STANDARD_TYPE(StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve))) {
27     BSCWR = 
28       Handle(StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve)
29         ::DownCast(SC);
30     BSCW = 
31       Handle(StepGeom_BSplineCurveWithKnots)
32         ::DownCast(BSCWR->BSplineCurveWithKnots());
33   }
34   else
35     BSCW = Handle(StepGeom_BSplineCurveWithKnots)::DownCast(SC);
36
37   const Standard_Integer Deg = BSCW->Degree();
38   const Standard_Integer NbPoles = BSCW->NbControlPointsList();
39   const Standard_Integer NbKnots = BSCW->NbKnotMultiplicities();
40
41   //aKnotMultiplicities = new TColStd_HArray1OfInteger(1,NbKnots);
42   const Handle(TColStd_HArray1OfInteger)& aKnotMultiplicities = BSCW->KnotMultiplicities();
43   
44   Standard_Integer i;
45   Standard_Integer aFMulDiff = 0,aLMulDiff = 0;
46   TColStd_Array1OfInteger Mult(1,NbKnots);
47   for (i=1; i<=NbKnots; ++i) {
48     Standard_Integer aCurrentVal = aKnotMultiplicities->Value(i);
49     if (aCurrentVal > Deg + 1)
50     {
51       if (i == 1)       aFMulDiff = aCurrentVal - Deg - 1;
52       if (i == NbKnots) aLMulDiff = aCurrentVal - Deg - 1;
53 #ifdef DEB
54       cout << "\nWrong multiplicity " << aCurrentVal <<  " on " << i 
55            << " knot!" << "\nChanged to " << Deg + 1 << endl;
56 #endif
57       aCurrentVal = Deg + 1;
58     }
59     Mult.SetValue(i,aCurrentVal);
60   }
61   
62   //aControlPointsList = new StepGeom_HArray1OfCartesianPoint(1,NbPoles);
63   const Handle(StepGeom_HArray1OfCartesianPoint)& aControlPointsList = BSCW->ControlPointsList();
64   Standard_Integer aSumMulDiff = aFMulDiff + aLMulDiff;
65   Array1OfPnt_gen Poles(1,NbPoles - aSumMulDiff);
66   CartesianPoint_gen P;
67   
68   for (i = 1 + aFMulDiff; i<= NbPoles - aLMulDiff; ++i)
69   {
70     if (StepToGeom_MakeCartesianPoint_gen::Convert(aControlPointsList->Value(i),P))
71       Poles.SetValue(i - aFMulDiff,P->Pnt_fonc());
72     else
73       return Standard_False;
74   }
75   
76   //aKnots = new TColStd_HArray1OfReal(1,NbKnots);
77   const Handle(TColStd_HArray1OfReal)& aKnots = BSCW->Knots();
78   TColStd_Array1OfReal Kn(1,NbKnots);
79   for (i=1; i<=NbKnots; i++) {
80     Kn.SetValue(i,aKnots->Value(i));
81   }
82   
83   // --- Does the Curve descriptor LOOKS like a periodic descriptor ? ---
84
85   Standard_Integer SumMult = 0;
86   for (i=1; i<=NbKnots; i++) {
87     SumMult += aKnotMultiplicities->Value(i);
88   }
89   
90   Standard_Boolean shouldBePeriodic;
91   if (SumMult == (NbPoles + Deg + 1)) {
92     shouldBePeriodic = Standard_False;
93   }
94   else if ((aKnotMultiplicities->Value(1) == 
95             aKnotMultiplicities->Value(NbKnots)) &&
96            ((SumMult - aKnotMultiplicities->Value(1)) == NbPoles)) {
97     shouldBePeriodic = Standard_True;
98   }
99   else {  // --- What is that ??? ---
100     shouldBePeriodic = Standard_False;
101     //cout << "Strange BSpline Curve Descriptor" << endl;
102   }
103   
104   if (SC->IsKind(STANDARD_TYPE(StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve))) {
105     const Handle(TColStd_HArray1OfReal)& aWeight = BSCWR->WeightsData();
106     TColStd_Array1OfReal W(1,NbPoles);
107     for (i=1; i<=NbPoles; i++)
108       W.SetValue(i,aWeight->Value(i));
109     CC = new BSplineCurve_gen(Poles, W, Kn, Mult, Deg, shouldBePeriodic);
110   }
111   else
112     CC = new BSplineCurve_gen(Poles, Kn, Mult, Deg, shouldBePeriodic);
113
114   // abv 04.07.00 CAX-IF TRJ4: trj4_k1_top-md-203.stp #716 (face #581):
115   // force periodicity on closed curves
116   if ( SC->ClosedCurve() && CC->Degree() >1 && CC->IsClosed() ) {
117     CC->SetPeriodic();
118 //#ifdef DEB
119 //    cout << "Warning: "__FILE__": Closed curve made periodic" << endl;
120 //#endif
121   }
122   return Standard_True;
123 }