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.euclidean.threed; 018 019import java.util.Arrays; 020import java.util.Collection; 021import java.util.List; 022import java.util.stream.Stream; 023 024import org.apache.commons.geometry.core.partitioning.BoundarySource; 025import org.apache.commons.geometry.core.precision.DoublePrecisionContext; 026import org.apache.commons.geometry.euclidean.threed.line.LineConvexSubset3D; 027import org.apache.commons.geometry.euclidean.threed.line.LinecastPoint3D; 028import org.apache.commons.geometry.euclidean.threed.line.Linecastable3D; 029import org.apache.commons.geometry.euclidean.threed.mesh.SimpleTriangleMesh; 030import org.apache.commons.geometry.euclidean.threed.mesh.TriangleMesh; 031 032/** Extension of the {@link BoundarySource} interface for Euclidean 3D space. 033 */ 034public interface BoundarySource3D extends BoundarySource<PlaneConvexSubset>, Linecastable3D { 035 036 /** Return a BSP tree constructed from the boundaries contained in this instance. This is 037 * a convenience method for quickly constructing BSP trees and may produce unbalanced trees 038 * with unacceptable performance characteristics when used with large numbers of boundaries. 039 * In these cases, alternate tree construction approaches should be used, such as 040 * {@link RegionBSPTree3D.PartitionedRegionBuilder3D}. 041 * @return a BSP tree constructed from the boundaries in this instance 042 * @see RegionBSPTree3D#partitionedRegionBuilder() 043 */ 044 default RegionBSPTree3D toTree() { 045 final RegionBSPTree3D tree = RegionBSPTree3D.empty(); 046 tree.insert(this); 047 048 return tree; 049 } 050 051 /** Construct a triangle mesh from the boundaries in this instance. 052 * @param precision precision context used in boundaries generated by the resulting mesh 053 * @return a triangle mesh representing the boundaries in this instance 054 * @throws IllegalStateException if any boundary in this boundary source is infinite 055 */ 056 default TriangleMesh toTriangleMesh(final DoublePrecisionContext precision) { 057 return SimpleTriangleMesh.from(this, precision); 058 } 059 060 /** Return the boundaries of this instance as a stream of {@link Triangle3D} 061 * instances. An {@link IllegalStateException} exception is thrown while reading 062 * from the stream if any boundary cannot be converted to a triangle (i.e. if it 063 * has infinite size). 064 * @return a stream of triangles representing the instance boundaries 065 * @see org.apache.commons.geometry.euclidean.threed.PlaneSubset#toTriangles() 066 */ 067 default Stream<Triangle3D> triangleStream() { 068 return boundaryStream().flatMap(b -> b.toTriangles().stream()); 069 } 070 071 /** {@inheritDoc} */ 072 @Override 073 default List<LinecastPoint3D> linecast(final LineConvexSubset3D subset) { 074 return new BoundarySourceLinecaster3D(this).linecast(subset); 075 } 076 077 /** {@inheritDoc} */ 078 @Override 079 default LinecastPoint3D linecastFirst(final LineConvexSubset3D subset) { 080 return new BoundarySourceLinecaster3D(this).linecastFirst(subset); 081 } 082 083 /** Get a {@link Bounds3D} object defining the axis-aligned box containing all vertices 084 * in the boundaries for this instance. Null is returned if any boundary is infinite 085 * or no vertices are found. 086 * @return the bounding box for this instance or null if no valid bounds could be determined 087 */ 088 default Bounds3D getBounds() { 089 return new BoundarySourceBoundsBuilder3D().getBounds(this); 090 } 091 092 /** Return a {@link BoundarySource3D} instance containing the given boundaries. 093 * @param boundaries boundaries to include in the boundary source 094 * @return a boundary source containing the given boundaries 095 */ 096 static BoundarySource3D from(final PlaneConvexSubset... boundaries) { 097 return from(Arrays.asList(boundaries)); 098 } 099 100 /** Return a {@link BoundarySource3D} instance containing the given boundaries. The given 101 * collection is used directly as the source of the boundaries; no copy is made. 102 * @param boundaries boundaries to include in the boundary source 103 * @return a boundary source containing the given boundaries 104 */ 105 static BoundarySource3D from(final Collection<PlaneConvexSubset> boundaries) { 106 return boundaries::stream; 107 } 108}