César Vonc
26/12/2011, 18h18
Bonjour,
Voici mon script COFFEE permettant de transformer des coordonnées UVW en un objet polygonal et vice versa.
Pour ceux qui n'aiment pas beaucoup l'interface de bodypaint et qui ont besoin de déplacer les points UV avec précision avec les outils de modélisation de base de c4d, je pense que ce script leur sera utile.
Sélectionnez votre objet, exécutez le script et les coordonnées UVW devrait apparaître sous forme d'un nouvel objet. Sélectionnez-le et relancez le script pour mettre le dépliage UVW de l'objet de base à jour.
Voici le code source, le script est en pièce jointe. Si vous avez des remarques, suggestions, ou trouvé des bogues... n'hésitez pas !
// Objet UVW par César Vonc (www.cesar.vonc.fr)
//v1.1
alerte(message) {
var erreur = new(array, 5);
erreur[0] = "Erreur.";
erreur[1] = "Veuillez sélectionner un objet éditable.";
erreur[2] = "Propriété UVW introuvable.";
erreur[3] = "Objet de base introuvable.";
erreur[4] = "L'objet de base ne correspond pas avec l'objet UVW.";
TextDialog(erreur[message], GEMB_OK);
}
modCoor(v) {
var vz = v.z;
var vy = v.y;
v.z = 1 - vy;
v.y = vz;
v *= 1000;
return v;
}
demodCoor(v) {
var vz = v.z;
var vy = v.y;
v.z = vy;
v.y = 1000 - vz;
v *= 0.001;
return v;
}
objVuvw(doc, op, texte) {
var obj = doc->FindObject(texte + " UVW");
if (obj) {
obj#ID_BASELIST_NAME += "_Ans";
obj#ID_BASEOBJECT_VISIBILITY_EDITOR = 1;
obj#ID_BASEOBJECT_VISIBILITY_RENDER = 1;
}
var uvw;
var tex;
var prop;
for(prop = op->GetFirstTag() ; prop ; prop = prop->GetNext()) {
if (instanceof(prop, UVWTag)) { uvw = prop; continue; }
if (instanceof(prop, TextureTag)) { tex = prop; continue; }
}
if(!instanceof(uvw, UVWTag)) return 2;
//if(!instanceof(tex, textureTag)) return;
var uvwObj = AllocObject(Opolygon);
var texProp = AllocTag(Ttexture);
var uvwTab = uvw->GetData();
var nbPolys = op->GetPolygonCount(); // Nombre de polygones
var nbPts = nbPolys*4; // Nombre de points
var posPts = uvw->GetData(); // Coordonnées des points
var maillage = new(array, nbPts); // Connexion des polygones
var i;
var n = 0; // Nombre réel de points
var tmp = new(array, nbPts);
for (i = 0 ; i < nbPolys ; i++) {
var poly = op->GetPolygon(i);
maillage[i*4] = n;
tmp[n] = i*4;
n++;
maillage[i*4+1] = n;
tmp[n] = i*4+1;
n++;
maillage[i*4+2] = n;
tmp[n] = i*4+2;
n++;
if (poly->c != poly->d) {
maillage[i*4+3] = n;
tmp[n] = i*4+3;
n++;
}
else {
maillage[i*4+3] = n-1;
tmp[n] = i*4+2;
}
posPts[i*4] = modCoor(posPts[i*4]);
posPts[i*4+1] = modCoor(posPts[i*4+1]);
posPts[i*4+2] = modCoor(posPts[i*4+2]);
posPts[i*4+3] = modCoor(posPts[i*4+3]);
}
var posPn = new(array, n);
for (i = 0 ; i < n ; i++) {
posPn[i] = posPts[tmp[i]];
}
var vc = new(VariableChanged); if (!vc) return 0;
vc->Init(0, n);
uvwObj->MultiMessage(MSG_POINTS_CHANGED, vc);
uvwObj->SetPoints(posPn);
var vc2 = new(VariableChanged); if (!vc2) return 0;
vc2->Init(0, nbPolys);
uvwObj->MultiMessage(MSG_POLYGONS_CHANGED, vc2);
uvwObj->SetPolygons(maillage);
doc->AddUndo(UNDO_OBJECT_NEW, uvwObj);
uvwObj#ID_BASELIST_NAME = op#ID_BASELIST_NAME + " UVW";
if(tex) {
texProp#TEXTURETAG_MATERIAL = tex#TEXTURETAG_MATERIAL;
texProp#TEXTURETAG_SIZE = texProp#TEXTURETAG_SIZE * 5;
texProp#TEXTURETAG_POSITION = vector(500, 0, 500);
texProp#TEXTURETAG_ROTATION:VECTOR_Y = 3*pi/2;
texProp#TEXTURETAG_PROJECTION = 2;
uvwObj->InsertTag(texProp, NULL);
}
doc->InsertObject(uvwObj, NULL, NULL);
doc->SetActiveObject(uvwObj);
uvwObj->Message(MSG_UPDATE);
// CallCommand(14023); // Aligner les normales
}
uvwVobj(doc, op, texte) {
var obj = doc->FindObject(texte);
if (!obj) return 3;
var uvw;
var prop;
for(prop = obj->GetFirstTag() ; prop ; prop = prop->GetNext()) {
if (instanceof(prop, UVWTag)) { uvw = prop; break; }
}
if(!instanceof(uvw, UVWTag)) return 2;
var nbPolys = op->GetPolygonCount();
var nbPolysObj = obj->GetPolygonCount();
if (nbPolys != nbPolysObj) { return 4; }
var i;
var uvwPos = new(array, nbPolys*4);
for (i = 0 ; i < nbPolys ; i++) {
var poly = op->GetPolygon(i);
uvwPos[i*4] = demodCoor(op->GetPoint(poly->a));
uvwPos[i*4 + 1] = demodCoor(op->GetPoint(poly->b));
uvwPos[i*4 + 2] = demodCoor(op->GetPoint(poly->c));
if (poly->c != poly->d)
uvwPos[i*4 + 3] = demodCoor(op->GetPoint(poly->d));
else
uvwPos[i*4 + 3] = demodCoor(op->GetPoint(poly->c));
}
doc->AddUndo(UNDO_OBJECT_BASEDATA, uvw);
uvw->SetData(uvwPos);
obj->Message(MSG_UPDATE);
uvw->Message(MSG_UPDATE);
}
main(doc, op)
{
if (!op || instanceof(op, Polygon)) { alerte(1); return; }
var texte = op#ID_BASELIST_NAME;
var posUVW = strstr(texte, " UVW");
var etat;
if (posUVW > 0) {
texte = strmid(texte, 0, posUVW);
etat = uvwVobj(doc, op, texte);
}
else {
etat = objVuvw(doc, op, texte);
}
if (etat) alerte(etat);
}
http://code.vonc.fr/details/s5-00.png
Maj du 28/12/11 : Correction d'un petit bogue.
Voici mon script COFFEE permettant de transformer des coordonnées UVW en un objet polygonal et vice versa.
Pour ceux qui n'aiment pas beaucoup l'interface de bodypaint et qui ont besoin de déplacer les points UV avec précision avec les outils de modélisation de base de c4d, je pense que ce script leur sera utile.
Sélectionnez votre objet, exécutez le script et les coordonnées UVW devrait apparaître sous forme d'un nouvel objet. Sélectionnez-le et relancez le script pour mettre le dépliage UVW de l'objet de base à jour.
Voici le code source, le script est en pièce jointe. Si vous avez des remarques, suggestions, ou trouvé des bogues... n'hésitez pas !
// Objet UVW par César Vonc (www.cesar.vonc.fr)
//v1.1
alerte(message) {
var erreur = new(array, 5);
erreur[0] = "Erreur.";
erreur[1] = "Veuillez sélectionner un objet éditable.";
erreur[2] = "Propriété UVW introuvable.";
erreur[3] = "Objet de base introuvable.";
erreur[4] = "L'objet de base ne correspond pas avec l'objet UVW.";
TextDialog(erreur[message], GEMB_OK);
}
modCoor(v) {
var vz = v.z;
var vy = v.y;
v.z = 1 - vy;
v.y = vz;
v *= 1000;
return v;
}
demodCoor(v) {
var vz = v.z;
var vy = v.y;
v.z = vy;
v.y = 1000 - vz;
v *= 0.001;
return v;
}
objVuvw(doc, op, texte) {
var obj = doc->FindObject(texte + " UVW");
if (obj) {
obj#ID_BASELIST_NAME += "_Ans";
obj#ID_BASEOBJECT_VISIBILITY_EDITOR = 1;
obj#ID_BASEOBJECT_VISIBILITY_RENDER = 1;
}
var uvw;
var tex;
var prop;
for(prop = op->GetFirstTag() ; prop ; prop = prop->GetNext()) {
if (instanceof(prop, UVWTag)) { uvw = prop; continue; }
if (instanceof(prop, TextureTag)) { tex = prop; continue; }
}
if(!instanceof(uvw, UVWTag)) return 2;
//if(!instanceof(tex, textureTag)) return;
var uvwObj = AllocObject(Opolygon);
var texProp = AllocTag(Ttexture);
var uvwTab = uvw->GetData();
var nbPolys = op->GetPolygonCount(); // Nombre de polygones
var nbPts = nbPolys*4; // Nombre de points
var posPts = uvw->GetData(); // Coordonnées des points
var maillage = new(array, nbPts); // Connexion des polygones
var i;
var n = 0; // Nombre réel de points
var tmp = new(array, nbPts);
for (i = 0 ; i < nbPolys ; i++) {
var poly = op->GetPolygon(i);
maillage[i*4] = n;
tmp[n] = i*4;
n++;
maillage[i*4+1] = n;
tmp[n] = i*4+1;
n++;
maillage[i*4+2] = n;
tmp[n] = i*4+2;
n++;
if (poly->c != poly->d) {
maillage[i*4+3] = n;
tmp[n] = i*4+3;
n++;
}
else {
maillage[i*4+3] = n-1;
tmp[n] = i*4+2;
}
posPts[i*4] = modCoor(posPts[i*4]);
posPts[i*4+1] = modCoor(posPts[i*4+1]);
posPts[i*4+2] = modCoor(posPts[i*4+2]);
posPts[i*4+3] = modCoor(posPts[i*4+3]);
}
var posPn = new(array, n);
for (i = 0 ; i < n ; i++) {
posPn[i] = posPts[tmp[i]];
}
var vc = new(VariableChanged); if (!vc) return 0;
vc->Init(0, n);
uvwObj->MultiMessage(MSG_POINTS_CHANGED, vc);
uvwObj->SetPoints(posPn);
var vc2 = new(VariableChanged); if (!vc2) return 0;
vc2->Init(0, nbPolys);
uvwObj->MultiMessage(MSG_POLYGONS_CHANGED, vc2);
uvwObj->SetPolygons(maillage);
doc->AddUndo(UNDO_OBJECT_NEW, uvwObj);
uvwObj#ID_BASELIST_NAME = op#ID_BASELIST_NAME + " UVW";
if(tex) {
texProp#TEXTURETAG_MATERIAL = tex#TEXTURETAG_MATERIAL;
texProp#TEXTURETAG_SIZE = texProp#TEXTURETAG_SIZE * 5;
texProp#TEXTURETAG_POSITION = vector(500, 0, 500);
texProp#TEXTURETAG_ROTATION:VECTOR_Y = 3*pi/2;
texProp#TEXTURETAG_PROJECTION = 2;
uvwObj->InsertTag(texProp, NULL);
}
doc->InsertObject(uvwObj, NULL, NULL);
doc->SetActiveObject(uvwObj);
uvwObj->Message(MSG_UPDATE);
// CallCommand(14023); // Aligner les normales
}
uvwVobj(doc, op, texte) {
var obj = doc->FindObject(texte);
if (!obj) return 3;
var uvw;
var prop;
for(prop = obj->GetFirstTag() ; prop ; prop = prop->GetNext()) {
if (instanceof(prop, UVWTag)) { uvw = prop; break; }
}
if(!instanceof(uvw, UVWTag)) return 2;
var nbPolys = op->GetPolygonCount();
var nbPolysObj = obj->GetPolygonCount();
if (nbPolys != nbPolysObj) { return 4; }
var i;
var uvwPos = new(array, nbPolys*4);
for (i = 0 ; i < nbPolys ; i++) {
var poly = op->GetPolygon(i);
uvwPos[i*4] = demodCoor(op->GetPoint(poly->a));
uvwPos[i*4 + 1] = demodCoor(op->GetPoint(poly->b));
uvwPos[i*4 + 2] = demodCoor(op->GetPoint(poly->c));
if (poly->c != poly->d)
uvwPos[i*4 + 3] = demodCoor(op->GetPoint(poly->d));
else
uvwPos[i*4 + 3] = demodCoor(op->GetPoint(poly->c));
}
doc->AddUndo(UNDO_OBJECT_BASEDATA, uvw);
uvw->SetData(uvwPos);
obj->Message(MSG_UPDATE);
uvw->Message(MSG_UPDATE);
}
main(doc, op)
{
if (!op || instanceof(op, Polygon)) { alerte(1); return; }
var texte = op#ID_BASELIST_NAME;
var posUVW = strstr(texte, " UVW");
var etat;
if (posUVW > 0) {
texte = strmid(texte, 0, posUVW);
etat = uvwVobj(doc, op, texte);
}
else {
etat = objVuvw(doc, op, texte);
}
if (etat) alerte(etat);
}
http://code.vonc.fr/details/s5-00.png
Maj du 28/12/11 : Correction d'un petit bogue.