private void DelaunayRefine(int scenario) { var sw = new Stopwatch(); sw.Start(); Random rng = new Random(); BoundingBox box = new BoundingBox(0, 10, -10, 0, 0, 0); int size = 50; Geometry.Vector[] points; if (scenario == 1) { points = box.RandomPointsInside(rng, size); } else if (scenario == 2) { points = new Geometry.Vector[] { new Geometry.Vector(10, -9.5), new Geometry.Vector(0, -9.5), new Geometry.Vector(2, -0.5), new Geometry.Vector(8, -0.5) //new Geometry.Vector(4.5,-0.5), //new Geometry.Vector(5.5,-0.5) }; } else { points = new Geometry.Vector[] { new Geometry.Vector(10, -6), new Geometry.Vector(10, -2), new Geometry.Vector(0, -6), //new Geometry.Vector(0, -6) }; } VertexCollection verts = new VertexCollection(points); MeshFaceCollection faces = Mesh.DelaunayTriangulationXY(verts); faces.Quadrangulate(); faces = faces.Refine(0.5); //Dictionary<Vertex, MeshFace> voronoi = Mesh.VoronoiFromDelaunay(verts, faces); //ShapeCollection geometry = new MeshFaceCollection(voronoi.Values).ExtractFaceBoundaries(); CurveCollection edges = faces.ExtractFaceBoundaries(); VertexGeometryCollection geometry = new VertexGeometryCollection(); foreach (var edge in edges) { var region = new PlanarRegion(edge); geometry.Add(region); region.Attributes = new GeometryAttributes(new Colour(128, 0, 255, 128)); geometry.Add(edge); edge.Attributes = new GeometryAttributes(new Colour(64, 0, 0, 0)); } geometry.Add(new Cloud(verts.ExtractPoints())); sw.Stop(); MeshingTimeText.Text = "Completed: " + faces.Count + " faces in " + sw.Elapsed; DelaunayCanvas.Geometry = geometry; }
/// <summary> /// Convert a Nucleus PlanarSurface into a Rhino BRep /// </summary> /// <param name="surface"></param> /// <returns></returns> public static RC.Brep Convert(PlanarRegion surface) { if (surface == null || !surface.IsValid) { return(null); } else { var rCrvs = new List <RC.Curve>(); rCrvs.Add(Convert(surface.Perimeter)); if (surface.HasVoids) { foreach (Curve voidCrv in surface.Voids) { rCrvs.Add(Convert(voidCrv)); } } RC.Brep[] result = RC.Brep.CreatePlanarBreps(rCrvs); if (result == null) { result = new RC.Brep[] { RC.Brep.CreatePatch(rCrvs, 1, 1, Tolerance.Distance) }; } if (result != null && result.Length > 0) { return(result[0]); } } return(null); }
private void DelaunayButton_Click(object sender, RoutedEventArgs e) { Random rng = new Random(); BoundingBox box = new BoundingBox(0, 10, -10, 0, 0, 0); int size = 100; Geometry.Vector[] points = box.RandomPointsInside(rng, size); VertexCollection verts = new VertexCollection(points); MeshFaceCollection faces = Mesh.DelaunayTriangulationXY(verts); faces.Quadrangulate(); //Dictionary<Vertex, MeshFace> voronoi = Mesh.VoronoiFromDelaunay(verts, faces); //ShapeCollection geometry = new MeshFaceCollection(voronoi.Values).ExtractFaceBoundaries(); CurveCollection edges = faces.ExtractFaceBoundaries(); VertexGeometryCollection geometry = new VertexGeometryCollection(); foreach (var edge in edges) { var region = new PlanarRegion(edge); geometry.Add(region); region.Attributes = new GeometryAttributes(new Colour(128, 0, 255, 128)); geometry.Add(edge); edge.Attributes = new GeometryAttributes(new Colour(64, 0, 0, 0)); } geometry.Add(new Cloud(verts.ExtractPoints())); DelaunayCanvas.Geometry = geometry; }
protected void GetPlanarPolys(PlanarRegion r, List <Polygon2d> polys) { try { MeshRegionBoundaryLoops loops = new MeshRegionBoundaryLoops(r.Mesh, r.Triangles); foreach (var loop in loops) { DCurve3 curve = loop.ToCurve(); Polygon2d poly = new Polygon2d(); int NV = curve.VertexCount; for (int k = 0; k < NV; k++) { poly.AppendVertex(curve[k].xy); } polys.Add(poly); } } catch (Exception) { // add each triangle as a polygon and let clipper sort it out Vector3d v0 = Vector3d.Zero, v1 = Vector3d.Zero, v2 = Vector3d.Zero; foreach (int tid in r.Triangles) { r.Mesh.GetTriVertices(tid, ref v0, ref v1, ref v2); Polygon2d p = new Polygon2d(); p.AppendVertex(v0.xy); p.AppendVertex(v1.xy); p.AppendVertex(v2.xy); polys.Add(p); } } }
/// <summary> /// Convert a planar Rhino surface to a Nucleus planar region /// </summary> /// <param name="brep"></param> /// <returns></returns> public static PlanarRegion ConvertToPlanarRegion(RC.Brep brep, RC.BrepFace face) { //if (face.IsPlanar()) //{ int[] iEdges = face.AdjacentEdges(); RC.Curve[] curves = new RC.Curve[iEdges.Length]; for (int i = 0; i < iEdges.Length; i++) { RC.BrepEdge bEdge = brep.Edges[i]; curves[i] = bEdge; } var joined = RC.Curve.JoinCurves(curves); if (joined.Length > 0) { RC.Curve outer = outerCurve(joined); if (outer != null) { Curve boundary = Convert(outer); var result = new PlanarRegion(boundary); for (int i = 0; i < joined.Length; i++) { if (joined[i] != outer) { Curve voidCrv = Convert(joined[i]); result.Voids.Add(voidCrv); } } return(result); } } //} return(null); }
/// <summary> /// Find regions of the input meshes that are horizontal, returns binned by Z-value. /// Currently only finds upward-facing regions. /// </summary> protected Dictionary <double, List <PlanarRegion> > FindPlanarZRegions(double minDimension, double dotNormalTol = 0.999) { Dictionary <double, List <PlanarRegion> > Regions = new Dictionary <double, List <PlanarRegion> >(); SpinLock region_lock = new SpinLock(); gParallel.ForEach(Meshes, (sliceMesh) => { if (sliceMesh.options.IsCavity == false) { return; } DMesh3 mesh = sliceMesh.mesh; HashSet <int> planar_tris = new HashSet <int>(); foreach (int tid in mesh.TriangleIndices()) { Vector3d n = mesh.GetTriNormal(tid); double dot = n.Dot(Vector3d.AxisZ); if (dot > dotNormalTol) { planar_tris.Add(tid); } } MeshConnectedComponents regions = new MeshConnectedComponents(mesh); regions.FilterF = planar_tris.Contains; regions.FindConnectedT(); foreach (var c in regions) { AxisAlignedBox3d bounds = MeshMeasurements.BoundsT(mesh, c.Indices); if (bounds.Width > minDimension && bounds.Height > minDimension) { double z = Math.Round(bounds.Center.z, PrecisionDigits); PlanarRegion planar = new PlanarRegion() { Mesh = mesh, Z = z, Triangles = c.Indices }; bool taken = false; region_lock.Enter(ref taken); List <PlanarRegion> zregions; if (Regions.TryGetValue(z, out zregions)) { zregions.Add(planar); } else { zregions = new List <PlanarRegion>() { planar }; Regions[z] = zregions; } region_lock.Exit(); } } }); return(Regions); }
/// <summary> /// Convert a netDXF hatch to a set of Nucleus planar regions /// </summary> /// <param name="hatch"></param> /// <returns></returns> public static PlanarRegion[] Convert(nDE.Hatch hatch) { PlanarRegion[] result = new PlanarRegion[hatch.BoundaryPaths.Count]; for (int i = 0; i < hatch.BoundaryPaths.Count; i++) { result[i] = new PlanarRegion(Convert(hatch.BoundaryPaths[i]), ExtractAttributes(hatch)); } return(result); }
/// <summary> /// Convert a Nucleus planar region to a netDXF hatch /// </summary> /// <param name="region"></param> /// <returns></returns> public static nDE.Hatch Convert(PlanarRegion region) { var result = new nDE.Hatch(nDE.HatchPattern.Solid, false); result.BoundaryPaths.Add(ConvertToBoundary(region.Perimeter)); foreach (Curve voidCrv in region.Voids) { result.BoundaryPaths.Add(ConvertToBoundary(voidCrv)); } SetAttributes(result, region.Attributes); return(result); }
public override bool Execute(ExecutionInfo exInfo = null) { if (Line != null && Line.Length > 0 && Height != 0) { var points = new Vector[] { Line.StartPoint, Line.EndPoint, Line.EndPoint + new Vector(0, 0, Height), Line.StartPoint + new Vector(0, 0, Height) }; PlanarRegion pRegion = new PlanarRegion(new PolyLine(points, true)); Element = Model.Create.PanelElement(pRegion, exInfo); Element.Family = BuildUp; } return(true); }
public override bool Execute(ExecutionInfo exInfo = null) { if (Perimeter != null && Perimeter.Plane() != null) { PlanarRegion pRegion = new PlanarRegion(Perimeter); Element = Model.Create.PanelElement(pRegion, exInfo); Element.Family = BuildUp; return(true); } else { throw new Exception("Input curve is not planar!"); } }
public override DisplayLayer PreviewLayer(PreviewParameters parameters) { if (parameters.IsDynamic && parameters.SelectionPoints != null && parameters.SelectionPoints.Count > 2 && parameters.SelectionPoints.ArePlanar()) { ManualDisplayLayer layer = new ManualDisplayLayer(); IMeshAvatar mesh = layer.CreateMeshAvatar(); PlanarRegion pRegion = new PlanarRegion(new PolyLine(parameters.SelectionPoints, true)); mesh.Builder.AddPanelPreview(pRegion, BuildUp); mesh.FinalizeMesh(); layer.Add(mesh); return(layer); } return(null); }
public override bool Execute(ExecutionInfo exInfo = null) { if (Points != null && Points.Count > 2) { if (!Points.ArePlanar()) { throw new Exception("Points do not lie on the same plane!"); } // TODO: Check for re-entrancy! PlanarRegion pRegion = new PlanarRegion(new PolyLine(Points, true)); Element = Model.Create.PanelElement(pRegion, exInfo); Element.Family = BuildUp; return(true); } else { throw new Exception("Insufficient points to define a panel!"); } }
private void AnalysisMeshButton_Click(object sender, RoutedEventArgs e) { Random rng = new Random(); BoundingBox box = new BoundingBox(1, 9, -9, -1, 0, 0); int size = 100; //Geometry.Vector[] points = box.RandomPointsInside(rng, size); //VertexCollection verts = new VertexCollection(points); VertexCollection verts = new VertexCollection(); //verts.Add(new Vertex(1, -1)); int divs = 5; for (int i = 0; i <= divs; i++) { for (int j = 0; j <= divs; j++) { Geometry.Vector pt = new Geometry.Vector(box.X.ValueAt(((double)i) / divs), box.Y.ValueAt(((double)j) / divs)); verts.Add(new Vertex(pt)); } } MeshFaceCollection faces = Mesh.DelaunayTriangulationXY(verts); faces.Quadrangulate(); //Dictionary<Vertex, MeshFace> voronoi = Mesh.VoronoiFromDelaunay(verts, faces); //ShapeCollection geometry = new MeshFaceCollection(voronoi.Values).ExtractFaceBoundaries(); CurveCollection edges = faces.ExtractFaceBoundaries(); VertexGeometryCollection geometry = new VertexGeometryCollection(); foreach (var edge in edges) { var region = new PlanarRegion(edge); geometry.Add(region); region.Attributes = new GeometryAttributes(new Colour(128, 0, 255, 128)); geometry.Add(edge); edge.Attributes = new GeometryAttributes(new Colour(64, 0, 0, 0)); } geometry.Add(new Cloud(verts.ExtractPoints())); DelaunayCanvas.Geometry = geometry; }
/// <summary> /// Initialise a new GeometricProfile with the specified geometry. /// </summary> /// <param name="geometry"></param> public GeometricProfile(PlanarRegion geometry) { Geometry = geometry; }
/// <summary> /// Add geometric contents to the canvas, automatically converting from /// Nucleus geometry to the WPF equivalent /// </summary> /// <param name="shape"></param> public void AddContents(VertexGeometry shape) { if (shape is Curve) { Curve crv = (Curve)shape; PathGeometry pathGeo = new PathGeometry(); pathGeo.Figures.Add(ToWPF.Convert(crv)); Path path = new Path(); path.DataContext = crv; //if (crv.Attributes == null || crv.Attributes.Brush == null) //{ // path.Stroke = DefaultBrush; //} //else path.Stroke = FBtoWPF.Convert(crv.Attributes.Brush); var strokeBinding = new Binding("Attributes.Brush"); strokeBinding.Converter = new Converters.BrushConverter(); strokeBinding.FallbackValue = DefaultBrush; path.SetBinding(Path.StrokeProperty, strokeBinding); path.StrokeStartLineCap = PenLineCap.Round; path.StrokeEndLineCap = PenLineCap.Round; //path.StrokeThickness = CurveThickness; //var thicknessBinding = new Binding("CurveThickness"); //thicknessBinding.Source = this; if (crv.Attributes == null) { //path.SetBinding(Path.StrokeThicknessProperty, thicknessBinding); path.StrokeThickness = CurveThickness; } else { /*var mBinding = new MultiBinding(); * mBinding.Converter = new Converters.MultiplicationConverter(); * mBinding.Bindings.Add(thicknessBinding); * mBinding.Bindings.Add(new Binding("Attributes.Weight")); * * path.SetBinding(Path.StrokeThicknessProperty, mBinding);*/ path.StrokeThickness = CurveThickness * crv.Attributes.Weight; } // * scaleFactor; path.Data = pathGeo; path.StrokeLineJoin = PenLineJoin.Round; if (crv.Closed && FillBrush != null) { path.Fill = FillBrush; } //fillBrush = null; path.Tag = shape; Children.Add(path); } else if (shape is PlanarRegion) { PlanarRegion reg = (PlanarRegion)shape; Curve perimeter = reg.Perimeter; CurveCollection voids = reg.Voids; PathGeometry perimeterPath = new PathGeometry(); perimeterPath.Figures.Add(ToWPF.Convert(perimeter)); CombinedGeometry cg = new CombinedGeometry(); cg.GeometryCombineMode = GeometryCombineMode.Exclude; cg.Geometry1 = perimeterPath; if (voids != null && voids.Count > 0) { PathGeometry inside = new PathGeometry(); foreach (Curve vCrv in voids) { inside.Figures.Add(ToWPF.Convert(vCrv)); } cg.Geometry2 = inside; } Path path = new Path(); path.DataContext = shape; //if (reg.Attributes == null || reg.Attributes.Brush == null) //{ // path.Fill = DefaultBrush; //} //else path.Fill = FBtoWPF.Convert(reg.Attributes.Brush, 192); var fillBinding = new Binding("Attributes.Brush"); fillBinding.Converter = new Converters.BrushConverter(); fillBinding.FallbackValue = DefaultBrush; fillBinding.ConverterParameter = 192; path.SetBinding(Path.FillProperty, fillBinding); //path.Stroke = Brushes.Black; //path.StrokeThickness = 0.01; path.Data = cg; path.Tag = shape; Children.Add(path); } else if (shape is FB.Label) { FB.Label label = (FB.Label)shape; TextBlock tB = new TextBlock(); tB.DataContext = label; tB.Padding = new Thickness(0); if (label.TextBinding != null) { tB.SetBinding(TextBlock.TextProperty, ToWPF.Convert(label.TextBinding)); } else { tB.SetBinding(TextBlock.TextProperty, new Binding("Text")); } tB.FontSize = 1; //label.TextSize; tB.RenderTransform = new ScaleTransform(label.TextSize, label.TextSize); //tB.RenderTransformOrigin = new System.Windows.Point(0, 1); var fillBinding = new Binding("Attributes.Brush"); fillBinding.Converter = new Converters.BrushConverter(); fillBinding.FallbackValue = DefaultBrush; tB.SetBinding(TextBlock.ForegroundProperty, fillBinding); FormattedText fT = new FormattedText(label.Text, CultureInfo.CurrentCulture, tB.FlowDirection, new Typeface(tB.FontFamily, tB.FontStyle, tB.FontWeight, tB.FontStretch), 1, tB.Foreground); double xOffset; if (label.HorizontalSetOut == HorizontalSetOut.Left) { xOffset = 0; } else if (label.HorizontalSetOut == HorizontalSetOut.Right) { xOffset = fT.Width * label.TextSize; } else { xOffset = label.TextSize * fT.Width / 2; } double yOffset; if (label.VerticalSetOut == VerticalSetOut.Top) { yOffset = 0; } else if (label.VerticalSetOut == VerticalSetOut.Bottom) { yOffset = fT.Height * label.TextSize; } else { yOffset = label.TextSize * fT.Height / 2; } SetLeft(tB, label.Position.X - xOffset); SetTop(tB, -label.Position.Y - yOffset); tB.Tag = shape; Children.Add(tB); } else if (shape is Cloud || shape is FB.Point) { double diameter = PointDiameter; if (shape.Attributes != null) { diameter *= shape.Attributes.Weight; } foreach (Vertex v in shape.Vertices) { Ellipse ellipse = new Ellipse(); ellipse.Width = diameter; ellipse.Height = diameter; ellipse.DataContext = shape; var fillBinding = new Binding("Attributes.Brush"); fillBinding.Converter = new Converters.BrushConverter(); fillBinding.FallbackValue = DefaultBrush; ellipse.SetBinding(Ellipse.FillProperty, fillBinding); SetLeft(ellipse, v.X - diameter / 2.0); SetTop(ellipse, -v.Y - diameter / 2.0); ellipse.Tag = shape; if (shape.Attributes != null && shape.Attributes.Interactive) { //TODO: CHANGE THIS! TEMP ONLY! ellipse.Cursor = Cursors.Hand; } Children.Add(ellipse); } } }
public GeometryVisualiserDialog(object visualise) : this() { VertexGeometryCollection geometry = new VertexGeometryCollection(); if (_StorePath.Exists) { try { Stream stream = new FileStream(_StorePath, FileMode.Open, FileAccess.Read, FileShare.Read); stream.Seek(0, SeekOrigin.Begin); IFormatter formatter = new BinaryFormatter(); formatter.Binder = new CustomSerializationBinder(); var storedGeo = formatter.Deserialize(stream) as VertexGeometryCollection; stream.Close(); if (storedGeo != null) { geometry.AddRange(storedGeo); } } catch { } } if (visualise is MeshFace) { visualise = new MeshFaceCollection((MeshFace)visualise); } //else if (visualise is Mesh) visualise = ((Mesh)visualise).Faces; if (visualise is IList <VertexGeometry> ) { geometry.TryAddRange((IList <VertexGeometry>)visualise); } else if (visualise is IList <Curve> ) { geometry.TryAddRange((IList <Curve>)visualise); } else if (visualise is IList <PlanarRegion> ) { geometry.TryAddRange((IList <PlanarRegion>)visualise); } else if (visualise is VertexGeometry) { geometry.TryAdd((VertexGeometry)visualise); } else if (visualise is MeshFaceCollection) { var faces = (MeshFaceCollection)visualise; CurveCollection edges = faces.ExtractFaceBoundaries(); foreach (var edge in edges) { var region = new PlanarRegion(edge); geometry.Add(region); region.Attributes = new GeometryAttributes(new Colour(128, 0, 255, 128)); geometry.Add(edge); edge.Attributes = new GeometryAttributes(new Colour(64, 0, 0, 0)); } } else if (visualise is IList <Vertex> ) { var verts = (IList <Vertex>)visualise; var cloud = new Cloud(verts.GetPositions()); geometry.Add(cloud); } else if (visualise is IList <Geometry.Vector> ) { var v = (IList <Geometry.Vector>)visualise; var cloud = new Cloud(v); geometry.Add(cloud); } else if (visualise is MeshDivisionEdge) { var mDE = (MeshDivisionEdge)visualise; var line = new Geometry.Line(mDE.Start, mDE.End); geometry.Add(line); if (mDE.Vertices != null && mDE.Vertices.Count > 0) { var cloud = new Cloud(mDE.Vertices.GetPositions()); geometry.Add(cloud); } } else if (visualise is IList <MeshDivisionEdge> ) { foreach (var mDC in (IList <MeshDivisionEdge>)visualise) { var mDE = (MeshDivisionEdge)visualise; var line = new Geometry.Line(mDE.Start, mDE.End); geometry.Add(line); if (mDE.Vertices != null && mDE.Vertices.Count > 0) { var cloud = new Cloud(mDE.Vertices.GetPositions()); geometry.Add(cloud); } } } else if (visualise is IWidePath) { IWidePath path = (IWidePath)visualise; AddWidePath(geometry, path); } else if (visualise is IList <IWidePath> ) { foreach (var path in (IList <IWidePath>)visualise) { AddWidePath(geometry, path); } } // TODO: Convert other types to vertexgeometry BoundingBox bBox = geometry.BoundingBox; /*MinX.Text = bBox.MinX.ToString(); * MaxX.Text = bBox.MaxX.ToString(); * MinY.Text = bBox.MinY.ToString(); * MaxY.Text = bBox.MaxY.ToString();*/ Canvas.CurveThickness = 0.005 * bBox.SizeVector.Magnitude(); Canvas.PointDiameter = 0.01 * bBox.SizeVector.Magnitude(); Canvas.DefaultBrush = new SolidColorBrush(Color.FromArgb(128, 0, 0, 0)); //Canvas.FillBrush = new SolidColorBrush(Color.FromArgb(64, 0, 0, 0)); Canvas.Geometry = geometry; /*var xDivs = bBox.X.ReasonableDivisions(10); * var yDivs = bBox.Y.ReasonableDivisions(10); * * foreach (double x in xDivs) * { * var line = new Geometry.Line(x, bBox.MinY - 10, x, bBox.MaxY + 10); * line.Attributes = new GeometryAttributes(Rendering.Colour.Green, 0.1); * Canvas.AddContents(line); * }*/ }
/// <summary> /// Initialise a new area load over the specified area to be resolved to the /// specified elements. /// </summary> /// <param name="appliedOver"></param> /// <param name="appliedTo"></param> public AreaLoad(PlanarRegion appliedOver, ElementCollection appliedTo) : this() { _AppliedOver = appliedOver; AppliedTo.Add(appliedTo); }