PDA

Voir la version complète : Extraire les coordonnées x,y,z d'objets



user4D
07/07/2014, 15h50
Bonjour à tous,

je souhaiterais extraire les coordonnées x,y,z de tous les objets présents dans ma scène avec leurs noms et leurs coordonnées.

Je sais que je peux exporter les données ASCII via l'onglet structure (points, polygones, uvw,...) mais j'ai pas trouvé pour les coordonnées objets :huh:

Au final, j'aimerais regrouper dans un tableur, une colonne le nom des objets et dans une autre colonne leurs positions x,y,z.

Quelqu'un aurait une piste à me proposer ? :icon_prie:

valkaari
07/07/2014, 19h24
Quelqu'un aurait une piste à me proposer ? :icon_prie:


ouais

valkaari
07/07/2014, 19h51
en m'appuyant sur cette page http://c4dprogramming.wordpress.com/2012/09/12/recursive-hierarchy-iteration/

(et en corrigeant les petits oublie de code genre parenthèse ou des modifs du sdk)

Si tu enregistre avec une extention .csv, tu devrais pouvoir importer ton fichier dans openoffice ou excel en lui spécifiant que tes colonnes sont séparées par des ;






import c4d
from c4d import gui
#Welcome to the world of Python




def print_object_name(op,fn):
if not op:
return False

xyz = str(op.GetMg().off.x) + ";" + str(op.GetMg().off.y) +";" + str(op.GetMg().off.z)
fn.write(op.GetName() + ";" + xyz + "\n")
return True




# Recurses a hierarchy, starting from op
# Returns number successful callbacks
def recurse_hierarchy(op, callback,fn):
count = 0
while op:
if callback(op,fn):
count += 1
count += recurse_hierarchy(op.GetDown(),callback,fn)
op = op.GetNext()
return count






def main():


fn = open(c4d.storage.SaveDialog(),"w")
fn.write("Nom de l'objet;x;y;z\n")

count = recurse_hierarchy(doc.GetFirstObject(), print_object_name,fn)
fn.write("Nombre d'objet traité " + str(count))
fn.close()


if __name__=='__main__':
main()





on notera que je me suis même pas emmerdé à renommer la fonction "print_object_name"

Faignasse que je suis T.T

César Vonc
07/07/2014, 19h52
Alors juste une piste !


Tu peux récupérer le premier objet de ta scène avec doc.GetFirstObject() (http://www.maxonexchange.de/sdk/CINEMA4DPYTHONSDK/help/modules/c4d.documents/BaseDocument/index.html?highlight=getfirstobject#BaseDocument.G etFirstObject).

Ses enfants avec GetChildren() (http://www.maxonexchange.de/sdk/CINEMA4DPYTHONSDK/help/modules/c4d/C4DAtom/GeListNode/index.html?highlight=getchildren#GeListNode.GetChi ldren).

L'objet suivant avec GetNext() (http://www.maxonexchange.de/sdk/CINEMA4DPYTHONSDK/help/modules/c4d/C4DAtom/GeListNode/index.html?highlight=getnext#GeListNode.GetNext).

La matrice de l'objet avec GetMg() (http://www.maxonexchange.de/sdk/CINEMA4DPYTHONSDK/help/modules/c4d/C4DAtom/GeListNode/BaseList2D/BaseObject/index.html?highlight=getmg#BaseObject.GetMg) pour les coordonnées globales, ou relatives avec GetMl() (http://www.maxonexchange.de/sdk/CINEMA4DPYTHONSDK/help/modules/c4d/C4DAtom/GeListNode/BaseList2D/BaseObject/index.html?highlight=getml#BaseObject.GetMl).

Le nom de l'objet avec GetName() (http://www.maxonexchange.de/sdk/CINEMA4DPYTHONSDK/help/modules/c4d/C4DAtom/GeListNode/BaseList2D/index.html?highlight=getname#BaseList2D.GetName).


Et enfin, t'as la fonction print de Python qui permet d'écrire dans la console.

valkaari
07/07/2014, 19h55
quand je disais juste "ouais" c'était le temps de bouffer une biscotte et de pondre le code hein (puis tester un peu en passant)

Tu soulèves un points important, j'ai pris les cordonnées globales de chaque objets et pas les relatives.

César Vonc
07/07/2014, 20h04
C'est dommage pour User4D qui aurait pu apprendre quelques notions tant qu'il avait encore un intérêt pour le codage.

On se retrouve de nouveau seuls ici.

Sir Gong
07/07/2014, 20h16
On se retrouve de nouveau seuls ici.On participerait volontiers, mais perso, le seul mot de la discussion que j'ai compris c'est "biscotte".

user4D
07/07/2014, 21h25
quand je disais juste "ouais" c'était le temps de bouffer une biscotte et de pondre le code hein (puis tester un peu en passant)

Tu soulèves un points important, j'ai pris les cordonnées globales de chaque objets et pas les relatives.

God save you Mister Val :icon_prie:

Je pensais à une piste avec moins de code en fait :sweatdrop:

En parlant de pondre, je suis tombé sur une vidéo qui devrait te plaire :icon_mrgreen: Il y a du nude et des boobs (https://www.youtube.com/watch?v=wKFZOIv5sS0)

user4D
13/02/2015, 10h28
Salut Val :kiss:

Es-ce qu'il serait possible pour toi de modifier ce script pour qu'il récupère les coordonnées des objets par rapport à une caméra à la place du monde ?

Merci :innocent:

oli_d
14/02/2015, 06h34
Je m'y suis collé.

J'ai repris le code de Val et modifié les coordonnées des objets par rapport à la caméra de rendu. J'ai également rajouté une ligne biscotte pour que sir Gong comprenne au moins une ligne :icon_mrgreen:.

Fais peut-être quelques vérifications sur un petit fichier avant de l'utiliser en prod ...


import c4d
from c4d import gui


def print_object_name(op,fn,pos_cam):
if not op:
return False
#on soustrait la position globale de la caméra à la position globale de l'objet
pos = op.GetMg().off - pos_cam
xyz = str(pos.x) + ";" + str(pos.y) +";" + str(pos.z)
fn.write(op.GetName() + ";" + xyz + "\n")
return True




# Recurses a hierarchy, starting from op
# Returns number successful callbacks
def recurse_hierarchy(op, callback,fn,pos_cam):
count = 0
while op:
if callback(op,fn,pos_cam):
count += 1
count += recurse_hierarchy(op.GetDown(),callback,fn,pos_cam )
op = op.GetNext()
return count


def main():
#biscotte
#récupération de la vue de rendu
bd = doc.GetRenderBaseDraw()
#récupération de la camera de la scene
cam = bd.GetSceneCamera(doc)
#si on n'a pas de camera active on prend la camera de la vue
if not cam : cam = bd.GetEditorCamera()
pos_cam = cam.GetMg().off

fn = open(c4d.storage.SaveDialog(),"w")
fn.write("Nom de l'objet;x;y;z\n")

count = recurse_hierarchy(doc.GetFirstObject(), print_object_name,fn,pos_cam)
fn.write("Nombre d'objet traité " + str(count))
fn.close()


if __name__=='__main__':
main()

Sir Gong
14/02/2015, 13h03
haha, merci ! :biggrin:

user4D
16/02/2015, 21h03
Merci oli_d (http://frenchcinema4d.fr/member.php?55058-oli_d):icon_love:

Je vais tester ça demain, mais connaissant ton niveau, ça m'étonnerait que cela ne fonctionne pas :P.

Et merci pour la biscotte :icon_mrgreen:

Realzeb
17/02/2015, 10h30
:icon_question: Juste une question :

Ça participe un peu de la question de base, mais c'est un poil différent, quand je modélise un gros truc comme en ce moment, je ne modélise pas toujours mes nouvelles pièces sur un nouveau fichier avant d'importer dans mon document principal, mais je modélise parfois in situ.

Mon problème est alors le suivant : Chaque nouvelle primitive que je créé se retrouve au point 0,0,0 (normal jusque là !) je dois alors lui coller les valeurs X, Y et Z de la pièce la plus proche pour l'amener au plus près de l'endroit où je vais en avoir besoin.

Ma question : Est-ce qu'il existe une fonction dans C4D, ou un truc quelconque, ou un plug-in, que gros bêta que je suis, je ne connais pas, pour copier / coller instantanément ces 3 valeurs d'un objet sur un autre, autre que le fastidieux copier / coller manuel valeur par valeur que je me coltine à chaque fois ? :huh:

sansalvador
17/02/2015, 11h22
Ma question : Est-ce qu'il existe une fonction dans C4D, ou un truc quelconque, ou un plug-in, que gros bêta que je suis, je ne connais pas, pour copier / coller instantanément ces 3 valeurs d'un objet sur un autre, autre que le fastidieux copier / coller manuel valeur par valeur que je me coltine à chaque fois ? :huh:

Alors moi je travaille en mode "monde" , lorsque j'ajoute une primitive , je la mets en enfant de l'objet aux coordonnées désirées , je passe en mode "objet réel" et je mets les coordonnées XYZ à 0 , ce qui est très rapide en utilisant la touche "Tab" , la primitive vient alors se placer sur le même axe que l'objet , il ne me reste plus qu'à ôter la primitive mise en enfant et de repasser en mode "monde" , cela évite les copier/coller que tu fais.
Quant à l'éventuel plugin , aucune idée

Sir Gong
17/02/2015, 11h30
Sérieux ?

Et la fonction "transférer" c'est du mou de veau ? ©PP
14240
(Outils > réorganiser les objets > transférer) à docker dans ton interface :icon_wip:

sansalvador
17/02/2015, 11h35
ah bin , je ne connaissais pas non plus^^....comme on dit "l'imbécile ne le reste que 5 mn s'il pose sa question mais le reste toute sa vie s'il ne dit rien" :P...me voilà donc moins gourde grâce à toi Sir Gong :kiss: ....qui a dit " oui mais il te reste encore un long chemin "? :biggrin:

Sir Gong
17/02/2015, 11h45
Pour les scènes complexes, un autre petit truc qui peut servir :
Dans les préférences générales > interface > Créer un nouvel objet au centre de la vue.

Comme son nom l'indique, une fois cette option cochée, les nouveaux objets seront crées au centre de la vue au lieu de 0,0,0.
Utile pour bosser une zone et que l'origine est hors champ.

Itsmil
17/02/2015, 13h04
Alors moi je travaille en mode "monde" , lorsque j'ajoute une primitive , je la mets en enfant de l'objet aux coordonnées désirées , je passe en mode "objet réel" et je mets les coordonnées XYZ à 0 , ce qui est très rapide en utilisant la touche "Tab" , la primitive vient alors se placer sur le même axe que l'objet , il ne me reste plus qu'à ôter la primitive mise en enfant et de repasser en mode "monde" , cela évite les copier/coller que tu fais.
Quant à l'éventuel plugin , aucune idée

sinon dans la même veine, tu peux t'amuser a mettre ton objet en enfant et faire maillage/centrer les axes/centrer sur le parent. Il y a plusieurs chemins pour arriver au Rhum !

Realzeb
17/02/2015, 14h37
Sérieux ?

Et la fonction "transférer" c'est du mou de veau ? ©PP
14240
(Outils > réorganiser les objets > transférer) à docker dans ton interface :icon_wip:


Aaaah ! je le savais, je le savais qu'il y avait un truc comme ça ! O-BLI-GÉ !
Merci Sir Gong :)
(mais tu sais il y a des tonnes des fonctions dont je ne fais que de me dire : "c'est quoi encore ce truc ? Bah on verra plus tard !")

Efficace en effet, je me coucherai encore moins bête ce soir, cool ! :thumbup1:



Alors moi je travaille en mode "monde" , lorsque j'ajoute une primitive , je la mets en enfant de l'objet aux coordonnées désirées , je passe en mode "objet réel" et je mets les coordonnées XYZ à 0 , ce qui est très rapide en utilisant la touche "Tab" , la primitive vient alors se placer sur le même axe que l'objet , il ne me reste plus qu'à ôter la primitive mise en enfant et de repasser en mode "monde" , cela évite les copier/coller que tu fais.
Quant à l'éventuel plugin , aucune idée


Je ne connaissais pas, mais ça semble logique ! ;)
Merci Sansa :)



sinon dans la même veine, tu peux t'amuser a mettre ton objet en enfant et faire maillage/centrer les axes/centrer sur le parent. Il y a plusieurs chemins pour arriver au Rhum !


J'en use et j'en abuse aussi dans pas mal de cas ! ;)


Merci les copains et copine !

Plus qu'à tester le mou de veau ! :P

paspas
18/02/2015, 09h01
hello


C'est dommage pour User4D qui aurait pu apprendre quelques notions tant qu'il avait encore un intérêt pour le codage.

On se retrouve de nouveau seuls ici.

c 'est a dire que vous été trop rapide et trop fort pour moi du coup je ferme ma g..... :)

pour répondre a Realzeb tu as aussi l objet "grille de construction " tu les rend visible ou non pour les rendre actives

C4D te créera tj ton nouvelle objet au centre de cette nouvelle grille et orienté comme les axe de cette grille ,
tu peut avoir plusieurs grilles par défaut il prend celle la plus haute dans la hiérarchie si tu ne joue pas avec la visibilité de la grille, la grille du monde est la plus basse de la hiérarchie