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.euclidean.threed; 18 19 import java.util.Arrays; 20 import java.util.Collection; 21 import java.util.List; 22 import java.util.stream.Collectors; 23 import java.util.stream.Stream; 24 25 import org.apache.commons.geometry.core.partitioning.BoundarySource; 26 import org.apache.commons.geometry.euclidean.threed.line.LineConvexSubset3D; 27 import org.apache.commons.geometry.euclidean.threed.line.LinecastPoint3D; 28 import org.apache.commons.geometry.euclidean.threed.line.Linecastable3D; 29 import org.apache.commons.geometry.euclidean.threed.mesh.SimpleTriangleMesh; 30 import org.apache.commons.geometry.euclidean.threed.mesh.TriangleMesh; 31 import org.apache.commons.numbers.core.Precision; 32 33 /** Extension of the {@link BoundarySource} interface for Euclidean 3D space. 34 */ 35 public interface BoundarySource3D extends BoundarySource<PlaneConvexSubset>, Linecastable3D { 36 37 /** Return a {@link BoundaryList3D} containing the boundaries in this instance. 38 * @return a {@link BoundaryList3D} containing the boundaries in this instance 39 */ 40 default BoundaryList3D toList() { 41 final List<PlaneConvexSubset> boundaries = boundaryStream() 42 .collect(Collectors.toList()); 43 44 return new BoundaryList3D(boundaries); 45 } 46 47 /** Return a BSP tree constructed from the boundaries contained in this instance. This is 48 * a convenience method for quickly constructing BSP trees and may produce unbalanced trees 49 * with unacceptable performance characteristics when used with large numbers of boundaries. 50 * In these cases, alternate tree construction approaches should be used, such as 51 * {@link RegionBSPTree3D.PartitionedRegionBuilder3D}. 52 * @return a BSP tree constructed from the boundaries in this instance 53 * @see RegionBSPTree3D#partitionedRegionBuilder() 54 */ 55 default RegionBSPTree3D toTree() { 56 final RegionBSPTree3D tree = RegionBSPTree3D.empty(); 57 tree.insert(this); 58 59 return tree; 60 } 61 62 /** Construct a triangle mesh from the boundaries in this instance. 63 * @param precision precision context used in boundaries generated by the resulting mesh 64 * @return a triangle mesh representing the boundaries in this instance 65 * @throws IllegalStateException if any boundary in this boundary source is infinite 66 */ 67 default TriangleMesh toTriangleMesh(final Precision.DoubleEquivalence precision) { 68 return SimpleTriangleMesh.from(this, precision); 69 } 70 71 /** Return the boundaries of this instance as a stream of {@link Triangle3D} 72 * instances. An {@link IllegalStateException} exception is thrown while reading 73 * from the stream if any boundary cannot be converted to a triangle (i.e. if it 74 * has infinite size). 75 * @return a stream of triangles representing the instance boundaries 76 * @see org.apache.commons.geometry.euclidean.threed.PlaneSubset#toTriangles() 77 */ 78 default Stream<Triangle3D> triangleStream() { 79 return boundaryStream().flatMap(b -> b.toTriangles().stream()); 80 } 81 82 /** {@inheritDoc} */ 83 @Override 84 default List<LinecastPoint3D> linecast(final LineConvexSubset3D subset) { 85 return new BoundarySourceLinecaster3D(this).linecast(subset); 86 } 87 88 /** {@inheritDoc} */ 89 @Override 90 default LinecastPoint3D linecastFirst(final LineConvexSubset3D subset) { 91 return new BoundarySourceLinecaster3D(this).linecastFirst(subset); 92 } 93 94 /** Get a {@link Bounds3D} object defining the axis-aligned box containing all vertices 95 * in the boundaries for this instance. Null is returned if any boundary is infinite 96 * or no vertices are found. 97 * @return the bounding box for this instance or null if no valid bounds could be determined 98 */ 99 default Bounds3D getBounds() { 100 return new BoundarySourceBoundsBuilder3D().getBounds(this); 101 } 102 103 /** Return a {@link BoundarySource3D} instance containing the given boundaries. 104 * @param boundaries boundaries to include in the boundary source 105 * @return a boundary source containing the given boundaries 106 */ 107 static BoundarySource3D of(final PlaneConvexSubset... boundaries) { 108 return of(Arrays.asList(boundaries)); 109 } 110 111 /** Return a {@link BoundarySource3D} instance containing the given boundaries. The given 112 * collection is used directly as the source of the boundaries; no copy is made. 113 * @param boundaries boundaries to include in the boundary source 114 * @return a boundary source containing the given boundaries 115 */ 116 static BoundarySource3D of(final Collection<PlaneConvexSubset> boundaries) { 117 return boundaries::stream; 118 } 119 }