예제 #1
0
        public void TestParseTwoInputsAndWire()
        {
            List <Sketch.Shape> modifiedShapes;

            // Add a wire
            Sketch.Substroke wireSub = AddNewStroke(new Tuple <double, double>(0.2, 0.2), new Tuple <double, double>(0.8, 0.8));
            Sketch.Shape     wire    = sketch.MakeNewShapeFromSubstroke(out modifiedShapes, wireSub, Domain.LogicDomain.WIRE, 1);
            wire.Name = "wire_0";

            // Add the left input and connect it to the wire
            Sketch.Substroke firstSub   = AddNewStroke(new Tuple <double, double>(0.0, 0.0), new Tuple <double, double>(0.1, 0.1));
            Sketch.Shape     firstLabel = sketch.MakeNewShapeFromSubstroke(out modifiedShapes, firstSub, Domain.LogicDomain.TEXT, 1);
            firstLabel.Name = "A";
            wire.Endpoints[0].ConnectedShape = firstLabel;
            sketch.connectShapes(firstLabel, wire);

            // Add the right input and connect it to the wire
            Sketch.Substroke secondSub   = AddNewStroke(new Tuple <double, double>(0.9, 0.9), new Tuple <double, double>(1.0, 1.0));
            Sketch.Shape     secondLabel = sketch.MakeNewShapeFromSubstroke(out modifiedShapes, secondSub, Domain.LogicDomain.TEXT, 1);
            secondLabel.Name = "B";
            wire.Endpoints[1].ConnectedShape = secondLabel;
            sketch.connectShapes(secondLabel, wire);

            Assert.IsTrue(parser.SuccessfullyParse(sketch), "parser should be able to parse sketch with a wire connecting two labels");
        }
예제 #2
0
        /// <summary>
        /// Break any shapes which are only partially in this selection
        /// </summary>
        private void BreakShapes()
        {
            foreach (Stroke stroke in resizedStrokes)
            {
                Sketch.Substroke substroke = inkSketch.GetSketchSubstrokeByInk(stroke);
                Sketch.Shape     parent    = substroke.ParentShape;

                if (parent != null && !oldShapesToNewShapes.ContainsKey(parent))
                {
                    bool breakShape = false;
                    List <Sketch.Substroke> substrokes = new List <Sketch.Substroke>();

                    foreach (Sketch.Substroke sub in parent.Substrokes)
                    {
                        if (!resizedStrokes.Contains(inkSketch.GetInkStrokeBySubstroke(sub)))
                        {
                            breakShape = true;
                        }
                        else
                        {
                            substrokes.Add(sub);
                        }
                    }

                    if (breakShape)
                    {
                        Sketch.Shape newShape = inkSketch.Sketch.BreakOffShape(parent, substrokes);
                        oldShapesToNewShapes[newShape] = parent;
                    }
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Constructor for StrokeInfoForm
        /// </summary>
        /// <param name="strokefeatures"></param> a FeatureStroke
        /// <param name="sketchFeatures"></param> a FeatureSketch
        /// <param name="inkStroke"></param> a System.Windows.Controls Stroke
        /// <param name="substroke"></param> a Sketch Substroke
        public StrokeInfoWindow(FeatureStroke strokefeatures, FeatureSketch sketchFeatures, Stroke inkStroke, Sketch.Substroke substroke)
        {
            InitializeComponent();

            inkMovedX = 0;
            inkMovedY = 0;
            scale     = 2.0f;

            mInkCanvas.Width  = Width / 2 - 20;
            mInkCanvas.Height = Height - 20;

            mInkCanvas.StrokeCollected += new InkCanvasStrokeCollectedEventHandler(mInkCanvas_StrokeCollected);

            mSketchFeatures = sketchFeatures;
            mStrokeFeatures = strokefeatures;
            mInkStroke      = inkStroke;
            mSubstroke      = substroke;

            mInkCanvas.Strokes.Add(mInkStroke);

            Red   = Color.FromArgb(255, 255, 0, 0);
            Green = Color.FromArgb(255, 0, 255, 0);
            Blue  = Color.FromArgb(255, 0, 0, 255);
            Black = Color.FromArgb(255, 0, 0, 0);

            mInkCanvas.Strokes[0].DrawingAttributes.Color = Red;
            populateListView();
        }
예제 #4
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="sketch">SketchPanel to add a label to</param>
        /// <param name="inkStrokes">InkOverlay strokes</param>
        /// <param name="inkStrokes">A StrokeCollection strokes</param>
        /// <param name="label">Label to apply</param>

        public ApplyLabelCmd(SketchPanel sketch, StrokeCollection inkStrokes,
                             ShapeType labelType, bool userSpecifiedGroup = true, bool userSpecifiedLabel = true, int tagNumber = int.MinValue)
        {
            isUndoable = true;

            this.sketchPanel        = sketch;
            this.inkStrokes         = inkStrokes;
            this.userSpecifiedGroup = userSpecifiedGroup;
            this.userSpecifiedLabel = userSpecifiedLabel;
            this.tagNumber          = tagNumber;
            this.labelType          = labelType;

            // Save the original labels of the substrokes
            originalLabels   = new Dictionary <Sketch.Shape, Tuple <ShapeType, StrokeCollection> >();
            unlabeledStrokes = new StrokeCollection();

            foreach (Stroke stroke in inkStrokes)
            {
                // If the stroke is classified, save its original shape.
                Sketch.Substroke sub = sketchPanel.InkSketch.GetSketchSubstrokeByInk(stroke);
                if (sub.ParentShape != null)
                {
                    if (!originalLabels.ContainsKey(sub.ParentShape))
                    {
                        originalLabels[sub.ParentShape] = new Tuple <ShapeType, StrokeCollection>(sub.ParentShape.Type, new StrokeCollection());
                    }
                    originalLabels[sub.ParentShape].Item2.Add(stroke);
                }
                else // Record that it wasn't labeled.
                {
                    unlabeledStrokes.Add(stroke);
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="sketch">SketchPanel to add a label to</param>
        /// <param name="inkStrokes">InkOverlay strokes</param>
        /// <param name="inkStrokes">A StrokeCollection strokes</param>
        /// <param name="label">Label to apply</param>
        public ApplyLabelCmd(SketchPanel sketch, StrokeCollection inkStrokes,
                             string label, bool userSpecifiedGroup = true, bool userSpecifiedLabel = true)
        {
            isUndoable = false;

            this.sketchPanel        = sketch;
            this.label              = label;
            this.inkStrokes         = inkStrokes;
            this.userSpecifiedGroup = userSpecifiedGroup;
            this.userSpecifiedLabel = userSpecifiedLabel;
            labelColor              = LogicDomain.getType(label).Color;

            // Save the original labels of the substrokes
            origLabels       = new Dictionary <string, Data.Pair <ShapeType, StrokeCollection> >();
            unlabeledStrokes = new StrokeCollection();

            foreach (Stroke stroke in inkStrokes)
            {
                Sketch.Substroke sub = sketchPanel.InkSketch.GetSketchSubstrokeByInk(stroke);

                if (sub.ParentShape != null)
                {
                    if (!origLabels.ContainsKey(sub.ParentShape.Name))
                    {
                        origLabels[sub.ParentShape.Name] = new Data.Pair <ShapeType, StrokeCollection>(sub.ParentShape.Type, new StrokeCollection());
                    }
                    origLabels[sub.ParentShape.Name].B.Add(stroke);
                }
                else
                {
                    unlabeledStrokes.Add(stroke);
                }
            }
        }
예제 #6
0
        /// <summary>
        /// Look at any out-of-context shapes in the sketch and refine them by
        /// removing a substroke. (We may want to try removing more strokes later).
        ///
        /// We assume that the substroke should be a wire, and we remove it
        /// from the shape. Then we regroup the shape without the substroke,
        /// re-recognize it, and check to see if it makes sense. If it does,
        /// keep it. If not, try again with a different substroke.
        /// </summary>
        public void StrokeShedRefine(Featurefy.FeatureSketch featureSketch)
        {
            foreach (Sketch.Shape shape in featureSketch.Sketch.Shapes)
            {
                bool valid = _domain.IsProperlyConnected(shape);

                // If the shape wansn't specified by the user, doesn't fit
                // its context, and is a gate
                if ((!shape.AlreadyGrouped) &&
                    (!valid || (shape.Probability < _thresholdProbability)) &&
                    (shape.Classification == LogicDomain.GATE_CLASS))
                {
                    float            bestProb      = 0F;
                    Sketch.Substroke bestSubstroke = null;

                    foreach (Sketch.Substroke substroke in shape.Substrokes)
                    {
                        // See how helpful it is to let the shape
                        // shed this stroke
                        float shedProb = strokeShedHelpfulness(shape, substroke, featureSketch);
                        if (shedProb > bestProb)
                        {
                            bestProb      = shedProb;
                            bestSubstroke = substroke;
                        }
                    }

                    // If hypotheticaly shedding one of the substrokes
                    // enhanced the recognition of the shape, do it for real
                    //if (bestProb > shape.Probability) // NOT SURE IF WE WANT TO KEEP THIS
                    shedStroke(shape, bestSubstroke, featureSketch);
                }
            }
        }
예제 #7
0
        /// <summary>
        /// Find all the substrokes that compose one subgroup
        /// within a given shape, starting with a given
        /// seed substroke, and store these substrokes in a
        /// given list.
        ///
        /// A subgroup is defined as a set of adjacent substrokes.
        /// This function uses a depth first search.
        ///
        /// NOTE: the shape must contain the given substroke
        /// </summary>
        /// <param name="seedSubstroke">A substroke in the desired subgroup</param>
        /// <param name="shape">The shape to investigate</param>
        /// <param name="adjacentSubstrokes">The list to store the desired substrokes</param>
        /// <param name="adjacency">The adjacency matrix for strokes</param>
        private void oneShapeSubgroup(Sketch.Substroke seedSubstroke,
                                      Sketch.Shape shape, List <Sketch.Substroke> adjacentSubstrokes, Dictionary <Guid, Dictionary <Guid, int> > adjacency)
        {
            Debug.Assert(shape.SubstrokesL.Contains(seedSubstroke), "Shape does not contain given substroke");

            // Make a list of adjacent substrokes not yet accounted for
            List <Sketch.Substroke> additionalSubstrokes = new List <Sketch.Substroke>();

            foreach (Sketch.Substroke substroke in shape.Substrokes)
            {
                if ((!adjacentSubstrokes.Contains(substroke)) &&
                    ((seedSubstroke.Id == substroke.Id) || (adjacency[seedSubstroke.Id][substroke.Id] > 0)))
                {
                    additionalSubstrokes.Add(substroke);
                }
            }

            // Recurse on each of the found adjacent substrokes
            if (additionalSubstrokes.Count > 0)
            {
                foreach (Sketch.Substroke substroke in additionalSubstrokes)
                {
                    adjacentSubstrokes.Add(substroke);
                }
                foreach (Sketch.Substroke substroke in additionalSubstrokes)
                {
                    oneShapeSubgroup(substroke, shape, adjacentSubstrokes, adjacency);
                }
            }
        }
예제 #8
0
        public void FeatureSketchCreationBehavior()
        {
            /*
             * Problem description:
             * When a sketch contains duplicated points, the creation of a FeatureSketch
             * may delete those points.
             */

            Sketch.Sketch sketch = Sketches.newValidSketch();

            // Duplicate a point in the sketch
            Sketch.Shape shape = sketch.Shapes[0];

            List <Sketch.Point> points = new List <Sketch.Point>(shape.Substrokes[0].Points);

            points.Add(points[points.Count - 1]);

            Sketch.Substroke substroke = new Sketch.Substroke(points);
            sketch.AddStroke(new Sketch.Stroke(substroke));
            shape.AddSubstroke(substroke);

            Sketch.Sketch clone = sketch.Clone();

            Assert.IsTrue(sketch.Equals(clone), "Sketch is not equal to its clone");

            Featurefy.FeatureSketch featureSketch = newValidFeatureSketch(new Sketch.Project(sketch));

            Assert.IsTrue(sketch.Equals(clone), "FeatureSketch creation modified original sketch");
        }
예제 #9
0
        /// <summary>
        /// Main constructor of the subcircuit window. Takes in a project that it will wrap into an inkcanvas sketch
        /// in order to display.
        /// </summary>
        /// <param name="subSketch"></param>
        public MainWindow(ref Sketch.Project subSketch)
        {
            try
            {
                InitializeComponent();
            }
            catch (Exception ex)
            {
                // Log error
                System.Console.WriteLine(ex.InnerException.Message);
                //System.Console.WriteLine(ex.ListTrace);
            }

            // Set up notes panel
            this.subSketch        = subSketch;
            WrapperSketch         = new InkToSketchWPF.InkCanvasSketch(new InkCanvas());
            WrapperSketch.project = subSketch;
            this.WrapperSketch.ClearButNotSketch();
            // Makes the ink to display
            WrapperSketch.CreateInkStrokesFromSketch();

            //Set up the ink holder
            this.inkCanvas        = WrapperSketch.InkCanvas;
            this.inkCanvas.Height = dockPanel.Height;
            this.inkCanvas.Width  = dockPanel.Width;

            //The dockPanel is in a view box, which means that it will scale (and scale its children)
            //to fit the screen.
            TextBlock helpText = new TextBlock();

            helpText.Text     = "You can click a sub-circuit if one exists to view it";
            helpText.FontSize = 16;

            dockPanel.Children.Clear();
            dockPanel.Children.Add(this.inkCanvas);
            this.inkCanvas.Children.Add(helpText);

            //Actually color the strokes on the inkcanvas according to the recognition
            //This is valid because only simulatable circuits can be viewed here
            foreach (System.Windows.Ink.Stroke inkStroke in this.inkCanvas.Strokes)
            {
                Sketch.Substroke substroke = (Sketch.Substroke)WrapperSketch.GetSketchSubstrokeByInk(inkStroke);
                Domain.ShapeType label     = substroke.Type;

                Color color = label.Color;

                inkStroke.DrawingAttributes.Color = color;
            }

            //Draws the inkcanvas with the new colors
            this.WrapperSketch.InkCanvas.InvalidateVisual();
            this.inkCanvas.UpdateLayout();



            // Set Editing Modes
            inkCanvas.EditingMode         = InkCanvasEditingMode.None;
            inkCanvas.EditingModeInverted = InkCanvasEditingMode.None;
            inkCanvas.StylusDown         += new StylusDownEventHandler(inkCanvas_StylusDown);
        }
예제 #10
0
        private static void WriteSubstroke(Sketch.Substroke substroke, XmlTextWriter xmlDocument)
        {
            string[] substrokeAttributeNames  = substroke.XmlAttrs.getAttributeNames();
            object[] substrokeAttributeValues = substroke.XmlAttrs.getAttributeValues();

            Sketch.Point[] points = substroke.Points;
            int            length;
            int            i;

            xmlDocument.WriteStartElement("shape");

            // Write all the attributes
            length = substrokeAttributeNames.Length;
            for (i = 0; i < length; ++i)
            {
                if (substrokeAttributeValues[i] != null)
                {
                    xmlDocument.WriteAttributeString(substrokeAttributeNames[i], substrokeAttributeValues[i].ToString());
                }
            }

            // Write the point references
            length = points.Length;
            for (i = 0; i < length; ++i)
            {
                SaveToXML.WritePointReference(points[i], xmlDocument);
            }

            xmlDocument.WriteEndElement();
        }
        /// <summary>
        /// Applies a label to a group of substrokes.
        /// </summary>
        public override bool Execute()
        {
            // Add the new stroke to the sketch
            inkSketch.AddStroke(newStroke);

            // Update connections
            Sketch.Substroke newSubstroke = inkSketch.GetSketchSubstrokeByInk(newStroke);
            changedShape.AddSubstroke(newSubstroke);
            oldLocation.ConnectedShape = changedShape;
            newSubstroke.Endpoints[0].ConnectedShape = changedShape;
            newSubstroke.Endpoints[1].ConnectedShape = shapeAtNewLoc;

            // Add the new wire to the old wire's shape
            inkSketch.Sketch.connectShapes(changedShape, changedShape); // wires connected to themselves indicates an internal connection
            inkSketch.Sketch.connectShapes(changedShape, shapeAtNewLoc);
            changedShape.AlreadyLabeled = true;

            // Pre-emptive merging! Helps us undo.
            if (newIsWire)
            {
                inkSketch.Sketch.mergeShapes(changedShape, shapeAtNewLoc);
            }

            // Regroup everything so highlighting/labels are correctly updated
            Handle(changedShape);
            Regroup(new List <Sketch.Shape> {
                changedShape
            });
            return(true);
        }
예제 #12
0
        /// <summary>
        /// Take a substroke and add it to a given shape.
        /// </summary>
        /// <param name="shape">The shape that steals</param>
        /// <param name="substroke">The substroke to steal</param>
        private void stealStroke(Sketch.Shape strokeThief, Sketch.Substroke strokeToSteal, Featurefy.FeatureSketch featureSketch)
        {
            if (strokeToSteal != null)
            {
                // Move the substroke we're trying to steal
                Sketch.Shape strokeLoser = strokeToSteal.ParentShape;
                strokeLoser.RemoveSubstroke(strokeToSteal);
                strokeThief.AddSubstroke(strokeToSteal);

                // Update what these recombinant shapes and their
                // connected shapes are connected to
                List <Sketch.Shape> changedShapes = new List <Sketch.Shape>();
                changedShapes.Add(strokeThief);
                changedShapes.Add(strokeLoser);
                _connector.recomputeConnectedShapes(changedShapes, featureSketch.Sketch);

                // Also update the substroke to match its new shape
                strokeToSteal.Classification = "Gate";

                // See if the stroke thief is a valid shape
                _sketchRecognizer.recognize(strokeThief, featureSketch);

                // See if the stroke loser is a valid shape
                if (strokeLoser.SubstrokesL.Count > 0)
                {
                    _sketchRecognizer.recognize(strokeLoser, featureSketch);
                }
            }
        }
예제 #13
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="order"></param>
        /// <param name="stroke"></param>
        public TimeToNext(SortedList <ulong, Sketch.Substroke> order, Sketch.Substroke stroke)
            : base("Time to Next Stroke", Scope.Multiple_Static)
        {
            m_Normalizer = Compute.StrokeTimeNormalizer;

            int index = order.IndexOfValue(stroke);

            if (index == order.Count - 1)
            {
                m_Value = 0.0;
            }
            else
            {
                ulong endCurrent = 0;
                ulong startNext  = 0;

                foreach (KeyValuePair <ulong, Sketch.Substroke> pair in order)
                {
                    if (pair.Value == stroke)
                    {
                        Sketch.Point[] points = pair.Value.Points;
                        endCurrent = points[points.Length - 1].Time;
                    }
                    else if (order.IndexOfKey(pair.Key) == index + 1)
                    {
                        startNext = pair.Key;
                    }
                }

                m_Value = (double)(startNext - endCurrent);
            }
        }
예제 #14
0
        public void testWriteXML()
        {
            Sketch.Sketch sketch = new Sketch.Sketch();
            sketch.XmlAttrs.Id = System.Guid.NewGuid();

            Sketch.Shape shape = new Sketch.Shape();
            shape.XmlAttrs.Id   = System.Guid.NewGuid();
            shape.XmlAttrs.Name = "shapeName";
            shape.XmlAttrs.Type = "shape";
            shape.XmlAttrs.Time = "111";

            Sketch.Stroke    stroke;
            Sketch.Substroke substroke;
            Sketch.Point     point;

            ulong h;
            ulong i;
            ulong j;

            for (h = 0; h < 3; ++h)
            {
                stroke               = new Sketch.Stroke();
                stroke.XmlAttrs.Id   = System.Guid.NewGuid();
                stroke.XmlAttrs.Name = "strokeName";
                stroke.XmlAttrs.Type = "stroke";
                stroke.XmlAttrs.Time = h;

                for (i = 0; i < 5; ++i)
                {
                    substroke               = new Sketch.Substroke();
                    substroke.XmlAttrs.Id   = System.Guid.NewGuid();
                    substroke.XmlAttrs.Name = "substrokeName";
                    substroke.XmlAttrs.Type = "substroke";
                    substroke.XmlAttrs.Time = i;

                    for (j = 0; j < 10; ++j)
                    {
                        point                   = new Sketch.Point();
                        point.XmlAttrs.X        = (float)random.NextDouble();
                        point.XmlAttrs.Y        = (float)random.NextDouble();
                        point.XmlAttrs.Id       = System.Guid.NewGuid();
                        point.XmlAttrs.Pressure = (ushort)(random.NextDouble() * 256);
                        point.XmlAttrs.Name     = "point" + j.ToString();
                        point.XmlAttrs.Time     = j;

                        substroke.AddPoint(point);
                    }
                    stroke.AddSubstroke(substroke);
                    shape.AddSubstroke(substroke);
                }
                sketch.AddStroke(stroke);
            }
            sketch.AddShape(shape);

            sketch.Strokes[0].SplitStrokeAt(new int[] { 7, 14, 16, 21 });

            ConverterXML.MakeXML xml = new ConverterXML.MakeXML(sketch);
            xml.WriteXML("test.xml");
        }
예제 #15
0
 /// <summary>
 /// Returns the stroke to it's original drawing attributes
 /// </summary>
 /// <param name="stroke"></param>
 private void unhighlightStroke(Stroke stroke)
 {
     if (sketchPanel.InkCanvas.Strokes.Contains(stroke))
     {
         Sketch.Substroke substroke = sketchPanel.InkSketch.GetSketchSubstrokeByInk(stroke);
         stroke.DrawingAttributes.Color = substroke.Type.Color;
     }
 }
예제 #16
0
        private static void WriteSubstrokeReference(Sketch.Substroke substroke, XmlTextWriter xmlDocument)
        {
            xmlDocument.WriteStartElement("arg");

            xmlDocument.WriteAttributeString("type", "substroke");
            xmlDocument.WriteString(substroke.XmlAttrs.Id.ToString());

            xmlDocument.WriteEndElement();
        }
예제 #17
0
        /// <summary>
        /// When we remove the stylus, we make our selection
        /// </summary>
        /// <param name="sender">Ignored :(</param>
        /// <param name="e">MouseEventArgs, contains mouse location</param>
        public override void InkCanvas_StylusUp(object sender, System.Windows.Input.StylusEventArgs e)
        {
            if (!subscribed || e.Inverted || !makingSelection)
            {
                return;
            }

            // Update the rectangle one more time
            BoxSelect_StylusMove(sender, e);

            // Select the strokes under the box
            StrokeCollection boxSelection = sketchPanel.InkCanvas.Strokes.HitTest(currentRect, 70);

            // Look for a stroke directly below us
            System.Windows.Point point          = e.GetPosition(sketchPanel.InkCanvas);
            Sketch.Substroke     substrokeBelow = sketchPanel.InkSketch.Sketch.substrokeAtPoint(point.X, point.Y, SEARCH_RADIUS);

            if (boxSelection.Count > 0)
            {
                selection = boxSelection;
            }
            else if (substrokeBelow != null)
            {
                Stroke singleStroke = sketchPanel.InkSketch.GetInkStrokeBySubstroke(substrokeBelow);
                if (selection.Contains(singleStroke))
                {
                    if (debug)
                    {
                        System.Console.WriteLine("Stroke being removed");
                    }
                    selection.Remove(singleStroke);
                }
                else
                {
                    if (debug)
                    {
                        System.Console.WriteLine("Stroke being added");
                    }
                    selection.Add(singleStroke);
                }
            }
            else if (substrokeBelow == null && boxSelection.Count == 0)
            {
                selection.Clear();
            }

            Selection            = selection;
            selectBox.Visibility = System.Windows.Visibility.Hidden;
            sketchPanel.InkCanvas.Children.Remove(selectBox);

            if (makingSelection)
            {
                selectionMade = selection.Count > 0;
            }
            makingSelection = false;
        }
예제 #18
0
        public void AddStroke(Sketch.Substroke sub)
        {
            for (int i = 0; i < sub.PointsL.Count; i++)
            {
                _points.Add(new GenericPoint(sub.PointsL[i].X, sub.PointsL[i].Y, false));
            }
            _points.Add(new GenericPoint(sub.PointsL[sub.PointsL.Count - 1].X, sub.PointsL[sub.PointsL.Count - 1].Y, true));

            update();
        }
예제 #19
0
        /// <summary>
        /// Remove a substroke from a shape and turn it into a wire, and
        /// update the remains of the shape. If the shape ends up breaking
        /// into multiple shapes upon removing the substroke, the function
        /// returns a a list of these broken off shapes. If the shape
        /// originally had one substroke and therefore ends up with none,
        /// the empty shape gets removed from the sketch.
        ///
        /// ASSUMPTIONS:
        ///   * The removed substroke should be a wire.
        ///   * The shape has at least 1 substroke
        /// </summary>
        /// <param name="shape">The shape that sheds</param>
        /// <param name="substroke">The substroke to shed</param>
        /// <returns>A list of any shapes that were broken off of the
        /// original shape in the process.</returns>
        private List <Sketch.Shape> shedStroke(Sketch.Shape shape, Sketch.Substroke substroke, Featurefy.FeatureSketch featureSketch)
        {
            if (substroke == null)
            {
                return(null);
            }
            else
            {
                Debug.Assert(shape.SubstrokesL.Contains(substroke), "The substroke is not in the shape!");

                // Change substroke classification to wire.
                substroke.Classification = "Wire";

                // Remove substroke from the shape, and make it a new shape.
                List <Sketch.Substroke> strokesToShed = new List <Sketch.Substroke>();
                strokesToShed.Add(substroke);
                Sketch.Shape newShape = featureSketch.Sketch.BreakOffShape(shape, strokesToShed);

                // Recognize the new shape.
                _sketchRecognizer.recognize(newShape, featureSketch);

                // Check if removing the substroke split the shape into smaller, unconnected shapes
                List <Sketch.Shape> brokenOffShapes = maybeBreakOffShapes(shape, featureSketch.Sketch);

                // Reconnect the shape(s) and the new, broken-off shape.
                List <Sketch.Shape> changedShapes = new List <Sketch.Shape>();
                changedShapes.Add(shape);
                changedShapes.Add(newShape);
                foreach (Sketch.Shape subshape in brokenOffShapes)
                {
                    changedShapes.Add(subshape);
                }
                _connector.recomputeConnectedShapes(changedShapes, featureSketch.Sketch);

                // If the shape no longer exists, remove it.
                if (shape.SubstrokesL.Count == 0)
                {
                    featureSketch.Sketch.RemoveShape(shape);
                }

                // Otherwise, rerecognize the new version of the shape(s)
                else
                {
                    _sketchRecognizer.recognize(shape, featureSketch);
                    foreach (Sketch.Shape subshape in brokenOffShapes)
                    {
                        _sketchRecognizer.recognize(subshape, featureSketch);
                    }
                }

                // Add shedded shape to the end of the list of broken off shapes
                brokenOffShapes.Add(newShape);
                return(brokenOffShapes);
            }
        }
예제 #20
0
        private void menuStrokeInformation_Click(object sender, EventArgs e)
        {
            Sketch.Sketch sketch         = sketchPanel.Sketch;
            FeatureSketch sketchFeatures = new FeatureSketch(ref sketch);

            Microsoft.Ink.Strokes         selected = sketchPanel.InkSketch.Ink.Strokes;
            Microsoft.Ink.Stroke          s        = selected[selected.Count - 1];
            Sketch.Substroke              ss       = sketchPanel.InkSketch.GetSketchSubstrokeByInkId(s.Id);
            StrokeInfoForm.strokeInfoForm sif      = new StrokeInfoForm.strokeInfoForm(sketchFeatures.GetFeatureStrokeByStrokeGUID(ss.Id), sketchFeatures, s, ss);
            sif.Show();
        }
예제 #21
0
        public void TestParseSingleWire()
        {
            List <Sketch.Shape> modifiedShapes;

            // Make a single substroke into a wire
            Sketch.Substroke substroke = AddNewStroke();
            Sketch.Shape     wire      = sketch.MakeNewShapeFromSubstroke(out modifiedShapes, substroke, Domain.LogicDomain.WIRE, 1);
            wire.Name = "wire_0";

            Assert.IsFalse(parser.SuccessfullyParse(sketch), "parser should not be able to parse sketch with single wire");
        }
예제 #22
0
        /// <summary>
        /// Find the number of times substrokes 1 and 2 touch.
        /// </summary>
        /// <param name="stroke1">First substroke</param>
        /// <param name="stroke2">Second substroke</param>
        /// <returns>Number of times substrokes 1 and 2 touch.</returns>
        private static int Adjacent(Sketch.Substroke stroke1, Sketch.Substroke stroke2)
        {
            double totaldistance = 0;
            int    count         = 0;

            for (int i = 0; i < stroke1.PointsL.Count - 2; i++)
            {
                totaldistance += stroke1.Points[i].distance(stroke1.Points[i + 1]);
                count++;
            }
            for (int i = 0; i < stroke2.PointsL.Count - 2; i++)
            {
                totaldistance += stroke2.Points[i].distance(stroke2.Points[i + 1]);
                count++;
            }
            double avgDistance = totaldistance / count * 10;
            int    numTouch    = 0;

            foreach (Sketch.Point endpoint in stroke1.Endpoints)
            {
                foreach (Sketch.Point point in stroke2.Points)
                {
                    if (endpoint.distance(point) < avgDistance)
                    {
                        numTouch++;
                        break;
                    }
                }
            }
            foreach (Sketch.Point endpoint in stroke2.Endpoints)
            {
                foreach (Sketch.Point point in stroke1.Points)
                {
                    if (endpoint.distance(point) < avgDistance)
                    {
                        numTouch++;
                        break;
                    }
                }
            }
            foreach (Sketch.Point endpoint1 in stroke1.Endpoints)
            {
                foreach (Sketch.Point endpoint2 in stroke2.Endpoints)
                {
                    if (endpoint1.distance(endpoint2) < avgDistance)
                    {
                        numTouch--;
                    }
                }
            }
            return(numTouch);
        }
예제 #23
0
        /// <summary>
        /// Applies a label to a group of substrokes.
        /// </summary>
        public override bool UnExecute()
        {
            List <Sketch.Shape> modifiedShapes;

            foreach (System.Windows.Ink.Stroke stroke in labeledStrokes)
            {
                stroke.DrawingAttributes.Color = labelColor;
                Sketch.Substroke sub = sketchPanel.InkSketch.GetSketchSubstrokeByInk(stroke);
                sketchPanel.InkSketch.Sketch.MakeNewShapeFromSubstroke(out modifiedShapes, sub, label);
            }

            return(true);
        }
예제 #24
0
        /// <summary>
        /// Updates the cursor inside the selection box to display whether stylus down will move the strokes
        /// or remove a stroke
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void InkCanvas_StylusInAirMove(object sender, System.Windows.Input.StylusEventArgs e)
        {
            // If there are no strokes below us, use the automatic cursors.
            // Otherwise, use the pen cursor.
            System.Windows.Point point          = e.GetPosition(sketchPanel.InkCanvas);
            Sketch.Substroke     substrokeBelow = sketchPanel.InkSketch.Sketch.substrokeAtPoint(point.X, point.Y, SEARCH_RADIUS);

            if (substrokeBelow != null)
            {
                sketchPanel.UseCustomCursor = true;
                sketchPanel.Cursor          = System.Windows.Input.Cursors.Pen;
            }
        }
예제 #25
0
        /// <summary>
        /// Creates a Substroke from Microsoft point data
        /// </summary>
        /// <param name="stroke"></param>
        /// <returns></returns>
        static public Sketch.Substroke MakeSubstroke(Microsoft.Ink.Stroke stroke)
        {
            Sketch.Point[] SketchPoints = stripStroke(stroke);
            Sketch.XmlStructs.XmlShapeAttrs XmlAttrs = new Sketch.XmlStructs.XmlShapeAttrs(true);
            XmlAttrs.Time      = SketchPoints[0].Time;
            XmlAttrs.Source    = "InkOverlay";
            XmlAttrs.PenHeight = stroke.DrawingAttributes.Height;
            XmlAttrs.PenTip    = stroke.DrawingAttributes.PenTip.ToString();
            XmlAttrs.PenWidth  = stroke.DrawingAttributes.Width;
            XmlAttrs.Color     = stroke.DrawingAttributes.Color.ToArgb();
            Sketch.Substroke s = new Sketch.Substroke(SketchPoints, XmlAttrs);

            return(s);
        }
예제 #26
0
        /// <summary>
        /// Removes a labeled shape from a Sketch.
        /// </summary>
        public override bool Execute()
        {
            bool success = false;

            foreach (Stroke stroke in labeledStrokes)
            {
                Sketch.Substroke sub = sketchPanel.InkSketch.GetSketchSubstrokeByInk(stroke);
                labeledShape = sub.RemoveLabel(label);

                if (this.labeledShape != null && this.labeledShape.Substrokes.Length == 0)
                {
                    success = sketchPanel.InkSketch.Sketch.RemoveShape(this.labeledShape);
                }
            }
            return(success);
        }
예제 #27
0
        private void Create2StrokeLR_new(Gate name, GatePart leftPart, GatePart rightPart)
        {
            if (m_InkOverlay.Ink.Strokes.Count != 2)
            {
                MessageBox.Show("Incorrect # of strokes present");
                return;
            }

            Rectangle b0 = m_InkOverlay.Ink.Strokes[0].GetBoundingBox();
            Rectangle b1 = m_InkOverlay.Ink.Strokes[1].GetBoundingBox();
            Rectangle bLeft, bRight;
            Stroke    msLeft, msRight;

            if (b0.Right < b1.Right)
            {
                msLeft  = m_InkOverlay.Ink.Strokes[0];
                msRight = m_InkOverlay.Ink.Strokes[1];
                bLeft   = b0;
                bRight  = b1;
            }
            else
            {
                msLeft  = m_InkOverlay.Ink.Strokes[1];
                msRight = m_InkOverlay.Ink.Strokes[0];
                bLeft   = b1;
                bRight  = b0;
            }


            Sketch.Substroke        Left    = m_Sketch.GetSketchSubstrokeByInkId(msLeft.Id);
            Sketch.Substroke        Right   = m_Sketch.GetSketchSubstrokeByInkId(msRight.Id);
            List <Sketch.Substroke> strokes = new List <Sketch.Substroke>();
            Dictionary <Sketch.Substroke, GatePart> strokeInfo = new Dictionary <Sketch.Substroke, GatePart>();

            strokes.Add(Left);
            strokeInfo.Add(Left, leftPart);
            strokes.Add(Right);
            strokeInfo.Add(Right, rightPart);

            Rectangle     shapeBbox         = m_InkOverlay.Ink.Strokes.GetBoundingBox();
            SymbolInfo    info              = new SymbolInfo(new User("Tester"), name.ToString(), "Gate");
            ImageTemplate complete          = new ImageTemplate(strokes, strokeInfo, info);

            m_ImageTemplates.Add(complete);
        }
예제 #28
0
        /// <summary>
        /// Converts a Sketch substroke into a Microsoft.Ink stroke.
        /// </summary>
        /// <param name="substroke">The Sketch substroke to convert</param>
        /// <param name="ink">A Microsoft.Ink Ink object</param>
        /// <returns>The desired ink stroke</returns>
        private Microsoft.Ink.Stroke convertToInk(
            Sketch.Substroke substroke,
            Microsoft.Ink.Ink ink)
        {
            int pointsCount = substroke.Points.Length;

            System.Drawing.Point[] inkPoints = new System.Drawing.Point[pointsCount];

            // Convert the Sketch point format to Microsoft point format
            for (int i = 0; i < pointsCount; i++)
            {
                inkPoints[i] = new System.Drawing.Point(
                    (int)(substroke.Points[i].X),
                    (int)(substroke.Points[i].Y));
            }

            return(ink.CreateStroke(inkPoints));
        }
예제 #29
0
        public void TestUpdateStrokeWithClassifiedStroke()
        {
            List <Sketch.Shape> modifiedShapes;
            // Add one stroke, classify it, and update it
            Stroke firstStroke = newStroke();

            inkCanvasSketch.AddStroke(firstStroke);
            Sketch.Substroke oldSubstroke = inkCanvasSketch.GetSketchSubstrokeByInk(firstStroke);
            inkCanvasSketch.Sketch.MakeNewShapeFromSubstroke(out modifiedShapes, inkCanvasSketch.GetSketchSubstrokeByInk(firstStroke), Domain.LogicDomain.AND);
            inkCanvasSketch.UpdateInkStroke(firstStroke);
            Sketch.Substroke newSubstroke = inkCanvasSketch.GetSketchSubstrokeByInk(firstStroke);

            Assert.IsTrue(inkCanvasSketch.Sketch.CheckConsistency(), "sketch should be consistent after updating a stroke");
            Assert.IsTrue(inkCanvasSketch.areDictionarySizesConsistent() == 1, "dictionary size should be 1 after updating the only stroke");
            Assert.IsTrue(inkCanvasSketch.FeatureSketch.hasConsistentSubstrokes(), "after updating a stroke, data structures should be consistent");
            Assert.IsTrue(inkCanvasSketch.InkCanvas.Strokes.Contains(firstStroke), "after updating a stroke, the inkcanvas should still contain it");
            Assert.AreEqual(inkCanvasSketch.GetSketchSubstrokeByInk(firstStroke).ParentShape.Type, Domain.LogicDomain.AND, "updating should preserve shapes");
        }
예제 #30
0
        /// <summary>
        /// Applies a label to a group of substrokes.
        /// </summary>
        public override bool Execute()
        {
            // Add the new stroke to the sketch
            inkSketch.AddStroke(newStroke);

            // Update connections
            Sketch.Substroke newSubstroke = inkSketch.GetSketchSubstrokeByInk(newStroke);

            // If we're using on-the-fly recognition, the new substroke may already have a parent shape.  Get rid of it!
            if (newSubstroke.ParentShape != null)
            {
                Sketch.Shape parent = newSubstroke.ParentShape;
                parent.RemoveSubstroke(newSubstroke);
                if (parent.SubstrokesL.Count == 0)
                {
                    inkSketch.Sketch.RemoveShape(parent);
                }
            }

            changedShape.AddSubstroke(newSubstroke);
            oldLocation.ConnectedShape = changedShape;
            newSubstroke.Endpoints[0].ConnectedShape = changedShape;
            newSubstroke.Endpoints[1].ConnectedShape = shapeAtNewLoc;

            // Add the new wire to the old wire's shape
            inkSketch.Sketch.connectShapes(changedShape, changedShape); // wires connected to themselves indicates an internal connection
            inkSketch.Sketch.connectShapes(changedShape, shapeAtNewLoc);
            changedShape.AlreadyLabeled = true;

            // Pre-emptive merging! Helps us undo.
            if (newIsWire)
            {
                inkSketch.Sketch.mergeShapes(changedShape, shapeAtNewLoc);
            }

            // Regroup everything so highlighting/labels are correctly updated
            Handle(changedShape);
            Regroup(new List <Sketch.Shape> {
                changedShape
            });
            return(true);
        }