1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
6 // This library is free software; you can redistribute it and / or modify it
7 // under the terms of the GNU Lesser General Public version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
17 #include <Convert_ConeToBSplineSurface.ixx>
20 #include <gp_Trsf.hxx>
22 static const Standard_Integer TheUDegree = 2;
23 static const Standard_Integer TheVDegree = 1;
24 static const Standard_Integer TheNbUKnots = 5;
25 static const Standard_Integer TheNbVKnots = 2;
26 static const Standard_Integer TheNbUPoles = 9;
27 static const Standard_Integer TheNbVPoles = 2;
30 static void ComputePoles( const Standard_Real R,
31 const Standard_Real A,
32 const Standard_Real U1,
33 const Standard_Real U2,
34 const Standard_Real V1,
35 const Standard_Real V2,
36 TColgp_Array2OfPnt& Poles)
38 Standard_Real deltaU = U2 - U1;
42 // Number of spans : maximum opening = 150 degrees ( = PI / 1.2 rds)
44 nbUSpans = (Standard_Integer)IntegerPart( 1.2 * deltaU / M_PI) + 1;
45 Standard_Real AlfaU = deltaU / ( nbUSpans * 2);
47 Standard_Real x[TheNbVPoles];
48 Standard_Real z[TheNbVPoles];
50 x[0] = R + V1 * Sin(A);
52 x[1] = R + V2 * Sin(A);
55 Standard_Real UStart = U1;
56 Poles(1,1) = gp_Pnt(x[0]*Cos(UStart),x[0]*Sin(UStart),z[0]);
57 Poles(1,2) = gp_Pnt(x[1]*Cos(UStart),x[1]*Sin(UStart),z[1]);
59 for ( i = 1; i <= nbUSpans; i++) {
60 Poles( 2*i, 1) = gp_Pnt( x[0] * Cos(UStart+AlfaU) / Cos(AlfaU),
61 x[0] * Sin(UStart+AlfaU) / Cos(AlfaU),
63 Poles( 2*i, 2) = gp_Pnt( x[1] * Cos(UStart+AlfaU) / Cos(AlfaU),
64 x[1] * Sin(UStart+AlfaU) / Cos(AlfaU),
66 Poles(2*i+1,1) = gp_Pnt( x[0] * Cos(UStart+2*AlfaU),
67 x[0] * Sin(UStart+2*AlfaU),
69 Poles(2*i+1,2) = gp_Pnt( x[1] * Cos(UStart+2*AlfaU),
70 x[1] * Sin(UStart+2*AlfaU),
77 //=======================================================================
78 //function : Convert_ConeToBSplineSurface
80 //=======================================================================
82 Convert_ConeToBSplineSurface::Convert_ConeToBSplineSurface
84 const Standard_Real U1,
85 const Standard_Real U2,
86 const Standard_Real V1,
87 const Standard_Real V2 )
88 : Convert_ElementarySurfaceToBSplineSurface (TheNbUPoles, TheNbVPoles,
89 TheNbUKnots, TheNbVKnots,
90 TheUDegree , TheVDegree )
92 Standard_Real deltaU = U2 - U1;
93 Standard_DomainError_Raise_if( (Abs(V2-V1) <= Abs(Epsilon(V1))) ||
96 "Convert_ConeToBSplineSurface");
98 isuperiodic = Standard_False;
99 isvperiodic = Standard_False;
101 Standard_Integer i,j;
102 // construction of cone in the reference mark xOy.
104 // Number of spans : maximum opening = 150 degrees ( = PI / 1.2 rds)
106 nbUSpans = (Standard_Integer)IntegerPart( 1.2 * deltaU / M_PI) + 1;
107 Standard_Real AlfaU = deltaU / ( nbUSpans * 2);
109 nbUPoles = 2 * nbUSpans + 1;
110 nbUKnots = nbUSpans + 1;
115 Standard_Real R = C.RefRadius();
116 Standard_Real A = C.SemiAngle();
118 ComputePoles( R, A, U1, U2, V1, V2, poles);
120 for ( i = 1; i<= nbUKnots; i++) {
121 uknots(i) = U1 + (i-1) * 2 * AlfaU;
124 umults(1)++; umults(nbUKnots)++;
125 vknots(1) = V1; vmults(1) = 2;
126 vknots(2) = V2; vmults(2) = 2;
128 // Replace the bspline in the mark of the sphere.
129 // and calculate the weight of the bspline.
132 Trsf.SetTransformation( C.Position(), gp::XOY());
134 for ( i = 1; i <= nbUPoles; i++) {
135 if ( i % 2 == 0) W1 = Cos(AlfaU);
138 for ( j = 1; j <= nbVPoles; j++) {
140 poles( i, j).Transform( Trsf);
146 //=======================================================================
147 //function : Convert_ConeToBSplineSurface
149 //=======================================================================
151 Convert_ConeToBSplineSurface::Convert_ConeToBSplineSurface
153 const Standard_Real V1,
154 const Standard_Real V2 )
155 : Convert_ElementarySurfaceToBSplineSurface (TheNbUPoles, TheNbVPoles,
156 TheNbUKnots, TheNbVKnots,
157 TheUDegree, TheVDegree)
159 Standard_DomainError_Raise_if( Abs(V2-V1) <= Abs(Epsilon(V1)),
160 "Convert_ConeToBSplineSurface");
162 Standard_Integer i,j;
164 isuperiodic = Standard_True;
165 isvperiodic = Standard_False;
167 // construction of the cone in the reference mark xOy.
169 Standard_Real R = C.RefRadius();
170 Standard_Real A = C.SemiAngle();
172 ComputePoles( R, A, 0., 2.*M_PI, V1, V2, poles);
179 for ( i = 1; i <= nbUKnots; i++) {
180 uknots(i) = ( i-1) * 2. * M_PI /3.;
183 vknots(1) = V1; vmults(1) = 2;
184 vknots(2) = V2; vmults(2) = 2;
186 // replace bspline in the mark of the cone.
187 // and calculate the weight of bspline.
190 Trsf.SetTransformation( C.Position(), gp::XOY());
192 for ( i = 1; i <= nbUPoles; i++) {
193 if ( i % 2 == 0) W = 0.5; // = Cos(pi /3)
196 for ( j = 1; j <= nbVPoles; j++) {
198 poles( i, j).Transform( Trsf);