Materialien mit Coffee definieren ?

NanoBot

Mitglied
Ich möchte 200 Würfel mit verschiedenen Texturen überziehen (ja, es ist eine heruntergebrochene Teilfrage eines anderen Threads, aber ich komme nicht weiter)

Im Projektordner sind die Texturen (Textur1.png, Textur2.png ...)
Im C4D sind die Objekte auch schon da (Würfel1, Würfel2 ...)

Seit Tagen (ausserhalb der Arbeit) knabber ich am Coffee-Script rum.
(Die SDK Dokumentation bringt mehr Fragen als Sie beantwortet, suche Handbuch oder Beispiele)

Ich kriege die For-Schleife nicht hin, sie soll:

Erstelle Neues Material "Mat1" mit Farbe "Textur1.png".
Weise "Würfel1" Material "Mat1" zu.

(Inzwischen hätte ich es von Hand 10x gemacht, möchte aber Kaffee lernen, oh bin ich deprimiert... )
 
Teilerfolg, ich kann neue Materialien erstellen und mit Texturen versehen:

Code:
var mat = new(Material);
mat->SetChannelState(CHANNEL_COLOR, TRUE);
var channel = mat->GetChannel(CHANNEL_COLOR);
var container = channel->GetContainer();
container->SetData(CH_TEXTURE, "Textur1.png");
container->SetData(CH_BRIGHTNESS, 1);
channel->SetContainer(container);
mat->SetName("Mat1");
doc->InsertMaterial(mat, NULL);


doch beim Tag einfügen kommt "Incompatible values... OBJECT / OBJECT":

Code:
var tag = new(TextureTag);
var mat = doc->FindMaterial("Mat1");
var obj = doc->GetFirstObject();

obj->InsertTag(tag);
tag->SetMaterial(mat);

Muss ich das umwandeln oder ist "FindMaterial" der falsche Befehl ?
 
Hi!

SetMaterial erwartet einen Marker (siehe SDK), eventuell liefert das den Fehler?!

Anbei eine schnelle, kleine, unsaubere Version, die funktionieren sollte :)
Code:
SetMaterial(doc, obj, suffix) {
    // Suche Texture-Tag
    var ttag = obj->GetFirstTag();
    while(ttag && ttag->GetType() != Ttexture) {
        ttag = ttag->GetNext();
    }
    // Abbruch bei vorhandenen Texture-Tag
    if (ttag) return false;

    // Suche Material
    var mat = doc->FindMaterial("Mat." + suffix);

    // Material nicht vorhanden -> Erstellen
    if (!mat) {
        mat = new(Material);
        mat->SetName("Mat." + suffix);
        var col = mat->GetChannel(CHANNEL_COLOR);
        var colBc = mat->GetContainer();
        colBc->SetData(CH_TEXTURE, "Textur" + suffix + ".png");
        col->SetContainer(colBc);
        doc->InsertMaterial(mat, NULL);
    }
    // Texture-Tag erzeugen
    ttag = new(TextureTag);
    obj->InsertTag(ttag, NULL);
    ttag->SetMaterial(mat->GetMarker());

    return true;
}

//    MAIN
main(doc,op)
{
    // Hierarchie unterhalb op abarbeiten
    var obj = op->GetDown();
    var i = 0;
    while (obj) {
        i++;
        var pos = strstr(obj->GetName(), ".");
        if (pos > -1)
            SetMaterial(doc, obj, strmid(obj->GetName(), pos+1, sizeof(obj->GetName())-pos-1)); 
        obj = obj->GetNext();
    }

    EventAdd();
}
Benutzung auf eigene Gefahr ;)

Liebe Grüße,
Mark.
 
Einen Marker von was ? Und wo wird der definiert ?

(Ich habe mal mein Script mit GetMarker versehen und C4D stürzt kommentarlos ab :suspekt: )
Nach Ausführung deines Scripts passiert nichts und der Expression Editor ist blockiert.
Mysteriös...
 
Hi!

Ach, der Expression-Editor mag das EventAdd() nicht -> einfach diese Zeile löschen (sie sorgte bei mir dafür, daß neue Materialien brav im Materialien-Fenster angezeigt wurden).

Mit "Marker" meine ich die Zeile:
ttag->SetMaterial(mat->GetMarker());
...auf diese Weise funktioniert es bei mir.

Ansonsten ist mein Beispiel ja nur eine Vorlage, die Du noch auf Deine Bedürfnisse zurecht stutzen mußt. Z.Z. schaut die Expression, ob ein Objekt überhaupt ein Texture-Tag hat, wenn ja, wird abgebrochen. Wenn nein, wird geschaut, ob des dazugehörige Material existiert, wenn nein, wird dieses erzeugt. Folglich wird ein Texture-Tag mit vorhandenem oder erzeugtem Material erzeugt und zugewiesen...
Dabei liegen die Objekte unterhalb einer Hierarchie / eines Null-Objekts, an dem das Coffee-Tag liegt (op->GetDown())

Liebe Grüße,
Mark.
 
Nach langen und schmerzhaften Versuchen muss ich nochmal fragen, wo der Marker definiert wird.
Sobald GetMarker() verwendet wird, stürzt C4D ab, dabei deutet "EXC_BAD_ACCESS" auf einen Zugriff auf etwas Ausserhalb des Programms, (erinnert mich an C mit einem falschen Pointer).
Wenn es ein GetMarker gibt, wo passiert dann das SetMarker ?
Nach ca. 12 Programabstürzen... muss ein Marker sein ?

(Ich möchte ja nur ein Material einem Objekt zuordnen...)
 
Sodele, wenn man ein Material erstellt und gleich zuordnet, dann klappt das mit dem Marker.

Hier noch der Code als Inspiration und damit andere nicht so lange suchen müssen:

Code:
main(doc,op)
{
var obj;
var i;
var mat;

for (i=1; i<=200; i++)
{ 
obj = doc->FindObject("Cube"+tostring(i));
mat = new(Material);

mat->SetChannelState(CHANNEL_COLOR, TRUE);
var channel = mat->GetChannel(CHANNEL_COLOR);
var container = channel->GetContainer();
container->SetData(CH_TEXTURE, "Textur"+tostring(i)+".png");
container->SetData(CH_BRIGHTNESS, 1);
channel->SetContainer(container);

var matmarker = mat->GetMarker();
doc->InsertMaterial(mat, NULL);

var tag = new(TextureTag);
obj->InsertTag(tag, NULL);
tag->SetMaterial(matmarker);
}//for
}//main

Und natürlich vielen Dank an den fabelhaften Mark !!
 
Zurück