1 /*
2 * Copyright (C) 1998, 2000-2007, 2010, 2011, 2012, 2013 SINTEF ICT,
3 * Applied Mathematics, Norway.
4 *
5 * Contact information: E-mail: tor.dokken@sintef.no
6 * SINTEF ICT, Department of Applied Mathematics,
7 * P.O. Box 124 Blindern,
8 * 0314 Oslo, Norway.
9 *
10 * This file is part of SISL.
11 *
12 * SISL is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Affero General Public License as
14 * published by the Free Software Foundation, either version 3 of the
15 * License, or (at your option) any later version.
16 *
17 * SISL is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Affero General Public License for more details.
21 *
22 * You should have received a copy of the GNU Affero General Public
23 * License along with SISL. If not, see
24 * <http://www.gnu.org/licenses/>.
25 *
26 * In accordance with Section 7(b) of the GNU Affero General Public
27 * License, a covered work must retain the producer line in every data
28 * file that is created or manipulated using SISL.
29 *
30 * Other Usage
31 * You can be released from the requirements of the license by purchasing
32 * a commercial license. Buying such a license is mandatory as soon as you
33 * develop commercial activities involving the SISL library without
34 * disclosing the source code of your own applications.
35 *
36 * This file may be used in accordance with the terms contained in a
37 * written agreement between you and SINTEF ICT.
38 */
39
40 #include "GoReadWrite.h"
41 #include <vector>
42 #include <iostream>
43 #include <stdexcept>
44 #include "sisl.h"
45
46
47 using namespace std;
48
49 namespace {
50 // Go-header-related info.
51 const int HEADER_SIZE = 4;
52 const int CURVE_INSTANCE_TYPE = 100;
53 const int SURFACE_INSTANCE_TYPE = 200;
54 const int POINTCLOUD_INSTANCE_TYPE = 400;
55 const int MAJOR_VERSION = 1;
56 const int MINOR_VERSION = 0;
57
determine_go_instance_type(istream & is)58 inline int determine_go_instance_type(istream& is)
59 {
60 int result;
61 is >> result;
62 for (int dummy, i = 1; i < HEADER_SIZE; ++i)
63 is >> dummy;
64 return result;
65 }
66
read_basis(istream & is,int & n,int & k,vector<double> & knots)67 inline void read_basis(istream& is, int& n, int& k, vector<double>& knots)
68 {
69 is >> n >> k;
70 knots.resize(n + k);
71 for (int i = 0; i < n + k; ++i) {
72 is >> knots[i];
73 }
74 }
75
write_basis(ostream & os,const int & n,const int & k,const double * knots)76 inline void write_basis(ostream& os, const int&n, const int& k, const double* knots)
77 {
78 os << n << ' ' << k << '\n';
79 for (int i = 0; i < n + k; ++i) {
80 os << knots[i] << ' ';
81 }
82 os << '\n';
83 }
84
85
86 }; // end anonymous namespace
87
88 //===========================================================================
readGoSurface(istream & go_stream)89 SISLSurf* readGoSurface(istream& go_stream)
90 //===========================================================================
91 {
92 if (determine_go_instance_type(go_stream) != SURFACE_INSTANCE_TYPE) {
93 throw runtime_error("stream given to readGoSurface() does not "
94 "contain surface type.");
95 }
96
97 // reading basic surface properties
98 int kind, dim, rational;
99 go_stream >> dim >> rational;
100 kind = rational ? 2 : 1;
101
102 // reading basis information (one basis for each parameter)
103 int num_coefs_1, num_coefs_2;
104 int order_1, order_2;
105 vector<double> knots_1, knots_2;
106 read_basis(go_stream, num_coefs_1, order_1, knots_1);
107 read_basis(go_stream, num_coefs_2, order_2, knots_2);
108
109 // reading control points
110 int coef_size = num_coefs_1 * num_coefs_2 * (rational ? dim + 1 : dim);
111 vector<double> coef(coef_size);
112 for (int i = 0; i < coef_size; ++i) {
113 go_stream >> coef[i];
114 }
115
116 int copy = 1; // flag that the input arrays should be _copied_
117 return newSurf(num_coefs_1,
118 num_coefs_2,
119 order_1,
120 order_2,
121 &knots_1[0],
122 &knots_2[0],
123 &coef[0],
124 kind,
125 dim,
126 copy);
127 }
128
129 //===========================================================================
writeGoSurface(SISLSurf * surf,ostream & go_stream)130 void writeGoSurface(SISLSurf* surf, ostream& go_stream)
131 //===========================================================================
132 {
133 if (!surf) {
134 throw runtime_error("zero pointer given to writeGoSurface()");
135 }
136
137 // write standard header
138 go_stream << SURFACE_INSTANCE_TYPE << ' ' << MAJOR_VERSION << ' '
139 << MINOR_VERSION << " 0\n";
140
141 // write basic surface properties
142 const int& dim = surf->idim;
143 const int rational = (surf->ikind % 2 == 0) ? 1 : 0;
144 go_stream << dim << ' ' << rational << '\n';
145
146 // writing basis information
147 write_basis(go_stream, surf->in1, surf->ik1, surf->et1);
148 write_basis(go_stream, surf->in2, surf->ik2, surf->et2);
149
150 // writing control points
151 int coef_size = surf->in1 * surf->in2 * (rational ? dim + 1 : dim);
152 const double* coef_pointer = rational ? surf->rcoef : surf->ecoef;
153 for (int i = 0; i < coef_size; ++i) {
154 go_stream << coef_pointer[i] << ' ';
155 }
156 go_stream << endl;
157 }
158
159
160 //===========================================================================
writeGoCurve(SISLCurve * curve,std::ostream & go_stream)161 void writeGoCurve(SISLCurve* curve, std::ostream& go_stream)
162 //===========================================================================
163 {
164 if (!curve) {
165 throw runtime_error("zero pointer given to writeGoCurve()");
166 }
167
168 // write standard header
169 go_stream << CURVE_INSTANCE_TYPE << ' ' << MAJOR_VERSION << ' '
170 << MINOR_VERSION << " 0\n";
171
172 // write basic curve properties
173 const int& dim = curve->idim;
174 const int rational = (curve->ikind % 2 == 0) ? 1 : 0;
175 go_stream << dim << ' ' << rational << '\n';
176
177 // write bspline basis information
178 write_basis(go_stream, curve->in, curve->ik, curve->et);
179
180 // write control points
181 int coef_size = curve->in * (rational ? (dim + 1) : dim);
182 const double* coef_pointer = rational ? curve->rcoef : curve->ecoef;
183 for (int i = 0; i < coef_size; ++i) {
184 go_stream << coef_pointer[i] << ' ';
185 }
186 go_stream << endl;
187 }
188
189
190 //===========================================================================
readGoCurve(istream & go_stream)191 SISLCurve* readGoCurve(istream& go_stream)
192 //===========================================================================
193 {
194 if (determine_go_instance_type(go_stream) != CURVE_INSTANCE_TYPE) {
195 throw runtime_error("stream given to readGoCurve() does not contain curve.");
196 }
197
198 // reading basic curve properties
199 int kind, dim, rational;
200 go_stream >> dim >> rational;
201 kind = rational ? 2 : 1;
202
203 // reading bspline basis information
204 int num_coefs, order;
205 vector<double> knots;
206 read_basis(go_stream, num_coefs, order, knots);
207
208 // reading control points
209 int coef_size = num_coefs * (rational ? (dim + 1) : dim);
210 vector<double> coef(coef_size);
211 for (int i = 0; i < coef_size; ++i) {
212 go_stream >> coef[i];
213 }
214
215 int copy = 1; // flag that the input arrays (knots, coef) should be _copied_
216 return newCurve(num_coefs, order, &knots[0], &coef[0], kind, dim, copy);
217
218 }
219
220
221 //===========================================================================
writeGoPoints(int num_points,double * coords,std::ostream & go_stream)222 void writeGoPoints(int num_points, double* coords, std::ostream& go_stream)
223 //===========================================================================
224 {
225 if (!coords) {
226 throw runtime_error("zero coordinate pointer given to writeGoPoints.");
227 }
228 // write standard header
229 go_stream << POINTCLOUD_INSTANCE_TYPE << ' ' << MAJOR_VERSION << ' '
230 << MINOR_VERSION << " 4 255 255 0 255\n";
231
232 // write the number of points
233 go_stream << num_points << '\n';
234
235 // write point coordinates
236 for (int i = 0; i < num_points * 3; ++i) {
237 go_stream << coords[i];
238 if ((i+1) % 3) {
239 go_stream << ' ';
240 } else {
241 go_stream << '\n';
242 }
243 }
244 go_stream << endl;
245 }
246
247 //===========================================================================
readGoPoints(std::vector<double> & coords,std::istream & go_stream)248 void readGoPoints(std::vector<double>& coords, std::istream& go_stream)
249 //===========================================================================
250 {
251 if (determine_go_instance_type(go_stream) != POINTCLOUD_INSTANCE_TYPE) {
252 throw runtime_error("stream given to readGoPoints() does not contain pointcloud.");
253 }
254 // read away extra header information
255 for (int dummy, i = 0; i < 4; ++i) {
256 go_stream >> dummy;
257 }
258
259 int num_points;
260 go_stream >> num_points;
261 coords.resize(num_points * 3);
262
263 // read point coordinates
264 for (int i = 0; i < (int)coords.size(); ++i) {
265 go_stream >> coords[i];
266 }
267 }
268