toxiclibs 0.2-java → 0.5.0-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +16 -0
- data/CHANGELOG.md +4 -0
- data/LICENSE +675 -0
- data/README.md +12 -5
- data/Rakefile +25 -82
- data/examples/attract_repel/attract_repel.rb +30 -0
- data/examples/attract_repel/attractor.rb +23 -0
- data/examples/attract_repel/particle.rb +27 -0
- data/examples/data/ti_yong.png +0 -0
- data/examples/force_directed/cluster.rb +76 -0
- data/examples/force_directed/force_directed_graph.rb +92 -0
- data/examples/force_directed/node.rb +26 -0
- data/examples/gray_scott_image.rb +75 -0
- data/examples/gray_scott_tone_map.rb +77 -0
- data/examples/implicit.rb +139 -0
- data/examples/inflate_mesh.rb +89 -0
- data/examples/model_align.rb +44 -0
- data/examples/povmesh/ftest.rb +46 -0
- data/examples/povmesh/tentacle.rb +73 -0
- data/examples/simple_cluster/cluster.rb +47 -0
- data/examples/simple_cluster/node.rb +27 -0
- data/examples/simple_cluster/simple_cluster.rb +60 -0
- data/examples/soft_body/blanket.rb +45 -0
- data/examples/soft_body/connection.rb +16 -0
- data/examples/soft_body/particle.rb +22 -0
- data/examples/soft_body/soft_body_square_adapted.rb +55 -0
- data/lib/toxiclibs.jar +0 -0
- data/lib/toxiclibs.rb +91 -32
- data/lib/toxiclibs/version.rb +1 -1
- data/pom.xml +122 -0
- data/src/com/toxi/net/ClientListener.java +41 -0
- data/src/com/toxi/net/ServerListener.java +70 -0
- data/src/com/toxi/net/ServerListenerAdapter.java +47 -0
- data/src/com/toxi/net/ServerState.java +18 -0
- data/src/com/toxi/net/UDPConnection.java +66 -0
- data/src/com/toxi/net/UDPSyncClient.java +81 -0
- data/src/com/toxi/net/UDPSyncServer.java +450 -0
- data/src/com/toxi/nio/UDPClient.java +121 -0
- data/src/com/toxi/nio/UDPClientState.java +32 -0
- data/src/com/toxi/nio/UDPServer.java +129 -0
- data/src/toxi/color/AccessCriteria.java +114 -0
- data/src/toxi/color/AlphaAccessor.java +67 -0
- data/src/toxi/color/CMYKAccessor.java +122 -0
- data/src/toxi/color/CMYKDistanceProxy.java +40 -0
- data/src/toxi/color/ColorGradient.java +260 -0
- data/src/toxi/color/ColorList.java +699 -0
- data/src/toxi/color/ColorRange.java +671 -0
- data/src/toxi/color/ColorTheme.java +163 -0
- data/src/toxi/color/DistanceProxy.java +44 -0
- data/src/toxi/color/HSVAccessor.java +113 -0
- data/src/toxi/color/HSVDistanceProxy.java +40 -0
- data/src/toxi/color/HistEntry.java +85 -0
- data/src/toxi/color/Histogram.java +185 -0
- data/src/toxi/color/Hue.java +249 -0
- data/src/toxi/color/LuminanceAccessor.java +78 -0
- data/src/toxi/color/NamedColor.java +935 -0
- data/src/toxi/color/ProximityComparator.java +70 -0
- data/src/toxi/color/RGBAccessor.java +113 -0
- data/src/toxi/color/RGBDistanceProxy.java +41 -0
- data/src/toxi/color/ReadonlyTColor.java +296 -0
- data/src/toxi/color/TColor.java +1677 -0
- data/src/toxi/color/TColorAdapter.java +68 -0
- data/src/toxi/color/ToneMap.java +218 -0
- data/src/toxi/color/theory/AnalogousStrategy.java +140 -0
- data/src/toxi/color/theory/ColorTheoryRegistry.java +139 -0
- data/src/toxi/color/theory/ColorTheoryStrategy.java +56 -0
- data/src/toxi/color/theory/ComplementaryStrategy.java +111 -0
- data/src/toxi/color/theory/CompoundTheoryStrategy.java +143 -0
- data/src/toxi/color/theory/LeftSplitComplementaryStrategy.java +82 -0
- data/src/toxi/color/theory/MonochromeTheoryStrategy.java +103 -0
- data/src/toxi/color/theory/RightSplitComplementaryStrategy.java +82 -0
- data/src/toxi/color/theory/SingleComplementStrategy.java +76 -0
- data/src/toxi/color/theory/SplitComplementaryStrategy.java +77 -0
- data/src/toxi/color/theory/TetradTheoryStrategy.java +114 -0
- data/src/toxi/color/theory/TriadTheoryStrategy.java +77 -0
- data/src/toxi/data/csv/CSVAdapter.java +74 -0
- data/src/toxi/data/csv/CSVFieldMapper.java +212 -0
- data/src/toxi/data/csv/CSVListener.java +61 -0
- data/src/toxi/data/csv/CSVParser.java +202 -0
- data/src/toxi/data/feeds/AtomAuthor.java +49 -0
- data/src/toxi/data/feeds/AtomContent.java +50 -0
- data/src/toxi/data/feeds/AtomEntry.java +111 -0
- data/src/toxi/data/feeds/AtomFeed.java +129 -0
- data/src/toxi/data/feeds/AtomLink.java +62 -0
- data/src/toxi/data/feeds/RSSChannel.java +88 -0
- data/src/toxi/data/feeds/RSSEnclosure.java +60 -0
- data/src/toxi/data/feeds/RSSFeed.java +99 -0
- data/src/toxi/data/feeds/RSSItem.java +104 -0
- data/src/toxi/data/feeds/util/EntityStripper.java +2480 -0
- data/src/toxi/data/feeds/util/Iso8601DateAdapter.java +101 -0
- data/src/toxi/data/feeds/util/Rfc822DateAdapter.java +93 -0
- data/src/toxi/geom/AABB.java +658 -0
- data/src/toxi/geom/Axis3D.java +116 -0
- data/src/toxi/geom/AxisAlignedCylinder.java +163 -0
- data/src/toxi/geom/BernsteinPolynomial.java +94 -0
- data/src/toxi/geom/BezierCurve2D.java +159 -0
- data/src/toxi/geom/BezierCurve3D.java +148 -0
- data/src/toxi/geom/BooleanShapeBuilder.java +185 -0
- data/src/toxi/geom/BoxIntersector.java +52 -0
- data/src/toxi/geom/Circle.java +230 -0
- data/src/toxi/geom/CircleIntersector.java +85 -0
- data/src/toxi/geom/Cone.java +150 -0
- data/src/toxi/geom/ConvexPolygonClipper.java +136 -0
- data/src/toxi/geom/CoordinateExtractor.java +16 -0
- data/src/toxi/geom/Ellipse.java +250 -0
- data/src/toxi/geom/GMatrix.java +2599 -0
- data/src/toxi/geom/GVector.java +833 -0
- data/src/toxi/geom/GlobalGridTesselator.java +54 -0
- data/src/toxi/geom/GridTesselator.java +108 -0
- data/src/toxi/geom/Intersector2D.java +49 -0
- data/src/toxi/geom/Intersector3D.java +51 -0
- data/src/toxi/geom/IsectData2D.java +103 -0
- data/src/toxi/geom/IsectData3D.java +103 -0
- data/src/toxi/geom/Line2D.java +534 -0
- data/src/toxi/geom/Line3D.java +471 -0
- data/src/toxi/geom/LineStrip2D.java +430 -0
- data/src/toxi/geom/LineStrip3D.java +230 -0
- data/src/toxi/geom/LocalGridTesselator.java +57 -0
- data/src/toxi/geom/Matrix3d.java +3048 -0
- data/src/toxi/geom/Matrix4f.java +3446 -0
- data/src/toxi/geom/Matrix4x4.java +1076 -0
- data/src/toxi/geom/MatrixSizeException.java +58 -0
- data/src/toxi/geom/OctreeVisitor.java +44 -0
- data/src/toxi/geom/Origin3D.java +148 -0
- data/src/toxi/geom/Plane.java +293 -0
- data/src/toxi/geom/PlaneIntersector.java +57 -0
- data/src/toxi/geom/PointCloud3D.java +253 -0
- data/src/toxi/geom/PointOctree.java +502 -0
- data/src/toxi/geom/PointQuadtree.java +375 -0
- data/src/toxi/geom/Polygon2D.java +1038 -0
- data/src/toxi/geom/PolygonClipper2D.java +45 -0
- data/src/toxi/geom/PolygonTesselator.java +20 -0
- data/src/toxi/geom/QuadtreeVisitor.java +44 -0
- data/src/toxi/geom/Quaternion.java +641 -0
- data/src/toxi/geom/Ray2D.java +146 -0
- data/src/toxi/geom/Ray3D.java +150 -0
- data/src/toxi/geom/Ray3DIntersector.java +75 -0
- data/src/toxi/geom/ReadonlyVec2D.java +575 -0
- data/src/toxi/geom/ReadonlyVec3D.java +628 -0
- data/src/toxi/geom/ReadonlyVec4D.java +431 -0
- data/src/toxi/geom/Rect.java +720 -0
- data/src/toxi/geom/Reflector3D.java +58 -0
- data/src/toxi/geom/Shape2D.java +94 -0
- data/src/toxi/geom/Shape3D.java +42 -0
- data/src/toxi/geom/SingularMatrixException.java +57 -0
- data/src/toxi/geom/SpatialBins.java +182 -0
- data/src/toxi/geom/SpatialIndex.java +61 -0
- data/src/toxi/geom/Sphere.java +224 -0
- data/src/toxi/geom/SphereIntersectorReflector.java +196 -0
- data/src/toxi/geom/Spline2D.java +349 -0
- data/src/toxi/geom/Spline3D.java +351 -0
- data/src/toxi/geom/SutherlandHodgemanClipper.java +151 -0
- data/src/toxi/geom/Triangle2D.java +422 -0
- data/src/toxi/geom/Triangle3D.java +456 -0
- data/src/toxi/geom/TriangleIntersector.java +105 -0
- data/src/toxi/geom/Vec2D.java +1328 -0
- data/src/toxi/geom/Vec3D.java +1832 -0
- data/src/toxi/geom/Vec4D.java +985 -0
- data/src/toxi/geom/VecMathUtil.java +100 -0
- data/src/toxi/geom/XAxisCylinder.java +64 -0
- data/src/toxi/geom/YAxisCylinder.java +65 -0
- data/src/toxi/geom/ZAxisCylinder.java +64 -0
- data/src/toxi/geom/mesh/BezierPatch.java +200 -0
- data/src/toxi/geom/mesh/BoxSelector.java +62 -0
- data/src/toxi/geom/mesh/DefaultSTLColorModel.java +67 -0
- data/src/toxi/geom/mesh/DefaultSelector.java +50 -0
- data/src/toxi/geom/mesh/Face.java +176 -0
- data/src/toxi/geom/mesh/LaplacianSmooth.java +80 -0
- data/src/toxi/geom/mesh/MaterialiseSTLColorModel.java +150 -0
- data/src/toxi/geom/mesh/Mesh3D.java +224 -0
- data/src/toxi/geom/mesh/MeshIntersector.java +91 -0
- data/src/toxi/geom/mesh/OBJWriter.java +194 -0
- data/src/toxi/geom/mesh/PLYWriter.java +167 -0
- data/src/toxi/geom/mesh/PlaneSelector.java +90 -0
- data/src/toxi/geom/mesh/STLColorModel.java +54 -0
- data/src/toxi/geom/mesh/STLReader.java +185 -0
- data/src/toxi/geom/mesh/STLWriter.java +323 -0
- data/src/toxi/geom/mesh/SphereFunction.java +156 -0
- data/src/toxi/geom/mesh/SphericalHarmonics.java +110 -0
- data/src/toxi/geom/mesh/SuperEllipsoid.java +110 -0
- data/src/toxi/geom/mesh/SurfaceFunction.java +75 -0
- data/src/toxi/geom/mesh/SurfaceMeshBuilder.java +149 -0
- data/src/toxi/geom/mesh/Terrain.java +451 -0
- data/src/toxi/geom/mesh/TriangleMesh.java +1201 -0
- data/src/toxi/geom/mesh/Vertex.java +78 -0
- data/src/toxi/geom/mesh/VertexSelector.java +193 -0
- data/src/toxi/geom/mesh/WEFace.java +100 -0
- data/src/toxi/geom/mesh/WEMeshFilterStrategy.java +51 -0
- data/src/toxi/geom/mesh/WETriangleMesh.java +761 -0
- data/src/toxi/geom/mesh/WEVertex.java +134 -0
- data/src/toxi/geom/mesh/WingedEdge.java +115 -0
- data/src/toxi/geom/mesh/subdiv/CentroidSubdiv.java +37 -0
- data/src/toxi/geom/mesh/subdiv/DisplacementSubdivision.java +85 -0
- data/src/toxi/geom/mesh/subdiv/DualDisplacementSubdivision.java +94 -0
- data/src/toxi/geom/mesh/subdiv/DualSubdivision.java +49 -0
- data/src/toxi/geom/mesh/subdiv/EdgeLengthComparator.java +50 -0
- data/src/toxi/geom/mesh/subdiv/FaceCountComparator.java +51 -0
- data/src/toxi/geom/mesh/subdiv/MidpointDisplacementSubdivision.java +80 -0
- data/src/toxi/geom/mesh/subdiv/MidpointSubdiv.java +42 -0
- data/src/toxi/geom/mesh/subdiv/MidpointSubdivision.java +48 -0
- data/src/toxi/geom/mesh/subdiv/NewSubdivStrategy.java +23 -0
- data/src/toxi/geom/mesh/subdiv/NormalDisplacementSubdivision.java +74 -0
- data/src/toxi/geom/mesh/subdiv/SubdivisionStrategy.java +83 -0
- data/src/toxi/geom/mesh/subdiv/TriSubdivision.java +51 -0
- data/src/toxi/geom/mesh2d/DelaunayTriangle.java +222 -0
- data/src/toxi/geom/mesh2d/DelaunayTriangulation.java +327 -0
- data/src/toxi/geom/mesh2d/DelaunayVertex.java +560 -0
- data/src/toxi/geom/mesh2d/Voronoi.java +149 -0
- data/src/toxi/geom/nurbs/BasicNurbsCurve.java +210 -0
- data/src/toxi/geom/nurbs/BasicNurbsSurface.java +233 -0
- data/src/toxi/geom/nurbs/ControlNet.java +148 -0
- data/src/toxi/geom/nurbs/CurveCreator.java +112 -0
- data/src/toxi/geom/nurbs/CurveUtils.java +259 -0
- data/src/toxi/geom/nurbs/InterpolationException.java +65 -0
- data/src/toxi/geom/nurbs/KnotVector.java +333 -0
- data/src/toxi/geom/nurbs/NurbsCreator.java +815 -0
- data/src/toxi/geom/nurbs/NurbsCurve.java +120 -0
- data/src/toxi/geom/nurbs/NurbsMeshCreator.java +145 -0
- data/src/toxi/geom/nurbs/NurbsSurface.java +147 -0
- data/src/toxi/image/util/Filter8bit.java +331 -0
- data/src/toxi/image/util/TiledFrameExporter.java +162 -0
- data/src/toxi/math/BezierInterpolation.java +102 -0
- data/src/toxi/math/CircularInterpolation.java +88 -0
- data/src/toxi/math/CosineInterpolation.java +51 -0
- data/src/toxi/math/DecimatedInterpolation.java +77 -0
- data/src/toxi/math/ExponentialInterpolation.java +68 -0
- data/src/toxi/math/InterpolateStrategy.java +60 -0
- data/src/toxi/math/Interpolation2D.java +93 -0
- data/src/toxi/math/LinearInterpolation.java +46 -0
- data/src/toxi/math/MathUtils.java +990 -0
- data/src/toxi/math/NonLinearScaleMap.java +101 -0
- data/src/toxi/math/ScaleMap.java +183 -0
- data/src/toxi/math/SigmoidInterpolation.java +78 -0
- data/src/toxi/math/SinCosLUT.java +141 -0
- data/src/toxi/math/ThresholdInterpolation.java +58 -0
- data/src/toxi/math/ZoomLensInterpolation.java +126 -0
- data/src/toxi/math/conversion/UnitTranslator.java +161 -0
- data/src/toxi/math/noise/PerlinNoise.java +281 -0
- data/src/toxi/math/noise/SimplexNoise.java +542 -0
- data/src/toxi/math/waves/AMFMSineWave.java +143 -0
- data/src/toxi/math/waves/AbstractWave.java +248 -0
- data/src/toxi/math/waves/ConstantWave.java +48 -0
- data/src/toxi/math/waves/FMHarmonicSquareWave.java +155 -0
- data/src/toxi/math/waves/FMSawtoothWave.java +144 -0
- data/src/toxi/math/waves/FMSineWave.java +142 -0
- data/src/toxi/math/waves/FMSquareWave.java +143 -0
- data/src/toxi/math/waves/FMTriangleWave.java +126 -0
- data/src/toxi/math/waves/SineWave.java +81 -0
- data/src/toxi/math/waves/Wave2D.java +68 -0
- data/src/toxi/math/waves/WaveState.java +69 -0
- data/src/toxi/music/scale/AbstractScale.java +117 -0
- data/src/toxi/music/scale/GenericScale.java +66 -0
- data/src/toxi/music/scale/MajorScale.java +41 -0
- data/src/toxi/newmesh/AttributedEdge.java +106 -0
- data/src/toxi/newmesh/AttributedFace.java +63 -0
- data/src/toxi/newmesh/IndexedTriangleMesh.java +809 -0
- data/src/toxi/newmesh/MeshAttributeCompiler.java +45 -0
- data/src/toxi/newmesh/MeshFaceNormalCompiler.java +52 -0
- data/src/toxi/newmesh/MeshUVCompiler.java +52 -0
- data/src/toxi/newmesh/MeshVertexColorCompiler.java +49 -0
- data/src/toxi/newmesh/MeshVertexCompiler.java +54 -0
- data/src/toxi/newmesh/MeshVertexNormalCompiler.java +55 -0
- data/src/toxi/newmesh/SpatialIndex.java +78 -0
- data/src/toxi/physics2d/ParticlePath2D.java +100 -0
- data/src/toxi/physics2d/ParticleString2D.java +184 -0
- data/src/toxi/physics2d/PullBackSpring2D.java +51 -0
- data/src/toxi/physics2d/VerletConstrainedSpring2D.java +89 -0
- data/src/toxi/physics2d/VerletMinDistanceSpring2D.java +57 -0
- data/src/toxi/physics2d/VerletParticle2D.java +457 -0
- data/src/toxi/physics2d/VerletPhysics2D.java +448 -0
- data/src/toxi/physics2d/VerletSpring2D.java +181 -0
- data/src/toxi/physics2d/behaviors/AttractionBehavior2D.java +212 -0
- data/src/toxi/physics2d/behaviors/ConstantForceBehavior2D.java +112 -0
- data/src/toxi/physics2d/behaviors/GravityBehavior2D.java +61 -0
- data/src/toxi/physics2d/behaviors/ParticleBehavior2D.java +66 -0
- data/src/toxi/physics2d/constraints/AngularConstraint.java +83 -0
- data/src/toxi/physics2d/constraints/AxisConstraint.java +71 -0
- data/src/toxi/physics2d/constraints/CircularConstraint.java +69 -0
- data/src/toxi/physics2d/constraints/MaxConstraint.java +66 -0
- data/src/toxi/physics2d/constraints/MinConstraint.java +66 -0
- data/src/toxi/physics2d/constraints/ParticleConstraint2D.java +47 -0
- data/src/toxi/physics2d/constraints/PolygonConstraint.java +93 -0
- data/src/toxi/physics2d/constraints/RectConstraint.java +114 -0
- data/src/toxi/physics3d/ParticlePath3D.java +100 -0
- data/src/toxi/physics3d/ParticleString3D.java +184 -0
- data/src/toxi/physics3d/PullBackSpring3D.java +50 -0
- data/src/toxi/physics3d/VerletConstrainedSpring3D.java +88 -0
- data/src/toxi/physics3d/VerletMinDistanceSpring3D.java +56 -0
- data/src/toxi/physics3d/VerletParticle3D.java +385 -0
- data/src/toxi/physics3d/VerletPhysics3D.java +417 -0
- data/src/toxi/physics3d/VerletSpring3D.java +180 -0
- data/src/toxi/physics3d/behaviors/AttractionBehavior3D.java +182 -0
- data/src/toxi/physics3d/behaviors/ConstantForceBehavior3D.java +92 -0
- data/src/toxi/physics3d/behaviors/GravityBehavior3D.java +61 -0
- data/src/toxi/physics3d/behaviors/ParticleBehavior3D.java +52 -0
- data/src/toxi/physics3d/constraints/AxisConstraint.java +68 -0
- data/src/toxi/physics3d/constraints/BoxConstraint.java +121 -0
- data/src/toxi/physics3d/constraints/CylinderConstraint.java +87 -0
- data/src/toxi/physics3d/constraints/MaxConstraint.java +65 -0
- data/src/toxi/physics3d/constraints/MinConstraint.java +65 -0
- data/src/toxi/physics3d/constraints/ParticleConstraint3D.java +49 -0
- data/src/toxi/physics3d/constraints/PlaneConstraint.java +78 -0
- data/src/toxi/physics3d/constraints/SoftBoxConstraint.java +87 -0
- data/src/toxi/physics3d/constraints/SphereConstraint.java +108 -0
- data/src/toxi/processing/ArrowModifier.java +116 -0
- data/src/toxi/processing/DashedLineModifier.java +48 -0
- data/src/toxi/processing/DeltaOrientationMapper.java +57 -0
- data/src/toxi/processing/Line2DRenderModifier.java +18 -0
- data/src/toxi/processing/MeshToVBO.java +94 -0
- data/src/toxi/processing/NormalMapper.java +18 -0
- data/src/toxi/processing/POVInterface.java +121 -0
- data/src/toxi/processing/POVMesh.java +219 -0
- data/src/toxi/processing/POVWriter.java +460 -0
- data/src/toxi/processing/RCOpaque.java +77 -0
- data/src/toxi/processing/RCTransp.java +78 -0
- data/src/toxi/processing/TextureBuilder.java +232 -0
- data/src/toxi/processing/Textures.java +110 -0
- data/src/toxi/processing/ToxiclibsSupport.java +1239 -0
- data/src/toxi/processing/Tracing.java +25 -0
- data/src/toxi/processing/XYZNormalMapper.java +30 -0
- data/src/toxi/sim/automata/CAMatrix.java +297 -0
- data/src/toxi/sim/automata/CARule.java +76 -0
- data/src/toxi/sim/automata/CARule2D.java +354 -0
- data/src/toxi/sim/automata/CAWolfram1D.java +309 -0
- data/src/toxi/sim/automata/EvolvableMatrix.java +61 -0
- data/src/toxi/sim/automata/MatrixEvolver.java +42 -0
- data/src/toxi/sim/dla/BottomUpOrder.java +76 -0
- data/src/toxi/sim/dla/DLA.java +497 -0
- data/src/toxi/sim/dla/DLAConfiguration.java +364 -0
- data/src/toxi/sim/dla/DLAEventAdapter.java +64 -0
- data/src/toxi/sim/dla/DLAEventListener.java +57 -0
- data/src/toxi/sim/dla/DLAGuideLines.java +219 -0
- data/src/toxi/sim/dla/DLAParticle.java +102 -0
- data/src/toxi/sim/dla/DLASegment.java +88 -0
- data/src/toxi/sim/dla/PipelineOrder.java +50 -0
- data/src/toxi/sim/dla/RadialDistanceOrder.java +92 -0
- data/src/toxi/sim/erosion/ErosionFunction.java +122 -0
- data/src/toxi/sim/erosion/TalusAngleErosion.java +145 -0
- data/src/toxi/sim/erosion/ThermalErosion.java +75 -0
- data/src/toxi/sim/fluids/FluidSolver2D.java +762 -0
- data/src/toxi/sim/fluids/FluidSolver3D.java +326 -0
- data/src/toxi/sim/grayscott/GrayScott.java +469 -0
- data/src/toxi/util/DateUtils.java +141 -0
- data/src/toxi/util/FileSequenceDescriptor.java +181 -0
- data/src/toxi/util/FileUtils.java +467 -0
- data/src/toxi/util/datatypes/ArraySet.java +128 -0
- data/src/toxi/util/datatypes/ArrayUtil.java +404 -0
- data/src/toxi/util/datatypes/BiasedDoubleRange.java +141 -0
- data/src/toxi/util/datatypes/BiasedFloatRange.java +141 -0
- data/src/toxi/util/datatypes/BiasedIntegerRange.java +141 -0
- data/src/toxi/util/datatypes/DoubleRange.java +251 -0
- data/src/toxi/util/datatypes/FloatRange.java +251 -0
- data/src/toxi/util/datatypes/GenericSet.java +215 -0
- data/src/toxi/util/datatypes/IntegerRange.java +247 -0
- data/src/toxi/util/datatypes/IntegerSet.java +149 -0
- data/src/toxi/util/datatypes/ItemIndex.java +72 -0
- data/src/toxi/util/datatypes/SingletonRegistry.java +91 -0
- data/src/toxi/util/datatypes/TypedProperties.java +291 -0
- data/src/toxi/util/datatypes/UndirectedGraph.java +134 -0
- data/src/toxi/util/datatypes/UniqueItemIndex.java +223 -0
- data/src/toxi/util/datatypes/WeightedRandomEntry.java +76 -0
- data/src/toxi/util/datatypes/WeightedRandomSet.java +125 -0
- data/src/toxi/util/events/EventDispatcher.java +86 -0
- data/src/toxi/volume/AdditiveBrush.java +19 -0
- data/src/toxi/volume/ArrayIsoSurface.java +297 -0
- data/src/toxi/volume/BoxBrush.java +100 -0
- data/src/toxi/volume/BrushMode.java +16 -0
- data/src/toxi/volume/HashIsoSurface.java +354 -0
- data/src/toxi/volume/IsoSurface.java +59 -0
- data/src/toxi/volume/MarchingCubesIndex.java +312 -0
- data/src/toxi/volume/MeshLatticeBuilder.java +358 -0
- data/src/toxi/volume/MeshVoxelizer.java +216 -0
- data/src/toxi/volume/MultiplyBrush.java +20 -0
- data/src/toxi/volume/PeakBrush.java +21 -0
- data/src/toxi/volume/ReplaceBrush.java +19 -0
- data/src/toxi/volume/RoundBrush.java +113 -0
- data/src/toxi/volume/VolumetricBrush.java +160 -0
- data/src/toxi/volume/VolumetricHashMap.java +179 -0
- data/src/toxi/volume/VolumetricSpace.java +195 -0
- data/src/toxi/volume/VolumetricSpaceArray.java +214 -0
- data/toxiclibs.gemspec +34 -0
- metadata +424 -27
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* __ .__ .__ ._____.
|
|
3
|
+
* _/ |_ _______ __|__| ____ | | |__\_ |__ ______
|
|
4
|
+
* \ __\/ _ \ \/ / |/ ___\| | | || __ \ / ___/
|
|
5
|
+
* | | ( <_> > <| \ \___| |_| || \_\ \\___ \
|
|
6
|
+
* |__| \____/__/\_ \__|\___ >____/__||___ /____ >
|
|
7
|
+
* \/ \/ \/ \/
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2006-2011 Karsten Schmidt
|
|
10
|
+
*
|
|
11
|
+
* This library is free software; you can redistribute it and/or
|
|
12
|
+
* modify it under the terms of the GNU Lesser General Public
|
|
13
|
+
* License as published by the Free Software Foundation; either
|
|
14
|
+
* version 2.1 of the License, or (at your option) any later version.
|
|
15
|
+
*
|
|
16
|
+
* http://creativecommons.org/licenses/LGPL/2.1/
|
|
17
|
+
*
|
|
18
|
+
* This library is distributed in the hope that it will be useful,
|
|
19
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
20
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
21
|
+
* Lesser General Public License for more details.
|
|
22
|
+
*
|
|
23
|
+
* You should have received a copy of the GNU Lesser General Public
|
|
24
|
+
* License along with this library; if not, write to the Free Software
|
|
25
|
+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
package toxi.geom.mesh;
|
|
29
|
+
|
|
30
|
+
import toxi.geom.Vec3D;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
*
|
|
34
|
+
* @author tux
|
|
35
|
+
*/
|
|
36
|
+
public class Vertex extends Vec3D {
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
*
|
|
40
|
+
*/
|
|
41
|
+
public final Vec3D normal = new Vec3D();
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
*
|
|
45
|
+
*/
|
|
46
|
+
public final int id;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
*
|
|
50
|
+
* @param v
|
|
51
|
+
* @param id
|
|
52
|
+
*/
|
|
53
|
+
public Vertex(Vec3D v, int id) {
|
|
54
|
+
super(v);
|
|
55
|
+
this.id = id;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
final void addFaceNormal(Vec3D n) {
|
|
59
|
+
normal.addSelf(n);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
final void clearNormal() {
|
|
63
|
+
normal.clear();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
final void computeNormal() {
|
|
67
|
+
normal.normalize();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
*
|
|
72
|
+
* @return
|
|
73
|
+
*/
|
|
74
|
+
@Override
|
|
75
|
+
public String toString() {
|
|
76
|
+
return id + ": p: " + super.toString() + " n:" + normal.toString();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* __ .__ .__ ._____.
|
|
3
|
+
* _/ |_ _______ __|__| ____ | | |__\_ |__ ______
|
|
4
|
+
* \ __\/ _ \ \/ / |/ ___\| | | || __ \ / ___/
|
|
5
|
+
* | | ( <_> > <| \ \___| |_| || \_\ \\___ \
|
|
6
|
+
* |__| \____/__/\_ \__|\___ >____/__||___ /____ >
|
|
7
|
+
* \/ \/ \/ \/
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2006-2011 Karsten Schmidt
|
|
10
|
+
*
|
|
11
|
+
* This library is free software; you can redistribute it and/or
|
|
12
|
+
* modify it under the terms of the GNU Lesser General Public
|
|
13
|
+
* License as published by the Free Software Foundation; either
|
|
14
|
+
* version 2.1 of the License, or (at your option) any later version.
|
|
15
|
+
*
|
|
16
|
+
* http://creativecommons.org/licenses/LGPL/2.1/
|
|
17
|
+
*
|
|
18
|
+
* This library is distributed in the hope that it will be useful,
|
|
19
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
20
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
21
|
+
* Lesser General Public License for more details.
|
|
22
|
+
*
|
|
23
|
+
* You should have received a copy of the GNU Lesser General Public
|
|
24
|
+
* License along with this library; if not, write to the Free Software
|
|
25
|
+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
package toxi.geom.mesh;
|
|
29
|
+
|
|
30
|
+
import java.util.Collection;
|
|
31
|
+
import java.util.HashSet;
|
|
32
|
+
import java.util.Set;
|
|
33
|
+
|
|
34
|
+
import toxi.geom.Vec3D;
|
|
35
|
+
import toxi.math.MathUtils;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Abstract parent class for selecting mesh vertices and manipulating resulting
|
|
39
|
+
* selections using set theory operations. Implementations of this class should
|
|
40
|
+
* aim to work with all mesh types (e.g. {@link TriangleMesh},
|
|
41
|
+
* {@link WETriangleMesh}).
|
|
42
|
+
*/
|
|
43
|
+
public abstract class VertexSelector {
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
*
|
|
47
|
+
*/
|
|
48
|
+
protected Mesh3D mesh;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
*
|
|
52
|
+
*/
|
|
53
|
+
protected Set<Vertex> selection;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Creates a new selector assigned to the given mesh
|
|
57
|
+
*
|
|
58
|
+
* @param mesh
|
|
59
|
+
*/
|
|
60
|
+
public VertexSelector(Mesh3D mesh) {
|
|
61
|
+
this.mesh = mesh;
|
|
62
|
+
this.selection = new HashSet<>();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Adds all vertices selected by the given selector to the current
|
|
67
|
+
* selection. The other selector needs to be assigned to the same mesh
|
|
68
|
+
* instance.
|
|
69
|
+
*
|
|
70
|
+
* @param sel2
|
|
71
|
+
* other selector
|
|
72
|
+
* @return itself
|
|
73
|
+
*/
|
|
74
|
+
public VertexSelector addSelection(VertexSelector sel2) {
|
|
75
|
+
checkMeshIdentity(sel2.getMesh());
|
|
76
|
+
selection.addAll(sel2.getSelection());
|
|
77
|
+
return this;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Utility function to check if the given mesh is the same instance as ours.
|
|
82
|
+
*
|
|
83
|
+
* @param mesh2
|
|
84
|
+
*/
|
|
85
|
+
protected void checkMeshIdentity(Mesh3D mesh2) {
|
|
86
|
+
if (mesh2 != mesh) {
|
|
87
|
+
throw new IllegalArgumentException(
|
|
88
|
+
"The given selector is not using the same mesh instance");
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Clears the current selection.
|
|
94
|
+
*
|
|
95
|
+
* @return itself
|
|
96
|
+
*/
|
|
97
|
+
public VertexSelector clearSelection() {
|
|
98
|
+
selection.clear();
|
|
99
|
+
return this;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Returns the associated mesh for this selector.
|
|
104
|
+
*
|
|
105
|
+
* @return itself
|
|
106
|
+
*/
|
|
107
|
+
public Mesh3D getMesh() {
|
|
108
|
+
return mesh;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Returns the actual collection of selected vertices
|
|
113
|
+
*
|
|
114
|
+
* @return vertex collection
|
|
115
|
+
*/
|
|
116
|
+
public Collection<Vertex> getSelection() {
|
|
117
|
+
return selection;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Creates a new selection of all vertices NOT currently selected.
|
|
122
|
+
*
|
|
123
|
+
* @return itself
|
|
124
|
+
*/
|
|
125
|
+
public VertexSelector invertSelection() {
|
|
126
|
+
final int size = MathUtils.max(0,
|
|
127
|
+
mesh.getNumVertices() - selection.size());
|
|
128
|
+
HashSet<Vertex> newSel = new HashSet<>(size);
|
|
129
|
+
mesh.getVertices().stream().filter((v) -> (!selection.contains(v))).forEach((v) -> {
|
|
130
|
+
newSel.add(v);
|
|
131
|
+
});
|
|
132
|
+
selection = newSel;
|
|
133
|
+
return this;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Selects vertices identical or closest to the ones given in the list of
|
|
138
|
+
* points.
|
|
139
|
+
*
|
|
140
|
+
* @param points
|
|
141
|
+
* @return itself
|
|
142
|
+
*/
|
|
143
|
+
public VertexSelector selectSimilar(Collection<? extends Vec3D> points) {
|
|
144
|
+
points.stream().forEach((v) -> {
|
|
145
|
+
selection.add(mesh.getClosestVertexToPoint(v));
|
|
146
|
+
});
|
|
147
|
+
return this;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Selects vertices using an implementation specific method. This is the
|
|
152
|
+
* only method which needs to be implemented by any selector subclass.
|
|
153
|
+
*
|
|
154
|
+
* @return itself
|
|
155
|
+
*/
|
|
156
|
+
public abstract VertexSelector selectVertices();
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Assigns a new mesh instance to this selector and clears the current
|
|
160
|
+
* selection.
|
|
161
|
+
*
|
|
162
|
+
* @param mesh
|
|
163
|
+
* the mesh to set
|
|
164
|
+
*/
|
|
165
|
+
public void setMesh(Mesh3D mesh) {
|
|
166
|
+
this.mesh = mesh;
|
|
167
|
+
clearSelection();
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Returns the current number of selected vertices.
|
|
172
|
+
*
|
|
173
|
+
* @return number of vertices
|
|
174
|
+
*/
|
|
175
|
+
public int size() {
|
|
176
|
+
return selection.size();
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Removes all vertices selected by the given selector from the current
|
|
181
|
+
* selection. The other selector needs to be assigned to the same mesh
|
|
182
|
+
* instance.
|
|
183
|
+
*
|
|
184
|
+
* @param sel2
|
|
185
|
+
* other selector
|
|
186
|
+
* @return itself
|
|
187
|
+
*/
|
|
188
|
+
public VertexSelector subtractSelection(VertexSelector sel2) {
|
|
189
|
+
checkMeshIdentity(sel2.getMesh());
|
|
190
|
+
selection.removeAll(sel2.getSelection());
|
|
191
|
+
return this;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* __ .__ .__ ._____.
|
|
3
|
+
* _/ |_ _______ __|__| ____ | | |__\_ |__ ______
|
|
4
|
+
* \ __\/ _ \ \/ / |/ ___\| | | || __ \ / ___/
|
|
5
|
+
* | | ( <_> > <| \ \___| |_| || \_\ \\___ \
|
|
6
|
+
* |__| \____/__/\_ \__|\___ >____/__||___ /____ >
|
|
7
|
+
* \/ \/ \/ \/
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2006-2011 Karsten Schmidt
|
|
10
|
+
*
|
|
11
|
+
* This library is free software; you can redistribute it and/or
|
|
12
|
+
* modify it under the terms of the GNU Lesser General Public
|
|
13
|
+
* License as published by the Free Software Foundation; either
|
|
14
|
+
* version 2.1 of the License, or (at your option) any later version.
|
|
15
|
+
*
|
|
16
|
+
* http://creativecommons.org/licenses/LGPL/2.1/
|
|
17
|
+
*
|
|
18
|
+
* This library is distributed in the hope that it will be useful,
|
|
19
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
20
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
21
|
+
* Lesser General Public License for more details.
|
|
22
|
+
*
|
|
23
|
+
* You should have received a copy of the GNU Lesser General Public
|
|
24
|
+
* License along with this library; if not, write to the Free Software
|
|
25
|
+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
package toxi.geom.mesh;
|
|
29
|
+
|
|
30
|
+
import java.util.ArrayList;
|
|
31
|
+
import java.util.List;
|
|
32
|
+
|
|
33
|
+
import toxi.geom.Vec2D;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
*
|
|
37
|
+
* @author tux
|
|
38
|
+
*/
|
|
39
|
+
public final class WEFace extends Face {
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
*
|
|
43
|
+
*/
|
|
44
|
+
public List<WingedEdge> edges = new ArrayList<>(3);
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
*
|
|
48
|
+
* @param a
|
|
49
|
+
* @param b
|
|
50
|
+
* @param c
|
|
51
|
+
*/
|
|
52
|
+
public WEFace(WEVertex a, WEVertex b, WEVertex c) {
|
|
53
|
+
super(a, b, c);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
*
|
|
58
|
+
* @param a
|
|
59
|
+
* @param b
|
|
60
|
+
* @param c
|
|
61
|
+
* @param uvA
|
|
62
|
+
* @param uvB
|
|
63
|
+
* @param uvC
|
|
64
|
+
*/
|
|
65
|
+
public WEFace(WEVertex a, WEVertex b, WEVertex c, Vec2D uvA, Vec2D uvB,
|
|
66
|
+
Vec2D uvC) {
|
|
67
|
+
super(a, b, c, uvA, uvB, uvC);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
*
|
|
72
|
+
* @param e
|
|
73
|
+
*/
|
|
74
|
+
public void addEdge(WingedEdge e) {
|
|
75
|
+
edges.add(e);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* @return the edges
|
|
80
|
+
*/
|
|
81
|
+
public List<WingedEdge> getEdges() {
|
|
82
|
+
return edges;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
*
|
|
87
|
+
* @param verts
|
|
88
|
+
* @return
|
|
89
|
+
*/
|
|
90
|
+
public final WEVertex[] getVertices(WEVertex[] verts) {
|
|
91
|
+
if (verts != null) {
|
|
92
|
+
verts[0] = (WEVertex) a;
|
|
93
|
+
verts[1] = (WEVertex) b;
|
|
94
|
+
verts[2] = (WEVertex) c;
|
|
95
|
+
} else {
|
|
96
|
+
verts = new WEVertex[] { (WEVertex) a, (WEVertex) b, (WEVertex) c };
|
|
97
|
+
}
|
|
98
|
+
return verts;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* __ .__ .__ ._____.
|
|
3
|
+
* _/ |_ _______ __|__| ____ | | |__\_ |__ ______
|
|
4
|
+
* \ __\/ _ \ \/ / |/ ___\| | | || __ \ / ___/
|
|
5
|
+
* | | ( <_> > <| \ \___| |_| || \_\ \\___ \
|
|
6
|
+
* |__| \____/__/\_ \__|\___ >____/__||___ /____ >
|
|
7
|
+
* \/ \/ \/ \/
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2006-2011 Karsten Schmidt
|
|
10
|
+
*
|
|
11
|
+
* This library is free software; you can redistribute it and/or
|
|
12
|
+
* modify it under the terms of the GNU Lesser General Public
|
|
13
|
+
* License as published by the Free Software Foundation; either
|
|
14
|
+
* version 2.1 of the License, or (at your option) any later version.
|
|
15
|
+
*
|
|
16
|
+
* http://creativecommons.org/licenses/LGPL/2.1/
|
|
17
|
+
*
|
|
18
|
+
* This library is distributed in the hope that it will be useful,
|
|
19
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
20
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
21
|
+
* Lesser General Public License for more details.
|
|
22
|
+
*
|
|
23
|
+
* You should have received a copy of the GNU Lesser General Public
|
|
24
|
+
* License along with this library; if not, write to the Free Software
|
|
25
|
+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
package toxi.geom.mesh;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
*
|
|
32
|
+
* @author tux
|
|
33
|
+
*/
|
|
34
|
+
public interface WEMeshFilterStrategy {
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
*
|
|
38
|
+
* @param selector
|
|
39
|
+
* @param numIterations
|
|
40
|
+
*/
|
|
41
|
+
public void filter(VertexSelector selector, int numIterations);
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Applies the vertex filter to the given mesh
|
|
45
|
+
*
|
|
46
|
+
* @param mesh
|
|
47
|
+
* @param numIterations
|
|
48
|
+
*/
|
|
49
|
+
public void filter(WETriangleMesh mesh, int numIterations);
|
|
50
|
+
|
|
51
|
+
}
|
|
@@ -0,0 +1,761 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* __ .__ .__ ._____.
|
|
3
|
+
* _/ |_ _______ __|__| ____ | | |__\_ |__ ______
|
|
4
|
+
* \ __\/ _ \ \/ / |/ ___\| | | || __ \ / ___/
|
|
5
|
+
* | | ( <_> > <| \ \___| |_| || \_\ \\___ \
|
|
6
|
+
* |__| \____/__/\_ \__|\___ >____/__||___ /____ >
|
|
7
|
+
* \/ \/ \/ \/
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2006-2011 Karsten Schmidt
|
|
10
|
+
*
|
|
11
|
+
* This library is free software; you can redistribute it and/or
|
|
12
|
+
* modify it under the terms of the GNU Lesser General Public
|
|
13
|
+
* License as published by the Free Software Foundation; either
|
|
14
|
+
* version 2.1 of the License, or (at your option) any later version.
|
|
15
|
+
*
|
|
16
|
+
* http://creativecommons.org/licenses/LGPL/2.1/
|
|
17
|
+
*
|
|
18
|
+
* This library is distributed in the hope that it will be useful,
|
|
19
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
20
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
21
|
+
* Lesser General Public License for more details.
|
|
22
|
+
*
|
|
23
|
+
* You should have received a copy of the GNU Lesser General Public
|
|
24
|
+
* License along with this library; if not, write to the Free Software
|
|
25
|
+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
package toxi.geom.mesh;
|
|
29
|
+
|
|
30
|
+
import java.util.ArrayList;
|
|
31
|
+
import java.util.Collection;
|
|
32
|
+
import java.util.Collections;
|
|
33
|
+
import java.util.Iterator;
|
|
34
|
+
import java.util.LinkedHashMap;
|
|
35
|
+
import java.util.List;
|
|
36
|
+
import java.util.logging.Level;
|
|
37
|
+
|
|
38
|
+
import toxi.geom.AABB;
|
|
39
|
+
import toxi.geom.Line3D;
|
|
40
|
+
import toxi.geom.Matrix4x4;
|
|
41
|
+
import toxi.geom.Quaternion;
|
|
42
|
+
import toxi.geom.ReadonlyVec3D;
|
|
43
|
+
import toxi.geom.Vec2D;
|
|
44
|
+
import toxi.geom.Vec3D;
|
|
45
|
+
import toxi.geom.mesh.subdiv.MidpointSubdivision;
|
|
46
|
+
import toxi.geom.mesh.subdiv.SubdivisionStrategy;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* A class to dynamically build, manipulate & export triangle meshes. Meshes are
|
|
50
|
+
* build face by face. The class automatically re-uses existing vertices and can
|
|
51
|
+
* create smooth vertex normals. Vertices and faces are directly accessible for
|
|
52
|
+
* speed & convenience.
|
|
53
|
+
*/
|
|
54
|
+
public class WETriangleMesh extends TriangleMesh {
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* WEVertex buffer & lookup index when adding new faces
|
|
58
|
+
*/
|
|
59
|
+
public LinkedHashMap<Line3D, WingedEdge> edges;
|
|
60
|
+
|
|
61
|
+
private final Line3D edgeCheck = new Line3D(new Vec3D(), new Vec3D());
|
|
62
|
+
|
|
63
|
+
private int uniqueEdgeID;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
*
|
|
67
|
+
*/
|
|
68
|
+
public WETriangleMesh() {
|
|
69
|
+
this("untitled");
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Creates a new mesh instance with initial default buffer sizes.
|
|
74
|
+
*
|
|
75
|
+
* @param name
|
|
76
|
+
* mesh name
|
|
77
|
+
*/
|
|
78
|
+
public WETriangleMesh(String name) {
|
|
79
|
+
this(name, DEFAULT_NUM_VERTICES, DEFAULT_NUM_FACES);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Creates a new mesh instance with the given initial buffer sizes. These
|
|
84
|
+
* numbers are no limits and the mesh can be smaller or grow later on.
|
|
85
|
+
* They're only used to initialise the underlying collections.
|
|
86
|
+
*
|
|
87
|
+
* @param name
|
|
88
|
+
* mesh name
|
|
89
|
+
* @param numV
|
|
90
|
+
* initial vertex buffer size
|
|
91
|
+
* @param numF
|
|
92
|
+
* initial face list size
|
|
93
|
+
*/
|
|
94
|
+
public WETriangleMesh(String name, int numV, int numF) {
|
|
95
|
+
super(name, numV, numF);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
@Override
|
|
99
|
+
public WETriangleMesh addFace(Vec3D a, Vec3D b, Vec3D c) {
|
|
100
|
+
return addFace(a, b, c, null, null, null, null);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
@Override
|
|
104
|
+
public WETriangleMesh addFace(Vec3D a, Vec3D b, Vec3D c, Vec2D uvA,
|
|
105
|
+
Vec2D uvB, Vec2D uvC) {
|
|
106
|
+
return addFace(a, b, c, null, uvA, uvB, uvC);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
*
|
|
111
|
+
* @param a
|
|
112
|
+
* @param b
|
|
113
|
+
* @param c
|
|
114
|
+
* @param n
|
|
115
|
+
* @return
|
|
116
|
+
*/
|
|
117
|
+
@Override
|
|
118
|
+
public WETriangleMesh addFace(Vec3D a, Vec3D b, Vec3D c, Vec3D n) {
|
|
119
|
+
return addFace(a, b, c, n, null, null, null);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
*
|
|
124
|
+
* @param a
|
|
125
|
+
* @param b
|
|
126
|
+
* @param c
|
|
127
|
+
* @param n
|
|
128
|
+
* @param uvA
|
|
129
|
+
* @param uvB
|
|
130
|
+
* @param uvC
|
|
131
|
+
* @return
|
|
132
|
+
*/
|
|
133
|
+
@Override
|
|
134
|
+
public WETriangleMesh addFace(Vec3D a, Vec3D b, Vec3D c, Vec3D n,
|
|
135
|
+
Vec2D uvA, Vec2D uvB, Vec2D uvC) {
|
|
136
|
+
WEVertex va = checkVertex(a);
|
|
137
|
+
WEVertex vb = checkVertex(b);
|
|
138
|
+
WEVertex vc = checkVertex(c);
|
|
139
|
+
if (va.id == vb.id || va.id == vc.id || vb.id == vc.id) {
|
|
140
|
+
if (logger.isLoggable(Level.FINE)) {
|
|
141
|
+
logger.log(Level.FINE, "ignorning invalid face: {0},{1},{2}", new Object[]{a, b, c});
|
|
142
|
+
}
|
|
143
|
+
} else {
|
|
144
|
+
if (n != null) {
|
|
145
|
+
Vec3D nc = va.sub(vc).crossSelf(va.sub(vb));
|
|
146
|
+
if (n.dot(nc) < 0) {
|
|
147
|
+
WEVertex t = va;
|
|
148
|
+
va = vb;
|
|
149
|
+
vb = t;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
WEFace f = new WEFace(va, vb, vc, uvA, uvB, uvC);
|
|
153
|
+
faces.add(f);
|
|
154
|
+
numFaces++;
|
|
155
|
+
updateEdge(va, vb, f);
|
|
156
|
+
updateEdge(vb, vc, f);
|
|
157
|
+
updateEdge(vc, va, f);
|
|
158
|
+
}
|
|
159
|
+
return this;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Adds all faces from the given mesh to this one.
|
|
164
|
+
*
|
|
165
|
+
* @param m
|
|
166
|
+
* source mesh instance
|
|
167
|
+
* @return
|
|
168
|
+
*/
|
|
169
|
+
@Override
|
|
170
|
+
public WETriangleMesh addMesh(Mesh3D m) {
|
|
171
|
+
super.addMesh(m);
|
|
172
|
+
return this;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
@Override
|
|
176
|
+
public AABB center(ReadonlyVec3D origin) {
|
|
177
|
+
super.center(origin);
|
|
178
|
+
rebuildIndex();
|
|
179
|
+
return bounds;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
private WEVertex checkVertex(Vec3D v) {
|
|
183
|
+
WEVertex vertex = (WEVertex) vertices.get(v);
|
|
184
|
+
if (vertex == null) {
|
|
185
|
+
vertex = createVertex(v, uniqueVertexID++);
|
|
186
|
+
vertices.put(vertex, vertex);
|
|
187
|
+
numVertices++;
|
|
188
|
+
}
|
|
189
|
+
return vertex;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Clears all counters, and vertex & face buffers.
|
|
194
|
+
* @return
|
|
195
|
+
*/
|
|
196
|
+
@Override
|
|
197
|
+
public WETriangleMesh clear() {
|
|
198
|
+
super.clear();
|
|
199
|
+
edges.clear();
|
|
200
|
+
return this;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Creates a deep clone of the mesh. The new mesh name will have "-copy" as
|
|
205
|
+
* suffix.
|
|
206
|
+
*
|
|
207
|
+
* @return new mesh instance
|
|
208
|
+
*/
|
|
209
|
+
@Override
|
|
210
|
+
public WETriangleMesh copy() {
|
|
211
|
+
WETriangleMesh m = new WETriangleMesh(name + "-copy", numVertices,
|
|
212
|
+
numFaces);
|
|
213
|
+
faces.stream().forEach((f) -> {
|
|
214
|
+
m.addFace(f.a, f.b, f.c, f.normal, f.uvA, f.uvB, f.uvC);
|
|
215
|
+
});
|
|
216
|
+
return m;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
*
|
|
221
|
+
* @param v
|
|
222
|
+
* @param id
|
|
223
|
+
* @return
|
|
224
|
+
*/
|
|
225
|
+
@Override
|
|
226
|
+
protected WEVertex createVertex(Vec3D v, int id) {
|
|
227
|
+
return new WEVertex(v, id);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Flips the vertex ordering between clockwise and anti-clockwise. WEFace
|
|
232
|
+
* normals are updated automatically too.
|
|
233
|
+
*
|
|
234
|
+
* @return itself
|
|
235
|
+
*/
|
|
236
|
+
@Override
|
|
237
|
+
public WETriangleMesh flipVertexOrder() {
|
|
238
|
+
super.flipVertexOrder();
|
|
239
|
+
return this;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
@Override
|
|
243
|
+
public WETriangleMesh flipYAxis() {
|
|
244
|
+
super.flipYAxis();
|
|
245
|
+
return this;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
*
|
|
250
|
+
* @param p
|
|
251
|
+
* @return
|
|
252
|
+
*/
|
|
253
|
+
@Override
|
|
254
|
+
public WEVertex getClosestVertexToPoint(ReadonlyVec3D p) {
|
|
255
|
+
return (WEVertex) super.getClosestVertexToPoint(p);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
*
|
|
260
|
+
* @return
|
|
261
|
+
*/
|
|
262
|
+
public Collection<WingedEdge> getEdges() {
|
|
263
|
+
return edges.values();
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
*
|
|
268
|
+
* @return
|
|
269
|
+
*/
|
|
270
|
+
public int getNumEdges() {
|
|
271
|
+
return edges.size();
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
*
|
|
276
|
+
* @param axis
|
|
277
|
+
* @param theta
|
|
278
|
+
* @return
|
|
279
|
+
*/
|
|
280
|
+
@Override
|
|
281
|
+
public WETriangleMesh getRotatedAroundAxis(Vec3D axis, float theta) {
|
|
282
|
+
return copy().rotateAroundAxis(axis, theta);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
*
|
|
287
|
+
* @param theta
|
|
288
|
+
* @return
|
|
289
|
+
*/
|
|
290
|
+
@Override
|
|
291
|
+
public WETriangleMesh getRotatedX(float theta) {
|
|
292
|
+
return copy().rotateX(theta);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
*
|
|
297
|
+
* @param theta
|
|
298
|
+
* @return
|
|
299
|
+
*/
|
|
300
|
+
@Override
|
|
301
|
+
public WETriangleMesh getRotatedY(float theta) {
|
|
302
|
+
return copy().rotateY(theta);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
*
|
|
307
|
+
* @param theta
|
|
308
|
+
* @return
|
|
309
|
+
*/
|
|
310
|
+
@Override
|
|
311
|
+
public WETriangleMesh getRotatedZ(float theta) {
|
|
312
|
+
return copy().rotateZ(theta);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
*
|
|
317
|
+
* @param scale
|
|
318
|
+
* @return
|
|
319
|
+
*/
|
|
320
|
+
@Override
|
|
321
|
+
public WETriangleMesh getScaled(float scale) {
|
|
322
|
+
return copy().scale(scale);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
*
|
|
327
|
+
* @param scale
|
|
328
|
+
* @return
|
|
329
|
+
*/
|
|
330
|
+
@Override
|
|
331
|
+
public WETriangleMesh getScaled(Vec3D scale) {
|
|
332
|
+
return copy().scale(scale);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
*
|
|
337
|
+
* @param trans
|
|
338
|
+
* @return
|
|
339
|
+
*/
|
|
340
|
+
@Override
|
|
341
|
+
public WETriangleMesh getTranslated(Vec3D trans) {
|
|
342
|
+
return copy().translate(trans);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
*
|
|
347
|
+
* @param v
|
|
348
|
+
* @return
|
|
349
|
+
*/
|
|
350
|
+
@Override
|
|
351
|
+
public WEVertex getVertexAtPoint(Vec3D v) {
|
|
352
|
+
return (WEVertex) vertices.get(v);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
*
|
|
357
|
+
* @param id
|
|
358
|
+
* @return
|
|
359
|
+
*/
|
|
360
|
+
@Override
|
|
361
|
+
public WEVertex getVertexForID(int id) {
|
|
362
|
+
return (WEVertex) super.getVertexForID(id);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
@Override
|
|
366
|
+
public WETriangleMesh init(String name, int numV, int numF) {
|
|
367
|
+
super.init(name, numV, numF);
|
|
368
|
+
edges = new LinkedHashMap<>(numV, 1.5f, false);
|
|
369
|
+
return this;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Rotates the mesh in such a way so that its "forward" axis is aligned with
|
|
374
|
+
* the given direction. This version uses the positive Z-axis as default
|
|
375
|
+
* forward direction.
|
|
376
|
+
*
|
|
377
|
+
* @param dir
|
|
378
|
+
* new target direction to point in
|
|
379
|
+
* @return itself
|
|
380
|
+
*/
|
|
381
|
+
@Override
|
|
382
|
+
public WETriangleMesh pointTowards(ReadonlyVec3D dir) {
|
|
383
|
+
return transform(Quaternion.getAlignmentQuat(dir, Vec3D.Z_AXIS)
|
|
384
|
+
.toMatrix4x4(matrix), true);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Rotates the mesh in such a way so that its "forward" axis is aligned with
|
|
389
|
+
* the given direction. This version allows to specify the forward
|
|
390
|
+
* direction.
|
|
391
|
+
*
|
|
392
|
+
* @param dir
|
|
393
|
+
* new target direction to point in
|
|
394
|
+
* @param forward
|
|
395
|
+
* current forward axis
|
|
396
|
+
* @return itself
|
|
397
|
+
*/
|
|
398
|
+
@Override
|
|
399
|
+
public WETriangleMesh pointTowards(ReadonlyVec3D dir, ReadonlyVec3D forward) {
|
|
400
|
+
return transform(
|
|
401
|
+
Quaternion.getAlignmentQuat(dir, forward).toMatrix4x4(matrix),
|
|
402
|
+
true);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
*
|
|
407
|
+
*/
|
|
408
|
+
public void rebuildIndex() {
|
|
409
|
+
LinkedHashMap<Vec3D, Vertex> newV = new LinkedHashMap<>(
|
|
410
|
+
vertices.size());
|
|
411
|
+
vertices.values().stream().forEach((v) -> {
|
|
412
|
+
newV.put(v, v);
|
|
413
|
+
});
|
|
414
|
+
vertices = newV;
|
|
415
|
+
LinkedHashMap<Line3D, WingedEdge> newE = new LinkedHashMap<>(
|
|
416
|
+
edges.size());
|
|
417
|
+
edges.values().stream().forEach((e) -> {
|
|
418
|
+
newE.put(e, e);
|
|
419
|
+
});
|
|
420
|
+
edges = newE;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
*
|
|
425
|
+
* @param e
|
|
426
|
+
*/
|
|
427
|
+
protected void removeEdge(WingedEdge e) {
|
|
428
|
+
e.remove();
|
|
429
|
+
WEVertex v = (WEVertex) e.a;
|
|
430
|
+
if (v.edges.isEmpty()) {
|
|
431
|
+
vertices.remove(v);
|
|
432
|
+
}
|
|
433
|
+
v = (WEVertex) e.b;
|
|
434
|
+
if (v.edges.isEmpty()) {
|
|
435
|
+
vertices.remove(v);
|
|
436
|
+
}
|
|
437
|
+
e.faces.stream().forEach((f) -> {
|
|
438
|
+
removeFace(f);
|
|
439
|
+
});
|
|
440
|
+
WingedEdge removed = edges.remove(edgeCheck.set(e.a, e.b));
|
|
441
|
+
if (removed != e) {
|
|
442
|
+
throw new IllegalStateException("can't remove edge");
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
*
|
|
448
|
+
* @param f
|
|
449
|
+
*/
|
|
450
|
+
@Override
|
|
451
|
+
public void removeFace(Face f) {
|
|
452
|
+
faces.remove(f);
|
|
453
|
+
((WEFace) f).edges.stream().map((WingedEdge e) -> {
|
|
454
|
+
e.faces.remove((WEFace)f);
|
|
455
|
+
return e;
|
|
456
|
+
}).filter((e) -> (e.faces.isEmpty())).forEach((e) -> {
|
|
457
|
+
removeEdge(e);
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
// FIXME
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
*
|
|
465
|
+
*/
|
|
466
|
+
public void removeUnusedVertices() {
|
|
467
|
+
for (Iterator<Vertex> i = vertices.values().iterator(); i.hasNext();) {
|
|
468
|
+
Vertex v = i.next();
|
|
469
|
+
boolean isUsed = false;
|
|
470
|
+
for (Face f : faces) {
|
|
471
|
+
if (f.a == v || f.b == v || f.c == v) {
|
|
472
|
+
isUsed = true;
|
|
473
|
+
break;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
if (!isUsed) {
|
|
477
|
+
logger.log(Level.INFO, "removing vertex: {0}", v);
|
|
478
|
+
i.remove();
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
*
|
|
485
|
+
* @param selection
|
|
486
|
+
*/
|
|
487
|
+
public void removeVertices(Collection<Vertex> selection) {
|
|
488
|
+
selection.stream().map((v) -> (WEVertex) v).forEach((WEVertex wv) -> {
|
|
489
|
+
new ArrayList<>(wv.edges).stream().forEach((e) -> {
|
|
490
|
+
new ArrayList<>(e.faces).stream().forEach((f) -> {
|
|
491
|
+
removeFace(f);
|
|
492
|
+
});
|
|
493
|
+
});
|
|
494
|
+
}); // rebuildIndex();
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/**
|
|
498
|
+
*
|
|
499
|
+
* @param axis
|
|
500
|
+
* @param theta
|
|
501
|
+
* @return
|
|
502
|
+
*/
|
|
503
|
+
@Override
|
|
504
|
+
public WETriangleMesh rotateAroundAxis(Vec3D axis, float theta) {
|
|
505
|
+
return transform(matrix.identity().rotateAroundAxis(axis, theta));
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
/**
|
|
509
|
+
*
|
|
510
|
+
* @param theta
|
|
511
|
+
* @return
|
|
512
|
+
*/
|
|
513
|
+
@Override
|
|
514
|
+
public WETriangleMesh rotateX(float theta) {
|
|
515
|
+
return transform(matrix.identity().rotateX(theta));
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
*
|
|
520
|
+
* @param theta
|
|
521
|
+
* @return
|
|
522
|
+
*/
|
|
523
|
+
@Override
|
|
524
|
+
public WETriangleMesh rotateY(float theta) {
|
|
525
|
+
return transform(matrix.identity().rotateY(theta));
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
/**
|
|
529
|
+
*
|
|
530
|
+
* @param theta
|
|
531
|
+
* @return
|
|
532
|
+
*/
|
|
533
|
+
@Override
|
|
534
|
+
public WETriangleMesh rotateZ(float theta) {
|
|
535
|
+
return transform(matrix.identity().rotateZ(theta));
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
*
|
|
540
|
+
* @param scale
|
|
541
|
+
* @return
|
|
542
|
+
*/
|
|
543
|
+
@Override
|
|
544
|
+
public WETriangleMesh scale(float scale) {
|
|
545
|
+
return transform(matrix.identity().scaleSelf(scale));
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
*
|
|
550
|
+
* @param scale
|
|
551
|
+
* @return
|
|
552
|
+
*/
|
|
553
|
+
@Override
|
|
554
|
+
public WETriangleMesh scale(Vec3D scale) {
|
|
555
|
+
return transform(matrix.identity().scaleSelf(scale));
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
*
|
|
560
|
+
* @param a
|
|
561
|
+
* @param b
|
|
562
|
+
* @param subDiv
|
|
563
|
+
*/
|
|
564
|
+
public void splitEdge(ReadonlyVec3D a, ReadonlyVec3D b,
|
|
565
|
+
SubdivisionStrategy subDiv) {
|
|
566
|
+
WingedEdge e = edges.get(edgeCheck.set(a, b));
|
|
567
|
+
if (e != null) {
|
|
568
|
+
splitEdge(e, subDiv);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
/**
|
|
573
|
+
*
|
|
574
|
+
* @param e
|
|
575
|
+
* @param subDiv
|
|
576
|
+
*/
|
|
577
|
+
public void splitEdge(WingedEdge e, SubdivisionStrategy subDiv) {
|
|
578
|
+
List<Vec3D> mid = subDiv.computeSplitPoints(e);
|
|
579
|
+
splitFace(e.faces.get(0), e, mid);
|
|
580
|
+
if (e.faces.size() > 1) {
|
|
581
|
+
splitFace(e.faces.get(1), e, mid);
|
|
582
|
+
}
|
|
583
|
+
removeEdge(e);
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
*
|
|
588
|
+
* @param f
|
|
589
|
+
* @param e
|
|
590
|
+
* @param midPoints
|
|
591
|
+
*/
|
|
592
|
+
protected void splitFace(WEFace f, WingedEdge e, List<Vec3D> midPoints) {
|
|
593
|
+
Vec3D p = null;
|
|
594
|
+
for (int i = 0; i < 3; i++) {
|
|
595
|
+
WingedEdge ec = f.edges.get(i);
|
|
596
|
+
if (!ec.equals(e)) {
|
|
597
|
+
if (ec.a.equals(e.a) || ec.a.equals(e.b)) {
|
|
598
|
+
p = ec.b;
|
|
599
|
+
} else {
|
|
600
|
+
p = ec.a;
|
|
601
|
+
}
|
|
602
|
+
break;
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
Vec3D prev = null;
|
|
606
|
+
for (int i = 0, num = midPoints.size(); i < num; i++) {
|
|
607
|
+
Vec3D mid = midPoints.get(i);
|
|
608
|
+
if (i == 0) {
|
|
609
|
+
addFace(p, e.a, mid, f.normal);
|
|
610
|
+
} else {
|
|
611
|
+
addFace(p, prev, mid, f.normal);
|
|
612
|
+
}
|
|
613
|
+
if (i == num - 1) {
|
|
614
|
+
addFace(p, mid, e.b, f.normal);
|
|
615
|
+
}
|
|
616
|
+
prev = mid;
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
/**
|
|
621
|
+
*
|
|
622
|
+
*/
|
|
623
|
+
public void subdivide() {
|
|
624
|
+
subdivide(0);
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
/**
|
|
628
|
+
*
|
|
629
|
+
* @param minLength
|
|
630
|
+
*/
|
|
631
|
+
public void subdivide(float minLength) {
|
|
632
|
+
subdivide(new MidpointSubdivision(), minLength);
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
/**
|
|
636
|
+
*
|
|
637
|
+
* @param subDiv
|
|
638
|
+
*/
|
|
639
|
+
public void subdivide(SubdivisionStrategy subDiv) {
|
|
640
|
+
subdivide(subDiv, 0);
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
*
|
|
645
|
+
* @param subDiv
|
|
646
|
+
* @param minLength
|
|
647
|
+
*/
|
|
648
|
+
public void subdivide(SubdivisionStrategy subDiv, float minLength) {
|
|
649
|
+
subdivideEdges(new ArrayList<>(edges.values()), subDiv,
|
|
650
|
+
minLength);
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
*
|
|
655
|
+
* @param origEdges
|
|
656
|
+
* @param subDiv
|
|
657
|
+
* @param minLength
|
|
658
|
+
*/
|
|
659
|
+
protected void subdivideEdges(List<WingedEdge> origEdges,
|
|
660
|
+
SubdivisionStrategy subDiv, float minLength) {
|
|
661
|
+
Collections.sort(origEdges, subDiv.getEdgeOrdering());
|
|
662
|
+
minLength *= minLength;
|
|
663
|
+
for (WingedEdge e : origEdges) {
|
|
664
|
+
if (edges.containsKey(e)) {
|
|
665
|
+
if (e.getLengthSquared() >= minLength) {
|
|
666
|
+
splitEdge(e, subDiv);
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
/**
|
|
673
|
+
*
|
|
674
|
+
* @param faces
|
|
675
|
+
* @param subDiv
|
|
676
|
+
* @param minLength
|
|
677
|
+
*/
|
|
678
|
+
public void subdivideFaceEdges(List<WEFace> faces,
|
|
679
|
+
SubdivisionStrategy subDiv, float minLength) {
|
|
680
|
+
List<WingedEdge> fedges = new ArrayList<>();
|
|
681
|
+
faces.stream().forEach((f) -> {
|
|
682
|
+
f.edges.stream().filter((e) -> (!fedges.contains(e))).forEach((e) -> {
|
|
683
|
+
fedges.add(e);
|
|
684
|
+
});
|
|
685
|
+
});
|
|
686
|
+
subdivideEdges(fedges, subDiv, minLength);
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
/**
|
|
690
|
+
*
|
|
691
|
+
* @return
|
|
692
|
+
*/
|
|
693
|
+
@Override
|
|
694
|
+
public String toString() {
|
|
695
|
+
return "WETriangleMesh: " + name + " vertices: " + getNumVertices()
|
|
696
|
+
+ " faces: " + getNumFaces() + " edges:" + getNumEdges();
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
/**
|
|
700
|
+
* Applies the given matrix transform to all mesh vertices and updates all
|
|
701
|
+
* face normals.
|
|
702
|
+
*
|
|
703
|
+
* @param mat
|
|
704
|
+
* @return itself
|
|
705
|
+
*/
|
|
706
|
+
@Override
|
|
707
|
+
public WETriangleMesh transform(Matrix4x4 mat) {
|
|
708
|
+
return transform(mat, true);
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
/**
|
|
712
|
+
* Applies the given matrix transform to all mesh vertices. If the
|
|
713
|
+
* updateNormals flag is true, all face normals are updated automatically,
|
|
714
|
+
* however vertex normals still need a manual update.
|
|
715
|
+
*
|
|
716
|
+
* @param mat
|
|
717
|
+
* @param updateNormals
|
|
718
|
+
* @return itself
|
|
719
|
+
*/
|
|
720
|
+
@Override
|
|
721
|
+
public WETriangleMesh transform(Matrix4x4 mat, boolean updateNormals) {
|
|
722
|
+
vertices.values().stream().forEach((v) -> {
|
|
723
|
+
mat.applyToSelf(v);
|
|
724
|
+
});
|
|
725
|
+
rebuildIndex();
|
|
726
|
+
if (updateNormals) {
|
|
727
|
+
computeFaceNormals();
|
|
728
|
+
}
|
|
729
|
+
return this;
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
/**
|
|
733
|
+
*
|
|
734
|
+
* @param trans
|
|
735
|
+
* @return
|
|
736
|
+
*/
|
|
737
|
+
@Override
|
|
738
|
+
public WETriangleMesh translate(Vec3D trans) {
|
|
739
|
+
return transform(matrix.identity().translateSelf(trans));
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
/**
|
|
743
|
+
*
|
|
744
|
+
* @param va
|
|
745
|
+
* @param vb
|
|
746
|
+
* @param f
|
|
747
|
+
*/
|
|
748
|
+
protected void updateEdge(WEVertex va, WEVertex vb, WEFace f) {
|
|
749
|
+
edgeCheck.set(va, vb);
|
|
750
|
+
WingedEdge e = edges.get(edgeCheck);
|
|
751
|
+
if (e != null) {
|
|
752
|
+
e.addFace(f);
|
|
753
|
+
} else {
|
|
754
|
+
e = new WingedEdge(va, vb, f, uniqueEdgeID++);
|
|
755
|
+
edges.put(e, e);
|
|
756
|
+
va.addEdge(e);
|
|
757
|
+
vb.addEdge(e);
|
|
758
|
+
}
|
|
759
|
+
f.addEdge(e);
|
|
760
|
+
}
|
|
761
|
+
}
|