Ejemplo n.º 1
0
//update frames for many vertex position changes
//assumes this is the first piece of thread
void ThreadPiece::updateFrames_all()
{
	update_edge();
	update_bishop_frame_firstPiece();
	ThreadPiece* curr_piece = _next_piece;

#ifdef ISOTROPIC
	for ( ; curr_piece->_next_piece != NULL; curr_piece = curr_piece->_next_piece)
	{
		curr_piece->update_edge();
		curr_piece->update_bishop_frame();
	}
  
  curr_piece = curr_piece->_prev_piece;
  curr_piece->_angle_twist += curr_piece->twist_angle_error();

#else
	update_material_frame();
	double twist_to_add = 0;
	for ( ; curr_piece->_next_piece != NULL; curr_piece = curr_piece->_next_piece)
	{
		curr_piece->update_edge();
		curr_piece->update_bishop_frame();
		curr_piece->_angle_twist += twist_to_add;
		double this_err = curr_piece->twist_angle_error();
		twist_to_add += this_err;
		curr_piece->_angle_twist += this_err;
		curr_piece->update_material_frame();
	}
#endif
}
Ejemplo n.º 2
0
//not applicable for first 2 or last 2 pieces
void ThreadPiece::updateFrames()
{
  /*if (_prev_piece == NULL || _prev_piece->_prev_piece == NULL || _next_piece == NULL || _next_piece->_next_piece == NULL)
  {
    std::cerr << "shouldn't call updateFrames() on the first 2 or last 2 pieces!" << std::endl;
    exit(0);
  }*/

  _prev_piece->update_edge();
  update_edge();

  ThreadPiece* to_change_bishop = _prev_piece;
  while (to_change_bishop->_next_piece != NULL)
  {
    to_change_bishop->update_bishop_frame();
    to_change_bishop = to_change_bishop->_next_piece;
  }


#ifdef ISOTROPIC
  //angle of last piece is the only one that matters
  to_change_bishop = to_change_bishop->_prev_piece;
  to_change_bishop->_angle_twist += to_change_bishop->twist_angle_error();
#else
  //twist angle may have changed
  double angle_twist_diff = _next_piece->twist_angle_error();
  //_prev_piece->_angle_twist += angle_twist_diff/3.0;
  _prev_piece->update_material_frame();
  //_angle_twist += 2.0*angle_twist_diff/3.0;
  update_material_frame();

  ThreadPiece* to_change_twist = _next_piece;
  while (to_change_twist->_next_piece != NULL)
  {
    to_change_twist->_angle_twist += angle_twist_diff;
    to_change_twist = to_change_twist->_next_piece;
  }
#endif
}
Ejemplo n.º 3
0
//THIS MAKES THREAD DATA INCONSISTENT! Careful when using
void ThreadPiece::offset_and_update_locally(const Vector3d& offset)
{

  //offset this vertex (call it vertex i)
  _vertex += offset;

#ifdef ISOTROPIC
  updateFrames();
#else
  //calculate the locally changed edges and bishop frames (from i-1 to i+1)
	if (_prev_piece != NULL)
	{
		_prev_piece->update_edge();
		if (_prev_piece->_prev_piece != NULL) {
			_prev_piece->update_bishop_frame();
			_prev_piece->update_material_frame();
		}
	}

	if (_next_piece != NULL)
	{
		update_edge();
		if (_prev_piece != NULL)
		{
			update_bishop_frame();
		}
		if (_next_piece->_next_piece != NULL)
		{
			_next_piece->update_bishop_frame();
			//find how the change in bishop frame affects the angle change
			update_material_frame();
			double angle_twist_diff = _next_piece->twist_angle_error();
			// std::cout << "angle twist diff: " << angle_twist_diff << std::endl;
			_next_piece->_angle_twist += angle_twist_diff;
			//_next_piece->update_material_frame();
		}
	}
#endif
}
Ejemplo n.º 4
0
//assumes the angles are correct, and calculates the material frames
void ThreadPiece::initializeFrames()
{
  if (_next_piece == NULL)
	{
//		update_bishop_frame_lastPiece();
//		update_material_frame();
    return;
	}

  update_edge();

  //now update bishop and material frames
  if (_prev_piece != NULL)
  {
    update_bishop_frame();
    update_material_frame();
  } else {
		update_bishop_frame_firstPiece();
    update_material_frame();
	}

  _next_piece->initializeFrames();
}
Ejemplo n.º 5
0
// Needs Y to only change once (looser than convex in X)
static void walk_simple_edges(SkEdge* prevHead, SkBlitter* blitter, int start_y, int stop_y) {
    validate_sort(prevHead->fNext);

    SkEdge* leftE = prevHead->fNext;
    SkEdge* riteE = leftE->fNext;
    SkEdge* currE = riteE->fNext;

#if 0
    int local_top = leftE->fFirstY;
    SkASSERT(local_top == riteE->fFirstY);
#else
    // our edge choppers for curves can result in the initial edges
    // not lining up, so we take the max.
    int local_top = SkMax32(leftE->fFirstY, riteE->fFirstY);
#endif
    ASSERT_RETURN(local_top >= start_y);

    while (local_top < stop_y) {
        SkASSERT(leftE->fFirstY <= stop_y);
        SkASSERT(riteE->fFirstY <= stop_y);

        int local_bot = SkMin32(leftE->fLastY, riteE->fLastY);
        local_bot = SkMin32(local_bot, stop_y - 1);
        ASSERT_RETURN(local_top <= local_bot);

        SkFixed left = leftE->fX;
        SkFixed dLeft = leftE->fDX;
        SkFixed rite = riteE->fX;
        SkFixed dRite = riteE->fDX;
        int count = local_bot - local_top;
        ASSERT_RETURN(count >= 0);
        if (0 == (dLeft | dRite)) {
            int L = SkFixedRoundToInt(left);
            int R = SkFixedRoundToInt(rite);
            if (L > R) {
                std::swap(L, R);
            }
            if (L < R) {
                count += 1;
                blitter->blitRect(L, local_top, R - L, count);
            }
            local_top = local_bot + 1;
        } else {
            do {
                int L = SkFixedRoundToInt(left);
                int R = SkFixedRoundToInt(rite);
                if (L > R) {
                    std::swap(L, R);
                }
                if (L < R) {
                    blitter->blitH(L, local_top, R - L);
                }
                // Either/both of these might overflow, since we perform this step even if
                // (later) we determine that we are done with the edge, and so the computed
                // left or rite edge will not be used (see update_edge). Use this helper to
                // silence UBSAN when we perform the add.
                left = Sk32_can_overflow_add(left, dLeft);
                rite = Sk32_can_overflow_add(rite, dRite);
                local_top += 1;
            } while (--count >= 0);
        }

        leftE->fX = left;
        riteE->fX = rite;

        if (!update_edge(leftE, local_bot)) {
            if (currE->fFirstY >= stop_y) {
                return; // we're done
            }
            leftE = currE;
            currE = currE->fNext;
            ASSERT_RETURN(leftE->fFirstY == local_top);
        }
        if (!update_edge(riteE, local_bot)) {
            if (currE->fFirstY >= stop_y) {
                return; // we're done
            }
            riteE = currE;
            currE = currE->fNext;
            ASSERT_RETURN(riteE->fFirstY == local_top);
        }
    }
}
Ejemplo n.º 6
0
/** Examine a datagram and determine what to do with it.
 *
 */
static int process_udp( n2n_sn_t * sss, 
                        const struct sockaddr_in * sender_sock,
                        const uint8_t * udp_buf, 
                        size_t udp_size,
                        time_t now)
{
    n2n_common_t        cmn; /* common fields in the packet header */
    size_t              rem;
    size_t              idx;
    size_t              msg_type;
    uint8_t             from_supernode;
    macstr_t            mac_buf;
    macstr_t            mac_buf2;
    n2n_sock_str_t      sockbuf;


    traceEvent( TRACE_DEBUG, "process_udp(%lu)", udp_size );

    /* Use decode_common() to determine the kind of packet then process it:
     *
     * REGISTER_SUPER adds an edge and generate a return REGISTER_SUPER_ACK
     *
     * REGISTER, REGISTER_ACK and PACKET messages are forwarded to their
     * destination edge. If the destination is not known then PACKETs are
     * broadcast.
     */

    rem = udp_size; /* Counts down bytes of packet to protect against buffer overruns. */
    idx = 0; /* marches through packet header as parts are decoded. */
    if ( decode_common(&cmn, udp_buf, &rem, &idx) < 0 )
    {
        traceEvent( TRACE_ERROR, "Failed to decode common section" );
        return -1; /* failed to decode packet */
    }

    msg_type = cmn.pc; /* packet code */
    from_supernode= cmn.flags & N2N_FLAGS_FROM_SUPERNODE;

    if ( cmn.ttl < 1 )
    {
        traceEvent( TRACE_WARNING, "Expired TTL" );
        return 0; /* Don't process further */
    }

    --(cmn.ttl); /* The value copied into all forwarded packets. */

    if ( msg_type == MSG_TYPE_PACKET )
    {
        /* PACKET from one edge to another edge via supernode. */

        /* pkt will be modified in place and recoded to an output of potentially
         * different size due to addition of the socket.*/
        n2n_PACKET_t                    pkt; 
        n2n_common_t                    cmn2;
        uint8_t                         encbuf[N2N_SN_PKTBUF_SIZE];
        size_t                          encx=0;
        int                             unicast; /* non-zero if unicast */
        const uint8_t *                 rec_buf; /* either udp_buf or encbuf */


        sss->stats.last_fwd=now;
        decode_PACKET( &pkt, &cmn, udp_buf, &rem, &idx );

        unicast = (0 == is_multi_broadcast(pkt.dstMac) );

        traceEvent( TRACE_DEBUG, "Rx PACKET (%s) %s -> %s %s",
                    (unicast?"unicast":"multicast"),
                    macaddr_str( mac_buf, pkt.srcMac ),
                    macaddr_str( mac_buf2, pkt.dstMac ),
                    (from_supernode?"from sn":"local") );

        if ( !from_supernode )
        {
            memcpy( &cmn2, &cmn, sizeof( n2n_common_t ) );

            /* We are going to add socket even if it was not there before */
            cmn2.flags |= N2N_FLAGS_SOCKET | N2N_FLAGS_FROM_SUPERNODE;

            pkt.sock.family = AF_INET;
            pkt.sock.port = ntohs(sender_sock->sin_port);
            memcpy( pkt.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE );

            rec_buf = encbuf;

            /* Re-encode the header. */
            encode_PACKET( encbuf, &encx, &cmn2, &pkt );

            /* Copy the original payload unchanged */
            encode_buf( encbuf, &encx, (udp_buf + idx), (udp_size - idx ) );
        }
        else
        {
            /* Already from a supernode. Nothing to modify, just pass to
             * destination. */

            traceEvent( TRACE_DEBUG, "Rx PACKET fwd unmodified" );

            rec_buf = udp_buf;
            encx = udp_size;
        }

        /* Common section to forward the final product. */
        if ( unicast )
        {
            try_forward( sss, &cmn, pkt.dstMac, rec_buf, encx );
        }
        else
        {
            try_broadcast( sss, &cmn, pkt.srcMac, rec_buf, encx );
        }
    }/* MSG_TYPE_PACKET */
    else if ( msg_type == MSG_TYPE_REGISTER )
    {
        /* Forwarding a REGISTER from one edge to the next */

        n2n_REGISTER_t                  reg;
        n2n_common_t                    cmn2;
        uint8_t                         encbuf[N2N_SN_PKTBUF_SIZE];
        size_t                          encx=0;
        int                             unicast; /* non-zero if unicast */
        const uint8_t *                 rec_buf; /* either udp_buf or encbuf */

        sss->stats.last_fwd=now;
        decode_REGISTER( &reg, &cmn, udp_buf, &rem, &idx );

        unicast = (0 == is_multi_broadcast(reg.dstMac) );
        
        if ( unicast )
        {
        traceEvent( TRACE_DEBUG, "Rx REGISTER %s -> %s %s",
                    macaddr_str( mac_buf, reg.srcMac ),
                    macaddr_str( mac_buf2, reg.dstMac ),
                    ((cmn.flags & N2N_FLAGS_FROM_SUPERNODE)?"from sn":"local") );

        if ( 0 != (cmn.flags & N2N_FLAGS_FROM_SUPERNODE) )
        {
            memcpy( &cmn2, &cmn, sizeof( n2n_common_t ) );

            /* We are going to add socket even if it was not there before */
            cmn2.flags |= N2N_FLAGS_SOCKET | N2N_FLAGS_FROM_SUPERNODE;

            reg.sock.family = AF_INET;
            reg.sock.port = ntohs(sender_sock->sin_port);
            memcpy( reg.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE );

            rec_buf = encbuf;

            /* Re-encode the header. */
            encode_REGISTER( encbuf, &encx, &cmn2, &reg );

            /* Copy the original payload unchanged */
            encode_buf( encbuf, &encx, (udp_buf + idx), (udp_size - idx ) );
        }
        else
        {
            /* Already from a supernode. Nothing to modify, just pass to
             * destination. */

            rec_buf = udp_buf;
            encx = udp_size;
        }

        try_forward( sss, &cmn, reg.dstMac, rec_buf, encx ); /* unicast only */
        }
        else
        {
            traceEvent( TRACE_ERROR, "Rx REGISTER with multicast destination" );
        }

    }
    else if ( msg_type == MSG_TYPE_REGISTER_ACK )
    {
        traceEvent( TRACE_DEBUG, "Rx REGISTER_ACK (NOT IMPLEMENTED) SHould not be via supernode" );
    }
    else if ( msg_type == MSG_TYPE_REGISTER_SUPER )
    {
        n2n_REGISTER_SUPER_t            reg;
        n2n_REGISTER_SUPER_ACK_t        ack;
        n2n_common_t                    cmn2;
        uint8_t                         ackbuf[N2N_SN_PKTBUF_SIZE];
        size_t                          encx=0;

        /* Edge requesting registration with us.  */
        
        sss->stats.last_reg_super=now;
        ++(sss->stats.reg_super);
        decode_REGISTER_SUPER( &reg, &cmn, udp_buf, &rem, &idx );

        cmn2.ttl = N2N_DEFAULT_TTL;
        cmn2.pc = n2n_register_super_ack;
        cmn2.flags = N2N_FLAGS_SOCKET | N2N_FLAGS_FROM_SUPERNODE;
        memcpy( cmn2.community, cmn.community, sizeof(n2n_community_t) );

        memcpy( &(ack.cookie), &(reg.cookie), sizeof(n2n_cookie_t) );
        memcpy( ack.edgeMac, reg.edgeMac, sizeof(n2n_mac_t) );
        ack.lifetime = reg_lifetime( sss );

        ack.sock.family = AF_INET;
        ack.sock.port = ntohs(sender_sock->sin_port);
        memcpy( ack.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE );

        ack.num_sn=0; /* No backup */
        memset( &(ack.sn_bak), 0, sizeof(n2n_sock_t) );

        traceEvent( TRACE_DEBUG, "Rx REGISTER_SUPER for %s [%s]",
                    macaddr_str( mac_buf, reg.edgeMac ),
                    sock_to_cstr( sockbuf, &(ack.sock) ) );

        update_edge( sss, reg.edgeMac, cmn.community, &(ack.sock), now );

#ifdef N2N_MULTIPLE_SUPERNODES
        {
            struct comm_info *ci = comm_find(sss->communities.list_head,
                                             cmn.community, strlen((const char *) cmn.community));
            if (ci)
            {
                ack.num_sn = ci->sn_num;
                memcpy(&ack.sn_bak, ci->sn_sock, ci->sn_num * sizeof(n2n_sock_t));
            }
        }
#endif

        encode_REGISTER_SUPER_ACK( ackbuf, &encx, &cmn2, &ack );

        sendto( sss->sock, ackbuf, encx, 0, 
                (struct sockaddr *)sender_sock, sizeof(struct sockaddr_in) );

        traceEvent( TRACE_DEBUG, "Tx REGISTER_SUPER_ACK for %s [%s]",
                    macaddr_str( mac_buf, reg.edgeMac ),
                    sock_to_cstr( sockbuf, &(ack.sock) ) );

    }


    return 0;
}