/// <summary>
 /// Adds a new tree to the list of trees to draw.
 /// </summary>
 /// <param name="tree">the tree to add</param>
 public void AddTree(ContourTree tree)
 {
     if (tree.maxValue > this.maxValue || this.trees.Count == 0) {
         this.maxValue = tree.maxValue; }
     if (tree.minValue < this.minValue || this.trees.Count == 0) {
         this.minValue = tree.minValue; }
     this.trees.Add(tree);
     this.DrawTrees();
 }
 /// <summary>
 /// Mutator for the contour tree that this view displays information about.
 /// </summary>
 /// <param name="tree">the tree to be displayed</param>
 public void SetTree(ContourTree tree)
 {
     this.tree = tree;
     if (tree != null) {
         this.maxValue = tree.GetMaxValue();
         this.minValue = tree.GetMinValue(); }
     else {
         this.maxValue = 0;
         this.minValue = 0; }
 }
Пример #3
0
        /// <summary>
        /// Figures out what kind of data the file contains and passes it to parser.
        /// </summary>
        /// <param name="myStream">the file to parse</param>
        private void readFileData(Stream myStream)
        {
            // Make a new StreamReader to read the text input file.
            StreamReader reader = new StreamReader(myStream);

            // Check the first line of the file for its file type identifier.
            string fileType = reader.ReadLine().Trim();

            // The new file data object will be stored here if successful.
            FileDataAbstract fileData;

            // Try to read the file data.
            if (fileType == "I0") { // TODO: Finish other data file types.
                fileData = new FileDataI0(reader.ReadToEnd(), this.currentTimeStep); }
            // Throw an exception if the format is not recognized.
            else {
                throw new Exception("The file format was not recognized; only files in 'I0' format work at this time."); }

            // If there are already other data files, make sure they are compatible.
            if (this.fileDataList.Count > 0) {
                FileDataAbstract tempData = this.fileDataList[0];
                if (tempData.Xdim != fileData.Xdim || tempData.Ydim != fileData.Ydim || tempData.Zdim != fileData.Zdim) {
                    throw new Exception("The file you are attempting to add has different dimensions than the previously added file(s). "
                        + "If you would like to start over with new data, please clear the current data first."); } }

            // If we've gotten this far without Exception, we can
            // assume the file data will be added successfully.
            this.currentTimeStep++;
            this.fileDataList.Add(fileData);

            // Take the file data and turn it into a list of grid points.
            List<GridPoint> pointsList = fileData.GetSortedGridPointList();

            // If there are already other file(s) in the program, clear out
            // the current trees and add their data to the points list.
            if (this.fileDataList.Count > 1) {
                // Clear the trees.
                this.joinTreeView.ClearTrees();
                this.splitTreeView.ClearTrees();
                this.contourTreeView.ClearTrees();
                // Add the data.
                foreach (FileDataAbstract data in this.fileDataList) {
                    pointsList = pointsList.Union(data.GetSortedGridPointList()).ToList();
                    pointsList.Sort(new Comparison<GridPoint>(GridPoint.Compare)); } }

            // Create the join tree and split tree from the file data.
             JoinTree  joinTree = new  JoinTree(pointsList[0].value, pointsList.Last().value, pointsList);
            SplitTree splitTree = new SplitTree(pointsList[0].value, pointsList.Last().value, pointsList);

            // Simplify the trees, except for the others' critical points.
             joinTree.SimplifyExceptFor(splitTree.GetCritical());
            splitTree.SimplifyExceptFor( joinTree.GetCritical());

            // Make the contour tree.
            ContourTree contourTree = new ContourTree(joinTree, splitTree);

            this.contourTreeView.AddTree(contourTree);
            this.topology.SetTree(contourTree);
            this.topology.AddTimeStep();

            // Simplify trees the rest of the way.
             joinTree.Simplify();
            splitTree.Simplify();

            // Add trees to their views.
            this.joinTreeView.AddTree(joinTree);
            this.splitTreeView.AddTree(splitTree);

            // Dispose of unneeded resources.
            reader.Dispose();
            myStream.Close();
        }
Пример #4
0
        /// <summary>
        /// Add a new data file with formatting like the data file from Nathaniel.
        /// </summary>
        /// <param name="uselessParam1">required by C#</param>
        /// <param name="uselessParam2">required by C#</param>
        private void addNewNathanielDataFile(object uselessParam1, EventArgs uselessParam2)
        {
            // If opened properly, the file data will be stored here.
            Stream myStream = null;
            // This is a popup window that lets you pick a file to open.
            OpenFileDialog openFileDialog = new OpenFileDialog();

            openFileDialog.InitialDirectory = "C:\\";
            openFileDialog.Filter = "txt files (*.txt)|*.txt"; // Only look at text files.

            // If the file doesn't get opened / read / added properly, display an error message.
            if (openFileDialog.ShowDialog() == DialogResult.OK) {
                try {
                    if ((myStream = openFileDialog.OpenFile()) != null) {
                        // Make a new StreamReader to read the text input file.
                        StreamReader reader = new StreamReader(myStream);

                        // The new file data object will be stored here if successful.
                        FileDataAbstract fileData;
                        fileData = new FileDataNathaniel(reader.ReadToEnd(), this.currentTimeStep);

                        // If there are already other data files, make sure they are compatible.
                        if (this.fileDataList.Count > 0)
                        {
                            FileDataAbstract tempData = this.fileDataList[0];
                            if (tempData.Xdim != fileData.Xdim || tempData.Ydim != fileData.Ydim || tempData.Zdim != fileData.Zdim)
                            {
                                throw new Exception("The file you are attempting to add has different dimensions than the previously added file(s). "
                                    + "If you would like to start over with new data, please clear the current data first.");
                            }
                        }

                        // If we've gotten this far without Exception, we can
                        // assume the file data will be added successfully.
                        this.currentTimeStep++;
                        this.fileDataList.Add(fileData);

                        // Take the file data and turn it into a list of grid points.
                        List<GridPoint> pointsList = fileData.GetSortedGridPointList();

                        // If there are already other file(s) in the program, clear out
                        // the current trees and add their data to the points list.
                        if (this.fileDataList.Count > 1)
                        {
                            // Clear the trees.
                            this.joinTreeView.ClearTrees();
                            this.splitTreeView.ClearTrees();
                            this.contourTreeView.ClearTrees();
                            // Add the data.
                            foreach (FileDataAbstract data in this.fileDataList)
                            {
                                pointsList = pointsList.Union(data.GetSortedGridPointList()).ToList();
                                pointsList.Sort(new Comparison<GridPoint>(GridPoint.Compare));
                            }
                        }

                        // Create the join tree and split tree from the file data.
                        JoinTree joinTree = new JoinTree(pointsList[0].value, pointsList.Last().value, pointsList);
                        SplitTree splitTree = new SplitTree(pointsList[0].value, pointsList.Last().value, pointsList);

                        // Simplify the trees, except for the others' critical points.
                        joinTree.SimplifyExceptFor(splitTree.GetCritical());
                        splitTree.SimplifyExceptFor(joinTree.GetCritical());

                        // Make the contour tree.
                        ContourTree contourTree = new ContourTree(joinTree, splitTree);

                        this.contourTreeView.AddTree(contourTree);
                        this.topology.SetTree(contourTree);
                        this.topology.AddTimeStep();

                        // Simplify trees the rest of the way.
                        joinTree.Simplify();
                        splitTree.Simplify();

                        // Add trees to their views.
                        this.joinTreeView.AddTree(joinTree);
                        this.splitTreeView.AddTree(splitTree);

                        // Dispose of unneeded resources.
                        reader.Dispose();
                        myStream.Close();
                    }
                }
                catch (Exception ex) {
                    MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message); }
            }
        }
        //===================================================================//
        //                            Actions                                //
        //===================================================================//
        /// <summary>
        /// Draw a particular contour tree.
        /// </summary>
        /// <param name="tree">the tree to draw</param>
        /// <param name="graphics">allows things to be drawn</param>
        /// <param name="pen">for drawing lines</param>
        /// <param name="nodeFill">for drawing nodes</param>
        private void drawTree(ContourTree tree, Graphics graphics, Pen pen, Brush nodeFill)
        {
            int   nrSlotsNeeded = tree.GetNumSlotsNeeded();
            float pixelsPerSlot = this.GetPixelsPerSlot(nrSlotsNeeded);
            float screenCenterX = this.Width / 2.0f;
            float half_Diameter = AbstractTreeView.NODE_DIAMETER / 2.0f;

            int topLeSlotsUsed = 0;
            int topRiSlotsUsed = 0;
            int botLeSlotsUsed = 0;
            int botRiSlotsUsed = 0;

            // Draw root, top, and bottom nodes.
            // TODO: Make the root node normal-colored again.
            graphics.FillEllipse(new SolidBrush(Color.Blue), screenCenterX - half_Diameter, this.ValueToYCoordinate(tree.GetRoot().value) - half_Diameter, AbstractTreeView.NODE_DIAMETER, AbstractTreeView.NODE_DIAMETER);
            graphics.FillEllipse(nodeFill, screenCenterX - half_Diameter, this.ValueToYCoordinate(tree.maxValue) - half_Diameter, AbstractTreeView.NODE_DIAMETER, AbstractTreeView.NODE_DIAMETER);
            graphics.FillEllipse(nodeFill, screenCenterX - half_Diameter, this.ValueToYCoordinate(tree.minValue) - half_Diameter, AbstractTreeView.NODE_DIAMETER, AbstractTreeView.NODE_DIAMETER);

            ContourNode currentTopMainPathNode = tree.GetTopMostLeaf();
            ContourNode currentBotMainPathNode = tree.GetBotMostLeaf();
            int currentTopDir = -1;
            int currentBotDir =  1;

            while (currentTopMainPathNode.GetTrunk() != tree.GetRoot()
                || currentBotMainPathNode.GetTrunk() != tree.GetRoot()) {

                // Top half of tree:
                if (currentTopMainPathNode.GetTrunk() != tree.GetRoot()) {
                    // Look ahead at next "main path" node.
                    ContourNode nextTopMainPathNode = currentTopMainPathNode.GetTrunk();

                    // Draw the next node.
                    graphics.FillEllipse(nodeFill, screenCenterX - half_Diameter, this.ValueToYCoordinate(nextTopMainPathNode.value) - half_Diameter, AbstractTreeView.NODE_DIAMETER, AbstractTreeView.NODE_DIAMETER);

                    // Draw the path to next node.
                    graphics.DrawLine(pen, screenCenterX, this.ValueToYCoordinate(currentTopMainPathNode.value),
                                           screenCenterX, this.ValueToYCoordinate(   nextTopMainPathNode.value));

                    // Make a list of branches from the next node.
                    List<ContourNode> branches = new List<ContourNode>(nextTopMainPathNode.GetBranches());

                    // Remove the current node from the list of branches.
                    branches.Remove(currentTopMainPathNode);

                    // Draw all the branches.
                    foreach (ContourNode branch in branches) {
                        drawBranch(branch, graphics, pen, nodeFill, currentTopDir, currentTopDir == -1 ? topLeSlotsUsed : topRiSlotsUsed, pixelsPerSlot, screenCenterX);
                        if (currentTopDir == -1) {
                            topLeSlotsUsed += branch.GetNumLeaves(); }
                        else {
                            topRiSlotsUsed += branch.GetNumLeaves(); } }

                    // Toggle the direction of adding.
                    currentTopDir *= -1;

                    // Point at next node.
                    currentTopMainPathNode = nextTopMainPathNode; }

                // Bottom half of tree:
                if (currentBotMainPathNode.GetTrunk() != tree.GetRoot()) {
                    // Look ahead at next "main path" node.
                    ContourNode nextBotMainPathNode = currentBotMainPathNode.GetTrunk();

                    // Draw the next node.
                    graphics.FillEllipse(nodeFill, screenCenterX - half_Diameter, this.ValueToYCoordinate(nextBotMainPathNode.value) - half_Diameter, AbstractTreeView.NODE_DIAMETER, AbstractTreeView.NODE_DIAMETER);

                    // Draw the path to next node.
                    graphics.DrawLine(pen, screenCenterX, this.ValueToYCoordinate(currentBotMainPathNode.value),
                                            screenCenterX, this.ValueToYCoordinate(   nextBotMainPathNode.value));

                    // Make a list of branches from the next node.
                    List<ContourNode> branches = new List<ContourNode>(nextBotMainPathNode.GetBranches());

                    // Remove the current node from the list of branches.
                    branches.Remove(currentBotMainPathNode);

                    // Draw all the branches.
                    foreach (ContourNode branch in branches) {
                        drawBranch(branch, graphics, pen, nodeFill, currentBotDir, currentBotDir == -1 ? botLeSlotsUsed : botRiSlotsUsed, pixelsPerSlot, screenCenterX);
                        if (currentBotDir == -1) {
                            botLeSlotsUsed += branch.GetNumLeaves(); }
                        else {
                            botRiSlotsUsed += branch.GetNumLeaves(); } }

                    // Toggle the direction of adding.
                    currentBotDir *= -1;

                    // Point at next node.
                    currentBotMainPathNode = nextBotMainPathNode; }
            }

            // Draw paths from currentTopMainPathNode and currentBotMainPathNode to root.
            graphics.DrawLine(pen, screenCenterX, this.ValueToYCoordinate(currentTopMainPathNode.value), screenCenterX, this.ValueToYCoordinate(currentBotMainPathNode.value));

            // Leftover branches from the root:
            foreach (ContourNode branch in tree.GetRoot().GetBranches())
            {
                if (branch != currentTopMainPathNode && branch != currentBotMainPathNode)
                {
                    if (branch.value > tree.GetRoot().value) {
                        drawBranch(branch, graphics, pen, nodeFill, currentTopDir, currentTopDir == -1 ? topLeSlotsUsed : topRiSlotsUsed, pixelsPerSlot, screenCenterX);
                        if (currentTopDir == -1) {
                            topLeSlotsUsed += branch.GetNumLeaves(); }
                        else {
                            topRiSlotsUsed += branch.GetNumLeaves(); }
                        currentTopDir *= -1; }
                    else {
                        drawBranch(branch, graphics, pen, nodeFill, currentBotDir, currentBotDir == -1 ? botLeSlotsUsed : botRiSlotsUsed, pixelsPerSlot, screenCenterX);
                        if (currentBotDir == -1) {
                            botLeSlotsUsed += branch.GetNumLeaves(); }
                        else {
                            botRiSlotsUsed += branch.GetNumLeaves(); }
                        currentBotDir *= -1; }
                }
            }
        }