public void Faces_ExtractsFacesAccountingForInstanceTransform() { var ele = ElementSelector.ByElementId(46874, true); var faces = ele.Faces; Assert.AreEqual(6, faces.Length); var bbox = BoundingBox.ByGeometry(faces); bbox.MaxPoint.ShouldBeApproximately(-210.846457, -26.243438, 199.124016, 1e-2); bbox.MinPoint.ShouldBeApproximately(-304.160105, -126.243438, 0, 1e-2); var refs = faces.Select(x => ElementFaceReference.TryGetFaceReference(x)); foreach (var refer in refs) { Assert.AreEqual(46874, refer.InternalReference.ElementId.IntegerValue); } }
public void Curves_ExtractsCurvesAccountingForInstanceTransform() { var ele = ElementSelector.ByElementId(32107, true); var crvs = ele.Curves; Assert.AreEqual(4, crvs.Length); Assert.AreEqual(4, crvs.OfType <Autodesk.DesignScript.Geometry.Line>().Count()); var bbox = BoundingBox.ByGeometry(crvs); bbox.MaxPoint.ShouldBeApproximately(50.0, 0, 0, 1e-3); bbox.MinPoint.ShouldBeApproximately(0, -100.0, 0, 1e-3); var refs = crvs.Select(x => ElementCurveReference.TryGetCurveReference(x)); foreach (var refer in refs) { Assert.AreEqual(32107, refer.InternalReference.ElementId.IntegerValue); } }
public void Curves_ExtractsCurvesFromNestedNonSharedFamilyInstanceAccountingForInstanceTransform() { var ele = ElementSelector.ByElementId(186006, true); var crvs = ele.Curves; Assert.AreEqual(4, crvs.Length); Assert.AreEqual(4, crvs.OfType <Autodesk.DesignScript.Geometry.Line>().Count()); var bbox = BoundingBox.ByGeometry(crvs); bbox.MinPoint.ShouldBeApproximately(-103.697, -88.156, 0, 1e-2); bbox.MaxPoint.ShouldBeApproximately(83.445, 108.963, 0, 1e-2); var refs = crvs.Select(x => ElementCurveReference.TryGetCurveReference(x)); foreach (var refer in refs) { Assert.AreEqual(186006, refer.InternalReference.ElementId.IntegerValue); } }
/* ------------ * K-Means clustering * ------------ */ public static List <List <Point> > kMeansClusteringWithK(List <Point> points, int k) { List <List <Point> > clusters = new List <List <Point> >(); List <Point> centroids = new List <Point>(); for (int i = 0; i < k; ++i) { clusters.Add(new List <Point>()); } //finding max and min X, Y, Z var box = BoundingBox.ByGeometry(points); Point minPt = box.MinPoint; Point maxPt = box.MaxPoint; //intitialize random centers for a given k for (int i = 0; i < k; ++i) { Random r = new Random(); Thread.Sleep(r.Next(0, 10)); double xVal = r.NextDouble() * (maxPt.X - minPt.X) + minPt.X; Thread.Sleep(r.Next(0, 10)); double yVal = r.NextDouble() * (maxPt.Y - minPt.Y) + minPt.Y; Thread.Sleep(r.Next(0, 10)); double zVal = r.NextDouble() * (maxPt.Z - minPt.Z) + minPt.Z; Point tempPt = Point.ByCoordinates(xVal, yVal, zVal); centroids.Add(Point.ByCoordinates(xVal, yVal, zVal)); } double prevDistance = 0; //assign points to the initial centroid for (int i = 0; i < points.Count; ++i) { int clusterToAdd = 0; Point pointInConsideration = points[i]; prevDistance = pointInConsideration.DistanceTo(centroids[0]); for (int j = 1; j < k; ++j) { double distance = pointInConsideration.DistanceTo(centroids[j]); if (distance < prevDistance) { clusterToAdd = j; prevDistance = distance; } } clusters[clusterToAdd].Add(pointInConsideration); } var oldCentroids = new List <Point>(); loop: oldCentroids = centroids; //compute new centroids for given clusters. If the clusters are empty, go back to old centroid for (int i = 0; i < clusters.Count; ++i) { if (clusters[i].Count == 0) { centroids[i] = centroids[i]; } else { double xSum = 0, ySum = 0, zSum = 0; for (int j = 0; j < clusters[i].Count; ++j) { xSum = xSum + clusters[i][j].X; ySum = ySum + clusters[i][j].Y; zSum = zSum + clusters[i][j].Z; } centroids[i] = Point.ByCoordinates(xSum / clusters[i].Count, ySum / clusters[i].Count, zSum / clusters[i].Count); } } for (int i = 0; i < centroids.Count; ++i) { if ((oldCentroids[i].X != centroids[i].X) || (oldCentroids[i].Y != centroids[i].Y) || (oldCentroids[i].Z != centroids[i].Z)) { oldCentroids = centroids; goto loop; } } return(clusters); }
public static List <List <DynamoRevitElements.Floor> > CreateRevitFloors( DynamoElements.Surface[][] srfList, DynamoRevitElements.FloorType floorType, string levelPrefixStr = "Dynamo Level") { if (srfList == null) { throw new ArgumentNullException(nameof(srfList)); } if (!(floorType.InternalElement is RevitElements.FloorType revitFloorType)) { throw new ArgumentOutOfRangeException(nameof(floorType)); } DisplayUnitType unitType = Document.GetUnits().GetFormatOptions(UnitType.UT_Length).DisplayUnits; var FloorElements = new List <List <DynamoRevitElements.Floor> >(); var collector = new FilteredElementCollector(Document); var levels = collector.OfClass(typeof(RevitElements.Level)).ToElements() .Where(e => e is RevitElements.Level) .Cast <RevitElements.Level>(); TransactionManager.Instance.EnsureInTransaction(Document); for (var i = 0; i < srfList.Length; i++) { if (srfList[i] == null) { throw new ArgumentNullException(nameof(srfList)); } FloorElements.Add(new List <DynamoRevitElements.Floor>()); string levelName = $"{levelPrefixStr} {i + 1}"; var revitLevel = levels.FirstOrDefault(level => level.Name == levelName); double elevation; using (var floorBounds = BoundingBox.ByGeometry(srfList[i])) { elevation = UnitUtils.ConvertToInternalUnits(floorBounds.MaxPoint.Z, unitType); } if (revitLevel != null) { // Adjust existing level to correct height. revitLevel.Elevation = elevation; } else { // Create new level. revitLevel = RevitElements.Level.Create(Document, elevation); revitLevel.Name = levelName; } var revitCurves = new CurveArray(); foreach (var surface in srfList[i]) { var loops = Building.GetSurfaceLoops(surface); revitCurves.Clear(); loops[0].Curves().ForEach(curve => revitCurves.Append(curve.ToRevitType())); var revitFloor = Document.Create.NewFloor(revitCurves, revitFloorType, revitLevel, true); FloorElements.Last().Add(revitFloor.ToDSType(false) as DynamoRevitElements.Floor); // Need to finish creating the floor before we add openings in it. TransactionManager.Instance.ForceCloseTransaction(); TransactionManager.Instance.EnsureInTransaction(Document); loops.Skip(1).ToArray().ForEach(loop => { revitCurves.Clear(); loop.Curves().ForEach(curve => revitCurves.Append(curve.ToRevitType())); Document.Create.NewOpening(revitFloor, revitCurves, true); }); loops.ForEach(x => x.Dispose()); revitFloor.Dispose(); } revitCurves.Dispose(); } TransactionManager.Instance.TransactionTaskDone(); collector.Dispose(); return(FloorElements); }
public static Dictionary <string, object> PackUnfoldSurfaces <K, T>(PlanarUnfolder.PlanarUnfolding <K, T> unfold, double width = 20, double height = 20, double gap = .3) where T : IUnfoldablePlanarFace <K>, new() where K : IUnfoldableEdge { //first step is to align all the facelikes in the unfold // to the plane and get new transforms and facelikes var alignedgeo = MoveSurfacesInUnfoldToPlane <K, T>(unfold); var translatedFaces = alignedgeo.Item1; var translationTransforms = alignedgeo.Item2; List <PlanarUnfolder.FaceTransformMap> packingtransforms = new List <PlanarUnfolder.FaceTransformMap>(); var facelikes = translatedFaces; var bbs = facelikes.Select(x => BoundingBox.ByGeometry(x.SurfaceEntities)).ToList(); var newcenters = DynamoPack.Packing.ByCoordinateSystems(bbs, width, height, gap); var centers = bbs.Select(x => x.MinPoint.Add((x.MaxPoint.Subtract(x.MinPoint.AsVector()).AsVector().Scale(.5)))).ToList(); if (newcenters.Count != centers.Count) { throw new Exception("The bounding box for this packing operation is too small, try a larger x or y value or smaller gap size"); } var packedfinalsurfaces = new List <List <Surface> >(); var packedfinalfacelikes = new List <T>(); foreach (var surftotrans in facelikes) { var index = facelikes.IndexOf(surftotrans); var transvec = Vector.ByTwoPoints(centers[index], newcenters[index]); var newsurface = surftotrans.SurfaceEntities.Select(x => x.Translate(transvec)).Cast <Surface>().ToList(); var ids = translatedFaces[index].IDS; // keep track of where all the newsurfaces end up in the packing and what labels where moved //TODO just try keeping the transvec instead..... packingtransforms.Add(new PlanarUnfolder.FaceTransformMap(surftotrans.SurfaceEntities.First().ContextCoordinateSystem, newsurface.First().ContextCoordinateSystem, ids)); packedfinalsurfaces.Add(newsurface); // create a copy of the old facelike, but update the surface var newfacelike = new T(); newfacelike.OriginalEntity = surftotrans.OriginalEntity; newfacelike.SurfaceEntities = newsurface as List <Surface>; newfacelike.ID = surftotrans.ID; newfacelike.IDS = surftotrans.IDS; newfacelike.EdgeLikeEntities = surftotrans.EdgeLikeEntities; packedfinalfacelikes.Add(newfacelike); } foreach (IDisposable item in translatedFaces.SelectMany(x => x.SurfaceEntities).ToList()) { item.Dispose(); } //first concat the old unfold transforms with the translation ones, // then add the final packing transforms var aggregatedtransforms = unfold.Maps.Concat(translationTransforms).ToList(); aggregatedtransforms.AddRange(packingtransforms); // finally create a new unfold object and pass it out var packedUnfolding = new PlanarUnfolder.PlanarUnfolding <K, T>(unfold.StartingUnfoldableFaces, packedfinalsurfaces, aggregatedtransforms, packedfinalfacelikes, unfold.OriginalGraph); return(new Dictionary <string, object> { { "packed surfaces", (packedfinalsurfaces) }, { "unfoldObject", (packedUnfolding) } }); }