View Javadoc

    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.stl;
    18
    19  import java.io.ByteArrayInputStream;
    20  import java.io.IOException;
    21  import java.net.URL;
    22  import java.nio.charset.StandardCharsets;
    23  import java.util.stream.Collectors;
    24
    25  import org.apache.commons.geometry.core.GeometryTestUtils;
    26  import org.apache.commons.geometry.euclidean.threed.BoundaryList3D;
    27  import org.apache.commons.geometry.io.euclidean.EuclideanIOTestUtils;
    28  import org.apache.commons.geometry.io.euclidean.threed.FacetDefinitionReader;
    29  import org.apache.commons.geometry.io.euclidean.threed.FacetDefinitions;
    30  import org.apache.commons.numbers.core.Precision;
    31  import org.junit.jupiter.api.Assertions;
    32  import org.junit.jupiter.api.Test;
    33
    34  class StlFacetDefinitionReadersTest {
    35
    36      private static final double TEST_EPS = 1e-10;
    37
    38      private static final Precision.DoubleEquivalence TEST_PRECISION =
    39              Precision.doubleEquivalenceOfEpsilon(TEST_EPS);
    40
    41      @Test
    42      void testCreate_cubeBinaryFile() throws IOException {
    43          // arrange
    44          final URL url = EuclideanIOTestUtils.resource("/models/cube-binary.stl");
    45
    46          // act
    47          try (FacetDefinitionReader reader = StlFacetDefinitionReaders.create(url.openStream(), null)) {
    48
    49              // assert
    50              Assertions.assertEquals(BinaryStlFacetDefinitionReader.class, reader.getClass());
    51
    52              BoundaryList3D boundaries = new BoundaryList3D(EuclideanIOTestUtils.readAll(reader).stream()
    53                      .map(f -> FacetDefinitions.toPolygon(f, TEST_PRECISION))
    54                      .collect(Collectors.toList()));
    55              EuclideanIOTestUtils.assertCube(boundaries, TEST_EPS);
    56          }
    57      }
    58
    59      @Test
    60      void testCreate_cubeAsciiFile() throws IOException {
    61          // arrange
    62          final URL url = EuclideanIOTestUtils.resource("/models/cube-ascii.stl");
    63
    64          // act
    65          try (FacetDefinitionReader reader = StlFacetDefinitionReaders.create(url.openStream(), null)) {
    66
    67              // assert
    68              Assertions.assertEquals(TextStlFacetDefinitionReader.class, reader.getClass());
    69
    70              BoundaryList3D boundaries = new BoundaryList3D(EuclideanIOTestUtils.readAll(reader).stream()
    71                      .map(f -> FacetDefinitions.toPolygon(f, TEST_PRECISION))
    72                      .collect(Collectors.toList()));
    73              EuclideanIOTestUtils.assertCube(boundaries, TEST_EPS);
    74          }
    75      }
    76
    77      @Test
    78      void testCreate_nonStandardCharset_charsetGiven() {
    79          // arrange
    80          final String content = "solid test\n" +
    81                  "facet normal 1 2 3 " +
    82                  "outer loop " +
    83                      "vertex 4 5 6 " +
    84                      "vertex 7 8 9 " +
    85                      "vertex 10 11 12 " +
    86                  "endloop " +
    87              "endfacet " +
    88              "endsolid test";
    89
    90          final ByteArrayInputStream in = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_16));
    91
    92          // act
    93          try (FacetDefinitionReader reader = StlFacetDefinitionReaders.create(in, StandardCharsets.UTF_16)) {
    94
    95              // assert
    96              Assertions.assertEquals(TextStlFacetDefinitionReader.class, reader.getClass());
    97
    98              Assertions.assertNotNull(reader.readFacet());
    99              Assertions.assertNull(reader.readFacet());
    100         }
    101     }
    102
    103     @Test
    104     void testCreate_nonStandardCharset_noCharsetGiven() {
    105         // arrange
    106         final String content = "solid test\n" +
    107                 "facet normal 1 2 3 " +
    108                 "outer loop " +
    109                     "vertex 4 5 6 " +
    110                     "vertex 7 8 9 " +
    111                     "vertex 10 11 12 " +
    112                 "endloop " +
    113             "endfacet " +
    114             "endsolid test";
    115
    116         final ByteArrayInputStream in = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_16));
    117
    118         // act
    119         try (FacetDefinitionReader reader = StlFacetDefinitionReaders.create(in, null)) {
    120
    121             // assert
    122             Assertions.assertEquals(BinaryStlFacetDefinitionReader.class, reader.getClass());
    123
    124             Assertions.assertNotNull(reader.readFacet());
    125             Assertions.assertNotNull(reader.readFacet());
    126             Assertions.assertThrows(IllegalStateException.class, () -> reader.readFacet());
    127         }
    128     }
    129
    130     @Test
    131     void testCreate_notEnoughBytes() {
    132         // arrange
    133         final byte[] bytes = new byte[1];
    134         final ByteArrayInputStream in = new ByteArrayInputStream(bytes);
    135
    136         // act/assert
    137         GeometryTestUtils.assertThrowsWithMessage(
    138                 () -> StlFacetDefinitionReaders.create(in, null),
    139                 IllegalStateException.class,
    140                 "Cannot determine STL format: attempted to read 5 bytes but found only 1 available");
    141     }
    142 }