PDA

Voir la version complète : Sélectionner n poly sur n



César Vonc
10/05/2012, 00h13
http://code.vonc.fr/details/s21-00.png

v 1.0

Voici un script python sélectionnant les polygones à intervalle régulier à partir d'une sélection continue.

http://code.vonc.fr/details/s21-01.png


import c4d
from c4d import gui
from c4d.utils import Neighbor

# v1.0 - César Vonc - http://code.vonc.fr

class Dialogue(gui.GeDialog) :
annuler = True
a = 1
b = 2
dec = 0

def CreateLayout(self) :
self.GroupBegin(10, c4d.BFH_SCALEFIT, 2, 3)
self.GroupBorderSpace(70, 0, 70, 0)
self.AddStaticText(20, c4d.BFH_SCALEFIT, 0, 0, "Sélectionner :")
self.AddEditNumberArrows(30, c4d.BFH_SCALEFIT)
self.AddStaticText(21, c4d.BFH_SCALEFIT, 0, 0, "Sur :")
self.AddEditNumberArrows(31, c4d.BFH_SCALEFIT)
self.AddStaticText(22, c4d.BFH_SCALEFIT, 0, 0, "Décalage :")
self.AddEditNumberArrows(32, c4d.BFH_SCALEFIT)
self.GroupEnd()
self.AddDlgGroup(c4d.DLG_OK|c4d.DLG_CANCEL)
return True

def InitValues(self) :
self.SetTitle("Sélectionner n poly sur n")
self.SetLong(30, 1, 1)
self.SetLong(31, 2, 1)
return True

def Command(self, id, msg) :
if id == 1 :
self.annuler = False
self.a = self.GetLong(30)
self.b = self.GetLong(31)
self.dec = self.GetLong(32)
self.Close()
if id == 2 :
self.Close()
return True

def verif(p, li, bs) :
if not bs.IsSelected(p) : return False
if li.IsSelected(p) : return False
return True

def bi_voisin(pp, li, bs, n) :
pol = op.GetPolygon(pp)
pa = None
pb = None

nab = n.GetNeighbor(pol.a, pol.b, pp)
if verif(nab, li, bs) is True :
pa = nab

nbc = n.GetNeighbor(pol.b, pol.c, pp)
if verif(nbc, li, bs) is True :
if pa is None : pa = nbc
else : pb = nbc

ncd = n.GetNeighbor(pol.c, pol.d, pp)
if verif(ncd, li, bs) is True :
if pa is None : pa = ncd
else : pb = ncd

nda = n.GetNeighbor(pol.d, pol.a, pp)
if verif(nda, li, bs) is True :
if pa is None : pa = nda
else : pb = nda

return pa, pb

def mono_voisin (pp, li, bs, n) :
pol = op.GetPolygon(pp)

nab = n.GetNeighbor(pol.a, pol.b, pp)
if verif(nab, li, bs) is True : return nab

nbc = n.GetNeighbor(pol.b, pol.c, pp)
if verif(nbc, li, bs) is True : return nbc

ncd = n.GetNeighbor(pol.c, pol.d, pp)
if verif(ncd, li, bs) is True : return ncd

nda = n.GetNeighbor(pol.d, pol.a, pp)
if verif(nda, li, bs) is True : return nda

return None

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

bs = op.GetPolygonS()
if bs.GetCount() < 2 : return

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

nbp = op.GetPolygonCount()

doc.StartUndo()
doc.AddUndo(c4d.UNDOTYPE_CHANGE_SELECTION, op)
pp = 0;
li = bs.GetClone()
li.DeselectAll()
ordre = []

for i, sel in enumerate(bs.GetAll(nbp)):
if not sel: continue
pp = i
break

n = Neighbor()
n.Init(op)

pa, pb = bi_voisin(pp, li, bs, n)
if pp != None :
li.Select(pp)
ordre.append(pp)
if pa != None :
li.Select(pa)
ordre.append(pa)

po = mono_voisin(pa, li, bs, n)
while (po != None) :
li.Select(po)
ordre.append(po)
po = mono_voisin(po, li, bs, n)


ordre2 = []
if pb != None :
li.Select(pb)
ordre2.append(pb)
po = mono_voisin(pb, li, bs, n)
else : po = None
while (po != None) :
li.Select(po)
ordre2.append(po)
po = mono_voisin(po, li, bs, n)

ordre.reverse()
ordre.extend(ordre2)

j = 0
jmax = len(ordre)
bs.DeselectAll()
a = dial.a
b = dial.b
if (dial.b < dial.a) : b = a
dec = dial.dec % b

while (j < jmax) :
for k in xrange(a) :
s = j + k + dec
if s >= jmax : break
bs.Select(ordre[s])
j += b

doc.EndUndo()
c4d.EventAdd()

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

lenogre
10/05/2012, 01h27
Je suis admiratif de ton travail mais un plug déjà existant fait la même chose : Ça s'appelle SelectLoop, en fait y a 2 fonctions :
- sélectionner une boucle de façon un peu différente à c4d
- sélectionner 1 poly sur 2, sur 3 ou encore 2 polys sur 2, etc

http://www.biomekk.com/index.php?itm=13

César Vonc
10/05/2012, 09h57
Merci Lenogre.
Oui, c'est après l'avoir essayé que j'ai voulu faire le mien. SelectLoop ne permet de sélectionner que UN polygone sur n (avec n limité à 10), ce qui m'a un poil déçu.

Par ailleurs, mon script fonctionne à partir d'une sélection de polygones qui se suivent, donc pas forcément une boucle (image mise à jour).

Sir Gong
10/05/2012, 14h11
Merci beaucoup César, je teste dès que je peux. :icon_clap:

Teutch
10/05/2012, 14h25
César, tu es un chef ! :icon_clap:

tabou
10/05/2012, 16h56
:icon_clap: Génial, je vais pouvoir remplacer SelectLoop que je trouve pas très pratique à utiliser.

Merci César :icon_thumbsup: