Пример #1
0
def getMarkerType(context, mesh, landmark):
    indices = np.array([vid for vid in landmark.v_indices], dtype=int);
    ratios = np.array([r for r in landmark.v_ratios]);
    c_nz = np.count_nonzero(ratios);
    arg_sorted = np.argsort(ratios)[::-1];
    
    v_indices = None;
    bm = getBMMesh(context, mesh, useeditmode=False);    
    ensurelookuptable(bm);
    if(c_nz == 1):
        v_indices = indices[arg_sorted[[0]]];
        location = bm.verts[v_indices[0]].co.to_tuple();
        bm.free();
        return 'VERTEX', v_indices[0], location, [location];
    elif (c_nz == 2):
        v_indices = indices[arg_sorted[[0, 1]]];
        edges_1 = np.array([e.index for e in bm.verts[v_indices[0]].link_edges]);
        edges_2 = np.array([e.index for e in bm.verts[v_indices[1]].link_edges]);
        edge_common = np.intersect1d(edges_1, edges_2);
        location = tuple([val for val in landmark.location]);
        edge_locations = [bm.verts[v_indices[0]].co.to_tuple(), bm.verts[v_indices[1]].co.to_tuple()];
        bm.free();
        return 'EDGE', edge_common.tolist()[0], location, edge_locations;
    elif(c_nz == 3):
        v_indices = indices[arg_sorted[[0, 1, 2]]];
        faces_1 = np.array([f.index for f in bm.verts[v_indices[0]].link_faces]);
        faces_2 = np.array([f.index for f in bm.verts[v_indices[1]].link_faces]);
        faces_3 = np.array([f.index for f in bm.verts[v_indices[2]].link_faces]);
        face_common = reduce(np.intersect1d, (faces_1, faces_2, faces_3));
        location = tuple([val for val in landmark.location]);
        face_locations = [bm.verts[v_indices[0]].co.to_tuple(), bm.verts[v_indices[1]].co.to_tuple(), bm.verts[v_indices[2]].co.to_tuple()];
        bm.free();
        return 'FACE', face_common.tolist()[0], location, face_locations;
    
    return None, None, None;
Пример #2
0
def applyVertexColors(context, mesh, colors,*, v_group_name = "lap_errors", for_vertices = True):
    if(None == mesh.data.vertex_colors.get(v_group_name)):
        mesh.data.vertex_colors.new(v_group_name);
    
    vertex_colors = mesh.data.vertex_colors[v_group_name];
    vertex_colors.active = True;
    try:
        material = bpy.data.materials[mesh.name+'_'+v_group_name];
    except KeyError:
        material = bpy.data.materials.new(mesh.name+'_'+v_group_name);
    
    try:
        mesh.data.materials[mesh.name+'_'+v_group_name];
    except KeyError:
        mesh.data.materials.append(material);
    
    if(for_vertices):
        bm = getBMMesh(context, mesh, False);
        ensurelookuptable(bm);        
        for v in mesh.data.vertices:            
            b_vert = bm.verts[v.index];            
            for l in b_vert.link_loops:
                vertex_colors.data[l.index].color = colors[v.index];                
        bm.free();
    
    else:        
        for f in mesh.data.polygons:
            for lid in f.loop_indices:
                vertex_colors.data[lid].color = colors[f.index];
    
    
    material.use_vertex_color_paint = True;
    
    return vertex_colors, material;
Пример #3
0
def autoCorrectLandmarksData(context, mesh):
    print('AUTOCORRECT: CONSTRUCT KDTREE');
    kd = getKDTree(context, mesh);
    print('AUTOCORRECT: CONSTRUCT BMESH DATA');
    bm = getBMMesh(context, mesh, False);
    print('AUTOCORRECT: CONSTRUCT BMESH DATA ENSURETABLE');
    ensurelookuptable(bm);
    
    print('AUTOCORRECT: ITERATE LANDMARKS AND FIX POSITION');
    for gm in mesh.generic_landmarks:
        loc = [dim for dim in gm.location];
        mco = Vector((loc[0], loc[1], loc[2]));
        
        co, index, dist = kd.find(mco);
        v = bm.verts[index];        
        f = v.link_faces[0];
            
        a = f.loops[0].vert;
        b = f.loops[1].vert;
        c = f.loops[2].vert;        
        u,v,w,ratio,isinside = getBarycentricCoordinate(co, a.co, b.co, c.co);
        gm.v_ratios = [u, v, w];
        gm.v_indices = [a.index, b.index, c.index];
    
    print('AUTOCORRECT: FREE THE BMESH DATA');
    bm.free();
def deformWithMapping(context, owner_mesh, map_to, apply_on_mesh, mapped_points):
    print('DEFORM WITH MAPPING (UPLIFTING)');
    c = context;        
    constraint_positions = [];
    constraint_ids = [];
    invalid_indices = [];
    
    for vid, mapped_point in enumerate(mapped_points):
        if(mapped_point.is_valid):
            co = getGeneralCartesianFromBarycentre(mapped_point.bary_ratios, [map_to.data.vertices[m_vid].co for m_vid in mapped_point.bary_indices]);
            constraint_ids.append(vid);
            constraint_positions.append(co.to_tuple());
        else:
            invalid_indices.append(vid);
    
    constraint_positions = np.array(constraint_positions, dtype=np.float);
    constraint_ids = np.array(constraint_ids, dtype=np.int);
    invalid_indices = np.array(invalid_indices, dtype=np.int);
    vpos = getMeshVPos(apply_on_mesh);
    print('TOTAL VERTICES : #%s, INVALID INDICES : #%s'%(vpos.shape[0], invalid_indices.shape[0], ));
                
    if(invalid_indices.shape[0] > 0 and invalid_indices.shape[0] != vpos.shape[0]):       
        print('SOLVE WITH LSE FOR INVALID MAPPING INDICES');   
        v_group_name='Mapping-LSE-deformer';

        if(None == apply_on_mesh.vertex_groups.get(v_group_name)):
            apply_on_mesh.vertex_groups.new(name=v_group_name);
        
        group_ind = apply_on_mesh.vertex_groups[v_group_name].index;
        vertex_group = apply_on_mesh.vertex_groups[group_ind];    
        vertex_group.remove([v.index for v in apply_on_mesh.data.vertices]);
        apply_on_mesh.modifiers.clear();
        vertex_group.add(constraint_ids.tolist(), 1.0, 'REPLACE');
        
        lap_mod = apply_on_mesh.modifiers.new(name=vertex_group.name, type='LAPLACIANDEFORM');
        lap_mod.vertex_group = vertex_group.name;
        lap_mod.iterations = 3;#its was 1 before
        
        bpy.ops.object.select_all(action="DESELECT");
        apply_on_mesh.select = True;
        c.scene.objects.active = apply_on_mesh;
        
        bpy.ops.object.laplaciandeform_bind(modifier=lap_mod.name);
        
        bm = getBMMesh(c, apply_on_mesh, useeditmode=False);
        ensurelookuptable(bm);
        for i in range(constraint_ids.shape[0]):
            vid = constraint_ids[i];
            bm.verts[vid].co = constraint_positions[i];
        
        bm.to_mesh(apply_on_mesh.data);
        bm.free();
        bpy.ops.object.modifier_apply(modifier=v_group_name);
    
    elif(invalid_indices.shape[0] == vpos.shape[0]):
        print('NO SOLUTION AVAILABLE FROM THIS MAPPING');
    else:
        setMeshVPOS(apply_on_mesh, constraint_positions);
            
    return getMeshVPos(apply_on_mesh);
Пример #5
0
def applyVertexWeights(context, mesh, weights,*, v_group_name = "lap_errors"):
    if(None == mesh.vertex_groups.get(v_group_name)):
        mesh.vertex_groups.new(name=v_group_name);
    
    group_ind = mesh.vertex_groups[v_group_name].index;
    vertex_group = mesh.vertex_groups[group_ind];
    
    bm = getBMMesh(context, mesh, False);
    ensurelookuptable(bm);
    
    for v in mesh.data.vertices:
        n = v.index;
        vertex_group.add([n], weights[v.index], 'REPLACE');
        b_vert = bm.verts[v.index];               
    bm.free();
    
    return vertex_group;
    def createBonesMesh(self, context, mesh, bone_vertices, edge_indices):
        iso_name = mesh.name + "_geodesics_bones"
        try:
            existing = context.scene.objects[iso_name]
            existing.name = "READY_FOR_DELETE"
            bpy.ops.object.select_all(action="DESELECT")
            existing.select = True
            context.scene.objects.active = existing
            bpy.ops.object.delete()
        except KeyError:
            pass

        iso_mesh = bpy.data.meshes.new(iso_name)
        vertex_cos = getMeshVPos(mesh)
        # Make a new BMesh
        bm = bmesh.new()

        for vid in bone_vertices:
            x, y, z = vertex_cos[vid]
            v = bm.verts.new()
            v.co = (x, y, z)

        ensurelookuptable(bm)

        for (id_1, id_2) in edge_indices:
            v1, v2 = bm.verts[id_1], bm.verts[id_2]
            e = bm.edges.new([v1, v2])
            print(id_1, id_2)

        bm.to_mesh(iso_mesh)

        iso_mesh_obj = bpy.data.objects.new(iso_name, iso_mesh)
        iso_mesh_obj.data = iso_mesh
        context.scene.objects.link(iso_mesh_obj)
        iso_mesh_obj.location = mesh.location.copy()

        return iso_mesh_obj
def remeshMarkersAsVertices(context, mesh):
    edge_indices = []
    edge_locations = []

    face_indices = []
    face_locations = []
    print('GET ALL LANDMARKS ON EDGE OR FACE')
    for gm in mesh.generic_landmarks:
        gm_on_type, gm_on_type_index, gm_location, gm_locations = getMarkerType(
            context, mesh, gm)
        if (gm_on_type == 'EDGE'):
            edge_locations.append(gm_location)
            edge_indices.append(gm_on_type_index)
        elif (gm_on_type == 'FACE'):
            face_locations.append(gm_location)
            face_indices.append(gm_on_type_index)

    verts_and_locations = []
    bm = getBMMesh(context, mesh, useeditmode=False)
    print('POKE THE FACES FIRST')
    ensurelookuptable(bm)
    faces = [bm.faces[ind] for ind in face_indices]
    returned_geometry_faces = bmesh.ops.poke(bm, faces=faces)

    for i, vert in enumerate(returned_geometry_faces['verts']):
        verts_and_locations.append((vert.index, face_locations[i]))

    print('CUT THE EDGES NOW')
    ensurelookuptable(bm)
    edges = [bm.edges[ind] for ind in edge_indices]
    returned_geometry_edges = bmesh.ops.bisect_edges(bm, edges=edges, cuts=1)
    returned_vertices = [
        vert for vert in returned_geometry_edges['geom_split']
        if isinstance(vert, bmesh.types.BMVert)
    ]

    for i, vert in enumerate(returned_vertices):
        verts_and_locations.append((vert.index, edge_locations[i]))

    ensurelookuptable(bm)
    print('TRIANGULATING THE MESH AS THE LAST STEP FOR MESH')
    bmesh.ops.triangulate(bm, faces=bm.faces[:], quad_method=0, ngon_method=0)
    print('NOW MAKE THIS NEW TOPOLOGY TO BE THE MESH')
    bm.to_mesh(mesh.data)

    bm.free()

    for vid, co in verts_and_locations:
        mesh.data.vertices[vid].co = co
    print('AUTOCORRECT THE MESH LANDMARKS WITH NEW TOPOLOGY')
    autoCorrectLandmarksData(context, mesh)
Пример #8
0
def need_curvatures(mesh):
    loops = mesh.data.loops;
    faces = mesh.data.polygons;
    vertices = mesh.data.vertices;
    n = len(mesh.data.vertices);
    f_n = len(mesh.data.polygons);
    
    #get the normals and pointareas associated with each vertices
    normals, normals_np = need_normals(mesh);
    pointareas, cornerareas = need_pointareas(mesh);
    
    curv1, curv2, curv12 = [0.0] * n, [0.0] * n, [0.0] * n;
    pdir1, pdir2 = [Vector((0,0,0))] * n, [Vector((0,0,0))] * n;
    principalvalues = [];    
    
    for f in faces:
        p0 = vertices[loops[f.loop_indices[0]].vertex_index];
        p1 = vertices[loops[f.loop_indices[1]].vertex_index];
        p2 = vertices[loops[f.loop_indices[2]].vertex_index];
        pdir1[p0.index] = p1.co - p0.co;
        pdir1[p1.index] = p2.co - p1.co;
        pdir1[p2.index] = p0.co - p2.co;
        
    
    for v in vertices:
        pdir1[v.index] = pdir1[v.index].cross(normals[v.index]);
        pdir1[v.index].normalize();
        pdir2[v.index] = normals[v.index].cross(pdir1[v.index]);
        
    
    for f in faces:
        #Creating reference to all the vertices in this face 'f'
        p0 = vertices[loops[f.loop_indices[0]].vertex_index];
        p1 = vertices[loops[f.loop_indices[1]].vertex_index];
        p2 = vertices[loops[f.loop_indices[2]].vertex_index];
        
        verts = [p0, p1, p2];
        e = [p2.co - p1.co, p0.co - p2.co, p1.co - p0.co];
        #Normal-Tangent-Basis coordinate system per face
        t = e[0].copy();        
        t.normalize();
        
        n = e[0].cross(e[1]);
        b = n.cross(t);
        b.normalize();
        
        #Estimating curvatures based on the variation of normals along the edges
        
        m = [0.0, 0.0, 0.0];
        w = [[0.0,0.0,0.0], [0.0,0.0,0.0], [0.0,0.0,0.0]];
        
        for j in range(3):
            prev_ii = (j + 3 - 1) % 3;
            next_ii = (j + 1) % 3;
            
            u = e[j].dot(t);
            v = e[j].dot(b);
            
            w[0][0] = w[0][0] + (u * u);
            w[0][1] = w[0][1] + (u * v);
            w[2][2] = w[2][2] + (v * v);
            
            #Find the normal between the "normals of vertices" connected to this 
            #vertex on this face 'f'
            dn = normals[verts[prev_ii].index] - normals[verts[next_ii].index];
            #Find their angular deviation (cosine theta) w.r.to tangent t and basis b
            dnu = dn.dot(t);
            dnv = dn.dot(b);
            
            m[0] = m[0] + (dnu * u);
            m[1] = m[1] + ((dnu * v) + (dnv * u));
            m[2] = m[2] + (dnv * v);
            
        w[1][1] = (w[0][0] + w[2][2]);
        w[1][2] = (w[0][1]);
        
        diag = [0.0, 0.0, 0.0];
        
        solvable, A, rdiag = ldltdc(w, diag);
        
        if(not solvable):
            continue;
            
        x, A, B, rdiag = ldltsl(A, rdiag, m, m);
        
        for index, v in enumerate(verts):
            new_ku, newkuv, newkv = proj_curv(t, b, m[0], m[1], m[2], pdir1[v.index], pdir2[v.index]);
            wt = (cornerareas[f.index][v.index] / pointareas[v.index]);
            curv1[v.index] = curv1[v.index] + (wt * new_ku);
            curv12[v.index] = curv12[v.index]+ (wt * newkuv);
            curv2[v.index] = curv2[v.index] + (wt * newkv);
            
    k1_list, k2_list, p1_list, p2_list, mean_list, gaussian_list  = [], [], [], [], [], [];
    
    bm = getBMMesh(bpy.context, mesh, useeditmode=False);
    ensurelookuptable(bm);
    
    for v in bm.verts:
        averagelength = sum([e.calc_length() for e in v.link_edges]) * (1.0 / len(v.link_edges));# * 0.4;
        k1, k2, p1, p2 = diagonalize_curv(pdir1[v.index], pdir2[v.index], curv1[v.index], curv12[v.index], curv2[v.index], normals[v.index]);        
        principalvalues.append(((k1+k2)*0.5,k1*k2 ,k1, k2, p1, p2));
        p1 = p1 * averagelength;
        p2 = p2 * averagelength;       
        
        o_values = np.array([k1, k2]);
        p_values = [p1, p2];
        abs_values = np.abs(o_values);
        indices_max = np.argmax(abs_values);
        indices_min = np.argmin(abs_values);
        
        k1_list.append(o_values[indices_max]);
        k2_list.append(o_values[indices_min]);
#         k1_list.append(k1);
#         k2_list.append(k2);
        p1_list.append(p_values[indices_max]);
        p2_list.append(p_values[indices_min]);
        mean_list.append((k1+k2)*0.5);
        gaussian_list.append(k1*k2);
    sx = np.abs(k1_list) - np.abs(k2_list);
    
    bm.free();
    
    return np.array(k1_list), np.array(k2_list), sx, np.array(p1_list), np.array(p2_list), np.array(mean_list), np.array(gaussian_list), normals_np;
Пример #9
0
    def constructFromFile(self, mapping_file_path, owner_mesh, map_to):
        n_count = len(owner_mesh.data.vertices)
        self.mapped_points.clear()

        #         np_file = np.loadtxt(mapping_file_path, dtype={'names':['index','u','v','w'], 'formats':[int, float, float, float]});
        #         np_file = np.loadtxt(mapping_file_path, dtype={'names':['index','u','v','w'], 'formats':[int, float, float, float]});
        try:
            np_file = np.loadtxt(mapping_file_path, dtype=None)
        except ValueError:
            np_file = np.loadtxt(
                mapping_file_path,
                dtype=None,
                delimiter=",",
            )
        isTriangleMapped = False
        isVertexMapped = False
        isVertexToVertexMapped = False

        try:
            isTriangleMapped = (np_file.shape[1] == 4)
            isVertexMapped = (np_file.shape[1] == 6)
        except IndexError:
            isVertexToVertexMapped = True
            ids = np_file
            bm = getBMMesh(bpy.context, map_to, useeditmode=False)
            ensurelookuptable(bm)

        if (isTriangleMapped):
            ids = np_file[:, 0].astype(int)
            ratios = np_file[:, -3:].astype(float)
        elif (isVertexMapped):
            ids = np_file[:, :3].astype('int')
            ratios = np_file[:, -3:].astype(float)

        print(ids.shape, ids[0])
        loops = map_to.data.loops
        vertices = map_to.data.vertices

        for vid, v in enumerate(owner_mesh.data.vertices):
            mapped_point = self.mapped_points.add()
            if (isTriangleMapped):
                fid = ids[vid]
                u, v, w = ratios[vid]
                if (fid == -1):
                    mapped_point.is_valid = False
                else:
                    face = map_to.data.polygons[fid]
                    vids = [
                        loops[lid].vertex_index for lid in face.loop_indices
                    ]
                    vid1, vid2, vid3 = vids
            elif (isVertexMapped):
                vid1, vid2, vid3 = [int(ii) for ii in ids[vid]]
                u, v, w = ratios[vid]
                if (vid1 == -1 and vid2 == -1 and vid3 == -1):
                    mapped_point.is_valid = False

            elif (isVertexToVertexMapped):
                useVertexTargetId = int(ids[vid])
                if (useVertexTargetId != -1):
                    bmface = bm.verts[useVertexTargetId].link_faces[0]
                    t_verts = [l.vert.index for l in bmface.loops]
                    t_ratios = [0.0, 0.0, 0.0]
                    t_ratios[t_verts.index(useVertexTargetId)] = 1.0
                    vid1, vid2, vid3 = t_verts
                    u, v, w = t_ratios
                else:
                    mapped_point.is_valid = False
            if (mapped_point.is_valid):
                mapped_point.bary_ratios = [u, v, w]
                mapped_point.bary_indices = [vid1, vid2, vid3]

        self.mapping_is_valid = True
        try:
            bm.free()
        except NameError:
            pass

        return True