| | | Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte |
Autor
|
Thema: Objekte zu Selectionset hinzufügen bzw. entfernen (1731 mal gelesen)
|
Wene71 Mitglied
Beiträge: 28 Registriert: 25.04.2010 Win8.1 Pro x64, ACAD 2015, VS 2013
|
erstellt am: 25. Apr. 2010 21:44 <-- editieren / zitieren --> Unities abgeben:
Hallo Ihr, ich möchte gerne zu einem bestehenden Selectionset Objekte hinzufügen bzw. entfernen. Ganz so wie es bei der Standadobjktwahl im AutoCAD z.B beim Strecken üblich ist. Die Selection muß ich über "SelectCrossingWindow" (siehe Code unten) erstellen, weil ich die beiden Eckpunkte der Fensterauswahl im späteren Programmverlauf noch brauche. Wenn ich die Eckpunkte nicht bräuchte könnte ich über editor.getselection auswählen und hätte keine Probleme. Gibt es da eine Möglichkeit? Bin für jede Anregung dankbar! Im vorraus besten Dank, Werner
Code: 'Selectionset am Bildschirm markieren bzw. demarieren. Private Sub HighlightSelectionSet(ByVal sset As SelectionSet, ByVal Highlight As Boolean) If sset.Count <= 0 Then Return Dim db As Database = HostApplicationServices.WorkingDatabase() Dim idarray As ObjectId() = sset.GetObjectIds() Using tr As Transaction = db.TransactionManager.StartTransaction() For Each ObjId As ObjectId In idarray Dim entity As Entity = TryCast(tr.GetObject(ObjId, OpenMode.ForRead, True), Entity) If Highlight = True Then entity.Highlight() Else entity.Unhighlight() End If Next ObjId tr.Commit() tr.Dispose() End Using End Sub <CommandMethod("tss")> _ Public Sub TestSelectionSets() Dim db As Database = HostApplicationServices.WorkingDatabase() Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor Try Dim fPt1 As New Point3d Dim PtRes As PromptPointResult = ed.GetPoint(vbCrLf & "Erste Ecke angeben:") If PtRes.Status = PromptStatus.OK Then fPt1 = PtRes.Value ElseIf PtRes.Status = PromptStatus.Cancel Or PtRes.Status = PromptStatus.Error Then Return End If Dim fPt2 As New Point3d Dim pco As New PromptCornerOptions(vbCrLf & "Entgegengesetzte Ecke angeben:", fPt1) pco.UseDashedLine = True pco.BasePoint = fPt1 PtRes = ed.GetCorner(pco) If PtRes.Status = PromptStatus.OK Then fPt2 = PtRes.Value ElseIf PtRes.Status = PromptStatus.Cancel Or PtRes.Status = PromptStatus.Error Then Return End If 'Ersten Auswahlsatz erstellen... Dim psRes As PromptSelectionResult = ed.SelectCrossingWindow(fPt1, fPt2) Dim sset1 As SelectionSet = psRes.Value If sset1 Is Nothing Then ed.WriteMessage(vbCrLf & "Keine Objekte gewählt!!! ") Return End If 'Object-Ids der ersten Auswahl als Collection speichern... Dim objIdCol As ObjectIdCollection = New ObjectIdCollection() objIdCol = New ObjectIdCollection(sset1.GetObjectIds()) 'Selection am Bildschirm markieren. HighlightSelectionSet(sset1, True) 'HIER OBJEKTE ZU SSET1 HINZUFÜGEN BZW. ENTFERNEN
Catch ex As Exception ed.WriteMessage(ex.ToString) End Try End Sub
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 25. Apr. 2010 22:00 <-- editieren / zitieren -->
Hi, herzlich willkommen bei CAD-de! Aus welchem Grund darf es nicht ein neues SelectionSet sein und Du holst dann die ObjectID's der zweiten Selektion zu Deiner objIdCol-ObjectIDCollection hinzu? - alfred - ------------------ www.hollaus.at |
Wene71 Mitglied
Beiträge: 28 Registriert: 25.04.2010 Win8.1 Pro x64, ACAD 2015, VS 2013
|
erstellt am: 26. Apr. 2010 10:02 <-- editieren / zitieren --> Unities abgeben:
Hallo Alfred, danke für die schnelle Antwort! Mir ist bekannt, daß man dies normalerweise so macht. Aber wenn ich die ObjectID's des zweiten SSet in die ObjectIDCollection hole und daraus ein finales SSet erstelle, sind die Informationen ob die Objekte gekreutzt oder ganz im Fenster waren verloren. Ich möchte das finale SSet bei einem "SendCommand" im Commandstring über "_p" (zB. "_strecken _p ...") abrufen können. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 26. Apr. 2010 21:21 <-- editieren / zitieren -->
Hi, sorry, ich steh auf der Leitung. Den Strecken-Befehl kannst Du nicht mit SendCommand _STRETCH _P ausführen (_P steht wohl für 'previous'), denn es werden beim Aufruf explizit kreuzen-Punkte oder z.B. kreuzen-Polygon verlangt. Probier das mal im AutoCAD direkt. Selektiere zuerst ein paar Objekte und probier dann _STRETCH _P geht nicht. Nun gehen wir davon aus, dass ich auf der Leitung stehe, denn Du wirst ja nicht so tief getüftelt haben, wenn Du's vorher nicht probiert hättest. Jedoch eine einfache Vorgehensweise ('einfach Objekte zu bestehendem Editor.SelectionSet dazunehmen) hab ich nicht bei der Hand. Bevor ich mich aber 'hinein steigere': kannst Du den gesamten Workflow beschreiben, was Du in Summe mit den Elementen vorhast. Vielleicht gibt's einen einfacheren Weg (auf die Idee komm ich einfach dadurch, weil ich schon SendCommand nicht mag ). - alfred - ------------------ www.hollaus.at |
Wene71 Mitglied
Beiträge: 28 Registriert: 25.04.2010 Win8.1 Pro x64, ACAD 2015, VS 2013
|
erstellt am: 26. Apr. 2010 22:46 <-- editieren / zitieren --> Unities abgeben:
Hallo, es geht mir darum die Selection am schluss zu strecken. Wie man programmgesteuert Objekte verschiebt oder dreht weiß ich, aber nicht wie man sie strecken kann. Deshalb greife ich aus verlegenheit auf SendCommand zurück. Ich bin auch kein Freund von Sendcommand, da ich ja damit die Programmkontrolle vollständig abgebe! Das mit SendCommand("_stretch" "_p" "VONPUNKT" "NACHPUNKT" "") geht auf jeden Fall. Probier selbst mal im AutoCAD direkt. 1. Selektiere zuerst ein paar Objekte 2. ENTER 3. _Stretch 4. _P 5. ENTER Alle vorher gewählten Objekte sind wieder gewählt und können gestreckt werden. Mein Problem ist eben wenn ich aus mehreren SelectionSets die ObjectIDs hole und in ein neues SSET fülle weiß daß SSET nicht ob die enthaltenen Objekte komplett im Auswahlfenster oder gekreutzt waren. Was ja beim Strecken wichtig ist. Mit anderen Worten die Objekte des neuen SSET werden beim Strecken alle nur verschoben nicht gestreckt. Anderer Weg wäre wenn es eine Möglichkeit geben würde über .GetSelection die Eckpunkte bei einer Fensterauswahl auszulesen. Aber ich glaube daß geht nicht.
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 26. Apr. 2010 23:48 <-- editieren / zitieren -->
Hi, >> Probier selbst mal im AutoCAD direkt. >> 1. Selektiere zuerst ein paar Objekte >> .... >> 5. ENTER Wow, da hab ich aber jetzt was serviert bekommen, woran ich schon ein wenig kiefeln muss. Ja, Du hast recht, das geht. Und ich bekomme es jetzt mal nicht so hin, dass ich dem ersten SelectionSet neue ObjectID's hinzufüge. Allerdings wüsste ich auch nicht, welche ObjID's Du hinzufügen wolltest, wenn dadurch, dass Du ja selbst das SelectionCrossing über zwei Punkte machst, hast Du schon alle streckbaren Elemente 'gefangen'. Elemente, die ausserhalb der Punkte liegen würden, würden aller Wahrscheinlichkeit nach auch dann nicht gestreckt werden.
Nicht probiert, ev. noch einen Versuch wert könnte sein, es über die COM-Schnittstellt und das PickFirstSelectionSet zu probieren. Um Objekte während der Selektion auszuschliessen, kannst Du ev. schon Filter an die Funktion SelectCrossingWindow übergeben. Sorry, mehr hab ich jetzt nicht, - alfred - ------------------ www.hollaus.at |
Wene71 Mitglied
Beiträge: 28 Registriert: 25.04.2010 Win8.1 Pro x64, ACAD 2015, VS 2013
|
erstellt am: 27. Apr. 2010 11:37 <-- editieren / zitieren --> Unities abgeben:
Hallo, nun ja, mich zu überzeugen, daß ich das ganze nicht brauche wäre auch ein Lösung. Zitat: Allerdings wüsste ich auch nicht, welche ObjID's Du hinzufügen wolltest, wenn dadurch, dass Du ja selbst das SelectionCrossing über zwei Punkte machst, hast Du schon alle streckbaren Elemente 'gefangen'.
Gut die Objekte habe ich über SelectionCrossingWindow gefangen. Aber was, wenn ich daraus wieder welche entfernen möchte? Hinzufügen oder entfernen beläuft sich auf das gleiche. Geht das eine, geht das andere auch. Das SelectionCrossingWindow ist halt eine sehr grobe Auswahl. Ein Filter nützt glaube ich nicht viel. Hier kann ich ja nur nach bestimmten Objekttypen bzw. Objekteigenschaften filtern. Außerdem muß ich den ja vor der Selection deffinieren, und beim Selectionsaufruf mit übergeben. Bitte Bitte kein COM mehr! Ich möchte keine Mischwelten in meinen Projekten. Wer weiß wie lange COM noch unterstützt wird. Jedenfalls soll wenn ich's richtig gelesen habe in AutoCAD 2012 die VBA-IDE nicht mehr zur verfügung gestellt werden. Ich beschäftige mich schon sehr lange mit der findung einer Lösung dieses Problems, und habe einiges ohne Erfolg probiert. Ich muß Dir gestehen, daß ich weiß das dies eine harte Nuss ist. Schließlich ist das der Grund gewesen mich in diesem Forum anzumelden. Ich wollte es endlich wissen Trotzdem 1000 Dank für Deine Hilfe und Anregungen, Grüßle Werner Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 27. Apr. 2010 20:00 <-- editieren / zitieren -->
Hi, >> nun ja, mich zu überzeugen, daß ich das ganze nicht brauche Nein, liegt mir fern. Wenn ich einen Weg als nicht (schnell/einfach) lösbar sehe, dann kann ich mit entsprechenden Hintergrundinformationen ev. einen alternativen Weg vorschlagen, darum die vielleicht lästigen vielen Rückfragen, damit ich verstehen lerne. >> Bitte Bitte kein COM mehr! ... >> Wer weiß wie lange COM noch unterstützt wird. >> .... in AutoCAD 2012 die VBA-IDE nicht mehr zur verfügung
Wenn VBA nicht mehr enthalten sein sollte, dann ist das bei weitem nicht gleichbedeutend, dass es das COM-Interface nicht mehr geben sollte. COM ist und bleibt meines Wissens noch lange Bestandteil von AutoCAD! Ich kann schon verstehen, dass die zusätzlich gebundene Interop nicht angenehm ist, insbesondere, wenn ich meine App für 32bit und 64bit tauglich gestalte und dann wegen der Interop doch nicht mit einer DLL für beides arbeiten kann (zumindest, solange ich diesen Teil nicht mit Late-Binding betreibe). In manchen Fällen, die nicht zeitkritisch sind, ist es aber nach wie vor ein taugliches Mittel, auf AutoCAD zuzugreifen. >> Ich muß Dir gestehen, daß ich weiß das dies eine harte Nuss ist.
Und deswegen kann ich das leider nicht so nebenbei machen, da muss ich mir ein wenig Zeit freischaufeln, ich nehm's mir aber vor, versprochen. - alfred - ------------------ www.hollaus.at |
Wene71 Mitglied
Beiträge: 28 Registriert: 25.04.2010 Win8.1 Pro x64, ACAD 2015, VS 2013
|
erstellt am: 27. Apr. 2010 21:39 <-- editieren / zitieren --> Unities abgeben:
Hallo, Deine Rückfragen sind nicht lästig, schließlich habe ich mit dem Fragen begonnen! Ich habe hier mal was um es Bildlich darzustellen zusammengebastelt. Hier werden zwei mal Objekte gewählt, wobei im Anschluss die zweite Auswahl aus der ersten entfernt wird. Am besten mal diesen Command nach meiner Anleitung ausprobieren. !. ein paar Linien zeichnen 2. mss ENTER (ist ja klar) 3. Linien über Fensterkreutzen so wählen das manche Linien nur gekreutzt werden. 4. ENTER 5. ein paar Linien die jetzt markiert sind wählen die wieder entfernt werden sollen 6. ENTER 7. direkt Streckbefehl ausführen und strecken Jetzt siehst Du das die finale Auswahl nur verschoben wird und nicht gestreckt.
Code: <CommandMethod("mss")> _ Public Sub MehrfachSelection() Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor Dim psRes As PromptSelectionResult Dim pso As New PromptSelectionOptions Dim sset1, sset2 As SelectionSet Dim ObjIdColl As ObjectIdCollection = New ObjectIdCollection() 'Erste Auswahl... pso.MessageForAdding = "Objekte für erste Auswahl wählen:" pso.AllowDuplicates = False psRes = ed.GetSelection(pso) If psRes.Status = PromptStatus.OK Then sset1 = psRes.Value HighlightSelectionSet(sset1, True) ObjIdColl = New ObjectIdCollection(sset1.GetObjectIds()) End If If ObjIdColl.Count <= 0 Then Return 'Zweite Auswahl... pso.MessageForAdding = "Objekte die aus erste Auswahl entfernt werden wählen:" pso.AllowDuplicates = False psRes = ed.GetSelection(pso) If psRes.Status = PromptStatus.OK Then sset2 = psRes.Value For Each objID As ObjectId In sset2.GetObjectIds() 'ObjectIDs der zweiten Auswahl aus Collection entfernen. ObjIdColl.Remove(objID) Next 'IDs von Collection in liste füllen und an finales SSET übergeben. Dim objects As New List(Of ObjectId)() For Each oID As ObjectId In ObjIdColl objects.Add(oID) Next Dim ssetFinal As SelectionSet = SelectionSet.FromObjectIds(objects.ToArray) 'Selection auf Bildschirm markieren. ed.SetImpliedSelection(ssetFinal) End If End Sub
Natürlich würde in meinem Produktionscode das erste SSET über "SelectCrossingWindows" kommen, aber das tut nichts zur Sache. Vielen Dank für Deinen Aufwand! Aber bitte nur so lange es Spaß macht. Ich werde auf jeden Fall selbst auch weiterforschen und werds wissen lassen wenn ich Fortschritte mache. Gruß Werner
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
| Anzeige.:
Anzeige: (Infos zum Werbeplatz >>)
|