/// <summary> /// Calculate extents of mesh along an axis, with optional transform /// </summary> public static Interval1d ExtentsOnAxis(IMesh mesh, Vector3d axis, Func <Vector3d, Vector3d> TransformF = null) { Interval1d extent = Interval1d.Empty; if (TransformF == null) { foreach (int vid in mesh.VertexIndices()) { extent.Contain(mesh.GetVertex(vid).Dot(ref axis)); } } else { foreach (int vid in mesh.VertexIndices()) { Vector3d vT = TransformF(mesh.GetVertex(vid)); extent.Contain(vT.Dot(ref axis)); } } return(extent); }
/// <summary> /// Calculate extents of mesh along an axis, with optional transform /// </summary> public static Interval1d ExtentsOnAxis(DMesh3 mesh, Vector3d axis, Func <Vector3d, Vector3d> TransformF = null) { Interval1d extent = Interval1d.Empty; if (TransformF == null) { foreach (Vector3d v in mesh.Vertices()) { extent.Contain(v.Dot(ref axis)); } } else { foreach (Vector3d v in mesh.Vertices()) { Vector3d vT = TransformF(v); extent.Contain(vT.Dot(ref axis)); } } return(extent); }
public void AddPoint(float t, Colorf c) { var cp = new ColorPoint() { t = t, c = c }; if (points.Count == 0) { points.Add(cp); validRange.Contain(t); } else if (t < points[0].t) { points.Insert(0, cp); validRange.Contain(t); } else { for (int k = 0; k < points.Count; ++k) { if (points[k].t == t) { points[k] = cp; return; } else if (points[k].t > t) { points.Insert(k, cp); return; } } points.Add(cp); validRange.Contain(t); } }
public void AddPoint(double t, double value) { var cp = new Sample() { t = t, value = value }; if (points.Count == 0) { points.Add(cp); validRange.Contain(t); } else if (t < points[0].t) { points.Insert(0, cp); validRange.Contain(t); } else { for (int k = 0; k < points.Count; ++k) { if (points[k].t == t) { points[k] = cp; return; } else if (points[k].t > t) { points.Insert(k, cp); return; } } points.Add(cp); validRange.Contain(t); } }
int split_tri_set_midpoint(int[] triangles, Vector3d[] centers, int iStart, int iCount, int depth, int minTriCount, boxes_set tris, boxes_set nodes, out AxisAlignedBox3f box) { box = AxisAlignedBox3f.Empty; int iBox = -1; if (iCount < minTriCount) { // append new triangles box iBox = tris.iBoxCur++; tris.box_to_index.insert(tris.iIndicesCur, iBox); tris.index_list.insert(iCount, tris.iIndicesCur++); for (int i = 0; i < iCount; ++i) { tris.index_list.insert(triangles[iStart + i], tris.iIndicesCur++); box.Contain(mesh.GetTriBounds(triangles[iStart + i])); } tris.box_centers.insert(box.Center, iBox); tris.box_extents.insert(box.Extents, iBox); return(-(iBox + 1)); } //compute interval along an axis and find midpoint int axis = depth % 3; Interval1d interval = Interval1d.Empty; for (int i = 0; i < iCount; ++i) { interval.Contain(centers[iStart + i][axis]); } double midpoint = interval.Center; int n0, n1; if (Math.Abs(interval.a - interval.b) > MathUtil.ZeroTolerance) { // we have to re-sort the centers & triangles lists so that centers < midpoint // are first, so that we can recurse on the two subsets. We walk in from each side, // until we find two out-of-order locations, then we swap them. int l = 0; int r = iCount - 1; while (l < r) { // [RMS] is <= right here? if v.axis == midpoint, then this loop // can get stuck unless one of these has an equality test. But // I did not think enough about if this is the right thing to do... while (centers[iStart + l][axis] <= midpoint) { l++; } while (centers[iStart + r][axis] > midpoint) { r--; } if (l >= r) { break; //done! } //swap Vector3d tmpc = centers[iStart + l]; centers[iStart + l] = centers[iStart + r]; centers[iStart + r] = tmpc; int tmpt = triangles[iStart + l]; triangles[iStart + l] = triangles[iStart + r]; triangles[iStart + r] = tmpt; } n0 = l; n1 = iCount - n0; Debug.Assert(n0 >= 1 && n1 >= 1); } else { // interval is near-empty, so no point trying to do sorting, just split half and half n0 = iCount / 2; n1 = iCount - n0; } // create child boxes AxisAlignedBox3f box1; int child0 = split_tri_set_midpoint(triangles, centers, iStart, n0, depth + 1, minTriCount, tris, nodes, out box); int child1 = split_tri_set_midpoint(triangles, centers, iStart + n0, n1, depth + 1, minTriCount, tris, nodes, out box1); box.Contain(box1); // append new box iBox = nodes.iBoxCur++; nodes.box_to_index.insert(nodes.iIndicesCur, iBox); nodes.index_list.insert(child0, nodes.iIndicesCur++); nodes.index_list.insert(child1, nodes.iIndicesCur++); nodes.box_centers.insert(box.Center, iBox); nodes.box_extents.insert(box.Extents, iBox); return(iBox); }
public override DeformInfo Apply(Frame3f vNextPos) { Interval1d edgeRangeSqr = Interval1d.Empty; int N = Curve.VertexCount; if (N > NewV.size) { NewV.resize(N); } if (N > ModifiedV.Length) { ModifiedV = new BitArray(2 * N); } // clear modified ModifiedV.SetAll(false); bool bSmooth = (SmoothAlpha > 0 && SmoothIterations > 0); double r2 = Radius * Radius; // deform pass if (DeformF != null) { for (int i = 0; i < N; ++i) { Vector3d v = Curve[i]; double d2 = (v - vPreviousPos.Origin).LengthSquared; if (d2 < r2) { double t = WeightFunc(Math.Sqrt(d2), Radius); Vector3d vNew = DeformF(i, t); if (bSmooth == false) { if (i > 0) { edgeRangeSqr.Contain(vNew.DistanceSquared(Curve[i - 1])); } if (i < N - 1) { edgeRangeSqr.Contain(vNew.DistanceSquared(Curve[i + 1])); } } NewV[i] = vNew; ModifiedV[i] = true; } } } else { // anything? } // smooth pass if (bSmooth) { for (int j = 0; j < SmoothIterations; ++j) { int iStart = (Curve.Closed) ? 0 : 1; int iEnd = (Curve.Closed) ? N : N - 1; for (int i = iStart; i < iEnd; ++i) { Vector3d v = (ModifiedV[i]) ? NewV[i] : Curve[i]; double d2 = (v - vPreviousPos.Origin).LengthSquared; if (ModifiedV[i] || d2 < r2) // always smooth any modified verts { double a = SmoothAlpha * WeightFunc(Math.Sqrt(d2), Radius); int iPrev = (i == 0) ? N - 1 : i - 1; int iNext = (i + 1) % N; Vector3d vPrev = (ModifiedV[iPrev]) ? NewV[iPrev] : Curve[iPrev]; Vector3d vNext = (ModifiedV[iNext]) ? NewV[iNext] : Curve[iNext]; Vector3d c = (vPrev + vNext) * 0.5f; NewV[i] = (1 - a) * v + (a) * c; ModifiedV[i] = true; if (i > 0) { edgeRangeSqr.Contain(NewV[i].DistanceSquared(Curve[i - 1])); } if (i < N - 1) { edgeRangeSqr.Contain(NewV[i].DistanceSquared(Curve[i + 1])); } } } } } // bake for (int i = 0; i < N; ++i) { if (ModifiedV[i]) { Curve[i] = NewV[i]; } } return(new DeformInfo() { minEdgeLenSqr = edgeRangeSqr.a, maxEdgeLenSqr = edgeRangeSqr.b }); }