예제 #1
0
    def add_child(self, dispatcher):
        try:
            assert dispatcher.dispatcher_id not in self._children_dispatchers
        except AssertionError:
            debuginfo((dispatcher.dispatcher_id, list(self._children_dispatchers.keys())))
            raise

        self._children_dispatchers[dispatcher.dispatcher_id] = dispatcher

        dispatcher.set_parent(self)
예제 #2
0
    def __init__(self, action_data):
        self.main_data = self.main_data

        try:
            assert isinstance(action_data, self.ActionDataCls)
        except AssertionError:
            debuginfo(action_data.__class__.__name__, action_data, self.ActionDataCls)
            raise

        self.action_data = action_data

        self.is_valid = True
예제 #3
0
def box_frustum_volume(frustum):
    """:type frustum: vtk.vtkPlanes"""

    points_ = frustum.GetPoints()
    normals_ = frustum.GetNormals()

    assert points_.GetNumberOfPoints() == 6

    points = []
    normals = []

    for i in range(6):
        points.append(np.array(points_.GetPoint(i), dtype=np.float64))
        normals.append(np.array(normals_.GetTuple3(i), dtype=np.float64))

    used = []
    pairs = []
    count = 0
    while count < 3:
        for i in range(6):
            if i in used:
                continue
            for j in range(6):
                if i == j or j in used:
                    continue

                if round(abs(np.dot(normals[i], normals[j])), 3) == 1.:
                    pairs.append((i, j))
                    used.append(i)
                    used.append(j)
                    count += 1

    dimensions = [0, 0, 0]

    for i in range(3):
        pair = pairs[i]

        i1 = pair[0]
        i2 = pair[1]

        d = points[i1] - points[i2]

        dimensions[i] = np.dot(d, normals[i1])

    debuginfo(dimensions)

    volume = dimensions[0] * dimensions[1] * dimensions[2]

    debuginfo('volume = ', volume)

    return volume
예제 #4
0
        def _make_connection(action):

            obj_signal = getattr(obj, action)

            if not isinstance(obj_signal, MrSignal):
                debuginfo(obj_signal)
                raise TypeError("Not a Signal!!!")

            action_name = "%s.%s" % (obj_name, action)

            def _connection(*args):
                return self.dispatch((action_name, args))

            _connection.__name__ = "%s_%s" % (obj_name, action)

            obj_signal.connect(_connection)
            setattr(obj, _connection.__name__, _connection)
예제 #5
0
def create_triangle_frustum(wp1, wp2, wp3, renderer):

    camera = renderer.GetActiveCamera()

    renderer.SetWorldPoint(wp1[0], wp1[1], wp1[2], 1)
    renderer.WorldToDisplay()
    dp1 = renderer.GetDisplayPoint()

    renderer.SetWorldPoint(wp2[0], wp2[1], wp2[2], 1)
    renderer.WorldToDisplay()
    dp2 = renderer.GetDisplayPoint()

    renderer.SetWorldPoint(wp3[0], wp3[1], wp3[2], 1)
    renderer.WorldToDisplay()
    dp3 = renderer.GetDisplayPoint()

    renderer.SetDisplayPoint(dp1[0], dp1[1], 0)
    renderer.DisplayToWorld()
    wp1 = renderer.GetWorldPoint()[:4]

    renderer.SetDisplayPoint(dp2[0], dp2[1], 0)
    renderer.DisplayToWorld()
    wp2 = renderer.GetWorldPoint()[:4]

    renderer.SetDisplayPoint(dp3[0], dp3[1], 0)
    renderer.DisplayToWorld()
    wp3 = renderer.GetWorldPoint()[:4]

    renderer.SetDisplayPoint(dp1[0], dp1[1], 1)
    renderer.DisplayToWorld()
    wp1_ = renderer.GetWorldPoint()[:4]

    renderer.SetDisplayPoint(dp2[0], dp2[1], 1)
    renderer.DisplayToWorld()
    wp2_ = renderer.GetWorldPoint()[:4]

    renderer.SetDisplayPoint(dp3[0], dp3[1], 1)
    renderer.DisplayToWorld()
    wp3_ = renderer.GetWorldPoint()[:4]

    normals = vtk.vtkFloatArray()
    normals.SetNumberOfComponents(3)
    normals.SetNumberOfTuples(6)

    points = vtk.vtkPoints()
    points.SetNumberOfPoints(6)

    dp1 = [dp1[0], dp1[1], 0]
    dp2 = [dp2[0], dp2[1], 0]
    dp3 = [dp3[0], dp3[1], 0]

    check = calculate_normal_from_points(dp1, dp2, dp3)

    debuginfo(check)

    if check[2] < 0:
        tmp = wp3
        wp3 = wp2
        wp2 = tmp

        tmp = wp3_
        wp3_ = wp2_
        wp2_ = tmp

    normal1 = calculate_normal_from_points(wp1, wp2, wp3)
    points.SetPoint(0, wp1[:3])
    normals.SetTuple3(0, *normal1)

    normal2 = calculate_normal_from_points(wp1_, wp3_, wp2_)
    points.SetPoint(1, wp1_[:3])
    normals.SetTuple3(1, *normal2)

    normal3 = calculate_normal_from_points(wp1, wp3, wp1_)
    points.SetPoint(2, wp1[:3])
    normals.SetTuple3(2, *normal3)

    normal4 = calculate_normal_from_points(wp1, wp1_, wp2)
    points.SetPoint(3, wp1[:3])
    normals.SetTuple3(3, *normal4)

    normal5 = calculate_normal_from_points(wp2, wp2_, wp3)
    points.SetPoint(4, wp2[:3])
    normals.SetTuple3(4, *normal5)

    points.SetPoint(5, wp2[:3])
    normals.SetTuple3(5, *normal5)

    planes = vtk.vtkPlanes()
    planes.SetNormals(normals)
    planes.SetPoints(points)

    return planes
예제 #6
0
def picking_ray(pos, renderer):
    """

    :param pos: list
    :param renderer: vtk.vtkRenderer
    :return:
    """

    selectionX = pos[0]
    selectionY = pos[1]
    selectionZ = pos[2]

    # code below is adapted from vtkPicker::Pick to calculate ray end points

    # Initialize picking process
    selection_point = [selectionX, selectionY, selectionZ]

    # Get camera focal point and position. Convert to display (screen)
    # coordinates. We need a depth value for z-buffer.
    camera = renderer.GetActiveCamera()
    cameraPos = camera.GetPosition()
    cameraPos += (1., )
    cameraFP = camera.GetFocalPoint()
    cameraFP += (1., )

    renderer.SetWorldPoint(cameraFP[0], cameraFP[1], cameraFP[2], cameraFP[3])
    renderer.WorldToDisplay()
    displayCoords = renderer.GetDisplayPoint()
    selectionZ = displayCoords[2]

    # Convert the selection point into world coordinates.
    renderer.SetDisplayPoint(selectionX, selectionY, selectionZ)
    renderer.DisplayToWorld()
    worldCoords = renderer.GetWorldPoint()

    if worldCoords[3] == 0.:
        debuginfo("Bad homogeneous coordinates")
        return -1

    PickPosition = [0, 0, 0]

    for i in range(3):
        PickPosition[i] = worldCoords[i] / worldCoords[3]

    # Compute the ray endpoints.  The ray is along the line running from
    # the camera position to the selection point, starting where this line
    # intersects the front clipping plane, and terminating where this
    # line intersects the back clipping plane.

    ray = [0, 0, 0]
    cameraDOP = [0, 0, 0]

    magnitude = 0.

    for i in range(3):
        ray[i] = PickPosition[i] - cameraPos[i]
        cameraDOP[i] = cameraFP[i] - cameraPos[i]
        magnitude += cameraDOP[i]**2

    magnitude **= 0.5

    for i in range(3):
        cameraDOP[i] /= magnitude

    dot_product = cameraDOP[0] * ray[0] + cameraDOP[1] * ray[1] + cameraDOP[
        2] * ray[2]

    if dot_product == 0.:
        debuginfo("Cannot process points")
        return -1

    rayLength = dot_product

    clipRange = camera.GetClippingRange()

    p1World = [0, 0, 0, 0]
    p2World = [0, 0, 0, 0]

    if camera.GetParallelProjection():
        tF = clipRange[0] - rayLength
        tB = clipRange[1] - rayLength
        for i in range(3):
            p1World[i] = PickPosition[i] + tF * cameraDOP[i]
            p2World[i] = PickPosition[i] + tB * cameraDOP[i]
    else:
        tF = clipRange[0] / rayLength
        tB = clipRange[1] / rayLength
        for i in range(3):
            p1World[i] = cameraPos[i] + tF * ray[i]
            p2World[i] = cameraPos[i] + tB * ray[i]

    p1World[3] = p2World[3] = 1.

    return [selection_point, PickPosition, p1World, p2World]
예제 #7
0
    def dispatch(self, action, tracking=True, traceback=True, action_str=None):

        # debuginfo(action)

        if traceback is True and self._parent_dispatcher is not None:
            return self._dispatch(action, tracking)

        try:
            assert isinstance(action, (str, tuple))
        except AssertionError:
            debuginfo(action.__class__.__name__)
            raise

        if self._try_undo_redo(action):
            return True

        if isinstance(action, str):

            i1 = action.index('(')
            action_name = action[:i1]
            action_data = action[i1:]

            if '.' in action_name:
                # try:
                tmp = action_name.split('.')
                # noinspection SpellCheckingInspection
                childname = tmp[0]

                action_ = '.'.join(tmp[1:]) + action_data

                # print(self.dispatcher_id, childname, action_)

                try:
                    # debuginfo(
                    #     'Calling child dispatcher {%s} from {%s}. {%s} {%s}' % (
                    #         childname, self.dispatcher_id, action_, action_str
                    #     )
                    # )
                    return self._children_dispatchers[childname].dispatch(action_, tracking, False, action_str)
                except KeyError:
                    debuginfo('###########################################')
                    debuginfo(self.dispatcher_id, childname, action, action_)
                    debuginfo(list(self._children_dispatchers.keys()))
                    debuginfo('###########################################')
                    raise

        # except AttributeError:
        #     pass

        # print(1, self.dispatcher_id, action)

        command = self._get_command(action)

        # print(2)

        if command is None:
            return False

        command = self._encapsulate_command(command)

        # print(3)

        command.skip_first = False
        command.redo()
        command_result = command.command_result
        command.skip_first = True

        # print(4)

        self._action_data = None

        # TODO: not sure if this is the desired behavior
        if command_result is False:
            return False

        action_ = command.action

        if action_.log_action is True and tracking is True:
            if action_str is None:
                action_str = str(action_)
            self.action_history.append(action_str)
            # this notifies the main window that an action has been added, so that it can update the log
            self.action_added.emit(action_str)

        # if the action is successful, push it to the stack (it will be skipped on first push)
        if command_result is True:
            if command.push_to_stack and tracking is True:

                self.undo_stack.push(command)

                if command.set_clean is True:
                    self.undo_stack.setClean()

            return True
        else:
            return False