| | | Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte |
Autor
|
Thema: Selectionset, bekomms nicht hin... (6466 mal gelesen)
|
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 11. Nov. 2008 19:23 <-- editieren / zitieren --> Unities abgeben:
Hallo! Ich möchte gerne etwas mit Selectionset rumspielen, aber ich bekomms nicht hin... ich habe Autocad 2008/09 Ich möchte aus einem Layout bestimmte Elemente nach einer Eigenschaft in einem SelectionSet speichern und dann darauf zugreifen. z.b wenn AcadEntity.ObjectName = "AcadBlockReference" ist soll der Entity im SS gespeichert werden. kann mir jemand weiterhelfen? mfg Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 11. Nov. 2008 19:27 <-- editieren / zitieren -->
Hi, kannst Du den Teil des Codes zeigen, den Du hast (nicht zuletzt um zu sehen, in welcher Programmiersprache, denn in diesem Forum existieren Beiträge in C++/C#/VB.NET) - alfred - |
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 11. Nov. 2008 19:40 <-- editieren / zitieren --> Unities abgeben:
hab schon verschiedenste teile probiert... Ziel ist vb.net hier mal 3 funktionen: Public Function SelectionSet_CreateWindow(ByVal Name As String, ByVal ObjectName As String) As AcadSelectionSet Dim acadApp As AcadApplication Dim acadDoc As AcadDocument Dim SSObj As AcadSelectionSet Try acadApp = CType(GetObject(, AutoCadApplicatie), AcadApplication) acadApp.Visible = True acadDoc = acadApp.ActiveDocument acadDoc.Application.Visible = True SSObj = acadDoc.SelectionSets.Add(Name) Dim FilterType() As Int16 = {0} Dim FilterData() As Object = {ObjectName} SSObj.SelectOnScreen(FilterType, FilterData) Return SSObj Autodesk.AutoCAD.ApplicationServices.CommandLinePrompts.Message(vbCrLf & SSObj.Count & " Objects selected" + vbCrLf) Catch ex As Exception MessageBox.Show(ex.ToString) Return Nothing End Try End Function Public Function SelectionSet_CreateAll(ByVal Name As String, ByVal ObjectName As String) As AcadSelectionSet Dim acadApp As AcadApplication Dim acadDoc As AcadDocument Dim SSObj As AcadSelectionSet Try acadApp = CType(GetObject(, AutoCadApplicatie), AcadApplication) acadApp.Visible = True acadDoc = acadApp.ActiveDocument acadDoc.Application.Visible = True SSObj = acadDoc.SelectionSets.Add(Name) Dim FilterType() As Int16 = {0} Dim FilterData() As Object = {ObjectName} SSObj.Select(AcSelect.acSelectionSetAll, , , FilterType, FilterData) Return SSObj Autodesk.AutoCAD.ApplicationServices.CommandLinePrompts.Message(vbCrLf & SSObj.Count & " Objects selected" + vbCrLf) Catch ex As Exception MessageBox.Show(ex.ToString) Return Nothing End Try End Function Public Function SelectionSet_Delete(ByVal Name As String) As Boolean Dim acadApp As AcadApplication Dim acadDoc As AcadDocument Dim Obj As AcadSelectionSet Dim Found As Boolean = False Try acadApp = CType(GetObject(, AutoCadApplicatie), AcadApplication) acadApp.Visible = True acadDoc = acadApp.ActiveDocument acadDoc.Application.Visible = True For Each Obj In acadDoc.SelectionSets If Obj.Name = Name Then Found = True End If If Found = True Then acadDoc.SelectionSets.Item(Name).Delete() Return True End If Next Catch ex As Exception MessageBox.Show(ex.ToString) Return False End Try End Function andere Version:
Dim sset As AcadSelectionSet, obj As AcadEntity, att, atts sset = thisdrawing.SelectionSets.Add("AcadBlockReference") sset.SelectOnScreen() For Each obj In sset If TypeOf obj Is AcadBlockReference Then If obj.HasAttributes Then atts = obj.GetAttributes For Each att In atts MsgBox(att.ToString) Next End If End If Next sind aus dem internet, aber verstehen tu ich sie nicht, sprich wo gebe ich den filter an, dass es acad blockreference sein soll,...
mfg Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 11. Nov. 2008 19:53 <-- editieren / zitieren -->
Hi, meinst Du so?
Code: Friend Shared Function getLayoutObjects(ByRef AcadDocED As EditorInput.Editor, ByVal LayoutName As String) As EditorInput.SelectionSet Dim tRetVal As EditorInput.SelectionSet = Nothing Try Dim tDxfFilter() As DatabaseServices.TypedValue = {New DatabaseServices.TypedValue(DatabaseServices.DxfCode.LayoutName, LayoutName), New DatabaseServices.TypedValue(DatabaseServices.DxfCode.Start, "INSERT")} Dim tSelFilter As New EditorInput.SelectionFilter(tDxfFilter) Dim tSelRes As EditorInput.PromptSelectionResult = AcadDocED.SelectAll(tSelFilter) If (tSelRes IsNot Nothing) AndAlso (tSelRes.Status = EditorInput.PromptStatus.OK) AndAlso (tSelRes.Value.Count > 0) Then tRetVal = tSelRes.Value End If Catch ex As Exception tRetVal = Nothing End Try Return tRetVal End Function
- alfred - |
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 11. Nov. 2008 21:45 <-- editieren / zitieren --> Unities abgeben:
danke, dass sieht schon etwas anders aus als bei mir. Gibts dazu irgendwo eine generelle Beschreibung im Internet? oder in einem Buch? Layoutname, ist mir klar wo ich das herbekomme, aber den AcadDocED wie muss ich den definieren? Und, wenn ich jetzt nicht auf die acadblockreferente selectieren will, sondern nach etwas anderem, gibts da wo eine Übersicht, oder irgend einen Anstoß? Der Code von dir sagt mir leider noch nicht viel. mfg Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 11. Nov. 2008 21:49 <-- editieren / zitieren -->
Hi, mit 'AcadDocED' meine ich das Editor-Objekt des aktuellen Documents (Document.Editor). Eine Liste der Objekte als Gesamtheit habe ich noch nie gesucht und noch nie gebraucht, wenn ich einen bestimmten Elementtyp suchen will, dann zeichne ich diesen in AutoCAD und gebe dann in der Befehlszeile ein: (entget (car (entsel))) damit bekomme ich alle Eigenschaften in Lisp-Syntax ==> unter '0' finde ich dann die Objektbezeichnung -------------- Der Code (die Funktion) selbst macht folgendes: a) deklariere eine Variable 'tRetVal' vom Typ SelectionSet b) erzeuge ein Array of TypedValue, gleich mit der Instanzierung mitgegeben die beiden FilterCodes für Filter nach LayoutName und Filter nach Objekttyp 'INSERT' c) lass den Editor die Selektion durchführen d) Prüfung, ob das SelectionSet auch tatsächlich (ohne Fehler) gebaut wurde und mehr als 0 Objekte enthält e) wenn alles ok, dann als Return-Wert festlegen - alfred - [Diese Nachricht wurde von a.n. am 11. Nov. 2008 editiert.] |
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 12. Nov. 2008 06:49 <-- editieren / zitieren --> Unities abgeben:
Hallo! Um sicherzugehen frage ich lieber nochmal. Mein Code: Dim acadapp As AcadApplication = DirectCast(Marshal.GetActiveObject("AutoCAD.Application"), AcadApplication) acadapp.Documents.Open("C:\t.dwg", False, False) Dim thisdrawing As AcadDocument = acadapp.ActiveDocument Dim AcadDocED As EditorInput.Editor --> ist wahrscheinlich noch falsch. Dim tRetVal As EditorInput.SelectionSet = Nothing Try For Each oLayout In thisdrawing.Layouts Dim Layoutname As String = oLayout.Name Dim tDxfFilter() As DatabaseServices.TypedValue = {New DatabaseServices.TypedValue(DatabaseServices.DxfCode.LayoutName, Layoutname), New DatabaseServices.TypedValue(DatabaseServices.DxfCode.Start, "INSERT")} Dim tSelFilter As New EditorInput.SelectionFilter(tDxfFilter) Dim tSelRes As EditorInput.PromptSelectionResult = AcadDocED.SelectAll(tSelFilter) If (tSelRes IsNot Nothing) AndAlso (tSelRes.Status = EditorInput.PromptStatus.OK) AndAlso (tSelRes.Value.Count > 0) Then tRetVal = tSelRes.Value End If Next Catch ex As Exception tRetVal = Nothing End Try Sinn der ganzen sache ist, dass ich folgenden Code optimieren wollte: For Each oLayout In oDoc.Layouts If oLayout.Name <> "Modell" And oLayout.Name <> "Model" Then For Each oAcadEntity In oLayout.Block If InStr(oAcadEntity.ObjectName, "BlockReference") > 0 Then oBlockRef = oAcadEntity If vb.Left(oBlockRef.Name, Len(cOLDTitleBlock)) = cOLDTitleBlock Then Dim varAttributes As Object varAttributes = oBlockRef.GetAttributes For i = LBound(varAttributes) To UBound(varAttributes) For j = 1 To UBound(aAttributes) If UCase(varAttributes(i).TagString) = UCase(aAttributes(j)) Then varAttributes(i).TextString = aValues(j) varAttributes(i).Invisible = False End If Next j Next i End If End If Next oAcadEntity End If Next oLayout ich habe in einem Array Elemente eines Schriftkopfes. und diese muss ich aktualisieren, um schneller zu sein und nicht immer alles durchzulaufen, wollte ich mit einem Selectionset nur nie benötigten rausholen und die durchgehen, da es glaube ich schneller ist. In dem Programm das ich geschrieben habe, kommen Stellen wo ich alle Elemente, Layouts, Blöcke durchlaufe sehr oft vor. vl bin ich da auch auf dem Holzweg und es keine bessere Lösung, oder sie geht ganz anders. mfg Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 12. Nov. 2008 09:53 <-- editieren / zitieren -->
Hi, Du must mal unterscheiden, ob Du COM-basiert arbeitest (was in meinen Augen, wenn Du mit dotNet arbeitest, schon mal die schlechtere Variante ist, weil langsamer (viel langsamer) und weniger Möglichkeiten oder mit Managed-Code. Der Ausdruck
Code: DirectCast(Marshal.GetActiveObject("AutoCAD.Application"), AcadApplication)
wird eigentlich verwendet, wenn Du Dich von einer externen Applikation aus mit AutoCAD verbinden willst. Das hat, da Du mit 'netload' Dein DLL ja schon in ein AutoCAD eingebettet hast, nur die grosse Gefahr, dass es nur funktioniert, wenn AutoCAD nicht aktiv ist (wenn Dein Code aber im AutoCAD läuft, dann ist AutoCAD aktiv, es würde mich also nicht wundern, wenn das hie und da mal stolpert. Weiters hast Du mit obigem das Problem (gleiches wie alle ActiveX-Anwendungen, die von aussen kommen), dass im Falle mehrerer gestarteter AutoCAD-Sessions Du NICHT weisst, mit welcher Du Dich jetzt verbindest. Mit AutoCAD verbinde ich mich wie folgt
Code: Dim pAcadDocMan As ApplicationServices.DocumentCollection = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager ...dann auf das aktuelle Document Dim pAcadDocCurrent as ApplicationServices.Document = pAcadDocMan.MdiActiveDocument ...das Document ist dann das managed-object, wenn du daraus das COM-basierende haben willst, dann dim tAcadDocCOMCurrent as Interop.IAcadDocument = pAcadDocCurrent.AcadDocument
Empfehlung: hol Dir von der Autodesk-Seite das ObjectARX-Kit herunter (ist frei, aber Registrierung notwendig), da hast Du eine Menge Code auch für dotNet-spezifische Dinge. - alfred -
|
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 12. Nov. 2008 11:47 <-- editieren / zitieren --> Unities abgeben:
Hallo! Hab mir das Kit heruntergeladen, und auch den Selectionset erfolgreich implementiert. In deinem Beispiel war Dim values() As TypedValue = { _ New TypedValue(DxfCode.Start, "INSERT")} wenn ich dann Dim entity As Entity = tm.GetObject(id, OpenMode.ForRead, True) MsgBox("entityname: " & entity.GetType().Name) bekomme ich acadblockreference zurück. ich will aber den Namen des Blockes haben, mir fällt keine kombination mehr ein, dass ich auf den namen komme. mfg Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 12. Nov. 2008 12:02 <-- editieren / zitieren -->
Hi, schau Dir mal an, was Du an Optionen bereitgestellt bekommst, wenn Du 'DxfCode.' eintipst, gleich nach Drücken auf '.' erhältst eine Liste und da steht, meine ich, 'BlockName' auch zur Verfügung. - alfred - |
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 12. Nov. 2008 13:17 <-- editieren / zitieren --> Unities abgeben:
hatte ich vorhin, aber bei Dim values() As TypedValue = { _ New TypedValue(DxfCode.BlockName, "INSERT")} findet er nichts. Bei Dim values() As TypedValue = { _ New TypedValue(DxfCode.Start, "INSERT")} komme ich auf den namen AcadBlockreference oder gehört, statt dem "INSERT", dann ein anderer Wert? evtl dass AcBlockReference? Das steht in den samples leider nicht, welche kombinationen es da gibt, und was wirklich wo hin gehört. mfg
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 12. Nov. 2008 13:21 <-- editieren / zitieren -->
Hi, wenn Du (so verstand ich Deine Aufgabenstellung) nach BlockReferenzen mit bestimmten Blocknamen suchst, dann: Dim values() As TypedValue = {New TypedValue(DxfCode.BlockName, "myBlockName")} - alfred - |
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 12. Nov. 2008 13:32 <-- editieren / zitieren --> Unities abgeben:
fast richtig, es ginge im prinzip so auch, aber mein gedanke war, Alle Blockreferenzen in selection set einlesen. Dann das Selectionset durchgeben, und dort abfragen ob sie einen bestimmten Namen haben, weil verschiedenen Namen auftreten können, die für mich relevant sind. Sonnst müsste ich nach jeden Namen suchen und überprüfen ob der Selectionset leer ist. Ausser es gibt da auch eine andere Möglichkeit. entity.GetType().Name = acblockreference , dann muss ich ja irgendwie auf den Block kommen, der referenziert wird. edit: habs raus, peinlich peinlich. Dim entity As Entity = tm.GetObject(id, OpenMode.ForRead, True).name kann natürlich nicht funktionieren. Dim block As BlockReference = tm.GetObject(id, OpenMode.ForRead, True) block.name = der block im selectionset
vl hilft es ja mal jemanden. mfg [Diese Nachricht wurde von veydan am 12. Nov. 2008 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 12. Nov. 2008 13:43 <-- editieren / zitieren -->
Hi, wenn Du die Blocknamen, nach denen Du suchst, vorweg schon weisst, dann kannst Du (bin mir aber nur fast sicher), die einzelnen Blocknamen mit ',' hintereinanderschreiben. Dim values() As TypedValue = {New TypedValue(DxfCode.BlockName, "myBlockName,myBlockName2,myBlockName3")} (wenn mit ',' nicht funktioniert, dann noch mit ';' probieren) sollte obiges nicht funktionieren, dann darfst Du halt nur auf (DxfCode.Start, "INSERT") filtern, das selection-set bringt die dann die ObjectID's der BlockReferenzen, die musst Du dann, wie Du schon angedeutet hast, durchscannen.
- alfred - |
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 12. Nov. 2008 15:01 <-- editieren / zitieren --> Unities abgeben:
ich nehme es zurück, es funktioniert doch noch nicht einwandfrei. jetzt sagt er, dass er die typen nicht konvertieren kann. Autodesk.AutoCAD.DatabaseServices.Blockreference auf Autodesk.AutoCAD.Interopt.Common.AcadBlockReference. was vorhin anders war, als es ging kann ich jetzt nicht sagen, aber dann muss man die einfach anders definieren. die Typen unter interopt.common beziehen sich auf die .net schnittstelle, oder auf die com? mfg [Diese Nachricht wurde von veydan am 12. Nov. 2008 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 12. Nov. 2008 15:07 <-- editieren / zitieren -->
Hi, dafür gibt's was! Wieder der Unterschied zwischen managed- und COM-basierend Code: dim tBlRef as DataBaseServices.BlockReference = xxxx dim tBlRefCOM as Interop.Common.AcadBlockReference = ctype(tBlRef.AcadObject, Interop.Common.AcadBlockReference)
- alfred -
|
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 12. Nov. 2008 18:38 <-- editieren / zitieren --> Unities abgeben:
kann man im selectionset auch angeben, was ein objekt nicht haben soll? Sprich ich gehe alle Linien durch und setze sie von Truecolors auf Acadcolors. da würde ich mir dann auch etwas ersparen, wenn ich nur die bekomme, die noch auf Truecolors sind. mfg Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 12. Nov. 2008 19:22 <-- editieren / zitieren -->
Hi, es gibt bei der Filterliste die Möglichkeit, 'and' bzw. 'or' und Klammerung zu machen, es wird dabei (voraussichtlich) auch ein 'not' geben. Da ich das aber nie verwende, bitte googlen. Wieso verwende ich das nie: Alle Funktionen, die in einer Transaction laufen und dabei berücksichtigen, nur die Objekte zu ändern, die zu ändern sind, ist managed-code so schnell, dass es meist gar nicht notwendig ist, zuerst ein SelectionSet zu bilden, sondern einfach alles durchscannen. Weiters wirst Du festgestellt haben, dass SelectionSet-Handling nicht möglich ist, wenn Du nur die Database einer DWG öffnest, diese aber nicht in den AutoCAD-Editor lädst, da kannst Du nur scannen. Als Beispiel: Du willst alle Elementfarben auf 'byLayer' stellen, dann nicht einfach jedem Element 'byLayer' zuweisen, sondern zuerst prüfen, ob es nicht schon auf 'byLayer' steht. - alfred - |
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 09. Mrz. 2009 08:47 <-- editieren / zitieren --> Unities abgeben:
Jetzt muss ich nochmal nachfragen. wo gehört das and or oder not hinzugefügt? weiters habe ich eine Funktion in vb die mir die Truecolor auf AcadColors umwandelt. Dies funktionierte durch einen einfachen Trick indem ich folgende Zeile schrieb: ActElement.color = ActElement.color dann wurde die Farbe auf Acadcolor umgewandelt. irgendwie funktioniert der Trick nicht mehr, gibt es da in .NET schon eine eigene Funktion dafür? bzw kann man gleich so filtern im selectionset dass es nur Truecolor Objekte auswählen soll? Wenn 50 % schon auf Acadcolor sind und 50% auf Truecolor muss ich ja nur die eine hälte der Truecolor durchgehen und spare mir so vl Zeit. mfg Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 09. Mrz. 2009 19:40 <-- editieren / zitieren -->
Hi, Zitat: wo gehört das and or oder not hinzugefügt
...nachdem ich die Klammerung in SelectionSets nie verwende, kann ich hier nur auf dieses Beispiel verweisen, wo es ev. klarer wird. Wenn ich Filterung verwende, dann kommt es scheinbar bei mir immer nur so unter, dass ich 'ODER' Verknüpfungen benötige, und dann schreibe ich diese eben mit ',' getrennt, siehe auch Beispiel (bereits oben):
Code: Dim values() As TypedValue = {New TypedValue(DxfCode.BlockName, "myBlockName,myBlockName2,myBlockName3")}
dieses kommt einer 'ODER'-Verknüfung gleich und kann auch WildChars enthalten, obiges bedeutet 'Selectiere alles, was den Blocknamen='myBlockName' ODER den Blocknamen='myBlockName2' .... hat'.Bzgl. des Farbzuweisungstricks: wenn das jemals so funktioniert hat, dann halte ich das für einen Fehler, da kommst Du nicht darum herum, die Elemente einzeln prüfen zu müssen, und dann auch einzeln zu setzen. Sorry - alfred - ------------------ www.hollaus.at |
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 10. Mrz. 2009 13:43 <-- editieren / zitieren --> Unities abgeben:
das mit den Farben klappt nicht so ganz... was mein Problem ist: Ich habe eben RGB Werte in den Eigenschaften von z.b. einer Linie stehen. Ich möchte aber die dazugehörige Autocadfarbe finden. Das ist weiters für mich wichtig, da ich jeder Indexfarbe eine bestimmte Linienstärke zuweise. darum muss ich vorher alle Farben umwandeln. jetzt die Frage, wie setze ich die Farbe auf eine Acadfarbe wenn ich nur den Wert 245,123,45 habe? bzw kann ich in einem Selectionset gleich nur die rgb Colors rausholen? es gibt ja Color und Colorname, evtl Funktioniert ja Colorname auf "" zu durchsuchen? nur das setzen bringe ich gar nicht hin so wie ich es will. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 10. Mrz. 2009 15:07 <-- editieren / zitieren -->
Hi, anbei Code, der (als Beispiel) aus dem ModelSpace alle Elemente durchforstet, wird ein Element gefunden, dessen Farbe eine TrueColor-Zuweisung hat, dann zeigt Dir dieser Code bei 'Debug.Print' den nächstgelegen AutoCAD-ColorIndex. Vorsicht, es hat mal einen Thread hier gegeben, der bei den Farben 7,8,9,250-255 bewiesen hat, dass die Umrechnung zwischen ColorIndex und TrueColor von der Bildschirmhintergrundfarben-Einstellung abhängig ist!! Code: Dim tBlTab As DatabaseServices.BlockTable = CType(tTrAct.GetObject(tAcadDoc.Database.BlockTableId, DatabaseServices.OpenMode.ForRead, True, True), DatabaseServices.BlockTable) Dim tModSp As DatabaseServices.BlockTableRecord = CType(tTrAct.GetObject(tBlTab(DatabaseServices.BlockTableRecord.ModelSpace), DatabaseServices.OpenMode.ForWrite, True, True), DatabaseServices.BlockTableRecord) For Each tObjID As DatabaseServices.ObjectId In tModSp If (tObjID.IsValid) AndAlso (Not tObjID.IsErased) Then Dim tEnt As DatabaseServices.Entity = CType(tTrAct.GetObject(tObjID, DatabaseServices.OpenMode.ForRead, True, True), DatabaseServices.Entity) If (tEnt.EntityColor.ColorMethod = Colors.ColorMethod.ByColor) Then 'ok, wir haben ein objekt, das ueber truecolor bestimmt wird Debug.Print(tEnt.EntityColor.ColorIndex.ToString) Debug.Print("") End If End If Next
Ich glaube nicht (hab aber auch nicht nachgeforscht), dass ein SelectionSet gebildet werden kann, das auf TrueColor-Elemente hinkommt.
- alfred - ------------------ www.hollaus.at |
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 10. Mrz. 2009 15:39 <-- editieren / zitieren --> Unities abgeben:
die Acadcolors sind unter .net ja im Namespace drawing.colors. oder? wenn man da nachschaut haben diese Farben aber keinen Index als Eigenschaft. Irgendwie funktionierte das mit vba etwas einfacher, oder ich blicke gerade einfach nicht durch. ich hoffe es stimmt wenn ich z.b herausgefunden habe das der Truecolor Wert eines Entities Grün ist und dann entity.color = drawing.colors.green setze. Wichtig ist dass unter den Entity Eigenschaften dann Green steht und nicht der RGB Wert. Bzw ich auf den Index zugreifen kann. mfg Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 10. Mrz. 2009 16:27 <-- editieren / zitieren -->
Hi, vorsicht mit der Unterscheidung, ob wir von Managed-Code sprechen oder Du das COM-Interface nutzt, mein Code von oben bezieht sich auf Managed-Code, Deiner Aussage nach '...haben diese Farben aber keinen Index als Eigenschaft...'. Hast Du meinen Code von oben mal probiert? - alfred - ------------------ www.hollaus.at |
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 11. Mrz. 2009 08:41 <-- editieren / zitieren --> Unities abgeben:
ja habe ich probiert, aber wenn der code fertig ist, und ich will in acad noch etwas arbeiten, es genügt 1 klick kommt folgende meldung: Systemfehler: Unhandled access violation reading 0x9000028 Exception at 62781b57h abgesehen von dem Fehler: Wenn ich es richtig verstanden habe müsste ich die Colormethod von den entities die ByColor(Truecolor) haben auf byAci(acadcolors) stellen, das property ist aber readonly. oder funktioniert das umschalten anders? gibt es irgendwo eine Doku wie die Farbfunktionen zusammenhängen, bzw was die Funktionen im Detail machen? und was ist der Unterschied zwischen tEnt.Color und tEnt.Entitycolor ? [Diese Nachricht wurde von veydan am 11. Mrz. 2009 editiert.]
[Diese Nachricht wurde von veydan am 11. Mrz. 2009 editiert.] [Diese Nachricht wurde von veydan am 11. Mrz. 2009 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 11. Mrz. 2009 10:10 <-- editieren / zitieren -->
Hi, Zitat: Systemfehler: Unhandled access violation reading 0x9000028 Exception at 62781b57h
==> sehr wahrscheinlich, dass eine TransAction oder ein DocumentLock nicht ordnungsgemäß beendet/disposed wurde. Zitat: gibt es irgendwo eine Doku wie die Farbfunktionen zusammenhängen
Ich habe nichts anderes als das ObjectArx-Kit (und CAD-de und Google) zur Verfügung, wobei die Beispiele im ObjectARX gut sind, die Doku, zugegeben, gibt größtenteils nur Signatures bekannt und leider wenig Beispiele bzw. nähere Erklärungen. Zitat: Unterschied zwischen tEnt.Color und tEnt.Entitycolor
Erstere ist die alte Version, diese wird auch als 'obsolete' markiert (wenn alle Compiler-Einstellungen auf 'besonders streng' eingestellt sind). Das bedeutet in einer der nächsten Versionen kann es sein, dass es diese Entity-Eigenschaft nicht mehr gibt, also ist '.EntityColor' zu empfehlen, auch wenn aufwendiger. Die Farbeigenschaft als ACI setzen funktioniert so:
Code: DBEntity.Color = Colors.Color.FromColorIndex(Colors.ColorMethod.ByAci, tColor) 'tColor steht für den ColorIndex als Short-Typ
- alfred - ------------------ www.hollaus.at |
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 11. Mrz. 2009 11:06 <-- editieren / zitieren --> Unities abgeben:
bei mir geht dass nicht... die Farben bleiben auf Truecolor. Code: <Autodesk.AutoCAD.Runtime.CommandMethod("vbChangeCol")> _ Public Sub ChangeCol() Dim tAcadDoc As ApplicationServices.Document tacaddoc = ApplicationServices.Application.DocumentManager.MdiActiveDocument Dim myTransMan As DatabaseServices.TransactionManager Dim tTrAct As DatabaseServices.Transaction myTransMan = tacaddoc.TransactionManager tTrAct = myTransMan.StartTransaction Dim tBlTab As DatabaseServices.BlockTable = CType(tTrAct.GetObject(tAcadDoc.Database.BlockTableId, DatabaseServices.OpenMode.ForRead, True, True), DatabaseServices.BlockTable) Dim tModSp As DatabaseServices.BlockTableRecord = CType(tTrAct.GetObject(tBlTab(DatabaseServices.BlockTableRecord.ModelSpace), DatabaseServices.OpenMode.ForWrite, True, True), DatabaseServices.BlockTableRecord) For Each tObjID As DatabaseServices.ObjectId In tModSp Dim tEnt As DatabaseServices.Entity = CType(tTrAct.GetObject(tObjID, DatabaseServices.OpenMode.ForWrite, True, True), DatabaseServices.Entity) If (tEnt.EntityColor.ColorMethod = Colors.ColorMethod.ByColor) Then tEnt.Color = Colors.Color.FromColorIndex(Colors.ColorMethod.ByAci, CShort(tEnt.EntityColor.ColorIndex)) End If 'End If Next tTrAct.Dispose() myTransMan.Dispose() End Sub
mfg Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 11. Mrz. 2009 11:10 <-- editieren / zitieren -->
Hi, ohne den Code intern angesehen zu haben, ganz unten fehlt tTrAct.Commit und ganz wichtig!!!! ==> nicht den TransActionManager disposen, den brauchst Du ja noch - alfred - ------------------ www.hollaus.at [Diese Nachricht wurde von a.n. am 11. Mrz. 2009 editiert.] |
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 11. Mrz. 2009 11:17 <-- editieren / zitieren --> Unities abgeben:
|
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 19. Mrz. 2009 14:55 <-- editieren / zitieren --> Unities abgeben:
hallo! ich wollte jetzt meine einzelnen funktionen in mein Programm reinpacken. Wenn ich meine Test dll mit den Funktionen lade und sie ausführe funktionieren sie. Lade ich aber eine dll wo ich eine Oberfläche aufrufe, über die ich steuere welche Funktion ich ausführe, bekomme ich z.b beim linienfarben umsetzen einen Fehler Hier der Code: Code:
Try Dim tAcadDoc As ApplicationServices.Document tAcadDoc = ApplicationServices.Application.DocumentManager.MdiActiveDocument Dim mydb As DatabaseServices.Database Dim myTransMan As DatabaseServices.TransactionManager mydb = tAcadDoc.Database Dim tTrAct As DatabaseServices.Transaction myTransMan = tAcadDoc.TransactionManager tTrAct = myTransMan.StartTransaction Dim tBlTab As DatabaseServices.BlockTable = CType(tTrAct.GetObject(tAcadDoc.Database.BlockTableId, DatabaseServices.OpenMode.ForRead, True, True), DatabaseServices.BlockTable) 'Dim tmpblockrec As DatabaseServices.BlockTableRecord = CType(tTrAct.GetObject(tBlTab(DatabaseServices.BlockTableRecord.ModelSpace), DatabaseServices.OpenMode.ForWrite, True, True), DatabaseServices.BlockTableRecord) Dim blockenum As DatabaseServices.SymbolTableEnumerator Dim blocktablerec As DatabaseServices.BlockTableRecord tBlTab = mydb.BlockTableId.GetObject(OpenMode.ForRead) blockenum = tBlTab.GetEnumerator While blockenum.MoveNext blocktablerec = blockenum.Current.GetObject(OpenMode.ForWrite) For Each tObjID As DatabaseServices.ObjectId In blocktablerec Dim tEnt As DatabaseServices.Entity = CType(tTrAct.GetObject(tObjID, DatabaseServices.OpenMode.ForWrite, True, True), DatabaseServices.Entity) If (tEnt.EntityColor.ColorMethod = Colors.ColorMethod.ByColor) Then tEnt.Color = Colors.Color.FromColorIndex(Colors.ColorMethod.ByAci, CShort(tEnt.EntityColor.ColorIndex)) End If Next End While tTrAct.Commit() tTrAct.Dispose() myTransMan.Dispose() Catch ex As Exception MsgBox("ConvertTrueColor2AcadColor" & vbNewLine & ex.Message & vbNewLine & ex.StackTrace) End Try
der Fehler passiert hier:
Code:
blocktablerec = blockenum.Current.GetObject(OpenMode.ForWrite)
eLockViolation bei Transactionmanager.GetObjectinternal .... getObject.eLock hört sich an, als wenn das Objekt gesperrt ist. aber ich habe vorher gar nichts gemacht, ausser die Form aufgerufen über die dann die Funktion ausgelöst wird. mfg Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 19. Mrz. 2009 16:22 <-- editieren / zitieren -->
Hi, wenn eine Funktion aus dem Form (eigentlich ohne AutoCAD-Befehl) gestartet wird, dann muss die Funktion dafür das Document vor Zugriff von anderen Befehlen sperren. Code: Dim tAcadDocLock As ApplicationServices.DocumentLock .... tAcadDocLock = tAcadDoc.LockDocument 'ist vor TransAction starten zu setzen... 'und am Ende (nach TransAction-dispose) if tAcadDocLock isnot nothing then tAcadDocLock.Dispose
- alfred - ------------------ www.hollaus.at |
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 28. Mai. 2009 15:47 <-- editieren / zitieren --> Unities abgeben:
Jetzt muss ich den Thread nochmal ausgraben. Es geht um eine Exe die Autocad Steuert, ja ich weiß da ist es langsamer als in einer dll, aber der Kunde will es so. Ich habe einen Selectionset, der nach einem bestimmten Block suchen soll. Zur Info, den Block habe ich 3x: jeweils 1x im Modell, Layout1, Layout2 hier der Code: Dim ssetSkObjs As AcadSelectionSet Dim FilterType(1) As Integer Dim FilterData(1) As Object FilterType(0) = 0 FilterType(1) = 2 FilterData(0) = "INSERT" FilterData(1) = "Schriftfelder*" ssetSkObjs = CreateSelectionSet(ThisDrawing, "SkObjs") Call ssetSkObjs.Select(Common.AcSelect.acSelectionSetAll, , , FilterType, FilterData) 'Call ssetSkObjs.SelectOnScreen(FilterType, FilterData) MessageBox.Show(ssetSkObjs.Count) --->>> Ergibt immer 0, ABER in vba Funktionierts!! hier noch die fkt für den Selectionset Public Function CreateSelectionSet(ByRef Thisdrawing As AcadDocument, ByVal ssName As String) As AcadSelectionSet Dim objSelSet As AcadSelectionSet Dim objSelCol As AcadSelectionSets objSelCol = Thisdrawing.SelectionSets For Each objSelSet In objSelCol If objSelSet.Name = ssName Then objSelCol.Item(ssName).Delete() Exit For End If Next objSelSet = objSelCol.Add(ssName) CreateSelectionSet = objSelSet End Function EDIT: Der Fehler den ich bekomme ist(errormessage): Beim Aufruf der COM Komponente wurde ein HRESULT E_FAIL-Fehler zurückgegeben. mfg [Diese Nachricht wurde von veydan am 28. Mai. 2009 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 28. Mai. 2009 16:38 <-- editieren / zitieren -->
Hi, probiert hab ich Deinen Code nicht, die wichtigste Info, die fehlt, wäre: an welcher Zeile tritt der Fehler auf? - alfred - [EDIT]probier mal Dim FilterType(1) As Integer auszutauschen gegen Dim FilterType(1) As Int16 [/EDIT] ------------------ www.hollaus.at [Diese Nachricht wurde von a.n. am 28. Mai. 2009 editiert.] |
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 29. Mai. 2009 07:36 <-- editieren / zitieren --> Unities abgeben:
Der Fehler passiert genau beim .select Aber vl ist es besser ich mache einen Workaround. Sprich eine Exe die Acad Startet und dann meine Dll lädt, wo ich dann auch die ApplicationServices zur Verfügung habe. Die Abänderung auf Int16 hat nicht funktioniert. Habe auch schon Object und Integer probiert. mfg Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 29. Mai. 2009 07:46 <-- editieren / zitieren -->
Hi, das mit in AutoCAD eine DLL laden (und nur das Laden DLL und das Ansteuern der Funktionen im DLL vom EXE aus steuern) halte ich jedenfalls für die bessere Variante. Noch ein Versuch: statt Call ssetSkObjs.Select(Common.AcSelect.acSelectionSetAll, , , FilterType, FilterData) versuch mal Call ssetSkObjs.Select(5, , , FilterType, FilterData) - alfred -
------------------ www.hollaus.at |
veydan Mitglied
Beiträge: 252 Registriert: 29.05.2008 AutoCAD/Mechanical 2009, Inventor 2009
|
erstellt am: 29. Mai. 2009 08:28 <-- editieren / zitieren --> Unities abgeben:
|
Silvan01 Mitglied
Beiträge: 128 Registriert: 28.04.2009 AutoCAD Civil 2009 AutoCAD Civil 2010 Visual Studio 2008
|
erstellt am: 06. Apr. 2010 11:20 <-- editieren / zitieren --> Unities abgeben: Nur für veydan
Hallo Zusammen, ich habe auch ein Filterproblem... Aufgabenstellung: Alle Objekte des Typs MTEXT auf allen Layouts die "planung" oder "Planung" im Namen beinhalten. Folgendes habe ich erstellt und getestet - ohne Erfolg: Code:
Dim tDxfFilter() As TypedValue = {New TypedValue(DxfCode.Operator, "<and"), _ New TypedValue(DxfCode.Start, "MTEXT"), _ New TypedValue(DxfCode.Operator, "<or"), _ New TypedValue(DxfCode.LayoutName, "*planung*"), _ New TypedValue(DxfCode.LayoutName, "*Planung*"), _ New TypedValue(DxfCode.Operator, "<or"), _ New TypedValue(DxfCode.Operator, "and>")}Dim tSelFilter As New SelectionFilter(tDxfFilter) Dim tSelRes As PromptSelectionResult = AcadDoc.Editor.SelectAll(tSelFilter)
kann mir jemand bitte auf die Sprünge helfen? Grüße Silvan
[Diese Nachricht wurde von Silvan01 am 06. Apr. 2010 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 06. Apr. 2010 11:25 <-- editieren / zitieren -->
Hi, wieso so kompliziert? Code: Dim tDxfFilter() As TypedValue = {New TypedValue(DxfCode.Start, "MTEXT"), _ New TypedValue(DxfCode.LayoutName, "*planung*,*Planung*")}
...wobei ich nichtmal glaube, dass Groß- und Kleinschreibung unterschieden wird. Bei z.B. Layernamen oder Blocknamen bin ich sicher, dass es keine Unterscheidung gibt, Layoutnamen glaub ich auch nicht, aber weiss ich nicht gewiss. - alfred - ------------------ www.hollaus.at |
Silvan01 Mitglied
Beiträge: 128 Registriert: 28.04.2009 AutoCAD Civil 2009 AutoCAD Civil 2010 Visual Studio 2008
|
erstellt am: 06. Apr. 2010 11:42 <-- editieren / zitieren --> Unities abgeben: Nur für veydan
Hallo, also komplizierter ist es geworden weils leicht nicht funktioniert hat. Fehler lag bei mir - Ich hab zum Test neue Layouts erstellt und Namen gegeben in denen "Planung" (groß- und kleingeschrieben) vorkam. Auf den Layouts hat man dann eine Abbildung vom Modell gesehen -> Die Objekte waren aber nicht kopiert. Das heißt die MTEXT Objekte waren nur im Modellbereich nicht aber da wo ich suchen wollte... Code:
Dim tDxfFilter() As TypedValue = {New TypedValue(DxfCode.Start, "MTEXT"), _ New TypedValue(DxfCode.LayoutName, "*planung*")}
<- hat wunderbar geklappt. Findet alle groß- und kleingeschriebenen "Planung". Danke trotzdem Grüße Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
| Anzeige.:
Anzeige: (Infos zum Werbeplatz >>)
|