pymaxwell - matériaux au hasard dans une scène MXS

Pour vous simplifier la vie
Avatar de l’utilisateur
Rodman
SL17
Messages : 1055

Re: pymaxwell - matériaux au hasard dans une scène MXS

Message 21 nov. 2012, 11:32

Merci ! 8)

Je patiente.

Avatar de l’utilisateur
Rodman
SL17
Messages : 1055

Re: pymaxwell - matériaux au hasard dans une scène MXS

Message 21 nov. 2012, 19:09

Il est toujours possible de calculer le vecteur normale d'un triangle à l'aide de ses vertex. :lol:
Comme ceci : http://www.developpez.net/forums/d27775 ... -triangle/
Mais bon, autant attendre la réponse d'un développeur. 8)

Avatar de l’utilisateur
Rodman
SL17
Messages : 1055

Re: pymaxwell - matériaux au hasard dans une scène MXS

Message 23 nov. 2012, 18:55

J'ai réussi à récupérer les angles. Mais cela n'est pas suffisant pour trier les faces : chaque triangle partage 3 angles du coup c'est débile mon code. :?

Par ailleurs je sais grouper des triangles ensemble et appliquer un matériau à ce groupe.

Voici des "print" de mon code (toujours tester sur le même objet) pour voir l'absurdité (ci-dessous). Une fois que j'ai un angle formé par 2 triangles adjacents, et que je récupère le numéro d'index de chaque face. Puisque chaque face à 3 côtés, il y aura un effacement des données précédentes (si vous voyez ce que je veux dire).

Code : Tout sélectionner

Vertexes number = 13
Triangles number = 14
-------------------------------------------
13 vertexes [[-0.053902719169855118, -0.00019685039296746254, 0.060819152742624283], [-0.018342647701501846, -0.016023622825741768, 0.051065530627965927], [-0.07783721387386322, -0.025297181680798531, 0.025259081274271011], [-0.042277116328477859, -0.039196088910102844, 0.015505461953580379], [-0.0067170439288020134, -0.018799846991896629, 0.0089624077081680298], [-0.093895100057125092, -0.006031242199242115, -0.010300991125404835], [-0.05833502858877182, -0.0045453393831849098, -0.020054610446095467], [-0.022774983197450638, 0.022785117849707603, -0.026597665622830391], [0.012785116210579872, 0.011106172576546669, -0.022526035085320473], [-0.083905257284641266, -0.0065697235986590385, -0.045861061662435532], [-0.048345189541578293, 0.026567185297608376, -0.055614680051803589], [-0.012785116210579872, 0.039196088910102844, -0.062157735228538513], [0.022774957120418549, -0.00022733045625500381, -0.058086108416318893]]
-------------------------------------------
14 triangles [[0, 1, 3], [3, 2, 0], [4, 3, 1], [2, 3, 6], [6, 5, 2], [3, 4, 7], [7, 6, 3], [8, 7, 4], [5, 6, 10], [10, 9, 5], [6, 7, 11], [11, 10, 6], [7, 8, 12], [12, 11, 7]]
-------------------------------------------
14 normales [[0.00033678563695173141, 0.0014979663459833703, -0.0012028199383163976], [0.00024942705820134867, 0.0014979675601114982, -0.001225233550488045], [-0.00087691046590074664, 0.0014211231431600193, -0.00033584135933939323], [0.00083221636741259795, 0.0014211424065253969, 0.0010089966003957833], [0.00013507382784068867, 0.0014211412248788038, 0.00070895864316875001], [-0.00045319917753601502, 0.0013695867498923911, 0.0018062859745366418], [-0.00074515127184805654, 0.0013695855945934123, 0.0016710523103000072], [0.00024598553759196812, 0.001199137746711449, 0.001291225689728611], [0.00025062091427573759, 0.0011670815294573013, 0.0010915196712377312], [-0.0011836029598101148, 0.0011670814030723155, -0.00035018094488147716], [-0.00086449507240552066, 0.0011991534383941835, 0.00031054724337635682], [-0.00024551372583012446, 0.0011991546147419006, 0.00098020294473016682], [0.00046144998738763677, 0.0013051946839205235, -0.00028634968921405256], [0.0013350801869786411, 0.0013051936931086396, 0.00097741004997808738]]
-------------------------------------------
42 edges [((0, 1), 0), ((1, 3), 0), ((3, 0), 0), ((3, 2), 1), ((2, 0), 1), ((0, 3), 1), ((4, 3), 2), ((3, 1), 2), ((1, 4), 2), ((2, 3), 3), ((3, 6), 3), ((6, 2), 3), ((6, 5), 4), ((5, 2), 4), ((2, 6), 4), ((3, 4), 5), ((4, 7), 5), ((7, 3), 5), ((7, 6), 6), ((6, 3), 6), ((3, 7), 6), ((8, 7), 7), ((7, 4), 7), ((4, 8), 7), ((5, 6), 8), ((6, 10), 8), ((10, 5), 8), ((10, 9), 9), ((9, 5), 9), ((5, 10), 9), ((6, 7), 10), ((7, 11), 10), ((11, 6), 10), ((11, 10), 11), ((10, 6), 11), ((6, 11), 11), ((7, 8), 12), ((8, 12), 12), ((12, 7), 12), ((12, 11), 13), ((11, 7), 13), ((7, 12), 13)]
-------------------------------------------
32 couples of vertexes [((1, 3), 0), ((3, 0), 0), ((3, 2), 1), ((0, 3), 1), ((4, 3), 2), ((3, 1), 2), ((2, 3), 3), ((3, 6), 3), ((6, 2), 3), ((6, 5), 4), ((2, 6), 4), ((3, 4), 5), ((4, 7), 5), ((7, 3), 5), ((7, 6), 6), ((6, 3), 6), ((3, 7), 6), ((8, 7), 7), ((7, 4), 7), ((5, 6), 8), ((6, 10), 8), ((10, 5), 8), ((5, 10), 9), ((6, 7), 10), ((7, 11), 10), ((11, 6), 10), ((10, 6), 11), ((6, 11), 11), ((7, 8), 12), ((12, 7), 12), ((11, 7), 13), ((7, 12), 13)]
-------------------------------------------
16 interior edges [(1, 3), (3, 0), (3, 2), (4, 3), (3, 6), (6, 2), (6, 5), (4, 7), (7, 3), (7, 6), (8, 7), (6, 10), (10, 5), (7, 11), (11, 6), (12, 7)]
-------------------------------------------
47.6641960886
2.64895454151
73.0268681641
63.8212700994
46.9667731676
22.3403388355
16.9386797686
20.0737296296
8.00020073234
35.6465213919
58.6426982466
18.320582739
75.60220873
77.0298863014
34.3943786896
46.7919964271
-------------------------------------------
14 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
14 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
Roch, as-tu une idée pour outrepasser ce problème ?

Peux-être faire une moyenne des 3 angles qui se rapporte à chaque face ?

Avatar de l’utilisateur
Roch
Messages : 7634
Localisation : Marseille - France
Contact :

Re: pymaxwell - matériaux au hasard dans une scène MXS

Message 25 nov. 2012, 21:30

hum c'est chaud tout ça. On est parti un peu vite sur le code peut être...

Je vois bien le souci et les ennuis qu'on va avoir derrière également...

Vite une bière pour m'aider dans la réflexion...

Avatar de l’utilisateur
Rodman
SL17
Messages : 1055

Re: pymaxwell - matériaux au hasard dans une scène MXS

Message 25 nov. 2012, 22:14

J'ai de nouvelles sources.

D'abord ce plugin : http://www.enrichpro.com/en/richdirt/features.html Il marche comme le VrayDirt.

En regardant les images du site. On en ressort que les zones de "dirt" commencent où l'angle (en degré) entre les normales des faces est le plus grand (en valeur absolue). Et que si l'angle entre les normales des faces = 0 (en degré) alors il n'y a pas de "dirt".

L’inconvénient du site est qu'il présente son plugin que sur des objets qui sont "plats" (cube, façade, etc.) du coup il faudrait tester le plugin sur un objet "patate" pour vraiment comprendre son fonctionnement. C'est la même chose pour le VrayDirt.

J'ai l'impression qu'au final on recherche à faire un "ambient occlusion" http://loulou.developpez.com/tutoriels/ ... occlusion/

Le mauvais point est que l'on n'a pas 10 000 fonctions avec pymaxwell et qu'on applique un matériau au mieux que par face.

Avatar de l’utilisateur
Roch
Messages : 7634
Localisation : Marseille - France
Contact :

Re: pymaxwell - matériaux au hasard dans une scène MXS

Message 27 nov. 2012, 08:27

on s'est peut être attaqué à un trop gros morceau...

Avatar de l’utilisateur
Rodman
SL17
Messages : 1055

Re: pymaxwell - matériaux au hasard dans une scène MXS

Message 27 nov. 2012, 12:23

Oui. Pour arriver au résultat final sans map procédurale c'est trop lourd à calculer. Il faudrait enregistrer un matériau par face. Chaque matériau ayant 3 bsdf avec 3 map + uv différents pour intégrer le "dirt" partant de chaque edge de la face.

Bref on est foutu.

Avatar de l’utilisateur
salvatore
SL24
Messages : 1998
Localisation : Paris

Re: pymaxwell - matériaux au hasard dans une scène MXS

Message 27 nov. 2012, 14:09

Roch a écrit :on sait peut être attaquer à un trop gros morceau...
à tel point que tu en as perdu ton orthographe.. 8)

maître cappello...pour vous servir
attend avec impatience les octocores et decacores

Avatar de l’utilisateur
Rodman
SL17
Messages : 1055

Re: pymaxwell - matériaux au hasard dans une scène MXS

Message 12 janv. 2013, 01:23

Je vous donne le code que j'avais écrit avec l'aide de fonctions que j'avais récupéré par la personne qui écrit les scripts Python pour Blender.
Si cela intéresse quelqu'un. Attention car ce n'est pas facile à lire !

Code : Tout sélectionner

################################################################
# Copyright 2012 Rodman
################################################################

from pymaxwell import *
import numpy as np
import math


def _GetEdgeData(faces):
    """Find edges from faces, and some lookup dictionaries.

    Args:
    faces: list of list of int - each a closed CCW polygon of vertex indices
    Returns:
    (list of ((int, int), int), dict{ int->list of int}) -
    list elements are ((startv, endv), face index)
    dict maps vertices to edge indices
    """
    edges = []
    vtoe = dict()
    for findex, f in enumerate(faces):
        nf = len(f)
        for i, v in enumerate(f):
            endv = f[(i+1) % nf]
            edges.append(((v, endv), findex))
            eindex = len(edges)-1
            if v in vtoe:
                vtoe[v].append(eindex)
            else:
                vtoe[v] = [ eindex ]
    return (edges, vtoe)


def _GetFaceGraph(faces, edges, vtoe):
    """Find the face adjacency graph.

    Faces are adjacent if they share an edge,
    and the shared edge goes in the reverse direction.

    Args:
    faces: list of list of int
    edges: list of ((int, int), int) - see _GetEdgeData
    vtoe: dict{ int->list of int } - see _GetEdgeData
    Returns:
    (list of  list of int, list of bool) -
    first list: each sublist is adjacent face indices for each face
    second list: maps edge index to True if it separates adjacent faces
    """
    face_adj = [ [] for i in range(len(faces)) ]
    is_interior_edge = [ False ] * len(edges)
    for e, ((vs, ve), f) in enumerate(edges):
        for othere in vtoe[ve]:
            ((_, we), g) = edges[othere]
            if we == vs:
                # face g is adjacent to face f
                if g not in face_adj[f]:
                    face_adj[f].append(g)
                    is_interior_edge[e] = True
                # Don't bother with mirror relations, will catch later
    return (face_adj, is_interior_edge)


def _FindFaceGraphComponents(faces, face_adj):
    """Partition faces into connected components.

    Args:
    faces: list of list of int
    face_adj: list of list of int - see _GetFaceGraph
    Returns:
    (list of list of int, list of int) -
    first list partitions face indices into separate lists, each a component
    second list maps face indices into their component index
    """
    if not faces:
        return ([], [])
    components = []
    ftoc = [ -1 ] * len(faces)
    for i in range(len(faces)):
        if ftoc[i] == -1:
            compi = len(components)
            comp = []
            _FFGCSearch(i, faces, face_adj, ftoc, compi, comp)
            components.append(comp)
    return (components, ftoc)


def _FFGCSearch(findex, faces, face_adj, ftoc, compi, comp):
    """Depth first search helper function for _FindFaceGraphComponents

    Searches recursively through all faces connected to findex, adding
    each face found to comp and setting ftoc for that face to compi.
    """
    comp.append(findex)
    ftoc[findex] = compi
    for otherf in face_adj[findex]:
        if ftoc[otherf] == -1:
            _FFGCSearch(otherf, faces, face_adj, ftoc, compi, comp)

def crossproduct(a, b):
    c = [a[1]*b[2] - a[2]*b[1],
         a[2]*b[0] - a[0]*b[2],
         a[0]*b[1] - a[1]*b[0]]

    return c


def dotproduct(v1, v2):
    return sum((a*b) for a, b in zip(v1, v2))


def length(v):
    return math.sqrt(dotproduct(v, v))


def angle_deg_math(v1, v2):
    angle = math.acos(dotproduct(v1, v2) / (length(v1) * length(v2)))
    return (angle * 360 / 2 / np.pi) # angle in degrees


def angle_deg_numpy(v1, v2):
    """
    x = np.array([1,2,3])
    y = np.array([-7,8,9])
    print angle_deg_numpy(x,y)
    """
    dot = np.dot(v1, v2)
    v1_modulus = np.sqrt((v1*v1).sum())
    v2_modulus = np.sqrt((v2*v2).sum())
    cos_angle = dot / v1_modulus / v2_modulus # cosinus of angle between x and y
    angle = np.arccos(cos_angle)
    return (angle * 360 / 2 / np.pi) # angle in degrees


def unique(a):
    """ return the list with duplicate elements removed """
    return list(set(a))

def intersect(a, b):
    """ return the intersection of two lists """
    return list(set(a) & set(b))

def union(a, b):
    """ return the union of two lists """
    return list(set(a) | set(b))


def adjacent_face_edge():

    # Load a scene
    scene = Cmaxwell(mwcallback)
    ok = scene.readMXS("f:/obj_14s.mxs")
    if ok == 0:
        print("Error reading mxs");
        return 0;

    # Add new material to scene
    material = scene.createMaterial("material");

    # Assign MXM to material
    ok = material.read("f:/black.mxm");
    if ok == 0:
	    print("Error reading material from disk");
    else:
	    print("ok");

    # Add new material to scene
    material2 = scene.createMaterial("material2");

    # Assign MXM to material
    ok = material2.read("f:/yellow.mxm");
    if ok == 0:
	    print("Error reading material from disk");
    else:
	    print("ok");
    

    # Loop through objects
    it = CmaxwellObjectIterator()
    obj = it.first( scene )

    while not obj.isNull():

        # Clean geometry
        obj.cleanGeometry()

        # Get number of vertexes, normales, and triangles
        number_vertexes = obj.getNumVertexes()
        number_normals = obj.getNumNormals()
        number_triangles = obj.getNumTriangles()        
        print "Vertexes number = " + str( number_vertexes )
        print "Normals number = " + str( number_normals )
        print "Triangles number = " + str( number_triangles )
        print "-------------------------------------------"

        # Get the vertex list
        array_vertex = []       
        for i in range(number_vertexes) :        
            x_vertex = obj.getVertex(i,0)[0]
            y_vertex = obj.getVertex(i,0)[1]
            z_vertex = obj.getVertex(i,0)[2]
            array_vertex.append([x_vertex,y_vertex,z_vertex])
        print len(array_vertex),array_vertex
        print "-------------------------------------------"

        """
        #Get the normal list
        array_normal = []
        for i in range(number_normals) : 
            x_normal = obj.getNormal(i,0)[0]
            y_normal = obj.getNormal(i,0)[1]
            z_normal = obj.getNormal(i,0)[2]
            array_normal.append([x_normal,y_normal,z_normal])
        print len(array_normal),array_normal
        """   

        # Get the face list
        faces = []
        #faces_normal = []
        for i in range(number_triangles) :
            list_triangles = obj.getTriangle(i)
            #print list_triangles
            faces.append(list(obj.getTriangle(i)[0:3]))
            #faces_normal.append(obj.getTriangle(i)[3:6])         
        print len(faces),faces
        #print len(faces_normal),faces_normal
        print "-------------------------------------------"
            
        # Get the list of the vertex list of face
        faces_vertex_p1 = []
        faces_vertex_p2 = []
        faces_vertex_p3 = []
        face_vertex_list = []
        for i in range(len(faces)):
            for j, vertex in enumerate(array_vertex):
                if faces[i][0] == j:
                    faces_vertex_p1.append(vertex)
                if faces[i][1] == j:
                    faces_vertex_p2.append(vertex)
                if faces[i][2] == j:
                    faces_vertex_p3.append(vertex)
        for i in range(len(faces)):
            face_vertex_list.append([faces_vertex_p1[i],faces_vertex_p2[i],faces_vertex_p3[i]])

        # Get the normal vector of each face
        S1S2 = []
        S1S3 = []
        face_normales = []
        for i in range(len(face_vertex_list)):
            x1 = face_vertex_list[i][0][0]
            y1 = face_vertex_list[i][0][1]
            z1 = face_vertex_list[i][0][2]

            x2 = face_vertex_list[i][1][0]
            y2 = face_vertex_list[i][1][1]
            z2 = face_vertex_list[i][1][2]

            x3 = face_vertex_list[i][2][0]
            y3 = face_vertex_list[i][2][1]
            z3 = face_vertex_list[i][2][2]
        
            S1S2.append([x2-x1,y2-y1,z2-z1])
            S1S3.append([x3-x1,y3-y1,z3-z1])
            face_normales.append(crossproduct(S1S2[i], S1S3[i]))
        print len(face_normales),face_normales
        print "-------------------------------------------"

        """
        print obj.getTriangle(1)[1:4]
        print obj.getTriangle(2)[-1]
        """

        (edges, vtoe) = _GetEdgeData(faces)
        print len(edges),edges 
        print len(vtoe),vtoe
        print "-------------------------------------------"

        
        (face_adj, is_interior_edge) = _GetFaceGraph(faces, edges, vtoe)
        #print len(face_adj),face_adj
        #print len(is_interior_edge),is_interior_edge
        
        """
        (components, ftoc) = _FindFaceGraphComponents(faces, face_adj)
        print len(components[0]),components
        print len(ftoc),ftoc
        """

        interior_edge_list = []
        for i in range(len(is_interior_edge)):
            if is_interior_edge[i] == True:
                interior_edge_list.append(edges[i])
    
        print len(interior_edge_list),interior_edge_list
        print "-------------------------------------------"

        in_edge_list = []

        for i in range(len(interior_edge_list)):   
            in_edge_list.append(interior_edge_list[i][0:2][0])

        in_edge_list_clean = []
        for i, (e1, e2) in enumerate(in_edge_list):
            if ((e1, e2) not in in_edge_list[:i]) and ((e2, e1) not in in_edge_list[:i]):
                in_edge_list_clean.append((e1, e2))
 
        print len(in_edge_list_clean), in_edge_list_clean
        print "-------------------------------------------"

        face_normales_binome = []
        face_binome = []

        triangles_moins_60 = []
        triangles_plus_60 = []
        
        for i in range(len(in_edge_list_clean)):
            for j in range(len(faces)):
                
                if len(intersect(in_edge_list_clean[i],faces[j])) == 2:
                    face_normales_binome.append(face_normales[j])
                    face_binome.append(j)
                    
                    if len(face_normales_binome) ==2 :
                        x = np.array(face_normales_binome[0])
                        y = np.array(face_normales_binome[1])
                        angle_face = angle_deg_numpy(x,y)
                        print angle_face
                        face_normales_binome = []
                        
                        if angle_face > 60:
                            triangles_moins_60.append(face_binome)
                        elif angle_face <= 60:
                            triangles_plus_60.append(face_binome)
        
        print "-------------------------------------------"
        
        aaa = sorted(list(set(triangles_moins_60[0])))
        print len(aaa),aaa

        bbb = sorted(list(set(triangles_plus_60[0])))
        print len(bbb),bbb
        
        """
        aaa = list(set(triangles_moins_30))
        print aaa
        cluster = scene.addCluster("clustername2")
        cluster.addObject( obj, aaa )

        bbb = list(set(triangles_plus_30))
        cluster2 = scene.addCluster("clustername2")
        cluster2.addObject( obj, bbb )
        """


        obj = it.next()

    # Save modified scene to a new MXS
    scene.writeMXS("f:/testy.mxs");

    # Close scene
    scene.freeScene()
    return 1

adjacent_face_edge()

Répondre