public virtual void Update() { base.begin_update(); if (MeshSource == null) { throw new Exception("MeshVertexDisplacementOp: must set valid MeshSource to compute!"); } if (DisplacementSource == null) { throw new Exception("MeshVertexDisplacementOp: must set valid DisplacementSource to compute!"); } DMesh3 meshIn = MeshSource.GetDMeshUnsafe(); IVectorDisplacement displace = DisplacementSource.GetDisplacement(); if (displace.Count != 0 && displace.Count != meshIn.MaxVertexID) { throw new Exception("MeshVertexDisplacementOp: inconsistent counts " + displace.Count.ToString() + " != " + meshIn.MaxVertexID.ToString()); } DMesh3 mesh = new DMesh3(meshIn, MeshHints.None); //if (!mesh.HasVertexNormals) // MeshNormals.QuickCompute(mesh); if (displace.Count > 0) { gParallel.ForEach(mesh.VertexIndices(), (vid) => { Vector3d dv = displace.GetDisplacementForIndex(vid); //Vector3f n = mesh.GetVertexNormal(vid); Vector3d v = mesh.GetVertex(vid); v += dv; mesh.SetVertex(vid, v); }); if (enable_heat_map) { // compute max displace len ColorMap map = new ColorMap(); map.AddPoint(0, Colorf.CornflowerBlue); float d = (float)HeatMapMaxDistance; map.AddPoint(d, Colorf.Orange); map.AddPoint(2 * d, Colorf.VideoYellow); map.AddPoint(4 * d, Colorf.VideoRed); map.AddPoint(-d, Colorf.VideoMagenta); float max_displace = d; gParallel.ForEach(mesh.VertexIndices(), (vid) => { Vector3f dv = (Vector3f)displace.GetDisplacementForIndex(vid); Vector3f n = mesh.GetVertexNormal(vid); float sign = n.Dot(dv) > 0 ? 1 : -1; Colorf c = map.Linear(dv.Length * sign); Colorf existing_c = mesh.GetVertexColor(vid); float preserve__max = max_displace / 2; float t = MathUtil.Clamp(dv.Length / preserve__max, 0.0f, 1.0f); c = (1.0f - t) * existing_c + (t) * c; mesh.SetVertexColor(vid, c); //float t = MathUtil.Clamp(dv.Length / max_displace, -1.0f, 1.0f); //mesh.SetVertexColor(vid, t * Colorf.Orange); }); } } MeshNormals.QuickCompute(mesh); DisplacedMesh = mesh; base.complete_update(); }