Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

changed Color and added Colormaps #152

Merged
merged 18 commits into from
Dec 5, 2024

Conversation

godardma
Copy link
Collaborator

@godardma godardma commented Dec 2, 2024

@SimonRohou les test unitaires passent tous, j'ai juste dû autoriser des marges de tolérance dans les conversions (RGB/HSV, float/int ...).

Il y a juste un point qui me dérange un peu et que je n'ai pas réussi à résoudre :
Mettons qu'en python je veuille créer une couleur HSV, j'écrirais quelque chose de la forme :
Color(0, 100, 100, InterpolMode.HSV)

Seulement le casting automatique python préfère appeler ce constructeur en convertissant le char en int (pensé pour les couleurs HSVA et RGBA):
.def(py::init<int,int,int,int,InterpolMode>(),
Plutôt que celui prévu à cet effet :
.def(py::init<int,int,int,InterpolMode>(),

La solution que j'ai trouvée et d'écrire :
Color(0, 100, 100, interpol_mode=InterpolMode.HSV)

Mais je me demande si il n'y a pas moyen de faire mieux

@godardma
Copy link
Collaborator Author

godardma commented Dec 3, 2024

Comme il n'y a pas d'urgence à accepter cette PR je passerai à l'occasion sur les codes afin d'uniformiser les notations et d'ajouter de commentaires. Si des parties ne te semblent pas claires et te semblent mériter une attention particulière n'hésite pas à commenter la PR !

@SimonRohou
Copy link
Member

Merci pour ta proposition !

J'ai fait quelques observations mais je te laisse décider.

Pour l'ambiguité du mode RGB/HSV converti en alpha, effectivement il faut éviter ça. Le plus simple c'est d'utiliser les std::array en argument des constructeurs (donc limiter les formes d'instanciations possibles). Ce qui au passage simplifie tout le reste (moins de constructeurs = plus de simplicité).

Voir aussi les héritages Color -> std::array<float,4> et ColorMap -> std::map<float,Color>.

@godardma
Copy link
Collaborator Author

godardma commented Dec 3, 2024

A priori il ne me reste plus qu'à modifier les TU et ça devrait être bon. Il y a juste une chose notable :
l'enum Model étant définie dans la struct Color, pour appeler RGB (ou HSV) depuis un code il faute faire:
en C++ : Color::RGB
en python : Model.RGB

Je suis pas fan de cette différence, il y a peut-être une modif à apporter au binding ?

@SimonRohou
Copy link
Member

lenum Model étant définie dans la struct Color, pour appeler RGB (ou HSV) depuis un code il faute faire: en C++ : Color::RGB en python : Model.RGB

Je suis pas fan de cette différence, il y a peut-être une modif à apporter au binding ?

Effectivement c'est pas top.
Après une courte recherche il semble ne pas y avoir de solution propre :
pybind/pybind11#1868

Alors peut-être nommer l'énumération "Model" et la place en dehors de la classe Color, pour que ce soit cohérent des deux côtés...

@godardma
Copy link
Collaborator Author

godardma commented Dec 3, 2024

Alors peut-être nommer l'énumération "Model" et la place en dehors de la classe Color, pour que ce soit cohérent des deux côtés...

Je suis parti sur cette solution du coup. Tous les tests passent de mon côté (C++ et python)

Si je n'ai rien raté j'ai tenu compte de tous tes commentaires. Si certains sont passés à travers les mailles du filet n'hésite pas à réouvrir le commentaire associé.

@SimonRohou
Copy link
Member

C'est super ! 👍
Merci pour ton travail !

Je me suis permis quelques petites discussions (voir plus bas) mais on peut clore cette PR 👍
Il y a juste deux tests qui ne passent pas (macosmatrix.yml et tests.yml), je t'ai proposé une piste.

py::class_<ColorMap> exported_colormap(m, "ColorMap", COLORMAP_MAIN);
exported_colormap

.def_readwrite("m", &ColorMap::m,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

À supprimer (voir plus bas)

explicit Color(float r, float g, float b, float alpha = 1.);
explicit Color(int r, int g, int b, int alpha = 255);

Model m = Model::RGB; //RGB or HSV
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Idéalement il faudrait que ce soit const et protected (sinon l'utilisateur peut changer le mode et mettre des valeurs incohérentes avec le mode). Mais il faudrait aussi rendre float& std::array<float,4>::operator[](size_t) en protected (ne laisser que son équivalent const en public) pour qu'une Color ne soit pas éditable. Bref c'est pas critique vu l'usage qu'on en fait :)
C'est juste pour info.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Passer le Model en const protected semble poser des problèmes pour les ColorMap.
De ma compréhension quand on fait :
map[key]=value;
Si la clé n'existe pas il crée d'abord la paire (key,value) en utilisant le constructeur par défaut (ici le constructeur Color::Color()) puis fais l'affectation de la couleur ... ce qui se passe mal vu que le Model est déjà défini dans le constructeur par défaut
Compromis : j'ai mis le Model m en protected avec un accesseur en read-only model()

Copy link
Collaborator Author

@godardma godardma Dec 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pour ce qui est de protéger le tableau de valeur, définir deux operateurs [] semble lourd point de vue utilisateur car besoin de spécifier const float x= color[i] à chaque fois, sinon message d'erreur car C++ pense qu'on souhaite attaquer l'opérateur protégé (non const)

Color color_lb = prev(it_ub)->second;
Color color_ub = it_ub->second;

// Interpolation according to the ColorMap model
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

J'aurais supprimé les lignes 36 à 48 : l'interpolation se fait dans l'espace de couleur défini par ses points de contrôles. Si la CM est faite de Color en HSV, alors l'interpolation est en HSV, et réciproquement pour le RGB.

Copy link
Collaborator Author

@godardma godardma Dec 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

J'y ai pensé, mais le problème est que rien n'empêche un utilisateur de créer sa propre ColorMap avec des couleurs en RGB et d'autres en HSV, auquel cas il faut convertir tout dans le même type avant interpolation .

Edit :
Ou alors on suppose/force que toutes les couleurs sont au même format

*/
struct ColorMap : public std::map<float,Color>
{
Model m; //RGB or HSV
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Et donc plus besoin de cet attribut.

@godardma
Copy link
Collaborator Author

godardma commented Dec 4, 2024

Je me suis mal exprimé hier, *tous les test unitaires passent de mon côté. j'ai tenté un nouveau commit avec le changement que tu as suggéré on va voir si les actions git passent

@godardma
Copy link
Collaborator Author

godardma commented Dec 4, 2024

Bien vu, tous les tests passent !

@SimonRohou SimonRohou merged commit e782e7f into codac-team:codac2_dev Dec 5, 2024
61 checks passed
@SimonRohou
Copy link
Member

👍 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants