1 // Created on: 1996-03-12
2 // Created by: Bruno DUMORTIER
3 // Copyright (c) 1995-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.
18 #include <Geom_BezierSurface.hxx>
19 #include <Geom_BSplineSurface.hxx>
20 #include <GeomConvert_BSplineSurfaceToBezierSurface.hxx>
21 #include <Standard_DimensionError.hxx>
22 #include <Standard_DomainError.hxx>
23 #include <Standard_OutOfRange.hxx>
24 #include <TColgp_Array2OfPnt.hxx>
25 #include <TColStd_Array2OfReal.hxx>
27 //=======================================================================
28 //function : GeomConvert_BSplineSurfaceToBezierSurface
30 //=======================================================================
31 GeomConvert_BSplineSurfaceToBezierSurface::GeomConvert_BSplineSurfaceToBezierSurface(const Handle(Geom_BSplineSurface)& BasisSurface)
33 mySurface = Handle(Geom_BSplineSurface)::DownCast(BasisSurface->Copy());
34 Standard_Real U1,U2,V1,V2;
35 mySurface->Bounds(U1,U2,V1,V2);
36 mySurface->Segment(U1,U2,V1,V2);
37 mySurface->IncreaseUMultiplicity(mySurface->FirstUKnotIndex(),
38 mySurface->LastUKnotIndex(),
39 mySurface->UDegree());
40 mySurface->IncreaseVMultiplicity(mySurface->FirstVKnotIndex(),
41 mySurface->LastVKnotIndex(),
42 mySurface->VDegree());
46 //=======================================================================
47 //function : GeomConvert_BSplineSurfaceToBezierSurface
49 //=======================================================================
51 GeomConvert_BSplineSurfaceToBezierSurface::GeomConvert_BSplineSurfaceToBezierSurface
52 (const Handle(Geom_BSplineSurface)& BasisSurface,
53 const Standard_Real U1,
54 const Standard_Real U2,
55 const Standard_Real V1,
56 const Standard_Real V2,
57 const Standard_Real ParametricTolerance)
59 if ( (U2 - U1 < ParametricTolerance) ||
60 (V2 - V1 < ParametricTolerance) )
61 throw Standard_DomainError("GeomConvert_BSplineSurfaceToBezierSurface");
63 Standard_Real Uf=U1, Ul=U2, Vf=V1, Vl=V2, PTol = ParametricTolerance/2;
64 Standard_Integer I1, I2;
66 mySurface = Handle(Geom_BSplineSurface)::DownCast(BasisSurface->Copy());
68 mySurface->LocateU(U1, PTol, I1, I2);
69 if (I1==I2) { // On est sur le noeud
70 if ( mySurface->UKnot(I1) > U1) Uf = mySurface->UKnot(I1);
73 mySurface->LocateU(U2, PTol, I1, I2);
74 if (I1==I2) { // On est sur le noeud
75 if ( mySurface->UKnot(I1) < U2) Ul = mySurface->UKnot(I1);
78 mySurface->LocateV(V1, PTol, I1, I2);
79 if (I1==I2) { // On est sur le noeud
80 if ( mySurface->VKnot(I1) > V1) Vf = mySurface->VKnot(I1);
83 mySurface->LocateV(V2, PTol, I1, I2);
84 if (I1==I2) { // On est sur le noeud
85 if ( mySurface->VKnot(I1) < V2) Vl = mySurface->VKnot(I1);
88 mySurface->Segment(Uf, Ul, Vf, Vl);
89 mySurface->IncreaseUMultiplicity(mySurface->FirstUKnotIndex(),
90 mySurface->LastUKnotIndex(),
91 mySurface->UDegree());
92 mySurface->IncreaseVMultiplicity(mySurface->FirstVKnotIndex(),
93 mySurface->LastVKnotIndex(),
94 mySurface->VDegree());
98 //=======================================================================
101 //=======================================================================
103 Handle(Geom_BezierSurface) GeomConvert_BSplineSurfaceToBezierSurface::Patch
104 (const Standard_Integer UIndex,
105 const Standard_Integer VIndex)
107 if (UIndex < 1 || UIndex > mySurface->NbUKnots()-1 ||
108 VIndex < 1 || VIndex > mySurface->NbVKnots()-1 ) {
109 throw Standard_OutOfRange("GeomConvert_BSplineSurfaceToBezierSurface");
111 Standard_Integer UDeg = mySurface->UDegree();
112 Standard_Integer VDeg = mySurface->VDegree();
114 TColgp_Array2OfPnt Poles(1,UDeg+1,1,VDeg+1);
116 Handle(Geom_BezierSurface) S;
117 if ( mySurface->IsURational() || mySurface->IsVRational()) {
118 TColStd_Array2OfReal Weights(1,UDeg+1,1,VDeg+1);
119 for ( Standard_Integer i = 1; i <= UDeg+1; i++) {
120 Standard_Integer CurI = i+UDeg*(UIndex-1);
121 for ( Standard_Integer j = 1; j <= VDeg+1; j++) {
122 Poles(i,j) = mySurface->Pole(CurI,j+VDeg*(VIndex-1));
123 Weights(i,j) = mySurface->Weight(CurI,j+VDeg*(VIndex-1));
126 S = new Geom_BezierSurface(Poles,Weights);
129 for ( Standard_Integer i = 1; i <= UDeg+1; i++) {
130 Standard_Integer CurI = i+UDeg*(UIndex-1);
131 for ( Standard_Integer j = 1; j <= VDeg+1; j++) {
132 Poles(i,j) = mySurface->Pole(CurI,j+VDeg*(VIndex-1));
135 S = new Geom_BezierSurface(Poles);
141 //=======================================================================
144 //=======================================================================
146 void GeomConvert_BSplineSurfaceToBezierSurface::Patches
147 (TColGeom_Array2OfBezierSurface& Surfaces)
149 Standard_Integer NbU = NbUPatches();
150 Standard_Integer NbV = NbVPatches();
151 for (Standard_Integer i = 1; i <= NbU; i++) {
152 for (Standard_Integer j = 1; j <= NbV; j++) {
153 Surfaces(i,j) = Patch(i,j);
158 //=======================================================================
161 //=======================================================================
163 void GeomConvert_BSplineSurfaceToBezierSurface::UKnots
164 (TColStd_Array1OfReal& TKnots) const
166 Standard_Integer ii, kk;
167 for (ii = 1, kk = TKnots.Lower();
168 ii <= mySurface->NbUKnots(); ii++, kk++)
169 TKnots(kk) = mySurface->UKnot(ii);
172 //=======================================================================
175 //=======================================================================
177 void GeomConvert_BSplineSurfaceToBezierSurface::VKnots
178 (TColStd_Array1OfReal& TKnots) const
180 Standard_Integer ii, kk;
181 for (ii = 1, kk = TKnots.Lower();
182 ii <= mySurface->NbVKnots(); ii++, kk++)
183 TKnots(kk) = mySurface->VKnot(ii);
186 //=======================================================================
187 //function : NbUPatches
189 //=======================================================================
191 Standard_Integer GeomConvert_BSplineSurfaceToBezierSurface::NbUPatches() const
193 return (mySurface->NbUKnots()-1);
197 //=======================================================================
198 //function : NbVPatches
200 //=======================================================================
202 Standard_Integer GeomConvert_BSplineSurfaceToBezierSurface::NbVPatches() const
204 return (mySurface->NbVKnots()-1);