PDA

Voir la version complète : Supression Polygone



leo3d
05/03/2016, 19h27
Pourquoi quand je supprime un polygone, il reste toujours les points, c'est nul
une astuce ??

sansalvador
05/03/2016, 19h59
Wow , je crois qu'il faudrait quand même que tu fasses un tour du côté des bases de C4D et de sa documentation , un minimum.
Pour virer les points , tu cliques droit et optimiser


... c'est nul

toujours autant emballé et optimiste avec ce soft......

leo3d
05/03/2016, 22h16
Non mais sérieux. T'inquiète pas je la consulte la doc. Je trouve naturel que lorsqu'on supprime un poly, les arrêtes et les points qui le compose disparaissent en même temps. Je suis toujours très emballé par ce soft. Je l'adore. C'est juste que vous adorez cliquer.

C4D supprime bien les arrêtes lors de la suppression du poly, oui. Il ne peut pas faire les points.

lenogre
05/03/2016, 22h25
Au contraire, je trouve ça très bien que les points restent. Des fois, on a des polygones pas chouettes alors hop on les supprime et on retricote les polys en s'appuyant sur les points des polys qu'on vient de supprimer.

Un jour, j'en suis sûr, tu te diras : "Ah oui, finalement, c'est plutôt pas mal !". Au moins avec C4D tu as le choix. Peut-être faudrait-il ajouter ça dans les préfs : Supprimer les points quand on supprime un polygone.

César Vonc
05/03/2016, 22h46
Sinon tu maintiens Maj en passant du mode polygones au mode points, puis tu supprimes les points sélectionnés.

leo3d
05/03/2016, 23h23
Et oui comme les points me gêne je les supprime par les points. À voir lenogre en effet je risque de les aimer à la longue.

leo3d
05/03/2016, 23h24
Une réponse pour une autre question. Comment afficher les points d objets non sélectionnés dans le viewport

Floc
06/03/2016, 01h22
Avoir une option de suppression "complete" poly et points serait quand même le bienvenue..

Car l'astuce dutiliser majuscule ne peut ne peu être utilisé que dans le cas ou les polys forme un ilot, sinon on vire une rangée de points en trop.

Du coup il faut utiliser l'option optimise et selon les cas n'utiliser que l'option "unusued points" au risque de faire des conneries. surtout que cette option est mémorisé avec le fichier, ce qui est plutôt bien, mais aussi peu être source d'erreur quand tu as une multitude de fichier ou tu est obligé de changer cette "pref" en permanence.
Alors effectivement dans le cas de bases de données simple ce n'est pas très grave, mais sur ce quoi je bosse en ce moment c'est un peu chiant. On a plus de trois km de bâtiment à découper en morceaux (c'est pour de l'impression), donc optimise a gogo, et avec ce système on a réussi à faire des conneries, genre souder des points sans le vouloir (et sans s'en rendre compte), et la base ayant évolué on ne peu plus revenir en arrière. Du coup on se retrouve par endroit avec des non-manifold et comme c'est pour de l'impression c'est plutôt gênant.
J'ai même voulu écrire une commande pour avoir l'option effacer poly avec point,
mais c'est plus compliqué que je ne pensais.

gr4ph0s
06/03/2016, 06h31
J'ai commencé a codé un script pour supprimer les polygones et les points. J'arrive à récupérer l'ID des Faces + Vertex a supprimer mais après comment faire pour les supprimer ^^'.

J'ai pensé à recréer un nouvel objet de a-Z mais bon on dois bien pouvoir mettre à jour un objet. Car sinon c'est un peu relou ^^'
Voila mon code pour le moment (il ne marche pas, il fait crash C4D). Pour ceux qui veulent tester faite un cube avec 5subdiv et selectionner par exemple 4 face côte/côte. Je sais pour le moment j'ai fait aucun check pour voir si la sélection est nul ou autre erreur d'entrée d'utilisateur.

pointToRemove va contenir l'ID du point central de ces 4 faces et idSelectedPoly contient l'ID des faces selectionnées


Merci d'avance :)


import c4d
from c4d.utils import Neighbor




def getSelectedPolyID(obj):
nbPoly = obj.GetPolygonCount()
selectedPoly = obj.GetPolygonS()
list_polys = selectedPoly.GetAll(nbPoly)

buffer = []
for i in xrange(nbPoly):
if list_polys[i]:
buffer.append(i)

return buffer




def getPointIDFromPolyID(obj,polyID):
buffer = []
for i in xrange(len(polyID)):
buffer_a = obj.GetPolygon(polyID[i]).a
buffer_b = obj.GetPolygon(polyID[i]).b
buffer_c = obj.GetPolygon(polyID[i]).c
buffer_d = obj.GetPolygon(polyID[i]).d

buffer.append(buffer_a)
buffer.append(buffer_b)
buffer.append(buffer_c)
buffer.append(buffer_d)

return buffer




def getPointsToRemove(obj,ptn):
nb = Neighbor()
nb.Init(obj,None)




buffer = []
for i in xrange(len(ptn)):
nbFaceNear = len(nb.GetPointPolys(ptn[i]))
if ptn.count(ptn[i]) >= nbFaceNear and not ptn[i] in buffer:
buffer.append(ptn[i])

nb.Flush()
return buffer




def getFaceWithoutSelected(obj,idSelectedPoly):
nbPoly = obj.GetPolygonCount()
buffer = []
for i in xrange(nbPoly):
if not i in idSelectedPoly:
buffer.append(obj.GetPolygon(i))

return buffer


def getPointWithoutSelected(obj,ptnToRemove):
allPoints = obj.GetAllPoints()
for i in xrange(len(ptnToRemove)):
allPoints.pop(ptnToRemove[i])

return allPoints


def removePoint(obj,pointFinal,polyFinal):
nbPts = len(pointFinal)
nbPolys = len(polyFinal)

obj.ResizeObject(nbPts, nbPolys)
#obj.SetAllPoints(pointFinal)

#for i, p in enumerate(polyFinal):
# obj.SetPolygon(i, p)

#obj.Message(c4d.MSG_UPDATE)
#c4d.EventAdd()





def main():
obj = doc.GetActiveObject()
idSelectedPoly = getSelectedPolyID(obj)
pointIDSelected = getPointIDFromPolyID(obj,idSelectedPoly)
pointToRemove = getPointsToRemove(obj,pointIDSelected)

polyFinal = getFaceWithoutSelected(obj,idSelectedPoly)
pointFinal = getPointWithoutSelected(obj,pointToRemove)


removePoint(obj,pointFinal,polyFinal)





if __name__=='__main__':
main()

César Vonc
06/03/2016, 09h14
Mais pourquoi s'emmerder, optimiser les points non utilisés ne suffit pas ?

Avec ces deux commandes à la suite, ça marche à merveille.

leo3d
06/03/2016, 09h27
Ok César je l'entends mais c'était une question.
S'il faut faire un u-o après la suppression c'est pas grave non plus


Envoyé de mon iPhone en utilisant Tapatalk

gr4ph0s
06/03/2016, 15h54
Mais pourquoi s'emmerder, optimiser les points non utilisés ne suffit pas ?

Parce que Python is great et que j'aime apprendre :p

Floc
06/03/2016, 16h40
Avec ces deux commandes à la suite, ça marche à merveille.

Oui dans la plupart des cas ça suffit et oui ça marche avec ces deux commandes.
Ce qui me gene c'est que optimise suprime les poits ET fusionne les points adjacents.
Dans certains cas il faut impérativement désactiver la fusion.
Quand on nettoie un objet pas de souci, mais dans le cadre du boulot que je suis en train de terminer, dont la phase finale est le découpage en morceau d'une base complexe ou on ne peut vérifier à l'oeuil ce qui se passe, et le fichier passant d'une personne à l'autre, ça nous a généré des problèmes.
Des polys on été fusionnés alors qu'il n'aurai pas du, résultant en un paquet de non-fanifold. ce qui est genant pour l'impression 3D.
Une commande directe effaçant les poly avec leurs point sans fusionner les point adjacent aurai évité ces problèmes. Et la je parle de couts de réimpression en centaines voir plus d'euros
C'est pourquoi j'ai essayé de scripter une commande, pour éviter les embrouilles.
Mais comme le montre le script de Graphos (merci au passage :) ) c'est pas si simple.
Du coup il a fallu etre super vigilant voir parano avec cette commande optimise.
Mais sinon oui ca marche :)

César Vonc
06/03/2016, 20h01
Oui oui j'avais compris, mais je veux dire que si tu veux faire un script, il suffit de balancer la commande de suppression, puis celle d'optimisation avec uniquement la suppression des points isolés en paramètre. ^^

César Vonc
06/03/2016, 20h14
Mettre ces deux commandes dans un script et luia ffecter un raccourci clavier tel que Maj + Supp fonctionne pas trop mal.


import c4d

def main():
if not op or not op.CheckType(c4d.Opolygon) : return
if doc.GetMode() != c4d.Mpolygons : return

doc.AddUndo(c4d.UNDOTYPE_CHANGE, op)

c4d.utils.SendModelingCommand(command = c4d.MCOMMAND_DELETE,
list = [op],
mode = c4d.MODELINGCOMMANDMODE_POLYGONSELECTION,
doc = doc)

bc = c4d.BaseContainer()
bc[c4d.MDATA_OPTIMIZE_POINTS] = False
bc[c4d.MDATA_OPTIMIZE_POLYGONS] = False
bc[c4d.MDATA_OPTIMIZE_UNUSEDPOINTS] = True

c4d.utils.SendModelingCommand(command = c4d.MCOMMAND_OPTIMIZE,
list = [op],
mode = c4d.MODELINGCOMMANDMODE_ALL,
bc = bc,
doc = doc)

doc.EndUndo()
c4d.EventAdd()

if __name__=='__main__':
main()


C'est sûr que c'est moins amusant que de recalculer l'objet, Graphos, certes. : p

J'ai pas regardé ton script, mais quand on modifie le nombre de points ou polys d'un objet, il faut pas oublier de modifier en conséquence toutes les propriétés de type point ou polygones associées (UVW, sélections...) pour qu'elles restent cohérentes, ce qui est assez chiant.

gr4ph0s
06/03/2016, 20h20
Sauf que la tu supprime si il y a d'autre points isolés.
Au début je pensais faire pareil mais je n'ai pas trouvé simplement de façon de passer d'une sélection de poly à une sélection de point. Et puis je me suis dis qu'explorer un peu les objets poly pourrais être cool :p

J'avais penser aussi en faisant un truc dans le genre, vu que j'ai l'ID des points a supprimer en sélectionnant les points devant être supprimé. Mais comment avoir un BaseSelect avec seulement l'ID du vertex? Puis après lancer la commande delete MCOMMAND_DELETE avec ma selection de Vertex.

oli_d
06/03/2016, 20h42
import c4d

def main():
#si on est pas en mode polygone -> stop
if not doc.GetMode() == c4d.Mpolygons: return

#conversion de la sélection
bc = c4d.BaseContainer()
bc[c4d.MDATA_CONVERTSELECTION_LEFT] = 2
bc[c4d.MDATA_CONVERTSELECTION_RIGHT] = 0
bc[c4d.MDATA_CONVERTSELECTION_TOLERANT] = False
c4d.utils.SendModelingCommand(command =c4d.MCOMMAND_CONVERTSELECTION,
list = [op],
mode = c4d.MODIFY_ALL,
bc = bc,
doc = doc)

c4d.CallCommand(12109) # Delete

#Optimisation uniquement pour les points inutiles
bc = c4d.BaseContainer()
bc[c4d.MDATA_OPTIMIZE_POINTS] = False
bc[c4d.MDATA_OPTIMIZE_POLYGONS] = False
bc[c4d.MDATA_OPTIMIZE_UNUSEDPOINTS] = True
c4d.utils.SendModelingCommand(command = c4d.MCOMMAND_OPTIMIZE,
list = [op],
mode = c4d.MODELINGCOMMANDMODE_POINTSELECTION,
bc = bc,
doc = doc)

c4d.EventAdd()

if __name__=='__main__':
main()

En rajoutant une commande pour convertir la sélection ...

César Vonc
06/03/2016, 21h11
Sauf qu'on perd notre sélection de points. Pour ça j'ai par contre rien trouvé de mieux que de l'enregistrer dans une propriété tampon (prise en charge automatiquement par les commandes) :



import c4d

def chargeSel(obj, prop) :
prop.GetBaseSelect().CopyTo(obj.GetPointS())
prop.Remove()

def sauveSel(obj) :
bs = obj.GetPointS()
prop = obj.MakeTag(c4d.Tpointselection)
bs.CopyTo(prop.GetBaseSelect())
return prop

def main():
if not op or not op.CheckType(c4d.Opolygon) : return
if doc.GetMode() != c4d.Mpolygons : return

doc.AddUndo(c4d.UNDOTYPE_CHANGE, op)

# Enregistre les points sélectionnés dans une propriété tampon
tampon = sauveSel(op)

# Sélectionne les points des polys sélectinnés
bc = c4d.BaseContainer()
bc[c4d.MDATA_CONVERTSELECTION_LEFT] = 2
bc[c4d.MDATA_CONVERTSELECTION_RIGHT] = 0
bc[c4d.MDATA_CONVERTSELECTION_TOLERANT] = False
c4d.utils.SendModelingCommand(command = c4d.MCOMMAND_CONVERTSELECTION,
list = [op],
mode = c4d.MODELINGCOMMANDMODE_ALL,
bc = bc,
doc = doc)

# Supprime les polygones
c4d.utils.SendModelingCommand(command = c4d.MCOMMAND_DELETE,
list = [op],
mode = c4d.MODELINGCOMMANDMODE_POLYGONSELECTION,
doc = doc)

# Optimize les points des polys supprimés
bc = c4d.BaseContainer()
bc[c4d.MDATA_OPTIMIZE_POINTS] = False
bc[c4d.MDATA_OPTIMIZE_POLYGONS] = False
bc[c4d.MDATA_OPTIMIZE_UNUSEDPOINTS] = True

c4d.utils.SendModelingCommand(command = c4d.MCOMMAND_OPTIMIZE,
list = [op],
mode = c4d.MODELINGCOMMANDMODE_POINTSELECTION,
bc = bc,
doc = doc)

# Rétablit les points sélectionnés de base et supprime la propriété tampon
chargeSel(op, tampon)

doc.EndUndo()
c4d.EventAdd()

if __name__=='__main__':
main()



Marrant comme exercice. : p

oli_d
06/03/2016, 21h23
Sauf qu'on perd notre sélection de points.Pour ça j'ai par contre rien trouvé de mieux que de l'enregistrer dans une propriété tampon

C'est vrai, ça me paraissait trop compliqué à corriger, mais ta solution est vraiment pas con !

leo3d
06/03/2016, 21h55
Sympa les gars ;)

Floc
06/03/2016, 23h00
Oua super !
Merci beaucoup à tous.