| |  | Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte | | |  | PNY präsentiert die neue NVIDIA RTX A400 und die A1000 Grafikkarte, eine Pressemitteilung
|
Autor
|
Thema: Block_Entities_auslesen (2907 mal gelesen)
|
cadx Mitglied Konstrukteur

 Beiträge: 12 Registriert: 28.01.2008 AutoCAD 2012 Mechanical
|
erstellt am: 04. Jul. 2011 17:50 <-- editieren / zitieren --> Unities abgeben:         
Hallo, ich arbeite mit VB.NET und möchte as Blöcken (Blockreferenzen) die Daten der Entities auslesen. z.B. die Endpunkte einer Linie usw. unter VB6 ist das so programmiert: BlkRef ist die Blockreference Entitiy Set BlkObj = ThisDrawing.Blocks.Item(BlkRef.Name) For Each BlkEnt In BlkObj ElementCounter = ElementCounter + 1 TextBox6.Text = ElementCounter Select Case BlkEnt.ObjectName Case "AcDbBlockReference" If ProcessBlock Then GetBlk BlkEnt Case "AcDbLine" If ProcessLine Then GetLine BlkEnt Case "AcDbCircle" If ProcessCircle Then GetCircle BlkEnt Case "AcDbArc" If ProcessArc Then GetArc BlkEnt Case "AcDbPolyline" If ProcessPolyl Then GetLwPLine BlkEnt Case "AcDb2dPolyline" ' Rechteck If Process2dPolyl Then Get2DPLine BlkEnt Case "AcDbText" If ProcessText Then GetText BlkEnt Case "AcDbMText" If ProcessMText Then GetMtext BlkEnt End Select Next BlkEnt Set BlkObj = Nothing Bin froh und dankbar für jede Hilfe!
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 04. Jul. 2011 18:06 <-- editieren / zitieren -->
Hi, ausser dass 'ThisDrawing' nicht so funkt, geht alles so wie Du beschrieben hast (solange Du über COM arbeitest und danach sieht's ja aus). Und damit vermisse ich Deine eigentliche Frage. Hast Du irgendwo Fehler (Fehlermeldung, Zeile des Fehlers, ...?) Oder was ist das Problem? - alfred - ------------------ www.hollaus.at |
cadx Mitglied Konstrukteur

 Beiträge: 12 Registriert: 28.01.2008 AutoCAD 2012 Mechanical
|
erstellt am: 05. Jul. 2011 11:58 <-- editieren / zitieren --> Unities abgeben:         
Nein dieser Code funktioniert sauber unter VBA. Ich möchte das Programm in VB.NET umschreiben und als DLL in AutoCAD einbinden. Nun hänge ich im Bereich Block durchsuchen und die Entities des gewählten Blocks auslesen. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 05. Jul. 2011 12:06 <-- editieren / zitieren -->
Hi, >> Ich möchte das Programm in VB.NET umschreiben und als DLL in AutoCAD einbinden. >> Nun hänge ich im Bereich Block durchsuchen und die Entities des gewählten Blocks Wo bist Du denn gerade? Ich seh nur Code, der so, wie er da steht, funktionieren sollte (so es die Funktionen GetBlk/GetLine/.... gibt), auch in VB.NET Wenn Du schreibst, DU möchtest es umschreiben, dann hätte ich jetzt die Stelle erwartet, an welcher Du beim Code-Schreiben steckst, oder wo Fehler kommen, .... nur das sehe ich hier nicht. Kann es sein, dass Du wünscht, dass wir Dein VB.NET-Projekt erstellen? - alfred - ------------------ www.hollaus.at |
cadx Mitglied Konstrukteur

 Beiträge: 12 Registriert: 28.01.2008 AutoCAD 2012 Mechanical
|
erstellt am: 05. Jul. 2011 13:23 <-- editieren / zitieren --> Unities abgeben:         
Hallo Alfred, als mein VB.NET Programm läuft so weit bis auf das Thema mit den Blöcken. Dazu fehlt mir etwas der Durchblick Hier der aktuelle Codebereich: ' Blockreferenz nach Objekten durchsuchen Function GetBlk(ByVal BlkRef As BlockReference) As Boolean 'Da steht noch einiges.... Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction() acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) acBlkTblRec = BlkRef.Id.GetObject(, OpenMode.ForRead) 'BlkObj = acTrans.GetObject(BlkRef.ObjectId, OpenMode.ForRead) 'ThisDrawing.Blocks.Item(BlkRef.Name) For Each ObjectId As ObjectId In acBlkTblRec BlkEnt = CType(ObjectId.GetObject(OpenMode.ForRead), Entity) ElementCounter = ElementCounter + 1 TextBox6.Text = ElementCounter.ToString DoEvents() tb_info1.Text = tb_info1.Text & ElementCounter.ToString & " : " & BlkEnt.GetRXClass.Name.ToString Select Case BlkEnt.GetRXClass.Name.ToString Case "AcDbBlockReference" If ProcessBlock Then GetBlk(BlkEnt) Case "AcDbLine" If ProcessLine Then GetLine(BlkEnt) Case "AcDbCircle" If ProcessCircle Then GetCircle(BlkEnt) Case "AcDbArc" If ProcessArc Then GetArc(BlkEnt) Case "AcDbPolyline" If ProcessPolyl Then GetLwPLine(BlkEnt) Case "AcDb2dPolyline" ' Rechteck If Process2dPolyl Then Get2DPLine(BlkEnt) Case "AcDbText" If ProcessText Then GetText(BlkEnt) Case "AcDbMText" If ProcessMText Then GetMtext(BlkEnt) 'Case "AmgStdPart" 'GetMPart BlkEnt Case Else ErrElementCount = ErrElementCount + 1 If UnbekannteMelden Then ShUnbekannt(BlkEnt) End Select Next ObjectId BlkObj = Nothing Xoffs = Xoffs - BlkXoffs Yoffs = Yoffs - BlkYoffs TransX = SavTransX TransY = SavTransY TransRot = SavTransRot GetBlk = (Err.Number = 0) End Using end Code: Die Programmteile wie GetLine, GetArc usw sind eigene Routinen die funktionieren. Der Programmteil GetBlk arbeitet rekursiv und soll die Blöcke in den Blöcken bis zum letzten Block durchsuchen. Letztendlich benötige ich die Daten aller Linien, Kreise und Bögen die in dem Block enthalten sind. Im Anhang habe ich das komplette Projekt eingestellt. - Gruß Thomas - Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 05. Jul. 2011 14:27 <-- editieren / zitieren -->
Hi, wie rufst Du denn diese Funktion GetBlk() überhaupt auf? Ich sehe weder einen Aufruf im Code noch einen Aufruf, wo das Form geladen wird (in welchem der Code drinsteht? - alfred - ------------------ www.hollaus.at |
cadx Mitglied Konstrukteur

 Beiträge: 12 Registriert: 28.01.2008 AutoCAD 2012 Mechanical
|
erstellt am: 05. Jul. 2011 14:55 <-- editieren / zitieren --> Unities abgeben:         
Hallo, der Aufruf geht über Class1 --> La_cad2cnc Imports System.IO Imports Autodesk.AutoCAD.Runtime Imports Autodesk.AutoCAD.ApplicationServices Imports Autodesk.AutoCAD.DatabaseServices Imports Autodesk.AutoCAD.EditorInput Public Class Class1 <CommandMethod("La_cad2cnc")> _ Public Sub La_cad2cnc() Dim f1 As New Menu f1.Show() End Sub End Class Damit startet das Form Menu.vb Mit der Taste START geht los Private Sub cmdApply_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdApply.Click MachEinDxf() End Sub Der Aufruf von GetBlk ist derzeit auskommentiert. For Each acSSobj As SelectedObject In acSSet If Not IsDBNull(acSSobj) Then ElementCounter = ElementCounter + 1 TextBox6.Text = ElementCounter.ToString DoEvents() acEnt = acTrans.GetObject(acSSobj.ObjectId, OpenMode.ForRead) tb_info1.Text = tb_info1.Text & ElementCounter.ToString & " : " & acEnt.GetRXClass.Name.ToString Select Case acEnt.GetRXClass.Name.ToString Case "AcDbBlockReference" BlkRef = acEnt 'If ProcessBlock Then GetBlk(BlkRef) tb_info1.Text = tb_info1.Text & " : " & BlkRef.Name & " geht n. nicht" Case "AcDbLine" If ProcessLine Then GetLine(acEnt) Case "AcDbCircle" usw...... - Gruß Thomas -
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 05. Jul. 2011 15:33 <-- editieren / zitieren -->
Hi, bin ich lästig? Die ersten Hürden (mit auskommentiertem Code, der zum Test notwendig ist ) hätt ma mal dann. Jetzt zur nächsten Hürde ==> Du filterst gleich am Anfang auf irgendwelche Layer (AM_0, AM_6) und bevor ich später dann auch noch draufkomm, auf welche Blocknamen, Z-Werte, Skalierfaktoren oder sonstiges noch gefiltert wird, möcht ich keine Zeichnung erstellen, die den Filterkriterien entspricht. Ich möchte auch den Code noch so runterbrechen, dass Du den dann nicht mehr zusammenbekommst, also: Bitte eine DWG. - alfred - ------------------ www.hollaus.at |
cadx Mitglied Konstrukteur

 Beiträge: 12 Registriert: 28.01.2008 AutoCAD 2012 Mechanical
|
erstellt am: 06. Jul. 2011 10:17 <-- editieren / zitieren --> Unities abgeben:         
Hallo, im Anhang die Musterzeichnung. Hab auch mal das "alte" funktionierernde VBA Programm angehängt. Die Filter auf AM_0, AM_6 usw sind richtig gesetzt und funktioniert richtig. Es sind nur Entities auf diesen Layers interessant. Ich hänge nur in dem Programmteil GetBlk und möchte eine über die Selction gefundene Blockreference nach Entities durchsuchen. Rekursiv deshalb weil ja eine oder mehrere verschachtelte Blockreferences darin enthalten sein können. Mir ist nicht klar wo ich die Entities innerhalb der Blockreferences finde. - Thomas - Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
cadx Mitglied Konstrukteur

 Beiträge: 12 Registriert: 28.01.2008 AutoCAD 2012 Mechanical
|
erstellt am: 07. Jul. 2011 16:46 <-- editieren / zitieren --> Unities abgeben:         
Hallo, habs jetzt geschafft Falls jemand damit etwas anfangen kann hier der code: ' Blockreferenz nach Objekten durchsuchen Function GetBlk(ByVal BlkRef As BlockReference) As Boolean Dim BlkEnt As Entity DoEvents() If Not CheckBlock(BlkRef.Name) Then Return False Exit Function End If Dim ExObjects As DBObjectCollection = New DBObjectCollection BlkRef.Explode(ExObjects) If (ExObjects IsNot Nothing) AndAlso (ExObjects.Count <> 0) Then For Each BlkEnt In ExObjects If (ScanKontur And (BlkEnt.Layer = InKonturLayer)) Or (ScanBiegelinie And (BlkEnt.Layer = InBiegeLayer)) _ Or (ScanGravur And (BlkEnt.Layer = InGravurLayer)) Or (ScanLaserText And (BlkEnt.Layer = InLasTxtLayer)) Then ElementCounter = ElementCounter + 1 TextBox6.Text = ElementCounter.ToString DoEvents() tb_info1.Text = tb_info1.Text & ElementCounter.ToString & " : " & BlkEnt.GetRXClass.Name.ToString Select Case BlkEnt.GetRXClass.Name.ToString Case "AcDbBlockReference" tb_info1.Text = tb_info1.Text & " : " & BlkRef.Name If ProcessBlock Then GetBlk(BlkEnt) Case "AcDbLine" If ProcessLine Then GetLine(BlkEnt) Case "AcDbCircle" If ProcessCircle Then GetCircle(BlkEnt) Case "AcDbArc" If ProcessArc Then GetArc(BlkEnt) Case "AcDbPolyline" If ProcessPolyl Then GetLwPLine(BlkEnt) Case "AcDb2dPolyline" ' Rechteck If Process2dPolyl Then Get2DPLine(BlkEnt) Case "AcDbText" If ProcessText Then GetText(BlkEnt) Case "AcDbMText" If ProcessMText Then GetMtext(BlkEnt) Case Else ErrElementCount = ErrElementCount + 1 If UnbekannteMelden Then ShUnbekannt(BlkEnt) tb_info1.Text = tb_info1.Text & " Unbekannt!" End Select tb_info1.Text = tb_info1.Text & vbCrLf End If Next BlkEnt End If ExObjects.Dispose() GetBlk = (Err.Number = 0) On Error GoTo 0 End Function - Thomas - Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 07. Jul. 2011 17:52 <-- editieren / zitieren -->
Hi, sorry, kam bis jetzt nicht dazu, mit Deiner Zeichnung zu probieren. Deine Methode, die BlockReference zu Explodieren, ist eine Variante, die Elemente zu zählen. Ich hätte aber (um Performance zu sparen) doch Deinen ersten Ansatz weiterverfolgt, nämlich die Elementanzahl aus der Blockdefinition zu ermitteln, als solches wäre der Workflow: a) aus BlockReference über die BlockDefintions-ID die Blockdefinition nehmen b) die Blockdefinition durchgehen, Elemente zählen und sollte in der Blockdefinition wieder eine BlockReference enthalten sein, dann rekursiv so weiter. Neben dem Punkt, dass die BlockReference nicht explodierbar sein kann (z.B. ungleichmäßig skaliert, es gibt auch noch andere Dummheiten, wie das zustandekommen kann), ist auch das .EXPLODE langsamer, da es Elemente anlegen muss. Suchst Du Dir aber die BlockDefinition, dann sind dort schon die Elemente vorhanden, die Du nurmehr durchzählen musst. Zugegeben, es kann auch einen Nachteil geben, wenn die BlockDefinition ein dynamischer Block ist, dann kann es von den Parametern der davon abgeleiteten BlockReference abhängen, wie viele Elemente beim Explode zustandekommen, das kann durchaus unterschiedlich sein zur BlockDefinition selbst. Beispiel: in der BlockDefinition hast Du einen Array-Parameter, dann bekommst Du nur ein Element (welches über den Array-Parameter zu vervielfältigen ist), aber in der BlockReference hast Du u.U. 27 Array-Elemente drin, die in der Definition ja so nicht ablesbar wären. Auch ein Sichtbarkeitsparameter im dynamischen Block kann da eine Rolle spielen. Lass wissen, wenn ich Dir das mit BlockDefinition doch noch bauen soll (jetzt hätte ich ja eine passende Zeichnung ) Wenn Du mit Deiner BlockReference-Variante glücklich bist, dann passt's auch so. - alfred - PS: wenn Du mit XRef arbeitest, dann Achtung bei Deinem rekursiven Element-Sammeln. ------------------ www.hollaus.at |

| |
cadx Mitglied Konstrukteur

 Beiträge: 12 Registriert: 28.01.2008 AutoCAD 2012 Mechanical
|
erstellt am: 08. Jul. 2011 09:53 <-- editieren / zitieren --> Unities abgeben:         
Hallo Alfred, danke für die Rückmeldung das Angebot und Deine Einsatz Mit der jetzigen Lösung bin ich soweit zufrieden zumal die Sekündchen mehr bei unseren Zeichnungen nicht ins Gewicht fallen. - Thomas - Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
| Anzeige.:
Anzeige: (Infos zum Werbeplatz >>)
 |