// smooths embedded loop in mesh, by first smoothing edge loop and then // smoothing vertex neighbourhood // [TODO] geodesic nbrhoold instead of # of rings // [TODO] reprojection? public static void smooth_loop(NGonsCore.geometry3Sharp.mesh.DMesh3 mesh, EdgeLoop loop, int nRings) { MeshFaceSelection roi_t = new MeshFaceSelection(mesh); roi_t.SelectVertexOneRings(loop.Vertices); for (int i = 0; i < nRings; ++i) { roi_t.ExpandToOneRingNeighbours(); } roi_t.LocalOptimize(true, true); MeshVertexSelection roi_v = new MeshVertexSelection(mesh); roi_v.SelectTriangleVertices(roi_t.ToArray()); roi_v.Deselect(loop.Vertices); MeshLoopSmooth loop_smooth = new MeshLoopSmooth(mesh, loop); loop_smooth.Rounds = 1; MeshIterativeSmooth mesh_smooth = new MeshIterativeSmooth(mesh, roi_v.ToArray(), true); mesh_smooth.Rounds = 1; for (int i = 0; i < 10; ++i) { loop_smooth.Smooth(); mesh_smooth.Smooth(); } }
public virtual bool Extrude(int group_id = -1) { // duplicate loop vertices int NV = Loop.Vertices.Length; NewLoop = new EdgeLoop(Mesh); NewLoop.Vertices = new int[NV]; for (int i = 0; i < NV; ++i) { int vid = Loop.Vertices[i]; NewLoop.Vertices[i] = Mesh.AppendVertex(Mesh, vid); } // move to offset positions for (int i = 0; i < NV; ++i) { Vector3D v = Mesh.GetVertex(Loop.Vertices[i]); Vector3F n = Mesh.GetVertexNormal(Loop.Vertices[i]); Vector3D new_v = PositionF(v, n, i); Mesh.SetVertex(NewLoop.Vertices[i], new_v); } // stitch interior MeshEditor edit = new MeshEditor(Mesh); NewTriangles = edit.StitchLoop(Loop.Vertices, NewLoop.Vertices, group_id); return(true); }
public AddTrianglesMeshChange fill_smooth(DMesh3 mesh, EdgeLoop loop) { AddTrianglesMeshChange addChange = null; SmoothedHoleFill filler = new SmoothedHoleFill(mesh, loop); filler.ConstrainToHoleInterior = true; if (this.AutoTargetEdgeLength) { double mine, maxe, avge; MeshQueries.EdgeLengthStatsFromEdges(mesh, loop.Edges, out mine, out maxe, out avge); filler.TargetEdgeLength = avge; } else { filler.TargetEdgeLength = this.TargetEdgeLength; } filler.SmoothSolveIterations = this.SmoothOptimizeRounds; bool fill_ok = filler.Apply(); if (fill_ok) { addChange = new AddTrianglesMeshChange(); addChange.InitializeFromExisting(mesh, filler.FillVertices, filler.FillTriangles); } return(addChange); }
public static void FindActualEdge(HalfEdge he, out HalfEdge he1, out double length) { EdgeLoop el = he.face.GetEdgeLoopFor(he); int ndx = el.IndexOf(he); while (true) { HalfEdge h = el[el.FixIndex(ndx - 1)]; if (ut.PointsAreCollinear3d(h.from, h.to, he.to)) { ndx--; } else { break; } } he1 = el[ndx]; double len = he1.Length(); while (true) { HalfEdge h = el[++ndx]; if (ut.PointsAreCollinear3d(he1.from, he1.to, h.to)) { len += h.Length(); } else { break; } } length = len; }
public LandBuilder(EdgeLoop <CityEdge> footprint, City city) { this.footprint = footprint; this.city = city; pointsPerUnit = 0.3f; treeModels = new GameObject[] { Resources.Load <GameObject>("Trees/Pine1"), Resources.Load <GameObject>("Trees/Pine2") }; }
protected override void SolveInstance(IGH_DataAccess DA) { this.Message = type.ToString(); DMesh3_goo goo = null; double eLen = 1; DA.GetData(0, ref goo); DA.GetData(1, ref eLen); DMesh3 msh = new DMesh3(goo.Value); DMesh3 outMesh = msh; MeshBoundaryLoops loops = new MeshBoundaryLoops(outMesh, true); var lps = loops.Loops; bool hasLoops = (lps.Count > 0); int iter = 0; while (hasLoops) { EdgeLoop loop = lps[0]; switch (type) { case HoleFillerType.Planar: outMesh = HoleFillMethods.PlanarFill(outMesh, loop, eLen); break; case HoleFillerType.Smooth: outMesh = HoleFillMethods.SmoothFill(outMesh, loop, eLen); break; case HoleFillerType.Minimal: outMesh = HoleFillMethods.MinimalFill(outMesh, loop, eLen); break; default: outMesh = HoleFillMethods.PlanarFill(outMesh, loop, eLen); break; } loops = new MeshBoundaryLoops(outMesh, true); lps = loops.Loops; hasLoops = (lps.Count > 0); iter++; if (iter > 500) { break; } } this.Message += "\n" + iter.ToString() + " holes filled."; DA.SetData(0, outMesh); }
public SimpleHoleFiller(NGonsCore.geometry3Sharp.mesh.DMesh3 mesh, EdgeLoop loop) { Mesh = mesh; Loop = loop; NewVertex = NGonsCore.geometry3Sharp.mesh.DMesh3.InvalidID; NewTriangles = null; }
public MeshExtrusion(NGonsCore.geometry3Sharp.mesh.DMesh3 mesh, EdgeLoop loop) { Mesh = mesh; Loop = loop; PositionF = (pos, normal, idx) => { return(pos + Vector3D.AxisY); }; }
public static DMesh3 SmoothFill(DMesh3 mesh, EdgeLoop loop, double eLen) { gs.SmoothedHoleFill smoothFill = new gs.SmoothedHoleFill(mesh, loop); smoothFill.TargetEdgeLength = eLen; bool success = smoothFill.Apply(); return(smoothFill.Mesh); }
public MeshLoopSmooth(NGonsCore.geometry3Sharp.mesh.DMesh3 mesh, EdgeLoop loop) { Mesh = mesh; Loop = loop; SmoothedPostions = new Vector3D[Loop.Vertices.Length]; ProjectF = null; }
Polygon2d make_poly(DMesh3 mesh, EdgeLoop loop) { Polygon2d poly = new Polygon2d(); for (int k = 0; k < loop.VertexCount; ++k) { Vector3d v = mesh.GetVertex(loop.Vertices[k]); poly.AppendVertex(v.xy); } return(poly); }
public void Merge(bool first, EdgeLoop loop) { if (first) { edges.InsertRange(0, loop.edges); } else { edges.AddRange(loop.edges); } length += loop.length; }
void GenerateMesh() { int bridgeCount = 0; int baseID = 0; backLoop = ModelUtils.CreateEdgeLoop(ref baseID, closeLoop, EdgeLoopVertCount); frontLoop = ModelUtils.CreateEdgeLoop(ref baseID, closeLoop, EdgeLoopVertCount); faceBevelLoops = new EdgeLoop[bevelSliceCount]; for (int i = 0; i < bevelSliceCount; i++) { faceBevelLoops[i] = ModelUtils.CreateEdgeLoop(ref baseID, closeLoop, EdgeLoopVertCount); bridgeCount++; } vertices = new Vector3[backLoop.VertCount + frontLoop.VertCount + (EdgeLoopVertCount * bevelSliceCount)]; SetVertices(); int triangleBaseID = 0; backFrontBridge = ModelUtils.CreateExtrustion(ref triangleBaseID, frontLoop, backLoop); bridgeCount++; triangles = new int[backFrontBridge.GetTriangleIndexCount() * bridgeCount]; backFrontBridge.TriangulateBridge(ref triangles, false); // do face bevel bridges faceBevelBridges = new EdgeBridge[bridgeCount]; EdgeLoop firstLoop = frontLoop; for (int i = 0; i < bevelSliceCount; i++) { EdgeLoop secondLoop = faceBevelLoops[i]; faceBevelBridges[i] = ModelUtils.CreateExtrustion(ref triangleBaseID, firstLoop, secondLoop); faceBevelBridges[i].TriangulateBridge(ref triangles, false); firstLoop = secondLoop; } // check to see if we're using our last bevel loop/bridge properly // do a loop fill on the last loop to fill our face in. }
EdgeLoop select_loop_tris_hint(MeshBoundaryLoops loops) { var hint_edges = new HashSet <int>(); foreach (int tid in BorderHintTris) { if (Mesh.IsTriangle(tid) == false) { continue; } Index3i et = Mesh.GetTriEdges(tid); for (int j = 0; j < 3; ++j) { if (Mesh.IsBoundaryEdge(et[j])) { hint_edges.Add(et[j]); } } } int N = loops.Count; int best_loop = -1; int max_votes = 0; for (int li = 0; li < N; ++li) { int votes = 0; EdgeLoop l = loops[li]; foreach (int eid in l.Edges) { if (hint_edges.Contains(eid)) { votes++; } } if (votes > max_votes) { best_loop = li; max_votes = votes; } } if (best_loop == -1) { return(null); } return(loops[best_loop]); }
public MeshStitchLoops(DMesh3 mesh, EdgeLoop l0, EdgeLoop l1) { Mesh = mesh; Loop0 = new EdgeLoop(l0); Loop1 = new EdgeLoop(l1); span s = new span() { span0 = new Interval1i(0, 0), span1 = new Interval1i(0, 0) }; spans.Add(s); }
public static DMesh3 PlanarFill(DMesh3 mesh, EdgeLoop loop, double eLen) { PlanarHoleFiller holeFiller = new PlanarHoleFiller(mesh); holeFiller.AddFillLoop(loop); Plane.FitPlaneToPoints(loop.Vertices.Select(ind => mesh.GetVertex(ind).ToRhinoPt()), out Plane pl); holeFiller.SetPlane(pl.Origin.ToVec3d(), pl.ZAxis.ToVec3d()); holeFiller.FillTargetEdgeLen = eLen; holeFiller.Fill(); return(holeFiller.Mesh); }
DMesh3 compute_partial_hole(Vector3d start, Vector3d end, double tol) { DMesh3 origMesh = MeshSource.GetDMeshUnsafe(); DMeshAABBTree3 origSpatial = MeshSource.GetSpatial() as DMeshAABBTree3; DMesh3 cutMesh = new DMesh3(origMesh); Polygon2d polygon = Polygon2d.MakeCircle(hole_size / 2, hole_subdivisions); Vector3f axis = (Vector3f)(start - end).Normalized; int start_tid = origSpatial.FindNearestTriangle(start); Frame3f start_frame = origMesh.GetTriFrame(start_tid); start_frame.Origin = (Vector3f)start; start_frame.AlignAxis(2, axis); int end_tid = origSpatial.FindNearestTriangle(end); //Frame3f end_frame = origMesh.GetTriFrame(end_tid); end_frame.Origin = (Vector3f)end; Frame3f end_frame = start_frame; end_frame.Origin = (Vector3f)end; // [TODO] we don't need to Simplify here...is more robust? MeshInsertProjectedPolygon start_insert = new MeshInsertProjectedPolygon(cutMesh, polygon, start_frame, start_tid); bool start_ok = start_insert.Insert(); if (start_ok == false) { throw new Exception("CutPolygonHoleOp.compute_partial_hole: start or end insertion failed!"); } EdgeLoop outLoop = start_insert.InsertedLoop; MeshExtrudeLoop extrude = new MeshExtrudeLoop(cutMesh, outLoop); extrude.PositionF = (v, n, vid) => { cutMesh.GetVertex(vid); return(end_frame.ProjectToPlane((Vector3f)v, 2)); }; extrude.Extrude(); SimpleHoleFiller filler = new SimpleHoleFiller(cutMesh, extrude.NewLoop); filler.Fill(); return(cutMesh); }
public AddTrianglesMeshChange fill_trivial(DMesh3 mesh, EdgeLoop loop) { AddTrianglesMeshChange addChange = null; SimpleHoleFiller filler = new SimpleHoleFiller(mesh, loop); bool fill_ok = filler.Fill(); if (fill_ok) { addChange = new AddTrianglesMeshChange(); addChange.InitializeFromExisting(mesh, new List <int>() { filler.NewVertex }, filler.NewTriangles); } return(addChange); }
public bool Compute() { DMesh3 copy = new DMesh3(Mesh); //Frame3f PlaneO = SceneTransforms.SceneToObject(TargetSO, PlaneS); Vector3f PlaneNormal = Plane.GetAxis(nPlaneAxis); MeshPlaneCut cut = new MeshPlaneCut(copy, Plane.Origin, PlaneNormal); cut.Cut(); Loops = new DCurve3[cut.CutLoops.Count]; for (int li = 0; li < cut.CutLoops.Count; ++li) { EdgeLoop edgeloop = cut.CutLoops[li]; DCurve3 loop = MeshUtil.ExtractLoopV(copy, edgeloop.Vertices); // [TODO] collapse degenerate points... if (NormalOffset > 0) { for (int i = 0; i < loop.VertexCount; ++i) { Vector3f n = Vector3f.Zero; if (copy.HasVertexNormals) { n = (Vector3f)copy.GetVertexNormal(edgeloop.Vertices[i]); } else { n = (Vector3f)MeshNormals.QuickCompute(Mesh, edgeloop.Vertices[i]); } n -= n.Dot(PlaneNormal) * PlaneNormal; n.Normalize(); loop[i] += NormalOffset * (Vector3d)n; } } Loops[li] = loop; } return(Loops.Length > 0); }
public AddTrianglesMeshChange fill_minimal(DMesh3 mesh, EdgeLoop loop) { AddTrianglesMeshChange addChange = null; MinimalHoleFill filler = new MinimalHoleFill(mesh, loop); filler.IgnoreBoundaryTriangles = false; filler.OptimizeDevelopability = true; filler.OptimizeTriangles = this.OptimizeTriangles; filler.DevelopabilityTolerance = this.OptimizeTrisDeviationThresh; bool fill_ok = filler.Apply(); if (fill_ok) { addChange = new AddTrianglesMeshChange(); addChange.InitializeFromExisting(mesh, filler.FillVertices, filler.FillTriangles); } return(addChange); }
DMesh3 compute_through_hole(Vector3d start, Vector3d end, double tol) { DMesh3 origMesh = MeshSource.GetDMeshUnsafe(); DMeshAABBTree3 origSpatial = MeshSource.GetSpatial() as DMeshAABBTree3; DMesh3 cutMesh = new DMesh3(origMesh); Polygon2d polygon = Polygon2d.MakeCircle(hole_size / 2, hole_subdivisions); Vector3f axis = (Vector3f)(start - end).Normalized; int start_tid = origSpatial.FindNearestTriangle(start); Frame3f start_frame = origMesh.GetTriFrame(start_tid); start_frame.Origin = (Vector3f)start; start_frame.AlignAxis(2, axis); int end_tid = origSpatial.FindNearestTriangle(end); //Frame3f end_frame = origMesh.GetTriFrame(end_tid); end_frame.Origin = (Vector3f)end; Frame3f end_frame = start_frame; end_frame.Origin = (Vector3f)end; MeshInsertProjectedPolygon start_insert = new MeshInsertProjectedPolygon(cutMesh, polygon, start_frame, start_tid); bool start_ok = start_insert.Insert(); MeshInsertProjectedPolygon end_insert = new MeshInsertProjectedPolygon(cutMesh, polygon, end_frame, end_tid); bool end_ok = end_insert.Insert(); if (start_ok == false || end_ok == false) { throw new Exception("CutPolygonHoleOp.compute_through_hole: start or end insertion failed!"); } MeshEditor editor = new MeshEditor(cutMesh); EdgeLoop l0 = start_insert.InsertedLoop; EdgeLoop l1 = end_insert.InsertedLoop; l1.Reverse(); editor.StitchLoop(l0.Vertices, l1.Vertices); return(cutMesh); }
public static CompoundSolid Tenon(CompoundSolid sol, HalfEdge he, xy pos, xyz size, string id) { Face f = he.face; EdgeLoop el = he.face.GetEdgeLoopFor(he); int ndx = el.IndexOf(he); ndx--; if (ndx < 0) { ndx += el.Count; } HalfEdge prevHe = el[ndx]; if (!fp.eq_inches(pos.y, 0)) { Solid cut = CreateCutter_Box(id, he, new xy(0, 0), new xyz(he.Length(), pos.y, size.z), new string[] { "NA_1", "NA_2", "NA_3", "frontshoulder", "NA_4", "front" }); sol = bool3d.Subtract(sol, cut); } if (!fp.eq_inches(pos.x, 0)) { Solid cut = CreateCutter_Box(id, he, new xy(0, pos.y), new xyz(pos.x, size.y, size.z), new string[] { "NA_1", "left", "NA_2", "leftshoulder", "NA_3", "NA_4" }); sol = bool3d.Subtract(sol, cut); } if ((pos.y + size.y) < prevHe.Length()) { Solid cut = CreateCutter_Box(id, he, new xy(0, pos.y + size.y), new xyz(he.Length(), prevHe.Length() - (pos.y + size.y), size.z), new string[] { "NA_1", "NA_2", "NA_3", "backshoulder", "back", "NA_4" }); sol = bool3d.Subtract(sol, cut); } if ((pos.x + size.x) < he.Length()) { Solid cut = CreateCutter_Box(id, he, new xy((pos.x + size.x), pos.y), new xyz(he.Length() - (pos.x + size.x), size.y, size.z), new string[] { "NA_1", "NA_2", "right", "rightshoulder", "NA_3", "NA_4" }); sol = bool3d.Subtract(sol, cut); } return(sol); }
protected override void SolveInstance(IGH_DataAccess DA) { this.Message = Type.ToString(); DMesh3_goo goo = null; EdgeLoop_goo loop_goo = null; double eLen = 1; DA.GetData(0, ref goo); DA.GetData(1, ref loop_goo); DA.GetData(2, ref eLen); DMesh3 msh = new DMesh3(goo.Value); EdgeLoop loop = new EdgeLoop(loop_goo.Value); DMesh3 outMesh; switch (Type) { case HoleFillerType.Planar: outMesh = HoleFillMethods.PlanarFill(msh, loop, eLen); break; case HoleFillerType.Smooth: outMesh = HoleFillMethods.SmoothFill(msh, loop, eLen); break; case HoleFillerType.Minimal: outMesh = HoleFillMethods.MinimalFill(msh, loop, eLen); break; default: outMesh = HoleFillMethods.PlanarFill(msh, loop, eLen); break; } DA.SetData(0, outMesh); }
virtual public void PreRender() { boundaryGeom.PreRender(); // could avoid full iteration here if we were smarter... if (visibility_valid == false) { numHolesFilled = 0; for (int i = 0; i < Loops.Count; ++i) { EdgeLoop l = Loops[i]; bool bIsBoundary = previewSO.Mesh.IsBoundaryEdge(l.Edges[0]); boundaryGeom.SetVisibility(i, bIsBoundary); if (bIsBoundary == false) { numHolesFilled++; } } visibility_valid = true; boundaryGeom.SetLayer(show_hidden ? FPlatform.WidgetOverlayLayer : FPlatform.GeometryLayer); } }
public Building(EdgeLoop <CityEdge> footprint, float floorHeight, int floors, City city) { this.footprint = footprint; Vector2[] footprintPoints = footprint.GetPoints(); basePoints = new Vector3[footprintPoints.Length]; float highestBasePoint = float.MinValue; for (int i = 0; i < basePoints.Length; i++) { Vector2 fpPt = footprintPoints[i]; basePoints[i] = new Vector3(fpPt.x, city.SampleElevation(fpPt.x, fpPt.y), fpPt.y); if (basePoints[i].y > highestBasePoint) { highestBasePoint = basePoints[i].y; } } this.foundationFirstFloorGap = 0.2f; this.elevation = highestBasePoint; this.floorHeight = floorHeight; this.floors = floors; this.city = city; }
protected virtual bool BackPropagate(RegionOperator regionOp, int[] insertedPolyVerts, EdgeLoop insertedLoop) { bool bOK = regionOp.BackPropropagate(); if (bOK) { ModifiedRegion = regionOp; IndexUtil.Apply(insertedPolyVerts, regionOp.ReinsertSubToBaseMapV); InsertedPolygonVerts = insertedPolyVerts; if (insertedLoop != null) { InsertedLoop = MeshIndexUtil.MapLoopViaVertexMap(regionOp.ReinsertSubToBaseMapV, regionOp.Region.SubMesh, regionOp.Region.BaseMesh, insertedLoop); if (RemovePolygonInterior) { InsertedLoop.CorrectOrientation(); } } } return(bOK); }
public bool FillHole(int hitHoleID, bool bInteractive) { if (is_computing) { return(false); } EdgeLoop loop = Loops[hitHoleID]; AddTrianglesMeshChange addChange = null; previewSO.EditAndUpdateMesh((mesh) => { switch (FillType) { case FillTypes.Trivial: addChange = fill_trivial(mesh, loop); break; case FillTypes.Minimal: addChange = fill_minimal(mesh, loop); break; case FillTypes.Smooth: addChange = fill_smooth(mesh, loop); break; } }, GeometryEditTypes.ArbitraryEdit); if (addChange != null) { add_change(addChange, bInteractive); // we know what changed visibility-wise, so we can avoid full visibility update boundaryGeom.SetVisibility(hitHoleID, false); numHolesFilled++; visibility_valid = true; return(true); } else { return(false); } }
public AppendInfo AppendConnectorTo(DMesh3 mesh, Vector3d translate) { validate_geometry(); AppendInfo info = new AppendInfo(); MeshEditor editor = new MeshEditor(mesh); int[] mapV; if (HasInner) { info.InnerGID = mesh.AllocateTriangleGroup(); editor.AppendMesh(InnerMesh, out mapV, info.InnerGID); info.InnerLoop = EdgeLoop.FromVertices(mesh, new MappedList(InnerLoop.Vertices, mapV)); MeshTransforms.PerVertexTransform(mesh, InnerMesh.VertexIndices(), (vid) => { return(mapV[vid]); }, (v, old_vid, new_vid) => { return(v + translate); }); } else { info.InnerGID = -1; info.InnerLoop = null; } info.OuterGID = mesh.AllocateTriangleGroup(); editor.AppendMesh(OuterMesh, out mapV, info.OuterGID); info.OuterLoop = EdgeLoop.FromVertices(mesh, new MappedList(OuterLoop.Vertices, mapV)); MeshTransforms.PerVertexTransform(mesh, OuterMesh.VertexIndices(), (vid) => { return(mapV[vid]); }, (v, old_vid, new_vid) => { return(v + translate); }); return(info); }
protected void set_output_meshes(DMesh3 inner, DMesh3 outer) { InnerMesh = inner; OuterMesh = outer; AxisAlignedBox3d bounds = OuterMesh.CachedBounds; if (InnerMesh != null) { bounds.Contain(InnerMesh.CachedBounds); } // position center-top at origin Vector3d top = bounds.Center + bounds.Extents[1] * Vector3d.AxisY; if (InnerMesh != null) { MeshTransforms.Translate(InnerMesh, -top); } MeshTransforms.Translate(OuterMesh, -top); CombinedBounds = OuterMesh.CachedBounds; if (InnerMesh != null) { CombinedBounds.Contain(InnerMesh.CachedBounds); } if (InnerMesh != null) { var innerLoops = new MeshBoundaryLoops(InnerMesh); InnerLoop = innerLoops[0]; } var outerLoops = new MeshBoundaryLoops(OuterMesh); OuterLoop = outerLoops[0]; }
public MinimalHoleFill(DMesh3 mesh, EdgeLoop fillLoop) { this.Mesh = mesh; this.FillLoop = fillLoop; }