1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.geometry.io.euclidean.threed;
18
19 import java.net.URL;
20 import java.nio.file.Path;
21 import java.util.Collection;
22 import java.util.stream.Stream;
23
24 import org.apache.commons.geometry.euclidean.threed.BoundarySource3D;
25 import org.apache.commons.geometry.euclidean.threed.PlaneConvexSubset;
26 import org.apache.commons.geometry.euclidean.threed.Triangle3D;
27 import org.apache.commons.geometry.euclidean.threed.mesh.TriangleMesh;
28 import org.apache.commons.geometry.io.core.GeometryFormat;
29 import org.apache.commons.geometry.io.core.input.FileGeometryInput;
30 import org.apache.commons.geometry.io.core.input.GeometryInput;
31 import org.apache.commons.geometry.io.core.input.UrlGeometryInput;
32 import org.apache.commons.geometry.io.core.output.FileGeometryOutput;
33 import org.apache.commons.geometry.io.core.output.GeometryOutput;
34 import org.apache.commons.numbers.core.Precision;
35
36 /** Utility class providing convenient access to 3D IO functionality. The static read and write methods here
37 * delegate to a default {@link #getDefaultManager() BoundaryIOManager3D} instance. The default
38 * configuration should be sufficient for most purposes. If customization is required, consider directly
39 * creating and configuring and a {@link BoundaryIOManager3D} instance.
40 *
41 * <p><strong>Examples</strong></p>
42 * <p>The example below reads an OBJ file as a stream of triangles, transforms each triangle, and writes the
43 * result as a CSV file. The data formats are inferred from the input and output file extensions.</p>
44 * <pre>
45 * GeometryInput input = new FileGeometryInput(Paths.get("orig.obj"));
46 * GeometryOutput scaledOutput = new FileGeometryOutput(Paths.get("scaled.csv"));
47 * AffineTransformMatrix3D transform = AffineTransformMatrix3D.createScale(2);
48 *
49 * // Use the input triangle stream in a try-with-resources statement to ensure
50 * // all resources are properly released.
51 * try (Stream<Triangle3D> stream = IO3D.triangles(input, null, precision)) {
52 * IO3D.write(stream.map(t -> t.transform(transform)), scaledOutput, null);
53 * }
54 * </pre>
55 * @see BoundaryIOManager3D
56 */
57 public final class IO3D {
58
59 /** Utility class; no instantiation. */
60 private IO3D() {}
61
62 /** Get a {@link FacetDefinitionReader} for reading facet information from the given file path.
63 * The data format is determined by the file extension of the argument.
64 * @param path path to obtain a reader for
65 * @return facet definition reader
66 * @throws IllegalArgumentException if no handler has been registered with the
67 * {@link #getDefaultManager() default manager} for the input format
68 * @throws IllegalStateException if a data format error occurs
69 * @throws java.io.UncheckedIOException if an I/O error occurs
70 * @see BoundaryIOManager3D#facetDefinitionReader(GeometryInput, GeometryFormat)
71 */
72 public static FacetDefinitionReader facetDefinitionReader(final Path path) {
73 return facetDefinitionReader(new FileGeometryInput(path), null);
74 }
75
76 /** Get a {@link FacetDefinitionReader} for reading facet information from the given URL.
77 * The data format is determined by the file extension of the argument.
78 * @param url URL to read from
79 * @return facet definition reader
80 * @throws IllegalArgumentException if no handler has been registered with the
81 * {@link #getDefaultManager() default manager} for the input format
82 * @throws IllegalStateException if a data format error occurs
83 * @throws java.io.UncheckedIOException if an I/O error occurs
84 * @see BoundaryIOManager3D#facetDefinitionReader(GeometryInput, GeometryFormat)
85 */
86 public static FacetDefinitionReader facetDefinitionReader(final URL url) {
87 return facetDefinitionReader(new UrlGeometryInput(url), null);
88 }
89
90 /** Get a {@link FacetDefinitionReader} for reading facet information from the given input.
91 * @param in input to read from
92 * @param fmt format of the input; if null, the format is determined implicitly from the
93 * file extension of the input {@link GeometryInput#getFileName() file name}
94 * @return facet definition reader
95 * @throws IllegalArgumentException if no handler has been registered with the
96 * {@link #getDefaultManager() default manager} for the input format
97 * @throws IllegalStateException if a data format error occurs
98 * @throws java.io.UncheckedIOException if an I/O error occurs
99 * @see BoundaryIOManager3D#facetDefinitionReader(GeometryInput, GeometryFormat)
100 */
101 public static FacetDefinitionReader facetDefinitionReader(final GeometryInput in, final GeometryFormat fmt) {
102 return getDefaultManager().facetDefinitionReader(in, fmt);
103 }
104
105 /** Return a {@link Stream} providing access to all facets from the given file path. The data format
106 * is determined by the file extension of the argument.
107 *
108 * <p>The underlying input stream is closed when the returned stream is closed. Callers should
109 * therefore use the returned stream in a try-with-resources statement to ensure that all
110 * resources are properly released. Ex:
111 * </p>
112 * <pre>
113 * try (Stream<FacetDefinition> stream = IO3D.facets(path)) {
114 * // access stream content
115 * }
116 * </pre>
117 * <p>The following exceptions may be thrown during stream iteration:
118 * <ul>
119 * <li>{@link IllegalStateException} if a data format error occurs</li>
120 * <li>{@link java.io.UncheckedIOException UncheckedIOException} if an I/O error occurs</li>
121 * </ul>
122 * @param path file path to read from
123 * @return stream providing access to the facets in the specified file
124 * @throws IllegalArgumentException if no handler has been registered with the
125 * {@link #getDefaultManager() default manager} for the input format
126 * @throws IllegalStateException if a data format error occurs during stream creation
127 * @throws java.io.UncheckedIOException if an I/O error occurs during stream creation
128 * @see BoundaryIOManager3D#facets(GeometryInput, GeometryFormat)
129 */
130 public static Stream<FacetDefinition> facets(final Path path) {
131 return facets(new FileGeometryInput(path), null);
132 }
133
134 /** Return a {@link Stream} providing access to all facets from the given URL. he data format
135 * is determined by the file extension of the argument.
136 *
137 * <p>The underlying input stream is closed when the returned stream is closed. Callers should
138 * therefore use the returned stream in a try-with-resources statement to ensure that all
139 * resources are properly released. Ex:
140 * </p>
141 * <pre>
142 * try (Stream<FacetDefinition> stream = IO3D.facets(url)) {
143 * // access stream content
144 * }
145 * </pre>
146 * <p>The following exceptions may be thrown during stream iteration:
147 * <ul>
148 * <li>{@link IllegalStateException} if a data format error occurs</li>
149 * <li>{@link java.io.UncheckedIOException UncheckedIOException} if an I/O error occurs</li>
150 * </ul>
151 * @param url URL to read from
152 * @return stream providing access to the facets from the specified URL
153 * @throws IllegalArgumentException if no handler has been registered with the
154 * {@link #getDefaultManager() default manager} for the input format
155 * @throws IllegalStateException if a data format error occurs during stream creation
156 * @throws java.io.UncheckedIOException if an I/O error occurs during stream creation
157 * @see BoundaryIOManager3D#facets(GeometryInput, GeometryFormat)
158 */
159 public static Stream<FacetDefinition> facets(final URL url) {
160 return facets(new UrlGeometryInput(url), null);
161 }
162
163 /** Return a {@link Stream} providing access to all facets from the given input. The underlying input
164 * stream is closed when the returned stream is closed. Callers should therefore use the returned stream
165 * in a try-with-resources statement to ensure that all resources are properly released.
166 * <pre>
167 * try (Stream<FacetDefinition> stream = IO3D.facets(in, fmt)) {
168 * // access stream content
169 * }
170 * </pre>
171 * <p>The following exceptions may be thrown during stream iteration:
172 * <ul>
173 * <li>{@link IllegalStateException} if a data format error occurs</li>
174 * <li>{@link java.io.UncheckedIOException UncheckedIOException} if an I/O error occurs</li>
175 * </ul>
176 * @param in input to read from
177 * @param fmt format of the input; if null, the format is determined implicitly from the
178 * file extension of the input {@link GeometryInput#getFileName() file name}
179 * @return stream providing access to the facets in the input
180 * @throws IllegalArgumentException if no read handler has been registered with the
181 * {@link #getDefaultManager() default manager} for the input format
182 * @throws IllegalStateException if a data format error occurs during stream creation
183 * @throws java.io.UncheckedIOException if an I/O error occurs during stream creation
184 * @see BoundaryIOManager3D#facets(GeometryInput, GeometryFormat)
185 */
186 public static Stream<FacetDefinition> facets(final GeometryInput in, final GeometryFormat fmt) {
187 return getDefaultManager().facets(in, fmt);
188 }
189
190 /** Return a {@link Stream} providing access to all boundaries from the given file path. The
191 * data format is determined by the file extension of the argument.
192 *
193 * <p>The underlying input stream is closed when the returned stream is closed. Callers should
194 * therefore use the returned stream in a try-with-resources statement to ensure that all
195 * resources are properly released. Ex:
196 * </p>
197 * <pre>
198 * try (Stream<PlaneConvexSubset> stream = IO3D.boundaries(path, precision)) {
199 * // access stream content
200 * }
201 * </pre>
202 * <p>The following exceptions may be thrown during stream iteration:
203 * <ul>
204 * <li>{@link IllegalArgumentException} if mathematically invalid data is encountered</li>
205 * <li>{@link IllegalStateException} if a data format error occurs</li>
206 * <li>{@link java.io.UncheckedIOException UncheckedIOException} if an I/O error occurs</li>
207 * </ul>
208 * @param path file path to read from
209 * @param precision precision context used for floating point comparisons
210 * @return stream providing access to the boundaries in the specified file
211 * @throws IllegalArgumentException if no read handler has been registered with the
212 * {@link #getDefaultManager() default manager} for the input format
213 * @throws IllegalStateException if a data format error occurs during stream creation
214 * @throws java.io.UncheckedIOException if an I/O error occurs during stream creation
215 * @see BoundaryIOManager3D#boundaries(GeometryInput, GeometryFormat, Precision.DoubleEquivalence)
216 */
217 public static Stream<PlaneConvexSubset> boundaries(final Path path, final Precision.DoubleEquivalence precision) {
218 return boundaries(new FileGeometryInput(path), null, precision);
219 }
220
221 /** Return a {@link Stream} providing access to all boundaries from the given URL. The data
222 * format is determined by the file extension of the argument.
223 *
224 * <p>The underlying input stream is closed when the returned stream is closed. Callers should
225 * therefore use the returned stream in a try-with-resources statement to ensure that all
226 * resources are properly released. Ex:
227 * </p>
228 * <pre>
229 * try (Stream<PlaneConvexSubset> stream = IO3D.boundaries(url, precision)) {
230 * // access stream content
231 * }
232 * </pre>
233 * <p>The following exceptions may be thrown during stream iteration:
234 * <ul>
235 * <li>{@link IllegalArgumentException} if mathematically invalid data is encountered</li>
236 * <li>{@link IllegalStateException} if a data format error occurs</li>
237 * <li>{@link java.io.UncheckedIOException UncheckedIOException} if an I/O error occurs</li>
238 * </ul>
239 * @param url URL to read from
240 * @param precision precision context used for floating point comparisons
241 * @return stream providing access to the boundaries in the specified URL
242 * @throws IllegalArgumentException if no read handler has been registered with the
243 * {@link #getDefaultManager() default manager} for the input format
244 * @throws IllegalStateException if a data format error occurs during stream creation
245 * @throws java.io.UncheckedIOException if an I/O error occurs during stream creation
246 * @see BoundaryIOManager3D#boundaries(GeometryInput, GeometryFormat, Precision.DoubleEquivalence)
247 */
248 public static Stream<PlaneConvexSubset> boundaries(final URL url, final Precision.DoubleEquivalence precision) {
249 return boundaries(new UrlGeometryInput(url), null, precision);
250 }
251
252 /** Return a {@link Stream} providing access to all boundaries from the given input. The underlying input
253 * stream is closed when the returned stream is closed. Callers should therefore use the returned stream
254 * in a try-with-resources statement to ensure that all resources are properly released. Ex:
255 * <pre>
256 * try (Stream<H> stream = IO3D.boundaries(in, fmt, precision)) {
257 * // access stream content
258 * }
259 * </pre>
260 * <p>The following exceptions may be thrown during stream iteration:
261 * <ul>
262 * <li>{@link IllegalArgumentException} if mathematically invalid data is encountered</li>
263 * <li>{@link IllegalStateException} if a data format error occurs</li>
264 * <li>{@link java.io.UncheckedIOException UncheckedIOException} if an I/O error occurs</li>
265 * </ul>
266 * @param in input to read boundaries from
267 * @param fmt format of the input; if null, the format is determined implicitly from the
268 * file extension of the input {@link GeometryInput#getFileName() file name}
269 * @param precision precision context used for floating point comparisons
270 * @return stream providing access to the boundaries in the input
271 * @throws IllegalArgumentException if no read handler is registered with the
272 * {@link #getDefaultManager() default manager} for the input format
273 * @throws IllegalStateException if a data format error occurs during stream creation
274 * @throws java.io.UncheckedIOException if an I/O error occurs during stream creation
275 * @see BoundaryIOManager3D#boundaries(GeometryInput, GeometryFormat, Precision.DoubleEquivalence)
276 */
277 public static Stream<PlaneConvexSubset> boundaries(final GeometryInput in, final GeometryFormat fmt,
278 final Precision.DoubleEquivalence precision) {
279 return getDefaultManager().boundaries(in, fmt, precision);
280 }
281
282 /** Return a {@link Stream} providing access to all triangles from the given file path. The data
283 * format is determined by the file extension of the argument.
284 *
285 * <p>The underlying input stream is closed when the returned stream is closed. Callers should
286 * therefore use the returned stream in a try-with-resources statement to ensure that all
287 * resources are properly released. Ex:
288 * </p>
289 * <pre>
290 * try (Stream<Triangle3D> stream = IO3D.triangles(path, precision)) {
291 * // access stream content
292 * }
293 * </pre>
294 * <p>The following exceptions may be thrown during stream iteration:
295 * <ul>
296 * <li>{@link IllegalArgumentException} if mathematically invalid data is encountered</li>
297 * <li>{@link IllegalStateException} if a data format error occurs</li>
298 * <li>{@link java.io.UncheckedIOException UncheckedIOException} if an I/O error occurs</li>
299 * </ul>
300 * @param path file path to read from
301 * @param precision precision context used for floating point comparisons
302 * @return stream providing access to the triangles in the specified file
303 * @throws IllegalArgumentException if no read handler is registered with the
304 * {@link #getDefaultManager() default manager} for the input format
305 * @throws IllegalStateException if a data format error occurs during stream creation
306 * @throws java.io.UncheckedIOException if an I/O error occurs during stream creation
307 * @see BoundaryIOManager3D#triangles(GeometryInput, GeometryFormat, Precision.DoubleEquivalence)
308 */
309 public static Stream<Triangle3D> triangles(final Path path, final Precision.DoubleEquivalence precision) {
310 return triangles(new FileGeometryInput(path), null, precision);
311 }
312
313 /** Return a {@link Stream} providing access to all triangles from the given URL. The data format
314 * is determined by the file extension of the argument.
315 *
316 * <p>The underlying input stream is closed when the returned stream is closed. Callers should
317 * therefore use the returned stream in a try-with-resources statement to ensure that all
318 * resources are properly released. Ex:
319 * </p>
320 * <pre>
321 * try (Stream<Triangle3D> stream = IO3D.triangles(url, precision)) {
322 * // access stream content
323 * }
324 * </pre>
325 * <p>The following exceptions may be thrown during stream iteration:
326 * <ul>
327 * <li>{@link IllegalArgumentException} if mathematically invalid data is encountered</li>
328 * <li>{@link IllegalStateException} if a data format error occurs</li>
329 * <li>{@link java.io.UncheckedIOException UncheckedIOException} if an I/O error occurs</li>
330 * </ul>
331 * @param url URL to read from
332 * @param precision precision context used for floating point comparisons
333 * @return stream providing access to the triangles from the specified URL
334 * @throws IllegalArgumentException if no read handler is registered with the
335 * {@link #getDefaultManager() default manager} for the input format
336 * @throws IllegalStateException if a data format error occurs during stream creation
337 * @throws java.io.UncheckedIOException if an I/O error occurs during stream creation
338 * @see BoundaryIOManager3D#triangles(GeometryInput, GeometryFormat, Precision.DoubleEquivalence)
339 */
340 public static Stream<Triangle3D> triangles(final URL url, final Precision.DoubleEquivalence precision) {
341 return triangles(new UrlGeometryInput(url), null, precision);
342 }
343
344 /** Return a {@link Stream} providing access to all triangles from the given input. The underlying input
345 * stream is closed when the returned stream is closed. Callers should therefore use the returned stream
346 * in a try-with-resources statement to ensure that all resources are properly released.
347 * <pre>
348 * try (Stream<Triangle3D> stream = IO3D.triangles(in, fmt, precision)) {
349 * // access stream content
350 * }
351 * </pre>
352 * <p>The following exceptions may be thrown during stream iteration:
353 * <ul>
354 * <li>{@link IllegalArgumentException} if mathematically invalid data is encountered</li>
355 * <li>{@link IllegalStateException} if a data format error occurs</li>
356 * <li>{@link java.io.UncheckedIOException UncheckedIOException} if an I/O error occurs</li>
357 * </ul>
358 * @param in input to read from
359 * @param fmt format of the input; if null, the format is determined implicitly from the
360 * file extension of the input {@link GeometryInput#getFileName() file name}
361 * @param precision precision context used for floating point comparisons
362 * @return stream providing access to the triangles in the input
363 * @throws IllegalArgumentException if no read handler is registered with the
364 * {@link #getDefaultManager() default manager} for the input format
365 * @throws IllegalStateException if a data format error occurs during stream creation
366 * @throws java.io.UncheckedIOException if an I/O error occurs during stream creation
367 * @see BoundaryIOManager3D#triangles(GeometryInput, GeometryFormat, Precision.DoubleEquivalence)
368 */
369 public static Stream<Triangle3D> triangles(final GeometryInput in, final GeometryFormat fmt,
370 final Precision.DoubleEquivalence precision) {
371 return getDefaultManager().triangles(in, fmt, precision);
372 }
373
374 /** Return a {@link BoundarySource3D} containing all boundaries from the file at the
375 * given path. The data format is determined from the file extension. A runtime exception may be
376 * thrown if mathematically invalid boundaries are encountered.
377 * @param path file path to read from
378 * @param precision precision context used for floating point comparisons
379 * @return object containing all boundaries from the file at the given path
380 * @throws IllegalArgumentException if mathematically invalid data is encountered or no read handler
381 * is registered with the {@link #getDefaultManager() default manager} for the input format
382 * @throws IllegalStateException if a data format error occurs
383 * @throws java.io.UncheckedIOException if an I/O error occurs
384 * @see BoundaryIOManager3D#read(GeometryInput, GeometryFormat, Precision.DoubleEquivalence)
385 */
386 public static BoundarySource3D read(final Path path, final Precision.DoubleEquivalence precision) {
387 return read(new FileGeometryInput(path), null, precision);
388 }
389
390 /** Return a {@link BoundarySource3D} containing all boundaries from the given URL. The data
391 * format is determined from the file extension of the URL path. A runtime exception may be
392 * thrown if mathematically invalid boundaries are encountered.
393 * @param url URL to read from
394 * @param precision precision context used for floating point comparisons
395 * @return object containing all boundaries from the given URL
396 * @throws IllegalArgumentException if mathematically invalid data is encountered or no read handler
397 * is registered with the {@link #getDefaultManager() default manager} for the input format
398 * @throws IllegalStateException if a data format error occurs
399 * @throws java.io.UncheckedIOException if an I/O error occurs
400 * @see BoundaryIOManager3D#read(GeometryInput, GeometryFormat, Precision.DoubleEquivalence)
401 */
402 public static BoundarySource3D read(final URL url, final Precision.DoubleEquivalence precision) {
403 return read(new UrlGeometryInput(url), null, precision);
404 }
405
406 /** Return a {@link BoundarySource3D} containing all boundaries from the given input. A runtime
407 * exception may be thrown if mathematically invalid boundaries are encountered.
408 * @param in input to read boundaries from
409 * @param fmt format of the input; if null, the format is determined implicitly from the
410 * file extension of the input {@link GeometryInput#getFileName() file name}
411 * @param precision precision context used for floating point comparisons
412 * @return object containing all boundaries from the input
413 * @throws IllegalArgumentException if mathematically invalid data is encountered or no read handler
414 * is registered with the {@link #getDefaultManager() default manager} for the input format
415 * @throws IllegalStateException if a data format error occurs
416 * @throws java.io.UncheckedIOException if an I/O error occurs
417 * @see BoundaryIOManager3D#read(GeometryInput, GeometryFormat, Precision.DoubleEquivalence)
418 */
419 public static BoundarySource3D read(final GeometryInput in, final GeometryFormat fmt,
420 final Precision.DoubleEquivalence precision) {
421 return getDefaultManager().read(in, fmt, precision);
422 }
423
424 /** Return a {@link TriangleMesh} containing all triangles from the given file path. The data
425 * format is determined from the file extension of the path. A runtime exception may be
426 * thrown if mathematically invalid boundaries are encountered.
427 * @param path file path to read from
428 * @param precision precision context used for floating point comparisons
429 * @return mesh containing all triangles from the given file path
430 * @throws IllegalArgumentException if mathematically invalid data is encountered or no read handler
431 * is registered with the {@link #getDefaultManager() default manager} for the input format
432 * @throws IllegalStateException if a data format error occurs
433 * @throws java.io.UncheckedIOException if an I/O error occurs
434 * @see BoundaryIOManager3D#readTriangleMesh(GeometryInput, GeometryFormat, Precision.DoubleEquivalence)
435 */
436 public static TriangleMesh readTriangleMesh(final Path path, final Precision.DoubleEquivalence precision) {
437 return readTriangleMesh(new FileGeometryInput(path), null, precision);
438 }
439
440 /** Return a {@link TriangleMesh} containing all triangles from the given URL. The data
441 * format is determined from the file extension of the URL path. A runtime exception may be
442 * thrown if mathematically invalid boundaries are encountered.
443 * @param url URL to read from
444 * @param precision precision context used for floating point comparisons
445 * @return mesh containing all triangles from the given URL
446 * @throws IllegalArgumentException if mathematically invalid data is encountered or no read handler
447 * is registered with the {@link #getDefaultManager() default manager} for the input format
448 * @throws IllegalStateException if a data format error occurs
449 * @throws java.io.UncheckedIOException if an I/O error occurs
450 * @see BoundaryIOManager3D#readTriangleMesh(GeometryInput, GeometryFormat, Precision.DoubleEquivalence)
451 */
452 public static TriangleMesh readTriangleMesh(final URL url, final Precision.DoubleEquivalence precision) {
453 return readTriangleMesh(new UrlGeometryInput(url), null, precision);
454 }
455
456 /** Return a {@link TriangleMesh} containing all triangles from the given input. A runtime exception
457 * may be thrown if mathematically invalid boundaries are encountered.
458 * @param in input to read from
459 * @param fmt format of the input; if null, the format is determined implicitly from the
460 * file extension of the input {@link GeometryInput#getFileName() file name}
461 * @param precision precision context used for floating point comparisons
462 * @return a mesh containing all triangles from the input
463 * @throws IllegalArgumentException if mathematically invalid data is encountered or no read handler
464 * is registered with the {@link #getDefaultManager() default manager} for the input format
465 * @throws IllegalStateException if a data format error occurs
466 * @throws java.io.UncheckedIOException if an I/O error occurs
467 * @see BoundaryIOManager3D#readTriangleMesh(GeometryInput, GeometryFormat, Precision.DoubleEquivalence)
468 */
469 public static TriangleMesh readTriangleMesh(final GeometryInput in, final GeometryFormat fmt,
470 final Precision.DoubleEquivalence precision) {
471 return getDefaultManager().readTriangleMesh(in, fmt, precision);
472 }
473
474 /** Write all boundaries in the stream to given file path. The data format is determined by
475 * the file extension of the target path. If the target path already exists, it is overwritten.
476 *
477 * <p>This method does not explicitly close the {@code boundaries} stream. Callers should use the stream
478 * in a try-with-resources statement outside of this method if the stream is required to be closed.</p>
479 * @param boundaries stream containing boundaries to write
480 * @param path file path to write to
481 * @throws IllegalArgumentException if no write handler is registered with the
482 * {@link #getDefaultManager() default manager} for the output format
483 * @throws java.io.UncheckedIOException if an I/O error occurs
484 * @see BoundaryIOManager3D#write(Stream, GeometryOutput, GeometryFormat)
485 */
486 public static void write(final Stream<? extends PlaneConvexSubset> boundaries, final Path path) {
487 write(boundaries, new FileGeometryOutput(path), null);
488 }
489
490 /** Write all boundaries in the stream to the output.
491 *
492 * <p>This method does not explicitly close the {@code boundaries} stream. Callers should use the stream
493 * in a try-with-resources statement outside of this method if the stream is required to be closed.</p>
494 * @param boundaries stream containing boundaries to write
495 * @param out output to write to
496 * @param fmt format of the output; if null, the format is determined implicitly from the
497 * file extension of the output {@link GeometryOutput#getFileName() file name}
498 * @throws IllegalArgumentException if no write handler is registered with the
499 * {@link #getDefaultManager() default manager} for the output format
500 * @throws java.io.UncheckedIOException if an I/O error occurs
501 * @see BoundaryIOManager3D#write(Stream, GeometryOutput, GeometryFormat)
502 */
503 public static void write(final Stream<? extends PlaneConvexSubset> boundaries, final GeometryOutput out,
504 final GeometryFormat fmt) {
505 getDefaultManager().write(boundaries, out, fmt);
506 }
507
508 /** Write all boundaries from {@code src} to the given file path. The data format
509 * is determined by the file extension of the target path. If the target path already exists,
510 * it is overwritten.
511 * @param src boundary source containing the boundaries to write
512 * @param path file path to write to
513 * @throws IllegalArgumentException if no write handler is registered with the
514 * {@link #getDefaultManager() default manager} for the output format
515 * @throws java.io.UncheckedIOException if an I/O error occurs
516 * @see org.apache.commons.geometry.io.core.BoundaryIOManager#write(
517 * org.apache.commons.geometry.core.partitioning.BoundarySource, GeometryOutput, GeometryFormat)
518 */
519 public static void write(final BoundarySource3D src, final Path path) {
520 write(src, new FileGeometryOutput(path), null);
521 }
522
523 /** Write all boundaries from {@code src} to the given output.
524 * @param src boundary source containing the boundaries to write
525 * @param out output to write to
526 * @param fmt format of the output; if null, the format is determined implicitly from the
527 * file extension of the output {@link GeometryOutput#getFileName() file name}
528 * @throws IllegalArgumentException if no write handler is registered with the
529 * {@link #getDefaultManager() default manager} for the output format
530 * @throws java.io.UncheckedIOException if an I/O error occurs
531 * @see org.apache.commons.geometry.io.core.BoundaryIOManager#write(
532 * org.apache.commons.geometry.core.partitioning.BoundarySource, GeometryOutput, GeometryFormat)
533 */
534 public static void write(final BoundarySource3D src, final GeometryOutput out, final GeometryFormat fmt) {
535 getDefaultManager().write(src, out, fmt);
536 }
537
538 /** Write the given facets to the file path. The data format is determined by the file extension of
539 * the target path. If the target path already exists, it is overwritten.
540 * @param facets facets to write
541 * @param path path to write to
542 * @throws IllegalArgumentException if no write handler is registered with the
543 * {@link #getDefaultManager() default manager} for the output format
544 * @throws java.io.UncheckedIOException if an I/O error occurs
545 * @see BoundaryIOManager3D#writeFacets(Collection, GeometryOutput, GeometryFormat)
546 */
547 public static void writeFacets(final Collection<? extends FacetDefinition> facets, final Path path) {
548 writeFacets(facets, new FileGeometryOutput(path), null);
549 }
550
551 /** Write the given collection of facets to the output.
552 * @param facets facets to write
553 * @param out output to write to
554 * @param fmt format of the output; if null, the format is determined implicitly from the
555 * file extension of the output {@link GeometryOutput#getFileName() file name}
556 * @throws IllegalArgumentException if no write handler is registered with the
557 * {@link #getDefaultManager() default manager} for the output format
558 * @throws java.io.UncheckedIOException if an I/O error occurs
559 * @see BoundaryIOManager3D#writeFacets(Collection, GeometryOutput, GeometryFormat)
560 */
561 public static void writeFacets(final Collection<? extends FacetDefinition> facets, final GeometryOutput out,
562 final GeometryFormat fmt) {
563 getDefaultManager().writeFacets(facets, out, fmt);
564 }
565
566 /** Write all facets in the stream to the file path. The data format is determined by the file
567 * extension of the target path. If the target path already exists, it is overwritten.
568 *
569 * <p>This method does not explicitly close the {@code facets} stream. Callers should use the stream
570 * in a try-with-resources statement outside of this method if the stream is required to be closed.</p>
571 * @param facets stream containing facets to write
572 * @param path path to write to
573 * @throws IllegalArgumentException if no write handler is registered with the
574 * {@link #getDefaultManager() default manager} for the output format
575 * @throws java.io.UncheckedIOException if an I/O error occurs
576 * @see BoundaryIOManager3D#writeFacets(Stream, GeometryOutput, GeometryFormat)
577 */
578 public static void writeFacets(final Stream<? extends FacetDefinition> facets, final Path path) {
579 writeFacets(facets, new FileGeometryOutput(path), null);
580 }
581
582 /** Write all facets in the stream to the output.
583 *
584 * <p>This method does not explicitly close the {@code facets} stream. Callers should use the stream
585 * in a try-with-resources statement outside of this method if the stream is required to be closed.</p>
586 * @param facets stream containing facets to write
587 * @param out output to write to
588 * @param fmt format of the output; if null, the format is determined implicitly from the
589 * file extension of the output {@link GeometryOutput#getFileName() file name}
590 * @throws IllegalArgumentException if no write handler is registered with the
591 * {@link #getDefaultManager() default manager} for the output format
592 * @throws java.io.UncheckedIOException if an I/O error occurs
593 * @see BoundaryIOManager3D#writeFacets(Stream, GeometryOutput, GeometryFormat)
594 */
595 public static void writeFacets(final Stream<? extends FacetDefinition> facets, final GeometryOutput out,
596 final GeometryFormat fmt) {
597 getDefaultManager().writeFacets(facets, out, fmt);
598 }
599
600 /** Get the default {@link BoundaryIOManager3D} instance.
601 * @return the default {@link BoundaryIOManager3D} instance
602 */
603 public static BoundaryIOManager3D getDefaultManager() {
604 return ManagerHolder.DEFAULT_MANAGER;
605 }
606
607 /** Class holding a reference to the default IO manager instance.
608 */
609 private static final class ManagerHolder {
610
611 /** Default IO manager instance. */
612 private static final BoundaryIOManager3D DEFAULT_MANAGER;
613
614 static {
615 DEFAULT_MANAGER = new BoundaryIOManager3D();
616 DEFAULT_MANAGER.registerDefaultHandlers();
617 }
618
619 /** Utility class; no instantiation. */
620 private ManagerHolder() {}
621 }
622 }