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.obj; 18 19 import java.io.Closeable; 20 import java.io.Reader; 21 22 import org.apache.commons.geometry.euclidean.threed.Vector3D; 23 import org.apache.commons.geometry.io.core.internal.GeometryIOUtils; 24 25 /** Abstract base class for types that read OBJ polygon content using 26 * {@link PolygonObjParser}. 27 */ 28 public abstract class AbstractObjPolygonReader implements Closeable { 29 30 /** Underlying reader. */ 31 private final Reader reader; 32 33 /** OBJ polygon parser. */ 34 private final PolygonObjParser parser; 35 36 /** Construct a new instance that reads OBJ content from the given reader. 37 * @param reader reader to read characters from 38 */ 39 protected AbstractObjPolygonReader(final Reader reader) { 40 this.reader = reader; 41 this.parser = new PolygonObjParser(reader); 42 } 43 44 /** Get the flag indicating whether or not an {@link IllegalStateException} will be thrown 45 * if the OBJ content contains any keywords defining non-polygon geometric content 46 * (ex: {@code curv}). If false, non-polygon data is ignored. 47 * @return flag indicating whether or not an {@link IllegalStateException} will be thrown 48 * if non-polygon content is encountered 49 * @see PolygonObjParser#isFailOnNonPolygonKeywords() 50 */ 51 public boolean isFailOnNonPolygonKeywords() { 52 return parser.isFailOnNonPolygonKeywords(); 53 } 54 55 /** Set the flag indicating whether or not an {@link IllegalStateException} will be thrown 56 * if the OBJ content contains any keywords defining non-polygon geometric content 57 * (ex: {@code curv}). If set to false, non-polygon data is ignored. 58 * @param fail flag indicating whether or not an {@link IllegalStateException} will be thrown 59 * if non-polygon content is encountered 60 */ 61 public void setFailOnNonPolygonKeywords(final boolean fail) { 62 parser.setFailOnNonPolygonKeywords(fail); 63 } 64 65 /** {@inheritDoc} */ 66 @Override 67 public void close() { 68 GeometryIOUtils.closeUnchecked(reader); 69 } 70 71 /** Return the next face from the OBJ content or null if no face is found. 72 * @return the next face from the OBJ content or null if no face is found 73 * @throws IllegalStateException if a parsing error occurs 74 * @throws java.io.UncheckedIOException if an I/O error occurs 75 */ 76 protected PolygonObjParser.Face readFace() { 77 while (parser.nextKeyword()) { 78 switch (parser.getCurrentKeyword()) { 79 case ObjConstants.VERTEX_KEYWORD: 80 handleVertex(parser.readVector()); 81 break; 82 case ObjConstants.VERTEX_NORMAL_KEYWORD: 83 handleNormal(parser.readVector()); 84 break; 85 case ObjConstants.FACE_KEYWORD: 86 return parser.readFace(); 87 default: 88 break; 89 } 90 } 91 92 return null; 93 } 94 95 /** Method called when a vertex is found in the OBJ content. 96 * @param vertex vertex value 97 */ 98 protected abstract void handleVertex(Vector3D vertex); 99 100 /** Method called when a normal is found in the OBJ content. 101 * @param normal normal value 102 */ 103 protected abstract void handleNormal(Vector3D normal); 104 }