Exemplo n.º 1
0
def check_collision(
        object1,
        object2):  #Renvois les faces qui sont en colisions avec l'objet 2
    bpy.ops.object.mode_set(mode='OBJECT')
    bpy.ops.object.mode_set(mode='EDIT')
    bpy.ops.mesh.select_mode(type="FACE")
    #bpy.ops.mesh.select_all(action = 'DESELECT')
    bpy.ops.object.mode_set(mode='OBJECT')
    # Get objects world matrix
    mat1 = object1.matrix_world
    mat2 = object2.matrix_world

    # Get the geometry in world coordinates
    vert1 = [mat1 @ v.co for v in object1.data.vertices]
    poly1 = [p.vertices for p in object1.data.polygons]

    vert2 = [mat2 @ v.co for v in object2.data.vertices]
    poly2 = [p.vertices for p in object2.data.polygons]

    # Create the BVH trees
    bvh1 = BVHTree.FromPolygons(vert1, poly1)
    bvh2 = BVHTree.FromPolygons(vert2, poly2)

    # Test if overlap
    overlaping = bvh1.overlap(bvh2)
    if (overlaping):
        facesToSelect = set(map(lambda x: x[1], overlaping))
        for face in facesToSelect:
            object2.data.polygons[face].select = True

    bpy.ops.object.mode_set(mode='EDIT')

    return overlaping
def check_collision(object1, object2):
    # Get objects world matrix
    mat1 = object1.matrix_world
    mat2 = object2.matrix_world

    # Get the geometry in world coordinates
    vert1 = [mat1 @ v.co for v in object1.data.vertices]
    poly1 = [p.vertices for p in object1.data.polygons]

    vert2 = [mat2 @ v.co for v in object2.data.vertices]
    poly2 = [p.vertices for p in object2.data.polygons]

    # Create the BVH trees
    bvh1 = BVHTree.FromPolygons(vert1, poly1)
    bvh2 = BVHTree.FromPolygons(vert2, poly2)

    # Test if overlap
    overlaping = bvh1.overlap(bvh2)
    """
    if overlaping:
        print("Overlap")
    else:
        print("NO")
    """
    return overlaping
Exemplo n.º 3
0
    def fromMeshData(self, vectorList, polygonsIndices, epsilon):
        maxPolygonIndex = max(itertools.chain([-1], *polygonsIndices))
        minPolygonIndex = min(itertools.chain([0], *polygonsIndices))

        if 0 <= minPolygonIndex and maxPolygonIndex < len(vectorList):
            return BVHTree.FromPolygons(vectorList, polygonsIndices, epsilon = epsilon)
        return BVHTree.FromPolygons([], [], epsilon = epsilon)
Exemplo n.º 4
0
def physIntersection(name1, name2):
    # Get the objects
    obj1 = bpy.data.objects[name1]
    obj2 = bpy.data.objects[name2]

    # Get their world matrix
    mat1 = obj1.matrix_world
    mat2 = obj2.matrix_world

    # Get the geometry in world coordinates
    vert1 = [mat1 @ v.co for v in obj1.data.vertices]
    poly1 = [p.vertices for p in obj1.data.polygons]

    vert2 = [mat2 @ v.co for v in obj2.data.vertices]
    poly2 = [p.vertices for p in obj2.data.polygons]

    # Create the BVH trees
    bvh1 = BVHTree.FromPolygons(vert1, poly1)
    bvh2 = BVHTree.FromPolygons(vert2, poly2)

    # Test if overlap
    if bvh1.overlap(bvh2):
        return True
    else:
        return False
Exemplo n.º 5
0
def get_obj_mesh_bvht(obj, depsgraph, applyModifiers=True, world_space=True):
    if applyModifiers:
        if world_space:
            depsgraph.objects[obj.name].data.transform(obj.matrix_world)
            bvh = BVHTree.FromObject(obj, depsgraph)
            depsgraph.objects[obj.name].data.transform(obj.matrix_world.inverted())
            return bvh
        else:
            return BVHTree.FromObject(obj, depsgraph)
    else:
        if world_space:
            return BVHTree.FromPolygons([obj.matrix_world @ v.co for v in obj.data.vertices], [p.vertices for p in obj.data.polygons])
        else:
            return BVHTree.FromPolygons([v.co for v in obj.data.vertices], [p.vertices for p in obj.data.polygons])
def BVHTreeAndVerticesInWorldFromObj( obj ):
    mWorld = obj.matrix_world
    vertsInWorld = [mWorld @ v.co for v in obj.data.vertices]

    bvh = BVHTree.FromPolygons( vertsInWorld, [p.vertices for p in obj.data.polygons] )

    return bvh, vertsInWorld
Exemplo n.º 7
0
 def compute_bbox(self):
     self.bbox_verts = np.array([(self.location[0] - self.size / 2,
                                  self.location[1] - self.size / 2,
                                  self.location[2] - self.size / 2),
                                 (self.location[0] - self.size / 2,
                                  self.location[1] - self.size / 2,
                                  self.location[2] + self.size / 2),
                                 (self.location[0] - self.size / 2,
                                  self.location[1] + self.size / 2,
                                  self.location[2] - self.size / 2),
                                 (self.location[0] - self.size / 2,
                                  self.location[1] + self.size / 2,
                                  self.location[2] + self.size / 2),
                                 (self.location[0] + self.size / 2,
                                  self.location[1] - self.size / 2,
                                  self.location[2] - self.size / 2),
                                 (self.location[0] + self.size / 2,
                                  self.location[1] - self.size / 2,
                                  self.location[2] + self.size / 2),
                                 (self.location[0] + self.size / 2,
                                  self.location[1] + self.size / 2,
                                  self.location[2] - self.size / 2),
                                 (self.location[0] + self.size / 2,
                                  self.location[1] + self.size / 2,
                                  self.location[2] + self.size / 2)])
     self.bbox_faces = [[0, 1, 2, 3], [4, 5, 6, 7], [0, 1, 4, 5],
                        [2, 3, 6, 7], [0, 2, 4, 6], [1, 3, 5, 7]]
     self.bvh_tree = BVHTree.FromPolygons(self.bbox_verts,
                                          self.bbox_faces,
                                          epsilon=1.0)
Exemplo n.º 8
0
 def process(self):
     Object, PointsUV = self.inputs
     Pom, uvV, uvP = self.outputs
     obj = Object.sv_get()[0]  # triangulate faces
     UVMAPV, UVMAPP = UV(self, obj)
     if Pom.is_linked:
         pointuv = PointsUV.sv_get()[0]
         bvh = BVHTree.FromPolygons(UVMAPV,
                                    UVMAPP,
                                    all_triangles=False,
                                    epsilon=0.0)
         ran = range(3)
         out = []
         uvMap = obj.data.uv_layers[0].data
         for Puv in pointuv:
             loc, norm, ind, dist = bvh.find_nearest(Puv)
             found_poly = obj.data.polygons[ind]
             verticesIndices = found_poly.vertices
             p1, p2, p3 = [
                 obj.data.vertices[verticesIndices[i]].co for i in ran
             ]
             uvMapIndices = found_poly.loop_indices
             uv1, uv2, uv3 = [
                 uvMap[uvMapIndices[i]].uv.to_3d() for i in ran
             ]
             V = barycentric_transform(Puv, uv1, uv2, uv3, p1, p2, p3)
             out.append(V[:])
         Pom.sv_set([out])
     if uvV.is_linked:
         uvV.sv_set([UVMAPV])
         uvP.sv_set([UVMAPP])
Exemplo n.º 9
0
def get_points_in_mesh_2D_clip(verts,
                               faces,
                               points,
                               normal,
                               clip_distance,
                               eps=0.0,
                               matchig_method='REPEAT'):
    mask_totals = []
    bvh = BVHTree.FromPolygons(verts, faces, all_triangles=False, epsilon=eps)

    normal, clip_distance = list_match_func[matchig_method](
        [normal, clip_distance])
    for point in points:
        inside = False
        for direction, dist in zip(normal, clip_distance):
            hit = bvh.ray_cast(point, Vector(direction))
            if hit[0] and hit[3] < dist:
                inside = True
                break
            else:
                hit = bvh.ray_cast(point, -Vector(direction))
                if hit[0] and hit[3] < dist:
                    inside = True
                    break
        mask_totals.append(inside)
    return mask_totals
Exemplo n.º 10
0
    def init_guess(surface, src_points, directions, samples=50):
        u_min = surface.get_u_min()
        u_max = surface.get_u_max()
        v_min = surface.get_v_min()
        v_max = surface.get_v_max()
        us = np.linspace(u_min, u_max, num=samples)
        vs = np.linspace(v_min, v_max, num=samples)
        us, vs = np.meshgrid(us, vs)
        us = us.flatten()
        vs = vs.flatten()

        points = surface.evaluate_array(us, vs).tolist()
        faces = make_faces(samples)

        bvh = BVHTree.FromPolygons(points, faces)

        us_out = []
        vs_out = []
        t_out = []
        nearest_out = []
        h2 = (u_max - u_min) / (2 * samples)
        for src_point, direction in zip(src_points, directions):
            nearest, normal, index, distance = bvh.ray_cast(
                src_point, direction)
            us_out.append(us[index] + h2)
            vs_out.append(vs[index] + h2)
            t_out.append(distance)
            nearest_out.append(tuple(nearest))

        return us_out, vs_out, t_out, nearest_out
Exemplo n.º 11
0
def lloyd_on_mesh(verts,
                  faces,
                  sites,
                  thickness,
                  n_iterations,
                  weight_field=None):
    bvh = BVHTree.FromPolygons(verts, faces)

    def iteration(points):
        n = len(points)

        normals = calc_bvh_normals(bvh, points)
        k = 0.5 * thickness
        points = np.array(points)
        plus_points = points + k * normals
        minus_points = points - k * normals
        all_points = points.tolist() + plus_points.tolist(
        ) + minus_points.tolist()

        diagram = Voronoi(all_points)
        centers = []
        for site_idx in range(n):
            region_idx = diagram.point_region[site_idx]
            region = diagram.regions[region_idx]
            region_verts = np.array([diagram.vertices[i] for i in region])
            center = weighted_center(region_verts, weight_field)
            centers.append(tuple(center))
        return centers

    points = calc_bvh_projections(bvh, sites)
    for i in range(n_iterations):
        points = iteration(points)
        points = calc_bvh_projections(bvh, points)

    return points.tolist()
Exemplo n.º 12
0
    def execute_Mesh(self, mesh, epsilon):
        if len(mesh.polygons) == 0:
            return self.getFallbackBVHTree()

        return BVHTree.FromPolygons(mesh.vertices,
                                    mesh.polygons,
                                    epsilon=max(epsilon, 0))
Exemplo n.º 13
0
def find_nearest_idxs(verts, faces, add_verts):
    bvh = BVHTree.FromPolygons(verts, faces)
    idxs = []
    for vert in add_verts:
        loc, normal, idx, distance = bvh.find_nearest(vert)
        idxs.append(idx)
    return idxs
Exemplo n.º 14
0
 def execute_MeshSurfaceFalloff(self, mesh, size, falloffWidth, useVolume,
                                invert, bvhMaxDistance, epsilon):
     vectorList, polygonsIndices = self.validMesh(mesh)
     bvhTree = BVHTree.FromPolygons(vectorList,
                                    polygonsIndices,
                                    epsilon=max(epsilon, 0))
     return calculateMeshSurfaceFalloff(bvhTree, bvhMaxDistance, size,
                                        falloffWidth, useVolume, invert)
Exemplo n.º 15
0
 def __init__(self, obj):
     self.matrix_local = obj.matrix_local
     # mesh_settings = (bpy.context.scene, True, 'RENDER')
     data = obj.to_mesh()  #*mesh_settings)
     vertices = [vert.co[:] for vert in data.vertices]
     polygons = [poly.vertices[:] for poly in data.polygons]
     self.BVH = BVHTree.FromPolygons(vertices, polygons)
     obj.to_mesh_clear()
Exemplo n.º 16
0
 def __init__(self, OB):
     self.matrix_local = OB.matrix_local
     mesh_settings = (bpy.context.scene, True, 'RENDER')
     data = OB.to_mesh(*mesh_settings)
     vertices = [vert.co[:] for vert in data.vertices]
     polygons = [poly.vertices[:] for poly in data.polygons]
     self.BVH = BVHTree.FromPolygons(vertices, polygons)
     bpy.data.meshes.remove(data)
Exemplo n.º 17
0
    def execute_Mesh(self, vectorList, polygonsIndices, epsilon):
        if len(polygonsIndices) == 0:
            return self.getFallbackBVHTree()

        if 0 <= polygonsIndices.getMinIndex() <= polygonsIndices.getMaxIndex(
        ) < len(vectorList):
            return BVHTree.FromPolygons(vectorList,
                                        polygonsIndices,
                                        epsilon=max(epsilon, 0))
Exemplo n.º 18
0
def BVHTreeAndVerticesInWorldFromObj(obj):
    """
    Input: Object of Blender type Object
    Output: BVH Tree necessary for ray tracing and vertsInWorld = verts in global coordinate system. 
    """
    mWorld = obj.matrix_world
    vertsInWorld = [mWorld @ v.co for v in obj.data.vertices]
    bvh = BVHTree.FromPolygons(vertsInWorld,
                               [p.vertices for p in obj.data.polygons])
    return bvh, vertsInWorld
Exemplo n.º 19
0
def lloyd_in_mesh(verts,
                  faces,
                  sites,
                  n_iterations,
                  thickness=None,
                  weight_field=None):
    bvh = BVHTree.FromPolygons(verts, faces)

    if thickness is None:
        x_min, x_max, y_min, y_max, z_min, z_max = calc_bounds(verts)
        thickness = max(x_max - x_min, y_max - y_min, z_max - z_min) / 4.0

    epsilon = 1e-8

    def iteration(points):
        n = len(points)

        all_points = points[:]
        k = 0.5 * thickness
        for p in points:
            p = Vector(p)
            loc, normal, index, distance = bvh.find_nearest(p)
            if distance <= epsilon:
                p1 = p + k * normal
                all_points.append(tuple(p1))

        diagram = Voronoi(all_points)
        centers = []
        for site_idx in range(n):
            region_idx = diagram.point_region[site_idx]
            region = diagram.regions[region_idx]
            region_verts = np.array([diagram.vertices[i] for i in region])
            center = weighted_center(region_verts, weight_field)
            centers.append(tuple(center))
        return centers

    def restrict(points):
        result = []
        for p in points:
            if point_inside_mesh(bvh, p):
                result.append(p)
            else:
                loc, normal, index, distance = bvh.find_nearest(p)
                if loc is not None:
                    result.append(tuple(loc))
        return result

    points = restrict(sites)
    for i in range(n_iterations):
        points = iteration(points)
        points = restrict(points)

    return points
Exemplo n.º 20
0
def voronoi_on_mesh(verts,
                    faces,
                    sites,
                    thickness,
                    spacing=0.0,
                    clip_inner=True,
                    clip_outer=True,
                    do_clip=True,
                    clipping=1.0,
                    mode='REGIONS',
                    precision=1e-8):
    bvh = BVHTree.FromPolygons(verts, faces)
    npoints = len(sites)

    if clipping is None:
        x_min, x_max, y_min, y_max, z_min, z_max = calc_bounds(verts)
        clipping = max(x_max - x_min, y_max - y_min, z_max - z_min) / 2.0

    if mode in {'REGIONS', 'RIDGES'}:
        if clip_inner or clip_outer:
            normals = calc_bvh_normals(bvh, sites)
        k = 0.5 * thickness
        sites = np.array(sites)
        all_points = sites.tolist()
        if clip_outer:
            plus_points = sites + k * normals
            all_points.extend(plus_points.tolist())
        if clip_inner:
            minus_points = sites - k * normals
            all_points.extend(minus_points.tolist())

        return voronoi3d_layer(npoints,
                               all_points,
                               make_regions=(mode == 'REGIONS'),
                               do_clip=do_clip,
                               clipping=clipping)

    else:  # VOLUME, SURFACE
        all_points = sites[:]
        if do_clip:
            for site in sites:
                loc, normal, index, distance = bvh.find_nearest(site)
                if loc is not None:
                    p1 = loc + clipping * normal
                    all_points.append(p1)
        verts, edges, faces = voronoi_on_mesh_bmesh(verts,
                                                    faces,
                                                    len(sites),
                                                    all_points,
                                                    spacing=spacing,
                                                    fill=(mode == 'VOLUME'),
                                                    precision=precision)
        return verts, edges, faces, all_points
Exemplo n.º 21
0
    def __init__(self, obj):
        self.matrix_local = obj.matrix_local

        # mesh_settings = (..., True, 'RENDER')
        # data = OB.to_mesh(*mesh_settings)
        data = obj.to_mesh() # bpy.context.depsgraph, apply_modifiers=True, calc_undeformed=False)

        vertices = [vert.co[:] for vert in data.vertices]
        polygons = [poly.vertices[:] for poly in data.polygons]

        self.BVH = BVHTree.FromPolygons(vertices, polygons)
        obj.to_mesh_clear()
Exemplo n.º 22
0
def lloyd_relax(vertices, faces, iterations, mask=None, method=NORMAL, skip_boundary=True, use_axes={0,1,2}):
    """
    supported shape preservation methods: NONE, NORMAL, LINEAR, BVH
    """

    def do_iteration(bvh, bm):
        verts_out = []
        face_centers = np.array([face.calc_center_median() for face in bm.faces])
        for bm_vert in bm.verts:
            co = bm_vert.co
            if (skip_boundary and bm_vert.is_boundary) or (mask is not None and not mask[bm_vert.index]):
                new_vert = tuple(co)
            else:    
                normal = bm_vert.normal
                cs = np.array([face_centers[face.index] for face in bm_vert.link_faces])
                
                if method == NONE:
                    new_vert = cs.mean(axis=0)
                elif method == NORMAL:
                    median = mathutils.Vector(cs.mean(axis=0))
                    dv = median - co
                    dv = dv - dv.project(normal)
                    new_vert = co + dv
                elif method == LINEAR:
                    approx = linear_approximation(cs)
                    median = mathutils.Vector(approx.center)
                    plane = approx.most_similar_plane()
                    dist = plane.distance_to_point(bm_vert.co)
                    new_vert = median + plane.normal.normalized() * dist
                elif method == BVH:
                    median = mathutils.Vector(cs.mean(axis=0))
                    new_vert, normal, idx, dist = bvh.find_nearest(median)
                else:
                    raise Exception("Unsupported volume preservation method")
                
                new_vert = tuple(new_vert)
                new_vert = mask_axes(tuple(co), new_vert, use_axes)
                
            verts_out.append(new_vert)

        return verts_out

    if mask is not None:
        mask = repeat_last_for_length(mask, len(vertices))

    bvh = BVHTree.FromPolygons(vertices, faces)
    for i in range(iterations):
        bm = bmesh_from_pydata(vertices, [], faces, normal_update=True)
        vertices = do_iteration(bvh, bm)
        bm.free()

    return vertices
Exemplo n.º 23
0
    def construct_pattern_BVHTree(self, obj):
        # give world space points ( multiplied by obj.mat_world)
        resampled_curve_segments = self.patter_segments_cache[obj.name]
        segments_points_flat = []
        for segment in resampled_curve_segments:  # add cloth sillayette
            segments_points_flat.extend(segment[:-1])

        # cast the ray
        sourceTri_BVHT = BVHTree.FromPolygons(
            segments_points_flat,
            [tuple(i for i in range(len(segments_points_flat)))],
            all_triangles=False)  # [0,1,2] - polygon == vert indices list
        return sourceTri_BVHT
Exemplo n.º 24
0
def _get_bvh(obj):
    """Get the BVH for an object

    Args:
        obj (variant): object to get the BVH for

    Returns:
        BVH for obj
    """
    mat = obj.matrix_world
    vs = [mat @ v.co for v in obj.data.vertices]
    ps = [p.vertices for p in obj.data.polygons]
    return BVHTree.FromPolygons(vs, ps)
Exemplo n.º 25
0
    def getValue(self):
        if getattr(self.object, "type", "") != "MESH":
            return self.getDefaultValue()

        evaluatedObject = getEvaluatedID(self.object)
        mesh = evaluatedObject.data
        polygons = mesh.an.getPolygonIndices()
        if len(polygons) == 0:
            return self.getDefaultValue()
        vertices = mesh.an.getVertices()
        if self.useWorldSpace:
            vertices.transform(evaluatedObject.matrix_world)
        return BVHTree.FromPolygons(vertices, polygons)
Exemplo n.º 26
0
def bvh_tree_from_polygons(vertices,
                           polygons,
                           all_triangles=False,
                           epsilon=0.0,
                           safe_check=True):
    if safe_check:
        bvh_safe_check(vertices, polygons)
    if isinstance(vertices, np.ndarray):
        vertices = vertices.tolist()
    if isinstance(polygons, np.ndarray):
        polygons = polygons.tolist()
    return BVHTree.FromPolygons(vertices,
                                polygons,
                                all_triangles=all_triangles,
                                epsilon=epsilon)
Exemplo n.º 27
0
 def curve_ray_cast(self, obj, ray_origin, ray_target):
     """Wrapper for ray casting that moves the ray into object space"""
     # get the ray relative to the object
     ray_direction = ray_target - ray_origin
     resampled_curve_segments = self.patter_segments_cache[obj.name]
     segments_points_flat = []
     for segment in resampled_curve_segments:  # add cloth sillayette
         segments_points_flat.extend(segment[:-1])
     # cast the ray
     sourceTri_BVHT = BVHTree.FromPolygons(
         segments_points_flat,
         [tuple(i for i in range(len(segments_points_flat)))],
         all_triangles=False)  # [0,1,2] - polygon == vert indices list
     # location, normal, index, dist =
     return sourceTri_BVHT.ray_cast(ray_origin, ray_direction, 600)
Exemplo n.º 28
0
def mesh_insert_verts(verts,
                      faces,
                      add_verts_by_face,
                      epsilon=1e-6,
                      exclude_boundary=True,
                      recalc_normals=True,
                      preserve_shape=False):
    if preserve_shape:
        bvh = BVHTree.FromPolygons(verts, faces)
    bm = bmesh_from_pydata(verts, [], [])
    for face_idx, face in enumerate(faces):
        n = len(face)
        add_verts = add_verts_by_face.get(face_idx)

        if not add_verts:
            bm_verts = [bm.verts[idx] for idx in face]
            bm.faces.new(bm_verts)
            bm.faces.index_update()
            continue

        done_verts = dict((i, bm.verts[face[i]]) for i in range(n))
        face_verts = [verts[i] for i in face]
        new_face_verts, edges, new_faces = single_face_delaunay(
            face_verts, add_verts, epsilon, exclude_boundary)
        if preserve_shape:
            new_face_verts = find_nearest_points(bvh, new_face_verts)
        for new_face in new_faces:
            bm_verts = []
            for i in new_face:
                bm_vert = done_verts.get(i)
                if not bm_vert:
                    bm_vert = bm.verts.new(new_face_verts[i])
                    bm.verts.index_update()
                    bm.verts.ensure_lookup_table()
                    done_verts[i] = bm_vert
                bm_verts.append(bm_vert)

            bm.faces.new(bm_verts)
            bm.faces.index_update()

    if recalc_normals:
        bmesh.ops.recalc_face_normals(bm, faces=bm.faces)

    verts, edges, faces = pydata_from_bmesh(bm)
    bm.free()
    return verts, edges, faces
Exemplo n.º 29
0
    def execute_Object(self, object, epsilon):
        if object is None:
            return self.getFallbackBVHTree()
        if object.type != "MESH":
            return self.getFallbackBVHTree()

        evaluatedObject = getEvaluatedID(object)
        mesh = evaluatedObject.data
        polygons = mesh.an.getPolygonIndices()
        if len(polygons) == 0:
            return self.getFallbackBVHTree()
        vertices = mesh.an.getVertices()
        vertices.transform(evaluatedObject.matrix_world)

        return BVHTree.FromPolygons(vertices,
                                    polygons,
                                    epsilon=max(epsilon, 0))
Exemplo n.º 30
0
def get_points_in_mesh_2D(verts, faces, points, normal, eps=0.0):
    mask_totals = []
    bvh = BVHTree.FromPolygons(verts, faces, all_triangles=False, epsilon=eps)

    for point in points:
        inside = False
        for direction in normal:
            hit = bvh.ray_cast(point, Vector(direction))
            if hit[0]:
                inside = True
                break
            else:
                hit = bvh.ray_cast(point, -Vector(direction))
                if hit[0]:
                    inside = True
                    break
        mask_totals.append(inside)
    return mask_totals