// Print what is wrong with the grid, appending it to the existing string void GridDefinition::PrintError(float originalXrange, float originalYrange, StringRef& r) const { if (spacing < MinSpacing) { r.cat("Spacing too small"); } else if (numX == 0) { r.cat("X range too small"); } else if (numY == 0) { r.cat("Y range too small"); } else if ( numX > MaxXGridPoints || numX > MaxGridProbePoints || numY > MaxGridProbePoints // check X and Y individually in case X*Y overflows || NumPoints() > MaxGridProbePoints ) { const float totalRange = originalXrange + originalYrange; const float area = originalXrange * originalYrange; const float minSpacing = (totalRange + sqrtf(fsquare(totalRange) + 4.0 * (MaxGridProbePoints - 1) * area))/(2.0 * (MaxGridProbePoints - 1)); const float minXspacing = originalXrange/(MaxXGridPoints - 1); r.catf("Too many grid points; suggest increase spacing to %.1fmm", max<float>(minSpacing, minXspacing)); } else { // The only thing left is a bad radius r.cat("Bad radius"); } }
void Tool::Print(StringRef& reply) { reply.printf("Tool %d - drives:", myNumber); char sep = ' '; for (size_t drive = 0; drive < driveCount; drive++) { reply.catf("%c%d", sep, drives[drive]); sep = ','; } reply.cat("; heaters (active/standby temps):"); sep = ' '; for (size_t heater = 0; heater < heaterCount; heater++) { reply.catf("%c%d (%.1f/%.1f)", sep, heaters[heater], activeTemperatures[heater], standbyTemperatures[heater]); sep = ','; } reply.cat("; xmap:"); sep = ' '; for (size_t xi = 0; xi < MAX_AXES; ++xi) { if ((xMapping & (1u << xi)) != 0) { reply.catf("%c%c", sep, GCodes::axisLetters[xi]); sep = ','; } } reply.cat("; fans:"); sep = ' '; for (size_t fi = 0; fi < NUM_FANS; ++fi) { if ((fanMapping & (1u << fi)) != 0) { reply.catf("%c%u", sep, fi); sep = ','; } } reply.catf("; status: %s", active ? "selected" : "standby"); }
// Load the grid from file, returning true if an error occurred with the error reason appended to the buffer bool HeightMap::LoadFromFile(FileStore *f, StringRef& r) { const size_t MaxLineLength = (MaxXGridPoints * 8) + 2; // maximum length of a line in the height map file, need 8 characters per grid point const char* const readFailureText = "failed to read line from file"; char buffer[MaxLineLength + 1]; StringRef s(buffer, ARRAY_SIZE(buffer)); ClearGridHeights(); GridDefinition newGrid; if (f->ReadLine(buffer, sizeof(buffer)) <= 0) { r.cat(readFailureText); } else if (!StringStartsWith(buffer, HeightMapComment)) // check the version line is as expected { r.cat("bad header line or wrong version header"); } else if (f->ReadLine(buffer, sizeof(buffer)) <= 0) { r.cat(readFailureText); } else if (!GridDefinition::CheckHeading(s)) // check the label line is as expected { r.cat("bad label line"); } else if (f->ReadLine(buffer, sizeof(buffer)) <= 0) // read the height map parameters { r.cat(readFailureText); } else if (!newGrid.ReadParameters(s)) { r.cat("failed to parse grid parameters"); } else if (!newGrid.IsValid()) { r.cat("invalid grid"); } else { SetGrid(newGrid); for (uint32_t row = 0; row < def.numY; ++row) // read the grid a row at a time { if (f->ReadLine(buffer, sizeof(buffer)) <= 0) { r.cat(readFailureText); return true; // failed to read a line } const char *p = buffer; for (uint32_t col = 0; col < def.numX; ++col) { if (*p == '0' && (p[1] == ',' || p[1] == 0)) { // Values of 0 with no decimal places in un-probed values, so leave the point set as not valid ++p; } else { char* np = nullptr; const float f = strtod(p, &np); if (np == p) { r.catf("number expected at line %u column %d", row + 3, (p - buffer) + 1); return true; // failed to read a number } SetGridHeight(col, row, f); p = np; } if (*p == ',') { ++p; } } } ExtrapolateMissing(); return false; // success! } return true; // an error occurred }