Example #1
0
/* Bloats a triangle so as to create a border kBloatSize pixels wide all around it. */
static bool bloat_tri(SkPoint pts[3]) {
    SkPoint line1 = pts[0] - pts[1];
    line1.normalize();
    SkPoint line2 = pts[0] - pts[2];
    line2.normalize();
    SkPoint line3 = pts[1] - pts[2];
    line3.normalize();

    SkPoint result[3];
    result[0] = pts[0];
    if (!outset(&result[0], line1, line2)) {
        return false;
    }
    result[1] = pts[1];
    if (!outset(&result[1], -line1, line3)) {
        return false;
    }
    result[2] = pts[2];
    if (!outset(&result[2], -line3, -line2)) {
        return false;
    }
    pts[0] = result[0];
    pts[1] = result[1];
    pts[2] = result[2];
    return true;
}
Example #2
0
Component CaseFactory::constructBase(double innerHeight, int extensionDirection)
{
    // The walls and the floor are made by subtracting two cuboids.
    Component base = Cube(board.size[0] + 2*outset(), board.size[1] + 2*outset(), innerHeight + floors, false)
            .translatedCopy(-outset(), -outset(), 0);
    Component baseInner = Cube(board.size[0] + 2*space,  board.size[1] + 2*space,  innerHeight + eps, false)
            .translatedCopy(-space, -space, floors);
    base = base - baseInner;

    // Extension (half width wall goes a bit higher, either the inner or the outer half depending on extensionDirection)
    double off_ext_outer = walls * (extensionDirection ? 1.00 : 0.45) + space;
    double off_ext_inner = walls * (extensionDirection ? 0.55 : 0.00) + space;
    Component extension = Cube(board.size[0] + 2*off_ext_outer, board.size[1] + 2*off_ext_outer, extensionHeight() + eps, false)
            .translatedCopy(-off_ext_outer, -off_ext_outer, innerHeight + floors - eps);
    Component extensionInner = Cube(board.size[0] + 2*off_ext_inner, board.size[1] + 2*off_ext_inner, extensionHeight() + 3 * eps, false)
            .translatedCopy(-off_ext_inner, -off_ext_inner, innerHeight + floors - 2 * eps);
    extension = extension - extensionInner;

    // Combine both
    return base + extension;
}
Example #3
0
Component CaseFactory::constructPart(Side whichSide)
{
    // Select parameters depending on which part to build
    auto innerHeight     = (whichSide == BottomSide) ? bottomInnerHeight()        : topInnerHeight();
    auto outerHeight     = (whichSide == BottomSide) ? bottomHeight()             : topHeight();
    auto forbiddenAreas  = (whichSide == BottomSide) ? board.bottomForbiddenAreas          : board.topForbiddenAreas;
    auto ports           = (whichSide == BottomSide) ? board.bottomPorts          : board.topPorts;
    auto wallSupports    = (whichSide == BottomSide) ? board.bottomWallSupports   : board.topWallSupports;
    auto extension       = (whichSide == outerExtensionOnSide) ? ExtensionOutside : ExtensionInside;
    auto screwHoleRadius =((whichSide == screwHeadsOnSide) ? holesAddRadiusLoose : holesAddRadiusTight) + board.holesRadius;
    auto screwHeads      = (whichSide == screwHeadsOnSide);

    // We start with the base
    Component c = constructBase(innerHeight, extension);

    // Add wall support
    for (auto wallSupport : wallSupports) {
        c = addWallSupport(c, outerHeight, wallSupport);
    }

    // Screw holes
    for (auto hole : board.holes) {
        c = addHoleForScrew(c, outerHeight, hole, screwHoleRadius, screwHeads);
    }

    // Added by: Anthony W. Rainer <*****@*****.**>
    // Modified by: Bogdan Vacaliuc <*****@*****.**> to allow selection of side
    if(whichSide == board.holeNutsSide) {
	// Screw holes Nuts
        for (auto holeNut : board.holeNuts) {
            c = addCavityForNut(c, outerHeight, board.holes[holeNut.holeIndex], holeNut);
        }
    }

    // Apply rounded corners (if enabled)
    if (cornerRadius > 0.0) {
        // Class "RoundedCube" of ooml is buggy as it doesn't respect the "faces" parameter.
        // So we construct our own rounded cuboid by taking the convex hull of eight spheres.
        Vec min = {-outset(), -outset(), 0};
        Vec max = outerDimensions() + min;
        Vec cornerOffset = {cornerRadius, cornerRadius, cornerRadius};
        min += cornerOffset;
        max -= cornerOffset;
        CompositeComponent roundedCorners = Hull::create();
        for (int corner = 0; corner < 8; corner++) {
            double x = (corner & (1 << 0)) ? min.x : max.x;
            double y = (corner & (1 << 1)) ? min.y : max.y;
            double z = (corner & (1 << 2)) ? min.z : max.z;
            roundedCorners.addComponent(Sphere(cornerRadius, cornerFaces).translatedCopy(x, y, z));
        }

        // Intersect the current part with the rounded cuboid
        c = c * roundedCorners;
    }

    // Port holes
    for (auto port : ports) {
        c = addHoleForPort(c, outerHeight, port);
    }

    // "Forbidden areas" of the board
    for (auto area : forbiddenAreas) {
        c = c - Cube(area.sx, area.sy, area.sz + extensionHeight() + eps, false)
                .translatedCopy(area.x, area.y, outerHeight - area.sz);
    }

    // If this is the top, we've just built it mirrored. So we mirror the y axis and move it so it matches the dimensions of the bottom part.
    if (whichSide == TopSide) {
        c.scale(1.0, -1.0, 1.0);
        c.translate(0.0, board.size[1], 0.0);
    }

    return c;
}
Example #4
0
// Like a==b, with a little slop recognizing that float equality can be weird.
static bool sloppy_rect_eq(SkRect a, SkRect b) {
    SkRect inset(a), outset(a);
    inset.inset(1, 1);
    outset.outset(1, 1);
    return outset.contains(b) && !inset.contains(b);
}
Example #5
0
int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_)
{
#if defined ZMQ_HAVE_POLLER
    // if poller is present, use that if there is at least 1 thread-safe socket,
    // otherwise fall back to the previous implementation as it's faster.
    for (int i = 0; i != nitems_; i++) {
        if (items_[i].socket
            && as_socket_base_t (items_[i].socket)->is_thread_safe ()) {
            return zmq_poller_poll (items_, nitems_, timeout_);
        }
    }
#endif // ZMQ_HAVE_POLLER
#if defined ZMQ_POLL_BASED_ON_POLL || defined ZMQ_POLL_BASED_ON_SELECT
    if (unlikely (nitems_ < 0)) {
        errno = EINVAL;
        return -1;
    }
    if (unlikely (nitems_ == 0)) {
        if (timeout_ == 0)
            return 0;
#if defined ZMQ_HAVE_WINDOWS
        Sleep (timeout_ > 0 ? timeout_ : INFINITE);
        return 0;
#elif defined ZMQ_HAVE_VXWORKS
        struct timespec ns_;
        ns_.tv_sec = timeout_ / 1000;
        ns_.tv_nsec = timeout_ % 1000 * 1000000;
        return nanosleep (&ns_, 0);
#else
        return usleep (timeout_ * 1000);
#endif
    }
    if (!items_) {
        errno = EFAULT;
        return -1;
    }

    zmq::clock_t clock;
    uint64_t now = 0;
    uint64_t end = 0;
#if defined ZMQ_POLL_BASED_ON_POLL
    zmq::fast_vector_t<pollfd, ZMQ_POLLITEMS_DFLT> pollfds (nitems_);

    //  Build pollset for poll () system call.
    for (int i = 0; i != nitems_; i++) {
        //  If the poll item is a 0MQ socket, we poll on the file descriptor
        //  retrieved by the ZMQ_FD socket option.
        if (items_[i].socket) {
            size_t zmq_fd_size = sizeof (zmq::fd_t);
            if (zmq_getsockopt (items_[i].socket, ZMQ_FD, &pollfds[i].fd,
                                &zmq_fd_size)
                == -1) {
                return -1;
            }
            pollfds[i].events = items_[i].events ? POLLIN : 0;
        }
        //  Else, the poll item is a raw file descriptor. Just convert the
        //  events to normal POLLIN/POLLOUT for poll ().
        else {
            pollfds[i].fd = items_[i].fd;
            pollfds[i].events =
              (items_[i].events & ZMQ_POLLIN ? POLLIN : 0)
              | (items_[i].events & ZMQ_POLLOUT ? POLLOUT : 0)
              | (items_[i].events & ZMQ_POLLPRI ? POLLPRI : 0);
        }
    }
#else
    //  Ensure we do not attempt to select () on more than FD_SETSIZE
    //  file descriptors.
    //  TODO since this function is called by a client, we could return errno EINVAL/ENOMEM/... here
    zmq_assert (nitems_ <= FD_SETSIZE);

    zmq::optimized_fd_set_t pollset_in (nitems_);
    FD_ZERO (pollset_in.get ());
    zmq::optimized_fd_set_t pollset_out (nitems_);
    FD_ZERO (pollset_out.get ());
    zmq::optimized_fd_set_t pollset_err (nitems_);
    FD_ZERO (pollset_err.get ());

    zmq::fd_t maxfd = 0;

    //  Build the fd_sets for passing to select ().
    for (int i = 0; i != nitems_; i++) {
        //  If the poll item is a 0MQ socket we are interested in input on the
        //  notification file descriptor retrieved by the ZMQ_FD socket option.
        if (items_[i].socket) {
            size_t zmq_fd_size = sizeof (zmq::fd_t);
            zmq::fd_t notify_fd;
            if (zmq_getsockopt (items_[i].socket, ZMQ_FD, &notify_fd,
                                &zmq_fd_size)
                == -1)
                return -1;
            if (items_[i].events) {
                FD_SET (notify_fd, pollset_in.get ());
                if (maxfd < notify_fd)
                    maxfd = notify_fd;
            }
        }
        //  Else, the poll item is a raw file descriptor. Convert the poll item
        //  events to the appropriate fd_sets.
        else {
            if (items_[i].events & ZMQ_POLLIN)
                FD_SET (items_[i].fd, pollset_in.get ());
            if (items_[i].events & ZMQ_POLLOUT)
                FD_SET (items_[i].fd, pollset_out.get ());
            if (items_[i].events & ZMQ_POLLERR)
                FD_SET (items_[i].fd, pollset_err.get ());
            if (maxfd < items_[i].fd)
                maxfd = items_[i].fd;
        }
    }

    zmq::optimized_fd_set_t inset (nitems_);
    zmq::optimized_fd_set_t outset (nitems_);
    zmq::optimized_fd_set_t errset (nitems_);
#endif

    bool first_pass = true;
    int nevents = 0;

    while (true) {
#if defined ZMQ_POLL_BASED_ON_POLL

        //  Compute the timeout for the subsequent poll.
        zmq::timeout_t timeout =
          zmq::compute_timeout (first_pass, timeout_, now, end);

        //  Wait for events.
        {
            int rc = poll (&pollfds[0], nitems_, timeout);
            if (rc == -1 && errno == EINTR) {
                return -1;
            }
            errno_assert (rc >= 0);
        }
        //  Check for the events.
        for (int i = 0; i != nitems_; i++) {
            items_[i].revents = 0;

            //  The poll item is a 0MQ socket. Retrieve pending events
            //  using the ZMQ_EVENTS socket option.
            if (items_[i].socket) {
                size_t zmq_events_size = sizeof (uint32_t);
                uint32_t zmq_events;
                if (zmq_getsockopt (items_[i].socket, ZMQ_EVENTS, &zmq_events,
                                    &zmq_events_size)
                    == -1) {
                    return -1;
                }
                if ((items_[i].events & ZMQ_POLLOUT)
                    && (zmq_events & ZMQ_POLLOUT))
                    items_[i].revents |= ZMQ_POLLOUT;
                if ((items_[i].events & ZMQ_POLLIN)
                    && (zmq_events & ZMQ_POLLIN))
                    items_[i].revents |= ZMQ_POLLIN;
            }
            //  Else, the poll item is a raw file descriptor, simply convert
            //  the events to zmq_pollitem_t-style format.
            else {
                if (pollfds[i].revents & POLLIN)
                    items_[i].revents |= ZMQ_POLLIN;
                if (pollfds[i].revents & POLLOUT)
                    items_[i].revents |= ZMQ_POLLOUT;
                if (pollfds[i].revents & POLLPRI)
                    items_[i].revents |= ZMQ_POLLPRI;
                if (pollfds[i].revents & ~(POLLIN | POLLOUT | POLLPRI))
                    items_[i].revents |= ZMQ_POLLERR;
            }

            if (items_[i].revents)
                nevents++;
        }

#else

        //  Compute the timeout for the subsequent poll.
        timeval timeout;
        timeval *ptimeout;
        if (first_pass) {
            timeout.tv_sec = 0;
            timeout.tv_usec = 0;
            ptimeout = &timeout;
        } else if (timeout_ < 0)
            ptimeout = NULL;
        else {
            timeout.tv_sec = static_cast<long> ((end - now) / 1000);
            timeout.tv_usec = static_cast<long> ((end - now) % 1000 * 1000);
            ptimeout = &timeout;
        }

        //  Wait for events. Ignore interrupts if there's infinite timeout.
        while (true) {
            memcpy (inset.get (), pollset_in.get (),
                    zmq::valid_pollset_bytes (*pollset_in.get ()));
            memcpy (outset.get (), pollset_out.get (),
                    zmq::valid_pollset_bytes (*pollset_out.get ()));
            memcpy (errset.get (), pollset_err.get (),
                    zmq::valid_pollset_bytes (*pollset_err.get ()));
#if defined ZMQ_HAVE_WINDOWS
            int rc =
              select (0, inset.get (), outset.get (), errset.get (), ptimeout);
            if (unlikely (rc == SOCKET_ERROR)) {
                errno = zmq::wsa_error_to_errno (WSAGetLastError ());
                wsa_assert (errno == ENOTSOCK);
                return -1;
            }
#else
            int rc = select (maxfd + 1, inset.get (), outset.get (),
                             errset.get (), ptimeout);
            if (unlikely (rc == -1)) {
                errno_assert (errno == EINTR || errno == EBADF);
                return -1;
            }
#endif
            break;
        }

        //  Check for the events.
        for (int i = 0; i != nitems_; i++) {
            items_[i].revents = 0;

            //  The poll item is a 0MQ socket. Retrieve pending events
            //  using the ZMQ_EVENTS socket option.
            if (items_[i].socket) {
                size_t zmq_events_size = sizeof (uint32_t);
                uint32_t zmq_events;
                if (zmq_getsockopt (items_[i].socket, ZMQ_EVENTS, &zmq_events,
                                    &zmq_events_size)
                    == -1)
                    return -1;
                if ((items_[i].events & ZMQ_POLLOUT)
                    && (zmq_events & ZMQ_POLLOUT))
                    items_[i].revents |= ZMQ_POLLOUT;
                if ((items_[i].events & ZMQ_POLLIN)
                    && (zmq_events & ZMQ_POLLIN))
                    items_[i].revents |= ZMQ_POLLIN;
            }
            //  Else, the poll item is a raw file descriptor, simply convert
            //  the events to zmq_pollitem_t-style format.
            else {
                if (FD_ISSET (items_[i].fd, inset.get ()))
                    items_[i].revents |= ZMQ_POLLIN;
                if (FD_ISSET (items_[i].fd, outset.get ()))
                    items_[i].revents |= ZMQ_POLLOUT;
                if (FD_ISSET (items_[i].fd, errset.get ()))
                    items_[i].revents |= ZMQ_POLLERR;
            }

            if (items_[i].revents)
                nevents++;
        }
#endif

        //  If timeout is zero, exit immediately whether there are events or not.
        if (timeout_ == 0)
            break;

        //  If there are events to return, we can exit immediately.
        if (nevents)
            break;

        //  At this point we are meant to wait for events but there are none.
        //  If timeout is infinite we can just loop until we get some events.
        if (timeout_ < 0) {
            if (first_pass)
                first_pass = false;
            continue;
        }

        //  The timeout is finite and there are no events. In the first pass
        //  we get a timestamp of when the polling have begun. (We assume that
        //  first pass have taken negligible time). We also compute the time
        //  when the polling should time out.
        if (first_pass) {
            now = clock.now_ms ();
            end = now + timeout_;
            if (now == end)
                break;
            first_pass = false;
            continue;
        }

        //  Find out whether timeout have expired.
        now = clock.now_ms ();
        if (now >= end)
            break;
    }

    return nevents;
#else
    //  Exotic platforms that support neither poll() nor select().
    errno = ENOTSUP;
    return -1;
#endif
}