-1

I want to draw a lot of lines on 3 forms but when I call this method, it takes a lot of time. With 200+ lines it takes 1 sec approximately. What am I doing wrong?

public void drawObjects()
{
    pAux = selectedPen;
    for (int i = 0; i < objects.Count; i++)
    {
        for(int ed = 0; ed < objects[i].getEdges().Count; ed++)
        {
            frontGraphics.DrawRectangle(recPen, (objects[i].getEdges()[ed].getPoint1().X + 332), -(objects[i].getEdges()[ed].getPoint1().Y - 170), 2, 2);
            rightGraphics.DrawRectangle(recPen, objects[i].getEdges()[ed].getPoint1().Z + 332, -(objects[i].getEdges()[ed].getPoint1().Y - 170), 2, 2);
            topGraphics.DrawRectangle(recPen, objects[i].getEdges()[ed].getPoint1().X + 332, -(objects[i].getEdges()[ed].getPoint1().Z - 170), 2, 2);

            if (objects[i].getEdges().Count > 0)
            {
                if (objects[i].selected == true)
                    pAux = selectedPen;
                else
                    pAux = linePen;
                frontGraphics.DrawLine(pAux, objects[i].getEdges()[ed].getPoint1().X + 332, -(objects[i].getEdges()[ed].getPoint1().Y -170), 
                                           objects[i].getEdges()[ed].getPoint2().X + 332, -(objects[i].getEdges()[ed].getPoint2().Y -170));
                rightGraphics.DrawLine(pAux, objects[i].getEdges()[ed].getPoint1().Z + 332, -(objects[i].getEdges()[ed].getPoint1().Y - 170),
                                            objects[i].getEdges()[ed].getPoint2().Z + 332, -(objects[i].getEdges()[ed].getPoint2().Y - 170));
                topGraphics.DrawLine(pAux, objects[i].getEdges()[ed].getPoint1().X + 332, -(objects[i].getEdges()[ed].getPoint1().Z - 170),
                                           objects[i].getEdges()[ed].getPoint2().X + 332, -(objects[i].getEdges()[ed].getPoint2().Z - 170));

            }
        }          
    }
}
Abbas
  • 14,186
  • 6
  • 41
  • 72
  • Look at this https://stackoverflow.com/questions/615781/can-i-suspend-redrawing-of-a-form-until-i-have-performed-all-updates –  May 14 '18 at 14:26
  • What front-end technology are you using — WinForms, WPF? Tag your question properly. What is 'slow' and would you expect? What quantities of 'lines' are you talking about? Please provide a better example — see this: https://stackoverflow.com/help/mcve – Ondrej Tucny May 14 '18 at 14:27
  • How is `drawObjects` being called? Why aren't you using the form's `Paint` event? Where does `frontGraphics` (etc) come from? How are they maintained? What does `getEdges` do? See how many unanswered questions there are? Your question cannot be answered as it is, there is just too much we don't know about what all is going on. – DonBoitnott May 14 '18 at 14:33
  • 1
    Review: inside the for-loop that ends on `objects[i].getEdges().Count` you are testing whether that is `> 0` - that is alway the case when you execute that line. – Hans Kesting May 14 '18 at 14:33
  • 2
    Assign the value of `objects[i].getEdges()[ed]` to a variable at the start of the loop. There's no reason to have to retrieve all that every time you want to use it. – itsme86 May 14 '18 at 14:34
  • 2
    How costly is that call to `.getEdges()`? You are calling it mutiple times each iteration through the loop. The value probably never changes, so get the edges once outside of the "ed" loop. – Hans Kesting May 14 '18 at 14:35
  • Im using WinForm, i need to draw objects in scene using points. in form's Paint event im called the function drawObjects, get edges return a edge and this edge have 2 points (sorry my english, and its my first question in stack overflow) – Dazentt Eduardo Dazentt55 May 15 '18 at 00:04
  • im trying to draw approximately 500+ lines in 3 forms simultaneously front top and right – Dazentt Eduardo Dazentt55 May 15 '18 at 00:07

2 Answers2

2

It is not clear what front-end you're using (WPF, WinForms), but you might be using a lot of resources with your current code. The getEdges() and/or getPoint() methods could be costly methods, and you're calling those methods a lot.

If there's a result of method that you're going to reuse: store it in a variable. Here's what your code will look like:

public void drawObjects()
{
    pAux = selectedPen;
    for (int i = 0; i < objects.Count; i++)
    {
        var currentObject = objects[i];
        var edges = currentObject.getEdges();

        for(int ed = 0; ed < edges.Count; ed++)
        {
            var currentEd = edges[ed];
            var edPoint1 = currentEd.getPoint1();
            var edPoint2 = currentEd.getPoint2();

            frontGraphics.DrawRectangle(recPen, (edPoint1.X + 332), -(edPoint1.Y - 170), 2, 2);
            rightGraphics.DrawRectangle(recPen, edPoint1.Z + 332, -(edPoint1.Y - 170), 2, 2);
            topGraphics.DrawRectangle(recPen, edPoint1.X + 332, -(edPoint1.Z - 170), 2, 2);

            pAux = currentObject.selected ? selectedPen : linePen;

            frontGraphics.DrawLine(pAux, edPoint1().X + 332, -(edPoint1().Y -170), edPoint2.X + 332, -(edPoint2.Y -170));
            rightGraphics.DrawLine(pAux, edPoint1.Z + 332, -(edPoint1.Y - 170), edPoint2.Z + 332, -(edPoint2.Y - 170));
            topGraphics.DrawLine(pAux, edPoint1.X + 332, -(edPoint1.Z - 170), edPoint2.X + 332, -(edPoint2.Z - 170));
        }          
    }
}

Edit: as @Hans Kesting mentioned, this line in the inner loop is superfluous:

if (objects[i].getEdges().Count > 0) 

It will always evaluate to true since you got in the inner loop.

PS: Note that this might not solve all your performance issues, but I'm sure this will help.

Abbas
  • 14,186
  • 6
  • 41
  • 72
0

I solve this using PICTURE BOX, i draw in a bitmap and set bitmap as the image of Picture box.