public Tab(T face, K edge, PlanarUnfolder.PlanarUnfolding <K, T> unfoldObject, double tabOffset = .3) { ID = face.ID; UnfoldableFace = face; TabSurf = generateTabGeo(edge, tabOffset); AlignedTabSurf = PlanarUnfolder.DirectlyMapGeometryToUnfoldingByID(unfoldObject, TabSurf, ID); }
public static Dictionary <int, List <Tab <K, T> > > GenerateTabSurfacesFromUnfold <K, T>(PlanarUnfolder.PlanarUnfolding <K, T> unfoldingObject, double relativeWidth = .3) where K : IUnfoldableEdge where T : IUnfoldablePlanarFace <K>, new() { //TODO cleanup old geometry var tabedges = new List <K>(); // gather the difference set of edges between all shared edegs and the edges we actually fold around // the difference are the edges that we need to add tabs to var gedges = GraphUtilities.GetAllGraphEdges <K, T>(unfoldingObject.OriginalGraph).Select(x => x.GeometryEdge).ToList(); var tedges = GraphUtilities.GetAllTreeEdges <K, T>(unfoldingObject.OriginalGraph).Select(x => x.GeometryEdge).ToList(); var nonFoldEdegs = gedges.Except(tedges, new SpatialEqualityComparer <K>()); var tabDict = new Dictionary <int, List <Tab <K, T> > >(); foreach (var edge in nonFoldEdegs) { if (tabedges.Contains(edge) == false) { tabedges.Add(edge); // find the first vertex that contains this edge in its graph edge list var firstmatchingvertingraph = unfoldingObject.OriginalGraph.Find(x => x.GraphEdges.Select(y => y.GeometryEdge).ToList().Contains(edge)); //make a new tab var newtab = new Tab <K, T>(firstmatchingvertingraph.Face, edge, unfoldingObject, relativeWidth); //store the tab //if the same surface has another tab on a different edge add it to the dict if (tabDict.ContainsKey(firstmatchingvertingraph.Face.ID)) { tabDict[firstmatchingvertingraph.Face.ID].Add(newtab); continue; } tabDict.Add(firstmatchingvertingraph.Face.ID, new List <Tab <K, T> >() { newtab }); } } return(tabDict); }
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) } }); }
//align all surfaces down, generate new transforms // private static Tuple <List <T>, List <PlanarUnfolder.FaceTransformMap> > MoveSurfacesInUnfoldToPlane <K, T>(PlanarUnfolder.PlanarUnfolding <K, T> unfold) where K : IUnfoldableEdge where T : IUnfoldablePlanarFace <K>, new() { var alignDownTransforms = new List <PlanarUnfolder.FaceTransformMap>(); var translatedFaces = new List <T>(); var faces = unfold.UnfoldedFaces; foreach (var facelike in faces) { var surfaceToAlignDown = facelike.SurfaceEntities; // get the coordinate system defined by the face normal var somePointOnSurface = facelike.SurfaceEntities.First().PointAtParameter(.5, .5); var norm = facelike.SurfaceEntities.First().NormalAtParameter(.5, .5); var facePlane = Plane.ByOriginNormal(somePointOnSurface, norm); var startCoordSystem = CoordinateSystem.ByPlane(facePlane); //TODO need to cleanup planes, coord systems... // transform surface to horizontal plane at x,y,0 of org surface var tempSurfaces = surfaceToAlignDown.Select(x => x.Transform(startCoordSystem, CoordinateSystem.ByPlane(Plane.ByOriginXAxisYAxis( Point.ByCoordinates(somePointOnSurface.X, somePointOnSurface.Y, 0), Vector.XAxis(), Vector.YAxis()))) as Surface).ToList(); var flatcoordsystem = CoordinateSystem.ByPlane(Plane.ByOriginXAxisYAxis( Point.ByCoordinates(somePointOnSurface.X, somePointOnSurface.Y, 0), Vector.XAxis(), Vector.YAxis())); // save transformation for each set, this should have all the ids present //TODO is this incorrect? should we be saving tempSurfaces? alignDownTransforms.Add(new PlanarUnfolder.FaceTransformMap(startCoordSystem, flatcoordsystem, facelike.IDS)); //alignDownTransforms.Add(new PlanarUnfolder.FaceTransformMap( //startCoordSystem, facelike.IDS)); //create a new facelike to hold the new surfaces that are aligned to the plane //the ids are the same though which lets us label these and apply the correct transformations var newfacelike = new T(); newfacelike.OriginalEntity = facelike.OriginalEntity; newfacelike.SurfaceEntities = tempSurfaces; newfacelike.ID = facelike.ID; newfacelike.IDS = facelike.IDS; newfacelike.EdgeLikeEntities = facelike.EdgeLikeEntities; translatedFaces.Add(newfacelike); } return(Tuple.Create(translatedFaces, alignDownTransforms)); }