001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.geometry.io.euclidean.threed.obj; 018 019import java.io.Closeable; 020import java.io.Reader; 021 022import org.apache.commons.geometry.euclidean.threed.Vector3D; 023import org.apache.commons.geometry.io.core.internal.GeometryIOUtils; 024 025/** Abstract base class for types that read OBJ polygon content using 026 * {@link PolygonObjParser}. 027 */ 028public abstract class AbstractObjPolygonReader implements Closeable { 029 030 /** Underlying reader. */ 031 private final Reader reader; 032 033 /** OBJ polygon parser. */ 034 private final PolygonObjParser parser; 035 036 /** Construct a new instance that reads OBJ content from the given reader. 037 * @param reader reader to read characters from 038 */ 039 protected AbstractObjPolygonReader(final Reader reader) { 040 this.reader = reader; 041 this.parser = new PolygonObjParser(reader); 042 } 043 044 /** Get the flag indicating whether or not an {@link IllegalStateException} will be thrown 045 * if the OBJ content contains any keywords defining non-polygon geometric content 046 * (ex: {@code curv}). If false, non-polygon data is ignored. 047 * @return flag indicating whether or not an {@link IllegalStateException} will be thrown 048 * if non-polygon content is encountered 049 * @see PolygonObjParser#isFailOnNonPolygonKeywords() 050 */ 051 public boolean isFailOnNonPolygonKeywords() { 052 return parser.isFailOnNonPolygonKeywords(); 053 } 054 055 /** Set the flag indicating whether or not an {@link IllegalStateException} will be thrown 056 * if the OBJ content contains any keywords defining non-polygon geometric content 057 * (ex: {@code curv}). If set to false, non-polygon data is ignored. 058 * @param fail flag indicating whether or not an {@link IllegalStateException} will be thrown 059 * if non-polygon content is encountered 060 */ 061 public void setFailOnNonPolygonKeywords(final boolean fail) { 062 parser.setFailOnNonPolygonKeywords(fail); 063 } 064 065 /** {@inheritDoc} */ 066 @Override 067 public void close() { 068 GeometryIOUtils.closeUnchecked(reader); 069 } 070 071 /** Return the next face from the OBJ content or null if no face is found. 072 * @return the next face from the OBJ content or null if no face is found 073 * @throws IllegalStateException if a parsing error occurs 074 * @throws java.io.UncheckedIOException if an I/O error occurs 075 */ 076 protected PolygonObjParser.Face readFace() { 077 while (parser.nextKeyword()) { 078 switch (parser.getCurrentKeyword()) { 079 case ObjConstants.VERTEX_KEYWORD: 080 handleVertex(parser.readVector()); 081 break; 082 case ObjConstants.VERTEX_NORMAL_KEYWORD: 083 handleNormal(parser.readVector()); 084 break; 085 case ObjConstants.FACE_KEYWORD: 086 return parser.readFace(); 087 default: 088 break; 089 } 090 } 091 092 return null; 093 } 094 095 /** Method called when a vertex is found in the OBJ content. 096 * @param vertex vertex value 097 */ 098 protected abstract void handleVertex(Vector3D vertex); 099 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}