示例#1
0
        def approximation_distance(sv0, sv1, sv2):
            # center-of-gravity distance
            sv_cog = SuperVertex.compute_surface_center_of_gravity(
                sv0, sv1, sv2)
            cog_surface = sv_cog.XYZ_vec3()
            cog_3d = (sv0.XYZ_vec3() + sv1.XYZ_vec3() + sv2.XYZ_vec3()) / 3
            cog_distance = np.linalg.norm(cog_surface - cog_3d)

            distance = cog_distance

            if APPROX_DIST_MULTI_SAMPLING:
                # halfway-point distances
                hw0_surface = SuperVertex.compute_halfway(sv0, sv1).XYZ_vec3()
                hw1_surface = SuperVertex.compute_halfway(sv1, sv2).XYZ_vec3()
                hw2_surface = SuperVertex.compute_halfway(sv2, sv0).XYZ_vec3()
                hw0_3d = sv0.XYZ_vec3() + (
                    (sv1.XYZ_vec3() - sv0.XYZ_vec3()) / 2)
                hw1_3d = sv1.XYZ_vec3() + (
                    (sv2.XYZ_vec3() - sv1.XYZ_vec3()) / 2)
                hw2_3d = sv2.XYZ_vec3() + (
                    (sv0.XYZ_vec3() - sv2.XYZ_vec3()) / 2)
                hw0_distance = np.linalg.norm(hw0_surface - hw0_3d)
                hw1_distance = np.linalg.norm(hw1_surface - hw1_3d)
                hw2_distance = np.linalg.norm(hw2_surface - hw2_3d)

                distance = (distance + hw0_distance + hw1_distance +
                            hw2_distance) / 4

            if APPROX_DIST_AREA_WRIGHTED:
                area = calculate_area(sv0.XYZ_vec3(), sv1.XYZ_vec3(),
                                      sv2.XYZ_vec3())
                distance /= area**0.5

            return distance**2
示例#2
0
def insert_halfway_as_debug(omesh, h):
    sv0 = sv_from_vh(omesh, omesh.from_vertex_handle(h))
    sv1 = sv_from_vh(omesh, omesh.to_vertex_handle(h))
    p0 = sv0.XYZ_vec3()
    p1 = sv1.XYZ_vec3()

    phw = p0 + ((p1 - p0) / 2)
    svhw = SuperVertex(*phw)
    svhw.set_same_face_as(sv0)
    DEBUG_VERTICES.append(svhw)

    return
示例#3
0
def split_edge(omesh, vertices, eh, meta_block):
    def remove_encroaching_vertices(omesh, vertices, vh, h):
        def remove_one_encroaching_vertex(omesh, vertices, phw, h):
            for vh in omesh.vertices():
                if omesh.is_boundary(vh):
                    continue

                pcurr = np.array((omesh.point(vh)))

                if np.linalg.norm(phw - pcurr) < h:
                    remove_inner_vertex(omesh, vertices, vh)
                    return True

            return False

        phw = np.array((omesh.point(vh)))

        n_deleted = 0
        while remove_one_encroaching_vertex(omesh, vertices, phw, h):
            n_deleted += 1

        return n_deleted

    hh = omesh.halfedge_handle(eh, 0)
    vh0 = omesh.from_vertex_handle(hh)
    vh1 = omesh.to_vertex_handle(hh)
    sv0 = sv_from_vh(omesh, vh0)
    sv1 = sv_from_vh(omesh, vh1)

    if omesh.is_boundary(eh):
        sv_new = SuperVertex.compute_halfway_on_shared_edge(sv0, sv1)
    else:
        sv_new = SuperVertex.compute_halfway(sv0, sv1)

    vertices.append(sv_new)

    # split segment
    vh_new = omesh.add_vertex(sv_new.XYZ_vec3())
    set_supervertex_property(omesh, vh_new, sv_new)
    omesh.split_edge(eh, vh_new)
    omesh.garbage_collection()
    meta_block[MeshkD.NV_SPLT] += 1

    # remove encroaching vertices
    if omesh.is_boundary(eh):
        h = np.linalg.norm(sv_new.XYZ_vec3() - sv0.XYZ_vec3())
        n_deleted = remove_encroaching_vertices(omesh, vertices, vh_new, h)
        meta_block[MeshkD.NV_DELT] += n_deleted

    return vh_from_sv(omesh, sv_new)
示例#4
0
        def sample_supervertex(surface, curve2d, parameter):
            p2d = curve2d.Value(parameter)
            p3d = surface.Value(p2d.X(), p2d.Y())

            sv = SuperVertex(x=p3d.X(), y=p3d.Y(), z=p3d.Z(), u=p2d.X(), v=p2d.Y())

            return sv
示例#5
0
    def scc_from_c_2d(c_2d, other_sv):
        scc = SuperVertex(u=c_2d[0], v=c_2d[1])
        scc.face = other_sv.face
        scc.face_id = other_sv.face_id
        scc.project_to_XYZ()

        return scc
示例#6
0
def split_segment(scdt, segment_index):
    def count_segments(segment_loops):
        nos = 0

        for segment_loop in segment_loops:
            nos += len(segment_loop)

        return nos

    vertices, segment_loops, _ = scdt
    l_index, s_index = segment_index
    print('split_segment()')
    print(segment_index, '->', segment_loops[l_index][s_index])

    segment_loop = segment_loops[l_index]
    vi0, vi1 = segment_loop[s_index]

    # compute and insert halfway vertex
    sv0 = vertices[vi0]
    sv1 = vertices[vi1]
    sv_halfway = SuperVertex.compute_halfway_on_shared_edge(sv0, sv1)
    # segment vertices are never deleted -> insert before inner vertices to avoid index shift
    hw_index = count_segments(segment_loops)  # == num of boundary vertices
    vertices.insert(hw_index, sv_halfway)

    # delete old and insert new segments
    print('del', segment_loop[s_index])
    del segment_loop[s_index]
    new_s0 = (vi0, hw_index)
    new_s1 = (hw_index, vi1)
    print('insert', new_s1)
    print('insert', new_s0)
    segment_loop.insert(s_index, new_s1)
    segment_loop.insert(s_index, new_s0)

    # delete encroaching vertices
    new_segments_length = np.linalg.norm(sv0.XYZ_vec3() -
                                         sv_halfway.XYZ_vec3())
    inner_vertices_offset = hw_index + 1
    sv_index = inner_vertices_offset
    while sv_index < len(vertices):
        sv = vertices[sv_index]
        dist_to_hw = np.linalg.norm(sv.XYZ_vec3() - sv_halfway.XYZ_vec3())

        if dist_to_hw < new_segments_length:
            del vertices[sv_index]
        else:
            sv_index += 1

    return
示例#7
0
def chew93_Surface(face_mesh, meta_block):
    vertices, wire_meshes, triangles, _ = face_mesh

    # step 1: compute initial CDT and iteratively transform into SCDT
    print('generating initial mesh...', end='')
    sys.stdout.flush()
    triangulate_cdt(face_mesh)
    omesh = parse_into_openmesh(face_mesh)
    flip_until_scdt(omesh)

    # step 2+3: find largest triangle that fails shape ans size criteria
    print('\b\b\b - done\nrefining mesh...', end='')
    delta = find_largest_failing_triangle(omesh)

    global iter_counter
    iter_counter = 0
    while delta.is_valid() and iter_counter != MAX_ITERATIONS:
        print('\rrefining mesh... iteration', iter_counter, '', end='')
        if iter_counter == DEBUG_ITERATION:  #TODO remove after debuging
            sv0, sv1, sv2 = collect_triangle_supervertices(omesh, delta)
            (x, y, z), (u, v) = calculate_cog(sv0, sv1, sv2)
            sv_cog = SuperVertex(x, y, z, u, v, same_as=sv0)
            DEBUG_VERTICES.append(sv_cog)
        else:
            DEBUG_VERTICES.clear()
            handle, scc = calculate_refinement(omesh, delta, meta_block)

            if isinstance(handle, om.FaceHandle):
                vh_new = insert_inner_vertex(omesh, vertices, handle, scc,
                                             meta_block)
            else:
                assert isinstance(handle, om.EdgeHandle)
                vh_new = split_edge(omesh, vertices, handle, meta_block)

            meta_block[MeshkD.NV_REFI] += 1

            # after vertex insertion and possible deletion, restore SCDT criteria
            restore_scdt(omesh, vh_new)

            # update for next iteration
            delta = find_largest_failing_triangle(omesh)
        iter_counter += 1

    parse_back(omesh, face_mesh)
    vertices += DEBUG_VERTICES

    return
示例#8
0
    def sample_interior(face_mesh):
        vertices, _, _, face = face_mesh

        additional_vertices = []

        surface = BRepAdaptor_Surface(face)
        FU = surface.FirstUParameter()
        LU = surface.LastUParameter()
        FV = surface.FirstVParameter()
        LV = surface.LastVParameter()

        U_LENGTH = LU - FU
        V_LENGTH = LV - FV

        if INTERIOR_SAMPLING_METHOD == INTERIOR_GRID:
            for u_index in range(1, GRID_U_SAMPLES + 1):
                for v_index in range(1, GRID_V_SAMPLES + 1):
                    u_offset = U_OFFSET_FACTOR / (GRID_U_SAMPLES + 1)
                    v_offset = V_OFFSET_FACTOR / (GRID_V_SAMPLES + 1)
                    u = FU + ((u_index /
                               (GRID_U_SAMPLES + 1)) + u_offset) * U_LENGTH
                    v = FV + ((v_index /
                               (GRID_V_SAMPLES + 1)) + v_offset) * V_LENGTH

                    sv_add = SuperVertex(u=u, v=v, same_as=vertices[0])
                    sv_add.project_to_XYZ()
                    additional_vertices.append(sv_add)
        elif INTERIOR_SAMPLING_METHOD == INTERIOR_RANDOM:
            for i in range(RANDOM_SAMPLES):
                rand0 = random.randint(
                    1, RANDOM_RESOLUTION - 1) / RANDOM_RESOLUTION
                rand1 = random.randint(
                    1, RANDOM_RESOLUTION - 1) / RANDOM_RESOLUTION
                u = FU + rand0 * U_LENGTH
                v = FV + rand1 * V_LENGTH

                sv_add = SuperVertex(u=u, v=v, same_as=vertices[0])
                sv_add.project_to_XYZ()
                additional_vertices.append(sv_add)
        else:
            raise Exception(
                'sample_interior() error - INTERIOR_SAMPLING_METHOD unknown')

        return additional_vertices
示例#9
0
def insert_inner_vertex(scdt, c):
    vertices, _, _ = scdt
    assert len(vertices) > 0

    svc = SuperVertex(x=c[0], y=c[1], z=c[2])
    svc.face_id = vertices[0].face_id
    svc.face = vertices[0].face
    svc.project_to_UV()

    vertices.append(svc)

    return
示例#10
0
def insert_halfway_vertex_of_edge(scdt, edge_vertex_indices):
    vertices, _, _ = scdt
    assert len(vertices) > 0

    ev0, ev1 = edge_vertex_indices
    sv0 = vertices[ev0]
    sv1 = vertices[ev1]

    p0 = sv0.UV_vec2()
    p1 = sv1.UV_vec2()
    p01 = p1 - p0
    hw = p0 + (p01 / 2)

    svhw = SuperVertex(u=hw[0], v=hw[1])
    svhw.face = sv0.face
    svhw.face_id = sv0.face_id
    svhw.project_to_XYZ()

    vertices.append(svhw)

    return
示例#11
0
    def travel(omesh, delta, hh, c_3d, c_2d_candidates, normal, meta_block):
        def traveled_too_far(omesh, hh, p_orig, ray_dir):
            vh_opposite = omesh.to_vertex_handle(hh)
            p_opposite = sv_from_vh(omesh, vh_opposite).XYZ_vec3()
            p_opposite -= p_orig  # move system to origin

            p_projected = np.abs(np.dot(p_opposite, ray_dir))
            if p_projected > 1.0:
                print('traveled too far:', p_projected)

            return p_projected > 1.0

        def halfedge_crossed_by_ray_shadow(omesh, hh, ray_ori, ray_dir,
                                           normal):
            # print('halfedge_crossed_by_ray_shadow: ', end='')
            assert np.allclose(np.linalg.norm(ray_dir), 1.0)
            assert np.allclose(np.linalg.norm(normal), 1.0)
            p_from = sv_from_vh(omesh, omesh.from_vertex_handle(hh)).XYZ_vec3()
            p_to = sv_from_vh(omesh, omesh.to_vertex_handle(hh)).XYZ_vec3()

            v_from = shortest_vector_between_two_lines(p_from, normal, ray_ori,
                                                       ray_dir)
            v_to = shortest_vector_between_two_lines(p_to, normal, ray_ori,
                                                     ray_dir)

            dp = np.dot(v_from, v_to)
            # print(dp < 0)

            return dp < 0

        meta_block[MeshkD.NT_INVK] += 1

        svh0 = sv_from_vh(omesh, omesh.from_vertex_handle(hh))
        svh1 = sv_from_vh(omesh, omesh.to_vertex_handle(hh))
        sv_orig = SuperVertex.compute_halfway(svh0, svh1)
        p_orig = sv_orig.XYZ_vec3()
        ray_dir = normalize(c_3d - p_orig)

        # halt if we encounter a boundary edge (split case)
        # travel_iteration = 0 #TODO remove after debuging
        while not omesh.is_boundary(omesh.edge_handle(hh)):
            # if travel_iteration > 262: #TODO remove after debuging
            #     print('travel() error - travel limit reached!')
            #     break
            # else:
            #     travel_iteration += 1
            #     if iter_counter == DEBUG_ITERATION:
            #         insert_halfway_as_debug(omesh, hh)
            meta_block[MeshkD.NT_LOOP] += 1
            # get inside neighboring triangle
            hh = omesh.opposite_halfedge_handle(hh)
            fh = omesh.face_handle(hh)

            # halt if surface circumcenter is found to be insides fh (insert case)
            inside_index = find_point_inside(omesh, fh, c_2d_candidates)
            if inside_index >= 0:
                return fh, scc_from_c_2d(c_2d_candidates[inside_index],
                                         sv_orig)

            hh = omesh.next_halfedge_handle(
                hh)  # go to first of the opposite halfedges

            if traveled_too_far(omesh, hh, p_orig, ray_dir):
                pass

            # which of the remaining edges is crossed to travel further in that direction
            if not halfedge_crossed_by_ray_shadow(omesh, hh, p_orig, ray_dir,
                                                  normal):
                # shadow apparently crossed the other edge
                hh = omesh.next_halfedge_handle(hh)
                assert halfedge_crossed_by_ray_shadow(omesh, hh, p_orig,
                                                      ray_dir, normal)
            meta_block[MeshkD.NT_SHAD] += 1

        return omesh.edge_handle(hh), None