void render_layer(int clayer, float alpha) { char *s = layer[clayer].index; char *e = layer[clayer].index + layer[clayer].size; float G = NAN, X = NAN, Y = NAN, E = NAN, Z = NAN, lastX = NAN, lastY = NAN, lastE = NAN; uint32_t seen = 0; for (X = 0; X < 201.0; X += 10.0) { gline(X, 0, X, 200, ((((int) X) % 50) == 0)?1:0.2, 0, 0, 0, 16); gline(0, X, 200, X, ((((int) X) % 50) == 0)?1:0.2, 0, 0, 0, 16); } //printf("render layer %d (%g)\n", clayer + 1, alpha); lastX = layer[clayer].startX; lastY = layer[clayer].startY; Z = layer[clayer].height; lastE = layer[clayer].startE; while (s < e) { seen = scanline(s, e - s, linewords, &s, LMASK('G') | LMASK('X') | LMASK('Y') | LMASK('Z') | LMASK('E')); if (SEEN('G') && (LW('G') == 0.0 || LW('G') == 1.0)) { G = LW('G'); if (SEEN('X')) X = LW('X'); if (SEEN('Y')) Y = LW('Y'); if (SEEN('Z')) Z = LW('Z'); if (SEEN('E')) E = LW('E'); //if (clayer == 2) // printf("SEEN %c%c%c%c X%g Y%g Z%g E%g\n", SEEN('X')?'X':' ', SEEN('Y')?'Y':' ', SEEN('Z')?'Z':' ', SEEN('E')?'E':' ', X, Y, Z, E); if (SEEN('X') || SEEN('Y')) { // draw uint8_t r = 0, g = 0, b = 0, a = 160; if (SEEN('E')) { r = 0; g = 0; b = 0; a = 224; } else if (Z > layer[clayer].height) { r = 224; g = 64; b = 64; a = 160; } else if (Z < layer[clayer].height) { r = 128; g = 0; b = 128; a = 160; } else { r = 0; g = 128; b = 64; a = 160; } if ((lastX != X || lastY != Y) && !isnan(X) && !isnan(Y) && lastX <= 200.0) gline(lastX, lastY, X, Y, extrusionWidth, r, g, b, a * alpha); } if (SEEN('X')) lastX = X; if (SEEN('Y')) lastY = Y; if (SEEN('E')) lastE = E; } } }
void scanLine() { static char* l = NULL; static float lastX = 0.0, lastY = 0.0, lastE = 0.0; if (l == NULL) l = gcodefile; char* end; uint32_t seen; if (l < gcodefile_end) { //printf("\t-\n"); seen = scanline(l, gcodefile_end - l, linewords, &end, LMASK('G') | LMASK('X') | LMASK('Y') | LMASK('Z') | LMASK('E')); if (SEEN('G')) { if (LW('G') == 0.0 || LW('G') == 1.0) { if (layer[layerCount].index == NULL) { layer[layerCount].index = l; layer[layerCount].startX = lastX; layer[layerCount].startY = lastY; layer[layerCount].startE = lastE; } if (SEEN('Z')) { //dumpZstack(); //printf("%d: Z%g\n", l - gcodefile, LW('Z')); if (layer[layerCount].height == NAN) layer[layerCount].height = LW('Z'); else { int i; //dumpZstack(); for (i = 0; i < ZstackIndex; i++) { //printf("Check %d: got %g vs found %g\n", i, Zstack[i].Z, LW('Z')); if (Zstack[i].Z == LW('Z')) { //printf("found end of hop\n"); // end of hop ZstackIndex = i + 1; break; } } //printf("ZS %d i %d\n", ZstackIndex, i); if (i >= ZstackIndex || ZstackIndex == 0) { //printf("found start of hop\n"); // start of hop or new layer Zstack[ZstackIndex].start = l; Zstack[ZstackIndex].X = lastX; Zstack[ZstackIndex].Y = lastY; Zstack[ZstackIndex].Z = LW('Z'); Zstack[ZstackIndex].E = lastE; ZstackIndex++; if (ZstackIndex >= 8) die("Zstack overflow!",""); } } } if (SEEN('E')) { // extrusion, collapse Z stack int i = ZstackIndex - 1; if (Zstack[i].Z != layer[layerCount].height) { //printf("E word at Z=%g\n", LW('Z')); //dumpZstack(); //printf("new layer!\n"); // finish previous layer layer[layerCount].size = Zstack[i].start - layer[layerCount].index; layer[layerCount].flags = 0; layer[layerCount].glList = 0; layer[layerCount].endX = Zstack[i].X; layer[layerCount].endY = Zstack[i].Y; layer[layerCount].endE = Zstack[i].E; // start new layer layerCount++; //printf("NEW LAYER: %d\n", layerCount); if (layerCount * sizeof(layerData) >= layerSize) { layerSize += sizeof(layerData) * 128; layer = realloc(layer, layerSize); if (layer == NULL) die("Scan: realloc layer",""); } //printf("START LAYER %d\n", layerCount); // initialise layer[layerCount].index = Zstack[i].start; layer[layerCount].startX = Zstack[i].X; layer[layerCount].startY = Zstack[i].Y; layer[layerCount].height = Zstack[i].Z; layer[layerCount].startE = Zstack[i].E; // flush Z stack memcpy(Zstack, &Zstack[i], sizeof(ZstackItem)); ZstackIndex = 1; //dumpZstack(); } } } if (SEEN('X')) lastX = LW('X'); if (SEEN('Y')) lastY = LW('Y'); if (SEEN('E')) lastE = LW('E'); } l = end; } if (l >= gcodefile_end) { layer[layerCount].size = l - layer[layerCount].index; layer[layerCount].flags = 0; layer[layerCount].glList = 0; layer[layerCount].endX = lastX; layer[layerCount].endY = lastY; layer[layerCount].endE = lastE; layerCount++; printf("Found %d layers\n", layerCount); if (0) for (int i = 0; i < layerCount; i++) { printf("Layer %d at %d+%d=%d\n", i, layer[i].index - gcodefile, layer[i].size, layer[i].index - gcodefile + layer[i].size); printf("\tHeight: %g\n", layer[i].height); printf("\tStarts at [%g,%g:%g]\n", layer[i].startX, layer[i].startY, layer[i].startE); printf("\tEnds at [%g,%g:%g]\n", layer[i].endX, layer[i].endY, layer[i].endE); } busy &= ~BUSY_SCANFILE; } }
void cproxy_process_upstream_ascii(conn *c, char *line) { assert(c != NULL); assert(c->next == NULL); assert(c->extra != NULL); assert(c->cmd == -1); assert(c->item == NULL); assert(line != NULL); assert(line == c->rcurr); assert(IS_ASCII(c->protocol)); assert(IS_PROXY(c->protocol)); if (settings.verbose > 2) { moxi_log_write("<%d cproxy_process_upstream_ascii %s\n", c->sfd, line); } // Snapshot rcurr, because the caller, try_read_command(), changes it. // c->cmd_curr = -1; c->cmd_start = c->rcurr; c->cmd_start_time = msec_current_time; c->cmd_retries = 0; proxy_td *ptd = c->extra; assert(ptd != NULL); /* For commands set/add/replace, we build an item and read the data * directly into it, then continue in nread_complete(). */ if (!cproxy_prep_conn_for_write(c)) { ptd->stats.stats.err_upstream_write_prep++; conn_set_state(c, conn_closing); return; } bool mcmux_command = false; bool self_command = false; /* Check for proxy pattern - A:host:port or B:host:port */ if (true == settings.enable_mcmux_mode && ((*line == 'A' || *line == 'B') && *(line + 1) == ':')) { mcmux_command = true; } else if (true == settings.enable_mcmux_mode) { self_command = true; } c->peer_protocol = 0; c->peer_host = NULL; c->peer_port = 0; if (mcmux_command) { char *peer_port = NULL; int i = 0; c->peer_protocol = (*line == 'A') ? proxy_downstream_ascii_prot : proxy_downstream_binary_prot; line += 2; c->peer_host = line; while (*line != ' ' && *line != '\0' && *line != ':' && ++i < MAX_HOSTNAME_LEN) { line++; } if (*line == '\0' || line - c->peer_host <= 0) { out_string(c, "ERROR"); moxi_log_write("Malformed request line"); return; } *line = '\0'; line++; peer_port = line; i = 0; while (*line != ' ' && *line != '\0' && ++i <= MAX_PORT_LEN) { line++; } if (*line == '\0' || line - peer_port <= 0) { out_string(c, "ERROR"); moxi_log_write("Malformed request line"); return; } c->peer_port = atoi(peer_port); *line++ = '\0'; c->cmd_start = line; } int cmd_len = 0; token_t tokens[MAX_TOKENS]; size_t ntokens = scan_tokens(line, tokens, MAX_TOKENS, &cmd_len); char *cmd = tokens[COMMAND_TOKEN].value; int cmdx = -1; int cmd_st = STATS_CMD_TYPE_REGULAR; int comm; #define SEEN(cmd_id, is_cas, cmd_len) \ cmd_st = c->noreply ? \ STATS_CMD_TYPE_QUIET : STATS_CMD_TYPE_REGULAR; \ ptd->stats.stats_cmd[cmd_st][cmd_id].seen++; \ ptd->stats.stats_cmd[cmd_st][cmd_id].read_bytes += cmd_len; \ if (is_cas) { \ ptd->stats.stats_cmd[cmd_st][cmd_id].cas++; \ } if (ntokens >= 3 && (false == self_command) && (strncmp(cmd, "get", 3) == 0)) { if (cmd[3] == 'l') { c->cmd_curr = PROTOCOL_BINARY_CMD_GETL; } else if (ntokens == 3) { // Single-key get/gets optimization. // c->cmd_curr = PROTOCOL_BINARY_CMD_GETK; } else { c->cmd_curr = PROTOCOL_BINARY_CMD_GETKQ; } // Handles get and gets. // cproxy_pause_upstream_for_downstream(ptd, c); // The cmd_len from scan_tokens might not include // all the keys, so cmd_len might not == strlen(command). // Handle read_bytes during multiget broadcast. // if (cmd[3] == 'l') { SEEN(STATS_CMD_GETL, true, 0); } else { SEEN(STATS_CMD_GET, cmd[3] == 's', 0); } } else if ((ntokens == 6 || ntokens == 7) && (false == self_command) && ((strncmp(cmd, "add", 3) == 0 && (comm = NREAD_ADD) && (cmdx = STATS_CMD_ADD) && (c->cmd_curr = PROTOCOL_BINARY_CMD_ADD)) || (strncmp(cmd, "set", 3) == 0 && (comm = NREAD_SET) && (cmdx = STATS_CMD_SET) && (c->cmd_curr = PROTOCOL_BINARY_CMD_SET)) || (strncmp(cmd, "replace", 7) == 0 && (comm = NREAD_REPLACE) && (cmdx = STATS_CMD_REPLACE) && (c->cmd_curr = PROTOCOL_BINARY_CMD_REPLACE)) || (strncmp(cmd, "prepend", 7) == 0 && (comm = NREAD_PREPEND) && (cmdx = STATS_CMD_PREPEND) && (c->cmd_curr = PROTOCOL_BINARY_CMD_PREPEND)) || (strncmp(cmd, "append", 6) == 0 && (comm = NREAD_APPEND) && (cmdx = STATS_CMD_APPEND) && (c->cmd_curr = PROTOCOL_BINARY_CMD_APPEND)))) { assert(c->item == NULL); c->item = NULL; process_update_command(c, tokens, ntokens, comm, false); if (cmdx >= 0) { item *it = c->item; if (it != NULL) { SEEN(cmdx, false, cmd_len + it->nbytes); } else { SEEN(cmdx, false, cmd_len); ptd->stats.stats_cmd[cmd_st][cmdx].misses++; } } } else if ((ntokens == 7 || ntokens == 8) && (false == self_command) && (strncmp(cmd, "cas", 3) == 0 && (comm = NREAD_CAS) && (c->cmd_curr = PROTOCOL_BINARY_CMD_SET))) { assert(c->item == NULL); c->item = NULL; process_update_command(c, tokens, ntokens, comm, true); item *it = c->item; if (it != NULL) { SEEN(STATS_CMD_CAS, true, cmd_len + it->nbytes); } else { SEEN(STATS_CMD_CAS, true, cmd_len); ptd->stats.stats_cmd[cmd_st][STATS_CMD_CAS].misses++; } } else if ((ntokens == 4 || ntokens == 5) && (false == self_command) && (strncmp(cmd, "incr", 4) == 0) && (c->cmd_curr = PROTOCOL_BINARY_CMD_INCREMENT)) { set_noreply_maybe(c, tokens, ntokens); cproxy_pause_upstream_for_downstream(ptd, c); SEEN(STATS_CMD_INCR, false, cmd_len); } else if ((ntokens == 4 || ntokens == 5) && (false == self_command) && (strncmp(cmd, "decr", 4) == 0) && (c->cmd_curr = PROTOCOL_BINARY_CMD_DECREMENT)) { set_noreply_maybe(c, tokens, ntokens); cproxy_pause_upstream_for_downstream(ptd, c); SEEN(STATS_CMD_DECR, false, cmd_len); } else if (ntokens >= 3 && ntokens <= 4 && (false == self_command) && (strncmp(cmd, "delete", 6) == 0) && (c->cmd_curr = PROTOCOL_BINARY_CMD_DELETE)) { set_noreply_maybe(c, tokens, ntokens); cproxy_pause_upstream_for_downstream(ptd, c); SEEN(STATS_CMD_DELETE, false, cmd_len); } else if (ntokens >= 2 && ntokens <= 4 && (false == self_command) && (strncmp(cmd, "flush_all", 9) == 0) && (c->cmd_curr = PROTOCOL_BINARY_CMD_FLUSH)) { set_noreply_maybe(c, tokens, ntokens); cproxy_pause_upstream_for_downstream(ptd, c); SEEN(STATS_CMD_FLUSH_ALL, false, cmd_len); } else if (ntokens >= 3 && ntokens <= 4 && (strncmp(cmd, "stats proxy", 10) == 0)) { process_stats_proxy_command(c, tokens, ntokens); SEEN(STATS_CMD_STATS, false, cmd_len); } else if (ntokens == 3 && (false == self_command) && (strcmp(cmd, "stats reset") == 0) && (c->cmd_curr = PROTOCOL_BINARY_CMD_STAT)) { cproxy_pause_upstream_for_downstream(ptd, c); SEEN(STATS_CMD_STATS_RESET, false, cmd_len); } else if (ntokens == 2 && (false == self_command) && (strcmp(cmd, "stats") == 0) && (c->cmd_curr = PROTOCOL_BINARY_CMD_STAT)) { // Even though we've coded to handle advanced stats // like stats cachedump, prevent those here to avoid // locking downstream servers. // cproxy_pause_upstream_for_downstream(ptd, c); SEEN(STATS_CMD_STATS, false, cmd_len); } else if (ntokens == 2 && (true == mcmux_command) && (strncmp(cmd, "version", 7) == 0) && (c->cmd_curr = PROTOCOL_BINARY_CMD_VERSION)) { /* downstream version command */ cproxy_pause_upstream_for_downstream(ptd, c); SEEN(STATS_CMD_VERSION, false, cmd_len); } else if (ntokens == 2 && (strncmp(cmd, "version", 7) == 0)) { out_string(c, "VERSION " VERSION); SEEN(STATS_CMD_VERSION, false, cmd_len); } else if ((ntokens == 3 || ntokens == 4) && (strncmp(cmd, "verbosity", 9) == 0)) { process_verbosity_command(c, tokens, ntokens); SEEN(STATS_CMD_VERBOSITY, false, cmd_len); } else if (ntokens == 2 && (strncmp(cmd, "quit", 4) == 0)) { conn_set_state(c, conn_closing); SEEN(STATS_CMD_QUIT, false, cmd_len); } else if (ntokens == 4 && (strncmp(cmd, "unl", 3) == 0) && (false == self_command) && (c->cmd_curr = PROTOCOL_BINARY_CMD_UNL)) { cproxy_pause_upstream_for_downstream(ptd, c); SEEN(STATS_CMD_UNL, false, cmd_len); } else { out_string(c, "ERROR"); SEEN(STATS_CMD_ERROR, false, cmd_len); } }