StlUtils.java
- /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.apache.commons.geometry.io.euclidean.threed.stl;
- import java.nio.ByteBuffer;
- import org.apache.commons.geometry.euclidean.threed.Vector3D;
- /** Utility methods for the STL format.
- */
- final class StlUtils {
- /** Utility class; no instantiation. */
- private StlUtils() { }
- /** Create a {@link ByteBuffer} with the given size and the byte order
- * appropriate for binary STL content.
- * @param capacity buffer capacity
- * @return byte buffer
- */
- static ByteBuffer byteBuffer(final int capacity) {
- return ByteBuffer.allocate(capacity)
- .order(StlConstants.BINARY_BYTE_ORDER);
- }
- /** Determine the normal that should be used for the given STL triangle vertices. If {@code normal}
- * is present and can be normalized, it is returned. Otherwise, a normal is attempted to be computed
- * using the given triangle vertices. If normal computation fails, the zero vector is returned.
- * @param p1 first point
- * @param p2 second point
- * @param p3 third point
- * @param normal defined triangle normal; may be null
- * @return STL normal for the triangle
- */
- static Vector3D determineNormal(final Vector3D p1, final Vector3D p2, final Vector3D p3,
- final Vector3D normal) {
- if (normal != null) {
- // try to normalize it
- final Vector3D normalized = normal.normalizeOrNull();
- if (normalized != null) {
- return normalized;
- }
- }
- // try to compute one from the triangle points
- final Vector3D computed = computeTriangleNormal(p1, p2, p3);
- return computed != null ?
- computed :
- Vector3D.ZERO;
- }
- /** Return true if the given points are arranged counter-clockwise relative to the
- * given normal. Returns true if {@code normal} is null.
- * @param p1 first point
- * @param p2 second point
- * @param p3 third point
- * @param normal normal; may be null, in which case the zero vector is used
- * @return true if {@code normal} is null or if the given points are arranged counter-clockwise
- * relative to {@code normal}
- */
- static boolean pointsAreCounterClockwise(final Vector3D p1, final Vector3D p2, final Vector3D p3,
- final Vector3D normal) {
- if (normal != null) {
- final Vector3D computedNormal = computeTriangleNormal(p1, p2, p3);
- if (computedNormal != null && normal.dot(computedNormal) < 0) {
- return false;
- }
- }
- return true;
- }
- /** Get the normal using the right-hand rule for the given triangle vertices. Null is returned
- * if the normal could not be computed.
- * @param p1 first point
- * @param p2 second point
- * @param p3 third point
- * @return the normal for the given triangle vertices or null if one could not be computed
- */
- private static Vector3D computeTriangleNormal(final Vector3D p1, final Vector3D p2, final Vector3D p3) {
- final Vector3D normal = p1.vectorTo(p2).cross(p1.vectorTo(p3)).normalizeOrNull();
- return normal != null ?
- normal :
- null;
- }
- }