GDI+ GraphicsPath addPath funktioniert nicht - ohne Fehlermeldung!

  • VB.NET

Es gibt 18 Antworten in diesem Thema. Der letzte Beitrag () ist von GuentherA.

    GDI+ GraphicsPath addPath funktioniert nicht - ohne Fehlermeldung!

    Hallo Zusammen,

    ich habe hier ein eher dubioses Problem mit dem GraphicsPath der GDI+ in meiner Anwendung.

    Meine Anwendung wertet sogenannten G-Code aus (Programme von CNC Maschinen) und stellt das ergebnis anschließend grafisch dar. Das funktioniert mittlerweile seit gut 2 Jahren auch im produktiven Umfeld recht gut. Jetzt kam aber plötzlich ein neues CNC-Programm, welches folgendes Verhalten zeigt:

    Beim Durchlaufen des G-Codes erzeuge ich die jeweiligen grafischen Elemente. Also zb. eine Linie bis zu einem Endpunkt, einen Kreisbogen oder einen Vollkreis. Dies wird jeweils als Figur einem (temporären) Graphicspath hinzugefügt. Ist das Bauteil nun fertig geschnitten (das wird im CNC Code durch einen Befehl angezeigt) wird der temporäre Pfad in die Pfadeigenschaft einer Bauteilklasse übertragen. Diese Übertragung erfolgt durch ein graphicspath.addpath(tempPafad,False). Das dubiose ist jetzt, das genau nur bei diesem einem Programm, der temppfad zwar gefüllt ist, also ich sehe eine PointCount von 141, die zugehörigen Punkte und Typen in den Eigenschaften. Nach der Zeile

    Quellcode

    1. finishedPart.AllgPath.AddPath(PfadGeometrie, False)


    ist allerdings AllgPath nach wie vor leer (PointCount=0).

    Bei allen anderen Programmen läuft dies einwandfrei und der in "Pfadgeometrie" enthaltene Pfad wird dem AllgPath hinzugefügt. Nur eben bei diesem Programm nicht. Es gibt dazu auch leider keine Fehlermeldung oder ähnliches. Unterschiede im CNC Programm finde ich eigentlich auch nicht, außer dass es natürlich unterschiedliche Bauteile und dem nach auch andere Koordinaten beinhaltet.

    Weiß jemand vielleicht ob die Methode AddPath irgendwelche Grenzen hat? In der MSDN hätte ich dazu nix gefunden!

    Bitte um eure Unterstützung,

    Danke und LG

    Günther
    @GuentherA Teste mal, dass Du nach jedem Hinzufügen eines Objekts die Anzahl der Objekte in der Console ausgibst.
    Hänge dazu eine Console an, da kannst Du alles mögliche loggen: C#, VB.NET: Console anhängen und Debugger-Option "Visual Studio-Hostingprozess aktivieren"
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hallo und Danke für Eure beiden Rückmeldungen!

    @ErfinderDesRades:
    finishedPart ist ein Objekt der Klasse, welches mir ein volles Bauteil beschreibt. Die Klasse hat einen Haufen Eigenschaften, unter anderem eben die Eigenschaft AllgPath (as GraphicsPath). Die Anwendung läuft grundsätzlich schon in mehrereren Threads, nicht aber die Auswertung von einem CNC-Programm. Die läuft in nur einem einzigen Thread. Also an ein Threading problem glaube ich in dem Fall nicht.

    @RodFromGermany:
    Das habe ich prinzipiell schon gemacht. Zwar nicht so elegant wie von dir vorgeschlagen mit einer eigenen Konsole, sondern nur mit einem ordinärem Debug.print, aber ergebnis war leider auch nicht erhellend. Bei allen Programmen wächst die Anzahl der Pfadelemente dem CNC-Code entsprechend an, bei "Part_End" wird der temporäre Pfad in der Eigenschaft AllgPath mittels der AddPath Methode hinzugfügt und anschließend weiter verarbeitet. Bei diesem einem nun nicht funktionierenden CNC-Programm, ist das eben nicht der Fall. Solange der temporäre Pfad befüllt wird passt alles. Also es werden auch die richtigen Pfadelemente dem CNC-Code entsprechend hinzugefügt. Wird nun das "Part_End" erreicht, so soll ja der temporäre Pfad dem gesamten (AllgPath) hinzugefügt werden. Und das passiert einfach nicht. Der temporäre Pfad ist ordentlich gefüllt. Auch die richtigen Daten sind drin, denn erstelle ich ein Bitmap aus dem Temporären Pfad, so schaut das schon nicht so verkehrt aus. Jetzt fragt sich nur, was könnte da wohl böses drin stehen, dass er das nicht in einen neuen Pfad hinzufügen will?!

    Werde aber deine Variante mit der Konsole auch noch ausprobieren, mal sehen ob die mehr ausspuckt...

    EDIT:
    @RodFromGermany:
    Hätte jetzt gerade mit dem Konsolendebugg begonnen. Aber was sollte denn das bringen? In meine Anwendung integerieren lasst sich das jetzt nicht so einfach, außerdem hab ich ohnehin ein log-File in meiner Anwendung und die Debugging Konsole vom VS und mehr als dorthin kann ich ja in die Konsole auch nicht schreiben oder? Übersehe ich was? :)

    Danke und LG
    Günther

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „GuentherA“ ()

    GuentherA schrieb:

    Übersehe ich was?
    Nein.
    Wenn Du das anders machst, ist es auch in Ordnung.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hallo,

    habe jetzt mal weiter getestet. Habe versucht, was ich mit dem GraphicsPath (dem temporäreren) sonst noch so alles anstellen kann. Ich habe jetzt versucht, einen Graphicsitereator zu erstellen:

    Quellcode

    1. finishedPart.AllgPath.AddPath(PfadGeometrie, False)
    2. Dim pa As New GraphicsPath
    3. pa.AddPath(PfadGeometrie, False)
    4. PfadGeometrie.CloseFigure()
    5. Dim x As New GraphicsPathIterator(PfadGeometrie)
    6. x.Rewind()


    In fast allen Fällen funktioniert der obige Code wie erwartet. x zeigt dann ebenfalls die Punkteanzahl der Pfadgeometrie an, auch die Anzahl der Figuren in diesem Pfad wird richtig angezeigt.
    Versuche ich nun das eine Programm zu öffnen das nicht funktioniert, so wird mir folgender Fehler entgegen geschmissen: "Nicht genügend Arbeitsspeicher"

    Das zeigt jetzt zumindest mal deutlich, dass ihm an dem Pfad irgendetwas nicht passt, nur wie komm ich da jetzt drauf WAS ihm nicht passt? Hätte da vielleicht irgendjemand eine Idee? ?(

    Danke und LG
    Günther
    @GuentherA Probierma, die Daten nicht dem GraphicsPath zuzufügen, sondern zu dumpen.
    Die kommen ja iwie von Deiner CNC zurück, als Byte-Array oder als String.
    Lass Dir das mal auf die Platte schreiben: .WriteAllBytes(...) oder .WriteAllText(...).
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    nein, ich bekomme die Daten nicht von einer CNC Maschine, sondern lese die Punkte und Geometrien aus dem CNC Programm aus. EIn CNC Programm schaut in etwa so aus:

    Quellcode

    1. START_TEXT
    2. N10 MSG("UNTERPROGRAMMNUMMER,SP1S156")
    3. N20G91
    4. N30;(TEILENUMMER:1)
    5. N40TC_POS_LEVEL(40.0)
    6. N50;(KONTURNUMMER:1)
    7. N60TC_LASER_ON(9,"T2D-6104",10,100);SprintLine
    8. N70TC_LASERCORR_ON(T_LEFT)
    9. N80X0.676Y5.080
    10. N90G03X-0.342Y0.424I-0.372J0.049
    11. N100G03I-0.589J-7.427
    12. N110TC_LASER_OFF(3);SprintLine_ENDE
    13. N120;(KONTURNUMMER:2)
    14. N130G01X-13.567Y1.244
    15. usw.


    Die darin angegebenen Punkte werden im Prinzip verfolgt und aufsummiert, und wenn zu diesem Zeitpunkt der Laser auf ON steht, dann wird auch gezeichnet, sprich zu dem Pfad hinzugefügt.

    Ich vergleiche jetzt schon die ganze zeit die Daten des Pfades bei einem Funktionierenden CNC Programm und bei dem das nicht funktioniert. ich finde keinen Unterschied. weder in der Menge der Punkte, noch in den Typen noch sonst was. ALso ich hab echt keine Ahnung wieso er sich gegen dieses einen File wehrt! :(
    @GuentherA Missverständnis.
    Gib das, was auch immer es ist, was Du auf welchem Wege auch immer von der CNC bekommst, nicht in einen GraphicsPath, sondern als Datei auf die Festplatte aus.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    So, also den Fehler konnte ich beseitigen. So ganz klar ist mir das Warum jetzt noch nicht, das muss aber doch irgendwie in der Geometrie des Bauteils liegen.

    Ich habe im Code eine Abfrage, in der geprüft wird, ob sich bereits Punkte im Pfad befinden. Befinden sich noch keine Punkte darin, so wird ein neues Liniensegment mit Anfang- und Endpunkt hinzugefügt (AddLine). SInd bereits Punkte vorhanden, so füge ich ein neues Liniensegment mit AddLines hinzu. Dazu muss ich nur ein Array mit Endpunkten übergeben. In meinem Fall ist in dem Array aber immer nur ein einziger Punkt drin, da ich ja zu jedem Zeitpunkt nur max ein Liniensegment hinzufüge. Und das dürfte ihm dann irgendwie/irgendwo nicht schmecken. Denn ändere ich meinen Code, das ich immer die Linien mit AddLine(Anfangs- , Endpunkt) hinzufüge, dann funktionierts einwandfrei....

    Danke in jedem Fall für Eure Unterstützung!!! :)

    LG Günther
    Die Entscheidung auf AddLine umzustellen war richtig. Der Fehler "nicht genügend Arbeitsspeicher" kommt auch dann wenn ein Element ( Arc, Elypse ) zu klein ist.

    Ich würde an deiner Stelle jedes Element als GraphicPath abspeichern und das ganze dann in eine List of GraphicPath. Dann kannst du mit dem Zeug machen was du willst. Klicken, Markieren, Löschen, etc.
    das kommt drauf an.
    GraphicsPath ist dafür gedacht, beliebige und beliebig viele Figur-Elemente aufzunehmen. Da jetzt für jedes Figur-Element einen eigenen GraphicsPath zu erstellen und verwalten wäre das Rad neu erfunden, und Wasserkopf.
    Ein GraphicsPath ist für eine vollständige Figur.
    Natürlich hat man mehrere davon, wenn man mehrere Figuren zu managen hat. Etwa Figuren von verschiedener Farbe oder sowas.
    In seinem Fall würde ein GP pro Figur ausreichen. Es stellt es nur optisch dar. Wenn er jetzt aber mit den einzelnen Elementen mehr anfangen will, Z.B. einzelne Anklicken und eine andere Farbe geben dann braucht er die List of GP.

    NOCH konkreter: Er laden eine DXF Datei rein und will jetzt einen bestimmten Teil verwenden um ein Laser-Cut Programm zu erzeugen. Wenn das alles in einem GP ist kannst garnichts mit dem anfangen
    Hallo und Danke für die Antworten.

    Leider bin ich noch nicht dazu gekommen, die Änderung in die produktive Anlage einzuspielen. Bei meinen Tests hats aber geklappt.

    @DragsTrail:
    Der Ablauf ist in Wahrheit umgekehrt. Der Laser schneidet irgendwas und ich muss erkennen was genau er geschnitten hat, UND wie ich das geschnittene Teil mit einem Roboter aufnehmen kann. Das heißt ein GraphicsPath reicht mir. Im Weiteren wird daraus dann noch eine Region erzeugt, die im Prinzip mein Werkstück wieder gibt.

    Das mit den zu kleinen Elementen im Pfad kann natürlich sein. Da wäre eine Auswertung fast interessant. Denn jetzt ist das Programm doch ein gutes Jahr (3-schichtig) gelaufen. Und jetzt gibts mit einem Teil solche Probleme?! Sobald ich mal Zeit habe werde ich mir das nochmal anschauen, fürs erste ist das Thema auf alle Fälle erledigt!

    Danke Euch allen,

    LG Günther
    @GuentherA Ohne Dir zu nahe treten zu wollen:
    Die lassen Dich mit diesen Vorkenntnissen an eine solch untriviale Maschine?
    Was ich bisher erlebt habe, da wurden entsprechende Vorkenntnisse abgefragt.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    GuentherA schrieb:

    Der Ablauf ist in Wahrheit umgekehrt. ...
    ließ mich dies vermuten.
    Sorry.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @GuentherA

    Also du nimmst den NC-Code um zu visualisieren???? Warum nicht die DXF oder STEP Datei? Oder die Native-Datei deines Programmiersystems? =O Mit was Programmiert ihr?

    ​Ich hab das Problem gelöst indem ich alle Elemente in Abhängigkeit von Zoom des Fensters, die gleich oder kleiner 2Pixels sind aus dem GraphicPath Liste entfernt habe. Beim Ran-Zoomen wieder dazu getan habe.

    ​Dann ist das Problem "Nicht genügend Arbeitsspeicher" nie wieder aufgetaucht.
    @DragsTrail

    Naja ich nehme NC Code untere anderem AUCH zum visualisieren. Aber das nicht vorrangig und das auch nur aus Mangel an Alternativen.

    Es gibt da eine Maschine, die erzeugt irgendwelche Teile aufgrund eines geladenen Programms (NC Code in Form einer Datei im Netzwerk). Die Maschine spuckt aber keinerlei Infos zu den Teilen aus. Auch der Hersteller der Maschine zeigt sich nicht bereit, dafür eine Schnittstelle zu implementieren - auch nicht gegen Einwurf kleiner Münzen. Nun soll aber meine daran angekoppelte Anlage mit einem Roboter die erzeugten Teile entladen und auf Paletten ablegen.

    Um jetzt trotzdem irgendwie an Infos zu den erzeugten Bauteilen zu kommen, habe ich nur die Möglichkeit, das Programm auszuwerten, nach welchem das Maschinchen die Teile erzeugt. Und die so erzeugte Geometrie kann ich dann auswerten und dafür ein Roboterprogramm zur Entnahme erzeugen. Die erzeugten Daten verwende ich dann der Vollständigkeit halber auch noch zum Visualisieren. Aber eben nicht in erster Linie.

    Also kein DXF oder STEP deshalb, weil ichs einfach nicht hab (leider :) ).

    LG Günther