/// <summary> /// Add point to the grid. /// </summary> /// <param name="pt">Point in world space</param> /// <param name="vg">Voxelgrid</param> public void AddPt(Point3d pt, ref VoxelGrid3D vg) { if (Distance < RhinoMath.ZeroTolerance) { var pti = vg.ClosestPoint(pt); if (pti >= Point3i.Origin && pti <= vg.SizeUVW) { vg.SetValue(pti, true); } } else { var bb = new BoundingBox(new [] { pt }); bb.Inflate(Distance * 1.1); foreach (var subPt in vg.PointsInBox(bb)) { if (vg.PointInGrid(subPt) && !vg[subPt] && vg.EvaluatePoint(subPt).DistanceTo(pt) < Distance) { vg[subPt] = true; } } } }
// iterate through the grid in the x directions /// <summary> /// Iterate through the grid and add voxels that are inside the Brep /// </summary> /// <param name="brepVolume"></param> /// <param name="vg"></param> public void AddSolidBrep(Brep brepVolume, ref VoxelGrid3D vg) { // get the axis direction for each point var pt1 = vg.EvaluatePoint(new Point3i(0, 0, 0)); var pt2 = vg.EvaluatePoint(new Point3i(1, 0, 0)); var pln = new Plane(pt1, (pt2 - pt1)); for (var x = 0; x < vg.SizeUVW.X; x++) { pln.Origin = vg.EvaluatePoint(new Point3i(x, 0, 0)); Intersection.BrepPlane(brepVolume, pln, DocumentHelper.GetModelTolerance(), out var sections, out var pts); var surfaces = Brep.CreatePlanarBreps(sections); // perhaps check first if the points are inside the bounding box of the surface. if (surfaces == null) { continue; } for (var y = 0; y < vg.SizeUVW.Y; y++) { for (var z = 0; z < vg.SizeUVW.Z; z++) { var pt = vg.EvaluatePoint(new Point3i(x, y, z)); var hasPixel = surfaces.Any(t => t.ClosestPoint(pt).DistanceTo(pt) < DocumentHelper.GetModelTolerance()); if (hasPixel) { vg.SetValue(new Point3i(x, y, z), true); } } } } }
/// <summary> /// Adds the mesh. /// </summary> /// <param name="m">The m.</param> /// <param name="vg">The vg.</param> private void AddMesh(Mesh m, ref VoxelGrid3D vg) { if (Distance < RhinoMath.ZeroTolerance) { // add closed mesh var bb = m.GetBoundingBox(true); var length = bb.Diagonal.Length * 1.1; for (var i = 0; i < vg.Count; i++) { var pt = vg.EvaluatePoint(i); var isInside = false; if (bb.Contains(pt)) { Intersection.MeshLine(m, new Line(pt, Vector3d.XAxis, length), out var faces); if (faces != null) { isInside = faces.Length % 2 == 1; } } if (isInside) { vg.SetValue(i, true); } } } else { // add open mesh var bb = m.GetBoundingBox(true); bb.Inflate(Distance * 0.6); for (var i = 0; i < vg.Count; i++) { var isInside = false; var pt = vg.EvaluatePoint(i); if (bb.Contains(pt)) { var foundPoint = m.ClosestPoint(pt); if (foundPoint.DistanceTo(pt) <= Distance) { isInside = true; } } if (isInside) { vg[i] = true; } } } }