private List <int> GetRelatedNodes(IEnumerable <int> shapeList, ShapeGraph shapeGraph) { var relatedNodes = new List <int>(); var referingNodes = new List <int>(); var nextLevel = new List <int>(); var processed = new List <int>(); referingNodes.AddRange(GetReferrencedByNodes(shapeList, shapeGraph)); nextLevel.AddRange(referingNodes); while (nextLevel.Count > 0 && !nextLevel.Contains(0)) { foreach (var node in nextLevel) { if (!relatedNodes.Contains(node) && !shapeList.Contains(node)) { relatedNodes.Add(node); } } referingNodes.Clear(); referingNodes.AddRange(GetReferrencedByNodes(nextLevel, shapeGraph).Where(p => p > 0)); nextLevel.Clear(); nextLevel.AddRange(referingNodes.Distinct()); nextLevel.RemoveAll(processed.Contains); processed.AddRange(nextLevel); } return(relatedNodes); }
private List <int> GetRelatedNodes(IEnumerable <int> shapeList, ShapeGraph shapeGraph) { var relatedNodes = new List <int>(); var referingNodes = new List <int>(); var nextLevel = new List <int>(); var processed = new List <int>(); referingNodes.AddRange(GetReferrencedByNodes(shapeList, shapeGraph)); nextLevel.AddRange(referingNodes); while (nextLevel.Count > 0) { foreach (var node in nextLevel) { if (!relatedNodes.Contains(node) && NodeIsPointOrCircle(node)) { relatedNodes.Add(node); } } var referencedBy = new List <int>(); var referencedNodes = GetReferingNodes(referingNodes, shapeGraph).Distinct().ToList(); referencedBy.AddRange(referencedNodes.Where(node => !NodeIsConstraint(node))); referingNodes.Clear(); referingNodes.AddRange(GetReferrencedByNodes(nextLevel, shapeGraph).Where(p => p > 0)); nextLevel.Clear(); nextLevel.AddRange(referingNodes.Concat(referencedBy).Distinct()); nextLevel.RemoveAll(processed.Contains); processed.AddRange(nextLevel); } return(relatedNodes); }
public override void OnCreate() { base.OnCreate(); shapeGraph = target as ShapeGraph; if (shapeGraph is null || !shapeGraph) { return; } window.titleContent = new GUIContent($"{shapeGraph.name}", "The shape graph editor"); }
public static List <List <IShape> > Interpret(IShape start, Rules rules, Control control, uint max) { ShapeGraph sg = new ShapeGraph(start); // Get all the LHSes, so we can search for them in the graph HashSet <Type> lhs = rules.GetAllLHS(); HashSet <(ShapeGraph, Type)> prototypes = new HashSet <(ShapeGraph, Type)>(); foreach (Type t in rules.GetAllLHS()) { // We know that Type t is IShape, which implements a static function // 'Prototype'. This piece of reflection is for calling that static // function. ShapeGraph protoSG = (ShapeGraph)t.GetMethod("Prototype").Invoke(null, new object[] {}); prototypes.Add((protoSG, t)); } List <List <IShape> > progress = new List <List <IShape> >(); // Find all the subgraphs of the shape graph that are prototypes if (max > 0) { for (int i = 0; i < max; ++i) { if (sg.Interpret(prototypes, control).Item2) { progress.Add(sg.GetShapes()); } } } else { bool cont = false; bool intr = false; while (((cont, intr) = sg.Interpret(prototypes, control)).Item1) { if (intr) { progress.Add(sg.GetShapes()); } } } return(progress); }
public static void DrawGraph(Graphics gr, List <IShape> shapes, float factor) { Font symbolfont = new Font("Times New Roman", 14f * factor); Brush brush = new SolidBrush(Color.Black); Brush brush2 = new SolidBrush(Color.White); Pen pen = new Pen(Color.Black, factor / 2f); // Create the shape graph ShapeGraph sg = new ShapeGraph(shapes); HashSet <ShapeGraph.Node> done = new HashSet <ShapeGraph.Node>(); foreach (ShapeGraph.Node node in sg) { Vertex nodeCenter = node.Shape.Center; // Draw lines between the vertices foreach ((ShapeGraph.Node, Attributes)conn in node.Connections) { if (done.Contains(conn.Item1)) { continue; } Vertex connCenter = conn.Item1.Shape.Center; gr.DrawLines(pen, new PointF[] { connCenter, nodeCenter }); } // Draw the point gr.FillEllipse(brush2, new Rectangle((int)(nodeCenter.x - 9 * factor), (int)(nodeCenter.y - 9 * factor), (int)(19 * factor), (int)(19 * factor))); done.Add(node); } DrawSymbols(gr, shapes, symbolfont, brush, 6f * factor, 9f * factor); }
protected override void OnMouseUpAction(Mouse3DPosition mouseData) { Inputs[InputNames.SelectionContainerPipe].Send(NotificationNames.BuildSelections, mouseData); var trimmedEntities = Inputs[InputNames.SelectionContainerPipe].GetData(NotificationNames.GetEntities).Get <List <SceneSelectedEntity> >(); if (trimmedEntities.Count == 0) { return; } InitSession(); Reset(); var newNodes = GetTrimResult(Document, trimmedEntities, mouseData.Point); if (newNodes.Count == 0) { return; } var shapesGraph = new ShapeGraph(); //DocumentShapesGraph(); shapesGraph.SetDocument(Document); shapesGraph.Update(); // remove all referenced constraints var constraints = Document.Root.Children.Where(n => NodeUtils.NodeIsConstraint(n.Value.Index, Document)).ToList(); foreach (var constraint in constraints) { var children = new NodeBuilder(constraint.Value).Node.Children; if (children.Any(child => child.Value.Get <ReferenceInterpreter>().Node.Equals(trimmedEntities[0].Node))) { NodeBuilderUtils.DeleteNode(constraint.Value, Document); } } var nodes = new List <ReferenceInterpreter>(); // remove all referenced points foreach (var child in trimmedEntities[0].Node.Children) { var node = child.Value.Get <ReferenceInterpreter>(); if (node == null) { continue; } nodes.Add(node); } foreach (var nb in newNodes) { var nodeBuilder = new NodeBuilder(nb.Node); nodeBuilder.ExecuteFunction(); AddNodeToTree(nodeBuilder.Node); } if (newNodes.First().FunctionName == FunctionNames.Trim) { NodeUtils.Hide(trimmedEntities[0].Node); } else { NodeBuilderUtils.DeleteNode(trimmedEntities[0].Node, Document); } CommitFinal("Trimmed wire"); RebuildTreeView(); UpdateView(); }
// Draw two parallel lines and delete one of the lines -> constraint should be deleted, as well public void PerpendicularDeleteLineTest() { var document = TestUtils.DefaultsSetup(); var sh = new ShapeGraph(); sh.SetDocument(document); var sketchCreator = new SketchCreator(document, false); var sketchNode = sketchCreator.BuildSketchNode(); document.Transact(); var pointBuilder = new NodeBuilder(document, FunctionNames.Point); pointBuilder[0].Reference = sketchNode; pointBuilder[1].TransformedPoint3D = new Point3D(4, 1, 0); var pointBuilder2 = new NodeBuilder(document, FunctionNames.Point); pointBuilder2[0].Reference = sketchNode; pointBuilder2[1].TransformedPoint3D = new Point3D(2, 3, 0); pointBuilder.ExecuteFunction(); var lineBuilder = new NodeBuilder(document, FunctionNames.LineTwoPoints); lineBuilder[0].Reference = pointBuilder.Node; lineBuilder[1].Reference = pointBuilder2.Node; lineBuilder.ExecuteFunction(); var pointBuilder3 = new NodeBuilder(document, FunctionNames.Point); pointBuilder3[0].Reference = sketchNode; pointBuilder3[1].TransformedPoint3D = new Point3D(4, 5, 0); pointBuilder3.ExecuteFunction(); var lineBuilder2 = new NodeBuilder(document, FunctionNames.LineTwoPoints); lineBuilder2[0].Reference = pointBuilder2.Node; lineBuilder2[1].Reference = pointBuilder3.Node; lineBuilder2.ExecuteFunction(); document.Commit("Drawn line"); document.Transact(); var options = new SketchHinterOptions { ParallelAngle = GeomUtils.DegreesToRadians(5.0), PointRange = 3.0 }; var sketchHinter = new Hinter2D(sketchNode, document, options); sketchHinter.Populate(); sketchHinter.ApplyAlgorithms(lineBuilder2); document.Commit("Perpendicular constraint added"); document.Transact(); Assert.AreEqual(document.Root.Children.Count, 7); Assert.AreEqual(document.Root[6].Get <ShapeFunctionsInterface.Functions.FunctionInterpreter>().Name, Constraint2DNames.PerpendicularFunction); var nodeToDelete = document.Root[3]; NodeBuilderUtils.DeleteNode(nodeToDelete, document); document.Commit("Deleted"); Assert.AreEqual(4, document.Root.Children.Count, "Line is not deleted"); }
private static IEnumerable <int> GetReferingNodes(IEnumerable <int> shapeNodes, ShapeGraph shapeGraph) { var fromMap = new List <int>(); foreach (var sourceNode in shapeNodes) { List <int> value; if (!shapeGraph.ReferringTo.TryGetValue(sourceNode, out value)) { continue; } fromMap.AddRange(value); } return(fromMap); }
private void Awake() { shapeGraph = target as ShapeGraph; }
protected override void OnActivate() { base.OnActivate(); ShapesGraph = new ShapeGraph(); }
// Draw two parallel lines and delete one of the lines -> constraint should be deleted, as well public void CutThroughAllTest() { var document = TestUtils.DefaultsSetup(); var sh = new ShapeGraph(); sh.SetDocument(document); var sketchCreator = new SketchCreator(document, false); var sketchNode = sketchCreator.BuildSketchNode(); document.Transact(); var circleBuilder = TestUtils.Circle(document, sketchNode, new Point3D(0, 0, 0), 10); TestUtils.Circle(document, sketchNode, new Point3D(20, 20, 0), 10); Assert.AreEqual(circleBuilder.LastExecute, true); sketchNode.Children[2].Set <MeshTopoShapeInterpreter>().Shape = AutoGroupLogic.RebuildSketchFace(sketchNode, document); var extrudeBuilder = new NodeBuilder(document, FunctionNames.Extrude); extrudeBuilder[0].Reference = sketchNode; extrudeBuilder[1].Integer = 0; extrudeBuilder[2].Real = 10; extrudeBuilder.ExecuteFunction(); Assert.AreEqual(extrudeBuilder.LastExecute, true); document.Commit("Extrude created"); document.Transact(); var volume = GeomUtils.GetSolidVolume(extrudeBuilder.Shape); Assert.AreEqual(volume, 2 * Math.PI * 1000); Assert.AreEqual(document.Root.Children.Count, 6); var sketchNode2 = sketchCreator.BuildSketchNode(); document.Commit("Added second sketch"); document.Transact(); TestUtils.Circle(document, sketchNode2, new Point3D(0, 0, 0), 5); sketchNode2.Children[2].Set <MeshTopoShapeInterpreter>().Shape = AutoGroupLogic.RebuildSketchFace(sketchNode2, document); document.Commit("Added circle node"); document.Transact(); var cutBuilder = new NodeBuilder(document, FunctionNames.Cut); cutBuilder[0].Reference = sketchNode2; cutBuilder[2].Integer = (int)ExtrusionTypes.MidPlane; cutBuilder[1].Real = 10000; cutBuilder.ExecuteFunction(); Assert.AreEqual(cutBuilder.LastExecute, true); volume = GeomUtils.GetSolidVolume(cutBuilder.Shape); Assert.AreEqual(volume, 2 * Math.PI * 1000 - Math.PI * 250); Assert.AreEqual(document.Root.Children.Count, 10); document.Commit("Added cut"); var expectedReferringTo = new SortedDictionary <int, List <int> > { { 1, new List <int> { 0 } }, { 2, new List <int> { 1 } }, { 3, new List <int> { 0 } }, { 4, new List <int> { 3 } }, { 5, new List <int> { 0 } }, { 7, new List <int> { 6 } }, { 8, new List <int> { 7 } }, { 9, new List <int> { 6, 5 } } }; foreach (var key in expectedReferringTo.Keys) { CollectionAssert.AreEquivalent(expectedReferringTo[key], sh.ReferringTo[key]); } var expectedReferrencedBy = new SortedDictionary <int, List <int> > { { 0, new List <int> { 1, 3, 5 } }, { 1, new List <int> { 2 } }, { 3, new List <int> { 4 } }, { 6, new List <int> { 7, 9 } }, { 7, new List <int> { 8 } } }; foreach (var key in expectedReferrencedBy.Keys) { CollectionAssert.AreEquivalent(expectedReferrencedBy[key], sh.ReferrencedBy[key]); } }
// Draw two parallel lines and delete one of the lines -> constraint should be deleted, as well public void PerpendicularLinesTest() { var document = TestUtils.DefaultsSetup(); var sh = new ShapeGraph(); sh.SetDocument(document); var sketchCreator = new SketchCreator(document, false); var sketchNode = sketchCreator.BuildSketchNode(); document.Transact(); var pointBuilder = new NodeBuilder(document, FunctionNames.Point); pointBuilder[0].Reference = sketchNode; pointBuilder[1].TransformedPoint3D = new Point3D(4, 1, 0); var pointBuilder2 = new NodeBuilder(document, FunctionNames.Point); pointBuilder2[0].Reference = sketchNode; pointBuilder2[1].TransformedPoint3D = new Point3D(2, 3, 0); pointBuilder.ExecuteFunction(); var lineBuilder = new NodeBuilder(document, FunctionNames.LineTwoPoints); lineBuilder[0].Reference = pointBuilder.Node; lineBuilder[1].Reference = pointBuilder2.Node; lineBuilder.ExecuteFunction(); var pointBuilder3 = new NodeBuilder(document, FunctionNames.Point); pointBuilder3[0].Reference = sketchNode; pointBuilder3[1].TransformedPoint3D = new Point3D(4, 5, 0); pointBuilder3.ExecuteFunction(); var lineBuilder2 = new NodeBuilder(document, FunctionNames.LineTwoPoints); lineBuilder2[0].Reference = pointBuilder2.Node; lineBuilder2[1].Reference = pointBuilder3.Node; lineBuilder2.ExecuteFunction(); document.Commit("Drawn line"); document.Transact(); var options = new SketchHinterOptions { ParallelAngle = GeomUtils.DegreesToRadians(5.0), PointRange = 3.0 }; var sketchHinter = new Hinter2D(sketchNode, document, options); sketchHinter.Populate(); sketchHinter.ApplyAlgorithms(lineBuilder2); document.Commit("Perpendicular constraint added"); document.Transact(); Assert.AreEqual(document.Root.Children.Count, 7); Assert.AreEqual(document.Root[6].Get <ShapeFunctionsInterface.Functions.FunctionInterpreter>().Name, Constraint2DNames.PerpendicularFunction); var expectedReferringTo = new SortedDictionary <int, List <int> > { { 1, new List <int> { 0 } }, { 2, new List <int> { 0 } }, { 3, new List <int> { 1, 2 } }, { 4, new List <int> { 0 } }, { 5, new List <int> { 4, 2 } }, { 6, new List <int> { 3, 5 } } }; foreach (var key in expectedReferringTo.Keys) { CollectionAssert.AreEquivalent(expectedReferringTo[key], sh.ReferringTo[key]); } var expectedReferrencedBy = new SortedDictionary <int, List <int> > { { 0, new List <int> { 1, 2, 4 } }, { 1, new List <int> { 3 } }, { 2, new List <int> { 3, 5 } }, { 3, new List <int> { 6 } }, { 4, new List <int> { 5 } }, { 5, new List <int> { 6 } } }; foreach (var key in expectedReferrencedBy.Keys) { CollectionAssert.AreEquivalent(expectedReferrencedBy[key], sh.ReferrencedBy[key]); } }
// Draw two parallel lines and delete one of the lines -> constraint should be deleted, as well public void CircleArcTest() { var document = TestUtils.DefaultsSetup(); var sh = new ShapeGraph(); sh.SetDocument(document); var sketchCreator = new SketchCreator(document, false); var sketchNode = sketchCreator.BuildSketchNode(); document.Transact(); TestUtils.Circle(document, sketchNode, new Point3D(10, 10, 0), 5); TestUtils.Arc(document, sketchNode, new Point3D(0, 0, 0), new Point3D(0, 5, 0), new Point3D(5, 0, 0)); document.Commit("Drawn circle and arc"); Assert.AreEqual(document.Root.Children.Count, 7); var expectedReferringTo = new SortedDictionary <int, List <int> > { { 1, new List <int> { 0 } }, { 2, new List <int> { 1 } }, { 3, new List <int> { 0 } }, { 4, new List <int> { 0 } }, { 5, new List <int> { 0 } }, { 6, new List <int> { 3, 4, 5 } } }; foreach (var key in expectedReferringTo.Keys) { CollectionAssert.AreEquivalent(expectedReferringTo[key], sh.ReferringTo[key]); } var expectedReferrencedBy = new SortedDictionary <int, List <int> > { { 0, new List <int> { 1, 3, 4, 5 } }, { 1, new List <int> { 2 } }, { 3, new List <int> { 6 } }, { 4, new List <int> { 6 } }, { 5, new List <int> { 6 } } }; foreach (var key in expectedReferrencedBy.Keys) { CollectionAssert.AreEquivalent(expectedReferrencedBy[key], sh.ReferrencedBy[key]); } }
public override void OnPopulate() { base.OnPopulate(); _graph = Hinter2D.Document.Root.Get <DocumentContextInterpreter>().ShapesGraph; }