| |  | Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte | | |  | NVIDIA GTC Paris und ISC High Performance-Konferenz 2025, eine Pressemitteilung
|
Autor
|
Thema: reaktor: erase, added, modified (1497 mal gelesen)
|
reltro Mitglied student
 
 Beiträge: 125 Registriert: 08.11.2009 Acad 2012 - VBA,Lisp Revit 2012 3dsMax 2012 Rhino 5 - GH,Pyhton,rhino.Common<P>Win 7 - i7 4x3.2GHz - 8Gb DDR3
|
erstellt am: 09. Feb. 2012 09:19 <-- editieren / zitieren --> Unities abgeben:         
Hallo erstmal, bin auf der suche nach unterstützung, in der Hoffnung diese hier anzufinden. Bin für jede Hilfe dankbar. Folgendes Problem bzw. Ziel: Ziel: Ich möchte eine polyLinie anklicken bzw. einen Befehl ausführen und sie dann anklicken, um aufgrund der Geometrie dieser Polyline ein technisches Symbol hinzuzufügen. In diesem konkreten fall geht es darum aus der Polyline eine AbdichtungsBahn(Hochbau) zu machen. dafür nehm lese ich die PolyLine ein, konstruiere meine zusätzliche Geometrie und packe die ZusatzGemoetrie in einen Block. Dieser Block liegt dann auf einem gesperrten Layer, so dass ich diesen nicht direkt verändern kann, weil er grundsätzlich immer mit der Polyline verknüpft sein soll, und aufgrund der veränderung der Polyline sich mitverändert. so weit so gut. Problem: Das Problem besteht darin die Polyline mit dem dazugehörigen Block auf ewig zu verknüpfen. sprich, wenn benutzer die polyline ändert, ändert sich der Inhalt des Blocks. Die Erstellung der Verknüpfung hätte ich wie folgt angedacht: Zunächst bekommt die Polyline XData angehängt, welche die Eigenschaften der ZusatzGeometrie beinhaltet Zudem wird ein Dictionary erstellt welches die Verknüpfung PolyLine - Block enthält. Hierzu hab ich mir gedacht ich verwende das Handle der PolyLine, welches ja eindeutig und statisch sein sollte, und den dazugehörigen Blockname. Dies Sollte soweit auch funktionieren und die dinge sollten daruch direkt verknüpfbar sein. Nun zu den Events: 1) wird der Layer auf dem die Blöcke liegen entsperrt werden, darf er das nicht tun, bzw. muss sich wieder sperren, weil ich ein verschieben/kopieren/löschen der Blockreference vermeiden will. 2) verändert der benutzer die PolyLine wird die Verknüpfung gesucht, der Inhalt des dazugehörigen Blockes gelöscht und im nachhinein neu erstellt. Hier bin ich mir noch nicht sicher wie ich vorgehn will; ob die veränderung der blockes gleich stattfindet oder erst mit dem "regen"-befehl, wobei ich eher dazu tendiere die Variante mit dem regen zu bauen. Hierzu hab ich mir überlegt dass das Dictionary(oben angesprochen), einen sozusagen "dieswürdeverändert"-Container enthält in dem die handels der geänderten Polylines liegen, und diese beim RegenBefehl ausgelesen werden, und stepbystep abgearbeitet werden. 3) Copy Wenn der Benutzer die PolyLine kopiert, bleiben die Xdatas ja erhalten bzw. werden dem neuen Objekt ebenso angehängt, nur das Handle (weil es ja eindeutig ist) verändert sich. Reaktor: added greift; welcher nun dem Dictionary einen eintrag (handle) hinzufügt um beim neusten "Regen" einen zusätzlichen Block für die Zusatzgeometrie zu erstellen. 4) erase Hier liegt momentan wohl mein größtes Problem. Die Rückgabe des erase-Events ist eine ObjectID, nur wie kann ich das ganze so hinbiegen dass ich das davor gültige Handel für das Objekt bekomme, um im nächsten Schritt nachzusehn ob es Teil des Dictionary ist, und somit in meine Bearbeitung mitaufgenommen werden muss. Beim erase, sollte der Eintrag aus dem Dictionary entfernt werden und der Inhalt des Blockes sowie die dazugehörige Blockreferenz gelöscht werden. Der Block ist jetzt jedoch immer noc vorhanden und würde ja erst mit einem Purge vershwinden, was ich aber aus dem Programm nicht machen will, weil VBA, soweit ich es gefunden habe, nur PurgeAll kennt. so bleibt einfach eine leerer Block bestehen, ohne zugehörige Blockreferenz, welche später weiterverwendet werde kann oder eben durch manuelles Purge eleminiert wird. Ähm ich glaube die erklärung zum vorhaben ist umfassend, vielleicht zu ausführlich. Momentan bin ich an dem Punkt dass ich die Zusatzgemoetire zeichne lassen kann, diese in einem Block steckt welcher eingefügt wird, der Layer ist gesperrt, und ja, das hinzufügen von XDATA und Dictionary ist zwar noch nicht vorhanden, stellt aber kein Problem dar. Das grundlegende Problem ist der bau der reaktoren bzw. Die herangsweise die Verknüpfung so simpel als möglich zu konstruieren. Wie es funktionieren könnte, hab ich mir schon ausgedacht , nur ob dieser Weg ein sinnvoller ist, naja, wage ich zu bezweifeln. Vielleicht hat jemand von euch hier eine Idee, bzw vorschlag. aso, die Events welche mit eine Class oder was auch immer verknüpft sind durchblicke ich nicht wirklich. Vielleicht ist dort ein Weg. Hoffe auf eure Hilfe, und "erwarte" mir viele viele Denkanstöße, vielleicht erklärende CodeSchnippsel . Nur bitte kein "HierhastDu"-Ding, weil mir dabei der Lernfaktor abgeht. Hoffe das ist Ok, das so zu sagen.
LG reltro
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Brischke Ehrenmitglied V.I.P. h.c. CAD on demand GmbH

 Beiträge: 4191 Registriert: 17.05.2001 ACAD20XX, defun-tools
|
erstellt am: 10. Feb. 2012 08:56 <-- editieren / zitieren --> Unities abgeben:          Nur für reltro
Hallo reltro, ich habe es mir jetzt 2mal durchgelesen. Die Aufgabe ist ansich soweit klar, aber das jetzt alles zu durchdenken und deine Gedanken zu prüfen, ist einiges an Aufwand, den ich nebenher nicht aufbringen kann. Interessant ist die Aufgabe, weshalb ich dennoch mit einem grundelegend anderen Ansatz antworte - allerdings ohne VBA. Die Schwierigkeit ist ja das aktuell halten der Verknüpfung zwischen Polyline und BLock. Daher würde ich dies umschiffen, indem ich die Polyline mit einer recht neuen Technik aus der .Net-Ecke angehen würde: Overrule Mit dieser Technik hast du die möglichkeit, die Darstellung der physisch vorhandenen Zeichnungsobjekte zu ändern. Das heißt, du kannst an einer Polylinie z.Bsp immer einen Text anzeigen lassen, der die aktuelle Länge dieser Polyline beinhaltet. Dieser Text existiert physisch in der Zeichnung nicht - ist auch nur sichtbar, wenn man das entsprechende Plugin besitzt. Diese Technik könnte man nun hernehmen und die Infos, die du im Block anzeigen möchtest, eben als solchen nicht physischen Text anzeigen zu lassen - damit ist das ganze Reactoren-Zeugs überflüssig. Sollen diese Infos allerdings physisch in die Zeichnung eingetragen werden, muss es einen Befehl geben, der diese Elemente dann eben auch tatsächlich in der Zeichnung erzeugt, das ist aber deutlich weniger Aufwand, als das Handling der Reaktoren .. und, imgrunde hättest du den dafür notwendigen Code ja bereits für das Overruling bereits geschrieben. Ich weiß, dass das jetzt keine Antwort ist, die dich weiter bringt, womöglich für dich auch nicht zu realisieren ist, weil du jenseits von VBA in eine für dich vielleicht neue Programmiersprache rein müßtest. Die Entscheidung liegt aber bei Dir .. denn es ist sicher auch noch zu prüfen, ob das Overruling für die Aufgabe tatsächlich geeignet ist. Grüße! Holger ------------------ Holger Brischke 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 |
reltro Mitglied student
 
 Beiträge: 125 Registriert: 08.11.2009 Acad 2012 - VBA,Lisp Revit 2012 3dsMax 2012 Rhino 5 - GH,Pyhton,rhino.Common<P>Win 7 - i7 4x3.2GHz - 8Gb DDR3
|
erstellt am: 10. Feb. 2012 11:58 <-- editieren / zitieren --> Unities abgeben:         
Hallo holger. Vielen Dank für deine Antwort. Zunächst mal. Es ist nicht notwenidg bzw. fordere ich nicht dass du meine Gedanken überprüfst. Ich habe sie nur, auch für mich, nochmal ins physische übersetzen wollen.  Das Ziel war ja eben jenes das du mit deiner Antwort wiedergibst: Eine andere Möglichkeit zu finden als Mühsehlig mit den Reaktoren rumzuspinnen. Weil, vielleicht durchblicke ich die Funktionsweise der Reaktoren auch nicht zur Gänze, ich einfach keinen "einfachen" Weg finde diese für ein spezielles makro zu bauen, und im gleichen Schritt für andere Dinge den Weg offen zu halten. Zu deiner Idee mit dem Overrule in VB.Net. Sowas suche ich schon längers, und hab mir auch ein paar Ideen zusammengesponnen was man mit sowas tun könnte, und das ist verdammt viel. In diesem konkreten Fall sollten die Dinge aber physisch vorhanden sein. Wobei man dazu sagen muss, sie sollten/müssten es erst beim Drucken einen physischen Charakter annehmen. Dies hätte den Vorteil dass die zeichnung nicht unnötig "verunreinigt" wird. Ich finde deine Antwort sehr hilfreich, und außerdem wollte ich sowieso von VBA weg und mich mit VB.net beschäftigen. Das wird jedoch erst nach vollendung des Projektes stattfinden. ob das Ding in VBA dann einwandfrei rennt bleibt noch fragwürdig und für mich auch nicht so wichtig. Weil ich mir im Anschluss so und so VB.net anschaun werde und dieses dort nochmal nachbauen werde. Diese Projekt ist ein Schritt in die Richtung die du beschreibst, Eben jenes "Preview" von Objekten ohne sie zu Zeichnen, oder in VBA eben das, dass physische Objekte den Charakter einer ""Preiview"" annhemen und von anderen abhängig gemacht werden.
Wie gesagt, werde das in VBA (versuchen zu) realisieren, wobei ich dazu ein paar konkrete Fragen hätte die du mir vielleicht beantworten kannst/magst/willst?
1) Wie bekomme ich beim Event ObjectErased aus der ObjectID das Handle. Im grund gibt es ja kein Handle mehr, weil das Object nicht mehr da ist. Meine herangehnsweise wär nun die gewesen, dass vor dem löschen, sprich mit BeginCommand(a) ->[a="ERASE"] die entsprechenden Elemente(über XDATA und APPNAME) suche die ObjectID und das Handle ablege um Danach(nach dem löschen) in der Liste die ObjectID zu suchen und somit das Handle habe, welches dann weiterverwertet wird. ???? Nun bleibt die Frage ob sich die ObjectID der Elemente in der Zeichnung während dem löschvorgang ändert? Ich lösche zb. 10Elemente. NR.1 wird gelöscht,reaktor "objecterased" springt an -> ObjectID -> Liste(oben beschreiben) -> Handle..... Ändern sich in der ZwischenZeit die ID's der restlichen 9? !!! Ein Problem bliebt hier aber. Was passiert wenn das Element nich direkt über ein Command vom Benutzer gelöscht wird, sondern aus einem Skript heraus? Dafür hab ich leider noch keinen Plan. :| wenn deine Zeit reicht, wär ich dankbar über eine antwort. Wenn nicht, macht nix. Dann werde ichs herausfinden 
LG Reltro Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Brischke Ehrenmitglied V.I.P. h.c. CAD on demand GmbH

 Beiträge: 4191 Registriert: 17.05.2001 ACAD20XX, defun-tools
|
erstellt am: 10. Feb. 2012 13:22 <-- editieren / zitieren --> Unities abgeben:          Nur für reltro
Hallo, die Ids bleiben für die aktive Sitzung gleich. Öffnet man die Zeichnung neu, könnte es eine andere Id sein. Wenn man ein Objekt löscht, ändern sich auch nicht die Ids der anderen Objekte. In VBA kenne ich mich zu wenig aus, als dass ich da sagen könnte, wei man von einer ObjektId auf die Handle kommt. In c#.Net ist das überhaupt kein Problem. Das Objekt kann schon vor Stunden gelöscht worden sein., so lange man die ObjektId hat, kann man davon auch die Handle abfragen. Das ist in c#.Net ein Einzeiler (wenn man den Überbau mal wegdenkt:
Code:
using System; using System.Collections.Generic; using System.Linq; using System.Text;using Autodesk.AutoCAD.Runtime; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; namespace testObjectIdByErased { public class HandleByObjectID { [LispFunction("_GetHandleByErasedObjectId")] public String GetHandleByErasedObjectId(ResultBuffer _rb) { String _result = ""; TypedValue[] _tvs =_rb.AsArray(); try { ObjectId _elemId = (ObjectId)_tvs[0].Value; _result = _elemId.Handle.ToString(); } catch { } return _result; } } }
Theoretisch kann man .Net Programme auch so kompilieren, dass die hinterher als in ActiveX eingebunden werden können. Vielleicht ist das ein Weg, dass man die beiden Umgebungen mischt? ------------------ Holger Brischke 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 |
reltro Mitglied student
 
 Beiträge: 125 Registriert: 08.11.2009 Acad 2012 - VBA,Lisp Revit 2012 3dsMax 2012 Rhino 5 - GH,Pyhton,rhino.Common<P>Win 7 - i7 4x3.2GHz - 8Gb DDR3
|
erstellt am: 10. Feb. 2012 14:28 <-- editieren / zitieren --> Unities abgeben:         
mmmkay, also C#.net ist mir ein wenig kryptisch. Was mir aber sofort ins auge gestochen ist, ist das [LispFunction("_GetHandleByErasedObjectId")] hmmm, ob das wirklich was mit Lisp zu tun hat, war die nächste Frage, wenn ja (wahrscheinlich ja), dann müsste dahinter doch eine Funktion stecken?  Lisp ist gut, in Lisp kenn ich mich aus du auch? vielleicht kennst du dort einen Weg? das mit dem compilieren zu AktiveX, ähm, ja; keine Ahnung wie, und vorallem noch weniger was ich compilieren sollte. Wenn es eine möglickeit gibt das handle aufgrund einer ObjectID eines gelöschten Elements zu bestimmen; die es anscheinend gibt; wär das doch der Knüller, und viele, wenn nicht all meine Probleme würden sich mir lösen.  Bitte Bitte sag du kennst eine Variante in Lisp  Lg Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Brischke Ehrenmitglied V.I.P. h.c. CAD on demand GmbH

 Beiträge: 4191 Registriert: 17.05.2001 ACAD20XX, defun-tools
|
erstellt am: 14. Feb. 2012 21:54 <-- editieren / zitieren --> Unities abgeben:          Nur für reltro
Hallo reltro, jetzt habe ich den Beitrag zu spät gelesen, als dass ich da den Code gleich noch kompliliert hätte anhängen können. (Bin nicht mehr im Büro, erst am Freitag wieder). Das Thema ActiveX habe ich nur reingebracht, weil du in deinem vorherigem Beitrag VBA erwähnt hattest. Der c#-Code definiert (das hast du also gut erkannt) eine zusätzliche Lisp-Funktion. Ist die compilierte DLL geladen, dann gibts es im Lisp auch diese Funktion. Ich mach's am Freitag, bis dahin ... Grüße! Holger ------------------ Holger Brischke 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 |
reltro Mitglied student
 
 Beiträge: 125 Registriert: 08.11.2009 Acad 2012 - VBA,Lisp Revit 2012 3dsMax 2012 Rhino 5 - GH,Pyhton,rhino.Common<P>Win 7 - i7 4x3.2GHz - 8Gb DDR3
|
erstellt am: 15. Feb. 2012 17:50 <-- editieren / zitieren --> Unities abgeben:         
Hey Holger, Danke für dein Angebot der Unterstützung. hab das ganz jetzt auf einen anderen Weg gelöst. Jedoch wär es mit sicherHeit für die Nachwelt hilfreich. Habe danach so intensiv gesucht wie selten nach etwas. Meine Lösung: Habe jetzt denn "acadDocument_activate"-reaktor verwendet um die ObjectID's jedes mal zu generieren und in ein Dictionary zu schreiben um die Verknüpfung mit den handle's aufzubauen. Funkt soweit sehr gut und bis zu diesem Punkt auch zufreidenstellend. '---------------------------------------------------------------------------------- Aber du kannst mir gern bei einem anderen Problem weiterhelfen. Nähmlich folgendes: Ich verwende unter anderem auch den "DoubleKlick"-reaktor, was in diesem Sinne auch nicht das Problem darstellt. Nur ist der DoubleKlick eben auf einen Block anzuwenden, bzw. reagiert auf Blöcke. Durch den DoubleKlick rufe ich eine Userform auf, aus welcher ich wiederrum in die Zeichnung zurkehren muss, um eine PolyLine auszuwählen. Jetzt ruft das zurückkehren zur Zeichnung (nach meiner Nachvollziehbarkeit) den befehl "Bedit" auf, mit passenden Dialog, welcher das "ThisDrawing.Utility.GetEntity" (aus der Userform aufgerufen) stört und einen fehler genau bei diesem verursacht. Dies tut das Ding genau 3mal; danach funktionierts tadellos. Jetzt könnte man den Weg gehn; weil ich ja weiß dass es genau 3mal vorkommt; das "ThisDrawing.Utility.GetEntity" genau so oft aufzurufen und den Fehler mit "on error resume Next" zuüberspringen. das wär jedoch nicht recht optimal, weil der Auruf auch aus anderen Anfangsbedingungen ausgeführt wird, wo es bereits beim ersten mal ohne Fehler funktioniert. Gibt es eine möglichkeit den start des command: "Bedit" verhindern? und wenn ja, wie denn? bzw. kann es auch sein dass es an etwas anderem liegt. '---------------------------------------------------------------------- Noch eine ExtraFrage, falls es deine Zeit zulässt  Ich suche nach einem "Browse a File"-Dialog mit der Begrenzung auf genau 1mal .txt (Aufruf aus einer Userform) Ahnung? Anregung? Wenn möglich in reinem VBA... maybe als Function mit Rückgabe des Files. :S '---------------------------------------------------------------------- Am Ende bleibt nur noch die Frage offen, wie ich dir für deine Hilfe danken kann... LG reltro Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Brischke Ehrenmitglied V.I.P. h.c. CAD on demand GmbH

 Beiträge: 4191 Registriert: 17.05.2001 ACAD20XX, defun-tools
|
erstellt am: 17. Feb. 2012 10:48 <-- editieren / zitieren --> Unities abgeben:          Nur für reltro
Zitat: Original erstellt von reltro: ... Jedoch wär es mit sicherHeit für die Nachwelt hilfreich. ...
anbei die DLL. Laden mit Netload, dann kann man in Lisp auf die neue Funktion _GetHandleByErasedObjectId zugreifen. (_GetHandleByErasedObjectId <ObjectId> ) ---------- Zu deinen anderen Fragen kann ich nichts sagen. Dazu habe ich zu wenig Ahnung, was VBA angeht. Wie der Doppelklick zum Öffnen des Blockeditors implementiert ist .. auch damitz habe ich mich noch nicht beschäftigen müssen. Grüße! Holger ------------------ Holger Brischke 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 |
CADmium Moderator Maschinenbaukonstrukteur
       

 Beiträge: 13530 Registriert: 30.11.2003 ACAD 2008 Mechanical
|
erstellt am: 17. Feb. 2012 11:01 <-- editieren / zitieren --> Unities abgeben:          Nur für reltro
|
reltro Mitglied student
 
 Beiträge: 125 Registriert: 08.11.2009 Acad 2012 - VBA,Lisp Revit 2012 3dsMax 2012 Rhino 5 - GH,Pyhton,rhino.Common<P>Win 7 - i7 4x3.2GHz - 8Gb DDR3
|
erstellt am: 20. Feb. 2012 09:21 <-- editieren / zitieren --> Unities abgeben:         
Hello again... Holger, Danke für deine Mühe. Wird in der zukunft mit Sicherheit seine Anwendung finden.  Cadmium, Danke für deine beitrag. Hab das mit dem WScript nun ausprobiert. Der Gedanke einfach ein ESC abzusetzen ist so banal, wie einfach und funktioniert zudem auch einwandfrei um das "BEDIT" abzufangen und zu beenden, ... Code:
'RundHerumBau des Reaktors fehlt hier Dim obj As Object Set obj = CreateObject("WScript.shell") obj.SendKeys "{ESC}" 'Anscheinend wird das "SendKey" auf das zur Zeit geöffnete Fenster angewendet bzw. gesendet. ja?
... jedoch tritt das Problem, die Fehler bei "ThisDrawing.Utility.GetEntity", beim Aufruf aus der Userform immer noch auf. Hab jetzt noch ein wenig genauer hingeschaut was den ablauf und die Fehler betrifft; sieht wie folgt aus: 1. und 2. Aufruf: Run-time error Method 'GetInteger' of Object 'IAcadUtility' failed beim 3ten Aufruf: startet das "Bedit" welches, ich glaube mal, nicht einmal abgefangen wird, sondern an das "ThisDrawing.Utility.GetEntity" weitergegeben wird, welches mir dann sagt: *Invalid Selection*, jedoch den Aufruf nicht abbricht sondern vielmehr neustartet, was eh voll OK ist. Vermutung: Selbiger fehler wie bei Aufruf 1. und 2. wird auch produziert wenn ich bei dem Aufruf "ThisDrawing.Utility.GetEntity" nichts auswähle bzw. auf eine schwarze/leere Fläche im *Model* klicke. Die Vermutung ist die, dass der DoubleKlick(Begin-reaktor), denn ich ja abfange um die Userform zu starten, beim Verlassen der UserForm, diese beiden Klicks "wieder" tätigt. Kann das Sein? Und wenn ja, wie verdämmt nochmal mach ich die Klicks tot? Lg Reltro Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
| Anzeige.:
Anzeige: (Infos zum Werbeplatz >>)
 |