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.
Lien alternatifCode PHP:
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()
Dernière modification par César Vonc ; 25/04/2012 à 14h36.
Bonjour
Cela fonctionne avec la version 12 ?
A+
"Athos pour un !… un Porthos !" (devise des 3 mousquetaires, lorsqu'ils n'étaient encore que 2)
merci,sa peut m'intéresser.Je pense que sa s’installe dans le fichier plugins de c4d ?
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ô
Dernière modification par chatbraque ; 10/02/2012 à 11h19.
"Athos pour un !… un Porthos !" (devise des 3 mousquetaires, lorsqu'ils n'étaient encore que 2)
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
"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
"Athos pour un !… un Porthos !" (devise des 3 mousquetaires, lorsqu'ils n'étaient encore que 2)
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 !
"Athos pour un !… un Porthos !" (devise des 3 mousquetaires, lorsqu'ils n'étaient encore que 2)
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.
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)
Dernière modification par chatbraque ; 10/02/2012 à 15h59.
"Athos pour un !… un Porthos !" (devise des 3 mousquetaires, lorsqu'ils n'étaient encore que 2)
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…
… car il apparaît alors avec ces caractères non-reconnus (système mac) ?
photo d'écran :
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 ?)
Dernière modification par chatbraque ; 10/02/2012 à 16h15.
"Athos pour un !… un Porthos !" (devise des 3 mousquetaires, lorsqu'ils n'étaient encore que 2)
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).
OK… c'est un problème de version… une fois de plus
(je vais donc remiser Python au rayonnage des gadgets pour nantis )
Dernière modification par chatbraque ; 12/02/2012 à 09h36.
"Athos pour un !… un Porthos !" (devise des 3 mousquetaires, lorsqu'ils n'étaient encore que 2)
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.
Je comprends vite, mais faut m'expliquer longtemps…
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.
Dernière modification par César Vonc ; 25/04/2012 à 14h37.
Ben voilà, c'est juste parfait, y a même l'icône. Et merci pour la réactivité.
Je comprends vite, mais faut m'expliquer longtemps…