| | | Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte | | | | PNY bietet das umfangreichste Ökosystem von B2B als auch B2C-Lösungen für IT-Akteure auf dem Markt, eine Pressemitteilung
|
Autor
|
Thema: BKS eines Layout ermitteln (2147 mal gelesen)
|
Andreas Widmann Mitglied ATHENA Support/Training
Beiträge: 218 Registriert: 24.08.2005
|
erstellt am: 04. Feb. 2013 14:33 <-- editieren / zitieren --> Unities abgeben:
Hallo Zusammen, Ziel meiner Bemühungen ist es ohne Userinteraktion die in einem Ansichtsfenster sichtbaren Entitys zu ermitteln. Allerdings stecke ich dabei fest die Koordinaten (.GeometricExtends.MinPoint und .MaxPoint) vom Papierbereich in den Modellbereich umzurechnen. Denn dort will ich diese dann per Selection auswählen und ggf. weiterverarbeiten. Ich möchte dazu den Editor meiden und möglichst nur mit Database arbeiten. Folgende Fragen stellen sich mir dabei: - Alle Anleitungen zur Koordinatenumrechnung benutzen das ".Editor.CurrentUserCoordinateSystem"... aber wie komme ich ohne das Layout aktiv zu haben an das jeweilige Koordinatensystem des Layouts? - Welches Koordinatensystem ist das das ich mit "acDb.UcsTableId.GetObject(OpenMode.ForRead)" bekomme, oder ist das kein Koordinatensystem? - Oder bin ich mit der Umrechnung auf dem Holzweg und es geht gar einfacher die sichtbaren Objekte zu ergattern? ich hoffe auf rege Beteiligung System: AutoCAD 2013 + Visual Studio 2010 => Sprache VB.net ------------------ Gruß Andreas ------------------------------------------------------------------------------------------------------------------------------------ Die Antwort ist 42! Die Antwort ist 42! Die Antwort ist 42! ...wenn ich nur die Frage wüsste... [Diese Nachricht wurde von Andreas Widmann am 04. Feb. 2013 editiert.] 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: 05. Feb. 2013 04:32 <-- editieren / zitieren --> Unities abgeben: Nur für Andreas Widmann
Hallo Andreas, ich bin mir sicher, dass dieses Thema auch schon im AutoLISP-Forum diskutiert wurde (musst mal dort suchen). Der Weg ist im .Net derselbe. Das Layoutansichtsfenster hat den Mittelpunkt im Modellbereich und die Höhe (oder Breite?) im Modellbereich als Eigenschaften. Daraus lassen sich die Koordinaten im Moddellbereich berechnen. Ohne es geprüft zu haben, ich denke aber, dass das Layout-Ansichtsfenster auch die Normale der Ansicht als Eigenschaft besitzt. Aus diesen Informationen sollten sich dann auch die Koordinaten in §d-Ansichten berechnen lassen. Vielleicht hilft's? Grüße! Holger ------------------ Holger Brischke FREIE SCHULUNGSPLÄTZE -- C#.NET-Schulung im Mai 2013 Bei Interesse bitte melden! CAD on demand GmbH Individuelle Lösungen von Heute auf Morgen.
defun-tools Das Download-Portal für AutoCAD-Zusatzprogramme!
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Andreas Widmann Mitglied ATHENA Support/Training
Beiträge: 218 Registriert: 24.08.2005
|
erstellt am: 05. Feb. 2013 16:51 <-- editieren / zitieren --> Unities abgeben:
Hallo Holger, diesen Weg musste ich leider schon in meiner VBA-Version meiden da ich feststellen musste dass die Variable Viewcenter in manchen Fällen unzuverlässig ist und einfach 0,0 angibt. Gerade bei gedrehten Ansichtsfenstern kommt das vor. Da ich über diese Funktion ermittle welche Objekte weggelöscht werden sollen kannst du dir aber denken dass es ungünstig ist wenn es nicht zuverlässig funktioniert. Die VBA-Variante funktioniert zuverlässig sofern im Modellbereich das BKS auf Welt steht. Ich hab dir mal meine Beispieldatei angehängt, hab ich erst vor ner Stunde produziert.Anfangs ging's noch, aber für das Schräge Ansichtsfenster bekomme ich jetzt nur 0,0 als ViewCenter obwohl es denselben Mittelpunkt wie das gerade hatte/haben müsste. (Das gerade Ansichtsfenster habe ich über die ACAD Funktion afenster erstsellt, dann kopiert und gedreht um das Schräge zu erhalten) Mein aktueller Code:
Code: <CommandMethod("Sesplit")> _ Public Sub seele_split() Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument Dim acDb As Database = acDoc.Database Using acTrans As Transaction = acDoc.TransactionManager.StartTransaction() Dim acBlkTbl As BlockTable = CType(acDb.BlockTableId.GetObject(OpenMode.ForRead), BlockTable) Dim acBlkTblRec As BlockTableRecord = CType(acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord) Dim vportscoll As ObjectIdCollection = acDb.GetViewports(True) Dim layoutdict As DBDictionary = CType(acDb.LayoutDictionaryId.GetObject(OpenMode.ForRead), DBDictionary) For Each layt As DBDictionaryEntry In layoutdict If Not layt.Key = "Model" Then Dim vplist As List(Of Viewport) = FindVPforLayout(layt, vportscoll) MsgBox("Layoutname: " & layt.Key & " Ansichtsfenster: " & vplist.Count) For Each vp As Viewport In vplist Dim ext As Extents3d = vp.GeometricExtents MsgBox("X: " & ext.MinPoint.X & " Y: " & ext.MinPoint.Y & " | | X: " & ext.MaxPoint.X & " Y: " & ext.MaxPoint.Y) Dim ll As New Point3d(vp.ViewCenter.X - vp.Width / 2, vp.ViewCenter.Y - vp.Height / 2, 0) Dim lr As New Point3d(vp.ViewCenter.X + vp.Width / 2, vp.ViewCenter.Y - vp.Height / 2, 0) Dim ur As New Point3d(vp.ViewCenter.X + vp.Width / 2, vp.ViewCenter.Y + vp.Height / 2, 0) Dim ul As New Point3d(vp.ViewCenter.X - vp.Width / 2, vp.ViewCenter.Y + vp.Height / 2, 0)
Dim pnt3dcoll As New Point3dCollection({ll, lr, ur, ul}) Dim dummycenterpoint As New Polyline2d(Poly2dType.SimplePoly, New Point3dCollection({New Point3d(0, 0, 0), New Point3d(vp.ViewCenter.X, vp.ViewCenter.Y, 0)}), 0, False, 0, 0, Nothing) acBlkTblRec.AppendEntity(dummycenterpoint) acTrans.AddNewlyCreatedDBObject(dummycenterpoint, True) Dim virtRec As New Polyline2d(Poly2dType.SimplePoly, pnt3dcoll, 0, True, 0, 0, Nothing) virtRec.TransformBy(Matrix3d.Scaling(1 / vp.CustomScale, New Point3d(vp.ViewCenter.X, vp.ViewCenter.Y, 0))) virtRec.TransformBy(Matrix3d.Rotation(-vp.TwistAngle, vp.ViewDirection, New Point3d(0, 0, 0))) virtRec.ColorIndex = 50 acBlkTblrec.AppendEntity(virtRec) acTrans.AddNewlyCreatedDBObject(virtRec, True) Next End If Next acTrans.Commit() End Using End Sub
Zur Kontrolle habe ich Objekte eingebaut. Das gelbe Rechteck sollte dann die in den Modellbereich umgerechnete Boundingbox des AF darstellen. Wenn das AF aber mit Fehlerhaftem Viewcenter auftritt, sitzt das Rechteck am Nullpunkt. dummycenterpoint erzeugt eine Linie vom Nullpunkt zum ViewCenter EDIT: Zum Vergleich, kopiere das gerade AF nocheinmal, drehe es um 30 Grad und führe das Prog nochmal aus. Du wirst sehen, das neue gelbe Rechteck deckt sich mit dem Cyanfarbenen und ist damit korrekt. ------------------ Gruß Andreas ------------------------------------------------------------------------------------------------------------------------------------ Die Antwort ist 42! Die Antwort ist 42! Die Antwort ist 42! ...wenn ich nur die Frage wüsste... [Diese Nachricht wurde von Andreas Widmann am 05. Feb. 2013 editiert.] 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: 07. Feb. 2013 12:22 <-- editieren / zitieren --> Unities abgeben: Nur für Andreas Widmann
Zitat: Original erstellt von Andreas Widmann: ... Wenn das AF aber mit Fehlerhaftem Viewcenter auftritt, sitzt das Rechteck am Nullpunkt. ...
Der ViewCenter-Wert wird nur ausgegeben, wenn der Viewport eine Orthogonale Ansicht beinhaltet. Ist dem nicht so, musst du Viewport.ViewTarget verwenden. Code:
Point3d _vt = _vp.ViewCenter.dtToPoint3d(); if (_vp.ViewOrthographic == OrthographicView.NonOrthoView) _vt = _vp.ViewTarget;
Grüße! Holger ------------------ Holger Brischke FREIE SCHULUNGSPLÄTZE -- C#.NET-Schulung im Mai 2013 Bei Interesse bitte melden! CAD on demand GmbH Individuelle Lösungen von Heute auf Morgen.
defun-tools Das Download-Portal für AutoCAD-Zusatzprogramme!
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Andreas Widmann Mitglied ATHENA Support/Training
Beiträge: 218 Registriert: 24.08.2005
|
erstellt am: 08. Feb. 2013 10:41 <-- editieren / zitieren --> Unities abgeben:
Hallo Holger, erstmal, Dankeschön. Kurz war ich auch fast schon euphorisch als ich es ausprobiert habe. Hab jetzt aber gleich Ausnahmen gefunden. Zum einen, es kann passieren dass ACAD ein AF als OrthogonalView einstuft obwohl es gedreht ist. Deine Zeile habe ich daher so abgeändert:
Code: Dim VPcenter As Point3d = CType(IIf(vp.ViewOrthographic = OrthographicView.NonOrthoView Or Not vp.TwistAngle = 0, vp.ViewTarget, New Point3d(vp.ViewCenter.X, vp.ViewCenter.Y, 0)), Point3d)
Gleichzeitig bin ich aber wieder enttäuscht von ViewTarget Ich habe beim ersten Versuch ein AF hinbekommen habe das solange falsche Werte liefert bis ich manuell mit AFmax das AF vergrößere und wieder zurückgehe. Das Gleiche ist mit polygonalen AF, der Mittelpunkt aus dem Modellbereich stimmt einfach nicht. Ich bin dabei so vorgegangen: - Ansichtsfenster erstellt - BKS verschoben und gedreht - "drsicht" eingegeben um die gedrehte Ansicht einzustellen Die Datei mit den Ansichtsfenstern habe ich angehängt. Mein neuer Code sieht im Moment so aus: (Ich habe mittlerweile ergänzt dass die exakte AF-Geometrie in den Modelbereich übernommen wird)
Code: For Each vp As Viewport In vplist Dim ext As Extents3d = vp.GeometricExtents 'MsgBox("X: " & ext.MinPoint.X & " Y: " & ext.MinPoint.Y & " | | X: " & ext.MaxPoint.X & " Y: " & ext.MaxPoint.Y) 'Zielpunkt des Ansichtsfensters 'Gedrehte Ansichten: ViewTarget, Orthogonale: ViewCenter Dim VPcenter As Point3d = CType(IIf(vp.ViewOrthographic = OrthographicView.NonOrthoView Or Not vp.TwistAngle = 0, vp.ViewTarget, New Point3d(vp.ViewCenter.X, vp.ViewCenter.Y, 0)), Point3d) 'Koordinaten des AF in Relation (Vectoren) zum Centerpoint (auf dem Layout) abrufen Dim vec3dcoll As New Vector3dCollection If vp.NonRectClipOn Then 'Zugeschnittenes AF 'Koordinaten des Clip-Objekts abrufen Dim clipobj As Polyline = CType(vp.NonRectClipEntityId.GetObject(OpenMode.ForRead), Polyline) For i As Double = 0 To clipobj.EndParam vec3dcoll.Add(vp.CenterPoint.GetVectorTo(clipobj.GetPointAtParameter(i))) Next Else 'Nicht-Zugeschnittenes AF 'Rechteck annehmen Dim ll As Vector3d = vp.CenterPoint.GetVectorTo(New Point3d(vp.CenterPoint.X - vp.Width / 2, vp.CenterPoint.Y - vp.Height / 2, 0)) Dim lr As Vector3d = vp.CenterPoint.GetVectorTo(New Point3d(vp.CenterPoint.X + vp.Width / 2, vp.CenterPoint.Y - vp.Height / 2, 0)) Dim ur As Vector3d = vp.CenterPoint.GetVectorTo(New Point3d(vp.CenterPoint.X + vp.Width / 2, vp.CenterPoint.Y + vp.Height / 2, 0)) Dim ul As Vector3d = vp.CenterPoint.GetVectorTo(New Point3d(vp.CenterPoint.X - vp.Width / 2, vp.CenterPoint.Y + vp.Height / 2, 0)) vec3dcoll = New Vector3dCollection({ll, lr, ur, ul}) End If 'Geometrie des AF um den Zielpunkt im Modellbereich neu aufbauen Dim pnt3dcoll As New Point3dCollection For Each vec As Vector3d In vec3dcoll pnt3dcoll.Add(New Point3d(VPcenter.ToArray).TransformBy(Matrix3d.Displacement(vec))) Next Dim dummycenterpoint As New Polyline2d(Poly2dType.SimplePoly, New Point3dCollection({New Point3d(0, 0, 0), VPcenter}), 0, False, 0, 0, Nothing) acBlkTblRec.AppendEntity(dummycenterpoint) acTrans.AddNewlyCreatedDBObject(dummycenterpoint, True) Dim virtRec As New Polyline2d(Poly2dType.SimplePoly, pnt3dcoll, 0, True, 0, 0, Nothing) virtRec.TransformBy(Matrix3d.Scaling(1 / vp.CustomScale, VPcenter)) virtRec.TransformBy(Matrix3d.Rotation(-vp.TwistAngle, vp.ViewDirection, VPcenter)) virtRec.ColorIndex = 50 acBlkTblRec.AppendEntity(virtRec) acTrans.AddNewlyCreatedDBObject(virtRec, True) Next
und hier hatte sich noch ein Fehler eingeschlichen:
Code: virtRec.TransformBy(Matrix3d.Scaling(1 / vp.CustomScale, VPcenter)) virtRec.TransformBy(Matrix3d.Rotation(-vp.TwistAngle, vp.ViewDirection, VPcenter))
Hast du mir nochmal eine Idee? ------------------ Gruß Andreas ------------------------------------------------------------------------------------------------------------------------------------ Die Antwort ist 42! Die Antwort ist 42! Die Antwort ist 42! ...wenn ich nur die Frage wüsste... Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Andreas Widmann Mitglied ATHENA Support/Training
Beiträge: 218 Registriert: 24.08.2005 Windows 10 Autocad 2015 - 2018 Athena 2015 - 2017 Aufsatz
|
erstellt am: 22. Feb. 2013 14:26 <-- editieren / zitieren --> Unities abgeben:
Hallo, ich bin wieder zurück mit neuen Ergebnissen: Meine 5 Test-Ansichtsfenster habe ich nämlich immer noch nicht korrekt umgerechnet bekommen. Um dem Problem auf die Schliche zu kommen habe ich nun die Werte der Viewporteigenschaften "Viewcenter" und "Viewtarget" vor und nach AF-Max ausgeben lassen. Vor der manuellen Behandlung mit AFMAX ViewCenterX ViewCenterY ViewTargetX ViewTargetY 0,00 0,00 99,99 100,00 0,00 0,00 99,99 100,00 -16,31 39,11 592,56 553,44 312,92 280,86 99,99 100,00 0,00 0,00 99,99 235,42 Nach der Behandlung mit AFMAX ViewCenterX ViewCenterY ViewTargetX ViewTargetY 0 0 99,99 99,99 0 0 99,99 99,99 0 0 558,88 579,15 0 0 412,91 380,85 0 0 99,99 235,41 bei dem dritten und vierten AF ist gut zu erkennen dass sich die Variable ViewTarget ändert. Das 5. ist quasi das Kontroll AF, es war auch bei "vor Behandlung" schon "Behandelt" Auf so ein Verhalten baue ich ungern ein Programm auf.
Ich brauche entweder zuverlässige Quellen für die Viewzentren o.Ä. finden, oder einen Weg haben die "Neuberechnung" von .Net aus auszulösen. (AFMAX für jedes AF kommt nicht in frage) Oder aber ich gehe doch den Weg (der in VBA zuverlässig funktioniert hat) über die Transformationsmatrix vom Layoutbks zum Weltbks um meine Koordinaten umzurechen. (Dazu fehlt mir aber das Know How in .Net) Kann mir hier jemand weiterhelfen? PS: Ich habe festgestellt, dass die Variable VIEWCTR (bei aktuellem AF im Acad eingegeben) als auch die Variable TARGET nicht gleichbedeutend sind mit ViewCenter und Viewtarget... wie kann ich denn an die über .Net rankommen ohne jeweils das AF aktiv machen zu müssen und dann von ACAD die Variable zu verlangen? ------------------ Gruß Andreas ------------------------------------------------------------------------------------------------------------------------------------ Die Antwort ist 42! Die Antwort ist 42! Die Antwort ist 42! ...wenn ich nur die Frage wüsste... Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
| Anzeige.:
Anzeige: (Infos zum Werbeplatz >>)
|