| | | Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte |
Autor
|
Thema: Alle Blöcke an einer Position bestimmen (1716 mal gelesen)
|
Gloem Mitglied Geoinformatiker
Beiträge: 179 Registriert: 07.12.2007 Windows 10 - 64 Bit, mindestens 16 GB RAM <P>AutoCAD Map 2020, VBA, Dot-Net
|
erstellt am: 20. Feb. 2010 17:28 <-- editieren / zitieren --> Unities abgeben:
Hallo, ich möchte alle Blockreferenzen innerhalb eines Toleranzbereiches um einen übergebenen Punkt bestimmen. Folgendes hab ich mal zusammengebastelt, funktioniert auch eigentlich nur bekomm ich zwei Ids mehr als mit dem Filter in AutoCAD selber. Kann mir einer sagen warum? Code: ' Funktion um Blöcke zu finden deren Position innerhalb eines Toleranzbereiches um einen übergebenen Punkt liegen ' - Benötigt ein Feld vom Typ ObjectID in welches die ID der gefundenen Blöcke gespeichert werden ' - Gibt Nothing zurück wenn erfolgreich ansonsten die aufgetretene Exception Public Function getBlocksOnPoint(ByVal point As Point3d, ByVal tolerance As Double, ByRef blockID As ObjectIdCollection) As Exception ' Anlegen eines Transaktionsobjektes um auf die Zeichnungsdatenbank zugreifen zu können Dim trans As Transaction = Application.DocumentManager.MdiActiveDocument.Database.TransactionManager.StartTransaction Try ' Holen des aktuellen Arbeitsbereiches - Leserechte Dim currentWorkspace As BlockTableRecord = trans.GetObject(Application.DocumentManager.MdiActiveDocument.Database.CurrentSpaceId, OpenMode.ForRead) For Each obj As ObjectId In currentWorkspace ' Holen des Elementes aus der Datenbank - Leserechte Dim dbObject As DBObject = trans.GetObject(obj, OpenMode.ForRead) If (dbObject.GetType().FullName = "Autodesk.AutoCAD.DatabaseServices.BlockReference") Then Dim blockRef As BlockReference = dbObject If ((blockRef.Position.X > point.X - tolerance And blockRef.Position.X < point.X + tolerance) And (blockRef.Position.Y > point.Y - tolerance And blockRef.Position.Y < point.Y + tolerance) And (blockRef.Position.Z > point.Z - tolerance And blockRef.Position.Z < point.Z + tolerance)) Then blockID.Add(dbObject.ObjectId) End If End If Next Return Nothing ' Abfangen eines evtl. auftretenden Fehlers Catch ex As Exception Return ex ' Schließen der Transaktion mit der Datenbank Finally trans.Dispose() End Try End Function
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 20. Feb. 2010 17:48 <-- editieren / zitieren -->
Hi, hast Du Zeichnung und Koordinaten+Toleranz für uns/mich, wo ich das reproduzieren kann? Im Code (oberflächlich) sehe ich jetzt mal keinen Fehler (Verbesserungsmöglichkeit in bezug auf Performance schon), aber obige Zusatzdaten würden mich zum Testen bringen. - alfred - [EDIT] es kann nicht sein, dass ev. BlockReferenzen an dieser Position auf gefrorenen Layern liegen? [/EDIT] ------------------ www.hollaus.at |
Gloem Mitglied Geoinformatiker
Beiträge: 179 Registriert: 07.12.2007 Windows 10 - 64 Bit, mindestens 16 GB RAM <P>AutoCAD Map 2020, VBA, Dot-Net
|
erstellt am: 20. Feb. 2010 18:21 <-- editieren / zitieren --> Unities abgeben:
Als Toleranz hab ich immer die Hälfte der Anzeigengenauigkeit genommen: Code: Math.Pow(10, Application.DocumentManager.MdiActiveDocument.Database.Luprec) / 2
Meine Testzeichnung hab ich leider am Wochenende nicht zur Hand. Was würdest du denn Performancemäßg ändern da die Funktion teilweise mehrere hundertmal auf einmal aufgerufen wird. Zum Hintergrund: Ich suche damit alle Blockreferencen die auf den Stützpunkten einer Polylinie liegen und will dann die Attribute aus den Blöcken extrahieren und weiterverarbeiten Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 20. Feb. 2010 18:31 <-- editieren / zitieren -->
Hi, >> Meine Testzeichnung hab ich leider am Wochenende nicht zur Hand Darf ich aber davon ausgehen, dass es nur mit einer bestimmten Zeichnung auftritt? Denn (ohne es probiert zu haben) ich kann mir nicht vorstellen, dass dies in der Regel auftritt. Ausnahmen, die ich mir vorstellen könnte: - BlockReferenzen auf gefrorenen Layer - BlockReferenzen, die keine sichtbare Geometrie vorweisen, sei es, dass die Layer der Blockgeometrie gefroren sind oder BlockReferenzen, die ausschliesslich aus Attributen bestehen, die Attributsinhalte aber leer sind. Verbesserung wäre, die Objekte nicht öffnen zu müssen, um zu wissen, dass/ob es sich um eine BlockReferenz handelt:
Code: For Each obj As ObjectId In currentWorkspace if obj.ObjectClass.DxfName = "INSERT" Then
- alfred - ------------------ www.hollaus.at |
Gloem Mitglied Geoinformatiker
Beiträge: 179 Registriert: 07.12.2007 Windows 10 - 64 Bit, mindestens 16 GB RAM <P>AutoCAD Map 2020, VBA, Dot-Net
|
erstellt am: 20. Feb. 2010 18:41 <-- editieren / zitieren --> Unities abgeben:
|
Ex-Mitglied
|
erstellt am: 20. Feb. 2010 18:54 <-- editieren / zitieren -->
Hi, peinlich sein muss gar nix! Es ist ein Schicksal der Programmierenden, dass sie sich selbst während des Code-Schreibens regelmäßig in massochistischer Manier ein Brett vor den Kopf nageln. Zum Thema Performance noch Kleinigkeiten: Speichere den Einfügepunkt der BlockReference in eine temporäre Variable, damit musst Du nicht jedesmal auf blockRef.Position zugreifen (sprich auf Objekt, in diesem die Properties auswerten, dann von Position die Properties auswerten um zu .X .Y und .Z zu kommen). Hier liegt wohl die geringste Performancesteigerung, das wird die ILR-Optimierung wohl wegbekommen. Dann aber schon ein bisschen mehr bekommst Du, wenn Du am Anfang 2 Punkte rechnest, einen für MinPnt und einen für MaxPnt. Dann musst Du nicht für jede BlockReference jedesmal von neuem die Toleranz-Subtraktion/-addition rechnen. Alternativ, wenn Du die Toleranz als Toleranzkugel um den gesuchten Punkt akzeptierst (und nicht als Quadrat, das Du derzeit mittels ToleranzX-Y-Z vorsiehst), dann kannst Du mit der Funktion
Code: if blockRef.Position.DistanceTo(point) < Toleranz
prüfen. Ich hab's nicht probiert, könnte mir aber vorstellen, dass das schneller sein könnte.Hoffe mich verständlich ausgedrückt zu haben, wenn nicht, lass es mich bitte wissen. - alfred - ------------------ www.hollaus.at |
Gloem Mitglied Geoinformatiker
Beiträge: 179 Registriert: 07.12.2007 Windows 10 - 64 Bit, mindestens 16 GB RAM <P>AutoCAD Map 2020, VBA, Dot-Net
|
erstellt am: 22. Feb. 2010 11:08 <-- editieren / zitieren --> Unities abgeben:
|
Ex-Mitglied
|
erstellt am: 22. Feb. 2010 11:15 <-- editieren / zitieren -->
Hi, Danke für die Rückmeldung! Hat sich das ursprüngliche Problem mit 'um zwei mehr als ... gefunden' lösen/finden lassen? (nur damit ich für mich den Task abschliessen kann ) - alfred - ------------------ www.hollaus.at |
Gloem Mitglied Geoinformatiker
Beiträge: 179 Registriert: 07.12.2007 Windows 10 - 64 Bit, mindestens 16 GB RAM <P>AutoCAD Map 2020, VBA, Dot-Net
|
erstellt am: 23. Feb. 2010 08:29 <-- editieren / zitieren --> Unities abgeben:
Hab die Zeichnung gerade nochmal geöffnet und hab alles eingeblendet und es waren durch die Schnellauswahl immer noch 2 Blockreferenzen zu wenig. Warum - Keine Ahnung. Denke aber mal in 99,9999% aller Fälle schließ ich das durch den Toleranzbereich aus Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 23. Feb. 2010 09:11 <-- editieren / zitieren -->
Hi, kann ich diese Zeichnung mal haben (plus der Poly, an deren Koordinaten dies auftritt)? - alfred - PS: nur, wenn Du auf 100% kommen willst. ------------------ www.hollaus.at |
Gloem Mitglied Geoinformatiker
Beiträge: 179 Registriert: 07.12.2007 Windows 10 - 64 Bit, mindestens 16 GB RAM <P>AutoCAD Map 2020, VBA, Dot-Net
|
erstellt am: 24. Feb. 2010 12:18 <-- editieren / zitieren --> Unities abgeben:
|
| Anzeige.:
Anzeige: (Infos zum Werbeplatz >>)
|