/*****************************************************************************/ /* */ /* Copyright (C) 1999-2025 M. Held */ /* */ /* This code is not in the public domain. All rights reserved! Please make */ /* sure to read the full copyright statement contained in "README.txt" or in */ /* the "main" file of this code, such as "main.cc". */ /* */ /*****************************************************************************/ /* */ /* Written by: Martin Held */ /* */ /* E-Mail: held@cs.sbg.ac.at */ /* Fax Mail: (+43 662) 8044-611 */ /* Voice Mail: (+43 662) 8044-6304 */ /* Snail Mail: Martin Held */ /* FB Informatik */ /* Universitaet Salzburg */ /* A-5020 Salzburg, Austria */ /* */ /*****************************************************************************/ /* */ /* get standard libraries */ /* */ #include #include #include #include /* */ /* get my header files */ /* */ #include "fpkernel.h" #include "vronivector.h" #include "vroni_object.h" #include "defs.h" /* */ /* the following functions read data encoded in one of my input formats. */ /* they rely on basic "parsers" to read simple entities that are provided in */ /* io_parse.cc. you are welcome to adapt those parsers to your needs. also, */ /* i'll happily add exterior application macros at points of your choice. if */ /* such (mostly non-invasive) changes should not suffice to parse your input */ /* then i'd strongly suggest to implement your own input functions, using my */ /* code as a blueprint for your implementation. please understand that there */ /* is no chance for me to provide parsers that are flexible enough to handle */ /* arbitrary input formats yet simple enough to be understood by folks with */ /* perhaps only a casual knowledge and experience in C/C++ programming... */ /* */ void vroniObject::ReadContour(FILE *input) { int i, i0, i1, number, orientation, attr, last_attr; double xc1, yc1, xc2, yc2, xc3, yc3; #ifdef EXT_APPL_SITES eas_type eas_data; #endif /* */ /* get the number of contour elements */ /* */ if (!ReadNumber(input, &number)) throw std::runtime_error("VRONI error: ReadContour() - premature end of file!"); if (number < 0) number = - number; if (number < 1) throw std::runtime_error("VRONI error: ReadContour() - less than one vertex!"); InitStoragePnts(number + 10); InitStorageSegs(number + 10); /* */ /* read the orientation of the contour. (we don't trust it, though.) */ /* */ if (!ReadOptionalNumber(input, &orientation)) throw std::runtime_error("VRONI error: ReadContour() - premature end of file!"); /* */ /* read the start point of the first segment/arc */ /* */ if (!ReadNumber(input, &attr)) throw std::runtime_error("VRONI error: ReadContour() - premature end of file!"); if ((attr < -1) || (attr > 1)) throw std::runtime_error("VRONI error: ReadContour() - unknown data format!"); if (!ReadVectorData(input, &xc1, &yc1)) throw std::runtime_error("VRONI error: ReadContour() - premature end of file!"); #ifdef EXT_APPL_PNTS i1 = HandlePnt(xc1, yc1, eap_NIL); #else i1 = HandlePnt(xc1, yc1); #endif i0 = i1; last_attr = attr; for (i = 1; i < number; ++i) { /* */ /* read the individual segments/arcs */ /* */ #ifdef EXT_APPL_SITES if (!ReadSiteData(input, &xc2, &yc2, &eas_data)) #else if (!ReadSiteData(input, &xc2, &yc2)) #endif throw std::runtime_error("VRONI error: ReadContour() - premature end of file!"); if (!ReadNumber(input, &attr)) throw std::runtime_error("VRONI error: ReadContour() - premature end of file!"); if (!ReadVectorData(input, &xc3, &yc3)) throw std::runtime_error("VRONI error: ReadContour() - premature end of file!"); if (last_attr == SEG) { /* */ /* the last object was a line segment */ /* */ #ifdef EXT_APPL_SITES AddSeg(&i1, xc3, yc3, eas_data); #else AddSeg(&i1, xc3, yc3); #endif } else if ((last_attr == -ARC) || (last_attr == ARC)) { /* */ /* the last object was a circular arc */ /* */ #ifdef EXT_APPL_SITES AddArc(&i1, xc3, yc3, xc2, yc2, last_attr, eas_data); #else AddArc(&i1, xc3, yc3, xc2, yc2, last_attr); #endif } else throw std::runtime_error("VRONI error: ReadContour() - unknown data format!"); last_attr = attr; } /* */ /* close the contour */ /* */ #ifdef EXT_APPL_SITES if (!ReadSiteData(input, &xc2, &yc2, &eas_data)) #else if (!ReadSiteData(input, &xc2, &yc2)) #endif throw std::runtime_error("VRONI error: ReadContour() - premature end of file!"); if (last_attr == SEG) { /* */ /* the last object was a line segment */ /* */ #ifdef EXT_APPL_SITES CloseSeg(i1, i0, eas_data); #else CloseSeg(i1, i0); #endif } else if ((last_attr == -ARC) || (last_attr == ARC)) { /* */ /* the last object was a circular arc */ /* */ #ifdef EXT_APPL_SITES CloseArc(i1, i0, xc2, yc2, last_attr, eas_data); #else CloseArc(i1, i0, xc2, yc2, last_attr); #endif } else throw std::runtime_error("VRONI error: ReadContour() - unknown data format!"); return; } /* */ /* this function reads a simply-connected or multiply-connected polygon */ /* specified in my format for curvilinear data. */ /* */ void vroniObject::ReadPolygon(char input_file[], vr_bool *new_input) { double xc1, yc1, xc2, yc2; int i, number; FILE *input; input = OpenFileVD(input_file, "r"); /* */ /* read enclosing bounding box (we don't trust it, though) */ /* */ if (!ReadOptionalCoord(input, &xc1)) throw std::runtime_error("VRONI error: ReadPolygon() - premature end of file!"); if (!ReadOptionalCoord(input, &yc1)) throw std::runtime_error("VRONI error: ReadPolygon() - premature end of file!"); if (!ReadOptionalCoord(input, &xc2)) throw std::runtime_error("VRONI error: ReadPolygon() - premature end of file!"); if (!ReadOptionalCoord(input, &yc2)) throw std::runtime_error("VRONI error: ReadPolygon() - premature end of file!"); /* */ /* get the number of contours */ /* */ if (!ReadNumber(input, &number)) throw std::runtime_error("VRONI error: ReadPolygon() - Premature end of file!"); for (i = 0; i < number; ++i) { /* */ /* handle each contour */ /* */ ReadContour(input); } fclose(input); *new_input = true; return; } /* */ /* this function reads a simply-connected polygon specified in my simplified */ /* format for polygons. */ /* */ void vroniObject::ReadPoly(char input_file[], vr_bool *new_input) { double xc1, yc1; int i0 = NIL, i1, number = 0; FILE *input; #ifdef EXT_APPL_SITES eas_type eas_data, eas_data_0; #endif input = OpenFileVD(input_file, "r"); /* */ /* get the number of contour elements */ /* */ if (!ReadOptionalNumber(input, &number)) throw std::runtime_error("VRONI error: ReadPoly() - premature end of file!"); if (number > 0) { InitPnts(number + 10); InitSegs(number + 10); } /* */ /* read the start point of the first segment */ /* */ #ifdef EXT_APPL_SITES if (!ReadSiteData(input, &xc1, &yc1, &eas_data_0)) #else if (!ReadSiteData(input, &xc1, &yc1)) #endif throw std::runtime_error("VRONI error: ReadPoly() - premature end of file!"); #ifdef EXT_APPL_PNTS i1 = HandlePnt(xc1, yc1, eap_NIL); #else i1 = HandlePnt(xc1, yc1); #endif i0 = i1; /* */ /* read the individual segments */ /* */ #ifdef EXT_APPL_SITES while (ReadSiteData(input, &xc1, &yc1, &eas_data)) { AddSeg(&i1, xc1, yc1, eas_data); } #else while (ReadSiteData(input, &xc1, &yc1)) { AddSeg(&i1, xc1, yc1); } #endif /* */ /* close the polygon */ /* */ #ifdef EXT_APPL_SITES CloseSeg(i1, i0, eas_data_0); #else CloseSeg(i1, i0); #endif fclose(input); *new_input = (i0 != NIL); return; } /* */ /* this function reads a list of points. */ /* */ void vroniObject::ReadPoints(char input_file[], vr_bool *new_input) { double xc1, yc1; int i0 = NIL, number = NIL; #ifdef EXT_APPL_PNTS eap_type eap_data; #endif FILE *input; input = OpenFileVD(input_file, "r"); /* */ /* if known, get the number of points. (if unknown, we will allocate */ /* memory "on the fly" as necessary.) */ /* */ if (!ReadOptionalNumber(input, &number)) throw std::runtime_error("VRONI error: ReadPoints() - premature end of file!"); if (number > 0) InitPnts(number + 10); #ifdef EXT_APPL_PNTS while (ReadPntData(input, &xc1, &yc1, &eap_data)) { i0 = HandlePnt(xc1, yc1, eap_data); } #else while (ReadPntData(input, &xc1, &yc1)) { i0 = HandlePnt(xc1, yc1); } #endif fclose(input); *new_input = (i0 != NIL); isolated_pnts = true; return; } /* */ /* this function reads a set of polygonal chains. */ /* */ void vroniObject::ReadPolylines(char input_file[], vr_bool *new_input) { double xc1, yc1, xc0, yc0; int i, i1 = NIL, number = 0, i0; FILE *input; #ifdef EXT_APPL_SITES eas_type eas_data, eas_data_0; #endif input = OpenFileVD(input_file, "r"); while (ReadNumber(input, &number)) { /* */ /* read the number of vertices of the next chain */ /* */ if (number < 1) throw std::runtime_error("VRONI error: ReadPolylines() - less than one vertex per chain!"); /* */ /* read first vertex of the next chain */ /* */ #ifdef EXT_APPL_SITES if (!ReadSiteData(input, &xc1, &yc1, &eas_data_0)) #else if (!ReadSiteData(input, &xc1, &yc1)) #endif throw std::runtime_error("VRONI error: ReadPolylines() - premature end of file!"); #ifdef EXT_APPL_PNTS i1 = HandlePnt(xc1, yc1, eap_NIL); #else i1 = HandlePnt(xc1, yc1); #endif i0 = i1; xc0 = xc1; yc0 = yc1; if (number == 1) isolated_pnts = true; --number; for (i = 1; i < number; ++i) { /* */ /* read the remaining vertices of this chain */ /* */ #ifdef EXT_APPL_SITES if (!ReadSiteData(input, &xc1, &yc1, &eas_data)) #else if (!ReadSiteData(input, &xc1, &yc1)) #endif throw std::runtime_error("VRONI error: ReadPolylines() - premature end of file!"); #ifdef EXT_APPL_SITES AddSeg(&i1, xc1, yc1, eas_data); #else AddSeg(&i1, xc1, yc1); #endif } if (number > 0) { #ifdef EXT_APPL_SITES if (!ReadSiteData(input, &xc1, &yc1, &eas_data)) #else if (!ReadSiteData(input, &xc1, &yc1)) #endif throw std::runtime_error("VRONI error: ReadPolylines() - premature end of file!"); if ((xc0 != xc1) || (yc0 != yc1)) { #ifdef EXT_APPL_SITES AddSeg(&i1, xc1, yc1, eas_data); #else AddSeg(&i1, xc1, yc1); #endif } else { #ifdef EXT_APPL_SITES CloseSeg(i1, i0, eas_data_0); #else CloseSeg(i1, i0); #endif } } } fclose(input); *new_input = ((number != 0) || isolated_pnts); return; } /* */ /* this function reads a set of polygons specified in .bdm format */ /* */ void vroniObject::ReadBDM(char input_file[], vr_bool *new_input) { double xc1, yc1; int i, i1 = NIL, i0 = NIL, number = 0; FILE *input; #ifdef EXT_APPL_SITES eas_type eas_data, eas_data_0; #endif input = OpenFileVD(input_file, "r"); while (ReadNumber(input, &number)) { /* */ /* read the number of vertices of the next chain */ /* */ if (number < 3) throw std::runtime_error("VRONI error: ReadBDM() - less than three vertices per polygon!"); /* */ /* read first vertex of the next polygon */ /* */ #ifdef EXT_APPL_SITES if (!ReadSiteData(input, &xc1, &yc1, &eas_data_0)) #else if (!ReadSiteData(input, &xc1, &yc1)) #endif throw std::runtime_error("VRONI error: ReadBDM() - premature end of file!"); #ifdef EXT_APPL_PNTS i1 = HandlePnt(xc1, yc1, eap_NIL); #else i1 = HandlePnt(xc1, yc1); #endif i0 = i1; for (i = 1; i < number; ++i) { /* */ /* read the remaining vertices of this chain */ /* */ #ifdef EXT_APPL_SITES if (!ReadSiteData(input, &xc1, &yc1, &eas_data)) #else if (!ReadSiteData(input, &xc1, &yc1)) #endif throw std::runtime_error("VRONI error: ReadBDM() - premature end of file!"); #ifdef EXT_APPL_SITES AddSeg(&i1, xc1, yc1, eas_data); #else AddSeg(&i1, xc1, yc1); #endif } /* */ /* close the polygon */ /* */ #ifdef EXT_APPL_SITES CloseSeg(i1, i0, eas_data_0); #else CloseSeg(i1, i0); #endif } fclose(input); *new_input = (number != 0); return; } /* */ /* this function reads individual sites (points, segments, arcs) from a file.*/ /* */ /* data format: */ /* */ /* segment */ /* 0 */ /* x_start y_start x_end y_end */ /* point */ /* 2 */ /* x y */ /* arc CCW */ /* 1 */ /* x_start y_start x_end y_end x_center y_center */ /* arc CW */ /* -1 */ /* x_start y_start x_end y_end x_center y_center */ /* */ /* */ void vroniObject::ReadSites(char input_file[], vr_bool *new_input) { double xc1, yc1, xc2, yc2, xc3, yc3; int attr; FILE *input; #ifdef EXT_APPL_PNTS eap_type eap_data; #endif #ifdef EXT_APPL_SITES eas_type eas_data; #endif input = OpenFileVD(input_file, "r"); while (ReadNumber(input, &attr)) { if (attr == PNT) { #ifdef EXT_APPL_PNTS if (!ReadPntData(input, &xc1, &yc1, &eap_data)) #else if (!ReadPntData(input, &xc1, &yc1)) #endif throw std::runtime_error("VRONI error: ReadSites() - premature end of file!"); #ifdef EXT_APPL_PNTS (void) HandlePnt(xc1, yc1, eap_data); #else (void) HandlePnt(xc1, yc1); #endif *new_input = true; isolated_pnts = true; } else if (attr == SEG) { if (!ReadVectorData(input, &xc1, &yc1)) throw std::runtime_error("VRONI error: ReadSites() - premature end of file!"); #ifdef EXT_APPL_SITES if (!ReadSiteData(input, &xc2, &yc2, &eas_data)) #else if (!ReadSiteData(input, &xc2, &yc2)) #endif throw std::runtime_error("VRONI error: ReadSites() - premature end of file!"); #ifdef EXT_APPL_SITES HandleSeg(xc1, yc1, xc2, yc2, eas_data); #else HandleSeg(xc1, yc1, xc2, yc2); #endif *new_input = true; } else if ((attr == ARC) || (attr == -ARC)) { if (!ReadVectorData(input, &xc1, &yc1)) throw std::runtime_error("VRONI error: ReadSites() - premature end of file!"); if (!ReadVectorData(input, &xc2, &yc2)) throw std::runtime_error("VRONI error: ReadSites() - premature end of file!"); #ifdef EXT_APPL_SITES if (!ReadSiteData(input, &xc3, &yc3, &eas_data)) #else if (!ReadSiteData(input, &xc3, &yc3)) #endif throw std::runtime_error("VRONI error: ReadSites() - premature end of file!"); #ifdef EXT_APPL_SITES HandleArc(xc1, yc1, xc2, yc2, xc3, yc3, attr, eas_data); #else HandleArc(xc1, yc1, xc2, yc2, xc3, yc3, attr); #endif *new_input = true; } else throw std::runtime_error("VRONI error: ReadSites() - unknown data format!"); } fclose(input); return; } FILE *vroniObject::OpenFileVD(const char *file_name, const char *access) { FILE *file; if ((file = fopen(file_name, access)) == NULL) throw std::runtime_error("VRONI error: OpenFileVD() - I/O file could not be opened!"); return file; } #include "ext_appl_io.cc"