Eigenes "CAD" programmieren mit VB.NET

  • VB.NET

Es gibt 26 Antworten in diesem Thema. Der letzte Beitrag () ist von SystemUnknow.

    Eigenes "CAD" programmieren mit VB.NET

    Kennt jemand ChemCAD? Wahrscheinlich nicht. Das ist eine Simulationssoftware für den Anlagenbau. Man kann damit z.B. thermodynamische und strömungstechnische Prozesse nachbilden. Im Anhang ein Screenshot.




    Ich plane etwas nicht ganz so umfangreiches, aber dennoch ähnliches. Eine Software zur Berechnung von Druckverlusten in Rohrleitungen. Das ganze habe ich für ein Rohrstück schon in Excel realisiert, die physikalischen Berechnungen die dahinter stecken sind mir also klar. Ich würde jetzt aber gerne, ähnlich wie in ChemCAD, eine Benutzeroberfläche programmieren. Der Anwender kann hingehen sich verschiedene Rohrteile aus einer Palette nehmen und per Drag & Drop auf einer Fläche platzieren und anordnen. Jedes Rohrteil, ob gerades Stück oder Krümmer, soll bestimmte Eigenschaften erhalten, die der Anwender beim Platzieren eingeben muss z.B. Länge, Durchmesser, Radius, Winkel. Dabei kann das Rohr das er platziert, ein starres Bitmap sein, das muss sich nicht verändern mit den eingegebenen Daten, wär natürlich schön, aber muss nicht. Es soll nur die Eigenschaften für die Berechnung speichern. Schlussendlich soll dann ein Algorithmus alle Teile zusammenzählen und die Berechnungen anstellen. Natürlich berechnet sich ein gerades Rohrstück mit einer anderen Funktion wie ein Krümmer, das muss erkannt werden. Jedes Stück wird separat Berechnet und zum Schluss wird der Druckverlust aufsummiert.

    Achso und ganz wichtig! Es sollte eine Speicherfunktion für die Anordnung geben.

    Ich hab mal so als "Vorarbeit" ein sinnloses Programm gemacht, wo man auf die Form klickt und dann farbige Quadrate erstellt werden, diese kann man mit einem Rechtsklick auch anklicken und bearbeiten. Sie sehen sich allerdings nicht und können sich überlappen. Aber ein gesetztes Quadrat kan man jederzeit anklicken und woanders hinschieben das ist schonmal gut. Vielleicht sollt ich mir auch mal das TETRIS Tutorial von GalileoComputing ansehn, da lernt man bestimmt auch noch die ein oder andere brauchbare Sache dazu.
    Ist dieses Vorgehen so wie es Programmiert ist im Prinzip richtig? Wie würdet ihr vorgehen um sowas zu realisieren?

    Tipps und Tricks, Anregungen und Tutorials gesucht :)
    Dateien
    • MoveObjects.zip

      (487,45 kB, 309 mal heruntergeladen, zuletzt: )
    "Es ist absolut möglich, dass jenseits der Wahrnehmung unserer Sinne ungeahnte Welten verborgen sind." — Albert Einstein
    "Wenn die Macht der Liebe die Liebe zur Macht übersteigt, erst dann wird die Welt endlich wissen, was Frieden heißt." — Jimi Hendrix

    Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von „FredM“ ()

    immer mittm Datenmodell anfangen.

    überlegen, was brauchst du für Objekte, und welche eigenschaften sind signifikant.

    für die Berechnung ist wohl der Durchflußwiderstand wichtig.

    für die Darstellung ist Länge und Orientierung wichtig.
    Gibts auch Verzweigungen? - das wäre dann ein annerer Rohrtyp.
    wichtig auch, an welchem anneren Rohr ein Rohr angeschlossen ist, und an welchem Ende.

    willst du mehrere Schaltpläne speichern können? - dann brauchst du übergeordnete Schaltplan-Objekte, wo du mehrere Rohr-Objekte reintun kannst.

    etc.

    sowas kannman ganz gut im typisierten Dataset konzipieren, und indems konzipiert ist, ist die Datenseite ja bereits fast ausprogrammiert.

    gugge DB-Programmierung ohne Datenbank
    Okay, ich hab mir mal das Video dazu angesehn.

    Das klingt gut, die "Datenbank" wird dann also praktisch in eine XML Datei gespeichert, hab ich das richtig verstanden? Und die kann man dann mit dem Save/Reload Laden und Speichern.
    Aber wie legt man Objekte in einer Datenbank ab?

    "Es ist absolut möglich, dass jenseits der Wahrnehmung unserer Sinne ungeahnte Welten verborgen sind." — Albert Einstein
    "Wenn die Macht der Liebe die Liebe zur Macht übersteigt, erst dann wird die Welt endlich wissen, was Frieden heißt." — Jimi Hendrix

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

    aber typisiertes dataset <> serialisiertes objekt
    ich glaube das ist nicht im sinne des erfinders^^ die serialisierten objekte sind ja nichts anderes als selbsterstellte klassen - der erfinder würde das mit einem datenmodell realisieren was denke ich auch besser ist. bin aber selbst auf dem gebiet am erst am lernen..
    @TE: beachte: hier im Forum bekommt man fast immer verschiedene Strategien geraten - wie FreakJns sagt: die Xml-Strategie unterscheidet sich vonne Dataset-Strategie.
    Xml ist definitiv ungeeignet, denn damit kann man prinzipiell nur Bäume persistieren - du brauchst aber ein relationales Datenmodell.

    FredM schrieb:

    die "Datenbank" wird dann also praktisch in eine XML Datei gespeichert, hab ich das richtig verstanden? Und die kann man dann mit dem Save/Reload Laden und Speichern.

    richtig.

    Entweder gleich ins Datagridview eingeben, oder per Code: DataTable.AddRow()
    Beim typisierten Dataset werden aber spezielle DataTables generiert, mit speziellen, verbesserten AddRow-Methoden - die heißen dann im Einzelfall halt jeweils anders.

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

    Mir geflällt das mit dem typisierten Dataset auch ganz gut, zumal ich schon mit Dataset für eine SQL Datenbank gearbeitet hab.

    Ich versteh aber noch nicht wie ich ein Objekt in ein typisiertes Dataset einfüge, serialisieren oder wie auch immer man das nennt.
    "Es ist absolut möglich, dass jenseits der Wahrnehmung unserer Sinne ungeahnte Welten verborgen sind." — Albert Einstein
    "Wenn die Macht der Liebe die Liebe zur Macht übersteigt, erst dann wird die Welt endlich wissen, was Frieden heißt." — Jimi Hendrix

    kein Problem - ich sags dir nochmal (s. post#6):

    Entweder gleich ins Datagridview eingeben, oder per Code: DataTable.AddRow()
    Beim typisierten Dataset werden aber spezielle DataTables generiert, mit speziellen, verbesserten AddRow-Methoden - die heißen dann im Einzelfall halt jeweils anders.

    mit serialisieren hats nix zu tun - das ist die annere Strategie, die keine Relationalität unterstützt.
    Achso und bei Datatype stell ich dann einfach auf Object?
    Bilder
    • so.png

      21,11 kB, 577×420, 450 mal angesehen
    "Es ist absolut möglich, dass jenseits der Wahrnehmung unserer Sinne ungeahnte Welten verborgen sind." — Albert Einstein
    "Wenn die Macht der Liebe die Liebe zur Macht übersteigt, erst dann wird die Welt endlich wissen, was Frieden heißt." — Jimi Hendrix

    nein - blos nicht!

    Der ganze Datensatz ist dein Objekt!

    Du solltest ddie DataTable "Rohrstueck" nennen, und spalten dranmachen wie
    ID - int32, PrimKey
    Laenge - int32
    Name - String
    Orientierung - int32
    PosX - int32
    PosY - int32
    PosWidth - int32
    PosHeight - int32

    So in der Art.
    Achso, ja klar, so hät ichs eigentlich auch gedacht, aber mich hat das gerede mit den Objekten verwirrt.

    Dein Programm "Most Primitive" zeigt ja genau wies geht :D super, jetzt ist mir das schonmal klar, ich meld mich dann beim nächsten Problem ^^
    "Es ist absolut möglich, dass jenseits der Wahrnehmung unserer Sinne ungeahnte Welten verborgen sind." — Albert Einstein
    "Wenn die Macht der Liebe die Liebe zur Macht übersteigt, erst dann wird die Welt endlich wissen, was Frieden heißt." — Jimi Hendrix

    Ich hab das jetzt mal für mich versucht zu adaptieren... aber irgendwie funktioniert es nicht, er bringt mir ein error beim schließen der form
    "Eine Ausnahme (erste Chance) des Typs "System.InvalidCastException" ist in MostPrimitive.exe aufgetreten."

    VB.NET-Quellcode

    1. Imports System.IO
    2. Public Class frmMDI
    3. Private _DataFile As New FileInfo("..\..\Data.xml")
    4. Private Sub frmParentChild_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
    5. If Not _DataFile.Exists Then Return
    6. Me.DataDts.ReadXml(_DataFile.FullName)
    7. For Each inf In DataDts.ChildInfo
    8. Dim frm As New Panel
    9. With frm
    10. .Left = inf.Left
    11. .Top = inf.Top
    12. .Width = inf.Width
    13. .Height = inf.Height
    14. End With
    15. Next
    16. End Sub
    17. Private Sub btAdd_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btAdd.Click
    18. Dim newPanel As New Panel
    19. With newPanel
    20. .Left = 20
    21. .Top = 20
    22. .Width = 20
    23. .Height = 20
    24. .BackColor = Color.AliceBlue
    25. End With
    26. Controls.Add(newPanel)
    27. End Sub
    28. Private Sub Form_FormClosing(ByVal sender As Object, ByVal e As FormClosingEventArgs) Handles Me.FormClosing
    29. DataDts.ChildInfo.Clear()
    30. For Each newPanel As Panel In Me.Controls
    31. With newPanel
    32. Me.DataDts.ChildInfo.AddChildInfoRow(.Left, .Top, .Width, .Height)
    33. End With
    34. Next
    35. DataDts.WriteXml(_DataFile.FullName)
    36. End Sub
    37. End Class
    Dateien
    "Es ist absolut möglich, dass jenseits der Wahrnehmung unserer Sinne ungeahnte Welten verborgen sind." — Albert Einstein
    "Wenn die Macht der Liebe die Liebe zur Macht übersteigt, erst dann wird die Welt endlich wissen, was Frieden heißt." — Jimi Hendrix

    fehlerzeile?

    ah - ja.

    gugge diese zeile:

    VB.NET-Quellcode

    1. For Each newPanel As Panel In Me.Controls
    Nun ist aber auch ein Button in Me.Controls drinne.

    ein Button ist aber kein Panel, und kann auch nicht darin umgewandelt werden, und genau das sagt der Fehler.

    Lösung mit Linq:

    VB.NET-Quellcode

    1. For Each newPanel In Me.Controls.OfType(Of Panel)()
    Dazu sollteste aber System.Linq zu den auf Projektebene eingestellten Imports hinzufügen, denn .OfType ist eine Linq-Extension.
    Projekteigenschaften - Verweise - Importe, und ziemlich weit runter.

    Es geht auch mit einer Imports - Anweisung im Code-File, aber Linq ist so genial, das sollteman immer importieren - also projektweit.

    So, nun vergiß das mal wieder, und konzipiere mal dein Datenmodell zuende.
    An die Darstellung brauchste dich erst zu machen, wenn du bereits mittels gebundener DGVs die eigentliche Verarbeitung hingestellt hast.
    Also dass du in DGVs Rohrstueke zufügen kannst, ihre Eigenschaften einstellen, etc.
    Weil das Förmchen schieben ist ja nur optischer Gimmick ;)
    Aber so als Ausblick für die Darstellung von Datensätze in selbstgebastelten Designern gugge Outlined und ziehbare Schrift

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    gibts keine, ich kann auf schließen klicken wie ich will es schließt sich nicht und es erscheint im log unten nur dieser fehler

    //edit ok danke :)
    "Es ist absolut möglich, dass jenseits der Wahrnehmung unserer Sinne ungeahnte Welten verborgen sind." — Albert Einstein
    "Wenn die Macht der Liebe die Liebe zur Macht übersteigt, erst dann wird die Welt endlich wissen, was Frieden heißt." — Jimi Hendrix

    Hmm doch eigentlich schon

    Wenn ich z.B. sowas mache:

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    Dim Test As Double
    Test = "tasdf"
    End Sub

    Und auf den Button klick, stoppt er und markiert die zeile und zeigt den Fehler an.
    Vllt liegts an der Express version?
    Bilder
    • Button.PNG

      196,86 kB, 1.414×905, 349 mal angesehen
    • nostop.PNG

      191,64 kB, 1.437×905, 326 mal angesehen
    "Es ist absolut möglich, dass jenseits der Wahrnehmung unserer Sinne ungeahnte Welten verborgen sind." — Albert Einstein
    "Wenn die Macht der Liebe die Liebe zur Macht übersteigt, erst dann wird die Welt endlich wissen, was Frieden heißt." — Jimi Hendrix

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

    abgesehen davon, dass das natürlich mit Strict Off geproggt ist, binnich da auch ratlos.
    Beim ButtonKlick funzt die Fehlerbehandlung durch die IDE, und im FormClosing nicht - wirklich misteriös.

    Zumal meine IDE sich bei deinem Upload absolut korrekt verhält.


    hmm.

    Computer runterfahren, neu starten - das hilft immer ;)
    *g* also mal wieder zum Datenmodell... du hast ja Recht :D

    Für die Darstellung ist Länge und Orientierung wichtig.
    Gibts auch Verzweigungen? - das wäre dann ein annerer Rohrtyp.
    wichtig auch, an welchem anneren Rohr ein Rohr angeschlossen ist, und an welchem Ende.

    willst du mehrere Schaltpläne speichern können? - dann brauchst du übergeordnete Schaltplan-Objekte, wo du mehrere Rohr-Objekte reintun kannst.


    Ein Schaltplan reicht eigenltich, ich kann ja dann einfach ein FileDialog machen wo ich die XML abspeichere bzw eine andere Laden kann



    Irgendwie kann ich mir aber gerade gar nicht vorstellen wie ich so ein Rohrnetz in einem Datenmodel abbilden könnte, vor allem die Frage welches an welchem Rohr angeschlossen ist.
    Ich hab dazu mal eine beispielhafte Skizze gemacht. Im Prinzip wird an jedem Ende ein bestimmter Luftstrom angegeben z.B. 200m³ pro Stunde, an einem Konten müssen dann natürlich beide Ströme addiert werden.
    Für die Druckberechnung spielt immer nur der längste Strang eine Rolle (gestrichelt markiert). Den Druckverlust muss ich dann stückchenweiße berechnen, d.h. solang der Luftstrom gleich bleibt kann ich mehrere Rohre zusammenfassen und dafür den gesamt Druckverlust berechnen, sobald ich an eine Abzweigung komme, muss ich aber wieder neu kalkulieren, da sich ja die Luftmenge ändert.

    Ich frag mich ob ich für jedes Rohr eine neue Tabelle zur Laufzeit erstellen muss, weil nur so könnte ich sie ja dann über die Primary Keys verknüpfen oder?
    "Es ist absolut möglich, dass jenseits der Wahrnehmung unserer Sinne ungeahnte Welten verborgen sind." — Albert Einstein
    "Wenn die Macht der Liebe die Liebe zur Macht übersteigt, erst dann wird die Welt endlich wissen, was Frieden heißt." — Jimi Hendrix

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

    FredM schrieb:

    Ich frag mich ob ich für jedes Rohr eine neue Tabelle zur Laufzeit erstellen muss, weil nur so könnte ich sie ja dann über die Primary Keys verknüpfen oder?

    Tja, du mußt dich in datenbänkerisches Denken einarbeiten:
    Ich würde graphentheoretisch modellieren, also mit Kanten und Knoten:
    Eine Tabelle mit Knoten, und eine Tabelle mit Kanten. Eine Kante verweist auf 2 Knoten.
    Kante = Rohr
    Knoten = Verbindungsstück

    Durch dieses Modell können an einem Verbindungsstück 2, aber auch mehr Rohre angeflanscht werden
    Also es gibt Rohre und Knoten. Jedes rohr hat einen Input und einen Output. In-/Out-put hängen je an einem Knoten.
    Es gibt also eine Tabelle "TubeSegment", und jedes TubeSegment hat 2 oder 3, vlt auch mehr Verbindungen.
    Also brauchst du auch eine Tabelle "Nodes".
    Jede TubeSebment hat 2 ForeignKeys, mit denen es auf die 2 Nodes verweist.

    Zur Laufzeit erstellt man übrigens niemals zusätzliche Tabellen.

    brauchst sehr gute kenntnisse in GDI und Mathe !
    GDI ja, Mathe nein.