[VB6 / AutoCAD] For each door modelspace onwijs traag

Pagina: 1
Acties:
  • 431 views sinds 30-01-2008
  • Reageer

  • Battle Bunny
  • Registratie: Oktober 2001
  • Laatst online: 23-11 19:37
Hoi,

Ik moet een AutoCAD (.dwg) file inlezen en zelf met de data aan de gang gaan (tekst bij ruimtes matchen, dingen in Oracle zetten, etc). Hiervoor heb ik de volgende code:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Dim App As AcadApplication
Dim DWG As AcadDocument
Dim modelSpace As AcadModelSpace
Dim Entity As AcadEntity

Set App = New AutoCAD.AcadApplication
Set DWG = App.Application.Documents.Open("c:\dwgfile.dwg", True)
Set modelSpace = DWG.modelSpace

For Each Entity In modelSpace
   (doe iets)
Next

App.Quit
Set DWG = Nothing
Set App = Nothing


Het gaat om een test dwg met een kleine 12000 entities (lijnen, tekst, etc). Deze For Each doet daar een minuut ofzo over, terwijl AutoCAD dit in een flits kan inlezen. Doe ik iets fout? Het is echt AutoCAD.exe die 100% cpu tijd pakt, dus niet mijn brakke code...

Of, heeft iemand een aanbeveling voor een andere tool waarmee ik DWG kan inlezen?

  • MrDry
  • Registratie: December 2001
  • Laatst online: 01-12 17:20

MrDry

Desperados!

Ook al vanuit autocad (VBA) geprobeerd?

Heb al heel veel gedaan in VBA onder autocad. Supersnel is het niet maar met maar 12.000 objects moet dat geen probleem zijn.

Anders post je de rest van je code eens..kan ik voor je kijken hoe lang het duurt in vba

Quod licet lovi, non licet bovi


  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Wat is nu je probleem???

Als je alles tussen regel 10 en 12 weghaalt dan duurt het nog 1 minuut? Of gaat het dan opeens sneller?
Want volgens mij zit de meeste wachttijd in het stuk code wat je net niet gepost hebt...

  • Battle Bunny
  • Registratie: Oktober 2001
  • Laatst online: 23-11 19:37
Nee, ik heb het niet vanuit autocad geprobeerd, aangezien ik de resultaten (de lijnen, kleuren, rechthoekjes, etc) nodig heb ik mijn VB applicatie. Of is daar ook een andere oplossing voor?

Mijn huidige code atm is:
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
Dim App As AcadApplication
Dim DWG As AcadDocument
Dim modelSpace As AcadModelSpace
Dim Entity As AcadEntity
Dim temp As AcadPolyline
Dim color As AcadAcCmColor
Dim coords() As Double
Dim coords2() As Double
Dim i As Integer
Dim s As String
Dim llCount As Long
Dim llTotal As Long
Dim llColor As Long
Dim BreakLong(3) As Byte

  frmStatus.Init "AutoCAD init"
  Set App = New AutoCAD.AcadApplication
  frmStatus.SetStatus "Open file"
  Set DWG = App.Application.Documents.Open("C:\test.dwg", True)
  Set modelSpace = DWG.modelSpace
  

  llTotal = modelSpace.Count
  For Each Entity In modelSpace
    llCount = llCount + 1
    If llCount Mod 100 = 0 Then
      frmStatus.SetStatus "Entity " & llCount & " van " & llTotal
    End If
    Select Case Entity.ObjectName
      Case "AcDbPoint"
        'coords = Entity.Coordinates
        'Debug.Print "Point: " & UBound(coords)
      Case "AcDbCircle"
      Case "AcDbText"
        'Debug.Print "Text: " & Entity.TextString
      Case "AcDbLine"
        coords = Entity.StartPoint
        's = "X: " & coords(0) & " Y: " & coords(1)
        coords2 = Entity.EndPoint
        's = s & " X: " & coords(0) & " Y: " & coords(1)
        Set color = Entity.TrueColor
        BreakLong(0) = color.EntityColor And &HFF&
        BreakLong(1) = (color.EntityColor And &HFF00&) \ &H100&
        BreakLong(2) = (color.EntityColor And &HFF0000) \ &H10000
        BreakLong(3) = (color.EntityColor And &H7F000000) \ &H1000000

        llColor = RGB(BreakLong(2), BreakLong(1), BreakLong(0))
        ActieveRuimte.Add coords(0), coords2(0), coords(1), coords2(1) , False, llColor, "dinges"
        'Debug.Print "Line: " & UBound(coords) & " " & s
      Case "AcDbArc"
      Case "AcDbPolyline"
        'coords = Entity.Coordinates
        'For i = 0 To UBound(coords) Step 2
        '  s = s & "X: " & coords(i) & " Y: " & coords(i + 1)
        'Next
        'Debug.Print "PolyLine: " & UBound(coords) & s
      Case "AcDbHatch"
      Case "AcDbSolid"
      Case Else
        Debug.Print Entity.ObjectName
    End Select

  Next
  

  App.Quit
  Set DWG = Nothing
  Set App = Nothing
  Set color = Nothing
  
  frmStatus.SetStatus "Done.", True


De kleur zooi heb ik net toegevoegd, maar daar word het *nog* langzamer van! Elke call naar het autocad object duurt stervenslang...

  • Battle Bunny
  • Registratie: Oktober 2001
  • Laatst online: 23-11 19:37
Wat is nu je probleem???

Als je alles tussen regel 10 en 12 weghaalt dan duurt het nog 1 minuut? Of gaat het dan opeens sneller?
Want volgens mij zit de meeste wachttijd in het stuk code wat je net niet gepost hebt...
Mijn probleem is dat een simpele for...each loop door het AutoCAD object 50 seconden duurt, *zonder* enige andere code er tussen (behalve een with ... end with).

Voor 12000 objecten is dit al belachelijk lang, laat staan dat ik straks met 100,000 objecten moet werken. Daarom vraag ik me af of ik iets fout doe, of iemand misschien een snellere (en betere) methode weet...

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 30-11 00:17
Probeer het eens zonder die for each dan. Zit et em in de lus of in dat wat je in die lus met het object doet?

Staan de bestanden lokaal of op een netwerk?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • Battle Bunny
  • Registratie: Oktober 2001
  • Laatst online: 23-11 19:37
Probeer het eens zonder die for each dan. Zit et em in de lus of in dat wat je in die lus met het object doet?

Staan de bestanden lokaal of op een netwerk?
Zonder de for each gaat 't (zoals verwacht) erg snel; het AutoCAD object hoeft dan immers niet elke keer het entity object te setten.

Ik heb het vermoeden dat het 'em daar in: AutoCAD heeft wel het 'AcadEntity' object type, maar dit type kan meerdere vormen aan nemen. Voor een poly line heeft dit andere properties dan voor een point, bijv. Lijkt me niet de snelste methode.

Hoe moeilijk kan het nou zijn om "even" alle entities in een AutoCAD bestand te doorlopen en deze te parsen? Moet toch ZO te doen zijn?!

Het bestand staat trouwens lokaal...

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 30-11 00:17
Battle Bunny schreef op donderdag 14 december 2006 @ 00:37:
Zonder de for each gaat 't (zoals verwacht) erg snel; het AutoCAD object hoeft dan immers niet elke keer het entity object te setten.
Mja, ik bedoelde eigenlijk met een andere constructie dan for each, iets als

Visual Basic:
1
2
For I = 0 to ACAD.Entities.Count - 1
Next I


en dan zo snel mogelijk 'casten' naar het goede object type.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • MrDry
  • Registratie: December 2001
  • Laatst online: 01-12 17:20

MrDry

Desperados!

Zou je nog ff je definitie van ActieveRuimte willen posten? Dan kan ik het echt voor je testen.

Quod licet lovi, non licet bovi


  • Battle Bunny
  • Registratie: Oktober 2001
  • Laatst online: 23-11 19:37
Mja, ik bedoelde eigenlijk met een andere constructie dan for each, iets als

Visual Basic:
1
2
For I = 0 to ACAD.Entities.Count - 1
Next I


en dan zo snel mogelijk 'casten' naar het goede object type.
Goed idee, zal ik zo even testen.
Zou je nog ff je definitie van ActieveRuimte willen posten? Dan kan ik het echt voor je testen.
Die is niet relevant. Dat is gewoon een collection met wat lijnen e.d., die hele regel kun voor een test weg laten.

[edit]
Net getest, maar met een for i = 1 to x kun je niet de juiste properties ophalen, erg maf, Plus dat het ongeveer net zo traag is als een for each ;-(

[ Voor 13% gewijzigd door Battle Bunny op 15-12-2006 13:46 ]


  • Battle Bunny
  • Registratie: Oktober 2001
  • Laatst online: 23-11 19:37
*kick*

  • MrDry
  • Registratie: December 2001
  • Laatst online: 01-12 17:20

MrDry

Desperados!

Als ik onderstaande code in VBA draai doet hij over ruim 185.000 entity's minder dan een seconde. Als je nog wat echo in de immediate window wilt hebben duurt het ca 5 seconden.

De code is dus snel zat.


code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
Public Sub testGOT()

Dim Entity As AcadEntity
Dim temp As AcadPolyline
Dim color As AcadAcCmColor
Dim coords() As Double
Dim coords2() As Double
Dim i As Integer
Dim s As String
Dim llCount As Long
Dim llTotal As Long
Dim llColor As Long
Dim BreakLong(3) As Byte
Dim start As Date

Dim ActieveRuimte As Variant
  llTotal = ThisDrawing.modelspace.Count
  start = Now
  For Each Entity In ThisDrawing.modelspace
    llCount = llCount + 1
    If llCount Mod 100 = 0 Then
      Debug.Print "Entity " & llCount & " van " & llTotal
    End If
    Select Case Entity.ObjectName
      Case "AcDbPoint"
        'coords = Entity.Coordinates
        'Debug.Print "Point: " & UBound(coords)
      Case "AcDbCircle"
      Case "AcDbText"
        'Debug.Print "Text: " & Entity.TextString
      Case "AcDbLine"
        coords = Entity.StartPoint
        's = "X: " & coords(0) & " Y: " & coords(1)
        coords2 = Entity.EndPoint
        's = s & " X: " & coords(0) & " Y: " & coords(1)
        Set color = Entity.TrueColor
        BreakLong(0) = color.EntityColor And &HFF&
        BreakLong(1) = (color.EntityColor And &HFF00&) \ &H100&
        BreakLong(2) = (color.EntityColor And &HFF0000) \ &H10000
        BreakLong(3) = (color.EntityColor And &H7F000000) \ &H1000000

        llColor = RGB(BreakLong(2), BreakLong(1), BreakLong(0))
        ''ActieveRuimte.Add coords(0), coords2(0), coords(1), coords2(1), False, llColor, "dinges"
        'Debug.Print "Line: " & UBound(coords) & " " & s
      Case "AcDbArc"
      Case "AcDbPolyline"
        'coords = Entity.Coordinates
        'For i = 0 To UBound(coords) Step 2
        '  s = s & "X: " & coords(i) & " Y: " & coords(i + 1)
        'Next
        'Debug.Print "PolyLine: " & UBound(coords) & s
      Case "AcDbHatch"
      Case "AcDbSolid"
      Case Else
        ''Debug.Print Entity.ObjectName
    End Select

  Next
    
    MsgBox llCount & " Entitys done in " & DateDiff("s", start, Now) & " seconds"

  
End Sub

Quod licet lovi, non licet bovi


  • Battle Bunny
  • Registratie: Oktober 2001
  • Laatst online: 23-11 19:37
Als ik onderstaande code in VBA draai doet hij over ruim 185.000 entity's minder dan een seconde. Als je nog wat echo in de immediate window wilt hebben duurt het ca 5 seconden.

De code is dus snel zat.
In elk geval bedankt voor het testen, ook al is dit wel raar. Dit is dus vanuit AutoCAD zelf, he? Blijkbaar zit de vertraging in het over halen van het object?

Zou er een andere oplossing zijn?

  • MrDry
  • Registratie: December 2001
  • Laatst online: 01-12 17:20

MrDry

Desperados!

Je hebt gelijk. Vanuit VB6 is het niet vooruit te branden. Waarom kan het niet vanuit VBA eigenlijk? Je kan hier toch ook alles mee?

Quod licet lovi, non licet bovi


  • Battle Bunny
  • Registratie: Oktober 2001
  • Laatst online: 23-11 19:37
Je hebt gelijk. Vanuit VB6 is het niet vooruit te branden. Waarom kan het niet vanuit VBA eigenlijk? Je kan hier toch ook alles mee?
In het kort: Ik heb een AutoCAD tekening en hier moet ik alle lijnen uit halen. Vervolgens moet ik hier mee aan het rekenen (tot zo ver zou het nog in VBA kunnen) en in een Oracle DB gooien. Daarna moet ik in mijn eigen programma de lijnen die ik nog over heb tekenen in een picturebox zodat een user daar zelf mee aan de gang kan.

Dat laatste wil (en kan niet?) ik niet in AutoCAD maken. Maar als er een tussen oplossing is, hoor ik dat graag :)

  • MrDry
  • Registratie: December 2001
  • Laatst online: 01-12 17:20

MrDry

Desperados!

Gaat het om een soort batch processing van veel tekeningen?

Anders zou je vanuit je app autocad kunnen starten en automatisch in autocad bij het opstarten je tekening doorlopen met je VB routine. Ook een conenctie met een database via ADO is natuurlijk geen probleem. Zorg dat je je overige entity gegevens ergens opslaat waar je weer bij kan als autocad weer afgesloten is.

Zou zo moeten kunnen behalve als het om veel tekeningen gaat. Elke keer autocad starten duurt dan domweg te lang....

Oja...Met pictureboxen aan de gang gaan kan wel in VBA hoor. Je kan bijna alles in VBA muv bepaalde event handlers en modelless forms maken.

Quod licet lovi, non licet bovi


  • Battle Bunny
  • Registratie: Oktober 2001
  • Laatst online: 23-11 19:37
Ja, het gaat wel om een soort batch processing. Maar jouw suggestie is niet eens zo vreemd, je kunt namelijk het AutoCAD object hergebruiken en elke keer een andere tekening openen. Ik zou dan eventueel alles vanuit AutoCAD (dus met AutoCADs VBA?) in een tijdelijke DB kunnen gooien en dat vervolgens inlezen... Omslachtig, maar waarschijnlijk wel sneller dan deze soep.

  • MrDry
  • Registratie: December 2001
  • Laatst online: 01-12 17:20

MrDry

Desperados!

Klopt. Weet niet welke versie je van autocad hebt maar vanaf 2006 is de VBA heel redelijk. (hoe nieuwer hoe meer systemevents je kan afvangen)

Quod licet lovi, non licet bovi

Pagina: 1