PDA

Voir la version complète : Class hérité ?



Steph3D ::.
12/04/2007, 19h51
Je me demande si en coffee comme c'est très orienté objet comme le c++ avec les class dérivées, si on pouvait pas créer un nouveau type d'objet dérivé qui hérite d'une partie des options de la class originale de C4D ? Enfin, je me doute qu'on peu repartir d'une class parentes, mais c'est un peu plus compliqué la :?

Par exemple, créer à partir de l'objet Light un objet NewLight au j'enlève/masque toutes les fonctions qui me sont inutiles, et ajouter d'autres options perso en plus ?

Imaginon que je veux créer par exemple un nouveau type d'objet "lampes" déjà préréglé d'origine ou l'on a accès qu'a un minimum d'options modifiable et avec l'ajout d'un comportement quelconque en plus :idea:

Steph3D ::.
12/04/2007, 23h19
J'aurais bien bien tenté de redéfinir un cube sur cette idée de départ, mais ça ne marche pas :cry:



var PLUGIN_ID = 1234580 ;
var PLUGIN_NAME = "Simple CUBE" ;
var PLUGIN_HELP = "CUBE Basic" ;
var icon;

class NewBox:CubeObject
{
public:

NewBox();
GetID();
GetIcon();
GetHelpText();
UseMenu();
GetName();
Execute(doc, op);
}

NewBox::NewBox() {super();}
NewBox::GetID() {return PLUGIN_ID ;}
NewBox::GetIcon() { return icon ;}
NewBox::GetHelpText() { return PLUGIN_HELP ;}
NewBox::UseMenu() { return TRUE ;}
NewBox::GetName() {return PLUGIN_NAME ;}


NewBox::Execute(doc, op) {

var mon_cube=new(NewBox);
doc->InsertObject(mon_cube,NULL,NULL);
return;

}

main()
{
var fn = GeGetRootFilename();
fn->RemoveLast();
fn->AddLast("Box.tif");

icon = new(BaseBitmap,1,1);
icon->Load(fn);

Register(NewBox);
}

xs_yann
13/04/2007, 12h31
Salut Steph3D,
J'ai vu dans ce tut, qu'il utilise une classe pour créer un objet : http://www.vgd.co.uk/pages/notebook/seib/house_intro.html
Peut-être une piste :wink:

Jean-Laurent
13/04/2007, 13h26
J'espère que quelqu'un pourra t'aider.
Je n'ai pas de réponse mais plutôt des questions. :oops:

Tu définies ta nouvelle classe à partir de la classe "CubeObject".
Dans le SDK cette classe n'est pas explicitée.
On trouve les classes 'PointObject", "PolygonObject","SplineObject".
Toutes les autres sont donc sous-entendues?

"LightObject", "SkyObject" etc... ?
Quelles sont alors les fonctions propres à ces classes? Pas évident à deviner.
Où trouve-t-on cela?

C'est pourquoi quand tu écris "class NewBox:CubeObject" je ne vois pas bien les fonctions de la classe parente.

Sinon le lien de Yann est sympa mais ne correspond pas à mon avis à ta recherche.
Puisqu'il consisterait si j'ai bien compris à redéfinir un cube, mais à partie de ses points ou de ses faces.
On créerait une classe qui construit un cube polygonal de la taille voulu mais sans exploiter les fonctions déjà présentes de la classe "cube".

Steph3D ::.
13/04/2007, 14h51
C'est vrai que ta pas tout sur le Cube dans le SDK, mais les primitives hérite des fonctions de BaseObject dont ils en sont l'enfant. Apres il n'y a que les 3 exemples documentés PointObject, PolygonObject et SplineObject. Bon apres j'ai juste fait un test de base, mais tu sais, j'ai fait qu'une fois des plug-ins tag il y a 2 ans, alors je me rappelle plus de tout depuis :oops:

Et en effet, le lien de Yann montre juste comment construire une forme polygonale dans un objet poly de base, il ne construit pas une nouvelle class :(

Moi je veux juste redéfinir une nouvelle class d'objet de la primitive cube. Je voudrais avoir une nouvelle class dérivée de la primitive cube en plus basic sans les options ( biseau, séparer surface et les segments ) en gardant juste l'option de taille des bords et en ajoutant un petit code pour bloquer l'échelle à 1.

Si par miracle j'y arrive, j'aurais tout plein d'autres objets C4D à redéfinir avec des options masquées et préréglées pour des besoins spécifique avec des nouveaux comportements.

En fait, cela me permettra de faire un truc vraiment cool qui transformera C4D en éditeur de niveaux ou de monde 3D à la UnrealEngime que j'aimerais faire en freeware, voir ouvrir un projet commun :?: Mon concept est déjà fonctionnel à titre de prototype, mais cela reste une méthode macgyver bordélique en utilisant les objets normaux de C4D, il y a que moi qui arriverai à monter facilement une scène, car je sais quelle option je peux ou pas toucher sur les objets pour que mon usine à gaze fonctionne, et dans quel ordre placez les choses, et dans de tel conditions je ne peux distribuer ça en public avec des bouts d'Xpresso et coffee éparpillé partout.

Pour le moment cela mais bien utile que pour monter mes propres créations, c'est vraiment très basic et j'ajoute des options au cas par cas selon mes besoins. Mais maintenant j'aimerais voir si je peux me lancer dans un vrai projet de plug-in propre et distribuable ou pas, j'ai pas envie de faire la même erreur que pour mon bipède et resté coincé à la fin pour tout remettre au propre :cry2:

paspas
17/04/2007, 13h40
je pense a un truc steph

:idea: c'est un idée comme ça , elle vaut ce quelle vaut :mrgreen:

je suis en train de me documenter sur le C++ en général ( pas que coffee) ça peut toujours servir

si j ai bien comprit on appelle toujours une base de donnée spécifique suivant ce que l 'on veut compiler , il en a pour le graphisme , pour crée des interface ,......

en général tu appelle toujours par isotream<..... .h> cette biblio

on peut suppose que cette appelle est automatique dans coffee

il serrait possible dans coffee de crée une bibliothèque supplémentaire ,

imagine que tu veille crée un lampe :

dans un fichier a part il y a tout les code pour la crée

de ton coffee tu crée une fonction qui vas chercher ce fichier et lis son contenu ->> crée ta lampe ( ça serra ta classe)

de ton programme tu n'a qua appeler cette fonction et tu a ta lampe

c' est tirée par les cheveux mais bon en théorie ça devrait marcher :arg:

paspas qui cherche et qui finira par trouver

Steph3D ::.
17/04/2007, 17h49
Ben le C++ j'ai pas le temps de mis mettre :-( Mais avec cela, en théorie tu peux tout faire. Je me demande aussi si on peu pas créer un plug-in de nouvelles fonctions en C++ qu'on peu appeler dans nos expressions coffee et xpresso pour ajouter en C++ les moyens qui manque au coffee. Mais malheureusement je n’ai pas le temps et les moyens d'expérimenter ça :?

Pour le moment j'ai réglé mon problème en créant des boutons plug-ins qui créent dans la scène des objets c4d avec ajout d'un tag de contrôle qui contiennent les nouvelles options et force les préréglages de l'objet.

Je ne pense pas qu'on peu redéfinir des nouvelles classes en objet de base en coffee car j'en ai jamais vu, c'est toujours basé sur un tag de contrôle et un objet poly, sauf en C++ bien sur.

Je présume qu'on pourrait crée une nouvelle class lampe ou autre en C++ avec ses options masquées contrôlées par un tag invisible ou non qui pourrais être manipulé par le coffee. une idée théorique parmi d'autres....

paspas
17/04/2007, 18h23
Ben le C++ j'ai pas le temps de mis mettre

ben moi mon apprentissage est très lent :cry2: et super complexe en auto ditact mais je désespère pas :mrgreen:

ça va daler comme on dis chez nous lol

paspas

ps cofee peut il appeler une bibio c++ autre que la sienne deja

Steph3D ::.
17/04/2007, 19h28
C'est toujours lents pour apprendre :| mais comme je dois déjà digérer de tonnes de logiciels 3D et me mettre à chaque fois à jour, j'ai pas trop le temps pour passé à la prog, je me contente des expressions, sinon mes neurones vont fumée :arg: Deja que le coffee à le SDK en us et que mon english se limite à trois mots, dur ! dur ! :coup: Difficil d'etre graphistes est programmeur, est surtout impossible de maîtriser les deux, il fauderait deux vies :cry2:

Steph3D ::.
18/04/2007, 22h19
Bon en fait le résonnement un peu plus juste je pense, serais celui-là, sur l'autre code j'ai bêtement fait un objet qui se crée lui-même :roll:


//------------------------------------------------------------------------------------------------------------------------------------------------------------
const var PLUGIN_ID = 9090900; // Plugin ID (Registered)
const var PLUGIN_ID2 = 9090901; // Plugin ID (Registered)

var icon; // Variable global de l'icône
//------------------------------------------------------------------------------------------------------------------------------------------------------------
class MyObj:CubeObject
{
public:
MyObj();
//DisplayAllowed();
GetID();
GetName();
GetIcon();
}

MyObj::GetName() { return "NewCube"; }
MyObj::GetID() { return PLUGIN_ID2; }


MyObj::GetIcon()
{
var Bitmap = new(BaseBitmap,1,1);
var File = new(Filename);

File = GeGetRootFilename();
File->RemoveLast();
File->AddLast("Ico.gif");
Bitmap->Load(File);

return Bitmap;
}

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------


// Plugin class
class Demo extends MenuPlugin {
public:
Demo(); // Constructeur
GetID(); // Plugin ID
GetName(); // Plugin nom
GetHelp(); // Plugin étiquette
GetIcon(); // Icon image
Execute(doc); // Execution du Plug-in
}
//------------------------------------------------------------------------------------------------------------------------------------------------------------
Demo::Demo() { super(); }
Demo::GetID() { return PLUGIN_ID; }
Demo::GetName() { return "TEST"; } // Non du plugin
Demo::GetHelp() { return "Lancer le TEST"; } // Etiquette du plugin
//------------------------------------------------------------------------------------------------------------------------------------------------------------
// Ici se trouve la fonction qui sera exécutée au lancement du plug-in, en somme, le programme principal

Demo::GetIcon()
{
var icon = new(BaseBitmap,1,1);
var File = new(Filename);

File = GeGetRootFilename();
File->RemoveLast();
File->AddLast("Ico.gif");
icon->Load(File);

return icon;
}

Demo::Execute(doc) {


//var mon_obj=new(MyObj);
var mon_obj = AllocObject(9090901); // Creer l'objet en mémoire
doc->InsertObject(mon_obj,NULL,NULL);
//------------------------------------------------------------------------------------------------------------------------------------------------------------
// Pour rafraîchir toute la scène
GeEventAdd(NEW_ACTIVE_OBJECT);
doc->Message(MSG_UPDATE);
doc->Message(DOCUMENT_CHANGED);

return TRUE;
}

//------------------------------------------------------------------------------------------------------------------------------------------------------------
main() {


//------------------------------------------------------------------------------------------------------------------------------------------------------------
// Enregistrer le Plug-in
Register(MyObj);
Register(Demo);
}


Mais ça ne marche pas quand meme, on ne peu pas crée de nouveau objet dérivé avec le coffee, faut passer par le C++ :cry:

Le seul truc qu'on peut faire, c'est partir d'un PolygonObject et contrôler la forme dans un tag comme Majoul là visiblement fait avec son TuilGen, voilà pour l'info.

Et puis tout manière, tan que j'arriverai pas à faire d'interface 100% fonctionnelle je ne pourrais jamais rien sortir de bien :roll: :cry2:

xs_yann
27/11/2007, 19h14
Je suis de retour sur ce topic après avoir commencé à apprendre plus en profondeur la POO.
L'apprentissage du C++ permet de mieux comprendre ce que l'on fait en coffee.
Voici donc une base avec un héritage tout simple :


var PLUGIN_ID = 1000003; //Fausse ID

//-----------------------------------------------Class pour mon objet

class MyClass : CubeObject {
public :

MyClass(); //Constructeur

}

MyClass::MyClass() {
super(); //appele le constructeur parent, vu que MyClass hérite de CubeObject,
} //il appele le constructeur de la class CubeObject


//------------------------------------------------- Class pour l'interface

class MyDialog : GeDialog {
public:
MyDialog();

CreateLayout();
Init();
Command(id,msg);
}
MyDialog::MyDialog() {
super(PLUGIN_ID);
}


MyDialog::CreateLayout() {
SetTitle("testClass");
AddGroupBeginV(8000,0,1,"",0);
{
AddButton(800,BFV_FIT,100,15,"Add an Object"); // Juste un bouton
}
AddGroupSpace(10,10);
AddGroupBorderSpace(25,25,25,25);
AddGroupEnd();

return TRUE;
}

MyDialog::Init() {

}

MyDialog::Command(id,msg) {
var doc = GetActiveDocument();
var object = new(MyClass); // Creation de l'Objet de type MyClass
switch(id) {
case 800: //Code executé lorsque l'on clique sur le bouton
doc->InsertObject(object,NULL,NULL); // Il hérite de la Class CubeObject il a donc exactement les même propriété
break;
}
EventAdd(MSG_UPDATE);
return TRUE;
}

//------------------------------------------Class pour le plugin

class MyMenuPlugin : MenuPlugin {
public:
MyMenuPlugin();

GetID();
GetName();
GetHelp();
Execute(doc);

RestoreLayout(secret);
}

MyMenuPlugin::MyMenuPlugin() {
super();
}

MyMenuPlugin::GetID() {
return PLUGIN_ID;
}

MyMenuPlugin::GetName() {
return "testClass";
}

MyMenuPlugin::GetHelp() {
return "testClass";
}

var d;

MyMenuPlugin::Execute(doc) {
d->Open(TRUE,-1,-1);
}

MyMenuPlugin::RestoreLayout(secret) {
if (!d) d = new(MyDialog);
d->RestoreLayout(secret);
}

main() {
d = new(MyDialog);

Register(MyMenuPlugin);
}


Voilà, a partir de là on peut peu être ajouter des méthodes dans la classe.
En revanche, pour en supprimer... je crois qu'une class hérites de toutes les méthodes de sa class parente :roll:

xs_yann
27/11/2007, 19h42
Voilà la suite, je vous explique.
Je vais rajouter une méthode nommée DoubleNom() à ma classe qui va servir à renommer mon objet.
Si mon objet s'appelle "Cube", DoubleNom("toto"); va le renommer "Cube toto".
Il renomme donc avec le nom de départ + la variable passée en paramètre.
Le code simplifié :


var PLUGIN_ID = 1000003; //Fausse ID

//-----------------------------------------------Class pour mon objet

class MyClass : CubeObject {
public :

MyClass(); //Constructeur
DoubleNom(nom);

}

MyClass::MyClass() {
super();
}

MyClass::DoubleNom(nom) {
var name = GetName(); //Normalement cela devrait revenir au même que "this->GetName()", this désignant l'objet mais this ne fonctionne pas :(
SetName(tostring(name +" "+ nom)); //Pareil "this->SetName()"
}

//------------------------------------------------- Class pour l'interface

class MyDialog : GeDialog {
public:
MyDialog();

CreateLayout();
Init();
Command(id,msg);
}
MyDialog::MyDialog() {
super(PLUGIN_ID);
}


MyDialog::CreateLayout() {
[.....]
}

MyDialog::Init() {

}

MyDialog::Command(id,msg) {
var doc = GetActiveDocument();
var object = new(MyClass);
switch(id) {
case 800:
doc->InsertObject(object,NULL,NULL);
object->DoubleNom("toto"); //Ici on teste la fonction avec "toto" comme paramètre
break;
}
EventAdd(MSG_UPDATE);
return TRUE;
}
....


Et voilà j'ai bien un cube nommé "Cube toto" qui se créer :art:

xs_yann
27/11/2007, 19h55
Pour faire un cube sans les options de biseaux, etc, il faudrait faire un truc dans le genre de la spline doublecircle du sdk c++. On peut donc inclure ce qui va bien pour le dialogue (c'est déjà écrit, ça doit être dans les ressource de c4d sous le nom de ocube.h ou un truc dans le genre), mais après j'ai bien peur qu'il faille redessiner tout le cube et ça ça devient compliqué, je vais analyser le fichier circle.cpp du SDK, je vous tiens au courant (enfin si ça interresse toujours).
:odile:

b3nj77
28/11/2007, 08h10
salut,

ah ouai moi sa m'interresse grave :poucehaut:

je trouve tes avancées super interressante xs_yann, :art:

bonne chance

bye :poucehaut: :prie: :odile:

moebius
28/11/2007, 09h47
je vous tiens au courant (enfin si ça interresse toujours).


ouaip!

merci pour tes recherches Yann, pour le moment j'avoue que j'ai un peu de mal à suivre, mais je sais où je vais venir quand je me lancerai un peu dans la programmation :poucehaut:

xs_yann
28/11/2007, 16h08
b3nj77 : Merci :D (au fait, "Acceuil" ça s'écrit "Accueil" : http://ledesgin.123.fr/ :wink:)
moebius : pas de problème, je te soutiendrais avec plaisir :wink:

Voilà l'avancée :
http://ykoeth.free.fr/fc4d/class_test1 (http://ykoeth.free.fr/fc4d/class_test1)

http://ykoeth.free.fr/fc4d/class_test2 (http://ykoeth.free.fr/fc4d/class_test2)

Je crois que je ne m'y suis pas pris par la bonne méthode mais je commence à comprendre quelques trucs. :art:

xs_yann
28/11/2007, 17h24
C'est bon j'ai trouvé comment le faire proprement, le code :



//roundedtube.cpp

#include "c4d.h"
#include "c4d_symbols.h"
#include "oroundedtube.h"

class RoundedTube : public ObjectData
{
public:
virtual Bool Init (GeListNode *node);

virtual void GetDimension (PluginObject *op, Vector *mp, Vector *rad);
virtual Bool Draw (PluginObject *op, LONG type, BaseDraw *bd, BaseDrawHelp *bh);
virtual Bool Message(GeListNode *node, LONG type, void *t_data);

static NodeData *Alloc(void) { return gNew RoundedTube; }
};

Bool RoundedTube::Message(GeListNode *node, LONG type, void *t_data)
{

if (type==MSG_MENUPREPARE)
{
((BaseObject*)node)->SetPhong(TRUE,FALSE,0.0);
}
return TRUE;
}

void RoundedTube::GetDimension(PluginObject *op, Vector *mp, Vector *rad)
{

BaseContainer *data = op->GetDataInstance();
Vector size = data->GetVector(CUBE_LEN);

*mp =0.0;
*rad = Vector(size.x/2,size.y/2,size.z/2);
}

Bool RoundedTube::Init(GeListNode *node)
{

BaseObject *op = (BaseObject*)node;
BaseContainer *data = op->GetDataInstance();
data->SetVector(CUBE_LEN,Vector(200,200,200));


return TRUE;
}

Bool RoundedTube::Draw(PluginObject *op, LONG type, BaseDraw *bd, BaseDrawHelp *bh)
{

return TRUE;
}

// be sure to use a unique ID obtained from www.plugincafe.com
#define ID_ROUNDEDTUBEOBJECT 1001157

Bool RegisterRoundedTube(void)
{
// decide by name if the plugin shall be registered - just for user convenience
String name=GeLoadString(IDS_ROUNDED_TUBE); if (!name.Content()) return TRUE;
return RegisterObjectPlugin(ID_ROUNDEDTUBEOBJECT,name,OBJ ECT_GENERATOR,RoundedTube::Alloc,"Oroundedtube","roundedtube.tif",0);
}



Ce code génère l'objet ci-dessus.
Il reste plus qu'a programmer le cube, et ensuite la gestion des poignées oranges (pour les primitives). :coup:
:odile:

oli_d
28/11/2007, 18h43
Salut Yann,

Si j'ai bien compris tu es passé du côté obscur de la force, c'est à dire dans le C++ !

J'ai pas encore bien compris le but final de ton code, si tu as un problème concret ou si tu fais un exercice de style pour l'apprentissage. De toute façon cela m'intéresse beaucoup. Je te suis et t'encourage, sans pouvoir malheureusement t'aider beaucoup.

Une petite question de béotien : dans le code que représente le"*" devant des variables (par ex "*mp =0.0;"

xs_yann
28/11/2007, 19h01
Oli_D : le but final du code n'est pas quelque chose de concret pour moi, c'est juste la solution au problème de Steph3D; le but est donc de creer un objet Primitive Cube avec seulement les options de taille (pas de segment, fillet...).

Le * devant les variable defini un pointeur, c'est assez compliqué à comprendre comme notion et encore plus à expliquer. :roll:
Si tu veux en savoir plus : http://www.siteduzero.com/tuto-3-3828-1-a-l-assaut-des-pointeurs.html

Ce n'était pas si compliqué que ça :mrgreen: :



//roundedtube.cpp

#include "c4d.h"
#include "c4d_symbols.h"
#include "oroundedtube.h"

class RoundedTube : public ObjectData
{
public:
virtual Bool Init (GeListNode *node);

virtual void GetDimension (PluginObject *op, Vector *mp, Vector *rad);
virtual Bool Draw (PluginObject *op, LONG type, BaseDraw *bd, BaseDrawHelp *bh);
virtual BaseObject* GetVirtualObjects(BaseObject* op, HierarchyHelp* hh);
virtual Bool Message(GeListNode *node, LONG type, void *t_data);

static NodeData *Alloc(void) { return gNew RoundedTube; }
};

Bool RoundedTube::Message(GeListNode *node, LONG type, void *t_data)
{

if (type==MSG_MENUPREPARE)
{
((BaseObject*)node)->SetPhong(TRUE,FALSE,0.0);
}
return TRUE;
}

void RoundedTube::GetDimension(PluginObject *op, Vector *mp, Vector *rad)
{

BaseContainer *data = op->GetDataInstance();
Vector size = data->GetVector(CUBE_LEN);

*mp =0.0;
*rad = Vector(size.x/2,size.y/2,size.z/2);
}

Bool RoundedTube::Init(GeListNode *node)
{

BaseObject *op = (BaseObject*)node;
BaseContainer *data = op->GetDataInstance();
data->SetVector(CUBE_LEN,Vector(200,200,200));


return TRUE;
}
BaseObject* RoundedTube::GetVirtualObjects(PluginObject* op, HierarchyHelp* hh)
{
BaseObject *ret = BaseObject::Alloc(Ocube);
BaseContainer *data = op->GetDataInstance();
BaseContainer *bc = ret->GetDataInstance();
Vector size = data->GetVector(CUBE_LEN);
bc->SetVector(PRIM_CUBE_LEN, size);
GePrint(LongToString(size.x));
ModelingCommandData cd;
cd.doc = GetActiveDocument();
cd.op = ret;
if (!SendModelingCommand(MCOMMAND_CURRENTSTATETOOBJEC T, cd)) return FALSE;

return ret;
}

Bool RoundedTube::Draw(PluginObject *op, LONG type, BaseDraw *bd, BaseDrawHelp *bh)
{

return TRUE;
}

// be sure to use a unique ID obtained from www.plugincafe.com
#define ID_ROUNDEDTUBEOBJECT 1001157

Bool RegisterRoundedTube(void)
{
// decide by name if the plugin shall be registered - just for user convenience
String name=GeLoadString(IDS_ROUNDED_TUBE); if (!name.Content()) return TRUE;
return RegisterObjectPlugin(ID_ROUNDEDTUBEOBJECT,name,OBJ ECT_GENERATOR,RoundedTube::Alloc,"Oroundedtube","roundedtube.tif",0);
}



Je me base sur la Primitive cube de c4d, en modifiant donc l'objet alloué exemple : "BaseObject::Alloc(Olight);" une lumière sera créée avec les paramètres Size.X, Size.Y, Size.Z (ce qui aurait peu de sens :roll:)

Voilà donc en partant de ce code il est possible de reprendre tous les objets de base de C4d (émetteurs, primitives, lumières...) avec des parmètres différents :wink:

Pour ceux que ça interesse je peux fournir le code source mais le projet est seulement pour Xcode et je peux compiler que pour OS X UB version supérieures à la R9.6. :wink:

edit : les screens :
http://ykoeth.free.fr/fc4d/class_test5.jpg (http://ykoeth.free.fr/fc4d/class_test5.jpg)
http://ykoeth.free.fr/fc4d/class_test3.jpg (http://ykoeth.free.fr/fc4d/class_test3.jpg)
http://ykoeth.free.fr/fc4d/class_test4.jpg (http://ykoeth.free.fr/fc4d/class_test4.jpg)

Je vais continuer à faire mumuse :bounce:

xs_yann
29/11/2007, 18h18
Et voilà le plug mis au propre :
http://ykoeth.free.fr/fc4d/class_test6.jpg (http://ykoeth.free.fr/fc4d/class_test6.jpg)

http://ykoeth.free.fr/fc4d/class_test7.jpg (http://ykoeth.free.fr/fc4d/class_test6.jpg)

genghiskhan
29/11/2007, 18h58
alors moi je dis respect :prie:

oli_d
29/11/2007, 20h57
:shock: il faudra quand même un jour que tu nous révéle de quelle planète tu viens !

:prie: respect et chapeau bas !

Est-ce que tu as trouvé le moyen d'hériter des poignées orange de redimensionnement ?

Merci pour le lien je suis exactement dans le cas du type qui a lu des bouquins sur le c++ et qui n'a jamais rien compris aux pointeurs. Mais quand je serai grand j'y arriverai (j'ai que 42ans après tout !)

xs_yann
29/11/2007, 21h02
:shock: il faudra quand même un jour que tu nous révéle de quelle planète tu viens !

Est-ce que tu as trouvé le moyen d'hériter des poignées orange de redimensionnement ?



Merci Oli_D, il faudrait que je demande à mon père :mrgreen:

Pour les poignées il y a des méthodes prévue pour dans la classe ObjectData. (DetectHandle...).
Ici il n'est plus question d'héritage (le seul truc qui a un rapport, c'est ma classe Plugin qui hérite de la classe ObjectData).
Comme je l'ai expliqué l'héritage ne correspondait pas trop au problème (c'est le premier code coffee que j'ai donné).

Si tu veux commencer le C++ pour les plugins C4d, il suffit de faire les cours sur le www.siteduzero.com (en commençant par le C) ensuite faire le tuto www.astrofish.com et après avec les exemples du SDK (Cinema4D>Plugins>cinema4dsdk) le sdk c++ de plugincafe.com et le forum de plugincafe.com tu peux avancer. Il est quand même préférable de faire du coffee d'abord (chose que tu fais apparement) pour avoir quelques notions de programmation avant de commencer. :wink:

Je vais essayer de voir pour les poignées oranges, la suite plus tard :art:

oli_d
30/11/2007, 11h40
Merci xs_yann,

Maintenant j'ai vraiment envie de me lancer dans le c++, j'espère avoir un peu de temps pendant les fêtes.

Et ne t'arrête surtout pas c'est super intéressant et motivant tes exemples, cela me donne plein d'idées.

xs_yann
02/12/2007, 14h51
Les poignées :
http://ykoeth.free.fr/fc4d/class_test8.jpg (http://ykoeth.free.fr/fc4d/class_test8.jpg)



//myprim.cpp

#include "c4d.h"
#include "c4d_symbols.h"
#include "omyprim.h"

class MyPrim : public ObjectData
{
public:
virtual Bool Init (GeListNode *node);

virtual void GetDimension (PluginObject *op, Vector *mp, Vector *rad);
virtual Bool Draw (PluginObject *op, LONG type, BaseDraw *bd, BaseDrawHelp *bh);
virtual BaseObject* GetVirtualObjects(BaseObject* op, HierarchyHelp* hh);
virtual Bool Message(GeListNode *node, LONG type, void *t_data);

static NodeData *Alloc(void) { return gNew MyPrim; }
};

Bool MyPrim::Message(GeListNode *node, LONG type, void *t_data)
{

if (type==MSG_MENUPREPARE)
{
((BaseObject*)node)->SetPhong(TRUE,FALSE,0.0);
}
return TRUE;
}

void MyPrim::GetDimension(PluginObject *op, Vector *mp, Vector *rad)
{

BaseContainer *data = op->GetDataInstance();
Vector size = data->GetVector(CUBE_LEN);

*mp =0.0;
*rad = Vector(size.x/2,size.y/2,size.z/2);
}

Bool MyPrim::Init(GeListNode *node)
{

BaseObject *op = (BaseObject*)node;
BaseContainer *data = op->GetDataInstance();
data->SetVector(CUBE_LEN,Vector(200,200,200));


return TRUE;
}
BaseObject* MyPrim::GetVirtualObjects(PluginObject* op, HierarchyHelp* hh)
{
BaseObject *ret = BaseObject::Alloc(Ocube);
BaseContainer *data = op->GetDataInstance();
BaseContainer *bc = ret->GetDataInstance();
Vector size = data->GetVector(CUBE_LEN);
bc->SetVector(PRIM_CUBE_LEN, size);
ret->SetName("My Primitive");
ModelingCommandData cd;
cd.doc = GetActiveDocument();
cd.op = ret;
if (!SendModelingCommand(MCOMMAND_CURRENTSTATETOOBJEC T, cd)) return FALSE;

return ret;
}

#define HANDLES 3

Bool MyPrim::Draw(PluginObject *op, LONG type, BaseDraw *bd, BaseDrawHelp *bh)
{
if (type!=DRAWPASS_HANDLES) return TRUE;

BaseContainer *data = op->GetDataInstance();
Vector size = data->GetVector(CUBE_LEN);

LONG hitid = op->GetHighlightHandle(bd);

Matrix m = bh->GetMg();
bd->SetPen(GetWorldColor(VIEWCOLOR_ACTIVEPOINT));

bd->Handle3D(Vector(size.x/2,0,0)*m,HANDLE_BIG);
bd->Line3D(Vector(size.x/2,0,0)*m,m.off);

bd->Handle3D(Vector(0,size.y/2,0)*m,HANDLE_BIG);
bd->Line3D(Vector(0,size.y/2,0)*m,m.off);

bd->Handle3D(Vector(0,0,size.z/2)*m,HANDLE_BIG);
bd->Line3D(Vector(0,0,size.z/2)*m,m.off);


return TRUE;
}

// be sure to use a unique ID obtained from www.plugincafe.com
#define ID_MYPRIM 1001157

Bool RegisterMyPrim(void)
{
// decide by name if the plugin shall be registered - just for user convenience
String name=GeLoadString(IDS_MYPRIM); if (!name.Content()) return TRUE;
return RegisterObjectPlugin(ID_MYPRIM,name,OBJECT_GENERAT OR,MyPrim::Alloc,"Omyprim","myprim.tif",0);
}



Pas encore d'interaction avec les poignées, à venir :art:

xs_yann
02/12/2007, 16h10
Et voilà il y a de l'interaction avec les poignées oranges et j'ai corrigé un petit bug avec le phong tag :


//myprim.cpp

#include "c4d.h"
#include "c4d_symbols.h"
#include "omyprim.h"

class MyPrim : public ObjectData
{
public:
virtual Bool Init (GeListNode *node);

virtual void GetDimension (PluginObject *op, Vector *mp, Vector *rad);
virtual Bool Draw (PluginObject *op, LONG type, BaseDraw *bd, BaseDrawHelp *bh);
virtual BaseObject* GetVirtualObjects(BaseObject* op, HierarchyHelp* hh);
virtual LONG DetectHandle (PluginObject *op, BaseDraw *bd, LONG x, LONG y, LONG qualifier);
virtual Bool MoveHandle (PluginObject *op, PluginObject *undo, const Matrix &tm, LONG hit_id, LONG qualifier);
virtual Bool Message(GeListNode *node, LONG type, void *t_data);

static NodeData *Alloc(void) { return gNew MyPrim; }
};

Bool MyPrim::Message(GeListNode *node, LONG type, void *t_data)
{

if (type==MSG_MENUPREPARE)
{
((BaseObject*)node)->SetPhong(TRUE,TRUE,Rad(80.0));
}
return TRUE;
}

void MyPrim::GetDimension(PluginObject *op, Vector *mp, Vector *rad)
{

BaseContainer *data = op->GetDataInstance();
Vector size = data->GetVector(CUBE_LEN);

*mp =0.0;
*rad = Vector(size.x/2,size.y/2,size.z/2);
}

Bool MyPrim::Init(GeListNode *node)
{

BaseObject *op = (BaseObject*)node;
BaseContainer *data = op->GetDataInstance();
data->SetVector(CUBE_LEN,Vector(200,200,200));


return TRUE;
}
BaseObject* MyPrim::GetVirtualObjects(PluginObject* op, HierarchyHelp* hh)
{

BaseObject *ret = BaseObject::Alloc(Ocube);
op->CopyTagsTo(ret,TRUE,FALSE,FALSE,NULL);

BaseContainer *data = op->GetDataInstance();
BaseContainer *bc = ret->GetDataInstance();

Vector size = data->GetVector(CUBE_LEN);
bc->SetVector(PRIM_CUBE_LEN, size);
ret->SetName("My Primitive");
ModelingCommandData cd;
cd.doc = GetActiveDocument();
cd.op = ret;
if (!SendModelingCommand(MCOMMAND_CURRENTSTATETOOBJEC T, cd)) return FALSE;

return ret;
}

#define HANDLES 3

Bool MyPrim::Draw(PluginObject *op, LONG type, BaseDraw *bd, BaseDrawHelp *bh)
{
if (type!=DRAWPASS_HANDLES) return TRUE;

BaseContainer *data = op->GetDataInstance();
Vector size = data->GetVector(CUBE_LEN);

LONG hitid = op->GetHighlightHandle(bd);

Matrix m = bh->GetMg();

bd->SetPen(GetWorldColor(VIEWCOLOR_ACTIVEPOINT));

bd->Line3D(Vector(size.x/2,0,0)*m,m.off);
bd->Line3D(Vector(0,size.y/2,0)*m,m.off);
bd->Line3D(Vector(0,0,size.z/2)*m,m.off);

if(hitid==0)bd->SetPen(GetWorldColor(VIEWCOLOR_SELECTION_PREVIEW)) ;
bd->Handle3D(Vector(size.x/2,0,0)*m,HANDLE_BIG);
bd->SetPen(GetWorldColor(VIEWCOLOR_ACTIVEPOINT));

if(hitid==1)bd->SetPen(GetWorldColor(VIEWCOLOR_SELECTION_PREVIEW)) ;
bd->Handle3D(Vector(0,size.y/2,0)*m,HANDLE_BIG);
bd->SetPen(GetWorldColor(VIEWCOLOR_ACTIVEPOINT));

if(hitid==2)bd->SetPen(GetWorldColor(VIEWCOLOR_SELECTION_PREVIEW)) ;
bd->Handle3D(Vector(0,0,size.z/2)*m,HANDLE_BIG);



return TRUE;
}
LONG MyPrim::DetectHandle(PluginObject *op, BaseDraw *bd, LONG x, LONG y, LONG qualifier)
{
BaseContainer *data = op->GetDataInstance();
Vector size = data->GetVector(CUBE_LEN);
if (qualifier&QUALIFIER_CTRL) return NOTOK;
Matrix mg = op->GetMg();
if (bd->PointInRange(Vector(size.x/2,0,0)*mg,x,y)) return 0;
if (bd->PointInRange(Vector(0,size.y/2,0)*mg,x,y)) return 1;
if (bd->PointInRange(Vector(0,0,size.z/2)*mg,x,y)) return 2;
return NOTOK;

}

Bool MyPrim::MoveHandle(PluginObject *op, PluginObject *undo, const Matrix &tm, LONG hit_id, LONG qualifier)
{

BaseContainer *src = undo->GetDataInstance();
BaseContainer *dst = op->GetDataInstance();
switch(hit_id) {
case 0 :
dst->SetVector(CUBE_LEN,Vector(tm.off.x+src->GetVector(CUBE_LEN).x,src->GetVector(CUBE_LEN).y,src->GetVector(CUBE_LEN).z));
break;
case 1 :
dst->SetVector(CUBE_LEN,Vector(src->GetVector(CUBE_LEN).x,tm.off.y+src->GetVector(CUBE_LEN).y,src->GetVector(CUBE_LEN).z));
break;
case 2 :
dst->SetVector(CUBE_LEN,Vector(src->GetVector(CUBE_LEN).x,src->GetVector(CUBE_LEN).y,tm.off.z+src->GetVector(CUBE_LEN).z));
break;
}

return TRUE;
}


// be sure to use a unique ID obtained from www.plugincafe.com
#define ID_MYPRIM 1022022

Bool RegisterMyPrim(void)
{
// decide by name if the plugin shall be registered - just for user convenience
String name=GeLoadString(IDS_MYPRIM); if (!name.Content()) return TRUE;
return RegisterObjectPlugin(ID_MYPRIM,name,OBJECT_GENERAT OR,MyPrim::Alloc,"Omyprim","myprim.tif",0);
}



Je crois que je suis arrivé au bout :art:
Reste plus qu'a s'en servir pour obtenir quelque chose d'utile :roll:

moebius
02/12/2007, 16h55
Reste plus qu'a s'en servir pour obtenir quelque chose d'utile :roll:


:mrgreen:


super taff en tous cas ! :poucehaut:

oli_d
04/12/2007, 12h24
Super xs_yann,

Je me suis remis au c++ sur le site que tu m'as conseillé, il est super bien fait.

Ton avancée sera très utile, par exemple si un jour j'ai le courage de relancer la maison paramétrique. Ce serait très utile de pouvoir dimensionner les éléments via des poignées oranges.

Encore bravo !

Steph3D ::.
05/12/2007, 02h33
Merci Super Yann :poucehaut:

Pour le moment je fais pas de prog, mais je pense mis remettre l'hiver, du moins pour le plug en coffee, par se que le C++ et moi ça fait deux ! j'ai malheureusement pas le temps de me mettre à un langage de prog pur et dur.

Là, je suis surtout en train de me faire ZBrush 3

Ta redéfini le cube la, et pas refait un neuf à la main ? et les autres infos inutiles sont donc bien masquées ? et je peu détecter l'objet dans mon code coffee comme un nouvel objet, et pas le Box C4D d'origine ?

Sinon, si tu veux construire un objet en C++, et que tu trouves ça compliqué, contente-toi alors de faire un simple polygone ( juste pour savoir qu'elle principe de construction C4D utilise ) Pour le reste je peux toujours demandé à mon dev, s'il peut te finaliser ta primitive, car la programmation d'objet 3D en OpenGL, c'est du gâteau pour lui, c'est juste C4D qu'il connait pas :(

xs_yann
05/12/2007, 15h06
Ta redéfini le cube la, et pas refait un neuf à la main ? et les autres infos inutiles sont donc bien masquées ? et je peu détecter l'objet dans mon code coffee comme un nouvel objet, et pas le Box C4D d'origine ?


Oui je l'ai redéfini, j'aurai pu redessiner tout le cube mais le "Box C4D" d'origine correspond à ce que je veux afficher alors pas besoin.
A partir de là vu que ce ne sont que des primitives que tu veux redéfinir c'est très simple, tu peux afficher que les paramètres que tu veux en ajouter ou bien en "forcer" certains.
Les attributs des primitives sont récupérables dans les ressources de C4D (ex : osphere.res, ocylinder.res...)

Steph3D ::.
31/05/2008, 14h43
Hello Yann

Quand je tente de compiler ton tout 1er exemple, j'obtiens l'erreur

1>...\source\roundedtube.cpp (39) : error C2065: 'CUBE_LEN' : identificateur non déclaré
1>...\source\roundedtube.cpp (50) : error C2065: 'CUBE_LEN' : identificateur non déclaré

:?
Tu as peut être modifié le oroundedtube.h d'origine du sdk pour ajouter des conteneurs ou je sais pas ? :oops:
Enfin pour le moment je peux pas bien suivre, mais j'essaye juste de monter un projet simple et faire en sorte qu'on es sur PC VC++ une base de départ très basic et compatible 10.5 pour débuter le truc :roll:

xs_yann
01/06/2008, 19h28
Pour compiler le code il faut créer un nouveau plug avec tout les fichiers ressources qui vont avec.
Voilà le dossier avec le code final : http://ykoeth.free.fr/fc4d/MyPrim.zip
Bon courage. :wink:

Steph3D ::.
01/06/2008, 19h55
Oki merci, alors la bonne nouvelle, c'est que j'arrive à compiler :bounce:
(semblerait que la maison d'olivier soit simplement incompatible avec le sdk 10.5 :|)

Après une semaine d'acharnement, j'arrive assez bien à me servir de VC++, je sais comment fonctionne les *. Lib, et pourquoi les *. a, etc...

Je posterais un projet au propre pour compiler sur PC quand j'aurais avancée, faut d'abord que je finisse de me taper les tuts C++ sur le siteduzero :mrgreen:

Apres pour coder un plug-in c++ sur C4D, c'est pas encor gagné :coup: j'ai deja peur pour la GUI :arg: