Stefan Schuermans commited on 2017-06-04 16:48:09
              Showing 1 changed files, with 157 additions and 101 deletions.
            
move some code from main to own functions exit with few different error codes
| ... | ... | @@ -35,6 +35,13 @@ | 
| 35 | 35 | #include "pixel.h" | 
| 36 | 36 | #include "point.h" | 
| 37 | 37 |  | 
| 38 | +#define SUCCESS (0) // no error | |
| 39 | +#define ERR_USAGE (2) // invalid command line arguments | |
| 40 | +#define ERR_FILE_OPEN (3) // could not open input/output file | |
| 41 | +#define ERR_FILE_READ (4) // could not read input file | |
| 42 | +#define ERR_FILE_PROC (5) // could not process input file | |
| 43 | +#define ERR_PROC (5) // error in processing of objects found in input file | |
| 44 | + | |
| 38 | 45 | // layers of drawing | 
| 39 | 46 | Layer gLayerVideo, gLayerPixel, gLayerNetwork; | 
| 40 | 47 | std::map<unsigned int, Layer> gLayerCables, gLayerDistributors; | 
| ... | ... | @@ -209,11 +216,71 @@ static bool cbEntity(const class dimeState * const state, | 
| 209 | 216 | return true; | 
| 210 | 217 | } | 
| 211 | 218 |  | 
| 219 | +/** | |
| 220 | + * @brief read a DXF file and process objects found in it | |
| 221 | + * @param[in] strDxfFileName name of DXF file | |
| 222 | + * @param[out] width width of logical video frame | |
| 223 | + * @param[out] height height of logical video frame | |
| 224 | + * @param[out] chains number of chains (outputs) per distributor | |
| 225 | + * @param[out] pixels number of pixels in one chain | |
| 226 | + * (i.e. connected to one output) | |
| 227 | + * @return SUCCESS on success, other value on error | |
| 228 | + */ | |
| 229 | +static int readDXF(std::string const &strDxfFileName, | |
| 230 | + unsigned int &width, unsigned int &height, | |
| 231 | + unsigned int &chains, unsigned int &pixels) | |
| 232 | +{ | |
| 233 | + // read DXF file | |
| 234 | + dimeInput in; | |
| 235 | +  if (!in.setFile(strDxfFileName.c_str())) { | |
| 236 | + std::cerr << "error opening file \"" << strDxfFileName | |
| 237 | + << "\" for reading" << std::endl; | |
| 238 | + return ERR_FILE_OPEN; | |
| 239 | + } | |
| 240 | + dimeModel model; | |
| 241 | +  if (!model.read(&in)) { | |
| 242 | + std::cerr << "DXF read error in line " << in.getFilePosition() | |
| 243 | + << " of file \"" << strDxfFileName << "\"" | |
| 244 | + << std::endl; | |
| 245 | + return ERR_FILE_READ; | |
| 246 | + } | |
| 247 | + | |
| 248 | + // get configuration from layers | |
| 249 | +  if (! get_config(model, width, height, chains, pixels)) { | |
| 250 | + return ERR_FILE_PROC; | |
| 251 | + } | |
| 252 | + | |
| 253 | + // enumerate all entities | |
| 254 | + model.traverseEntities(cbEntity, NULL); | |
| 255 | + | |
| 256 | + // merge all cable layers | |
| 257 | + std::map<unsigned int, Layer>::iterator itCable; | |
| 258 | + for (itCable = gLayerCables.begin(); | |
| 259 | + itCable != gLayerCables.end(); ++itCable) | |
| 260 | + gLayerCable.merge(&itCable->second); | |
| 261 | + // gLayerCables[] is now empty and will not be used any more | |
| 262 | + | |
| 263 | + // output object count information | |
| 264 | + std::cout << "object counts:" << std::endl; | |
| 265 | + std::cout << " video: " << gLayerVideo.mObjects.size() << std::endl; | |
| 266 | + std::cout << " pixel: " << gLayerPixel.mObjects.size() << std::endl; | |
| 267 | + std::cout << " cable: " << gLayerCable.mObjects.size() << std::endl; | |
| 268 | + std::cout << " network: " << gLayerNetwork.mObjects.size() << std::endl; | |
| 269 | + std::cout << " distributor:" << std::endl; | |
| 270 | + std::map<unsigned int, Layer>::const_iterator itDistri; | |
| 271 | + for (itDistri = gLayerDistributors.begin(); | |
| 272 | + itDistri != gLayerDistributors.end(); ++itDistri) | |
| 273 | + std::cout << " " << itDistri->first << ": " | |
| 274 | + << itDistri->second.mObjects.size() << std::endl; | |
| 275 | + | |
| 276 | + return SUCCESS; | |
| 277 | +} | |
| 278 | + | |
| 212 | 279 | /** | 
| 213 | 280 | * @brief create a chain | 
| 214 | 281 | * @param[in] chain chain to create | 
| 215 | 282 | * @param[in] pObjCable cable to first pixel | 
| 216 | - * @return 0 on success, -1 on error | |
| 283 | + * @return SUCCESS on success, other value on error | |
| 217 | 284 | */ | 
| 218 | 285 | static int createChain(Chain &chain, const Object *pObjCable) | 
| 219 | 286 |  { | 
| ... | ... | @@ -238,14 +305,14 @@ static int createChain(Chain &chain, const Object *pObjCable) | 
| 238 | 305 |  | 
| 239 | 306 | // end of chain | 
| 240 | 307 | if (intersectsPixels.size() < 1) | 
| 241 | - return 0; | |
| 308 | + return SUCCESS; | |
| 242 | 309 |  | 
| 243 | 310 | // more than one next pixel | 
| 244 | 311 |      if (intersectsPixels.size() > 1) { | 
| 245 | 312 |        std::cerr << "pixel cable connects multiple pixels (" | 
| 246 | 313 | << intersectsPixels[0].pt.mX << "," | 
| 247 | 314 | << intersectsPixels[0].pt.mY << ")" << std::endl; | 
| 248 | - return -1; | |
| 315 | + return ERR_PROC; | |
| 249 | 316 | } | 
| 250 | 317 |  | 
| 251 | 318 | // pixel found | 
| ... | ... | @@ -271,14 +338,14 @@ static int createChain(Chain &chain, const Object *pObjCable) | 
| 271 | 338 |  | 
| 272 | 339 | // end of chain | 
| 273 | 340 | if (intersectsCables.size() < 1) | 
| 274 | - return 0; | |
| 341 | + return SUCCESS; | |
| 275 | 342 |  | 
| 276 | 343 | // more than one next pixel | 
| 277 | 344 |      if (intersectsCables.size() > 1) { | 
| 278 | 345 |        std::cerr << "pixel connected to multiple pixel cables (" | 
| 279 | 346 | << intersectsCables[0].pt.mX << "," | 
| 280 | 347 | << intersectsCables[0].pt.mY << ")" << std::endl; | 
| 281 | - return -1; | |
| 348 | + return ERR_PROC; | |
| 282 | 349 | } | 
| 283 | 350 |  | 
| 284 | 351 | // next cable found | 
| ... | ... | @@ -299,7 +366,7 @@ static bool intersectsCablesSort(const Layer::Intersection& i1, | 
| 299 | 366 | * @param[in] distri distributor to create | 
| 300 | 367 | * @param[in] pLayer layer containing distributor | 
| 301 | 368 | * @param[in] pixels number of pixels per chain | 
| 302 | - * @return 0 on success, -1 on error | |
| 369 | + * @return SUCCESS on success, other value on error | |
| 303 | 370 | */ | 
| 304 | 371 | static int createDistri(Distri &distri, const Layer *pLayer, | 
| 305 | 372 | unsigned int pixels) | 
| ... | ... | @@ -308,7 +375,7 @@ static int createDistri(Distri &distri, const Layer *pLayer, | 
| 308 | 375 |    if (pLayer->mObjects.size() != 1) { | 
| 309 | 376 | std::cerr << "layer of distributor 0x" << std::hex << distri.getNo() | 
| 310 | 377 | << "contains no object or multiple objects" << std::endl; | 
| 311 | - return -1; | |
| 378 | + return ERR_PROC; | |
| 312 | 379 | } | 
| 313 | 380 | const Object *pObjDistri = pLayer->mObjects[0]; | 
| 314 | 381 |  | 
| ... | ... | @@ -319,7 +386,7 @@ static int createDistri(Distri &distri, const Layer *pLayer, | 
| 319 | 386 | std::cerr << "distributor 0x" << std::hex << distri.getNo() | 
| 320 | 387 | << "has no network connection or multiple network connections" | 
| 321 | 388 | << std::endl; | 
| 322 | - return -1; | |
| 389 | + return ERR_PROC; | |
| 323 | 390 | } | 
| 324 | 391 | Point ptNetwork = intersectsNet[0].pt; | 
| 325 | 392 |  | 
| ... | ... | @@ -344,7 +411,72 @@ static int createDistri(Distri &distri, const Layer *pLayer, | 
| 344 | 411 | err = true; | 
| 345 | 412 | } | 
| 346 | 413 |  | 
| 347 | - return err ? -1 : 0; | |
| 414 | + return err ? ERR_PROC : SUCCESS; | |
| 415 | +} | |
| 416 | + | |
| 417 | +/** | |
| 418 | + * @brief make config file object from DXF layers | |
| 419 | + * @param[in] width width of logical video frame | |
| 420 | + * @param[in] height height of logical video frame | |
| 421 | + * @param[in] chains number of chains (outputs) per distributor | |
| 422 | + * @param[in] pixels number of pixels in one chain | |
| 423 | + * (i.e. connected to one output) | |
| 424 | + * @param[out] distris distributor objects | |
| 425 | + * @return true on success, false on error | |
| 426 | + */ | |
| 427 | +static bool makeObjects(unsigned int width, unsigned int height, | |
| 428 | + unsigned int chains, unsigned int pixels, | |
| 429 | + std::vector<Distri> &distris) | |
| 430 | +{ | |
| 431 | + // get origin and size of pixels in video | |
| 432 | + Box boundsVideo; | |
| 433 | + gLayerVideo.getBounds(boundsVideo); | |
| 434 | + Point ptPixel0(boundsVideo.mBL.mX, boundsVideo.mTR.mY); | |
| 435 | + Point ptPixelSz = boundsVideo.mTR - boundsVideo.mBL; | |
| 436 | + ptPixelSz.mX /= (double)width; | |
| 437 | + ptPixelSz.mY /= (double)height; | |
| 438 | + ptPixelSz.mY *= -1; | |
| 439 | + std::cout << "video bounds: " | |
| 440 | + << boundsVideo.mBL.mX << "," << boundsVideo.mBL.mY | |
| 441 | + << " " << boundsVideo.mTR.mX << "," << boundsVideo.mTR.mY | |
| 442 | + << std::endl; | |
| 443 | + | |
| 444 | + // create distributors | |
| 445 | + bool ok = true; | |
| 446 | + std::map<unsigned int, Layer>::const_iterator itDistri; | |
| 447 | + for (itDistri = gLayerDistributors.begin(); | |
| 448 | +       itDistri != gLayerDistributors.end(); ++itDistri) { | |
| 449 | + distris.push_back(Distri(itDistri->first, chains, pixels)); | |
| 450 | +    if (createDistri(distris.back(), &itDistri->second, pixels) != SUCCESS) { | |
| 451 | + ok = false; | |
| 452 | + } | |
| 453 | + } | |
| 454 | + | |
| 455 | + // obtain pixel coordinates | |
| 456 | + std::vector<Distri>::iterator itD; | |
| 457 | + for (itD = distris.begin(); itD != distris.end(); ++itD) | |
| 458 | + if (itD->pixCoord(ptPixel0, ptPixelSz, width, height) != 0) | |
| 459 | + ok = false; | |
| 460 | + | |
| 461 | + // count pixels connected to distributors and compare to total pixels | |
| 462 | + size_t distri_pixels = 0; | |
| 463 | + for (itD = distris.begin(); itD != distris.end(); ++itD) | |
| 464 | + distri_pixels += itD->countPixels(); | |
| 465 | + std::cout << "pixels connected to distributors: " | |
| 466 | + << distri_pixels << std::endl; | |
| 467 | +  if (distri_pixels != gLayerPixel.mObjects.size()) { | |
| 468 | +    std::cerr << "number of connected pixels (" << distri_pixels | |
| 469 | +              << ") does not match total number of pixels (" | |
| 470 | + << gLayerPixel.mObjects.size() << ")" << std::endl; | |
| 471 | + ok = false; | |
| 472 | + } | |
| 473 | + | |
| 474 | + // output extra error message if errors were detected | |
| 475 | +  if (! ok) { | |
| 476 | + std::cerr << "ERRORs were found" << std::endl; | |
| 477 | + } | |
| 478 | + | |
| 479 | + return ok; | |
| 348 | 480 | } | 
| 349 | 481 |  | 
| 350 | 482 | /** | 
| ... | ... | @@ -352,6 +484,7 @@ static int createDistri(Distri &distri, const Layer *pLayer, | 
| 352 | 484 | * @param[in] width width of video in pixels | 
| 353 | 485 | * @param[in] height height of video in pixels | 
| 354 | 486 | * @param[in] distris distributor objects | 
| 487 | + * @reutrn SUCCESS on success, other value on error | |
| 355 | 488 | */ | 
| 356 | 489 | static int writeCfg(unsigned int width, unsigned int height, | 
| 357 | 490 | const std::vector<Distri> &distris, | 
| ... | ... | @@ -362,7 +495,7 @@ static int writeCfg(unsigned int width, unsigned int height, | 
| 362 | 495 |    if (!strm.is_open()) { | 
| 363 | 496 | std::cerr << "could not open \"" << strCfgFileName | 
| 364 | 497 | << "\" for wrinting" << std::endl; | 
| 365 | - return -1; | |
| 498 | + return ERR_FILE_OPEN; | |
| 366 | 499 | } | 
| 367 | 500 |  | 
| 368 | 501 | // video size | 
| ... | ... | @@ -386,14 +519,14 @@ static int writeCfg(unsigned int width, unsigned int height, | 
| 386 | 519 | strm << std::endl; | 
| 387 | 520 |  | 
| 388 | 521 | strm.close(); | 
| 389 | - return 0; | |
| 522 | + return SUCCESS; | |
| 390 | 523 | } | 
| 391 | 524 |  | 
| 392 | 525 | /** | 
| 393 | 526 | * @brief main program | 
| 394 | 527 | * @param[in] argc number of parameters | 
| 395 | 528 | * @param[in] argv parameter values | 
| 396 | - * @return 0 on success, -1 on error | |
| 529 | + * @return SUCCESS on success, other value on error | |
| 397 | 530 | */ | 
| 398 | 531 | int main(int argc, char *argv[]) | 
| 399 | 532 |  { | 
| ... | ... | @@ -405,107 +538,30 @@ int main(int argc, char *argv[]) | 
| 405 | 538 | << ETPCG_VER_REV << std::endl | 
| 406 | 539 | << "usage: " << argv[0] << " <schematic_drawing.dxf> <config.etp>" | 
| 407 | 540 | << std::endl; | 
| 408 | - return -1; | |
| 541 | + return ERR_USAGE; | |
| 409 | 542 | } | 
| 410 | 543 | std::string strDxfFileName = argv[1]; | 
| 411 | 544 | std::string strCfgFileName = argv[2]; | 
| 412 | 545 |  | 
| 413 | 546 | // read DXF file | 
| 414 | - dimeInput in; | |
| 415 | -  if (!in.setFile(strDxfFileName.c_str())) { | |
| 416 | - std::cerr << "error opening file \"" << strDxfFileName | |
| 417 | - << "\" for reading" << std::endl; | |
| 418 | - return -1; | |
| 419 | - } | |
| 420 | - dimeModel model; | |
| 421 | -  if (!model.read(&in)) { | |
| 422 | - std::cerr << "DXF read error in line " << in.getFilePosition() | |
| 423 | - << " of file \"" << strDxfFileName << "\"" | |
| 424 | - << std::endl; | |
| 425 | - return -1; | |
| 426 | - } | |
| 427 | - | |
| 428 | - // get configuration from layers | |
| 429 | 547 | unsigned int width, height, chains, pixels; | 
| 430 | -  if (! get_config(model, width, height, chains, pixels)) { | |
| 431 | - return -1; | |
| 548 | + int ret = readDXF(strDxfFileName, width, height, chains, pixels); | |
| 549 | +  if (ret != SUCCESS) { | |
| 550 | + return ret; | |
| 432 | 551 | } | 
| 433 | 552 |  | 
| 434 | - // enumerate all entities | |
| 435 | - model.traverseEntities(cbEntity, NULL); | |
| 436 | - | |
| 437 | - // merge all cable layers | |
| 438 | - std::map<unsigned int, Layer>::iterator itCable; | |
| 439 | - for (itCable = gLayerCables.begin(); | |
| 440 | - itCable != gLayerCables.end(); ++itCable) | |
| 441 | - gLayerCable.merge(&itCable->second); | |
| 442 | - // gLayerCables[] is now empty and will not be used any more | |
| 443 | - | |
| 444 | - // output object count information | |
| 445 | - std::cout << "object counts:" << std::endl; | |
| 446 | - std::cout << " video: " << gLayerVideo.mObjects.size() << std::endl; | |
| 447 | - std::cout << " pixel: " << gLayerPixel.mObjects.size() << std::endl; | |
| 448 | - std::cout << " cable: " << gLayerCable.mObjects.size() << std::endl; | |
| 449 | - std::cout << " network: " << gLayerNetwork.mObjects.size() << std::endl; | |
| 450 | - std::cout << " distributor:" << std::endl; | |
| 451 | - std::map<unsigned int, Layer>::const_iterator itDistri; | |
| 452 | - for (itDistri = gLayerDistributors.begin(); | |
| 453 | - itDistri != gLayerDistributors.end(); ++itDistri) | |
| 454 | - std::cout << " " << itDistri->first << ": " | |
| 455 | - << itDistri->second.mObjects.size() << std::endl; | |
| 456 | - | |
| 457 | - // get origin and size of pixels in video | |
| 458 | - Box boundsVideo; | |
| 459 | - gLayerVideo.getBounds(boundsVideo); | |
| 460 | - Point ptPixel0(boundsVideo.mBL.mX, boundsVideo.mTR.mY); | |
| 461 | - Point ptPixelSz = boundsVideo.mTR - boundsVideo.mBL; | |
| 462 | - ptPixelSz.mX /= (double)width; | |
| 463 | - ptPixelSz.mY /= (double)height; | |
| 464 | - ptPixelSz.mY *= -1; | |
| 465 | - std::cout << "video bounds: " | |
| 466 | - << boundsVideo.mBL.mX << "," << boundsVideo.mBL.mY | |
| 467 | - << " " << boundsVideo.mTR.mX << "," << boundsVideo.mTR.mY | |
| 468 | - << std::endl; | |
| 469 | - | |
| 470 | - // create distributors | |
| 471 | - bool err = false; | |
| 553 | + // make config file objects from DXF layers | |
| 472 | 554 | std::vector<Distri> distris; | 
| 473 | - for (itDistri = gLayerDistributors.begin(); | |
| 474 | -       itDistri != gLayerDistributors.end(); ++itDistri) { | |
| 475 | - distris.push_back(Distri(itDistri->first, chains, pixels)); | |
| 476 | -    if (createDistri(distris.back(), &itDistri->second, pixels) != 0) { | |
| 477 | - err = true; | |
| 478 | - } | |
| 479 | - } | |
| 480 | - | |
| 481 | - // obtain pixel coordinates | |
| 482 | - std::vector<Distri>::iterator itD; | |
| 483 | - for (itD = distris.begin(); itD != distris.end(); ++itD) | |
| 484 | - if (itD->pixCoord(ptPixel0, ptPixelSz, width, height) != 0) | |
| 485 | - err = true; | |
| 486 | - | |
| 487 | - // count pixels connected to distributors and compare to total pixels | |
| 488 | - size_t distri_pixels = 0; | |
| 489 | - for (itD = distris.begin(); itD != distris.end(); ++itD) | |
| 490 | - distri_pixels += itD->countPixels(); | |
| 491 | - std::cout << "pixels connected to distributors: " | |
| 492 | - << distri_pixels << std::endl; | |
| 493 | -  if (distri_pixels != gLayerPixel.mObjects.size()) { | |
| 494 | -    std::cerr << "number of connected pixels (" << distri_pixels | |
| 495 | -              << ") does not match total number of pixels (" | |
| 496 | - << gLayerPixel.mObjects.size() << ")" << std::endl; | |
| 497 | - err = true; | |
| 555 | +  if (! makeObjects(width, height, chains, pixels, distris)) { | |
| 556 | + return ERR_PROC; | |
| 498 | 557 | } | 
| 499 | 558 |  | 
| 500 | 559 | // write config file | 
| 501 | - if (writeCfg(width, height, distris, strCfgFileName) != 0) | |
| 502 | - err = true; | |
| 503 | - | |
| 504 | - // output message if errors were detected | |
| 505 | -  if (err) { | |
| 506 | - std::cerr << "ERRORs were found" << std::endl; | |
| 507 | - return -1; | |
| 560 | + ret = writeCfg(width, height, distris, strCfgFileName); | |
| 561 | +  if ( ret != SUCCESS) { | |
| 562 | + return ret; | |
| 508 | 563 | } | 
| 509 | - return 0; | |
| 564 | + | |
| 565 | + return SUCCESS; | |
| 510 | 566 | } | 
| 511 | 567 |  | 
| 512 | 568 |