PDA

Voir la version complète : Python - Coquilles et bogues



César Vonc
23/09/2013, 12h22
Je propose de tenir un sujet de référencement des bogues en tout genre liés à la programmation Python, afin de ne pas submerger le sujet de référencement général de fragments de codes pas très explicites.

Le but est non seulement de référencer les problèmes connus afin d'éviter toute perte de temps, mais également proposer des solutions de secours.

S'il est également possible de rapporter ces coquilles pour une future correction, ce ne serait évidemment pas plus mal. ^^


--

Vector.__rxor__ : (http://frenchcinema4d.fr/#post1018268)Opérateur erroné (http://frenchcinema4d.fr/showthread.php?77126-Python-Coquilles-et-bogues&p=1018268&viewfull=1#post1018268)
(http://frenchcinema4d.fr/#post1018268)BaseObject.CopyTagsTo : (http://frenchcinema4d.fr/#post1018268)Description erronée (http://frenchcinema4d.fr/showthread.php?77126-Python-Coquilles-et-bogues&p=1018268&viewfull=1#post1018268)
(http://frenchcinema4d.fr/#post1018268)BaseDraw.GetEditorCamera : (http://frenchcinema4d.fr/#post1018268)Argument erroné (http://frenchcinema4d.fr/showthread.php?77126-Python-Coquilles-et-bogues&p=1018268&viewfull=1#post1018268)
(http://frenchcinema4d.fr/#post1018268)ViewportSelect.GetPixelInfoPolygon : (http://frenchcinema4d.fr/#post1018268)Exemple erroné (http://frenchcinema4d.fr/showthread.php?77126-Python-Coquilles-et-bogues&p=1018268&viewfull=1#post1018268)
(http://frenchcinema4d.fr/#post1018268)SendModelingCommand MCOMMAND_SPLIT : (http://frenchcinema4d.fr/#post1018268)Description incomplète (http://frenchcinema4d.fr/showthread.php?77126-Python-Coquilles-et-bogues&p=1018268&viewfull=1#post1018268)
(http://frenchcinema4d.fr/#post1018268)SendModelingCommand MCOMMAND_JOIN : (http://frenchcinema4d.fr/#post1018268)Fonction boguée (http://frenchcinema4d.fr/showthread.php?77126-Python-Coquilles-et-bogues&p=1018268&viewfull=1#post1018268)
(http://frenchcinema4d.fr/#post1018268)Offd : (http://frenchcinema4d.fr/#post1018268)Taille boguée (http://frenchcinema4d.fr/showthread.php?77126-Python-Coquilles-et-bogues&p=1018268&viewfull=1#post1018268)
GvPort.SetName(name) (http://frenchcinema4d.fr/#post1040243) : Fonction boguée
(http://frenchcinema4d.fr/showthread.php?77126-Python-Coquilles-et-bogues&p=1040243&viewfull=1#post1040243)GvNode.AddPort(c4d.GV_PORT_ INPUT, c4d.GV_OBJECT_OPERATOR_OBJECT_IN) (http://frenchcinema4d.fr/#post1040243) : Fonction boguée
(http://frenchcinema4d.fr/showthread.php?77126-Python-Coquilles-et-bogues&p=1040243&viewfull=1#post1040243)GvNode.SetPortType(port, id) (http://frenchcinema4d.fr/#post1040243) : Fonction boguée (http://frenchcinema4d.fr/showthread.php?77126-Python-Coquilles-et-bogues&p=1040243&viewfull=1#post1040243)
(http://frenchcinema4d.fr/#post1040243)


--


R15.037 - Vector.__rxor__(self, other)

L'opérateur % entre deux vecteurs ne renvoie pas la multiplication entre chaque composant du vecteur mais le produit vectoriel.

v = c4d.Vector(1,2,3) % c4d.Vector(2,3,4) # Vector(-1, 2, -1)
Solution :

v = c4d.Vector(1,2,3).__rxor__(c4d.Vector(2,3,4)) # Vector(2, 6, 12)


--


R15.037 - BaseObject.CopyTagsTo(dest, visible, variable, hierarchial)

Description erronée :

Set the ip of the object.


--


R15.037 - BaseDraw.GetEditorCamera(doc)

Retourne une erreur à cause de l'argument doc.

bd = doc.GetActiveBaseDraw()
camera = bd.GetEditorCamera(doc) # TypeError: GetEditorCamera() takes no arguments (1 given)
Solution :

bd = doc.GetActiveBaseDraw()
camera = bd.GetEditorCamera()


--


R15.037 - ViewportSelect.GetPixelInfoPolygon(x, y)

L'exemple utilise GetPixelInfoPoint au lieu de GetPixelInfoPolygon.

infopoint = viewportselect.GetPixelInfoPoint(x, y)


--


R15.037 - c4d.utils.SendModelingCommand(command, list[, mode=MODIFY_ALL[, bc[, doc[, flags]]]]) - MCOMMAND_SPLIT

Manque de précision : la commande MCOMMAND_SPLIT renvoie une liste d'objets.


--


R15.037 - c4d.utils.SendModelingCommand(command, list[, mode=MODIFY_ALL[, bc[, doc[, flags]]]]) - MCOMMAND_JOIN

La commande MCOMMAND_JOIN unit tous les objets de la même hiérarchie se trouvant après le premier objet de la liste.
Les coordonnées du nouvel objet obtenu sont les mêmes que celles du premier objet de la liste, alors que pour correspondre aux anciens objets, ces coordonnées doivent être nulles.

# Créez au préalable trois objets éditables

op = doc.GetFirstObject()
op2 = op.GetNext()
ops = [op, op2]
res = c4d.utils.SendModelingCommand(command = c4d.MCOMMAND_JOIN,
list = ops,
doc = doc)

if res : doc.InsertObject(res[0]) # Les trois objets sont unis et décalés
c4d.EventAdd()
Solution :

Créer virtuellement un objet neutre dans lequel placer les objets à unir.

# Créez au préalable trois objets éditables

op = doc.GetFirstObject()
op2 = op.GetNext()
ops = [op, op2]

neutre = c4d.BaseObject(c4d.Onull)
for obj in ops : obj.GetClone().InsertUnder(neutre)

res = c4d.utils.SendModelingCommand(command = c4d.MCOMMAND_JOIN,
list = [neutre],
doc = doc)

if res : doc.InsertObject(res[0]) # Les deux objets sont unis et correctement positionnés
c4d.EventAdd()


--


R15.037 - Offd (Déformation libre)

Impossible de définir la taille de la grille, bien que le champ soit modifiable.

obj = c4d.BaseObject(c4d.Offd)
obj[c4d.FFDOBJECT_SIZE] = c4d.Vector(10.0) # Valeur modifiée, mais visuellement à sa valeur par défaut (300).
doc.InsertObject(obj)
c4d.EventAdd()

Solution :

Proposée par xs_yann (http://frenchcinema4d.fr/showthread.php?77126-Python-Coquilles-et-bogues&p=1018269&viewfull=1#post1018269) : Mettre à jour manuellement la propriété c4d.Tpoint.

xs_yann
23/09/2013, 13h10
Salut,

Très bonne idée ce topic César.

Pour le FFD j'avais posté la solution sur plugincafe.
En fait c'est le PointTag qui n'est pas mis à jour correctement.
Il faut donc :

1. Récupérer le PointTag
2. Récupérer les positions des points dans le PointTag
3. Multiplier toutes les positions par un facteur taille.
4. Mettre la taille correspondante dans les paramètres du FFD


import c4d

def setFFDSize(ffd, size):
tag = ffd.GetTag(c4d.Tpoint) # 1
points = tag.GetAllHighlevelData() # 2
oldSize = ffd[c4d.FFDOBJECT_SIZE]
scaleFactor = c4d.Vector(size.x / oldSize.x, size.y / oldSize.y, size.z / oldSize.z)
for i, point in enumerate(points):
points[i].x *= scaleFactor.x # 3
points[i].y *= scaleFactor.y
points[i].z *= scaleFactor.z
tag.SetAllHighlevelData(points)
ffd[c4d.FFDOBJECT_SIZE] = size # 4

ffd.Message(c4d.MSG_UPDATE)


def main():
setFFDSize(doc.GetActiveObject(), c4d.Vector(1200, 350, 100))
c4d.EventAdd()


if __name__=='__main__':
main()

César Vonc
23/09/2013, 13h36
Oh, merci Yann, c'est parfait, fallait le trouver !

J'ajoute un lien vers ton message en solution.

César Vonc
12/10/2013, 10h59
Nouvelle prise de tête qui m'a coûté une soirée, encore avec SendModelingCommand, j'ignore si c'est un bogue ou juste un truc à savoir, mais si vous utilisez la commande MCOMMAND_MAKEEDITABLE, votre objet doit se trouver dans le document avant puis être réinséré après.

Ce qui est contraire, par exemple, à la commande MCOMMAND_CURRENTSTATETOOBJECT qui ne nécessite pas d'avoir l'objet dans le doc pour son exécution.


import c4d

def main():
obj = c4d.BaseObject(c4d.Osplinecircle)

doc.InsertObject(obj) # Indispensable

ret = c4d.utils.SendModelingCommand(
command=c4d.MCOMMAND_MAKEEDITABLE, list=[obj], doc=doc)

if ret : doc.InsertObject(ret[0])

c4d.EventAdd()

if __name__=='__main__':
main()

valkaari
13/10/2013, 20h16
d'après la doc


The document for the operation. Should be set if possible. Must be set for MCOMMAND_MAKEEDITABLE, MCOMMAND_CURRENTSTATETOOBJECT and MCOMMAND_SPLINE_PROJECT.

Donc c'est un fonctionnement "prévu"

A la rigueur c'est le currestate qui ne fonctionne pas comme prévu si tu ne spécifie pas le document.

Par contre il y a des commandes qui nécessitent de réinsérer l'objet dans le document et d'autre non. Insérer un objet dans un document ça prend du temps, donc c'est pas forcement un mal qu'il ne le fasse pas à tous les coups.

Le problème, et je te rejoins dans ta remarque, c'est que toutes les fonctions n'ont pas le même comportement, et parfois c'est une perte de temps et une prise de tête très importante.

xs_yann
01/10/2014, 15h05
R15.008 - GvPort.SetName(name)

GvPort.SetName(name) modifie le nom du noeud parent (GvNode) au lieu de celui du port.

xpresso = c4d.BaseTag(c4d.Texpresso)
op.InsertTag(xpresso)
master = xpresso.GetNodeMaster()
python_node = master.CreateNode(master.GetRoot(), ID_OPERATOR_PYTHON)
python_node.RemoveUnusedPorts()
port = python_node.AddPort(c4d.GV_PORT_OUTPUT, c4d.OUT_STRING)
port.SetName("Foobar")


--


R15.008 - GvNode.AddPort(c4d.GV_PORT_INPUT, c4d.GV_OBJECT_OPERATOR_OBJECT_IN)

Impossible d'ajouter un port objet sur un noeud objet (ni en entrée, ni en sortie).


object_node = master.CreateNode(master.GetRoot(), c4d.ID_OPERATOR_OBJECT)
object_node[c4d.GV_OBJECT_OBJECT_ID] = op
object_node.AddPort(c4d.GV_PORT_INPUT, c4d.GV_OBJECT_OPERATOR_OBJECT_IN)

Solution :

Proposée sur plugincafe : Créer une donnée utilisateur de type lien vers l'objet. Ce n'est pas très élégant mais ça fonctionne.


bc = c4d.GetCustomDataTypeDefault(c4d.DTYPE_BASELISTLIN K)
bc[c4d.DESC_NAME] = "Object"
bc[c4d.DESC_SHORT_NAME] = "Object"
bc[c4d.DESC_DEFAULT] = op
ud = op.AddUserData(bc)
op[ud] = op
object_node.AddPort(c4d.GV_PORT_INPUT, ud)


--


R15.008 - GvNode.SetPortType(port, id)

GvNode.SetPortType(port, id) ne change pas le type du port.

Solution :

Faire un appel à GvNode.AddPort avant avec le même type.


python_node.AddPort(c4d.GV_PORT_OUTPUT, c4d.OUT_STRING)
output_port = python_node.GetOutPort(0)
python_node.SetPortType(output_port, c4d.OUT_STRING)

César Vonc
08/10/2014, 21h29
Merci pour le partage, Yann !

J'ai mis à jour le premier message du sujet.

lenogre
08/10/2014, 22h42
Je vous admire les gars !
La moindre ligne de code me fait fuir. Une ligne de basse ok, mais une ligne de code, c'est de la torture pour moi.
Quant à la ligne de coke, ça m'a jamais tenté.

oli_d
24/09/2015, 08h05
La classe Vector a une curieuse façon d'arrondir les float :



import c4d

def main():
v = c4d.Vector(1094854.6949,1094854.6949,1094854.6949)
print v
print v.x
print v.y
print v.z

if __name__=='__main__':
main()

qui me donne dans la console :

Vector(1094854.695, 1094854.75, 1094854.75)
1094854.6949
1094854.75
1094854.75

En x tout se passe bien, par contre en y et z, il arrondi de façon bizarre.

Vous me direz que ça ne fait que 5.5 cm de différence sur plus d'un million de mètres, mais pour un homme 5 cm c'est important ...

J'ai testé r16 et r17, c'est la même chose. Est-ce que quelqu'un peut me confirmer ?

valkaari
24/09/2015, 15h27
16228

j'ai testé sur la r17 osx. J'ai la même chose. (ce qui est rassurant)
ce qui est marrant c'est qu'il ne fait pas la même erreur quand tu utilises uniquement un seul paramètre.

oli_d
24/09/2015, 20h05
Merci val,

C'est pas top ce bug pour moi qui manipule pas mal de données géographiques avec ce genre de coordonnées ...

Je vais essayer de remonter ça sur PluginCafe avec mon english à deux balles