461a7ece19a6613a96309ad128d010861409b292
[occt.git] / src / StepToGeom / StepToGeom_MakeBSplineSurface.cxx
1 // Created on: 1993-07-02
2 // Created by: Martine LANGLOIS
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 <StepToGeom_MakeBSplineSurface.ixx>
18 #include <StepGeom_BSplineSurfaceWithKnots.hxx>
19 #include <StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface.hxx>
20 #include <TColStd_Array1OfInteger.hxx>
21 #include <TColStd_Array1OfReal.hxx>
22 #include <TColgp_Array2OfPnt.hxx>
23 #include <TColStd_HArray1OfInteger.hxx>
24 #include <TColStd_HArray1OfReal.hxx>
25 #include <TColStd_HArray2OfReal.hxx>
26 #include <StepGeom_HArray2OfCartesianPoint.hxx>
27 #include <StepGeom_CartesianPoint.hxx>
28 #include <StepToGeom_MakeCartesianPoint.hxx>
29 #include <Geom_CartesianPoint.hxx>
30 #include <gp_Pnt.hxx>
31
32 //=============================================================================
33 // Creation d' une BSplineSurface de Geom a partir d' une
34 // BSplineSurface de Step
35 //=============================================================================
36
37 Standard_Boolean StepToGeom_MakeBSplineSurface::Convert
38     (const Handle(StepGeom_BSplineSurface)& SS,
39      Handle(Geom_BSplineSurface)& CS)
40 {
41   Standard_Integer                    i, j;
42   Handle(StepGeom_BSplineSurfaceWithKnots) BS;
43   Handle(StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface) BSR;
44
45   if (SS->
46       IsKind(STANDARD_TYPE(StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface))) {
47     BSR = 
48       Handle(StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface)
49         ::DownCast(SS);
50     BS = 
51       Handle(StepGeom_BSplineSurfaceWithKnots)
52         ::DownCast(BSR->BSplineSurfaceWithKnots());
53   }
54   else
55     BS = Handle(StepGeom_BSplineSurfaceWithKnots)::DownCast(SS);
56
57   const Standard_Integer UDeg = BS->UDegree();
58   const Standard_Integer VDeg = BS->VDegree();
59   const Standard_Integer NUPoles = BS->NbControlPointsListI();
60   const Standard_Integer NVPoles = BS->NbControlPointsListJ();
61   const Handle(StepGeom_HArray2OfCartesianPoint)& aControlPointsList = BS->ControlPointsList();
62   Handle(Geom_CartesianPoint) P;
63   TColgp_Array2OfPnt Poles(1,NUPoles,1,NVPoles);
64   for (i=1; i<=NUPoles; i++) {
65     for (j=1; j<=NVPoles; j++) {
66       if (StepToGeom_MakeCartesianPoint::Convert(aControlPointsList->Value(i,j),P))
67         Poles.SetValue(i,j,P->Pnt());
68           else
69         return Standard_False;
70     }
71   }
72   const Standard_Integer NUKnots = BS->NbUMultiplicities();
73   const Handle(TColStd_HArray1OfInteger)& aUMultiplicities = BS->UMultiplicities();
74   const Handle(TColStd_HArray1OfReal)& aUKnots = BS->UKnots();
75   
76   // count number of unique uknots
77   Standard_Real lastKnot = RealFirst();
78   Standard_Integer NUKnotsUnique = 0;
79   for (i=1; i<=NUKnots; i++) {
80     if (aUKnots->Value(i) - lastKnot > Epsilon (Abs(lastKnot))) {
81       NUKnotsUnique++;
82       lastKnot = aUKnots->Value(i);
83     }
84   }
85
86   // set umultiplicities and uknots
87   TColStd_Array1OfInteger UMult(1,NUKnotsUnique);
88   TColStd_Array1OfReal KUn(1,NUKnotsUnique);
89   Standard_Integer pos = 1;
90   lastKnot = aUKnots->Value(1);
91   KUn.SetValue(1, aUKnots->Value(1));
92   UMult.SetValue(1, aUMultiplicities->Value(1));
93   for (i=2; i<=NUKnots; i++) {
94     if (aUKnots->Value(i) - lastKnot > Epsilon (Abs(lastKnot))) {
95       pos++;
96       KUn.SetValue(pos, aUKnots->Value(i));
97       UMult.SetValue(pos, aUMultiplicities->Value(i));
98       lastKnot = aUKnots->Value(i);
99     }
100     else {
101       // Knot not unique, increase multiplicity
102       Standard_Integer curMult = UMult.Value(pos);
103       UMult.SetValue(pos, curMult + aUMultiplicities->Value(i));
104     }
105   }
106   const Standard_Integer NVKnots = BS->NbVMultiplicities();
107   const Handle(TColStd_HArray1OfInteger)& aVMultiplicities = BS->VMultiplicities();
108   const Handle(TColStd_HArray1OfReal)& aVKnots = BS->VKnots();
109   
110   // count number of unique vknots
111   lastKnot = RealFirst();
112   Standard_Integer NVKnotsUnique = 0;
113   for (i=1; i<=NVKnots; i++) {
114     if (aVKnots->Value(i) - lastKnot > Epsilon (Abs(lastKnot))) {
115       NVKnotsUnique++;
116       lastKnot = aVKnots->Value(i);
117     }
118   }
119   
120   // set vmultiplicities and vknots
121   TColStd_Array1OfInteger VMult(1,NVKnotsUnique);
122   TColStd_Array1OfReal KVn(1,NVKnotsUnique);
123   pos = 1;
124   lastKnot = aVKnots->Value(1);
125   KVn.SetValue(1, aVKnots->Value(1));
126   VMult.SetValue(1, aVMultiplicities->Value(1));
127   for (i=2; i<=NVKnots; i++) {
128     if (aVKnots->Value(i) - lastKnot > Epsilon (Abs(lastKnot))) {
129       pos++;
130       KVn.SetValue(pos, aVKnots->Value(i));
131       VMult.SetValue(pos, aVMultiplicities->Value(i));
132       lastKnot = aVKnots->Value(i);
133     }
134     else {
135       // Knot not unique, increase multiplicity
136       Standard_Integer curMult = VMult.Value(pos);
137       VMult.SetValue(pos, curMult + aVMultiplicities->Value(i));
138     }
139   }
140   
141   // --- Does the Surface Descriptor LOOKS like a U and/or V Periodic ---
142   // --- Descriptor ? ---
143   
144   // --- U Periodic ? ---
145   
146   Standard_Integer SumMult = 0;
147   for (i=1; i<=NUKnotsUnique; i++) {
148     SumMult += UMult.Value(i);
149   }
150   
151   Standard_Boolean shouldBeUPeriodic = Standard_False;
152   if (SumMult == (NUPoles + UDeg + 1)) {
153     //shouldBeUPeriodic = Standard_False;
154   }
155   else if ((UMult.Value(1) == 
156             UMult.Value(NUKnotsUnique)) &&
157            ((SumMult - UMult.Value(1))== NUPoles)) {
158     shouldBeUPeriodic = Standard_True;
159   }
160   /*else {  // --- What is that ??? ---
161     shouldBeUPeriodic = Standard_False;
162 #ifdef DEBUG
163     cout << "Strange BSpline Surface Descriptor" << endl;
164 #endif
165   }*/
166   
167   // --- V Periodic ? ---
168   
169   SumMult = 0;
170   for (i=1; i<=NVKnotsUnique; i++) {
171     SumMult += VMult.Value(i);
172   }
173   
174   Standard_Boolean shouldBeVPeriodic = Standard_False;
175   if (SumMult == (NVPoles + VDeg + 1)) {
176     //shouldBeVPeriodic = Standard_False;
177   }
178   else if ((VMult.Value(1) == 
179             VMult.Value(NVKnotsUnique)) &&
180            ((SumMult - VMult.Value(1)) == NVPoles)) {
181     shouldBeVPeriodic = Standard_True;
182   }
183   /*else {  // --- What is that ??? ---
184     shouldBeVPeriodic = Standard_False;
185 #ifdef DEBUG
186     cout << "Strange BSpline Surface Descriptor" << endl;
187 #endif
188   }*/
189   
190   if (SS->IsKind(STANDARD_TYPE(StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface))) {
191     const Handle(TColStd_HArray2OfReal)& aWeight = BSR->WeightsData();
192     TColStd_Array2OfReal W(1,NUPoles,1,NVPoles);
193     for (i=1; i<=NUPoles; i++) {
194       for (j=1; j<=NVPoles; j++) {
195         W.SetValue(i,j,aWeight->Value(i,j));
196       }
197     }
198     CS = new Geom_BSplineSurface(Poles, W, KUn, KVn, UMult,
199                                  VMult, UDeg, VDeg,
200                                  shouldBeUPeriodic,
201                                  shouldBeVPeriodic);
202   }
203   else
204     CS = new Geom_BSplineSurface(Poles, KUn, KVn, UMult,
205                                  VMult, UDeg, VDeg,
206                                  shouldBeUPeriodic,
207                                  shouldBeVPeriodic);
208   return Standard_True;
209 }