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.StringReader;
20  import java.util.Arrays;
21  import java.util.List;
22  import java.util.regex.Pattern;
23  
24  import org.apache.commons.geometry.core.GeometryTestUtils;
25  import org.apache.commons.geometry.euclidean.threed.Vector3D;
26  import org.apache.commons.geometry.io.core.test.CloseCountReader;
27  import org.apache.commons.geometry.io.euclidean.EuclideanIOTestUtils;
28  import org.apache.commons.geometry.io.euclidean.threed.FacetDefinition;
29  import org.junit.jupiter.api.Assertions;
30  import org.junit.jupiter.api.Test;
31  
32  class TextStlFacetDefinitionReaderTest {
33  
34      private static final double TEST_EPS = 1e-10;
35  
36      @Test
37      void testGetSolidName() {
38          // act/assert
39          Assertions.assertEquals("Test Name", facetReader("solid    Test Name  \r\n").getSolidName());
40          Assertions.assertEquals("Test", facetReader("solid    Test  ").getSolidName());
41          Assertions.assertNull(facetReader("solid    ").getSolidName());
42          Assertions.assertNull(facetReader("solid").getSolidName());
43      }
44  
45      @Test
46      void testClose() {
47          // arrange
48          final CloseCountReader countReader = new CloseCountReader(new StringReader(""));
49          final TextStlFacetDefinitionReader reader = new TextStlFacetDefinitionReader(countReader);
50  
51          // act
52          reader.close();
53  
54          // assert
55          Assertions.assertEquals(1, countReader.getCloseCount());
56      }
57  
58      @Test
59      void testEmpty() {
60          // arrange
61          final TextStlFacetDefinitionReader reader = facetReader(
62                  "solid \n" +
63                  "endsolid");
64  
65          // act
66          final List<FacetDefinition> facets = EuclideanIOTestUtils.readAll(reader);
67  
68          // assert
69          Assertions.assertNull(reader.getSolidName());
70  
71          Assertions.assertEquals(0, facets.size());
72          Assertions.assertNull(reader.readFacet());
73      }
74  
75      @Test
76      void testSingleFacet() {
77          // arrange
78          final TextStlFacetDefinitionReader reader = facetReader(
79                  "solid test\n" +
80                  "facet normal 1 2 3 " +
81                      "outer loop " +
82                          "vertex 4 5 6 " +
83                          "vertex 7 8 9 " +
84                          "vertex 10 11 12 " +
85                      "endloop " +
86                  "endfacet " +
87                  "endsolid test");
88  
89          // act
90          final List<FacetDefinition> facets = EuclideanIOTestUtils.readAll(reader);
91  
92          // assert
93          Assertions.assertEquals("test", reader.getSolidName());
94  
95          Assertions.assertEquals(1, facets.size());
96  
97          EuclideanIOTestUtils.assertFacetVerticesAndNormal(
98                  facets.get(0),
99                  Arrays.asList(Vector3D.of(4, 5, 6), Vector3D.of(7, 8, 9), Vector3D.of(10, 11, 12)),
100                 Vector3D.of(1, 2, 3), TEST_EPS);
101 
102         Assertions.assertNull(reader.readFacet());
103     }
104 
105     @Test
106     void testMultipleFacets() {
107         // arrange
108         final TextStlFacetDefinitionReader reader = facetReader(
109                 "solid test solid\r\n\n" +
110                 "facet normal 1 2 3 " +
111                     "outer loop " +
112                         "vertex 4 5 6 " +
113                         "vertex 7 8 9 " +
114                         "vertex 10 11 12 " +
115                     "endloop " +
116                 "endfacet " +
117                 "facet normal 0.0 0.0 0.0" +
118                     "outer loop " +
119                         "vertex 4e1 5.0e1 6.0e01 " +
120                         "vertex 70.00 80.00 \t 90.00 " +
121                         "vertex 10e+1 11e+1 12e+1 " +
122                     "endloop " +
123                 "endfacet\n" +
124                 "facet   normal 0.1 0.2 0.3 " +
125                     "outer  loop\n" +
126                         "vertex 4e-1 5e-1 6e-1 " +
127                         "vertex -0.07 \n -0.08 -0.09 " +
128                         "vertex 10e-1 11e-1 12e-1 " +
129                     "endloop\r" +
130                 "endfacet \r\n" +
131                 "endsolid test solid");
132 
133         // act
134         final List<FacetDefinition> facets = EuclideanIOTestUtils.readAll(reader);
135 
136         // assert
137         Assertions.assertEquals("test solid", reader.getSolidName());
138 
139         Assertions.assertEquals(3, facets.size());
140 
141         EuclideanIOTestUtils.assertFacetVerticesAndNormal(
142                 facets.get(0),
143                 Arrays.asList(Vector3D.of(4, 5, 6), Vector3D.of(7, 8, 9), Vector3D.of(10, 11, 12)),
144                 Vector3D.of(1, 2, 3), TEST_EPS);
145 
146         EuclideanIOTestUtils.assertFacetVerticesAndNormal(
147                 facets.get(1),
148                 Arrays.asList(Vector3D.of(40, 50, 60), Vector3D.of(70, 80, 90), Vector3D.of(100, 110, 120)),
149                 Vector3D.of(0, 0, 0), TEST_EPS);
150 
151         EuclideanIOTestUtils.assertFacetVerticesAndNormal(
152                 facets.get(2),
153                 Arrays.asList(Vector3D.of(0.4, 0.5, 0.6), Vector3D.of(-0.07, -0.08, -0.09), Vector3D.of(1, 1.1, 1.2)),
154                 Vector3D.of(0.1, 0.2, 0.3), TEST_EPS);
155 
156         Assertions.assertNull(reader.readFacet());
157     }
158 
159     @Test
160     void testNoName() {
161         // arrange
162         final TextStlFacetDefinitionReader reader = facetReader(
163                 "solid\n" +
164                 "facet normal 1 2 3 " +
165                     "outer loop " +
166                         "vertex 4 5 6 " +
167                         "vertex 7 8 9 " +
168                         "vertex 10 11 12 " +
169                     "endloop " +
170                 "endfacet " +
171                 "endsolid");
172 
173         // act
174         final List<FacetDefinition> facets = EuclideanIOTestUtils.readAll(reader);
175 
176         // assert
177         Assertions.assertNull(reader.getSolidName());
178 
179         Assertions.assertEquals(1, facets.size());
180 
181         EuclideanIOTestUtils.assertFacetVerticesAndNormal(
182                 facets.get(0),
183                 Arrays.asList(Vector3D.of(4, 5, 6), Vector3D.of(7, 8, 9), Vector3D.of(10, 11, 12)),
184                 Vector3D.of(1, 2, 3), TEST_EPS);
185 
186         Assertions.assertNull(reader.readFacet());
187     }
188 
189     @Test
190     void testContentEndsEarly() {
191         // arrange
192         final TextStlFacetDefinitionReader reader = facetReader(
193                 "solid test\n" +
194                 "facet normal 1 2 3 " +
195                     "outer loop " +
196                         "vertex 4 5 6 " +
197                         "vertex 7 8 9 " +
198                         "vertex 10 11 12 " +
199                     "endloop " +
200                 "endfacet");
201 
202         // act
203         final List<FacetDefinition> facets = EuclideanIOTestUtils.readAll(reader);
204 
205         // assert
206         Assertions.assertEquals("test", reader.getSolidName());
207 
208         Assertions.assertEquals(1, facets.size());
209 
210         EuclideanIOTestUtils.assertFacetVerticesAndNormal(
211                 facets.get(0),
212                 Arrays.asList(Vector3D.of(4, 5, 6), Vector3D.of(7, 8, 9), Vector3D.of(10, 11, 12)),
213                 Vector3D.of(1, 2, 3), TEST_EPS);
214 
215         Assertions.assertNull(reader.readFacet());
216     }
217 
218     @Test
219     void testParseErrors() {
220         // act/assert
221         assertParseError(
222                 "soli test\n" +
223                 "facet normal 1 2 3 " +
224                     "outer loop " +
225                         "vertex 4 5 6 " +
226                         "vertex 7 8 9 " +
227                         "vertex 10 11 12 " +
228                     "endloop " +
229                 "endfacet " +
230                 "endsolid test");
231         assertParseError(
232                 "solid test\n" +
233                 "facet normal 1 2 3 " +
234                     "outer loop " +
235                         "vertex abc 5 6 " +
236                         "vertex 7 8 9 " +
237                         "vertex 10 11 12 " +
238                     "endloop " +
239                 "endfacet " +
240                 "endsolid test");
241     }
242 
243     private static TextStlFacetDefinitionReader facetReader(final String content) {
244         return new TextStlFacetDefinitionReader(new StringReader(content));
245     }
246 
247     private static void assertParseError(final String content) {
248         GeometryTestUtils.assertThrowsWithMessage(
249                 () -> EuclideanIOTestUtils.readAll(facetReader(content)),
250                 IllegalStateException.class,
251                 Pattern.compile("^Parsing failed.*"));
252     }
253 }