private void createOrientationStrategy() { switch (orientation) { case LayoutType.Horizontal: this.orientationStrategy = new HorizontalPopoutStrategy(this); break; case LayoutType.Vertical: this.orientationStrategy = new VerticalPopoutStrategy(this); break; default: throw new NotImplementedException(); } }
private Node(string id, Point center, Solid nodeBaseGeo, List <Line> lines, double strutDiameter, double drillDepth, OrientationStrategy strategy) { ID = id; originalGeometry = nodeBaseGeo; Center = center; DrillDepth = drillDepth; //orient the struts so they all point away from the node var newlines = lines.Select(x => pointAway(center, x)).ToList(); //construct stuts from these new lines this.Struts = newlines.Select(x => new Strut(x, strutDiameter, this)).ToList(); //calculate the orientation of the node based on the orientation strategy this.OrientedNodeGeometry = orientNode(strategy, this.Struts); }
private Solid orientNode(OrientationStrategy strategy, List <Strut> struts) { switch (strategy) { case OrientationStrategy.AllNodesOrientedToWorldXYZ: var plane = Plane.ByOriginNormal(Center, Vector.ZAxis()); var newCs = CoordinateSystem.ByPlane(plane); var output = originalGeometry.Transform(newCs) as Solid; plane.Dispose(); newCs.Dispose(); return(output); break; case OrientationStrategy.AllNodesSameAsBaseGeo: var orgCs = originalGeometry.ContextCoordinateSystem; plane = Plane.ByOriginNormal(Center, orgCs.ZAxis); newCs = CoordinateSystem.ByPlane(plane); output = originalGeometry.Transform(newCs) as Solid; plane.Dispose(); newCs.Dispose(); orgCs.Dispose(); return(output); break; case OrientationStrategy.AverageStrutsVector: //orient the cube based on the average normal of the incoming struts var spoints = struts.Select(x => x.LineRepresentation.StartPoint).ToList(); var epoints = struts.Select(x => x.LineRepresentation.EndPoint).ToList(); var vectors = spoints.Zip(epoints, (x, y) => Vector.ByTwoPoints(x, y)).ToList(); var averageNorm = averageVector(vectors); var revd = averageNorm.Reverse(); if (revd.IsAlmostEqualTo(Vector.ByCoordinates(0, 0, 0))) { revd = Vector.ByCoordinates(0, 0, 1); } //reverse the normal so the top face is correct plane = Plane.ByOriginNormalXAxis(Center, revd, Vector.ByCoordinates(0, 0, 1)); newCs = CoordinateSystem.ByPlane(plane); output = originalGeometry.Transform(newCs) as Solid; plane.Dispose(); newCs.Dispose(); spoints.ForEach(x => x.Dispose()); epoints.ForEach(x => x.Dispose()); vectors.ForEach(x => x.Dispose()); averageNorm.Dispose(); revd.Dispose(); return(output); break; case OrientationStrategy.OrientationProvided: break; default: return(NodeGeometry); break; } //eh? return(NodeGeometry); }
/// <summary> /// construct list of nodes from a list of points and lines, this method finds the struts that belong /// to each node, orient them correctly, and constructs a geometric representation of the individual nodes /// from some base geometry which is oriented in a variety of ways /// </summary> /// <param name="nodeCenters"> the points where the nodes are positioned</param> /// <param name="struts"> the lines that represent the struts, these must be intersecting the points at their endpoints</param> /// <param name="strutDiameter"> the diameter of the struts</param> /// <param name="drillDepth"> the depth that a strut should be sunk into the surface of node</param> /// <param name="baseNode"></param> /// <param name="nodeOrientationStrategy"></param> /// <returns></returns> public static List <Node> ByPointsLinesAndGeoOrientationStrategy(List <Point> nodeCenters, List <Line> struts, double strutDiameter, Solid baseNode, OrientationStrategy nodeOrientationStrategy, double drillDepth = 12.7) { int currentId = 1; //prune all duplicate inputs from wireframe var prunedPoints = Point.PruneDuplicates(nodeCenters); var prunedLines = GeometryExtensions.PruneDuplicates(struts); //find the adjacentLines for each node var output = new List <Node>(); foreach (var centerPoint in prunedPoints) { //find adjacent struts for this node var intersectingLines = findAdjacentLines(centerPoint, prunedLines); var currentNode = new Node("N" + currentId.ToString().PadLeft(4, '0'), centerPoint, baseNode, intersectingLines, strutDiameter, drillDepth, nodeOrientationStrategy); //get the most z face and store it as the holder face var surfaces = baseNode.Explode().OfType <Surface>().OrderBy(x => x.PointAtParameter(.5, .5).Z).ToList(); currentNode.holderFacePreTransform = surfaces.Last(); surfaces.Remove(currentNode.holderFacePreTransform); output.Add(currentNode); surfaces.ForEach(x => x.Dispose()); //increment the string ID var i = 0; currentId = currentId + 1; i++; } //from the set of nodes, find the unique struts and use these to update the ids of the struts as well as trim the lines to the correct length // and update the final strut geometry var graphEdges = UniqueStruts(output); foreach (var edge in graphEdges) { var strutA = edge.GeometryEdges.First(); var strutB = edge.GeometryEdges.Last(); var nodeA = strutA.OwnerNode; var nodeB = strutB.OwnerNode; var indA = edge.GeometryEdges.First().OwnerNode.Struts.IndexOf(strutA); var indB = edge.GeometryEdges.Last().OwnerNode.Struts.IndexOf(strutB); var id = nodeA.ID + 'S' + indA.ToString() + "_" + nodeB.ID + 'S' + indB.ToString(); //update each struts id to a combination of both nodes and the strut index foreach (var strut in edge.GeometryEdges) { strut.SetId(id); strut.computeTrimmedLine(nodeA, nodeB); strut.computeStrutGeometry(); } } return(output); }