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
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
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>
32 //=============================================================================
33 // Creation d' une BSplineSurface de Geom a partir d' une
34 // BSplineSurface de Step
35 //=============================================================================
37 Standard_Boolean StepToGeom_MakeBSplineSurface::Convert
38 (const Handle(StepGeom_BSplineSurface)& SS,
39 Handle(Geom_BSplineSurface)& CS)
41 Standard_Integer i, j;
42 Handle(StepGeom_BSplineSurfaceWithKnots) BS;
43 Handle(StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface) BSR;
46 IsKind(STANDARD_TYPE(StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface))) {
48 Handle(StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface)
51 Handle(StepGeom_BSplineSurfaceWithKnots)
52 ::DownCast(BSR->BSplineSurfaceWithKnots());
55 BS = Handle(StepGeom_BSplineSurfaceWithKnots)::DownCast(SS);
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());
69 return Standard_False;
72 const Standard_Integer NUKnots = BS->NbUMultiplicities();
73 const Handle(TColStd_HArray1OfInteger)& aUMultiplicities = BS->UMultiplicities();
74 const Handle(TColStd_HArray1OfReal)& aUKnots = BS->UKnots();
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))) {
82 lastKnot = aUKnots->Value(i);
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))) {
96 KUn.SetValue(pos, aUKnots->Value(i));
97 UMult.SetValue(pos, aUMultiplicities->Value(i));
98 lastKnot = aUKnots->Value(i);
101 // Knot not unique, increase multiplicity
102 Standard_Integer curMult = UMult.Value(pos);
103 UMult.SetValue(pos, curMult + aUMultiplicities->Value(i));
106 const Standard_Integer NVKnots = BS->NbVMultiplicities();
107 const Handle(TColStd_HArray1OfInteger)& aVMultiplicities = BS->VMultiplicities();
108 const Handle(TColStd_HArray1OfReal)& aVKnots = BS->VKnots();
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))) {
116 lastKnot = aVKnots->Value(i);
120 // set vmultiplicities and vknots
121 TColStd_Array1OfInteger VMult(1,NVKnotsUnique);
122 TColStd_Array1OfReal KVn(1,NVKnotsUnique);
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))) {
130 KVn.SetValue(pos, aVKnots->Value(i));
131 VMult.SetValue(pos, aVMultiplicities->Value(i));
132 lastKnot = aVKnots->Value(i);
135 // Knot not unique, increase multiplicity
136 Standard_Integer curMult = VMult.Value(pos);
137 VMult.SetValue(pos, curMult + aVMultiplicities->Value(i));
141 // --- Does the Surface Descriptor LOOKS like a U and/or V Periodic ---
142 // --- Descriptor ? ---
144 // --- U Periodic ? ---
146 Standard_Integer SumMult = 0;
147 for (i=1; i<=NUKnotsUnique; i++) {
148 SumMult += UMult.Value(i);
151 Standard_Boolean shouldBeUPeriodic = Standard_False;
152 if (SumMult == (NUPoles + UDeg + 1)) {
153 //shouldBeUPeriodic = Standard_False;
155 else if ((UMult.Value(1) ==
156 UMult.Value(NUKnotsUnique)) &&
157 ((SumMult - UMult.Value(1))== NUPoles)) {
158 shouldBeUPeriodic = Standard_True;
160 /*else { // --- What is that ??? ---
161 shouldBeUPeriodic = Standard_False;
163 cout << "Strange BSpline Surface Descriptor" << endl;
167 // --- V Periodic ? ---
170 for (i=1; i<=NVKnotsUnique; i++) {
171 SumMult += VMult.Value(i);
174 Standard_Boolean shouldBeVPeriodic = Standard_False;
175 if (SumMult == (NVPoles + VDeg + 1)) {
176 //shouldBeVPeriodic = Standard_False;
178 else if ((VMult.Value(1) ==
179 VMult.Value(NVKnotsUnique)) &&
180 ((SumMult - VMult.Value(1)) == NVPoles)) {
181 shouldBeVPeriodic = Standard_True;
183 /*else { // --- What is that ??? ---
184 shouldBeVPeriodic = Standard_False;
186 cout << "Strange BSpline Surface Descriptor" << endl;
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));
198 CS = new Geom_BSplineSurface(Poles, W, KUn, KVn, UMult,
204 CS = new Geom_BSplineSurface(Poles, KUn, KVn, UMult,
208 return Standard_True;