0031668: Visualization - WebGL sample doesn't work on Emscripten 1.39
[occt.git] / src / GeomFill / GeomFill_Coons.cxx
1 // Created on: 1993-09-29
2 // Created by: Bruno DUMORTIER
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
18 #include <BSplCLib.hxx>
19 #include <GeomFill_Coons.hxx>
20 #include <PLib.hxx>
21 #include <TColgp_HArray2OfPnt.hxx>
22 #include <TColStd_HArray2OfReal.hxx>
23
24 //=======================================================================
25 //function : GeomFill_Coons
26 //purpose  : 
27 //=======================================================================
28 GeomFill_Coons::GeomFill_Coons()
29 {
30 }
31
32
33 //=======================================================================
34 //function : GeomFill_Coons
35 //purpose  : 
36 //=======================================================================
37
38 GeomFill_Coons::GeomFill_Coons(const TColgp_Array1OfPnt& P1, 
39                          const TColgp_Array1OfPnt& P2, 
40                          const TColgp_Array1OfPnt& P3, 
41                          const TColgp_Array1OfPnt& P4)
42 {
43   Init( P1, P2, P3, P4);
44 }
45
46
47 //=======================================================================
48 //function : GeomFill_Coons
49 //purpose  : 
50 //=======================================================================
51
52 GeomFill_Coons::GeomFill_Coons(const TColgp_Array1OfPnt&   P1, 
53                          const TColgp_Array1OfPnt&   P2, 
54                          const TColgp_Array1OfPnt&   P3, 
55                          const TColgp_Array1OfPnt&   P4, 
56                          const TColStd_Array1OfReal& W1, 
57                          const TColStd_Array1OfReal& W2, 
58                          const TColStd_Array1OfReal& W3, 
59                          const TColStd_Array1OfReal& W4)
60 {
61   Init( P1, P2, P3, P4, W1, W2, W3, W4);
62 }
63
64
65 //=======================================================================
66 //function : Init
67 //purpose  : 
68 //=======================================================================
69
70 void  GeomFill_Coons::Init(const TColgp_Array1OfPnt& P1, 
71                         const TColgp_Array1OfPnt& P2, 
72                         const TColgp_Array1OfPnt& P3, 
73                         const TColgp_Array1OfPnt& P4)
74 {
75   Standard_DomainError_Raise_if
76     ( P1.Length() != P3.Length() || P2.Length() != P4.Length()," ");
77
78   Standard_Integer NPolU = P1.Length();
79   Standard_Integer NPolV = P2.Length();
80
81   IsRational = Standard_False;
82
83   myPoles = new TColgp_HArray2OfPnt( 1, NPolU, 1, NPolV);
84
85   // The boundaries are not modified
86   Standard_Integer i,j,k;
87
88   for (i=1; i<=NPolU; i++) {
89     myPoles->SetValue( i, 1    , P1(i));
90     myPoles->SetValue( i, NPolV, P3(i));
91   }
92   for (i=1; i<=NPolV; i++) {
93     myPoles->SetValue( 1    , i, P2(i));
94     myPoles->SetValue( NPolU, i, P4(i));
95   }
96
97   // Calcul des coefficients multiplicateurs
98   TColgp_Array1OfPnt Coef ( 1, 4);
99   TColgp_Array1OfPnt Pole ( 1, 4);
100   TColgp_Array1OfPnt CoefU( 1, NPolU);
101   TColgp_Array1OfPnt CoefV( 1, NPolV);
102   Coef( 4) = gp_Pnt(  2., -2., 0.);
103   Coef( 3) = gp_Pnt( -3.,  3., 0.);
104   Coef( 2) = gp_Pnt(  0.,  0., 0.);
105   Coef( 1) = gp_Pnt(  1.,  0., 0.);
106   PLib::CoefficientsPoles(Coef, PLib::NoWeights(),
107                           Pole, PLib::NoWeights());
108   if (NPolU > 4) {
109     BSplCLib::IncreaseDegree(NPolU-1, Pole, BSplCLib::NoWeights(), 
110                              CoefU, BSplCLib::NoWeights());
111   }
112   else {
113      CoefU = Pole;
114   }
115   if (NPolV > 4) {
116     BSplCLib::IncreaseDegree(NPolV-1, Pole, BSplCLib::NoWeights(), 
117                              CoefV, BSplCLib::NoWeights());
118   }
119   else {
120       CoefV = Pole;
121   }
122   TColStd_Array1OfReal FU(2,NPolU-1);
123   TColStd_Array1OfReal GU(2,NPolU-1);
124   TColStd_Array1OfReal FV(2,NPolV-1);
125   TColStd_Array1OfReal GV(2,NPolV-1);
126   Standard_Real Dummy;
127   for ( i= 2; i< NPolU; i++) {
128     CoefU(i).Coord(FU(i), GU(i), Dummy);
129   }
130   for ( i= 2; i< NPolV; i++) {
131     CoefV(i).Coord(FV(i), GV(i), Dummy);
132   }
133   
134   // Clacul des poles interieurs
135   gp_Pnt P;
136   for ( j=2; j<NPolV; j++) {
137     for ( i=2; i<NPolU; i++) {
138       for ( k=1; k<=3      ; k++) {
139         P.SetCoord( k,
140                              FV(j) * (myPoles->Value(i    ,1    )).Coord(k)
141                    +         GV(j) * (myPoles->Value(i    ,NPolV)).Coord(k)
142                    +         FU(i) * (myPoles->Value(1    ,j    )).Coord(k)
143                    +         GU(i) * (myPoles->Value(NPolU,j    )).Coord(k)
144                    - FU(i) * FV(j) * (myPoles->Value(1    ,1    )).Coord(k)
145                    - FU(i) * GV(j) * (myPoles->Value(1    ,NPolV)).Coord(k)
146                    - GU(i) * FV(j) * (myPoles->Value(NPolU,1    )).Coord(k)
147                    - GU(i) * GV(j) * (myPoles->Value(NPolU,NPolV)).Coord(k));
148       }
149       myPoles->SetValue(i,j,P);
150     }
151   }
152 }
153
154
155 //=======================================================================
156 //function : Init
157 //purpose  : 
158 //=======================================================================
159
160 void  GeomFill_Coons::Init(const TColgp_Array1OfPnt&   P1, 
161                            const TColgp_Array1OfPnt&   P2, 
162                            const TColgp_Array1OfPnt&   P3, 
163                            const TColgp_Array1OfPnt&   P4, 
164                            const TColStd_Array1OfReal& W1, 
165                            const TColStd_Array1OfReal& W2, 
166                            const TColStd_Array1OfReal& W3,
167                            const TColStd_Array1OfReal& W4
168                           )
169 {
170
171   Standard_DomainError_Raise_if
172     ( W1.Length() != W3.Length() || W2.Length() != W4.Length()," ");
173   Standard_DomainError_Raise_if
174     ( W1.Length() != P1.Length() || 
175       W2.Length() != P2.Length() || 
176       W3.Length() != P3.Length() || 
177       W4.Length() != P4.Length()   , " ");
178   Init(P1,P2,P3,P4);
179   IsRational = Standard_True;
180
181   Standard_Integer NPolU = W1.Length();
182   Standard_Integer NPolV = W2.Length();
183
184 //#ifdef OCCT_DEBUG
185   Standard_Real NU = NPolU - 1;
186   Standard_Real NV = NPolV - 1;
187 //#endif
188   myWeights = new TColStd_HArray2OfReal( 1, NPolU, 1, NPolV);
189    // The boundaries are not modified
190   Standard_Integer i,j;
191   for ( i=1; i<=NPolU; i++) {
192     myWeights->SetValue( i, 1    , W1(i));
193     myWeights->SetValue( i, NPolV, W3(i));
194   }
195   Standard_Real PU,PU1,PV,PV1;
196   
197   for ( j=2; j<=NPolV-1; j++) {
198     PV  = (j-1)/NV;
199     PV1 = 1 - PV;
200     myWeights->SetValue( 1    , j, W4(j));
201     myWeights->SetValue( NPolU, j, W2(j));
202
203     for ( i=2; i<=NPolU-1; i++) {
204       PU  = (i-1)/NU;
205       PU1 = 1 - PU;
206
207 //      Standard_Real W = 0.5 * ( PV1 * W1(i) + PV  * W3(i) +
208 //                              PU  * W2(j) + PU1 * W4(j)  );
209       Standard_Real W = PV1 * W1(i) + PV  * W3(i) +
210                         PU  * W2(j) + PU1 * W4(j) -
211                       ( PU1 * PV1 * W1(1)     +
212                         PU  * PV1 * W2(1)     +
213                         PU  * PV  * W3(NPolU) +
214                         PU1 * PV  * W4(NPolV)   );
215
216       myWeights->SetValue(i,j,W);
217     }
218   }
219  
220 }
221
222
223