Komplizierte Vergleiche/Datenabgleiche <- Zum Knobeln für Könner/Profies



  • Hallo C++ Community,

    Ich schreibe zurzeit einen Exporter für ein bestimmtes Programm (Cinema 4D). Mit C++ bin ich noch ganz so fit, habe aber schon ein paar Plug-Ins in C++ dafür geschrieben. Das ganze ist keine große Hürde, jedoch hänge ich an einem Problem (gute Optimierung), an den ich schon mindestens 48 Zeitstunden hänge! Kurze Rede, schwieriger Sinn:

    Ich habe ein "Array" cpol welches Zugehörigkeiten regelt. Es besteht aus Polygonindexe(0..n) mit drei dazugehörigen Punkteindexe (0..n). Es sind nie die gleichen Punkte innerhalb eines Polygons, jedoch können die Punkte in anderen Polygonen vorkommen.

    //Zugriff: k ist der Index, a,b,c sind programmintern festgelegt 
    cpol[k].a  // Punkt 1 des Polygons
    cpol[k].b  // Punkt 2 des Polygons
    cpol[k].c  // Punkt 3 des Polygons
    

    Weiterhin habe ich ein "Array" uvw, welches aus einem Polygonindex(0..n) mit den dazugehörigen drei Vektoren (x,y,z) der Punkte von cpol besteht. Innerhalb eines Polygons gibt es keine gleichen Vektoren, aber in anderen Polygonen kann es gleiche geben.
    Die Vektoren sind Eigenschaftene(UVW Position) der Punkte, keine Ortskoordinaten.

    //Zugriff: k ist der Index, Get(k),a,b,c sind programmintern festgelegt 
    uvw->Get(k).a  // Vektor 1
    uvw->Get(k).b  // Vektor 2
    uvw->Get(k).c  // Vektor 3
    

    Die Polygonindexe von cpol und uvw sind verknüpft. Das heißt: Die Vektoren von uvw sind auf die Punkte abgestimmt.

    Beispiel:
    Vektor uvw->Get(4).a bezieht sich auf den Punkt cpol[4].a .
    Vektor uvw->Get(4).b bezieht sich auf den Punkt cpol[4].b .
    Vektor uvw->Get(4).c bezieht sich auf den Punkt cpol[4].c .

    Die Größen der "Arrays" sind immer bekannt.

    Was ist jetzt das Problem:
    Ein und der selbe Punkt kann verschiedene und/oder gleiche Vektoren besitzen.

    Gibt es einen Vektor des Punktes, der unterschiedlich zu einen anderen Vektor des Punktes ist, so soll ein neuer Punkt erstellt werden und dem cpol im richtigen Polygonindex zugeordnet werden.

    Was ich suche:
    Einen "for, do, while, if" Algorithmus, der mir ausgibt, zeigt etc.

    Welcher Punkt hat nur gleiche Vektoren?

    > Punktindex und Polygonindexe des Punktes, indem er sich befindet (können ja mehrere sein)

    Welcher Punkt hat unterschiedliche Vektoren?

    > Wie oft unterschiedlich (Anzahl der neuen Punkte)
    > Der Polygonindex der Punktegruppe (die den gleichen Vektor haben)

    Beispiel:
    Ein Datenblatt zur besseren Erkenntnis:
    http://www.imagebanana.com/view/wry2nk82/14.01.png

    Jemand eine klitze kleine Idee oder wenigstens ein Hinweis?

    Sollte jemand etwas nicht verstanden haben was ich meine, bitte sagen. Danke schon mal beim Kopfzerbrechen. Wäre für wirklich jede Hilfe dankbar auch für: "Das ist nicht wirklich realisierbar" oder "Das wird dir keiner machen, es ist zu komplex" oder "Du hast doch einen an der Waffel". Weiß ja nicht ob ich das nur als Laie schwierig finde.
    Würde mich auch gerne mit jemand anderweitig auseinandersetzen (ICQ, Mail, Skype etc. [Sachsen (bin flexibel mit der Bahn) 🙄]) für die Lösungsfindung.

    Cheers Toni

    P.S. Ich habe über zwei Stunden für diesen Beitrag gebraucht, jetzt enttäuscht mich nicht. 😃



  • Etwas mehr Code wäre schön. Dein Gerede kann ich irgendwie nur schwer verstehen (Das Bild kann ich leider nicht sehen, die Seite ist hier in der Firma geblockt).
    Was ich verstanden habe: Es gibt Polygone. Jedes Polygon besteht aus 3 unterschiedlichen Punkten. Einige Polygone teilen sich Punkte (Sie hängen aneinander).
    Was ich nicht verstehe ist, was bei dir der Unterschied zwischen Vektoren und Punkten ist. Ich sehe keinen Unetrschied zwischen cpol und uvw. Und erst recht verstehe ich deine Fragen nicht "Welcher Punkt hat nur gleiche Vektoren?"
    Was hat ein Punkt ausser seinem Ortsvektor noch für Vektoren?

    Gib mal die Definitionen deiner Typen, die du bisher hast, um mal über etwas reden zu können. Etwa so was:

    class Vektor{/*..*/};
    class Polygon
    {
      Array<Vektor, 3> punkte_;
    };
    


  • Hallo brotbernd,

    Danke für deine Antwort. Ich lade das Bild noch einmal wo anders hoch, eventuell siehst du es dort.
    http://img818.imageshack.us/i/1401.png/
    http://tinypic.com/r/av1la8/7

    Unterschied zwischen Vektoren und Punkte, damit meinst du den Unterschied zwischen uvw und cpol, sind:

    uvw gibt mit damit uvw->Get(k).a //(b,c) Vektoren(x,y,z) aus. cpol gibt damit cpol[k].a //(b,c) den Punkteindex aus, das heißt eine Zahl zwischen 0..n.
    Diese Zahlen kann ich dann in einer anderen internen Klasse (Vektorarray) als Indexe (Punktindexe) wieder verwenden.

    Genauer Erklärung wieso ein Punkt verschiedene uvw Eigenschaften hat:
    Die Vektoren sind keine Ortskoordinaten innerhalb des 3D Raumes.
    Damit man eine 2D-Textur auf eine dreidimensionales Objekt bekommt, muss die Struktur des Objektes verflacht werden auf 2D (heißt UVW). Dabei entstehen mehrere gleiche Punkte mit unterschiedlichen UVW. Somit ist der Vektor von uvw die Position innerhalb der Textur. (Textur = Bild, dass auf die Oberfläche vom Objekt projiziert mit).

    Bild zum besseren Verständnis (2 Hoster):
    http://img199.imageshack.us/i/1301d.png/
    http://tinypic.com/r/34h6vis/7

    Code:
    Da es auf einer eigenen API gebunden ist, sieht es anders etwas anders aus.

    // Werden aus einer Datei ausgelesen:
    const CPolygon* cpol = object->GetPolygonR(); // Das cpol Array
    UVWTag* uvw = (UVWTag*)object->GetTag(Tuvw,0); // Das uvw Array
    
    // Eigene Arrays, Variabeln
    Vector* uvwspeicher=bNew Vector[object->GetPointCount()]; //Ein Vektor Array, der so groß ist wie es Punkte gibt
    LONG t;
    
    for(t=0;t<object->GetPolygonCount();t++)  // Anzahl der Polygone
    {
        uvwspeicher[cpol[t].a]=uvw->GetSlow(t).a; //Speichert im Index (Punkteindex) den Vektor
        uvwspeicher[cpol[t].b]=uvw->GetSlow(t).b;
        uvwspeicher[cpol[t].c]=uvw->GetSlow(t).c;
    }
    

    Problem des uvwspeicher: Da es ja Punkte gibt, die verschiedene UVW-Koordinaten(Vektoren) haben, werden diese einfach überschrieben. Ich muss also die Punkte finden, die mehrere Vektoren haben und damit das obere Problem (Überschreibung der Punkte) verhindern.

    Jetzt etwas besser oder muss ich noch mehr ins Detail gehen? Ich hoffe du kannst jetzt die Bilder sehen, wenn nicht, sag mir bitte welche Seite ich verwenden könnte. 😉



  • Ein bischen mehr habe ich schon verstanden. Einem Ortsvektor werden mehrere sog. UVW Vektoren zugeordnet.

    Mit deinem Code kann ich aber überhaupt nichts anfangen. Das ist irgendeine Stelle in der Implementierung. Was ich brauch sind Typdefinitionen. Was sind bei dir Punkte, Vektoren, Polygone.. wie sieht das aus. Was gibt die Get Methode zurück, was nimmt sie als Argument.
    Was ich bisher verstanden habe sieht etwa so aus:

    /// Ein Punkt hat 3 Koordinaten
    class Punkt
    {
        int a, b, c;
    };
    
    /// Es gibt viele Punkte
    class Punkte  // (cpol?)
    {
        Punkt& ByID(PunktID id);
    };
    
    /// Ein Polygon besteht aus 3 Punkten
    class Polygon
    {
        std::array<PunktID, 3> punkte;
    };
    
    /// Ein UVWVektor hat 3 Koordinaten und ist Puntken zugeordnet
    class UVWVektor
    {
        int a, b, c;
        std::vector<PunktID> punkte;
    };
    
    class UVW
    {
        std::vector<UVWVektor> vektoren;
    };
    
    // -------- Oder ----------
    class UVWVektor
    {
        int a, b, c;
    };
    
    class Punkt
    {
        int a, b, c;
        std::vector<UVWVektor*> vektoren;    
    };
    


  • Das kann man nicht so schreiben, ist eben alles auf eine API/SDK ausgelegt.

    Vielleicht kannst du damit mehr anfangen:

    class PolygonObject: public PointObject
    {
    public:
      const CPolygon* GetPolygonR(void);  // Aufbau des Objektes mit den einzelnen Polygonen (cpol)
      LONG GetPolygonCount(void); // Anzahl der Polygone eines Objektes
    };
    
    class uvw: public PointObject //uvw Array
    {
    public:
      UVWStruct Get(LONG i); //Die UVW-Koordinaten für ein Polygon bekommen (3 Vektoren)
    };
    


  • Du sagtest es sei eine eigene API. Und auch von einer fremden API hat man ja zumindest die Schnittstelle. Der Code ist ja schonmal ein Anfang. Jetzt wäre noch interessant: Was ist PointObject, was ist CPolygon, was ist UVWStruct, was ist LONG(ok das kann ich mir denken), bzw. wie sehen diese Klassen oder Typen aus.



  • Du stellst ganz schön schwierige Fragen aber mal sehen ob ich dir da antworten kann:

    struct CPolygon
    {
    	CPolygon(void) {}
    	CPolygon(LONG t_a, LONG t_b, LONG t_c) { a=t_a; b=t_b; c=d=t_c; }
    	CPolygon(LONG t_a, LONG t_b, LONG t_c, LONG t_d) { a=t_a; b=t_b; c=t_c; d=t_d; }
    
    	LONG a,b,c,d; // d fällt bei mir heraus, da meine Polygone nur 3 Punkte haben
    };
    
    struct UVWStruct
    {
    public:
      UVWStruct(_DONTCONSTRUCT dc);
      UVWStruct(void);
      UVWStruct(const Vector& t_a, const Vector& t_b, const Vector& t_c, const Vector& t_d);
      UVWStruct(const Vector& t_a, const Vector& t_b, const Vector& t_c);
      Vector a;
      Vector b;
      Vector c;
      Vector d;  // d fällt bei mir heraus, da meine Polygone nur 3 Punkte haben
    };
    

    Ein PolygonObject ist ein Subtyp von einem PointObject, dies ist ein Untertyp von BaseObject, wiederrum von BaseList2D... Diese spielen hier auch keine wirkliche Rolle, da nur diese zwei Strukturen CPolygon und UVWStructure meines Erachtens den Weg zur Lösung weisen.



  • Und die Klasse uvw verwaltet die Verknüpfung von Punkt zu UVWStruct? Oder Polygon->UVWStruct?
    Ah ich glaub jetzt geht mir ein Licht auf
    uvw: Polygon->UVWStruct
    Der Vektor UVWSturct::a gehört zum Punkt CPolygon::a usw.

    UVWStruct Get(LONG i);  // das i ist eine Polygon id?
    

    Ist die Klasse uvw von dir selbst geschrieben? Hast du also die Implementierung?



  • Nein, die Klasse ist nicht von mir selber geschrieben. Ebenfalls API.

    Im Grunde habe ich ein Objekt welchem ich die einzelnen Werte (uvw, cpol) entziehe.

    Ich denke ich habe eine Lösung gefunden, sehr simpel aber sie scheint zu funktionieren und das erst nach so vielen Stunden. 😞 Was ich alles funktioniert habe....

    LONG t;
    BaseObject* object = doc->GetActiveObject();
    UVWTag* uvw_tag=(UVWTag*)object->GetTag(Tuvw,0);
    PolygonObject* polyobj =  ToPoly((BaseObject*)(object));
    CPolygon* pa=polyobj->GetPolygonW();
    LONG point_count = pointobj->GetPointCount();
    Vector* pvc=bNew Vector[point_count*3];
    
    for(t=0;t<point_count;t++) pvc[t]=-1;
    
    for(t=0;t<poly_count;t++)							
    {
        if(uvw_tag->GetSlow(t).a!=pvc[pa[t].a] && pvc[pa[t].a]!=-1)
        {
             //Erstelle an der Stelle pa[t].a einen neuen Punkt
        }
        if(uvw_tag->GetSlow(t).a!=pvc[pa[t].b] && pvc[pa[t].b]!=-1)
        {
             //Erstelle an der Stelle pa[t].b einen neuen Punkt
        }
        if(uvw_tag->GetSlow(t).a!=pvc[pa[t].c] && pvc[pa[t].c]!=-1)
        {
             //Erstelle an der Stelle pa[t].a einen neuen Punkt
        }
        pvc[pa[t].a]=uvw_tag->GetSlow(t).a;
        pvc[pa[t].b]=uvw_tag->GetSlow(t).b;
        pvc[pa[t].c]=uvw_tag->GetSlow(t).c;
    }
    

    Es hat mir sicherlich geholfen hier dies alles aufzuschreiben, damit habe ich meinen eigenen Code besser verstanden. 😉

    Dankeschön und ein schönes Wochenende. 😉


Anmelden zum Antworten