PDA

Voir la version complète : Troueur



César Vonc
04/02/2012, 01h11
http://code.vonc.fr/details/s9-01.png Troueur v1.3

Voici un script Python qui troue les polygones sélectionnés en créant automatiquement un booléen et un cylindre adéquat.


http://code.vonc.fr/details/s9-00.png


import c4d
from c4d import gui

class Dialogue(gui.GeDialog):
annuler = True
cotes = 6
bool = True
inter = False
rotb = 0

def CreateLayout(self):
self.SetTitle("Troueur v1.3")
self.GroupBegin(10, 2, 2)
self.AddStaticText(11, c4d.BFH_SCALEFIT, 0, 0, "Côtés :", 0)
self.AddEditNumberArrows(12, c4d.BFH_SCALEFIT, 0, 0)
self.AddStaticText(17, c4d.BFH_SCALEFIT, 0, 0, "Rotation B :", 0)
self.AddEditNumberArrows(18, c4d.BFH_SCALEFIT, 0, 0)
self.AddCheckbox(13, c4d.BFH_SCALEFIT, 0, 0, "Booléen")
self.AddCheckbox(14, c4d.BFH_SCALEFIT, 0, 0, "Intersection")
self.GroupEnd()
self.AddSeparatorV(15)
self.AddButton(19, c4d.BFH_SCALEFIT, initw = 100, inith = 20, name = "Trouer")
self.AddStaticText(16, c4d.BFH_SCALEFIT, 0, 0, "César Vonc - code.vonc.fr", 1)
return True

def InitValues(self) :
self.SetLong(12, 6, 3, 1000, 1)
self.SetBool(13, True)
self.SetBool(16, True)
self.SetDegree(18, 0)
return True

def Command(self, id, msg):
if (id == 13):
self.Enable(14, self.GetBool(13))
if (id == 19):
self.annuler = False
self.cotes = self.GetLong(12)
self.bool = self.GetBool(13)
self.inter = self.GetBool(14)
self.rotb = self.GetReal(18)
self.Close()
return True

def tailleur(pMax, pMin, p):
if pMax is None:
pMax = c4d.Vector(p.x, p.y, p.z)
else:
if pMax.x < p.x: pMax.x = p.x
if pMax.y < p.y: pMax.y = p.y
if pMax.z < p.z: pMax.z = p.z

if pMin is None:
pMin = c4d.Vector(p.x, p.y, p.z)
else:
if pMin.x > p.x: pMin.x = p.x
if pMin.y > p.y: pMin.y = p.y
if pMin.z > p.z: pMin.z = p.z

return pMax, pMin

def troueur():
if not op: return
if (op.GetType() != c4d.Opolygon): return

polSel = op.GetPolygonS()
polSel_nb = polSel.GetCount()
if (polSel_nb == 0): return

dial = Dialogue()
dial.Open(c4d.DLG_TYPE_MODAL)
if (dial.annuler is True): return

pol_nb = op.GetPolygonCount()
polSel_nor = c4d.Vector(0, 0, 0)
polSel_tMax = None
polSel_tMin = None

for i, sel in enumerate(polSel.GetAll(pol_nb)):
if not sel: continue
pol = op.GetPolygon(i)
pA = pol.a
pB = pol.b
pC = pol.c
pD = pol.d
posA = op.GetPoint(pA)
posB = op.GetPoint(pB)
posC = op.GetPoint(pC)
posD = op.GetPoint(pD)
v1 = posA - posC
v2 = posB - posD
v3 = v1.Cross(v2)
polSel_nor += v3
polSel_tMax, polSel_tMin = tailleur(polSel_tMax, polSel_tMin, posA)
polSel_tMax, polSel_tMin = tailleur(polSel_tMax, polSel_tMin, posB)
polSel_tMax, polSel_tMin = tailleur(polSel_tMax, polSel_tMin, posC)
polSel_tMax, polSel_tMin = tailleur(polSel_tMax, polSel_tMin, posD)

polSel_nor.Normalize()
polSel_pos = (polSel_tMax + polSel_tMin) / 2
vdiff = polSel_tMax - polSel_tMin
polSel_long = vdiff.GetLength() / 4

doc.StartUndo()
c4d.CallCommand(13324) # Tout désélectionner

# Cylindre
lissage = c4d.BaseTag(c4d.Tphong)
lissage[c4d.PHONGTAG_PHONG_ANGLELIMIT] = True
lissage[c4d.PHONGTAG_PHONG_USEEDGES] = False
cylindre = c4d.BaseObject(c4d.Ocylinder)
cylindre.SetName("Trou")
doc.AddUndo(c4d.UNDOTYPE_NEW, cylindre)
cylindre.InsertTag(lissage)
doc.InsertObject(cylindre, op)
cylindre[c4d.PRIM_CYLINDER_SEG] = dial.cotes
cylindre[c4d.PRIM_CYLINDER_HEIGHT] = polSel_long * 1.5
cylindre[c4d.PRIM_CYLINDER_RADIUS] = polSel_long
cylindre[c4d.ID_BASEOBJECT_REL_POSITION] = polSel_pos
cylindre[c4d.PRIM_AXIS] = 4
cylindre[c4d.ID_BASEOBJECT_REL_ROTATION] = c4d.utils.VectorToHPB(polSel_nor)
cylindre[c4d.ID_BASEOBJECT_REL_ROTATION,c4d.VECTOR_Z] = dial.rotb
if ((dial.inter is True) and (dial.bool is True)):
cylindre[c4d.PRIM_CYLINDER_CAPS] = False

# Booléen
if dial.bool is True:
booleen = c4d.BaseObject(c4d.Oboole)
booleen[c4d.BOOLEOBJECT_SINGLE_OBJECT] = True
booleen[c4d.BOOLEOBJECT_HIDE_NEW_EDGES] = True
if dial.inter is True :
booleen[c4d.BOOLEOBJECT_TYPE] = 3
doc.AddUndo(c4d.UNDOTYPE_NEW, booleen)
doc.InsertObject(booleen, None, op)
doc.AddUndo(c4d.UNDOTYPE_CHANGE, op)
cyGlob = cylindre.GetMg()
doc.InsertObject(cylindre, booleen)
cylindre.SetMg(cyGlob)
op.Remove()
op.InsertUnder(booleen)
doc.SetActiveObject(booleen)

doc.EndUndo()
c4d.EventAdd()

if __name__=='__main__':
troueur()
Lien alternatif (http://code.vonc.fr/?a=9)

chatbraque
10/02/2012, 09h30
Bonjour

Cela fonctionne avec la version 12 ?

A+

ateo9480
10/02/2012, 10h05
merci,sa peut m'intéresser.Je pense que sa s’installe dans le fichier plugins de c4d ?

chatbraque
10/02/2012, 10h17
Beeen ?… je l'ai installé depuis la fenêtre : "Python" … "scripts personnalisés"… "dossier script"

ça place le dossier dans la librairie… je ne sais pas si c'est la bonne procédure, mais en tout cas, sous mac en version 12 prime…
'a morche pô

:icon_cry:

ateo9480
10/02/2012, 10h33
Beeen ?… je l'ai installé depuis la fenêtre : "Python" … "scripts personnalisés"… "dossier script"

ça place le dossier dans la librairie… je ne sais pas si c'est la bonne procédure, mais en tout cas, sous mac en version 12 prime…
'a morche pô

:icon_cry:

Pour ma part,je fais "démarrer le script " puis je sélectionne le fichier ".py" et sa fonctionne.

Je pense qu'il doit y avoir une solution plus pratique pour l'utiliser.J'ai essayé de le mettre dans le dossier "plugins" de c4d mais il fonctionne qu'avec la manip que j'ai fais plus haut.

Si quelqu'un peut nous expliqué une façon plus simple et plus pratique on est preneur :)

chatbraque
10/02/2012, 10h38
"lancer le script" ???… môrche pas chez moi…
… la typo du bouton n'est pas reconnue (caractères zarbis)… et il ne se passe rien lorsque je tape "enter"
… un petit mode d'emploi pour cette section ? (je plussoie)

merci

ateo9480
10/02/2012, 10h59
Peut-être que sa passe pas sur ta version.



… un petit mode d'emploi pour cette section ? (je plussoie)

merci



+1 avec toi pour le mode d'emploie.

oli_d
10/02/2012, 11h40
Il faut qu'il y ait un objet polygonal sélectionné et des polygones de cet objet sélectionnés et ça marche nickel.

C'est un script, le code est à coller dans le gestionnaire de scripts

Merci à toi ô grand César !

chatbraque
10/02/2012, 14h13
Merci pour les tutos
(a priori, je ne faisais pas de grosse boulette)

… mais sur mac et en version 12 prime, je me retrouve toujours avec ceci :

http://data.imagup.com/12/1143544994.jpg (http://www.imagup.com/data/1143544994.html)

… j'entre une valeur, je clic "enter"… et il ne passe rien :huh:

(vous pouvez remarquer en "2" que la typo du bouton ne semble pas être reconnue (bug ?)

César Vonc
10/02/2012, 14h42
Bizarre, ça ressemble à un problème d'encodage.

Tu peux me dire ce qu'affiche la console ? (Python > Console (Python))

Et dans le gestionnaire de script, tu dois normalement avoir la même chose que le code du premier message de ce sujet.

chatbraque
10/02/2012, 14h54
je l'ai fais plusieurs fois, voici ce qu'il me renvoit :

Traceback (most recent call last):
File "<Troueur.py>", line 19, in CreateLayout
AttributeError: 'Dialogue' object has no attribute 'AddDlgGroup'
Traceback (most recent call last):
File "<Troueur.py>", line 138, in <module>
File "<Troueur.py>", line 77, in troueur
AttributeError: 'c4d.PolygonObject' object has no attribute 'GetPolygon'
Traceback (most recent call last):
File "<Troueur.py>", line 19, in CreateLayout
AttributeError: 'Dialogue' object has no attribute 'AddDlgGroup'
Traceback (most recent call last):
File "<Troueur.py>", line 138, in <module>
File "<Troueur.py>", line 77, in troueur
AttributeError: 'c4d.PolygonObject' object has no attribute 'GetPolygon'


… j'ai aussi collé le script dans le gestionnaire de script (il y avait un autre script)… j'ai recommencé, même résultat
(y compris dans la console)

chatbraque
10/02/2012, 15h01
je me demande si le souci ne viendrait pas tout simplement du fait que je copie le texte avec simpletext pour le coller dans le gestionnaire… :icon_redface:
… car il apparaît alors avec ces caractères non-reconnus (système mac) ?

photo d'écran :
http://data.imagup.com/10/1143548175.jpg (http://www.imagup.com/data/1143548175.html)




Ou, plus simplement, vu que le fichier que j'ai téléchargé comporte lui aussi ces caractères non reconnus… peut-être est-ce la police que tu utilises qui ne serait pas compatible mac ?
(texte ci-dessous… il semble ne pas reconnaître le "e" avec accent aigu… ni le "o" avec accent circonflexe)



import c4d
from c4d import gui

class Dialogue(gui.GeDialog):
annuler = False
cotes = 6
bool = True
inter = False

def CreateLayout(self):
self.SetTitle("Troueur v1.2")
self.GroupBegin(10, 2, 2)
self.AddStaticText(11, c4d.BFH_SCALEFIT, 0, 0, "Côtés :", 0)
self.AddEditNumberArrows(12, c4d.BFH_SCALEFIT, 0, 0)
self.AddCheckbox(13, c4d.BFH_SCALEFIT, 0, 0, "Booléen")
self.AddCheckbox(14, c4d.BFH_SCALEFIT, 0, 0, "Intersection")
self.GroupEnd()
self.AddSeparatorV(15)
self.AddDlgGroup(c4d.DLG_OK|c4d.DLG_CANCEL)
self.AddStaticText(16, c4d.BFH_SCALEFIT, 0, 0, "César Vonc - www.cesarvonc.fr", 1)

self.SetLong(12, 6, 3, 1000, 1)
self.SetBool(13, True)
self.SetBool(16, True)
return True

def Command(self, id, msg):
if (id == 13):
self.Enable(14, self.GetBool(13))
if (id == 1):
self.annuler = False
self.cotes = self.GetLong(12)
self.bool = self.GetBool(13)
self.inter = self.GetBool(14)
self.Close()
if (id == 2):
self.annuler = True
self.Close()
return True

def tailleur(pMax, pMin, p):
if pMax is None:
pMax = c4d.Vector(p.x, p.y, p.z)
else:
if pMax.x < p.x: pMax.x = p.x
if pMax.y < p.y: pMax.y = p.y
if pMax.z < p.z: pMax.z = p.z

if pMin is None:
pMin = c4d.Vector(p.x, p.y, p.z)
else:
if pMin.x > p.x: pMin.x = p.x
if pMin.y > p.y: pMin.y = p.y
if pMin.z > p.z: pMin.z = p.z

return pMax, pMin

def troueur():
if not op: return
if (op.GetType() != c4d.Opolygon): return

polSel = op.GetPolygonS()
polSel_nb = polSel.GetCount()
if (polSel_nb == 0): return

dial = Dialogue()
dial.Open(c4d.DLG_TYPE_MODAL)
if (dial.annuler is True): return

pol_nb = op.GetPolygonCount()
polSel_nor = c4d.Vector(0, 0, 0)
polSel_tMax = None
polSel_tMin = None

for i, sel in enumerate(polSel.GetAll(pol_nb)):
if not sel: continue
pol = op.GetPolygon(i)
pA = pol.a
pB = pol.b
pC = pol.c
pD = pol.d
posA = op.GetPoint(pA)
posB = op.GetPoint(pB)
posC = op.GetPoint(pC)
posD = op.GetPoint(pD)
v1 = posA - posC
v2 = posB - posD
v3 = v1.Cross(v2)
polSel_nor += v3
polSel_tMax, polSel_tMin = tailleur(polSel_tMax, polSel_tMin, posA)
polSel_tMax, polSel_tMin = tailleur(polSel_tMax, polSel_tMin, posB)
polSel_tMax, polSel_tMin = tailleur(polSel_tMax, polSel_tMin, posC)
polSel_tMax, polSel_tMin = tailleur(polSel_tMax, polSel_tMin, posD)

polSel_nor.Normalize()
polSel_pos = (polSel_tMax + polSel_tMin) / 2
vdiff = polSel_tMax - polSel_tMin
polSel_long = vdiff.GetLength() / 4

doc.StartUndo()
c4d.CallCommand(13324) # Tout désélectionner

# Cylindre
cylindre = c4d.BaseObject(c4d.Ocylinder)
cylindre.SetName("Trou")
doc.AddUndo(c4d.UNDOTYPE_NEW, cylindre)
doc.InsertObject(cylindre, op)
cylindre[c4d.PRIM_CYLINDER_SEG] = dial.cotes
cylindre[c4d.PRIM_CYLINDER_HEIGHT] = polSel_long * 1.5
cylindre[c4d.PRIM_CYLINDER_RADIUS] = polSel_long
cylindre[c4d.ID_BASEOBJECT_REL_POSITION] = polSel_pos
cylindre[c4d.PRIM_AXIS] = 4
cylindre[c4d.ID_BASEOBJECT_REL_ROTATION] = c4d.utils.VectorToHPB(polSel_nor)
if ((dial.inter is True) and (dial.bool is True)):
cylindre[c4d.PRIM_CYLINDER_CAPS] = False

# Booléen
if dial.bool is True:
booleen = c4d.BaseObject(c4d.Oboole)
booleen[c4d.BOOLEOBJECT_SINGLE_OBJECT] = True
booleen[c4d.BOOLEOBJECT_HIDE_NEW_EDGES] = True
if dial.inter is True :
booleen[c4d.BOOLEOBJECT_TYPE] = 3
doc.AddUndo(c4d.UNDOTYPE_NEW, booleen)
doc.InsertObject(booleen, None, op)
doc.AddUndo(c4d.UNDOTYPE_CHANGE, op)
cyGlob = cylindre.GetMg()
doc.InsertObject(cylindre, booleen)
cylindre.SetMg(cyGlob)
op.Remove()
op.InsertUnder(booleen)
doc.SetActiveObject(booleen)

doc.EndUndo()
c4d.EventAdd()

if __name__=='__main__':
troueur()




(m'enfin, je dis ça… je dis rien… j'imagine que ce sont des caractères qui n'apparaisent que dans les commentaires et pas dans le code ?)

César Vonc
10/02/2012, 15h15
Apparemment c'est un problème de version, les fonctions AddDlgGroup() et GetPolygon() ne semblent pas être reconnues chez toi car elles ont visiblement été implantées depuis la version R13.029 :

http://chicagoc4d.com/C4DPythonSDK/misc/whatisnew.html


Mais dans ce cas, je ne comprends pas comment ce script peut fonctionner chez Oli_d qui est pourtant en R12.


Le problème des caractères spéciaux est aussi sûrement lié à ta version, les scripts Pythons de la R13 sont encodés en UTF-8, et je soupçonne ceux de ta version d'être en ANSI.
Vois si tu peux écrire juste un é dans le gestionnaire de script, l'enregistrer et le poster sur le forum (en pièce jointe zipée).

oli_d
10/02/2012, 17h14
Mais dans ce cas, je ne comprends pas comment ce script peut fonctionner chez Oli_d qui est pourtant en R12.


Oupsss mon profil n'était pas à jour, je suis en 13.051

chatbraque
10/02/2012, 18h18
OK… c'est un problème de version… une fois de plus
(je vais donc remiser Python au rayonnage des gadgets pour nantis :icon_cry:)

gaff
24/04/2012, 20h39
Merci pour le script.
Juste un petit truc qui serrait bien utile à rajouter : l'orientation en B du cylindre.
comme, on peut indiquer le nombre de segments au cylindre; à 3 cela fait un triangle et à 4 un carré ( bien pratique la ruse ).
Et si on pouvait lors de l'exécution du script orienter le cylindre en rotation B, cela permettrait d'obtenir au choix, un trou cylindrique, un trou en forme de " triangle " ou cubique orienté comme on le souhaite.
En tout cas, bravo pour tous ces petits scripts qui font gagner énormément de temps. :thumbup1:

César Vonc
24/04/2012, 23h07
Merci pour le retour.

Ah oui je vois, ajouter un petit champ pour la rotation B dans la boîte de dialogue, en somme.
Pas de soucis, je m'en occupe d'ici peu, je vais en profiter pour changer l'icône actuelle qui n'est pas très claire en 16 × 16 pixels.


Édition : Script mis à jour.

gaff
25/04/2012, 20h30
:icon_clap: Ben voilà, c'est juste parfait, y a même l'icône. Et merci pour la réactivité.