| |
| 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: Punkte aus Blockreferenz (1358 mal gelesen)
|
Silvan01 Mitglied
Beiträge: 128 Registriert: 28.04.2009 AutoCAD Civil 2009 AutoCAD Civil 2010 Visual Studio 2008
|
erstellt am: 23. Sep. 2009 13:46 <-- editieren / zitieren --> Unities abgeben:
Hallo Zusammen, in einem Programm von mir (eine in VB.Net geschriebene .dll) setze ich eine Blockreferenz auf meine Zeichnung und will von dieser verschiedene Punkte auslesen kann mir da jemand weiterhelfen? Den Block, den ich einfügen soll hat die Form eines Tisches mit 4 Beinen an jedem Bein ist ein Punkt. Von diesen 4 Punkten möchte ich gern die Koordinaten haben. Grüße Silvan Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 23. Sep. 2009 13:51 <-- editieren / zitieren -->
Hi, explodier die BlockReference, damit bekommst Du eine DatabaseServices.DBObjectCollection der explodierten Elemente, diese suchst Du nach Deinen gewünschten Punkten durch, dann hast Du die Koordinaten. Nicht vergessen, danach der Speicher-Reinlichkeit wegen die in dieser Collection retournierten (nicht TransAction-residenten) Elemente mit .Dispose wieder entlassen. - alfred - ------------------ www.hollaus.at |
Brischke Moderator CAD on demand GmbH
Beiträge: 4187 Registriert: 17.05.2001 AutoCAD 20XX, defun-tools
|
erstellt am: 24. Sep. 2009 08:05 <-- editieren / zitieren --> Unities abgeben: Nur für Silvan01
Zitat: Original erstellt von a.n.: ... explodier die BlockReference, damit bekommst Du eine DatabaseServices.DBObjectCollection der explodierten Elemente, diese suchst Du nach Deinen gewünschten Punkten durch, dann hast Du die Koordinaten. ...
Hallo Silvan, hallo Alfred, der von Alfred beschriebene Weg ist sicher ein funktionierendes Konstrukt. Aber, ich halte dies nicht für den richtigen Weg. Ich denke, du solltest die Koordinaten aus der Blockdefinition ermitteln, und diese dann auf die Blockreferenz umrechnen. Das ist ein wenig Mathematik (Vektorrechnung), verhindert aber, dass irgendwelche Objekte umherschwirren, die nun wirklich nicht notwendig sind. Bei Fragen ... Grüße! Holger ------------------ Holger Brischke CAD on demand GmbH Individuelle Lösungen von Heute auf Morgen. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Silvan01 Mitglied
Beiträge: 128 Registriert: 28.04.2009 AutoCAD Civil 2009 AutoCAD Civil 2010 Visual Studio 2008
|
erstellt am: 24. Sep. 2009 09:15 <-- editieren / zitieren --> Unities abgeben:
Hallo Brischke, Zitat:
Ich denke, du solltest die Koordinaten aus der Blockdefinition ermitteln, und diese dann auf die Blockreferenz umrechnen.Bei Fragen ...
ja da hab ich gleich mal ne Frage: Was genau meinst du mit "Koordinaten aus der Blockdefinition ermitteln" bzw. wie komme ich an die Daten der Punkte? Meinst du dann folgenden Ablauf: Koordinaten der Punkte aus Blockdefinition ermitteln, Koordinaten vom Basispunkt der platzierten Blockreferenz ermitteln und anschließend daraus die Koordinaten der Punkte ausrechnen? Grüße Silvan
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 24. Sep. 2009 09:28 <-- editieren / zitieren -->
Hi, @Holger: >> Ich denke, du solltest die Koordinaten aus der Blockdefinition ermitteln, >> und diese dann auf die Blockreferenz umrechnen. Das ist ein wenig >> Mathematik (Vektorrechnung), verhindert aber, dass irgendwelche Objekte >> umherschwirren, die nun wirklich nicht notwendig sind Schwirren keine Objekte herum, da beim Explode in dotNET keine Elemente in der Datenbank generiert werden, damit die Funktion auch nicht mit Hinzufügen zur Datenbank/Hinzufügen zum Undo-space etc. zu tun hat. Die Funktion ist schnell und einfach und Du hast keine Abhängigkeiten von speziellen Blockvarianten wie z.B. bei dynamischen Blöcken (soll heissen geht auch mit dynamischen BlockReferenzen). @Silvan:
>> Was genau meinst du mit "Koordinaten aus der Blockdefinition ermitteln" >> bzw. wie komme ich an die Daten der Punkte?
Zu den Punkten kannst Du in der Blockdefinition kommen. D.h. der Weg wäre dann: a) Du suchst diese Punkte in der Blockdefinition (statt in der BlockReference) b) Du ermittelst die Koordinaten dieser und merkst sie Dir als Point3D-Objects c) Du holst Dir vom Block die Block-Transformationsmatrix (in dieser steht die Verschiebung/Rotation/Skalierung drin) d) Du transformierst jeden der obigen Punkte um diese Matrix Zusatz: hast Du einen dynamischen Block in der Hand, gibt's Brösel. HTH, - alfred -
------------------ www.hollaus.at |
Silvan01 Mitglied
Beiträge: 128 Registriert: 28.04.2009 AutoCAD Civil 2009 AutoCAD Civil 2010 Visual Studio 2008
|
erstellt am: 24. Sep. 2009 10:02 <-- editieren / zitieren --> Unities abgeben:
Hi, @alfred habe das mit dem Explode einmal gemacht und verschiedene Datenbankobjekte bekommen. Unter anderem eine weitere Blockreferenz. Das heißt, wenn ich mich nicht irre, dass es eine Blockreferenz in einer Blockreferenz (also verschachtelt) ist oder? Außerdem würde ich mich bei Möglichkeit 2. interessieren wie ich die Definition des Blockes bekomme? Danke für eure Hilfe Grüße Silvan
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 24. Sep. 2009 10:10 <-- editieren / zitieren -->
Hi, >> Das heißt, wenn ich mich nicht irre, dass es eine Blockreferenz in einer >> Blockreferenz (also verschachtelt) ist oder? Ist anzunehmen. Sind die Punkte in diesen Subblockreferenzen enthalten, dann musst Du die Transformationsmatrix mehrfach anwenden. Wenn Du eine Chance hast, die Blöcke selbst zu definieren und dieser Fall mit der Punktermittlung öfter vorkommt, dann überleg Dir das, macht früher oder später Aufwand. >> würde ich mich bei Möglichkeit 2. interessieren wie ich die Definition des Blockes bekomme?
Solange es sich nicht um einen dynamischen Block handelt, dann ist die Vorgehensweise wie folgt: a) aus Deiner BlockReference holst Du Dir die Eigenschaft 'BlockTableID' b) mit einer TransAction holst Du Dir mit dieser ObjectID den BlockTableRecord c) und diesen kannst Du mit einem Enumerator oder mit
Code: For Each tObjID as DatabaseServices.ObjectID in tBlTabRec Dim tDBEnt as DatabaseServices.Entity = TrAct.GetObject(tObjID, DatabaseServices.OpenMode.ForRead, True, True) 'und jetzt hast Du ein Element der BlockDefinition in der Hand '...
die Blockdefinition durchscannen.- alfred - ------------------ www.hollaus.at |
Silvan01 Mitglied
Beiträge: 128 Registriert: 28.04.2009 AutoCAD Civil 2009 AutoCAD Civil 2010 Visual Studio 2008
|
erstellt am: 24. Sep. 2009 12:22 <-- editieren / zitieren --> Unities abgeben:
Hallo, also die Möglichkeit von alfred find ich vom Verständnis her leichter. Konnte es auch umsetzten und funktioniert genau wie ichs mir vorgestellt hab! Die zweite Möglichkeit kommt mir umständlicher vor. Danke für eure Hilfe! Grüße Silvan Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Brischke Moderator CAD on demand GmbH
Beiträge: 4187 Registriert: 17.05.2001 AutoCAD 20XX, defun-tools
|
erstellt am: 24. Sep. 2009 13:58 <-- editieren / zitieren --> Unities abgeben: Nur für Silvan01
Zitat: Original erstellt von a.n.: ... Schwirren keine Objekte herum, da beim Explode in dotNET keine Elemente in der Datenbank generiert werden ...
... stimmt, da war ich wohl in Gedanken bei den anderen Möglichkeiten der Programmierung, beidenen eben genau dieser Aspekt eine Rolle spielt. Grüße Holger ------------------ Holger Brischke CAD on demand GmbH Individuelle Lösungen von Heute auf Morgen. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Brischke Moderator CAD on demand GmbH
Beiträge: 4187 Registriert: 17.05.2001 AutoCAD 20XX, defun-tools
|
erstellt am: 24. Sep. 2009 14:00 <-- editieren / zitieren --> Unities abgeben: Nur für Silvan01
Zitat: Original erstellt von Silvan01: ... Die zweite Möglichkeit kommt mir umständlicher vor. ...
... da hast du wohl Recht. Aber wie Alfred schon geschrieben hat-> im .Net schwirren keine Objekte rum, womit dan wohl auch der erste Weg ohne Probleme gegangen werden kann. Grüße Holger ------------------ Holger Brischke CAD on demand GmbH Individuelle Lösungen von Heute auf Morgen. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Silvan01 Mitglied
Beiträge: 128 Registriert: 28.04.2009 AutoCAD Civil 2009 AutoCAD Civil 2010 Visual Studio 2008
|
erstellt am: 16. Okt. 2009 10:15 <-- editieren / zitieren --> Unities abgeben:
Hallo Zusammen, ich habe Alfreds Beispiel folgendermaßen umgesetzt: If tSelSet IsNot Nothing Then If tSelSet.Count > 0 Then For Each obj As ObjectId In tSelSet.GetObjectIds Dim bref As BlockReference = TryCast(tTrAct.GetObject(obj, OpenMode.ForRead, True, True), BlockReference) If bref <> Nothing Then Dim Objects As DBObjectCollection = New DBObjectCollection bref.Explode(Objects) If Objects.Count <> 0 Then For Each pnt As Point3d In Objects PointCollection.Add(pnt) Next End If End If Next End If End If Bei der fett markierten Zeile kommt der Fehler ich ging mal davon aus, dass es daran liegt, dass keine Point3d Objekte zu finden waren also hab ich nachgesehen und es waren anscheinend nur dbPoint Objekte. Ich wollte anschließend einfach die innere For-Schleife ersetzen: For Each pnt As DBPoint In Objects PointCollection.Add(TryCast(pnt, Point3d)) Next Dabei wird mir aber angezeigt, dass es der Trycast Operand ein reference type und kein value type sein muss?!? Was kann ich tun um an jeden Punkt ranzukommen? Grüße Silvan Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 16. Okt. 2009 11:31 <-- editieren / zitieren -->
Hi Silvan, die retournierte Collection enthält DBObjects, castbar (in diesem Zusammenhang) zu Entity, aber nicht zu Geometry.Point3D (welches nur in einer Eigenschaft 'Position' des AutoCAD-Punkts enthalten ist)! Code: bref.Explode(Objects) If Objects.Count <> 0 Then For Each tEnt As Entity In Objects if tEnt.Gettype.Equals(gettype(DBPoint)) then 'erst hier weisst du, dass es sich um einen AutoCAD-Punkt handelt PointCollection.Add(CType(tEnt,DBPoint).Position) 'und erst kommen wir zum Typ Geometry.Point3D end if Next End If
HTH, - alfred - ------------------ www.hollaus.at |
Silvan01 Mitglied
Beiträge: 128 Registriert: 28.04.2009 AutoCAD Civil 2009 AutoCAD Civil 2010 Visual Studio 2008
|
erstellt am: 19. Okt. 2009 09:17 <-- editieren / zitieren --> Unities abgeben:
Hi nochmal, ich habe die Verbesserung von Alfred eingesetzt, jetzt treten dennoch häufig Probleme auf. Ich bekomme einen Exception Fehler kann ihn aber nicht auswerten. Wenn ich das Programm starte und anschließend auf anhalten klicke markiert mir das Visual Studio folgende Zeile: bref.Explode(Objects) If Objects.Count <> 0 Then als den nächsten Step. Kann es bei dem bref.explode zu irgendwelchen weiteren Problemen kommen? Grüße Silvan
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 19. Okt. 2009 09:42 <-- editieren / zitieren -->
Hi, ich gehe davon aus, dass Du zuvor 'Objects' deklariert hast als DBObjectCollection Weiters das IF-Statement umdrehen auf:
Code: If (Objects isnot nothing) andalso (Objects.Count <> 0) Then
Und last but not least, des sauberen Memories wegen solltest Du die Objekte, die aus dem Explode kommen auch mit '.Dispose' ordnungsgemäß vertschüssen. - alfred - ------------------ www.hollaus.at |
Silvan01 Mitglied
Beiträge: 128 Registriert: 28.04.2009 AutoCAD Civil 2009 AutoCAD Civil 2010 Visual Studio 2008
|
erstellt am: 19. Okt. 2009 10:06 <-- editieren / zitieren --> Unities abgeben:
Hi Alfred, das mit dem if objects isnot Nothing and also Objects.Count <> 0 hatte ich bereits drinnen habe das Programm um das Objects.dispose erweitert. Der Fehler tritt aber leider immernoch auf es wird wieder die markierte Stelle als nächster Step angezeigt. If tSelSet.Count > 0 Then For Each obj As ObjectId In tSelSet.GetObjectIds Dim bref As BlockReference = TryCast(tTrAct.GetObject(obj, OpenMode.ForRead, True, True), BlockReference) If bref <> Nothing Then Dim Objects As DBObjectCollection = New DBObjectCollection bref.Explode(Objects) If Objects IsNot Nothing AndAlso Objects.Count <> 0 Then For Each tEnt As Entity In Objects If tEnt.GetType.Equals(GetType(DBPoint)) Then PointCollection.Add(CType(tEnt, DBPoint).Position) End If Next Objects.Dispose() End If End If Next End If Grüße Silvan Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 19. Okt. 2009 12:04 <-- editieren / zitieren -->
Hi, mein Code wäre:
Code: If tSelSet.Count > 0 Then For Each obj As ObjectId In tSelSet.GetObjectIds Dim bref As BlockReference = TryCast(tTrAct.GetObject(obj, OpenMode.ForRead, True, True), BlockReference) 'kommen aus dem SelectionSet wirklich nur BlockRef's raus? If bref isnot Nothing Then Dim Objects As DBObjectCollection = New DBObjectCollection bref.Explode(Objects) If (Objects IsNot Nothing) AndAlso (Objects.Count <> 0) Then For Each tEnt As Entity In Objects If tEnt.GetType.Equals(GetType(DBPoint)) Then PointCollection.Add(CType(tEnt, DBPoint).Position) End If tEnt.Dispose Next Objects.Dispose() End If End If Next End If
>> Ich bekomme einen Exception Fehler kann ihn aber nicht auswerten.
Und dazu hätte ich die Frage, was damit gemeint ist, wie kommst Du auf 'ich bekomme eine Exception' wenn diese 'nicht auswertbar ist'/beim Debug daher scheinbar nicht unterbricht (ich nehme wohl an, dass bei Dir bei Fehler auf Abbruch gestellt ist? - alfred - ------------------ www.hollaus.at |
Silvan01 Mitglied
Beiträge: 128 Registriert: 28.04.2009 AutoCAD Civil 2009 AutoCAD Civil 2010 Visual Studio 2008
|
erstellt am: 20. Okt. 2009 08:32 <-- editieren / zitieren --> Unities abgeben:
|
Silvan01 Mitglied
Beiträge: 128 Registriert: 28.04.2009 AutoCAD Civil 2009 AutoCAD Civil 2010 Visual Studio 2008
|
erstellt am: 12. Nov. 2009 12:53 <-- editieren / zitieren --> Unities abgeben:
Hallo Nochmal, ich hab noch eine weitere Frage und zwar hat sich das "Punkt" Objekt nun zu einem "Koordinatenpunkt" geändert deshalb funktioniert die folgende Zeile nicht mehr. Code: If tEnt.GetType.Equals(GetType(DBPoint)) Then
Kann mir jemand sagen, was ich jetzt bei dem 2. GetType einfügen muss? Tia & Grüße Silvan
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 12. Nov. 2009 14:17 <-- editieren / zitieren -->
Hi Silvan, >> hat sich das "Punkt" Objekt nun zu einem "Koordinatenpunkt" geändert Dann mach einen BreakPoint bei der gezeigten Zeile, klick 'tEnt' an ==> rechte Maustaste ==> Schnllüberwachung und Du siehst den Objekttyp. Wenn Du es im Code ausgeben willst, dann geht das auch, z.B. mit:
Code: debug.print tEnt.getType.FullName
- alfred - ------------------ www.hollaus.at |
Silvan01 Mitglied
Beiträge: 128 Registriert: 28.04.2009 AutoCAD Civil 2009 AutoCAD Civil 2010 Visual Studio 2008
|
erstellt am: 12. Nov. 2009 14:44 <-- editieren / zitieren --> Unities abgeben:
|
Ex-Mitglied
|
erstellt am: 12. Nov. 2009 15:16 <-- editieren / zitieren -->
Hi, hast Du die Civil-Libraries geladen? Ich vermute mal, dass Du damit den Civil-punkt bekommst, die Eigenschaften dazu werden dann auch nur verfügar gemacht, wenn Du auch darauf Zugriff hast. - alfred - ------------------ www.hollaus.at |
Silvan01 Mitglied
Beiträge: 128 Registriert: 28.04.2009 AutoCAD Civil 2009 AutoCAD Civil 2010 Visual Studio 2008
|
erstellt am: 12. Nov. 2009 15:42 <-- editieren / zitieren --> Unities abgeben:
Hallo Alfred, meinst du die Civil Dll-Referenzen? Als Referenzen habe ich die acdbmgd.dll, acmgd.dll, aecbasemgd.dll und aeccdbmgd.dll in meinem Projekt gesetzt. Grüße Silvan Ah also hab den Fehler gefunden. Ich hatte den Import zu verschiedenen Objekten der aeccdbmgd.dll vergessen. Danke trotzdem für den Tipp! [Diese Nachricht wurde von Silvan01 am 12. Nov. 2009 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |