Results 1 to 32 of 32

Thread: Gerber Files in VB6

  1. #1

    Thread Starter
    Junior Member
    Join Date
    Jun 2009
    Posts
    20

    Gerber Files in VB6

    Hello,

    I saw a lot of threads on how to import Gerber files in VB6. I've finally managed to develop an application which can open Gerber files and show them in a picture box. However the process is quite slow. In case of silk layers, where there are sometimes more than 30,000 to 50,000 coordinates, it takes upto 4-5 minutes to load one layer.

    The process that I'm using is:

    Read the gerber file line per line
    Read the coordinate system (Inch or mm)
    Read the aperture codes and put them in a Flex Grid
    Read the coordinates of each line and put the X and Y coordinates in another FLex Grid.
    In the same grid, the details of the aperture are also added
    Once the grid is complete, plotting is started from the first row of the second flexgrid and it starts plotting each point as per the aperture code
    In case in any row the X coordinate is the same as that in the previous row and the Y coordinate is different, it is considered to be a line from X2, Y2 to X1, Y1.

    But this process is extremely slow.

    Does any of you know of a method where the process can be made faster? For example all freely available gerber viewers import these gerbers in less than a second!

    Is VB6 responsible for the slow import and plotting?

    I really look forward to your valuable suggestions.

    Regards
    Vinit

  2. #2
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,929

    Re: Gerber Files in VB6

    VB6 itself isn't what is slow - I'm afraid that in one or more ways, the slow part is the code you have written.

    If you show us the code, we can help you make it faster (note that in threads like this, we typically make the code 10 to 100 times faster).

  3. #3

    Thread Starter
    Junior Member
    Join Date
    Jun 2009
    Posts
    20

    Re: Gerber Files in VB6

    Hi Si,

    Thanks a lot for your prompt response. I'm not sure how much sense my code will make, but I'm still attaching it for your perusal. I'm not a professional programmer so all my coding is primarily amateurish. So please excuse me for silly mistakes!

    Basically I need to import two gerber layers - Paste layer (showing just the pads) and the silk layer (with the names and legends marked). The file system, import units etc. are taken from the paste layer and are not taken from the silk layer so as to avoid duplicacy of processes.

    I've attached the project and also attached the sample paste and silk gerbers (2 samples) so that you can have a look and comment on how to make it a lot faster!!

    Awaiting your response.

    Thanks and regards
    Vinit
    Attached Files Attached Files

  4. #4
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,929

    Re: Gerber Files in VB6

    There are some articles you should look at in our Classic VB FAQs (in the FAQ forum):


    In terms of speed, setting the .Top/Left/Width/Height of a control separately is slow, as it gets resized 4 times - you can change it to just once by using the .Move method instead, for example this:
    Code:
    For i = 1 To shcnt
    
        Shape1(i).Left = Shape1(i).Left * zoom
        Shape1(i).Top = Shape1(i).Top * zoom
        Shape1(i).Width = Shape1(i).Width * zoom
        Shape1(i).Height = Shape1(i).Height * zoom
    
    Next
    ..is faster like this:
    Code:
    For i = 1 To shcnt
        Shape1(i).Move Shape1(i).Left * zoom, Shape1(i).Top * zoom, Shape1(i).Width * zoom, Shape1(i).Height * zoom
    Next
    However, it would be even faster if you stored the positions in an array (too much work for me to give an example of I'm afraid!), and drew the items using code rather than controls, eg:
    Code:
          Picture1.Line (X1, Y1)-(X2, Y2)
    ..or with a specific colour per item:
    Code:
          Picture1.Line (X1, Y1)-(X2, Y2), vbRed

    Note that the second line here just wastes time:
    Code:
        If code = "D03" Or code = "D3" Then
            If code <> "D02" And code <> "D2" And code <> "D1" And code <> "D01" Then
    ..because the previous line already makes sure that the value is either "D03" or "D3".

    Also, when you are checking a variable against multiple values, it is quicker to use a Select Case, so this:
    Code:
        If temp = "C" Then
          shcnt = shcnt + 1
          ...
        Else
          If temp = "R" Then
            shcnt = shcnt + 1
            ...
          Else
            If temp = "O" Then
              shcnt = shcnt + 1
              ...
            End If
          End If
        End If
    ..would be like this:
    Code:
        Select Case temp
        Case "C"
          shcnt = shcnt + 1
          ...
        Case "R"
          shcnt = shcnt + 1
          ...
        Case "O"
          shcnt = shcnt + 1
          ...
        End Select
    And this:
    Code:
            If grdTemp.TextMatrix(i - 1, 3) = "D02" Or grdTemp.TextMatrix(i - 1, 3) = "D2" _
             Or grdTemp.TextMatrix(i - 1, 3) = "D01" Or grdTemp.TextMatrix(i - 1, 3) = "D1" Then
              ...
            End If
    ..becomes this:
    Code:
            Select Case grdTemp.TextMatrix(i - 1, 3)
            Case "D02", "D2", "D01", "D1"
              ...
            End If


    You also have several places where you do the same (slow) work repeatedly, such as this:
    Code:
            grdTemp.TextMatrix(grdTemp.Rows - 1, 4) = GrdFS.TextMatrix(apnum(Split(dcode, "D")(1)), 1)
            grdTemp.TextMatrix(grdTemp.Rows - 1, 5) = GrdFS.TextMatrix(apnum(Split(dcode, "D")(1)), 2)
            grdTemp.TextMatrix(grdTemp.Rows - 1, 6) = GrdFS.TextMatrix(apnum(Split(dcode, "D")(1)), 3)
            grdTemp.TextMatrix(grdTemp.Rows - 1, 7) = GrdFS.TextMatrix(apnum(Split(dcode, "D")(1)), 4)
    ..which would run more quickly if you just did that calculation once, and use it repeatedly, eg:
    Code:
    Dim lngRow as Long
            lngRow = apnum(Split(dcode, "D")(1)
            grdTemp.TextMatrix(grdTemp.Rows - 1, 4) = GrdFS.TextMatrix(lngRow, 1)
            grdTemp.TextMatrix(grdTemp.Rows - 1, 5) = GrdFS.TextMatrix(lngRow, 2)
            grdTemp.TextMatrix(grdTemp.Rows - 1, 6) = GrdFS.TextMatrix(lngRow, 3)
            grdTemp.TextMatrix(grdTemp.Rows - 1, 7) = GrdFS.TextMatrix(lngRow, 4)
    In Prepare1 you have a similar issue, such as usage of InStr(linetext, "X") and InStr(linetext, "Y")


    There are other things that could be done, but I think this should be enough to keep you busy for a while!

  5. #5

    Thread Starter
    Junior Member
    Join Date
    Jun 2009
    Posts
    20

    Re: Gerber Files in VB6

    Hi Si,

    This is exactly the kind of help I needed - someone who could teach these nuances of making the code faster! I acknowledge that I never thought of these small things to make it faster since, as I mentioned earlier, I'm just an ameteur trying to write code without any formal training!

    Yes this will keep me busy for a today! I'll write back as soon as I've implemented your suggestions and will ask for more!!

    Thanks a ton once again.

    Regards
    Vinit

  6. #6

    Thread Starter
    Junior Member
    Join Date
    Jun 2009
    Posts
    20

    Re: Gerber Files in VB6

    Hi Si (is that your name?),

    I've done the changes as per your suggestions. The code seems to have become slightly faster. But the silk layer import is still very slow. Basically Prepare1 and List1 are for importing the paste layer (list1 calls Plot1 for plotting it). Similary Preparesilk1 and List2 are for importing the silk layer (with list2 calling Plot2 for plotting). I've noticed the the slowness is in Preparesilk1 and Plot2.

    I think the problems are in both Prepare1 as well as PrepareSilk1 (and similarly in List1 and List2), but they're more visible in case of PrepareSilk1 and List2 since the silk layer has a lot of points (in the Gerber1 sample there are approx. 33000 points in the silk layer). Please let me know what else can be modified to speed it up.

    Also you mentioned:

    In Prepare1 you have a similar issue, such as usage of InStr(linetext, "X") and InStr(linetext, "Y")

    I didn't understand what should be changed here. Please let me know becasue InStr is used a lot in Prepare1 as well as PrepareSilk1. May be this could fasten up the entire loading. Also please let me know what to modify in Plot2 to make the plotting faster.

    Looking forward to your valuable inputs!!

    Regards
    Vinit

  7. #7
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,929

    Re: Gerber Files in VB6

    Quote Originally Posted by vinit1973 View Post
    Hi Si (is that your name?),
    It is indeed.
    Quote Originally Posted by vinit1973
    Also you mentioned:

    In Prepare1 you have a similar issue, such as usage of InStr(linetext, "X") and InStr(linetext, "Y")

    I didn't understand what should be changed here.
    This is part of the code (with indenting to make it more readable):
    Code:
            If InStr(linetext, "X") > 0 Or InStr(linetext, "Y") > 0 Then
              If InStr(linetext, "D") = 0 Then
                linetext = linetext & "D01"
              End If
            End If
            
            If InStr(linetext, "D") > 0 Then
              If Val(Split(linetext, "D")(1)) >= 10 Then
                linetext = "D" & Split(linetext, "D")(1)
              End If
            End If
            
            If InStr(linetext, "X") = 0 And InStr(linetext, "Y") = 0 And InStr(linetext, "Y") = 0 _
            And InStr(linetext, "G") > 0 Then
              gcode = 1
              GoTo nextline5
            End If
            
            On Error Resume Next
            If Val(Split(linetext, "D")(1)) >= 10 Then
              gcode = 0
            End If
    As you aren't using Else (or ElseIf) here, you always check X twice, Y twice (actually 3, but one should be removed as coloured above), G once, and D once or twice - as well as splitting on D once or twice.

    To start with, think about the two blocks that check for X's and Y's... if the first one is true, the second one cannot be (so shouldn't even be checked); if the first is false, you already know that your checks on the second will be true (so there is no need to check them again).

    As such, those two X/Y blocks can be reduced to this:
    Code:
            If InStr(linetext, "X") > 0 Or InStr(linetext, "Y") > 0 Then
              If InStr(linetext, "D") = 0 Then
                linetext = linetext & "D01"
              End If
            Else
              If InStr(linetext, "G") > 0 Then
                gcode = 1
                GoTo nextline5
              End If
            End If
    This has removed one check for X and Y, and sometimes the check for G too.

    Now do similar for D... due to what the 'G' check does, there is no need to do the D check before it (because linetext will be reset). As for the second D block, it is basically re-checking the same thing as the first, so you could merge the two by moving the 'gcode = 0' like this:
    Code:
            If InStr(linetext, "D") > 0 Then
              If Val(Split(linetext, "D")(1)) >= 10 Then
                linetext = "D" & Split(linetext, "D")(1)
                gcode = 0
              End If
            End If
    This can be taken further still, because the X/Y check might add D01 to the text... and after the D check that will be all that is used.

    If you move the D check to each part of the X/Y check (just before the "Else", and just before the last "End If"), you will see that the first section has this:
    Code:
              If InStr(linetext, "D") = 0 Then
                linetext = linetext & "D01"
              End If
              If InStr(linetext, "D") > 0 Then
                If Val(Split(linetext, "D")(1)) >= 10 Then
                  linetext = "D" & Split(linetext, "D")(1)
                  gcode = 0
                End If
              End If
    ..and that can be shrunk down to this:
    Code:
              If InStr(linetext, "D") = 0 Then
                linetext = linetext & "D01"
              Else
                If Val(Split(linetext, "D")(1)) >= 10 Then
                  linetext = "D" & Split(linetext, "D")(1)
                  gcode = 0
                End If
              End If
    These changes have reduced the InStr's from 6 or 7 down to 3 or 4, and the Split's from 1 to 2 down to 0 or 1 - which has roughly halved the workload for this section.


    Based on this example, you should be able to make similar improvements with other parts of the routine, and several other parts of the program - including PrepareSilk1 and List2.

    Note that for PrepareSilk1 and Prepare1, you should have noticed (and changed) something about the two lines for apnum and codeap.

    Have a go at improving those routines based on the advice I've given so far, which should give noticeable improvements - and you can then post your code for those routines, and we'll move on to other ways to speed them up.
    Quote Originally Posted by vinit1973
    Also please let me know what to modify in Plot2 to make the plotting faster.
    Beyond using Select Case and nesting If's, the best thing to do is lose your reliance on the grid text, by storing the data in an array (using an apt data type) instead - but to do that would require significant changes throughout your app, which is a bit much for me to explain I'm afraid.

  8. #8

    Thread Starter
    Junior Member
    Join Date
    Jun 2009
    Posts
    20

    Re: Gerber Files in VB6

    Hi Si,

    Thanks once again for your help!

    I've gone through your suggestion in detail. In Prepare1, I had made a mistake of repeating the Y check as you correctly pointed out.

    Besides that, you had mentioned:

    To start with, think about the two blocks that check for X's and Y's... if the first one is true, the second one cannot be (so shouldn't even be checked); if the first is false, you already know that your checks on the second will be true (so there is no need to check them again).

    As such, those two X/Y blocks can be reduced to this:
    Code:
           If InStr(linetext, "X") > 0 Or InStr(linetext, "Y") > 0 Then
              If InStr(linetext, "D") = 0 Then
                linetext = linetext & "D01"
              End If
            Else
              If InStr(linetext, "G") > 0 Then
                gcode = 1
                GoTo nextline5
              End If
            End If
    This is not correct since the first check is an 'OR' check and the other one is 'AND' check. So if the first is not true, the second need not be necessarily true.

    I've implemented the other suggestion regarding D check.

    Still, my problem remains in List2 and Plot2 which are the slowest! I always felt that probably my usage of a Flexgrid to first list the data and then plotting it might be contributing to the slowness of the code, but was never too sure of it and hence never tried to change! But you confirmed this in your previous post. I'll try to use arrays (I'll need to learn more on that!).

    If you could help further!!

    Regards
    Vinit

  9. #9
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,929

    Re: Gerber Files in VB6

    Quote Originally Posted by vinit1973
    This is not correct since the first check is an 'OR' check and the other one is 'AND' check. So if the first is not true, the second need not be necessarily true.
    I understand why you think that - but read it more carefully, paying particular attention to what is being checked:
    Code:
    If InStr(linetext, "X") > 0 Or InStr(linetext, "Y") > 0 Then
    If InStr(linetext, "X") = 0 And InStr(linetext, "Y") = 0 And InStr(linetext, "G") > 0 Then
    The first line is >0 , but the second line is =0

    Pick a few numbers to use in place of InStr(linetext, "X") and InStr(linetext, "Y"), and go thru it manually. If you pick 1 and 0, it would become:
    Code:
    If 1 > 0 Or 0 > 0 Then   '1>0 is true, so this will fire
    If 1 = 0 And 0 = 0 And InStr(linetext, "G") > 0 Then  '1=0 will fail, so this will not fire
    No matter which numbers you pick, you will see that what I said before still stands.


    For information about how to use arrays, see the article What are arrays and how do I use them? from our Classic VB FAQs (in the FAQ forum)

    Have a go at it, and if you get stuck let us know what the problem is. If you manage to get it working, show us the code for those two routines (and the declaration of the relevant variables, including the arrays).

  10. #10

    Thread Starter
    Junior Member
    Join Date
    Jun 2009
    Posts
    20

    Re: Gerber Files in VB6

    Hi Si,

    You're right! Actually I tried as per your suggestion but on doing that, for some Gerbers it didn't load anything into the grid and hence no plots! But the problem was because of the line:

    Code:
    GoTo nextline5
    I just removed this line and now it's ok!

    Now I'll try to use arrays and will let you know if I face problems!

    Regards
    Vinit

  11. #11

    Thread Starter
    Junior Member
    Join Date
    Jun 2009
    Posts
    20

    Re: Gerber Files in VB6

    Hi Si,

    First of all, a million thanks for your valuable suggestions! Over the past few weeks I've converted all the FlexGrids to arrays and the speed has nearly doubled.

    I also implemented your suggestion of drawing lines using picture1.line code instead of using line controls. And yes, the speed increased by more than 300 times! A problem that I was facing was that in some Gerbers there are more than 300,000 lines to be drawn. However the line control only allows 32,767 controls. So then I had to give 10 line controls and count the no. of lines already drawn to decide which line control will draw the lines! This was slower than I could ever imagine. For one Gerber that I had, it took approx. 3 hours! The moment I changed this to Picture1.line coding it imported the Gerber in flat 36 seconds!

    Now I'm facing just one problem! When I zoom the Picturebox, the lines vanish! How can they be made to zoom and move along with the picture box?

    I look forward to your guidance one more time!

    Regards
    Vinit

  12. #12
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,929

    Re: Gerber Files in VB6

    That's a nice speed improvement - especially the 3 hours down to 36 seconds!


    I'm not sure how you zoom/move the picturebox (and due to all the changes, it probably isn't worth me checking your original code), but in simple terms you are likely to need to re-draw all of the lines.

    If you show us your current code, we might be able to come up with something better.

  13. #13

    Thread Starter
    Junior Member
    Join Date
    Jun 2009
    Posts
    20

    Re: Gerber Files in VB6

    Hi Si,

    Yes it indeed is and thanks to you for that!

    The code right now is too cluttered to make any sense to someone sensible!!!!! The way I'm zooming the picture box (picture1) is by placing it inside another picture box (picture2) and then increasing (or decreasing) the picture1.height and width property by 20% on each zoom in and by reducing it by 20% on each zoom out. It is working perfectly fine when I used the line controls to draw the lines on picture1.

    Now that I am not using line1 and am using picture1.line code, the lines disappear the moment the picture is zoomed in or out. What I need to know is if there is a way of refreshing the picturebox so that it can display the lines again with the new sizes or do I have to load all of them again using picture1.line? If so, it will take 36 seconds for each zoom in and zoom out which doesn't look too good! I tried the paintpicture property as well by painting the picture1 image (and picture) to another picture box (picture3) and then painting it back to picture1 with increased (or reduced) scalewidth and scaleheight to give a zoom effect. Again, the lines are only visible if drawn with the line control but not if drawing using picture1.line code.

    So in effect, what I only need is on how to zoom in or zoom out any picture box with picture.line used to draw a few lines!

    Hope I've been able to explain!

    Awaiting your guidance once again!

    Regards
    Vinit

  14. #14
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,929

    Re: Gerber Files in VB6

    It seems like there could be a very simple fix... check the AutoRedraw property of the picturebox, as it sounds like it is currently set to False.

    That should keep the lines visible, but perhaps not scale them - so you may need to use the Picture3/paintpicture method too.

  15. #15
    Fanatic Member
    Join Date
    Sep 2009
    Location
    Lakewood, Colorado
    Posts
    621

    Re: Gerber Files in VB6

    I see that you are getting a lot of useful help, so I won't dive right in and look at your code. However, as you say, the FlexGrid control can be slow. Make sure that you set the flexgrid .Redraw property to False before you add/change data in it. After you have made all of the changes that you need, set it back to True, and then call the .Refresh method.

    Dick
    Richard Grier, Consultant, Hard & Software
    Microsoft MVP (Visual Basic)

  16. #16

    Thread Starter
    Junior Member
    Join Date
    Jun 2009
    Posts
    20

    Re: Gerber Files in VB6

    Hi Si,

    I've attached the project with only the code that is needed.

    There are 2 files with the data in the format X,Y,Dcode. One is a very small file (silk1.txt) with total approx. 1500 lines to be drawn and the other is pretty complex (silk2.txt) with over 328,000 lines to be drawn. The silk2.txt file is quite huge and the attachment size becomes too large so I have deleted a lot of lines from the file and the attached silk2.txt file now has over 110,000 lines only!

    There are 2 buttons on the form to import these files. Both import the data into arrays instead of flex grids. One imports and plots the lines using the Line Control and the other imports and plots the lines using Picture1.line code. The speed of importing and plotting is the same for silk1.txt since there are very few lines. However for silk2.txt, if you import it using line control, it is able to import and plot only the first 32,767 lines and then gives and error after that. I could add more line arrays so that it could complete all the lines but you will get an idea of the slowness of the code with just 32,767 lines. However if I import this silk2.txt file using picture1.line code it happens in approx. 30 seconds. Till here everything seems to be ok and picture1.line code wins the game!

    However when I zoom the picture box, the lines also get properly zoomed if they were imported using the line control. But not if I used the picture1.line code. I tried to use picture1.paintpicture to zoom the picture box but it distorts the image considerable and doesn't leave the text readable after zooming. So paintpicture is not an option that can be used.

    Can you please help me how to go ahead with the zooming!!!

    Awaiting your response.

    Thanks and regards
    Vinit
    Attached Files Attached Files

  17. #17
    Fanatic Member
    Join Date
    Sep 2009
    Location
    Lakewood, Colorado
    Posts
    621

    Re: Gerber Files in VB6

    What statement causes the error? I cannot actually run your code -- I don't have the AcroPDF.dll. The error indicates that some index is dimensioned as an Integer, when you need it to be a Long.

    I suggest that you look at Rod Stephen's site, www.vb-helper.com. He has VB6 graphics examples (he has written several books on the subject) that should show how to improve your code for zooming, both in detail, and speed.

    Dick
    Richard Grier, Consultant, Hard & Software
    Microsoft MVP (Visual Basic)

  18. #18

    Thread Starter
    Junior Member
    Join Date
    Jun 2009
    Posts
    20

    Re: Gerber Files in VB6

    Hi Dick,

    Firstly, the reference to AcroPDF.dll is not required for this project so you can remove all enabled references and components concerning Adobe in this project. It would then run.

    Coming to the error, the error is not while zooming, it is while drawing the lines using line control when the no. of lines reaches 32767 which is the maximum allowed in VB6 (I guess for .NET it is much higher since it is 32bit). In the project I've already avoided the error with On Error Resume Next statement.

    My problem is not actually zooming. It concerns drawing of lines which can be later zoomed along with the picture box. If I draw the lines using a line control I can easily zoom them by increasing/reducing the .X1, .X2, .Y1, .Y2 properties by the zoom factor while also increasing/reducing the picture box .width and .height by the same factor. However if I import 300,000+ lines using line control it takes ages to do so and I have to rely on multiple line controls (each handling up to 32,767 lines). On the other hand, if I use the picturebox.line code to draw the lines, the drawing is done in less than a minute which is what I need! however, since these lines are not accessible by code any longer, I cannot change their .X1, .X2., .Y1 and .Y2 properties to zoom them! This is my predicament.

    Please run the project and my problem will be evident!

    Regards
    Vinit

  19. #19
    Fanatic Member
    Join Date
    Sep 2009
    Location
    Lakewood, Colorado
    Posts
    621

    Re: Gerber Files in VB6

    VB6 is 32bit, so that isn't the issue. However, the number of controls that you can instantiate is limited, for obvious reasons. PC resources are not infinite, and (as you observe), even if memory virtualization allows huge numbers of windowsless controls (like the line control), you still would run into performance issues. There simply is lots of bookkeeping that has to be done behind the scenes.

    IMO, you would have to create your own methods that do this bookkeeping, and use line drawing methods, instead of controls, if you want to exceed the limitations of the line control. However... all of this (too) would have performance issues. "Knowing where things are" so that you can modify them, after the fact, is a non-trivial task.

    The reason that CAD programs cost so much, is that it costs time and money to design high-performance engines. It is not common for CAD engines to be built in VB, but in C/C++.

    I suggest that you take a look at http://gerbv.gpleda.org/index.html to get an idea aobut the issues involved.

    There are Gerber file viewers around, so perhaps it would make sense to use one of these. For example, http://www.softpedia.com/get/Office-...ls/Gerbv.shtml and http://gerbmagic.software.informer.com/3.3/

    I'm far from an expert in this area, and it isn't that I want to discourage you from trying. However, I think you may be chewing off a big chunk. IMO, Rod Stephen's site and books will tell you as much, or more, than any other.

    Dick
    Richard Grier, Consultant, Hard & Software
    Microsoft MVP (Visual Basic)

  20. #20
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,929

    Re: Gerber Files in VB6

    I see what you mean about distortion, and I couldn't find a quick fix (unless you want to restrict the zoom to about 2, which is doubtful)... but there are things we can do to make re-drawing much faster, to the point where I think it could be acceptable to do that for zooming.


    I re-arranged the code in cmdImport_Click slightly, so that it had two loops - one to just load the data in to the array, and the other one (which can easily be moved to a separate re-usable routine) to display it. I added timing code around it to see how long each part took.

    The version of Silk2 you posted took about 1.4 seconds to load, and about 6.5 to display (total of about 7.9). With a couple of minor changes, the display time dropped to about 1.8 seconds - which would probably be about 6 seconds for the entire Silk2 file on your computer at this stage.

    What I did is comment out this code you had inside the loop:
    Code:
                        Picture1.DrawWidth = 1
                        Picture1.Line ((dataarray(arraynum - 1, 1)) * TxtZoom.Text, Picture1.ScaleHeight - (dataarray(arraynum - 1, 2) * TxtZoom.Text))- _
                        ((dataarray(arraynum, 1)) * TxtZoom.Text, Picture1.ScaleHeight - (dataarray(arraynum, 2) * TxtZoom.Text)), vbRed
    ..and replace it with this before the loop:
    Code:
    Dim sngZoom As Single
    Dim sngSH As Single
      sngSH = Picture1.ScaleHeight
      sngZoom = CSng(TxtZoom.Text)
      Picture1.DrawWidth = 1
    ..and this inside:
    Code:
                        Picture1.Line ((dataarray(arraynum - 1, 1)) * sngZoom, sngSH - (dataarray(arraynum - 1, 2) * sngZoom))- _
                        ((dataarray(arraynum, 1)) * sngZoom, sngSH - (dataarray(arraynum, 2) * sngZoom)), vbRed

    There are other improvements that could be done too, the easiest of which is to move the If statements to the 'loading' section - and store the results to another array, which you check (instead of running all the If's) in the display section.

    By doing that the initial loading will be slightly slower, but each time you re-draw it after that it will be quicker - because instead of up to 10 checks for each line, you will only have 1.

    This took the time from 1.4 to load and 1.8 to display, to 1.7 to load and 1.5 to display - so the whole file for you should be about 5 seconds.

    Here is the routine at this stage:
    Code:
    'added to the Declarations section
    Dim drawit(1000000) As Boolean
    
    'the routine
    Private Sub cmdImport_Click()
    Dim File As String
    Dim linetext As String
    
    dlgImport.ShowOpen
    File = dlgImport.FileName
    
    arraynum = 0
    
    Dim sngTiming As Single
    DoEvents
    sngTiming = Timer
    
    Open File For Input As #1
        While Not EOF(1)
            Line Input #1, linetext
            arraynum = arraynum + 1
            dataarray(arraynum, 1) = Split(linetext, ",")(0)
            dataarray(arraynum, 2) = Split(linetext, ",")(1)
            dataarray(arraynum, 3) = Split(linetext, ",")(2)
    
            drawit(arraynum) = False
            If dataarray(arraynum, 3) = "D01" Or dataarray(arraynum, 3) = "D1" Then
                If dataarray(arraynum - 1, 3) = "D02" Or dataarray(arraynum - 1, 3) = "D2" _
                 Or dataarray(arraynum - 1, 3) = "D01" Or dataarray(arraynum - 1, 3) = "D1" Then
                    If dataarray(arraynum, 1) <> "" And dataarray(arraynum, 2) <> "" And _
                    dataarray(arraynum - 1, 1) <> "" And dataarray(arraynum - 1, 2) <> "" Then
                        drawit(arraynum) = True
                    End If
                End If
            End If
    
         Wend
    Close #1
    
    MsgBox "Load " & Format(Timer - sngTiming, "0.00")
    DoEvents
    sngTiming = Timer
    
    Dim sngZoom As Single
    Dim sngSH As Single
    sngSH = Picture1.ScaleHeight
    sngZoom = CSng(TxtZoom.Text)
    Picture1.DrawWidth = 1
    
    For arraynum = 1 To arraynum
      If drawit(arraynum) Then
        Picture1.Line ((dataarray(arraynum - 1, 1)) * sngZoom, sngSH - (dataarray(arraynum - 1, 2) * sngZoom))- _
                      ((dataarray(arraynum, 1)) * sngZoom, sngSH - (dataarray(arraynum, 2) * sngZoom)), vbRed
      End If
    Next arraynum
    MsgBox "Display " & Format(Timer - sngTiming, "0.00")
    
    End Sub
    The next step is to change the array a bit, so that you use proper data types for each item (rather than Variant for all of them as you have at the moment, which is slow and wastes memory)... Unfortunately this could mean lots of typing if you use the array in other parts of the program too.

    A good way to do that is to use a Type, which will define each 'column' in the array. To do that, comment out dataarray and drawIt in the declarations section, and add this:
    Code:
    Private Type TheData
      X As Single
      Y As Single
      Text As String
      drawit As Boolean
    End Type
    Dim dataTypeArray(1000000) As TheData
    The modified routine to use the new array is this:
    Code:
    Private Sub cmdImport_Click()
    Dim File As String
    Dim linetext As String
    
    dlgImport.ShowOpen
    File = dlgImport.FileName
    
    arraynum = 0
    
    Dim sngTiming As Single
    DoEvents
    sngTiming = Timer
    
    Open File For Input As #1
        While Not EOF(1)
            Line Input #1, linetext
            arraynum = arraynum + 1
            dataTypeArray(arraynum).X = Split(linetext, ",")(0)
            dataTypeArray(arraynum).Y = Split(linetext, ",")(1)
            dataTypeArray(arraynum).Text = Split(linetext, ",")(2)
    
            dataTypeArray(arraynum).drawIt = False
            
            If dataTypeArray(arraynum).Text = "D01" Or dataTypeArray(arraynum).Text = "D1" Then
    
                If dataTypeArray(arraynum - 1).Text = "D02" Or dataTypeArray(arraynum - 1).Text = "D2" _
                 Or dataTypeArray(arraynum - 1).Text = "D01" Or dataTypeArray(arraynum - 1).Text = "D1" Then
    
    'this check is no longer apt, instead you will get an error above (so you may want to deal with that situation somehow)
                    'If dataTypeArray(arraynum).X <> "" And dataTypeArray(arraynum).Y <> "" And _
                    dataTypeArray(arraynum - 1).X <> "" And dataTypeArray(arraynum - 1).Y <> "" Then
    
                        dataTypeArray(arraynum).drawIt = True
    
                    'End If
                End If
            End If
         
         Wend
    Close #1
    
    MsgBox "Load " & Format(Timer - sngTiming, "0.00")
    sngTiming = Timer
    
    Dim sngZoom As Single
    Dim sngSH As Single
      sngSH = Picture1.ScaleHeight
      sngZoom = CSng(TxtZoom.Text)
      Picture1.DrawWidth = 1
    
    For arraynum = 1 To arraynum
      If dataTypeArray(arraynum).drawIt Then
        Picture1.Line ((dataTypeArray(arraynum - 1).X) * sngZoom, sngSH - (dataTypeArray(arraynum - 1).Y * sngZoom))- _
                      ((dataTypeArray(arraynum).X) * sngZoom, sngSH - (dataTypeArray(arraynum).Y * sngZoom)), vbRed
      End If
    Next arraynum
    MsgBox "Display " & Format(Timer - sngTiming, "0.00")
    
    End Sub
    For me the Display part of this takes about 0.9 seconds - so for you the whole file should be re-drawn in a little over 3 seconds, which I think could be an acceptable zoom time for a file with that much detail.
    Last edited by si_the_geek; Nov 19th, 2009 at 02:07 PM.

  21. #21
    Frenzied Member
    Join Date
    Mar 2009
    Posts
    1,182

    Re: Gerber Files in VB6

    Si, just jumping in with a thought here as this dawned upon me as I try to go to sleep. I wonder if the OP could use a stdPicture object or a picture box that is defined at four or more times as large as the display area. Draw to this very large object and then bitblt (or some other API) the large picture down to the display size, then when OP or OP's user wants to zoom, bitblt once again with different arguements.

    Just a thought from somewhere out in left field or beyond...
    Option Explicit should not be an Option!

  22. #22
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,929

    Re: Gerber Files in VB6

    That is a valid idea, and is one that I had myself - unfortunately there are two restrictions to it.

    The first is the memory usage, which can be a problem if the files are large like in the case of the Silk2 file (hence my comment about restricting the zoom to about 2, but that was using a Picturebox which is more limiting).

    The other is that you get a loss of accuracy when drawing at a lower zoom level (such as the initial zoom of 1). That doesn't sound too bad, but it is in this case - because everything in the picture is just 1 pixel wide (and usually vertical or horizontal), so the loss of accuracy means that several of the lines would completely vanish.

  23. #23
    Frenzied Member
    Join Date
    Mar 2009
    Posts
    1,182

    Re: Gerber Files in VB6

    Like I said, it was a thought that popped in as I lay there and it would not let me get to sleep... Oh well....



    Good Luck
    Option Explicit should not be an Option!

  24. #24
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,929

    Re: Gerber Files in VB6

    It turned out to not be right for the situation, but the idea was definitely worth sharing

  25. #25

    Thread Starter
    Junior Member
    Join Date
    Jun 2009
    Posts
    20

    Re: Gerber Files in VB6

    Hi Si,

    I don't have words to thank you enough! I don't know what I'd have done without your guidance and support!

    With your last post, I was able to solve the problem of displaying hundreds of thousands of lines in seconds!

    I'll disturb you once again if I need your support!!

    Thanks once again.

  26. #26
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,929

    Re: Gerber Files in VB6

    No problem, it's therapeutic to be involved in something like this every now and then.

  27. #27
    PowerPoster
    Join Date
    May 2006
    Location
    Location, location!
    Posts
    2,673

    Re: Gerber Files in VB6

    It's not much use NOW to the OP (original poster), but I thought I'd post it here anyway in case he ever reads the thread again or someone else comes here to read through the post. It isn't limited in any way to this type of file, and is about optimisation of code speed within any program.

    Whenever I have needed to optimise code, I have used the gettickcount api to help generate a rolling total of how much time the code I have written takes and also how long it takes to get from one check point to another (using a custom function which remembers the tickcount at the last call and works out how many ticks have elapsed). Doing this, you might find that to get from check point 1 to 2 takes 10ms while check point 2 to 3 takes 2500ms then check point 3 to 4 takes 15ms...so you know that somewhere between 2 and 3 is a piece of code that is seriously slowing down your program and you can then modify the check points to find out which line it is happening at.

    While this is standard practice for many coders, there are still a lot of people out there who don't bother to pinpoint exactly where their code is slowed down and they just assume that generally speaking the program is slow...99&#37; of the time it ISN'T the whole program, it's a loop somewhere or a certain function you're using.

    If you find a section of code that is slow and you don't feel you know enough about VB to speed it up, do as the OP did and ask the experts here...post your code section (you may be asked to post it all so they can see what happens before and after, this is normal) so people can look and see why it might be holding the program hostage, people here are very helpful and may even offer you rewritten code that performs better or at the very least point you towards the help you require. I myself have asked for help with bits of code and the speed increase was astronomical.

    Very often the speed issues are because of minor things like extraneous code that you could do without or memory issues or the types of variable you are working with...in my case it was to do with calculations that were being done that could have been done in advance and stored in an array then called from the array rather than being done repeatedly :-)
    Well, everyone else has been doing it :-)
    Loading a file into memory QUICKLY - Using SendKeys - HyperLabel - A highly customisable label replacement - Using resource files/DLLs with VB - Adding GZip to your projects
    Expect more to come in future
    If I have helped you, RATE ME! :-)

    I love helping noobs with their VB problems (probably because, as an amateur programmer, I am only slightly better at VB than them :-)) but if you SERIOUSLY want to get help for free from a community such as VBForums, you have to first have a grounding (basic knowledge) in VB6, otherwise you're way too much work to help...You've got to give a little if you want to get help from us, in other words!

    And we DON'T do your homework. If your tutor doesn't teach you enough to help you make the project without his or her help, FIND A BETTER TUTOR or try reading books on programming! We are happy to help with minor things regarding the project, but you have to understand the rest of it if you want our help to be useful.

  28. #28
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,929

    Re: Gerber Files in VB6

    Well said, but unfortunately you are pretty much preaching to the choir... vinit1973 has followed your advice since the start, and from way back in post #11:
    Quote Originally Posted by vinit1973 View Post
    For one Gerber that I had, it took approx. 3 hours! The moment I changed this to Picture1.line coding it imported the Gerber in flat 36 seconds!
    ..and we've had other (smaller) improvements since then too.

    It would be nice to get the message out to more people, as there are some people who are the opposite of vinit1973, and take lots of persuading to let others help them optimise... they somehow seem to think that code which works couldn't be improved, and that any issues (speed or otherwise) must be VB's fault rather than their own lack of expertise in the area.

    Even with lots of VB experience, there is always room for improvement... With one of my own projects I had a piece of code which originally took about 2 minutes, which I reduced to about 15 seconds by optimising it myself. With the help (or rather, CodeBank examples) of another forum member who specialises in what the code did, I got it under 2 seconds. It could probably be reduced even more, but as you go further the work gets much harder, and the gains get much smaller.

  29. #29
    PowerPoster
    Join Date
    May 2006
    Location
    Location, location!
    Posts
    2,673

    Re: Gerber Files in VB6

    I miss Static! He'd help you get your code to run in 10ms :-P
    Well, everyone else has been doing it :-)
    Loading a file into memory QUICKLY - Using SendKeys - HyperLabel - A highly customisable label replacement - Using resource files/DLLs with VB - Adding GZip to your projects
    Expect more to come in future
    If I have helped you, RATE ME! :-)

    I love helping noobs with their VB problems (probably because, as an amateur programmer, I am only slightly better at VB than them :-)) but if you SERIOUSLY want to get help for free from a community such as VBForums, you have to first have a grounding (basic knowledge) in VB6, otherwise you're way too much work to help...You've got to give a little if you want to get help from us, in other words!

    And we DON'T do your homework. If your tutor doesn't teach you enough to help you make the project without his or her help, FIND A BETTER TUTOR or try reading books on programming! We are happy to help with minor things regarding the project, but you have to understand the rest of it if you want our help to be useful.

  30. #30
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,929

    Re: Gerber Files in VB6

    For particular things maybe, but how long code takes depends on what it needs to do, and how much relevant expertise (and amount of effort) is involved in the optimisation process.

    In terms of this thread, simply reading the file (and ignoring the data) would take significantly more than 10ms due to disk speed etc. There may well be room for improvement on the current speed, but the gains will be far smaller than we had before, and will take more effort too.

    With my situation many people would have written code that took far more than my initial 2 minutes (possibly even hours), due to the huge amount of operations required. Unless Static was very specialised in the particular area (I've never seen anything to suggest he had any experience of it) I seriously doubt his optimisations would have been better than my 15 seconds, and may not even have got that far.

  31. #31
    PowerPoster
    Join Date
    May 2006
    Location
    Location, location!
    Posts
    2,673

    Re: Gerber Files in VB6

    Static was the resident speed geek, didn't you know that? Although I *was* joking about 10ms, I am sure he would have been able to shave a few milliseconds off of the time it took, he'd look at the variable types used, loops in the code and ways to improve on them, allsorts...no idea where he is now though, haven't seen him in a while
    Well, everyone else has been doing it :-)
    Loading a file into memory QUICKLY - Using SendKeys - HyperLabel - A highly customisable label replacement - Using resource files/DLLs with VB - Adding GZip to your projects
    Expect more to come in future
    If I have helped you, RATE ME! :-)

    I love helping noobs with their VB problems (probably because, as an amateur programmer, I am only slightly better at VB than them :-)) but if you SERIOUSLY want to get help for free from a community such as VBForums, you have to first have a grounding (basic knowledge) in VB6, otherwise you're way too much work to help...You've got to give a little if you want to get help from us, in other words!

    And we DON'T do your homework. If your tutor doesn't teach you enough to help you make the project without his or her help, FIND A BETTER TUTOR or try reading books on programming! We are happy to help with minor things regarding the project, but you have to understand the rest of it if you want our help to be useful.

  32. #32
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,929

    Re: Gerber Files in VB6

    There are a few optimisation experts around (including Merri and others), and even after reading hundreds of Static's posts I've never seen a reason to think of him being one of them - let alone being "the resident speed geek".

    Based on the very basic optimisation methods you suggested, I doubt he would have got my code under 2 minutes... but I'm willing to bet he did much more than that (like dozens of us do in threads like these), so he might have got somewhere close to my 15 seconds.

    That isn't to say he is in any way a bad coder, just that you seem to have a fairly unique opinion about his specialities.


    Anyhoo, that is enough chit-chat for this thread - if you want to discuss it further then create a thread in the chit-chat forum.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width