PDA

Voir la version complète : C++ : Fichiers RES et String non pris en compte



César Vonc
27/09/2015, 10h23
Salut,

Je me suis fait une nouvelle installation du système avec Win 7, C4D R13 à R17 et Visual Studio Express 2013 pour me renouer avec le C++.

Je n'ai eu aucun soucis à compiler les exemples du SDK de la R17 du premier coup après avoir tout installé (miracle), ni même mon nouveau module qui utilise la base de l'exemple Oatom, en suivant cette doc : https://developers.maxon.net/?p=81 .

Il apparaît bien dans C4D, génère bien un cube, mais on dirait que le fichier res de la description n'est pas chargé, ni le titre de l'objet qui se trouve dans c4d_strings.

En Python ça marchait très bien, mais là, j'ai juste l'icône de l'objet, pourtant j'ai bien mis le bon nom dans l'attribut description de RegisterObjectPlugin, je pige pas.


C'est sûrement une erreur toute bête mais je trouve pas. :icon_cry:


Voici comment se présente mon projet dans Visual Studio :

16250


Ce que j'ai dans C4D, seul le code fonctionne bien, pas de description ni de nom :

16249


Les fichiers sources :

main.h


#ifndef MAIN_H__
#define MAIN_H__

Bool EnregistreProc3Durale(void);

#endif // MAIN_H__


main.cpp


#include "c4d.h"
#include "main.h"

Bool PluginStart(void)
{
if (!EnregistreProc3Durale())
return false;
return true;
}

void PluginEnd(void)
{
}

Bool PluginMessage(Int32 id, void *data)
{
return false;
}


vonc_proc3durale.cpp


#include "c4d.h"
#include "c4d_symbols.h"
#include "vonc_proc3durale.h"
#include "main.h"

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

virtual BaseObject* GetVirtualObjects(BaseObject* op, HierarchyHelp* hh);
virtual Bool Message(GeListNode* node, Int32 type, void* t_data);

static NodeData* Alloc(void) { return NewObjClear(Proc3DuraleObjet); }
};

Bool Proc3DuraleObjet::Init(GeListNode* node)
{
//BaseObject* op = (BaseObject*)node;
//BaseContainer* data = op->GetDataInstance();
return true;
}

Bool Proc3DuraleObjet::Message(GeListNode* node, Int32 type, void* t_data)
{
if (type == MSG_DESCRIPTION_VALIDATE) {
BaseContainer* data = ((BaseObject*)node)->GetDataInstance();
}
return true;
}

BaseObject* Proc3DuraleObjet::GetVirtualObjects(BaseObject* op, HierarchyHelp* hh)
{
BaseObject* orig = op->GetDown();

if (!orig) return nullptr;

Bool dirty = false;
BaseObject* main = nullptr, *res = op->GetAndCheckHierarchyClone(hh, orig, HIERARCHYCLONEFLAGS_ASPOLY, &dirty, nullptr, false);

if (!dirty) return res;
if (!res) return nullptr;

main = BaseObject::Alloc(Ocube);
if (!main) goto error;

blDelete(res);
return main;

error:
blDelete(res);
blDelete(main);
return nullptr;
}

#define MODULE_ID 1035788

//----------------------------------------------------------------------------------------
/// Plugin help support callback. Can be used to display context sensitive help when the
/// user selects "Show Help" for an object or attribute. <B>Only return true for your own
/// object types</B>. All names are always uppercase.
/// @param[in] opType Object type name, for example "OATOM".
/// @param[in] baseType Name of base object type that opType is derived from, usually the same as opType.
/// @param[in] group Name of group in the attribute manager, for example "ID_OBJECTPROPERTIES".
/// @param[in] property Name of the object property, for example "ATOMOBJECT_SINGLE";
/// @return True if the plugin can display help for this request.
//----------------------------------------------------------------------------------------
static Bool Proc3DuraleAide(const String& opType, const String& baseType, const String& group, const String& property)
{
// Make sure that your object type name is unique and only return true if this is really your object type name and you are able to present a decent help.
if (opType == "vonc_proc3durale") {
GeOutString("If you implement custom object help, please use something better than GeOutString.", GEMB_OK);
return true;
}
else {
// You might handle more than one of your object/command/plugin types in one delegate ...
}
return false;
}

Bool EnregistreProc3Durale(void)
{
if (RegisterPluginHelpDelegate(MODULE_ID, Proc3DuraleAide) == false) return false;

return RegisterObjectPlugin(MODULE_ID, GeLoadString(VONC_PROC3DURALE_NOM), OBJECT_GENERATOR | OBJECT_INPUT, Proc3DuraleObjet::Alloc, "vonc_proc3durale", AutoBitmap("vonc_proc3durale.tif"), 0);
}


res/c4d_symbols.h


enum
{
VONC_PROC3DURALE_NOM = 1000,
_DUMMY_ELEMENT_
};


res/strings_fr/c4d_strings.str


STRINGTABLE
{
VONC_PROC3DURALE_NOM "Proc3Durale 2";
}



res/strings_fr/description/vonc_proc3durale.str


STRINGTABLE vonc_proc3durale
{
vonc_proc3durale "Proc3Durale 2";

VONC_PROC3DURALE_PREC "Subdivision (Vue)";
VONC_PROC3DURALE_MAT "Mati_re";
VONC_PROC3DURALE_PRECR "Subdivision (Rendu)";
VONC_PROC3DURALE_BORDS "Bordures";
VONC_PROC3DURALE_LISSAGE "Lisser";
VONC_PROC3DURALE_LISSITE "It_rations";
VONC_PROC3DURALE_LUMI "Luminosit_";
VONC_PROC3DURALE_INV "Inverser";
VONC_PROC3DURALE_BORIG "Rigidit_ des bordures";
VONC_PROC3DURALE_BORPHONG "Cassure Phong des bordures";
VONC_PROC3DURALE_TAILLE "Taille";
VONC_PROC3DURALE_DECALAGE "D_calage";
VONC_PROC3DURALE_ECHELLE "_chelle";
VONC_PROC3DURALE_ANIME "Anim_";
VONC_PROC3DURALE_MAJAUTO "Actualisation auto";
VONC_PROC3DURALE_MAJ "Actualiser";
}


res/description/vonc_proc3durale.h


#ifndef _vonc_proc3durale_H_
#define _vonc_proc3durale_H_

enum
{
VONC_PROC3DURALE_PREC = 1000,
VONC_PROC3DURALE_MAT = 1001,
VONC_PROC3DURALE_PRECR = 1002,
VONC_PROC3DURALE_BORDS = 1003,
VONC_PROC3DURALE_LISSAGE = 1004,
VONC_PROC3DURALE_LISSITE = 1005,
VONC_PROC3DURALE_LUMI = 1006,
VONC_PROC3DURALE_INV = 1007,
VONC_PROC3DURALE_BORIG = 1008,
VONC_PROC3DURALE_BORPHONG = 1009,
VONC_PROC3DURALE_TAILLE = 1010,
VONC_PROC3DURALE_DECALAGE = 1011,
VONC_PROC3DURALE_ECHELLE = 1012,
VONC_PROC3DURALE_ANIME = 1013,
VONC_PROC3DURALE_MAJAUTO = 1014,
VONC_PROC3DURALE_MAJ = 1015
};

#endif


res/description/vonc_proc3durale.res


CONTAINER vonc_proc3durale
{
NAME vonc_proc3durale;
INCLUDE Obase;

GROUP ID_OBJECTPROPERTIES
{
VECTOR VONC_PROC3DURALE_TAILLE { UNIT METER; }
VECTOR VONC_PROC3DURALE_DECALAGE { UNIT METER; }
VECTOR VONC_PROC3DURALE_ECHELLE { UNIT PERCENT; }
SEPARATOR { LINE; }
REAL VONC_PROC3DURALE_PREC { UNIT METER; MIN 1.0; }
REAL VONC_PROC3DURALE_PRECR { UNIT METER; MIN 1.0; }
SEPARATOR { LINE; }
GROUP {
COLUMNS 3;
BUTTON VONC_PROC3DURALE_MAJ { }
BOOL VONC_PROC3DURALE_MAJAUTO { }
BOOL VONC_PROC3DURALE_ANIME { }
}
SEPARATOR { LINE; }
REAL VONC_PROC3DURALE_LUMI { UNIT PERCENT; MIN -100.0; MAX 100.0; STEP 1.0; CUSTOMGUI REALSLIDER; }
BOOL VONC_PROC3DURALE_INV { }
SEPARATOR { LINE; }
BOOL VONC_PROC3DURALE_BORDS { }
BOOL VONC_PROC3DURALE_BORPHONG { }
SEPARATOR { LINE; }
REAL VONC_PROC3DURALE_LISSAGE { UNIT PERCENT; MIN 0.0; MAX 100.0; STEP 1.0; CUSTOMGUI REALSLIDER; }
LONG VONC_PROC3DURALE_LISSITE { MIN 0; }
REAL VONC_PROC3DURALE_BORIG { UNIT PERCENT; MIN 0.0; MAX 100.0; STEP 1.0; CUSTOMGUI REALSLIDER; }
SEPARATOR { LINE; }
SEPARATOR { LINE; }
SHADERLINK VONC_PROC3DURALE_MAT { }
}
}

valkaari
27/09/2015, 18h40
Je changerais le nom du fichier res si j'étais toi. Quand tu lances la commande registerObjectPlugin tu lui spécifie le nom du fichier res. (comme tu sais)

Je sais pas comment il vas réagir quand tu fais un include vonc_proc3durale
Lequel il vas prendre ? celui de ton programme ou celui de l'interface. (puisque tu as un vonc_proc3durale.cpp et un vonc_proc3durale.h dans ton répertoire source)

Il y a un façon de nommer tes fichiers dans c4d (https://developers.maxon.net/docs/Cinema4DCPPSDK/html/page_description_resource.html#section_description resource_namingconvention) tu devrais utiliser Ovoncproc3durale.res, .h et .str


Quand j'ai le même type de soucis c'est que le nom de fichier sur le disque ne corresponds pas à celui que j'ai donné dans le fichier c++ (majuscule/minuscule, orthographe)

César Vonc
27/09/2015, 20h51
Oui en effet, j'ai remplacé par Ovoncproc3durale les fichiers res, h et str.

Hélas le problème persiste.

Même le GeLoadString(VONC_PROC3DURALE_NOM) ne semble pas charger le titre dans c4d_strings.str, qui ne dépend pas du nom donné pour les fichiers de description.

valkaari
27/09/2015, 23h12
Je supprimerais le c4d_symbol.h de ton projet. Le projet est configuré pour aller chercher dans le répertoire res.

sinon je vois pas trop mis à part un problème dans l'arborescence du répertoire res


et t'as même pas un message d'insulte dans la console ?

César Vonc
28/09/2015, 18h27
D'accord pour le .h.


Eh non, rien du tout dans la console. : /


J'espère que c'est pas lié à la R17. En même temps j'ai pu compiler les exemples du SDK donc il n'y a priori pas de soucis de ce côté là.


C'est bête d'être bloqué sur ça. :icon_banghead:

valkaari
28/09/2015, 18h52
Sinon envoie moi ton projet. C'est surement un truc tout con à coté duquel t'es passé 50 fois sans le voir. (comme tous les problèmes à la con qu'on rencontre quand on code)


ceci dit me semble que s'il ne trouve pas le fichier de langue, il met "stringnotfound" ce qu'il ne mets même pas.....

César Vonc
28/09/2015, 21h44
Oui, d'habitude C4D hésite pas à hurler quand quelque chose ne va pas. Là, je suis offensé par son silence méprisant. : p

Merci pour ton temps sur le problème, voici l'archive. ^^


PS : Dans le Init, j'ai laissé deux GeOutString qui affichent à l'écran le nom censé être chargé du module.

valkaari
29/09/2015, 00h11
ben voilà la solution était là mais en fait non ^^


dans ton fichier main.cpp (que je n'avais même pas regardé)




Bool PluginMessage(Int32 id, void *data)
{
switch (id)
{
case C4DPL_INIT_SYS:
if (!resource.Init())
return false; // don't start plugin without resource


}


return false;
}



Je comprends ça comme le fait de dire à cinema4D d'attendre d'avoir charger les fichiers ressources de tous les plugins. Mais officiellement j'en sais rien ^^

César Vonc
29/09/2015, 20h21
Alors là je trouve ça fourbe car dans le main.cpp des exemples du SDK, tout en haut est écrit, en commentaire, à quoi ressemble un module vierge, or le PluginMessage renvoie juste false.


Bon, certes j'aurais dû copier un exemple complet. : p



En tout cas bravo et merci infiniment Val, ça marche impec, maintenant !

xs_yann
29/09/2015, 22h34
Salut,

C'est vrai que l'exemple donné dans cinema4dsdk est mauvais.
En fait quand tu inclus c4d.h, il inclus lui même c4d_resource.h qui déclare une variable globale resource de la classe GeResource :


extern GeResource resource;

https://developers.maxon.net/docs/Cinema4DCPPSDK/html/c4d__resource_8h.html

Il faut initialiser cet object avec Init(const Filename & path, Bool regardIsStopped = true) ou Init().

Mais le main du SDK n'est pas tout à fait mieux parce qu'il serait plus logique de faire :



Bool PluginStart()
{
if (!resource.Init()) // don't start plugin without resource
return false;

if (!EnregistreProc3Durale())
return false;

return true;
}

Bool PluginMessage(Int32 id, void *data)
{
return false;
}


Comme indiqué ici :
https://developers.maxon.net/docs/Cinema4DCPPSDK/html/c4d__plugin_8h.html#af22b8ef1034a96db62a920545afdb bda

Et si tu utilises PluginMessage, selon la doc le code devrait être :



Bool PluginMessage(Int32 id, void *data)
{
switch (id)
{
case C4DPL_INIT_SYS:
resource.Init();
return true;
}
return false;
}


Puisque la valeur de retour ne sert pas à charger ou non le plugin mais à dire si le message a été utilisé.

valkaari
29/09/2015, 23h36
et soudain une lumière ...


C'est vrai que si c'est à ce point obligatoire, le mettre dans PluginStart me semble bien plus logique. En plus le commentaire "don't startplugin without ressource" prends tout son sens.

Mais alors il semblerait qu'ils aient déplacé cette ligne dans Message() ...


Est ce qu'on devrait pas ouvrir un "problème" sur github ?
https://github.com/PluginCafe/cinema4d_cpp_sdk