Dynamic parameteric plot 3D
A low-level example of working with indexed geometry
Here we will make an adapter for ParametericPlot3D
to work dynamically morph one shape into another one. Since it naturally does not support dynamic updates, we need to manually wire dynamic symbols to each primitive supplying vertices, normals and indexes.
Our shapes
sample[t_] := With[{ complex = ParametricPlot3D[ (1 - t) * { (2 + Cos[v]) * Cos[u], (2 + Cos[v]) * Sin[u], Sin[v] } + t * { 1.16^v * Cos[v] * (1 + Cos[u]), -1.16^v * Sin[v] * (1 + Cos[u]), -2 * 1.16^v * (1 + Sin[u]) + 1.0 }, {u, -\[Pi], \[Pi]}, {v, -\[Pi], \[Pi]}, MaxRecursion -> 2, Mesh -> None ][[1, 1]] }, { complex[[1]], Cases[complex[[2]], _Polygon, 6] // First // First, complex[[3, 2]] } ]
Then we can use the output of this function to feed data into our GraphicsComplex
LeakyModule[{ vertices, normals, indices }, { EventHandler[InputRange[0,1,0.1,0], Function[value, With[{res = sample[value]}, normals = res[[3]]; indices = res[[2]]; vertices = res[[1]]; ]; ]], {vertices, indices, normals} = sample[0]; Graphics3D[{ MeshMaterial[MeshToonMaterial[]], Gray, SpotLight[Red, 5 {1,1,1}], SpotLight[Blue, 5 {-1,-1,1}], SpotLight[Green, 5 {1,-1,1}], PointLight[Magenta, {10,10,10}], GraphicsComplex[vertices // Offload, { Polygon[indices // Offload] }, VertexNormals->Offload[normals, "Static"->True]] }, Lighting->None] } // Column // Panel ]
(*BB[*)(Panel[(*GB[*){{(*VB[*)(EventObject[<|"Id" -> "6cefd35b-96e1-4165-b469-9a58a39163e1", "Initial" -> 0, "View" -> "1059ab52-7641-4ab0-8fc4-ce353d630947"|>])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKGxqYWiYmmRrpmpuZGOqaJCYZ6FqkJZvoJqcamxqnmBkbWJqYAwB5LxUO"*)(*]VB*)}(*||*),(*||*){(*VB[*)(Graphics3D[{MeshMaterial[MeshToonMaterial[]], GrayLevel[0.5], SpotLight[RGBColor[1, 0, 0], {5, 5, 5}], SpotLight[RGBColor[0, 0, 1], {-5, -5, 5}], SpotLight[RGBColor[0, 1, 0], {5, -5, 5}], PointLight[RGBColor[1, 0, 1], {10, 10, 10}], GraphicsComplex[Offload[vertices$110624], {Polygon[Offload[indices$110624]]}, VertexNormals -> Offload[normals$110624, "Static" -> True]]}, Lighting -> None])(*,*)(*"1:eJyVkdtOwkAQhhc8gMbTK5j4AKLGWxMxwYuCphDvVzrbbrLsNLsLgbf1Pbwoe7AtqYQAF3/oP9Nv/s7cfmPMWoQQfWzlHUXC2u7p3MpA0TzjU/34xjplR8S1Cf0XVoagsyE1oDgVjDj35s+dIMqq4vvPAnEVwQKEIv738xKmudo4RxPxNDPsyFldK/HgtY8CFXcATkoJDWUafuL8SvYDViyPbgB/i6IIciCwtSthA+gW/Ilc7vHNWyK6t2sJxeuNk/VxlgtYhs27430wJpAmvmkByvAp6Lte7/754ak+f33cjk8nVinK/4wrN1cmm4h2iYjnAvSl/fNlh8ByhGpGhQ71JkOG4lbG+NQt3FAb1HsTNYfGlK5PbJfHZerdEUpYAycxnYg="*)(*]VB*)}}(*]GB*)])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KWlMIB4/kAgoyi/LTElN8S8oyczPK05jAElwgCQS81JznPIrIEpBGoNKc1KDwSakJqYEs8LUAADiShU/"*)(*]BB*)