How to concatenate operators in a pie menu

Hi all,

following this short thread, I have another problem.
I am building a pie menu with all possible extrusion types - among them is “mesh.extrude_region_move” which is actually in two parts : MESH_OT_extrude_region and TRANSFORM_OT_translate. How do I make them into one operator and how do I specify their arguments ?

Right now this is what I have :

        extrude_normal_average_op = pie.operator("mesh.extrude_region_move", "transform.translate", text="Extrude straight")
        extrude_normal_average_op.constraint_axis=(False, False, True)
        extrude_normal_average_op.constraint_orientation='NORMAL'

After a little investigation I’m seing that “loopcut and slide” is also built this way - this is what appears in the info window after using that tool :

bpy.ops.mesh.loopcut_slide(MESH_OT_loopcut={"number_cuts":1, "smoothness":0, "falloff":'INVERSE_SQUARE', "edge_index":46620, "mesh_select_mode_init":(False, False, True)}, TRANSFORM_OT_edge_slide={"value":-0.417855, "single_side":False, "use_even":False, "flipped":False, "use_clamp":True, "mirror":False, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "correct_uv":False, "release_confirm":False})

I think my problem is mostly a syntax problem.

Hadrien

>>I have another problem.
but what is your problem? You don’t say it!

Hi Spirou,

like I said I want to make a pie menu item with the “extrude_region_move” command, but I can’t get it to work because it is made of two distinct operators : extrude and move. I don’t know where to specify the arguments “constraint axis” and “constraint orientation” (respectively False, False, True and ‘NORMAL’).

In the link above zeffii taught me I had to store arguments in their own variable under a new operator object, so that’s what I did, but what if I have two operators whose arguments I have to specify, and execute them in order ?

Any idea ?

you want use this option:
“constraint axis”= (False, False, True)
+
“constraint orientation”= ‘NORMAL’

and your function is:


bpy.ops.mesh.loopcut_slide(MESH_OT_loopcut={"number_cuts":1,
                                            "smoothness":0,
                                            "falloff":'INVERSE_SQUARE',
                                            "edge_index":46620,
                                            "mesh_select_mode_init":(False, False, True)}, \
                            TRANSFORM_OT_edge_slide={"value":-0.417855,
                                                    "single_side":False,
                                                    "use_even":False,
                                                    "flipped":False,
                                                    "use_clamp":True,
                                                    "mirror":False,
                                                    "snap":False,
                                                    "snap_target":'CLOSEST',
                                                    "snap_point":(0, 0, 0),
                                                    "snap_align":False,
                                                    "snap_normal":(0, 0, 0),
                                                    "correct_uv":False,
                                                    "release_confirm":False}
                                                    )

There are something weird here! Are you sure that operator use “constraint axis”= (False, False, True) and
“constraint orientation”= ‘NORMAL’

The slide function use the snap help! may be this:


bpy.ops.mesh.loopcut_slide(MESH_OT_loopcut={"number_cuts":1,
                                            "smoothness":0,
                                            "falloff":'INVERSE_SQUARE',
                                            "edge_index":46620,
                                            "mesh_select_mode_init":(False, False, True)}, \
                            TRANSFORM_OT_edge_slide={"value":-0.417855,
                                                    "single_side":False,
                                                    "use_even":False,
                                                    "flipped":False,
                                                    "use_clamp":True,
                                                    "mirror":False,
                                                    "snap":True,
                                                    "snap_target":'NORMAL',
                                                    "snap_point":(0, 0, 0),
                                                    "snap_align":False,
                                                    "snap_normal":(0, 0, 1),
                                                    "correct_uv":False,
                                                    "release_confirm":False}
                                                    )

May be "mesh_select_mode_init is ok for “constraint axis”= (False, False, True)?

(si je t’explique rapidement, ce que tu vois est la listes des variable internes des fonctions, tu n’est pas obligé de toutes les écrire puisque que ce sont des valeurs par défaut donc avec seulement ça:


bpy.ops.mesh.loopcut_slide(MESH_OT_loopcut={"mesh_select_mode_init":(False, False, True)}, \
                            TRANSFORM_OT_edge_slide={"snap":True,
                                                    "snap_target":'NORMAL',
                                                    "snap_normal":(0, 0, 1)}
                                                    )

Essaie pour voir!

Ha! j’ai compris ton erreur: tu parles de extrude & move mais tu as trouvé l’opérateur pour faire des coupes en boucle ce n’est pas la même chose!
“bpy.ops.mesh.loopcut_slide” n’est pas “bpy.ops.mesh.extrude_region_move”

voici la bonne function:


bpy.ops.mesh.extrude_region_move(
            MESH_OT_extrude_region, \
            TRANSFORM_OT_translate={
                                    "constraint_axis":(False, False, True),
                                    "constraint_orientation":'Normal'}
                                    )

Donc si je poursuis:
pie.operator(“mesh.extrude_region_move”, “transform.translate”, text=“Extrude straight”)

Alors là c’est faux!
pie.operator(OPERATOR ,TEXT ,ICON)

donc


pie.operator("mesh.extrude_region_move(MESH_OT_extrude_region, TRANSFORM_OT_translate={"constraint_axis":(False, False, True), "constraint_orientation":'Normal'})", text="Extrude straight")

Au temps pour moi, je parlais de loopcut&slide à titre d’exemple.

J’ai essayé ton dernier code, mais Blender ne le comprend pas manifestement (absence de réaction, pas d’erreur) - la coloration syntaxique me laissait penser que c’était peut-être un problème de guillemets, alors j’ai essayé de bidouiller ça mais sans succès.

Merci de ton aide !

Pour clarifier, en français : je veux créer un pie menu item qui déclenche l’extrusion standard, toute droite sur la normale de la face. En interne Blender fait ça en invoquant d’abord l’extrusion puis le translate verrouillé sur Z en normale. zeffii m’a montré que pour spécifier plusieurs arguments pour un opérateur il fallait les écrire en dessous en les stockant chacun dans leur variable, mais là, comme j’ai en fait deux opérateurs concaténés, je n’arrive pas à savoir comment et où lui spécifier ces arguments. C’est pas évident à expliquer, mais tu vois ?

Il faudrait que je vois ton code pour te dire plus…

mesh.extrude_region_move(MESH_OT_extrude_region={“mirror”:False}, TRANSFORM_OT_translate={“constraint_axis”:(False, False, True),“constraint_orientation”:‘Normal’})

peut-être que ={“mirror”:False} était nécessaire, essaie de l’ajouter pour voir.

Voici un exemple de pie:


class VIEW3D_PIE_artistpaint(Menu):
    # label is displayed at the center of the pie menu.
    bl_label = "PAINTER"


    def draw(self, context):
        layout = self.layout
        
        pie = layout.menu_pie()
        #pie.operator("render.render", text='one')


        pie.operator("slots.projectpaint", text='Slots', icon='COLLAPSEMENU')
        pie.operator("paint.brush_popup", text='Paint Brush', icon='BRUSH_DATA')
        pie.operator("artist_paint.popup", text='Canvas Control', icon='TEXTURE')
        pie.operator("object.oper_nested", text='Drawtype', icon='CANCEL')

Est ce que tu respectes cette mise en forme, stp?

car la réponse de Zeffi est un peu vague pour toi:
pie.operator((“mesh.bevel”, text=“Bevel”).segments = 2
tu ne peux passer deux paramètres à la queue leu-leu car la fonction va s’executer quand? Un seul c’est possible mais pas deux.
Pour en passer plusieurs il faut que tu crées une class operateur avec paramètres.

Ben y’a pas de contexte, en fait, à part quelques pie menus qui marchent eux sans problème. L’ajout de ={“mirror”:False} ne change rien. Tiens, http://pastebin.com/7CvkXvkr -> cherche “mesh_extrude”.

C’est bien ce que je croyais tu as mis op1 =
moi je l’avais mis pour rester comme Zeffi mais c’est comme


pie.operator("mesh.extrude_region_move(MESH_OT_extrude_region, TRANSFORM_OT_translate={"constraint_axis":(False, False, True), "constraint_orientation":'Normal'})", text="Extrude straight")

Oui, je me suis basé sur l’addon officiel pour faire mes menus. J’ai remplacé la ligne par ton dernier bout de code mais toujours rien. :confused: Cette fois-ci Blender ne semble plus du tout reconnaître l’ensemble de l’addon (il ne m’affiche plus aucune pie)…

mais ton code n’a pas de raccourcie?

je suis en train d’essayer de le faire fonctionner…

Non je les mets depuis Blender, l’assignation auto me faisait des doublons… par exemple j’ai assigné VIEW3D_PIE_object au clic droit.

C’est ok! mais je ne sais si c’est ça que tu veux:
LINK

je t’ai mis la solution 1 que tu voulais et la solution 2 avec une function déjà existante.
Dans la solution 1 il n’y a pas dans la class de fonction poll(), tu dois la créer aussi en plus pour fonctionner seulement en mode edit, non?

j’ai mis le raccourcie Alt W pour les extusions.

Tu vois que la solution 2 n’a aucun paramètre mais surtout que c’est un operateur de VIEW3D et non de MESH ce qui veut dire que l’extrusion se fait en temp-réel.

Je voudrais bien savoir où tu as trouvé cette fonction, stp? Bizarre:
bpy.ops.mesh.extrude_region_move()

Merci ! Le premier opérateur fait une extrusion en laissant les nouvelles faces en place, c’est intéressant, pourquoi pas ? Le second, c’est exactement ce que j’avais en tête, c’est-à-dire une extrusion sur la normale.
Par contre, je ne comprends pas bien ce que tu as fait pour que ça marche. Je vais étudier ça.
C’est cool d’y avoir passé du temps, j’apprécie beaucoup.

Je dois t’avouer que je ne comprends pas du tout ce que ca veut dire…

Que veux-tu dire par “en temps réel” ? Chez moi ça se comporte exactement comme l’extrusion “basique”, hotkey E, c’est tout à fait ce que je cherchais à répliquer !

Dans la fenêtre d’info après avoir fait une extrusion, ou bien dans le tooltip au-dessus de “region” quand tu tapes alt+e.
Attends non, au temps pour moi, il y a mesh.extrude_faces_move et view3d.edit_mesh_extrude_move_normal, j’ai mélangé les deux. Je crois que je suis un peu dyslexique…

Je crois que j’ai compris ce que tu veux dire par “en temps réel” - au lieu d’être une opération instantanée comme un subdivide par exemple, c’est un truc qui demande un input de la souris ou du clavier, bref un truc qui s’ajuste, comme un transform, ou un shrink/fatten ?

Yes, absolutelly!

Bon dans mon fichier, la class que j’ai créé est bidon et j’ai repris le même nom de class que plus haut donc tu dois la créer proprement avec un nom propre si tu utilises cette méthode. C’est simplement un modèle d’astuce.
Ciao.
Spirou4D