Blender 2.25/2.26...etc.
Python : 
Modélisation et structure:
repérer les segments d'un mesh
et 
accessoirement les faces qui 
empêchent de décimer un mesh
    Début   Index
précédentScript Python
Changer de camera Suivant

Avant d'utiliser ce script, il est indispensable de d'assimiler certaines notions:

1/ Les meshes de Blender sont comme des voiles qui enrobent les objets : Sphere, Cube, Tore, Cone etc. Fondamentalement rien ne les distingue.

2/ Ces voiles ne sont pas de vrais d'objet  << mathématiques >>,  ils en imitent seulement la forme.

3/ Le système de décimation de Blender n'accepte que des voiles continus

4/ Si un voile est << cousu >> sur un premier ailleurs que sur la limite extérieure, la décimation ne fonctionnera plus.

Ces voiles continus ont, malgré tout, certaines propriétés qui les regroupent sous le nom de "manifold".

Exemple de mesh reconnu comme un manifold

Exemple de mesh non reconnu comme un manifold


 
 

L'axe central de ce mesh partagé par plus de deux faces rend impossible l'utilisation de l'outil de décimation .

Après application du script  en mode faceselect toutes les face concernées sont sélectionnées et peuvent être traitées par un Separate, pkey ou un Split :



 
 
 
 

#------------------------------------
# Reperage des faces engendrant
# des erreurs de type no manifold mesh
# (c) J-M Soler mai 2003
#------------------------------------
#------------------------------------
# L'objectif premier de ce script etait de 
# creer un objet qui n'est pas gere 
# pas la structure de donnes de 
# Blender: les segments
#
# Ces segments sont reperes par 
# face et cette attribution est utilisee
# pour retrouver ceux qui n'appartiennent
# qu'a une seule.
#
# 
# Accidentellemeent la premiere version
# du script original montrait aussi
# ceux qui étaient relies a plus d'une
# face et ainsi de reperer ce
# qui empeche blender de realiser
# une decimation correcte.
#
# Plusieurs conditions sont necessaires
# pour donner à ce script un peu d'efficacite:
#
# 1/ le mesh cree en fin de parcourt
# qui se nomme  "test" doit être efface
# avant de relancer le script une seconde
# fois
#
# 2/ le mesh original doit avoir recu
# des coordonnees uv pour que le script puisse
# les utiliser afin de pointer aussi les faces
# fautives en mode FaceSelect. L'execution
# du script lui-même ne doit pas se faire
# en mode FaceSelect.
#------------------------------------
import Blender

#------------------------------------
# o est un objet mesh que l'on doit
# imperativement nommer 
#------------------------------------
o=Blender.Object.Get('Plane')

#------------------------------------
# m copie des donnees du mesh
#------------------------------------
m=Blender.NMesh.GetRaw(o.data.name)

#------------------------------------
# mn est second receptacle pour les donnees
# traitees
#------------------------------------
mn=Blender.NMesh.GetRaw()

#------------------------------------
# un tableau pou regrouper toutes les 
# paires de sommets qui constitue un 
# segment
#------------------------------------
segment=[]

#------------------------------------
# un tableau pour identier les segments
# qui sont utilises par une face
#------------------------------------
faceseg=[]

#------------------------------------
# On analyse toutes les faces
#------------------------------------
for f in m.faces:
   
   #------------------------------------
   # Verifier que le travail est necessaire
   #------------------------------------
   #if len(f.v)>=3:
   if 1==1:
     #----------------------
     # Creation d'un receptacle
     # pour les infos collectees
     # on ne s'interesse qu'aux
     # valeur d'index des sommets 
     #----------------------
     face=[]
     #----------------------
     # Analyser chaque paire de sommets...
     #----------------------
     for n in range(len(f.v)-1):
        #----------------------
        # Comme les extremites peuvent
        # apparaitre dans un sens ou
        # dans l'autre...  
        #----------------------
        s0=[f.v[n].index,
            f.v[n+1].index]
        s1=[f.v[n+1].index,
             f.v[n].index]
        #----------------------
        # on teste la presence des 
        # deux combinaisons dans
        # la liste de segments qui
        # sont donc des paires de
        # positions de sommets dans
        # la listes des mesh.verts
        #----------------------
        if s0 not in segment and\
             s1 not in segment:
            #----------------------
            # ...si elle n'y est pas
            # on l'ajoute
            #----------------------
            segment.append(s0)
        #----------------------
        # On enregistre la position 
        # dans la liste de segments
        # de la face courante.
        #
        # Comme on ne sait pas dans quel
        # ordre les sommets du
        # segment ont ete enregistres
        # on essaye les deux possibilites. 
        #----------------------
        try:
          face.append(segment.index(s0))
        except:
          face.append(segment.index(s1))
     #----------------------
     # On complete le face en 
     # testant le segment constitue
     # du premier et du dernier
     # sommet de la liste
     #----------------------
     s2=[f.v[0].index,f.v[n+1].index]
     s3=[f.v[n+1].index,f.v[0].index]
     #----------------------
     # Meme procedure que les autres 
     # paires...
     #----------------------
     if s2 not in segment and\
             s3 not in segment:
            segment.append(s2)
     #----------------------
     # ...
     #----------------------
     try:
          face.append(segment.index(s2))
     except:
          face.append(segment.index(s3))
     #----------------------
     # On ajoute la liste des segments
     # de la face traitee
     # a la liste des faces
     # deja analysees
     #----------------------
     faceseg.append(face[:])
     #----------------------
     # lordre de la liste faceseg correspont
     # exactement a celui de la liste mesh.faces
     #----------------------
   else:
     
     pass
#print len(faceseg), len(segment)
#------------------------------------
# Le principe consiste à filtrer toute la
# liste de segment face par face.
#
# Si un segment se trouve deja dans la liste
# alors il est marque' ...
#
# Si un segment n'a recu qu'une marque
# il appartient au perimetre de la forme
# S'il en a deux c'est qu'il fait partie
# d'un voile/enveloppe/plan gauchi au choix
# qui pourra être decime.
#
# S'il y en a 3 et plus les faces qui portent
# ce segment devront être separees du
# mesh principal.
#
# La liste segmentface gardera les
# marques de ce tri.
#------------------------------------
segmentface=len(segment)*[0]
tampon=[]
#------------------------------------
# nomanifoldkiller gere la liste des 
# faces qui partagent un segment
# avec plus de 2 marques.
#------------------------------------
nomanifoldkiller=[]
m0=0
for f in faceseg:
   for s in f:
       if s in tampon:
          segmentface[s]+=1
          if segmentface[s]>1:
             if m0 not in nomanifoldkiller:
                  nomanifoldkiller.append(m0)
       else:
          tampon.append(s)
   m0+=1       
m0=0
#------------------------------------
# Au premier passage, les faces fautives
# ne sont pas toutes marquees. Il faut donc 
# les reprendre a partir de de la liste de segments
# pour reconnaitre celles qui n'ont pas ete
# deja enregistrees dans nomanifoldkiller
#------------------------------------
for f in faceseg:
   for s in f:
      if segmentface[s]>1:
             if m0 not in nomanifoldkiller:
                  nomanifoldkiller.append(m0)
   m0+=1
#------------------------------------
# Creation d'un mesh concretisant la limite
# du champ de faces genantes
#------------------------------------
s=0
for s0 in segmentface:
   if s0>1:
      for n in [0,1]:
        vo=m.verts[segment[s][n]].co
        vn=Blender.NMesh.Vert()
        vn.co.x=vo.x
        vn.co.y=vo.y
        vn.co.z=vo.z
        mn.verts.append(vn)
       
      l=len(mn.verts)
      f=Blender.NMesh.Face()
      f.append(mn.verts[l-1])
      f.append(mn.verts[l-2])
      mn.faces.append(f)
   s+=1
#------------------------------------
# Marquage des faces fautives dans le
# la zone uvmapping de telle maniere
# qu'un passage en mode FaceSelect
# les rende pleinement visibles sur
# l'objet meme. 
#------------------------------------
for f in  m.faces:
          f.flag=0

for f in nomanifoldkiller:
   m.faces[f].flag=1

Blender.NMesh.PutRaw(m,m.name)

o2=Blender.NMesh.PutRaw(mn,'test')

#print o2.name
o2.LocX,o2.LocY,o2.LocZ=o.LocX,o.LocY,o.LocZ
o2.SizeX,o2.SizeY,o2.SizeZ=o.SizeX,o.SizeY,o.SizeZ
o2.RotX,o2.RotY,o2.RotZ=o.RotX,o.RotY,o.RotZ

del nomanifoldkiller
del segmentface
del faceseg
del segment
précédentScript Python
 Changer de camera Suivant
Vers le  Haut de page

Les questions concernant cette page  peuvent être posées sur  :
 news://news.zoo-logique.org/3D.Blender

Livre en français
Blender : apprenez, pratiquez, Créez, livre, Ed. Campus Press, coll. Starter Kit
Blender Starter Kit

Forum
FAQ
Lexique
Didacticiels
Compilations
Blender2KT
Débuter
Modelage
Blender python
Materiaux
Lumière
Animation
API python (eng)
Archives nzn
Statistiques
Doc flash Sculptris
Galerie Sculptris

mon site de démos sur youtube