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.
Files changed (383) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +16 -0
  3. data/CHANGELOG.md +4 -0
  4. data/LICENSE +675 -0
  5. data/README.md +12 -5
  6. data/Rakefile +25 -82
  7. data/examples/attract_repel/attract_repel.rb +30 -0
  8. data/examples/attract_repel/attractor.rb +23 -0
  9. data/examples/attract_repel/particle.rb +27 -0
  10. data/examples/data/ti_yong.png +0 -0
  11. data/examples/force_directed/cluster.rb +76 -0
  12. data/examples/force_directed/force_directed_graph.rb +92 -0
  13. data/examples/force_directed/node.rb +26 -0
  14. data/examples/gray_scott_image.rb +75 -0
  15. data/examples/gray_scott_tone_map.rb +77 -0
  16. data/examples/implicit.rb +139 -0
  17. data/examples/inflate_mesh.rb +89 -0
  18. data/examples/model_align.rb +44 -0
  19. data/examples/povmesh/ftest.rb +46 -0
  20. data/examples/povmesh/tentacle.rb +73 -0
  21. data/examples/simple_cluster/cluster.rb +47 -0
  22. data/examples/simple_cluster/node.rb +27 -0
  23. data/examples/simple_cluster/simple_cluster.rb +60 -0
  24. data/examples/soft_body/blanket.rb +45 -0
  25. data/examples/soft_body/connection.rb +16 -0
  26. data/examples/soft_body/particle.rb +22 -0
  27. data/examples/soft_body/soft_body_square_adapted.rb +55 -0
  28. data/lib/toxiclibs.jar +0 -0
  29. data/lib/toxiclibs.rb +91 -32
  30. data/lib/toxiclibs/version.rb +1 -1
  31. data/pom.xml +122 -0
  32. data/src/com/toxi/net/ClientListener.java +41 -0
  33. data/src/com/toxi/net/ServerListener.java +70 -0
  34. data/src/com/toxi/net/ServerListenerAdapter.java +47 -0
  35. data/src/com/toxi/net/ServerState.java +18 -0
  36. data/src/com/toxi/net/UDPConnection.java +66 -0
  37. data/src/com/toxi/net/UDPSyncClient.java +81 -0
  38. data/src/com/toxi/net/UDPSyncServer.java +450 -0
  39. data/src/com/toxi/nio/UDPClient.java +121 -0
  40. data/src/com/toxi/nio/UDPClientState.java +32 -0
  41. data/src/com/toxi/nio/UDPServer.java +129 -0
  42. data/src/toxi/color/AccessCriteria.java +114 -0
  43. data/src/toxi/color/AlphaAccessor.java +67 -0
  44. data/src/toxi/color/CMYKAccessor.java +122 -0
  45. data/src/toxi/color/CMYKDistanceProxy.java +40 -0
  46. data/src/toxi/color/ColorGradient.java +260 -0
  47. data/src/toxi/color/ColorList.java +699 -0
  48. data/src/toxi/color/ColorRange.java +671 -0
  49. data/src/toxi/color/ColorTheme.java +163 -0
  50. data/src/toxi/color/DistanceProxy.java +44 -0
  51. data/src/toxi/color/HSVAccessor.java +113 -0
  52. data/src/toxi/color/HSVDistanceProxy.java +40 -0
  53. data/src/toxi/color/HistEntry.java +85 -0
  54. data/src/toxi/color/Histogram.java +185 -0
  55. data/src/toxi/color/Hue.java +249 -0
  56. data/src/toxi/color/LuminanceAccessor.java +78 -0
  57. data/src/toxi/color/NamedColor.java +935 -0
  58. data/src/toxi/color/ProximityComparator.java +70 -0
  59. data/src/toxi/color/RGBAccessor.java +113 -0
  60. data/src/toxi/color/RGBDistanceProxy.java +41 -0
  61. data/src/toxi/color/ReadonlyTColor.java +296 -0
  62. data/src/toxi/color/TColor.java +1677 -0
  63. data/src/toxi/color/TColorAdapter.java +68 -0
  64. data/src/toxi/color/ToneMap.java +218 -0
  65. data/src/toxi/color/theory/AnalogousStrategy.java +140 -0
  66. data/src/toxi/color/theory/ColorTheoryRegistry.java +139 -0
  67. data/src/toxi/color/theory/ColorTheoryStrategy.java +56 -0
  68. data/src/toxi/color/theory/ComplementaryStrategy.java +111 -0
  69. data/src/toxi/color/theory/CompoundTheoryStrategy.java +143 -0
  70. data/src/toxi/color/theory/LeftSplitComplementaryStrategy.java +82 -0
  71. data/src/toxi/color/theory/MonochromeTheoryStrategy.java +103 -0
  72. data/src/toxi/color/theory/RightSplitComplementaryStrategy.java +82 -0
  73. data/src/toxi/color/theory/SingleComplementStrategy.java +76 -0
  74. data/src/toxi/color/theory/SplitComplementaryStrategy.java +77 -0
  75. data/src/toxi/color/theory/TetradTheoryStrategy.java +114 -0
  76. data/src/toxi/color/theory/TriadTheoryStrategy.java +77 -0
  77. data/src/toxi/data/csv/CSVAdapter.java +74 -0
  78. data/src/toxi/data/csv/CSVFieldMapper.java +212 -0
  79. data/src/toxi/data/csv/CSVListener.java +61 -0
  80. data/src/toxi/data/csv/CSVParser.java +202 -0
  81. data/src/toxi/data/feeds/AtomAuthor.java +49 -0
  82. data/src/toxi/data/feeds/AtomContent.java +50 -0
  83. data/src/toxi/data/feeds/AtomEntry.java +111 -0
  84. data/src/toxi/data/feeds/AtomFeed.java +129 -0
  85. data/src/toxi/data/feeds/AtomLink.java +62 -0
  86. data/src/toxi/data/feeds/RSSChannel.java +88 -0
  87. data/src/toxi/data/feeds/RSSEnclosure.java +60 -0
  88. data/src/toxi/data/feeds/RSSFeed.java +99 -0
  89. data/src/toxi/data/feeds/RSSItem.java +104 -0
  90. data/src/toxi/data/feeds/util/EntityStripper.java +2480 -0
  91. data/src/toxi/data/feeds/util/Iso8601DateAdapter.java +101 -0
  92. data/src/toxi/data/feeds/util/Rfc822DateAdapter.java +93 -0
  93. data/src/toxi/geom/AABB.java +658 -0
  94. data/src/toxi/geom/Axis3D.java +116 -0
  95. data/src/toxi/geom/AxisAlignedCylinder.java +163 -0
  96. data/src/toxi/geom/BernsteinPolynomial.java +94 -0
  97. data/src/toxi/geom/BezierCurve2D.java +159 -0
  98. data/src/toxi/geom/BezierCurve3D.java +148 -0
  99. data/src/toxi/geom/BooleanShapeBuilder.java +185 -0
  100. data/src/toxi/geom/BoxIntersector.java +52 -0
  101. data/src/toxi/geom/Circle.java +230 -0
  102. data/src/toxi/geom/CircleIntersector.java +85 -0
  103. data/src/toxi/geom/Cone.java +150 -0
  104. data/src/toxi/geom/ConvexPolygonClipper.java +136 -0
  105. data/src/toxi/geom/CoordinateExtractor.java +16 -0
  106. data/src/toxi/geom/Ellipse.java +250 -0
  107. data/src/toxi/geom/GMatrix.java +2599 -0
  108. data/src/toxi/geom/GVector.java +833 -0
  109. data/src/toxi/geom/GlobalGridTesselator.java +54 -0
  110. data/src/toxi/geom/GridTesselator.java +108 -0
  111. data/src/toxi/geom/Intersector2D.java +49 -0
  112. data/src/toxi/geom/Intersector3D.java +51 -0
  113. data/src/toxi/geom/IsectData2D.java +103 -0
  114. data/src/toxi/geom/IsectData3D.java +103 -0
  115. data/src/toxi/geom/Line2D.java +534 -0
  116. data/src/toxi/geom/Line3D.java +471 -0
  117. data/src/toxi/geom/LineStrip2D.java +430 -0
  118. data/src/toxi/geom/LineStrip3D.java +230 -0
  119. data/src/toxi/geom/LocalGridTesselator.java +57 -0
  120. data/src/toxi/geom/Matrix3d.java +3048 -0
  121. data/src/toxi/geom/Matrix4f.java +3446 -0
  122. data/src/toxi/geom/Matrix4x4.java +1076 -0
  123. data/src/toxi/geom/MatrixSizeException.java +58 -0
  124. data/src/toxi/geom/OctreeVisitor.java +44 -0
  125. data/src/toxi/geom/Origin3D.java +148 -0
  126. data/src/toxi/geom/Plane.java +293 -0
  127. data/src/toxi/geom/PlaneIntersector.java +57 -0
  128. data/src/toxi/geom/PointCloud3D.java +253 -0
  129. data/src/toxi/geom/PointOctree.java +502 -0
  130. data/src/toxi/geom/PointQuadtree.java +375 -0
  131. data/src/toxi/geom/Polygon2D.java +1038 -0
  132. data/src/toxi/geom/PolygonClipper2D.java +45 -0
  133. data/src/toxi/geom/PolygonTesselator.java +20 -0
  134. data/src/toxi/geom/QuadtreeVisitor.java +44 -0
  135. data/src/toxi/geom/Quaternion.java +641 -0
  136. data/src/toxi/geom/Ray2D.java +146 -0
  137. data/src/toxi/geom/Ray3D.java +150 -0
  138. data/src/toxi/geom/Ray3DIntersector.java +75 -0
  139. data/src/toxi/geom/ReadonlyVec2D.java +575 -0
  140. data/src/toxi/geom/ReadonlyVec3D.java +628 -0
  141. data/src/toxi/geom/ReadonlyVec4D.java +431 -0
  142. data/src/toxi/geom/Rect.java +720 -0
  143. data/src/toxi/geom/Reflector3D.java +58 -0
  144. data/src/toxi/geom/Shape2D.java +94 -0
  145. data/src/toxi/geom/Shape3D.java +42 -0
  146. data/src/toxi/geom/SingularMatrixException.java +57 -0
  147. data/src/toxi/geom/SpatialBins.java +182 -0
  148. data/src/toxi/geom/SpatialIndex.java +61 -0
  149. data/src/toxi/geom/Sphere.java +224 -0
  150. data/src/toxi/geom/SphereIntersectorReflector.java +196 -0
  151. data/src/toxi/geom/Spline2D.java +349 -0
  152. data/src/toxi/geom/Spline3D.java +351 -0
  153. data/src/toxi/geom/SutherlandHodgemanClipper.java +151 -0
  154. data/src/toxi/geom/Triangle2D.java +422 -0
  155. data/src/toxi/geom/Triangle3D.java +456 -0
  156. data/src/toxi/geom/TriangleIntersector.java +105 -0
  157. data/src/toxi/geom/Vec2D.java +1328 -0
  158. data/src/toxi/geom/Vec3D.java +1832 -0
  159. data/src/toxi/geom/Vec4D.java +985 -0
  160. data/src/toxi/geom/VecMathUtil.java +100 -0
  161. data/src/toxi/geom/XAxisCylinder.java +64 -0
  162. data/src/toxi/geom/YAxisCylinder.java +65 -0
  163. data/src/toxi/geom/ZAxisCylinder.java +64 -0
  164. data/src/toxi/geom/mesh/BezierPatch.java +200 -0
  165. data/src/toxi/geom/mesh/BoxSelector.java +62 -0
  166. data/src/toxi/geom/mesh/DefaultSTLColorModel.java +67 -0
  167. data/src/toxi/geom/mesh/DefaultSelector.java +50 -0
  168. data/src/toxi/geom/mesh/Face.java +176 -0
  169. data/src/toxi/geom/mesh/LaplacianSmooth.java +80 -0
  170. data/src/toxi/geom/mesh/MaterialiseSTLColorModel.java +150 -0
  171. data/src/toxi/geom/mesh/Mesh3D.java +224 -0
  172. data/src/toxi/geom/mesh/MeshIntersector.java +91 -0
  173. data/src/toxi/geom/mesh/OBJWriter.java +194 -0
  174. data/src/toxi/geom/mesh/PLYWriter.java +167 -0
  175. data/src/toxi/geom/mesh/PlaneSelector.java +90 -0
  176. data/src/toxi/geom/mesh/STLColorModel.java +54 -0
  177. data/src/toxi/geom/mesh/STLReader.java +185 -0
  178. data/src/toxi/geom/mesh/STLWriter.java +323 -0
  179. data/src/toxi/geom/mesh/SphereFunction.java +156 -0
  180. data/src/toxi/geom/mesh/SphericalHarmonics.java +110 -0
  181. data/src/toxi/geom/mesh/SuperEllipsoid.java +110 -0
  182. data/src/toxi/geom/mesh/SurfaceFunction.java +75 -0
  183. data/src/toxi/geom/mesh/SurfaceMeshBuilder.java +149 -0
  184. data/src/toxi/geom/mesh/Terrain.java +451 -0
  185. data/src/toxi/geom/mesh/TriangleMesh.java +1201 -0
  186. data/src/toxi/geom/mesh/Vertex.java +78 -0
  187. data/src/toxi/geom/mesh/VertexSelector.java +193 -0
  188. data/src/toxi/geom/mesh/WEFace.java +100 -0
  189. data/src/toxi/geom/mesh/WEMeshFilterStrategy.java +51 -0
  190. data/src/toxi/geom/mesh/WETriangleMesh.java +761 -0
  191. data/src/toxi/geom/mesh/WEVertex.java +134 -0
  192. data/src/toxi/geom/mesh/WingedEdge.java +115 -0
  193. data/src/toxi/geom/mesh/subdiv/CentroidSubdiv.java +37 -0
  194. data/src/toxi/geom/mesh/subdiv/DisplacementSubdivision.java +85 -0
  195. data/src/toxi/geom/mesh/subdiv/DualDisplacementSubdivision.java +94 -0
  196. data/src/toxi/geom/mesh/subdiv/DualSubdivision.java +49 -0
  197. data/src/toxi/geom/mesh/subdiv/EdgeLengthComparator.java +50 -0
  198. data/src/toxi/geom/mesh/subdiv/FaceCountComparator.java +51 -0
  199. data/src/toxi/geom/mesh/subdiv/MidpointDisplacementSubdivision.java +80 -0
  200. data/src/toxi/geom/mesh/subdiv/MidpointSubdiv.java +42 -0
  201. data/src/toxi/geom/mesh/subdiv/MidpointSubdivision.java +48 -0
  202. data/src/toxi/geom/mesh/subdiv/NewSubdivStrategy.java +23 -0
  203. data/src/toxi/geom/mesh/subdiv/NormalDisplacementSubdivision.java +74 -0
  204. data/src/toxi/geom/mesh/subdiv/SubdivisionStrategy.java +83 -0
  205. data/src/toxi/geom/mesh/subdiv/TriSubdivision.java +51 -0
  206. data/src/toxi/geom/mesh2d/DelaunayTriangle.java +222 -0
  207. data/src/toxi/geom/mesh2d/DelaunayTriangulation.java +327 -0
  208. data/src/toxi/geom/mesh2d/DelaunayVertex.java +560 -0
  209. data/src/toxi/geom/mesh2d/Voronoi.java +149 -0
  210. data/src/toxi/geom/nurbs/BasicNurbsCurve.java +210 -0
  211. data/src/toxi/geom/nurbs/BasicNurbsSurface.java +233 -0
  212. data/src/toxi/geom/nurbs/ControlNet.java +148 -0
  213. data/src/toxi/geom/nurbs/CurveCreator.java +112 -0
  214. data/src/toxi/geom/nurbs/CurveUtils.java +259 -0
  215. data/src/toxi/geom/nurbs/InterpolationException.java +65 -0
  216. data/src/toxi/geom/nurbs/KnotVector.java +333 -0
  217. data/src/toxi/geom/nurbs/NurbsCreator.java +815 -0
  218. data/src/toxi/geom/nurbs/NurbsCurve.java +120 -0
  219. data/src/toxi/geom/nurbs/NurbsMeshCreator.java +145 -0
  220. data/src/toxi/geom/nurbs/NurbsSurface.java +147 -0
  221. data/src/toxi/image/util/Filter8bit.java +331 -0
  222. data/src/toxi/image/util/TiledFrameExporter.java +162 -0
  223. data/src/toxi/math/BezierInterpolation.java +102 -0
  224. data/src/toxi/math/CircularInterpolation.java +88 -0
  225. data/src/toxi/math/CosineInterpolation.java +51 -0
  226. data/src/toxi/math/DecimatedInterpolation.java +77 -0
  227. data/src/toxi/math/ExponentialInterpolation.java +68 -0
  228. data/src/toxi/math/InterpolateStrategy.java +60 -0
  229. data/src/toxi/math/Interpolation2D.java +93 -0
  230. data/src/toxi/math/LinearInterpolation.java +46 -0
  231. data/src/toxi/math/MathUtils.java +990 -0
  232. data/src/toxi/math/NonLinearScaleMap.java +101 -0
  233. data/src/toxi/math/ScaleMap.java +183 -0
  234. data/src/toxi/math/SigmoidInterpolation.java +78 -0
  235. data/src/toxi/math/SinCosLUT.java +141 -0
  236. data/src/toxi/math/ThresholdInterpolation.java +58 -0
  237. data/src/toxi/math/ZoomLensInterpolation.java +126 -0
  238. data/src/toxi/math/conversion/UnitTranslator.java +161 -0
  239. data/src/toxi/math/noise/PerlinNoise.java +281 -0
  240. data/src/toxi/math/noise/SimplexNoise.java +542 -0
  241. data/src/toxi/math/waves/AMFMSineWave.java +143 -0
  242. data/src/toxi/math/waves/AbstractWave.java +248 -0
  243. data/src/toxi/math/waves/ConstantWave.java +48 -0
  244. data/src/toxi/math/waves/FMHarmonicSquareWave.java +155 -0
  245. data/src/toxi/math/waves/FMSawtoothWave.java +144 -0
  246. data/src/toxi/math/waves/FMSineWave.java +142 -0
  247. data/src/toxi/math/waves/FMSquareWave.java +143 -0
  248. data/src/toxi/math/waves/FMTriangleWave.java +126 -0
  249. data/src/toxi/math/waves/SineWave.java +81 -0
  250. data/src/toxi/math/waves/Wave2D.java +68 -0
  251. data/src/toxi/math/waves/WaveState.java +69 -0
  252. data/src/toxi/music/scale/AbstractScale.java +117 -0
  253. data/src/toxi/music/scale/GenericScale.java +66 -0
  254. data/src/toxi/music/scale/MajorScale.java +41 -0
  255. data/src/toxi/newmesh/AttributedEdge.java +106 -0
  256. data/src/toxi/newmesh/AttributedFace.java +63 -0
  257. data/src/toxi/newmesh/IndexedTriangleMesh.java +809 -0
  258. data/src/toxi/newmesh/MeshAttributeCompiler.java +45 -0
  259. data/src/toxi/newmesh/MeshFaceNormalCompiler.java +52 -0
  260. data/src/toxi/newmesh/MeshUVCompiler.java +52 -0
  261. data/src/toxi/newmesh/MeshVertexColorCompiler.java +49 -0
  262. data/src/toxi/newmesh/MeshVertexCompiler.java +54 -0
  263. data/src/toxi/newmesh/MeshVertexNormalCompiler.java +55 -0
  264. data/src/toxi/newmesh/SpatialIndex.java +78 -0
  265. data/src/toxi/physics2d/ParticlePath2D.java +100 -0
  266. data/src/toxi/physics2d/ParticleString2D.java +184 -0
  267. data/src/toxi/physics2d/PullBackSpring2D.java +51 -0
  268. data/src/toxi/physics2d/VerletConstrainedSpring2D.java +89 -0
  269. data/src/toxi/physics2d/VerletMinDistanceSpring2D.java +57 -0
  270. data/src/toxi/physics2d/VerletParticle2D.java +457 -0
  271. data/src/toxi/physics2d/VerletPhysics2D.java +448 -0
  272. data/src/toxi/physics2d/VerletSpring2D.java +181 -0
  273. data/src/toxi/physics2d/behaviors/AttractionBehavior2D.java +212 -0
  274. data/src/toxi/physics2d/behaviors/ConstantForceBehavior2D.java +112 -0
  275. data/src/toxi/physics2d/behaviors/GravityBehavior2D.java +61 -0
  276. data/src/toxi/physics2d/behaviors/ParticleBehavior2D.java +66 -0
  277. data/src/toxi/physics2d/constraints/AngularConstraint.java +83 -0
  278. data/src/toxi/physics2d/constraints/AxisConstraint.java +71 -0
  279. data/src/toxi/physics2d/constraints/CircularConstraint.java +69 -0
  280. data/src/toxi/physics2d/constraints/MaxConstraint.java +66 -0
  281. data/src/toxi/physics2d/constraints/MinConstraint.java +66 -0
  282. data/src/toxi/physics2d/constraints/ParticleConstraint2D.java +47 -0
  283. data/src/toxi/physics2d/constraints/PolygonConstraint.java +93 -0
  284. data/src/toxi/physics2d/constraints/RectConstraint.java +114 -0
  285. data/src/toxi/physics3d/ParticlePath3D.java +100 -0
  286. data/src/toxi/physics3d/ParticleString3D.java +184 -0
  287. data/src/toxi/physics3d/PullBackSpring3D.java +50 -0
  288. data/src/toxi/physics3d/VerletConstrainedSpring3D.java +88 -0
  289. data/src/toxi/physics3d/VerletMinDistanceSpring3D.java +56 -0
  290. data/src/toxi/physics3d/VerletParticle3D.java +385 -0
  291. data/src/toxi/physics3d/VerletPhysics3D.java +417 -0
  292. data/src/toxi/physics3d/VerletSpring3D.java +180 -0
  293. data/src/toxi/physics3d/behaviors/AttractionBehavior3D.java +182 -0
  294. data/src/toxi/physics3d/behaviors/ConstantForceBehavior3D.java +92 -0
  295. data/src/toxi/physics3d/behaviors/GravityBehavior3D.java +61 -0
  296. data/src/toxi/physics3d/behaviors/ParticleBehavior3D.java +52 -0
  297. data/src/toxi/physics3d/constraints/AxisConstraint.java +68 -0
  298. data/src/toxi/physics3d/constraints/BoxConstraint.java +121 -0
  299. data/src/toxi/physics3d/constraints/CylinderConstraint.java +87 -0
  300. data/src/toxi/physics3d/constraints/MaxConstraint.java +65 -0
  301. data/src/toxi/physics3d/constraints/MinConstraint.java +65 -0
  302. data/src/toxi/physics3d/constraints/ParticleConstraint3D.java +49 -0
  303. data/src/toxi/physics3d/constraints/PlaneConstraint.java +78 -0
  304. data/src/toxi/physics3d/constraints/SoftBoxConstraint.java +87 -0
  305. data/src/toxi/physics3d/constraints/SphereConstraint.java +108 -0
  306. data/src/toxi/processing/ArrowModifier.java +116 -0
  307. data/src/toxi/processing/DashedLineModifier.java +48 -0
  308. data/src/toxi/processing/DeltaOrientationMapper.java +57 -0
  309. data/src/toxi/processing/Line2DRenderModifier.java +18 -0
  310. data/src/toxi/processing/MeshToVBO.java +94 -0
  311. data/src/toxi/processing/NormalMapper.java +18 -0
  312. data/src/toxi/processing/POVInterface.java +121 -0
  313. data/src/toxi/processing/POVMesh.java +219 -0
  314. data/src/toxi/processing/POVWriter.java +460 -0
  315. data/src/toxi/processing/RCOpaque.java +77 -0
  316. data/src/toxi/processing/RCTransp.java +78 -0
  317. data/src/toxi/processing/TextureBuilder.java +232 -0
  318. data/src/toxi/processing/Textures.java +110 -0
  319. data/src/toxi/processing/ToxiclibsSupport.java +1239 -0
  320. data/src/toxi/processing/Tracing.java +25 -0
  321. data/src/toxi/processing/XYZNormalMapper.java +30 -0
  322. data/src/toxi/sim/automata/CAMatrix.java +297 -0
  323. data/src/toxi/sim/automata/CARule.java +76 -0
  324. data/src/toxi/sim/automata/CARule2D.java +354 -0
  325. data/src/toxi/sim/automata/CAWolfram1D.java +309 -0
  326. data/src/toxi/sim/automata/EvolvableMatrix.java +61 -0
  327. data/src/toxi/sim/automata/MatrixEvolver.java +42 -0
  328. data/src/toxi/sim/dla/BottomUpOrder.java +76 -0
  329. data/src/toxi/sim/dla/DLA.java +497 -0
  330. data/src/toxi/sim/dla/DLAConfiguration.java +364 -0
  331. data/src/toxi/sim/dla/DLAEventAdapter.java +64 -0
  332. data/src/toxi/sim/dla/DLAEventListener.java +57 -0
  333. data/src/toxi/sim/dla/DLAGuideLines.java +219 -0
  334. data/src/toxi/sim/dla/DLAParticle.java +102 -0
  335. data/src/toxi/sim/dla/DLASegment.java +88 -0
  336. data/src/toxi/sim/dla/PipelineOrder.java +50 -0
  337. data/src/toxi/sim/dla/RadialDistanceOrder.java +92 -0
  338. data/src/toxi/sim/erosion/ErosionFunction.java +122 -0
  339. data/src/toxi/sim/erosion/TalusAngleErosion.java +145 -0
  340. data/src/toxi/sim/erosion/ThermalErosion.java +75 -0
  341. data/src/toxi/sim/fluids/FluidSolver2D.java +762 -0
  342. data/src/toxi/sim/fluids/FluidSolver3D.java +326 -0
  343. data/src/toxi/sim/grayscott/GrayScott.java +469 -0
  344. data/src/toxi/util/DateUtils.java +141 -0
  345. data/src/toxi/util/FileSequenceDescriptor.java +181 -0
  346. data/src/toxi/util/FileUtils.java +467 -0
  347. data/src/toxi/util/datatypes/ArraySet.java +128 -0
  348. data/src/toxi/util/datatypes/ArrayUtil.java +404 -0
  349. data/src/toxi/util/datatypes/BiasedDoubleRange.java +141 -0
  350. data/src/toxi/util/datatypes/BiasedFloatRange.java +141 -0
  351. data/src/toxi/util/datatypes/BiasedIntegerRange.java +141 -0
  352. data/src/toxi/util/datatypes/DoubleRange.java +251 -0
  353. data/src/toxi/util/datatypes/FloatRange.java +251 -0
  354. data/src/toxi/util/datatypes/GenericSet.java +215 -0
  355. data/src/toxi/util/datatypes/IntegerRange.java +247 -0
  356. data/src/toxi/util/datatypes/IntegerSet.java +149 -0
  357. data/src/toxi/util/datatypes/ItemIndex.java +72 -0
  358. data/src/toxi/util/datatypes/SingletonRegistry.java +91 -0
  359. data/src/toxi/util/datatypes/TypedProperties.java +291 -0
  360. data/src/toxi/util/datatypes/UndirectedGraph.java +134 -0
  361. data/src/toxi/util/datatypes/UniqueItemIndex.java +223 -0
  362. data/src/toxi/util/datatypes/WeightedRandomEntry.java +76 -0
  363. data/src/toxi/util/datatypes/WeightedRandomSet.java +125 -0
  364. data/src/toxi/util/events/EventDispatcher.java +86 -0
  365. data/src/toxi/volume/AdditiveBrush.java +19 -0
  366. data/src/toxi/volume/ArrayIsoSurface.java +297 -0
  367. data/src/toxi/volume/BoxBrush.java +100 -0
  368. data/src/toxi/volume/BrushMode.java +16 -0
  369. data/src/toxi/volume/HashIsoSurface.java +354 -0
  370. data/src/toxi/volume/IsoSurface.java +59 -0
  371. data/src/toxi/volume/MarchingCubesIndex.java +312 -0
  372. data/src/toxi/volume/MeshLatticeBuilder.java +358 -0
  373. data/src/toxi/volume/MeshVoxelizer.java +216 -0
  374. data/src/toxi/volume/MultiplyBrush.java +20 -0
  375. data/src/toxi/volume/PeakBrush.java +21 -0
  376. data/src/toxi/volume/ReplaceBrush.java +19 -0
  377. data/src/toxi/volume/RoundBrush.java +113 -0
  378. data/src/toxi/volume/VolumetricBrush.java +160 -0
  379. data/src/toxi/volume/VolumetricHashMap.java +179 -0
  380. data/src/toxi/volume/VolumetricSpace.java +195 -0
  381. data/src/toxi/volume/VolumetricSpaceArray.java +214 -0
  382. data/toxiclibs.gemspec +34 -0
  383. metadata +424 -27
@@ -0,0 +1,106 @@
1
+ package toxi.newmesh;
2
+
3
+ import java.util.ArrayList;
4
+ import java.util.List;
5
+
6
+ /**
7
+ *
8
+ * @author tux
9
+ */
10
+ public class AttributedEdge {
11
+
12
+ public final int a,
13
+
14
+ /**
15
+ *
16
+ */
17
+
18
+ /**
19
+ *
20
+ */
21
+ b;
22
+
23
+ /**
24
+ *
25
+ */
26
+ public List<AttributedFace> faces;
27
+
28
+ /**
29
+ *
30
+ * @param a
31
+ * @param b
32
+ */
33
+ public AttributedEdge(int a, int b) {
34
+ this.a = a;
35
+ this.b = b;
36
+ }
37
+
38
+ /**
39
+ *
40
+ * @param f
41
+ */
42
+ public void addFace(AttributedFace f) {
43
+ if (faces == null) {
44
+ faces = new ArrayList<>(2);
45
+ }
46
+ faces.add(f);
47
+ }
48
+
49
+ /*
50
+ * (non-Javadoc)
51
+ *
52
+ * @see java.lang.Object#equals(java.lang.Object)
53
+ */
54
+
55
+ /**
56
+ *
57
+ * @param obj
58
+ * @return
59
+ */
60
+
61
+ @Override
62
+ public boolean equals(Object obj) {
63
+ if (this == obj) {
64
+ return true;
65
+ }
66
+ if (obj == null) {
67
+ return false;
68
+ }
69
+ if (getClass() != obj.getClass()) {
70
+ return false;
71
+ }
72
+ AttributedEdge other = (AttributedEdge) obj;
73
+ if (a != other.a) {
74
+ return false;
75
+ }
76
+ return (b != other.b) ;
77
+ }
78
+
79
+ /*
80
+ * (non-Javadoc)
81
+ *
82
+ * @see java.lang.Object#hashCode()
83
+ */
84
+
85
+ /**
86
+ *
87
+ * @return
88
+ */
89
+
90
+ @Override
91
+ public int hashCode() {
92
+ final int prime = 31;
93
+ int result = prime + a;
94
+ result = prime * result + b;
95
+ return result;
96
+ }
97
+
98
+ /**
99
+ *
100
+ * @return
101
+ */
102
+ @Override
103
+ public String toString() {
104
+ return String.format("a=%d, b=%d", a, b);
105
+ }
106
+ }
@@ -0,0 +1,63 @@
1
+ package toxi.newmesh;
2
+
3
+ import java.util.HashMap;
4
+
5
+ /**
6
+ *
7
+ * @author tux
8
+ */
9
+ public class AttributedFace {
10
+
11
+ public int a,
12
+
13
+ /**
14
+ *
15
+ */
16
+
17
+ /**
18
+ *
19
+ */
20
+ b,
21
+
22
+ /**
23
+ *
24
+ */
25
+
26
+ /**
27
+ *
28
+ */
29
+ c;
30
+
31
+ /**
32
+ *
33
+ */
34
+ public int normal = -1;
35
+
36
+ /**
37
+ *
38
+ */
39
+ public HashMap<String, int[]> attribs;
40
+
41
+ /**
42
+ *
43
+ * @param a
44
+ * @param b
45
+ * @param c
46
+ * @param attribs
47
+ */
48
+ public AttributedFace(int a, int b, int c, HashMap<String, int[]> attribs) {
49
+ this.a = a;
50
+ this.b = b;
51
+ this.c = c;
52
+ this.attribs = attribs;
53
+ }
54
+
55
+ /**
56
+ *
57
+ * @return
58
+ */
59
+ @Override
60
+ public String toString() {
61
+ return String.format("a=%d,b=%d,c=%d,n=%d", a, b, c, normal);
62
+ }
63
+ }
@@ -0,0 +1,809 @@
1
+ package toxi.newmesh;
2
+
3
+ import java.util.ArrayList;
4
+ import java.util.HashMap;
5
+ import java.util.HashSet;
6
+ import java.util.Iterator;
7
+ import java.util.List;
8
+
9
+ import toxi.geom.AABB;
10
+ import toxi.geom.IsectData3D;
11
+ import toxi.geom.Ray3D;
12
+ import toxi.geom.ReadonlyVec3D;
13
+ import toxi.geom.Sphere;
14
+ import toxi.geom.Triangle3D;
15
+ import toxi.geom.TriangleIntersector;
16
+ import toxi.geom.Vec2D;
17
+ import toxi.geom.Vec3D;
18
+ import toxi.geom.mesh.subdiv.NewSubdivStrategy;
19
+ import toxi.util.datatypes.ItemIndex;
20
+ import toxi.util.datatypes.UniqueItemIndex;
21
+
22
+ /**
23
+ *
24
+ * @author tux
25
+ */
26
+ public class IndexedTriangleMesh {
27
+
28
+ /**
29
+ *
30
+ */
31
+ public static final String ATTR_EDGES = "edges";
32
+
33
+ /**
34
+ *
35
+ */
36
+ public static final String ATTR_FNORMALS = "fnormals";
37
+
38
+ /**
39
+ *
40
+ */
41
+ public static final String ATTR_UVCOORDS = "uv";
42
+
43
+ /**
44
+ *
45
+ */
46
+ public static final String ATTR_VCOLORS = "col";
47
+
48
+ /**
49
+ *
50
+ */
51
+ public static final String ATTR_VERTICES = "vertices";
52
+
53
+ /**
54
+ *
55
+ */
56
+ public static final String ATTR_VNORMALS = "vnormals";
57
+
58
+ /**
59
+ *
60
+ */
61
+ public SpatialIndex vertices = new SpatialIndex(0.001f);
62
+
63
+ /**
64
+ *
65
+ */
66
+ public ItemIndex<Vec3D> fnormals = new UniqueItemIndex<>();
67
+
68
+ /**
69
+ *
70
+ */
71
+ public final ArrayList<AttributedFace> faces = new ArrayList<>();
72
+
73
+ /**
74
+ *
75
+ */
76
+ public final HashMap<String, UniqueItemIndex<Object>> attributes = new HashMap<>();
77
+
78
+ /**
79
+ *
80
+ */
81
+ public IndexedTriangleMesh() {
82
+ }
83
+
84
+ /**
85
+ *
86
+ * @param a
87
+ * @param b
88
+ * @param c
89
+ * @param attribs
90
+ * @return
91
+ */
92
+ public IndexedTriangleMesh addFace(Vec3D a, Vec3D b, Vec3D c,
93
+ HashMap<String, Object[]> attribs) {
94
+ int idA = vertices.index(a);
95
+ int idB = vertices.index(b);
96
+ int idC = vertices.index(c);
97
+ if (idA != idB && idA != idC && idB != idC) {
98
+ AttributedFace f = new AttributedFace(idA, idB, idC,
99
+ addFaceAttributes(null, attribs));
100
+ faces.add(f);
101
+ }
102
+ return this;
103
+ }
104
+
105
+ /**
106
+ *
107
+ * @param a
108
+ * @param b
109
+ * @param c
110
+ * @param uva
111
+ * @param uvb
112
+ * @param uvc
113
+ * @return
114
+ */
115
+ public IndexedTriangleMesh addFace(Vec3D a, Vec3D b, Vec3D c, Vec2D uva,
116
+ Vec2D uvb, Vec2D uvc) {
117
+ HashMap<String, Object[]> attribs = null;
118
+ if (uva != null && uvb != null && uvc != null) {
119
+ attribs = new HashMap<>();
120
+ attribs.put(ATTR_UVCOORDS, new Object[] {
121
+ uva, uvb, uvc
122
+ });
123
+ }
124
+ return addFace(a, b, c, attribs);
125
+ }
126
+
127
+ /**
128
+ *
129
+ * @param f
130
+ * @param attrib
131
+ * @param attA
132
+ * @param attB
133
+ * @param attC
134
+ * @return
135
+ */
136
+ public HashMap<String, int[]> addFaceAttribute(AttributedFace f,
137
+ String attrib, Object attA, Object attB, Object attC) {
138
+ if (f != null && attrib != null && attA != null && attB != null
139
+ && attC != null) {
140
+ ItemIndex<Object> idx = getAttributeIndex(attrib);
141
+ f.attribs.put(attrib, new int[] {
142
+ idx.index(attA), idx.index(attB), idx.index(attC)
143
+ });
144
+ return f.attribs;
145
+ }
146
+ return null;
147
+ }
148
+
149
+ /**
150
+ *
151
+ * @param f
152
+ * @param attribs
153
+ * @return
154
+ */
155
+ public HashMap<String, int[]> addFaceAttributes(AttributedFace f,
156
+ HashMap<String, Object[]> attribs) {
157
+ HashMap<String, int[]> fattribs = null;
158
+ if (attribs != null) {
159
+ fattribs = (f != null) ? f.attribs : new HashMap<String, int[]>(
160
+ attribs.size(), 1);
161
+ for (String attID : attribs.keySet()) {
162
+ Object[] items = attribs.get(attID);
163
+ if (items.length >= 3) {
164
+ ItemIndex<Object> idx = getAttributeIndex(attID);
165
+ int[] ids = new int[] {
166
+ idx.index(items[0]), idx.index(items[1]),
167
+ idx.index(items[2])
168
+ };
169
+ fattribs.put(attID, ids);
170
+ }
171
+ }
172
+ }
173
+ return fattribs;
174
+ }
175
+
176
+ /**
177
+ *
178
+ * @param mesh
179
+ * @return
180
+ */
181
+ public IndexedTriangleMesh addMesh(IndexedTriangleMesh mesh) {
182
+ Vec3D[] v = null;
183
+ for (AttributedFace f : mesh.faces) {
184
+ v = mesh.getFaceVertices(f, v);
185
+ addFace(v[0], v[1], v[2], null);
186
+ }
187
+ return this;
188
+ }
189
+
190
+ /**
191
+ *
192
+ * @param mesh
193
+ * @return
194
+ */
195
+ public IndexedTriangleMesh addMeshWithAttribs(IndexedTriangleMesh mesh) {
196
+ HashMap<String, Object[]> attribs = new HashMap<>();
197
+ Vec3D[] v = null;
198
+ for (AttributedFace f : mesh.faces) {
199
+ attribs.clear();
200
+ for (String a : f.attribs.keySet()) {
201
+ attribs.put(a, mesh.getFaceAttribValues(f, a));
202
+ }
203
+ v = mesh.getFaceVertices(f, v);
204
+ addFace(v[0], v[1], v[2], attribs);
205
+ }
206
+ return this;
207
+ }
208
+
209
+ /**
210
+ *
211
+ * @return
212
+ */
213
+ public IndexedTriangleMesh clear() {
214
+ vertices.clear();
215
+ fnormals.clear();
216
+ attributes.clear();
217
+ faces.clear();
218
+ return this;
219
+ }
220
+
221
+ /**
222
+ *
223
+ * @return
224
+ */
225
+ public HashMap<String, float[]> compile() {
226
+ HashSet<String> attribs = new HashSet<>();
227
+ attribs.add(ATTR_VERTICES);
228
+ attribs.add(ATTR_FNORMALS);
229
+ return compile(attribs, null);
230
+ }
231
+
232
+ /**
233
+ *
234
+ * @param attribs
235
+ * @param compilers
236
+ * @return
237
+ */
238
+ public HashMap<String, float[]> compile(HashSet<String> attribs,
239
+ HashMap<String, MeshAttributeCompiler> compilers) {
240
+ HashMap<String, MeshAttributeCompiler> mergedComps = new HashMap<>(
241
+ getDefaultCompilers());
242
+ if (compilers != null) {
243
+ mergedComps.putAll(compilers);
244
+ }
245
+ HashMap<String, float[]> buffers = new HashMap<>();
246
+ int numF = faces.size();
247
+ for (String attrib : attribs) {
248
+ MeshAttributeCompiler comp = mergedComps.get(attrib);
249
+ if (comp != null) {
250
+ comp.setMesh(this);
251
+ ItemIndex<?> index = comp.getIndex();
252
+ int faceStride = 3 * comp.getStride();
253
+ float[] buf = new float[numF * faceStride];
254
+ int offset = 0;
255
+ for (AttributedFace f : faces) {
256
+ comp.compileFace(f, index, buf, offset);
257
+ offset += faceStride;
258
+ }
259
+ buffers.put(attrib, buf);
260
+ }
261
+ }
262
+ return buffers;
263
+ }
264
+
265
+ /**
266
+ *
267
+ * @return
268
+ */
269
+ public List<Object> computeEdges() {
270
+ ItemIndex<Object> edges = getAttributeIndex(ATTR_EDGES);
271
+ edges.clear();
272
+ for (AttributedFace f : faces) {
273
+ if (f.attribs == null) {
274
+ f.attribs = new HashMap<>();
275
+ }
276
+ f.attribs.put(ATTR_EDGES, new int[] {
277
+ indexFaceEdge(f, f.a, f.b), indexFaceEdge(f, f.b, f.c),
278
+ indexFaceEdge(f, f.c, f.a)
279
+ });
280
+ }
281
+ return edges.getItems();
282
+ }
283
+
284
+ /**
285
+ *
286
+ * @return
287
+ */
288
+ public List<Vec3D> computeFaceNormals() {
289
+ fnormals.clear();
290
+ Vec3D[] v = null;
291
+ for (AttributedFace f : faces) {
292
+ v = getFaceVertices(f, v);
293
+ f.normal = fnormals.index(v[0].sub(v[1]).crossSelf(v[0].sub(v[2]))
294
+ .normalize());
295
+ }
296
+ return fnormals.getItems();
297
+ }
298
+
299
+ /**
300
+ *
301
+ * @return
302
+ */
303
+ public List<Object> computeVertexNormals() {
304
+ Vec3D[] vnorms = new Vec3D[vertices.size()];
305
+ for (int i = 0; i < vnorms.length; i++) {
306
+ vnorms[i] = new Vec3D();
307
+ }
308
+ for (AttributedFace f : faces) {
309
+ final Vec3D n = fnormals.forID(f.normal);
310
+ vnorms[f.a].addSelf(n);
311
+ vnorms[f.b].addSelf(n);
312
+ vnorms[f.c].addSelf(n);
313
+ }
314
+ for (Vec3D vnorm : vnorms) {
315
+ vnorm.normalize();
316
+ }
317
+ ItemIndex<Object> idx = getAttributeIndex(ATTR_VNORMALS);
318
+ idx.clear();
319
+ for (AttributedFace f : faces) {
320
+ if (f.attribs == null) {
321
+ f.attribs = new HashMap<>();
322
+ }
323
+ f.attribs.put(
324
+ ATTR_VNORMALS,
325
+ new int[] {
326
+ idx.index(vnorms[f.a]), idx.index(vnorms[f.b]),
327
+ idx.index(vnorms[f.c])
328
+ });
329
+ }
330
+ return idx.getItems();
331
+ }
332
+
333
+ /**
334
+ *
335
+ * @param f
336
+ * @param offset
337
+ * @param scale
338
+ * @return
339
+ */
340
+ public IndexedTriangleMesh extrudeFace(AttributedFace f, Vec3D offset,
341
+ float scale) {
342
+ Vec3D[] v = getFaceVertices(f, null);
343
+ Vec3D[] v2 = new Vec3D[3];
344
+ Vec3D c = v[0].add(v[1]).addSelf(v[2]).scaleSelf(1 / 3f);
345
+ Vec3D n = c.add(offset);
346
+ v2[0] = v[0].sub(c).scaleSelf(scale).addSelf(n);
347
+ v2[1] = v[1].sub(c).scaleSelf(scale).addSelf(n);
348
+ v2[2] = v[2].sub(c).scaleSelf(scale).addSelf(n);
349
+ removeFace(f);
350
+ // extruded copy
351
+ addFace(v2[0], v2[1], v2[2], null);
352
+ // sides
353
+ addFace(v[0], v[1], v2[0], null);
354
+ addFace(v[1], v2[1], v2[0], null);
355
+ addFace(v[1], v[2], v2[1], null);
356
+ addFace(v[2], v2[2], v2[1], null);
357
+ addFace(v[2], v[0], v2[2], null);
358
+ addFace(v[0], v2[0], v2[2], null);
359
+ return this;
360
+ }
361
+
362
+ /**
363
+ * Flips the current order of all face vertices and attributes. If face or
364
+ * vertex normals are present their direction will be inverted as well.
365
+ *
366
+ * @return itself
367
+ */
368
+ public IndexedTriangleMesh flipVertexOrder() {
369
+ for (AttributedFace f : faces) {
370
+ int t = f.b;
371
+ f.b = f.c;
372
+ f.c = t;
373
+ if (f.attribs != null) {
374
+ for (int[] att : f.attribs.values()) {
375
+ t = att[1];
376
+ att[1] = att[2];
377
+ att[2] = t;
378
+ }
379
+ }
380
+ }
381
+ for (Vec3D n : fnormals.getItems()) {
382
+ fnormals.reindex(n, n.getInverted());
383
+ }
384
+ ItemIndex<Object> vnormals = attributes.get(ATTR_VNORMALS);
385
+ if (vnormals != null) {
386
+ for (Object n : vnormals.getItems()) {
387
+ vnormals.reindex(n, ((Vec3D) n).getInverted());
388
+ }
389
+ }
390
+ return this;
391
+ }
392
+
393
+ /**
394
+ *
395
+ * @param attID
396
+ * @return
397
+ */
398
+ public ItemIndex<Object> getAttributeIndex(String attID) {
399
+ UniqueItemIndex<Object> idx = attributes.get(attID);
400
+ if (idx == null) {
401
+ idx = new UniqueItemIndex<>();
402
+ attributes.put(attID, idx);
403
+ }
404
+ return idx;
405
+ }
406
+
407
+ /**
408
+ *
409
+ * @return
410
+ */
411
+ public Sphere getBoundingSphere() {
412
+ return getBounds().getBoundingSphere();
413
+ }
414
+
415
+ /**
416
+ *
417
+ * @return
418
+ */
419
+ public AABB getBounds() {
420
+ return AABB.getBoundingBox(vertices.getItems());
421
+ }
422
+
423
+ /**
424
+ *
425
+ * @return
426
+ */
427
+ public Vec3D getCentroid() {
428
+ return new Vec3D(getBounds());
429
+ }
430
+
431
+ /**
432
+ *
433
+ * @param p
434
+ * @return
435
+ */
436
+ public Vec3D getClosestVertexToPoint(ReadonlyVec3D p) {
437
+ Vec3D closest = null;
438
+ float minDist = Float.MAX_VALUE;
439
+ for (Vec3D v : vertices.getItems()) {
440
+ float d = v.distanceToSquared(p);
441
+ if (d < minDist) {
442
+ closest = v;
443
+ minDist = d;
444
+ }
445
+ }
446
+ return closest;
447
+ }
448
+
449
+ /**
450
+ *
451
+ * @return
452
+ */
453
+ public HashMap<String, MeshAttributeCompiler> getDefaultCompilers() {
454
+ HashMap<String, MeshAttributeCompiler> compilers = new HashMap<>();
455
+ compilers.put(ATTR_VERTICES, new MeshVertexCompiler());
456
+ compilers.put(ATTR_FNORMALS, new MeshFaceNormalCompiler());
457
+ compilers.put(ATTR_VNORMALS, new MeshVertexNormalCompiler());
458
+ compilers.put(ATTR_UVCOORDS, new MeshUVCompiler());
459
+ compilers.put(ATTR_VCOLORS, new MeshVertexColorCompiler());
460
+ return compilers;
461
+ }
462
+
463
+ /**
464
+ * @return the edges
465
+ */
466
+ public List<Object> getEdges() {
467
+ return getAttributeIndex(ATTR_EDGES).getItems();
468
+ }
469
+
470
+ /**
471
+ *
472
+ * @param v
473
+ * @return
474
+ */
475
+ public List<AttributedEdge> getEdgesForVertex(Vec3D v) {
476
+ List<AttributedEdge> vedges = null;
477
+ int id = vertices.getID(v);
478
+ if (id != -1) {
479
+ vedges = getEdgesForVertexID(id);
480
+ }
481
+ return vedges;
482
+ }
483
+
484
+ /**
485
+ *
486
+ * @param id
487
+ * @return
488
+ */
489
+ public List<AttributedEdge> getEdgesForVertexID(int id) {
490
+ List<AttributedEdge> vedges = new ArrayList<>(2);
491
+ for (Object o : getEdges()) {
492
+ AttributedEdge e = (AttributedEdge) o;
493
+ if (e.a == id || e.b == id) {
494
+ vedges.add(e);
495
+ }
496
+ }
497
+ return vedges;
498
+ }
499
+
500
+ /**
501
+ *
502
+ * @param f
503
+ * @return
504
+ */
505
+ public Triangle3D getFaceAsTriangle(AttributedFace f) {
506
+ Vec3D[] verts = getFaceVertices(f, null);
507
+ return new Triangle3D(verts[0], verts[1], verts[2]);
508
+ }
509
+
510
+ /**
511
+ *
512
+ * @param f
513
+ * @param attribs
514
+ * @return
515
+ */
516
+ public HashMap<String, Object[]> getFaceAttribValues(AttributedFace f,
517
+ String... attribs) {
518
+ HashMap<String, Object[]> values = new HashMap<>(
519
+ attribs.length, 1);
520
+ for (String a : attribs) {
521
+ values.put(a, getFaceAttribValues(f, a));
522
+ }
523
+ return values;
524
+ }
525
+
526
+ /**
527
+ *
528
+ * @param f
529
+ * @param att
530
+ * @return
531
+ */
532
+ public Object[] getFaceAttribValues(AttributedFace f, String att) {
533
+ ItemIndex<Object> idx = attributes.get(att);
534
+ int[] fattribs = f.attribs.get(att);
535
+ if (idx == null || fattribs == null) {
536
+ return null;
537
+ }
538
+ return new Object[] {
539
+ idx.forID(fattribs[0]), idx.forID(fattribs[1]),
540
+ idx.forID(fattribs[2])
541
+ };
542
+ }
543
+
544
+ /**
545
+ * @return the fnormals
546
+ */
547
+ public List<Vec3D> getFaceNormals() {
548
+ return fnormals.getItems();
549
+ }
550
+
551
+ /**
552
+ * @return the faces
553
+ */
554
+ public List<AttributedFace> getFaces() {
555
+ return faces;
556
+ }
557
+
558
+ /**
559
+ *
560
+ * @param v
561
+ * @return
562
+ */
563
+ public List<AttributedFace> getFacesForVertex(Vec3D v) {
564
+ List<AttributedFace> vfaces = null;
565
+ int id = vertices.getID(v);
566
+ if (id != -1) {
567
+ vfaces = new ArrayList<>(2);
568
+ for (AttributedFace f : faces) {
569
+ if (f.a == id || f.b == id || f.c == id) {
570
+ vfaces.add(f);
571
+ }
572
+ }
573
+ }
574
+ return vfaces;
575
+ }
576
+
577
+ /**
578
+ *
579
+ * @param f
580
+ * @param verts
581
+ * @return
582
+ */
583
+ public final Vec3D[] getFaceVertices(AttributedFace f, Vec3D[] verts) {
584
+ if (verts != null) {
585
+ verts[0] = vertices.forID(f.a);
586
+ verts[1] = vertices.forID(f.b);
587
+ verts[2] = vertices.forID(f.c);
588
+ return verts;
589
+ } else {
590
+ return new Vec3D[] {
591
+ vertices.forID(f.a), vertices.forID(f.b),
592
+ vertices.forID(f.c)
593
+ };
594
+ }
595
+ }
596
+
597
+ /**
598
+ *
599
+ * @param id
600
+ * @param neighbors
601
+ * @return
602
+ */
603
+ public List<Vec3D> getNeighborsForVertexID(int id, List<Vec3D> neighbors) {
604
+ List<AttributedEdge> vedges = getEdgesForVertexID(id);
605
+ if (vedges.size() > 0) {
606
+ if (neighbors == null) {
607
+ neighbors = new ArrayList<>();
608
+ } else {
609
+ neighbors.clear();
610
+ }
611
+ for (AttributedEdge e : vedges) {
612
+ neighbors.add(vertices.forID((e.a == id) ? e.b : e.a));
613
+ }
614
+ } else if (neighbors != null) {
615
+ neighbors.clear();
616
+ }
617
+ return neighbors;
618
+ }
619
+
620
+ /**
621
+ *
622
+ * @return
623
+ */
624
+ public final int getNumFaces() {
625
+ return faces.size();
626
+ }
627
+
628
+ /**
629
+ *
630
+ * @return
631
+ */
632
+ public final int getNumVertices() {
633
+ return vertices.size();
634
+ }
635
+
636
+ /**
637
+ *
638
+ * @return
639
+ */
640
+ public float getVertexDelta() {
641
+ return vertices.getDelta();
642
+ }
643
+
644
+ /**
645
+ * @return the vertices
646
+ */
647
+ public List<Vec3D> getVertices() {
648
+ return vertices.getItems();
649
+ }
650
+
651
+ /**
652
+ *
653
+ * @param verts
654
+ * @param ids
655
+ * @return
656
+ */
657
+ public List<Vec3D> getVerticesForIDs(List<Vec3D> verts, int... ids) {
658
+ if (verts == null) {
659
+ verts = new ArrayList<>(ids.length);
660
+ }
661
+ for (int id : ids) {
662
+ verts.add(vertices.forID(id));
663
+ }
664
+ return verts;
665
+ }
666
+
667
+ /**
668
+ *
669
+ * @param f
670
+ * @param a
671
+ * @param b
672
+ * @return
673
+ */
674
+ protected final int indexFaceEdge(AttributedFace f, int a, int b) {
675
+ final AttributedEdge e1 = new AttributedEdge(a, b);
676
+ final AttributedEdge e2 = new AttributedEdge(b, a);
677
+ ItemIndex<Object> edges = getAttributeIndex(ATTR_EDGES);
678
+ final int id1 = edges.getID(e1);
679
+ final int id2 = edges.getID(e2);
680
+ if (id1 != -1) {
681
+ ((AttributedEdge) edges.forID(id1)).addFace(f);
682
+ return id1;
683
+ } else if (id2 != -1) {
684
+ ((AttributedEdge) edges.forID(id2)).addFace(f);
685
+ return id2;
686
+ } else {
687
+ e1.addFace(f);
688
+ return edges.index(e1);
689
+ }
690
+ }
691
+
692
+ /**
693
+ *
694
+ * @param ray
695
+ * @return
696
+ */
697
+ public IsectData3D intersectsRay(Ray3D ray) {
698
+ TriangleIntersector intersector = new TriangleIntersector();
699
+ Triangle3D tri = intersector.getTriangle();
700
+ Vec3D[] v = null;
701
+ for (AttributedFace f : faces) {
702
+ v = getFaceVertices(f, v);
703
+ tri.set(v[0], v[1], v[2]);
704
+ if (intersector.intersectsRay(ray)) {
705
+ return intersector.getIntersectionData();
706
+ }
707
+ }
708
+ return null;
709
+ }
710
+
711
+ /**
712
+ *
713
+ */
714
+ public void rebuildVertexIndex() {
715
+ SpatialIndex newVerts = new SpatialIndex(vertices.getDelta());
716
+ Vec3D[] v = null;
717
+ for (AttributedFace f : faces) {
718
+ v = getFaceVertices(f, v);
719
+ f.a = newVerts.index(v[0]);
720
+ f.b = newVerts.index(v[1]);
721
+ f.c = newVerts.index(v[2]);
722
+ }
723
+ vertices = newVerts;
724
+ }
725
+
726
+ /**
727
+ *
728
+ * @param f
729
+ * @return
730
+ */
731
+ public IndexedTriangleMesh removeFace(AttributedFace f) {
732
+ faces.remove(f);
733
+ return this;
734
+ }
735
+
736
+ /**
737
+ *
738
+ * @param delta
739
+ * @return
740
+ */
741
+ public IndexedTriangleMesh setVertexDelta(float delta) {
742
+ vertices.setDelta(delta);
743
+ return this;
744
+ }
745
+
746
+ /**
747
+ *
748
+ * @return
749
+ */
750
+ public IndexedTriangleMesh smooth() {
751
+ HashMap<Integer, Vec3D> lapIndex = new HashMap<>();
752
+ List<Vec3D> neighbors = null;
753
+ for (int i = 0, numV = getNumVertices(); i < numV; i++) {
754
+ neighbors = getNeighborsForVertexID(i, neighbors);
755
+ if (neighbors != null && neighbors.size() > 0) {
756
+ Vec3D l = new Vec3D();
757
+ for (Vec3D n : neighbors) {
758
+ l.addSelf(n);
759
+ }
760
+ l.scaleSelf(1f / neighbors.size());
761
+ lapIndex.put(i, l);
762
+ }
763
+ }
764
+ SpatialIndex newVerts = new SpatialIndex(vertices.getDelta());
765
+ for (Iterator<AttributedFace> i = faces.iterator(); i.hasNext();) {
766
+ AttributedFace f = i.next();
767
+ f.a = newVerts.index(lapIndex.get(f.a));
768
+ f.b = newVerts.index(lapIndex.get(f.b));
769
+ f.c = newVerts.index(lapIndex.get(f.c));
770
+ if (f.a == f.b || f.a == f.c || f.b == f.c) {
771
+ i.remove();
772
+ }
773
+ }
774
+ vertices = newVerts;
775
+ computeEdges();
776
+ return this;
777
+ }
778
+
779
+ /**
780
+ *
781
+ * @param strategy
782
+ * @return
783
+ */
784
+ public IndexedTriangleMesh subdivide(NewSubdivStrategy strategy) {
785
+ Vec3D[] v = null;
786
+ List<Vec3D[]> splitFaces = new ArrayList<>();
787
+ for (AttributedFace f : new ArrayList<>(faces)) {
788
+ removeFace(f);
789
+ v = getFaceVertices(f, v);
790
+ for (Vec3D[] fverts : strategy.subdivideTriangle(v[0], v[1], v[2],
791
+ splitFaces)) {
792
+ addFace(fverts[0], fverts[1], fverts[2], null);
793
+ }
794
+ splitFaces.clear();
795
+ }
796
+ rebuildVertexIndex();
797
+ return this;
798
+ }
799
+
800
+ /**
801
+ *
802
+ * @return
803
+ */
804
+ @Override
805
+ public String toString() {
806
+ return String.format("vertices: %d, faces: %d", getNumVertices(),
807
+ getNumFaces());
808
+ }
809
+ }