Created
March 8, 2024 22:45
-
-
Save moyix/dc15f77a51c380df9bb5b3a1bc36389c to your computer and use it in GitHub Desktop.
Revisions
-
moyix created this gist
Mar 8, 2024 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,130 @@ C++ files are are from this GitHub repository, with a small modification by me to allow the parser to accept a filename on the command line: https://github.com/alepapadop/vrml `genvrml_v*.py` written by Claude 3 Opus. The conversation was: ## Initial Prompt > (Attached files: `data_types.cpp`, `data_types.h`, `main.cpp`, `vrml_parser.cpp`, `vrml_parser.h`) > > Given this C++ program, can you write a Python function that generates random VRML files that fully exercise the parsing code? The function should have the signature: > > ``` > # Generates a random file into `out` > def generate_random_input(out: BinaryIO): > ``` ## Claude > Here's a Python function that generates random VRML files to exercise the parsing code you provided: > > \[Attached: `genvrml_v0.py`\] > > This function generates random VRML files by constructing different node types and their fields based on probabilities. It supports the following node types: > > - Shape: Generates a Shape node with optional Appearance and geometry (PointSet, IndexedLineSet, or IndexedFaceSet). > - Transform: Generates a Transform node with optional translation, rotation, and scale fields. It also recursively generates children nodes. > - PointSet: Generates a PointSet node with random points. > > The function also includes a probability to add DEF/USE statements to test the parsing of these constructs. > > You can adjust the probabilities, ranges, and node types based on your specific testing requirements. > > To use the function, you can simply call it with a binary file object, and it will write the generated VRML content to the file. In the example usage, it generates a random VRML file named "random.wrl". > > Note: Make sure to have the necessary imports and Python version that supports the `BinaryIO` type hint. ## Me > I get: > > ``` > Traceback (most recent call last): > File "/Users/moyix/git/vrml/genvrml.py", line 112, in <module> > generate_random_input(of) > File "/Users/moyix/git/vrml/genvrml.py", line 85, in generate_random_input > generate_random_input(out) > File "/Users/moyix/git/vrml/genvrml.py", line 105, in generate_random_input > generate_random_input(out) > File "/Users/moyix/git/vrml/genvrml.py", line 85, in generate_random_input > generate_random_input(out) > File "/Users/moyix/git/vrml/genvrml.py", line 85, in generate_random_input > generate_random_input(out) > File "/Users/moyix/git/vrml/genvrml.py", line 85, in generate_random_input > generate_random_input(out) > [Previous line repeated 9 more times] > File "/Users/moyix/git/vrml/genvrml.py", line 63, in generate_random_input > out.write(f"{indices[i]}, {indices[i+1]}, {indices[i+2]}, -1,\n".encode()) > ~~~~~~~^^^^^ > IndexError: list index out of range > ``` ## Claude > Apologies for the oversight in the IndexedFaceSet generation. Here's the corrected version of the `generate_random_input` function: > > \[Attached: `genvrml_v1.py`\] > > The issue was in the IndexedFaceSet generation, specifically in the loop that writes the `coordIndex` field. The loop was not properly handling the case when the number of points is not divisible by 3. > > I've updated the loop to iterate up to `num_points - 2` with a step of 3, ensuring that there are always enough points to form a triangle. > > ```python > for i in range(0, num_points - 2, 3): > out.write(f"{indices[i]}, {indices[i+1]}, {indices[i+2]}, -1,\n".encode()) > ``` > > With this correction, the function should generate valid random VRML files without encountering the `IndexError`. ## Me > Now I get: > > ``` > Traceback (most recent call last): > File "/Users/moyix/git/vrml/genvrml.py", line 111, in <module> > generate_random_input(file) > File "/Users/moyix/git/vrml/genvrml.py", line 85, in generate_random_input > generate_random_input(out) > File "/Users/moyix/git/vrml/genvrml.py", line 105, in generate_random_input > generate_random_input(out) > File "/Users/moyix/git/vrml/genvrml.py", line 85, in generate_random_input > generate_random_input(out) > [...] > File "/Users/moyix/git/vrml/genvrml.py", line 85, in generate_random_input > generate_random_input(out) > [Previous line repeated 27 more times] > File "/Users/moyix/git/vrml/genvrml.py", line 7, in generate_random_input > num_nodes = random.randint(1, 10) > ^^^^^^^^^^^^^^^^^^^^^ > File "/Users/moyix/.pyenv/versions/3.12.2/lib/python3.12/random.py", line 336, in randint > return self.randrange(a, b+1) > ^^^^^^^^^^^^^^^^^^^^^^ > File "/Users/moyix/.pyenv/versions/3.12.2/lib/python3.12/random.py", line 318, in randrange > return istart + self._randbelow(width) > ^^^^^^^^^^^^^^^^^^^^^^ > RecursionError: maximum recursion depth exceeded > ``` ## Claude > I apologize for the inconvenience caused by the recursive calls. The recursive generation of child nodes in the Transform node can lead to excessive recursion depth in some cases. Let's modify the code to limit the recursion depth and prevent the RecursionError. > > Here's the updated version of the `generate_random_input` function with a maximum recursion depth: > > \[Attached: `genvrml_v2.py`\] > > The main changes are: > > 1. The `generate_random_input` function now takes two additional parameters: `max_depth` (default value of 5) to limit the maximum recursion depth, and `current_depth` (default value of 0) to keep track of the current depth. > > 2. At the beginning of the function, we check if the `current_depth` exceeds the `max_depth`. If so, we return immediately to stop further recursion. > > 3. When recursively generating child nodes for the Transform node, we pass the `max_depth` and `current_depth + 1` to the recursive calls. > > 4. The number of nodes generated at each level is reduced to a random number between 1 and 5 to limit the overall size of the generated file. > > With these modifications, the function should generate valid random VRML files without exceeding the maximum recursion depth. You can adjust the `max_depth` value according to your needs. This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,1391 @@ #include "data_types.h" #include "str_and_math.h" #include "file_handler.h" #include "vrml_parser.h" #include <iostream> using namespace std; /*************************************************************************************/ /*************************************************************************************/ void set_node_id(void *node, int id) { Info **info = NULL; info = (Info **)node; if (info) { (*info)->id = id; } } /*************************************************************************************/ /*************************************************************************************/ void set_node_type(void *node, DataType type) { Info **info = NULL; info = (Info **)node; if (info) { (*info)->type = type; } } /*************************************************************************************/ /*************************************************************************************/ int get_node_id(void *node) { Info **info = NULL; int value = -1; info = (Info **)node; if (info) { value = (*info)->id; } return value; } /*************************************************************************************/ /*************************************************************************************/ DataType get_node_type(void *node) { Info **info = NULL; DataType value = UNKNOWN; info = (Info **)node; if (info) { value = (*info)->type; } return value; } /*************************************************************************************/ /*************************************************************************************/ void check_def_tokn(string tokn) { if (tokn.find("DEF") != string::npos) { gvar->def_flag = 1; gvar->def_tokn = get_tokn(); } // unset the def flag when you find the first opening bracket "{" if (gvar->def_flag && tokn.find("{") != string::npos) { gvar->def_flag = 0; gvar->def_tokn = ""; } } /*************************************************************************************/ /*************************************************************************************/ void check_use_tokn(string tokn) { if (gvar->use_flag) { gvar->use_flag = 0; gvar->use_tokn = ""; } if (tokn.find("USE") != string::npos) { // prosoxi i seira pou exoun oi netoles einai poli simantiki gvar->use_tokn = get_tokn(); gvar->use_flag = 1; } } /*************************************************************************************/ /*************************************************************************************/ void add_to_def(string tokn, Container *container) { // eukolaki vazeis sto map perneis apo to map // o kwdika tha mpei mesa stin get_tokn opote // den tha mplexoume me ta alla // prepei na kanw kai ta alla na epistrefoun container // episi na kanw kai to group // poly testing para poly :) if (gvar->def_map) { (*(gvar->def_map))[tokn] = container; } gvar->def_flag = 0; gvar->def_tokn = ""; } /*************************************************************************************/ /*************************************************************************************/ void add_to_def_map(string tokn, void *data) { // eukolaki vazeis sto map perneis apo to map // o kwdika tha mpei mesa stin get_tokn opote // den tha mplexoume me ta alla // prepei na kanw kai ta alla na epistrefoun container // episi na kanw kai to group // poly testing para poly :) if (gvar->def_map2) { (*(gvar->def_map2))[tokn] = data; } gvar->def_flag = 0; gvar->def_tokn = ""; } /*************************************************************************************/ /*************************************************************************************/ void* get_from_def(string tokn) { //otan epistrefo to grafo amesws sto frame mesw tis global var Container *container = NULL; map<string, Container *>::iterator it; if (gvar->def_map) { it = gvar->def_map->find(tokn); if (it != gvar->def_map->end()) { container = it->second; } } gvar->use_flag = 0; return container; } /*************************************************************************************/ /*************************************************************************************/ Container *new_container() { Container *container = NULL; container = new Container; return container; } /*************************************************************************************/ /*************************************************************************************/ void delete_container(Container *container) { delete container; } /*************************************************************************************/ /*************************************************************************************/ void set_container_type(Container *container, DataType type) { if (container) { container->type = type; } } /*************************************************************************************/ /*************************************************************************************/ void set_container_data(Container *container, void *data) { if (container) { container->data = data; } } /*************************************************************************************/ /*************************************************************************************/ DataType get_container_type(Container *container) { DataType type = UNKNOWN; if (container) { type = container->type; } return type; } /*************************************************************************************/ /*************************************************************************************/ void *get_container_data(Container *container) { void *data = NULL; if (container) { data = container->data; } return data; } /*************************************************************************************/ /*************************************************************************************/ void init_node_type_map(map<string, DataType> **node_type_map) { if (*node_type_map == NULL) { *node_type_map = new map<string, DataType>; } (**node_type_map)["Shape"] = SHAPE; (**node_type_map)["Group"] = GROUP; (**node_type_map)["Coordinate"] = COORDINATE; (**node_type_map)["IndexedLineSet"] = INDEXED_LINE_SET; (**node_type_map)["IndexedFaceSet"] = INDEXED_FACE_SET; (**node_type_map)["Transform"] = TRANSFORM; (**node_type_map)["Material"] = MATERIAL; (**node_type_map)["PointSet"] = POINT_SET; (**node_type_map)["Appearance"] = APPEARANCE; } /*************************************************************************************/ /*************************************************************************************/ void init_field_type_map(map<string, DataType> **field_type_map) { if (*field_type_map == NULL) { *field_type_map = new map<string, DataType>; } (**field_type_map)["translation"] = TRANSLATION; (**field_type_map)["rotation"] = ROTATION; (**field_type_map)["scale"] = SCALE; (**field_type_map)["point"] = POINT; } /*************************************************************************************/ /*************************************************************************************/ DataSup *add_type_sup_map(string keyword, DataType type, READ_NODE_FUN read_node_fun, READ_FIELD_FUN read_field_fun, CREATE_FUN create_fun) { DataSup *data_sup = NULL; data_sup = new DataSup; if (data_sup) { data_sup->keyword = keyword; data_sup->type = type; data_sup->read_node_fun = read_node_fun; data_sup->read_field_fun = read_field_fun; data_sup->create_fun = create_fun; } return data_sup; } /*************************************************************************************/ /*************************************************************************************/ void init_type_sup_map(map<DataType, DataSup *> **type_sup_map) { if (*type_sup_map == NULL) { *type_sup_map = new map<DataType, DataSup *>; } /* NODE FUNCTIONS */ (**type_sup_map)[COORDINATE] = add_type_sup_map("Coordinate", COORDINATE ,read_coordinate, NULL, NULL); (**type_sup_map)[POINT_SET] = add_type_sup_map("PointSet", POINT_SET ,read_point_set, NULL, NULL); (**type_sup_map)[SHAPE] = add_type_sup_map("Shape", SHAPE ,read_shape, NULL, NULL); (**type_sup_map)[TRANSFORM] = add_type_sup_map("Transform", TRANSFORM, read_transform, NULL, NULL); /* FIELD FUNCTIONS */ (**type_sup_map)[TRANSLATION] = add_type_sup_map("translation", TRANSLATION, NULL, read_translation, NULL); (**type_sup_map)[ROTATION] = add_type_sup_map("rotation", ROTATION, NULL, read_rotation, NULL); (**type_sup_map)[SCALE] = add_type_sup_map("scale", SCALE, NULL, read_scale, NULL); (**type_sup_map)[POINT] = add_type_sup_map("point", POINT, NULL, read_point, NULL); } /*************************************************************************************/ /*************************************************************************************/ void init_frame(vector<Container *> **frame) { if (*frame == NULL) { *frame =new vector<Container *>; } } /*************************************************************************************/ /*************************************************************************************/ void init_def(map<string, Container *> **def) { if (*def == NULL) { *def = new map<string, Container *>; } } /*************************************************************************************/ /*************************************************************************************/ void init_def_map2(map<string, void *> **def_map2) { if (*def_map2 == NULL) { *def_map2 = new map<string, void *>; } } /*************************************************************************************/ /* Point */ /*************************************************************************************/ Point *new_point() { Point *point = NULL; point = new Point; return point; } /*************************************************************************************/ /*************************************************************************************/ void delete_point(Point *point) { delete point; } /*************************************************************************************/ /*************************************************************************************/ void debug_read_point(vector<Point *> *coordinate_vec) { vector<Point *>::iterator it; Point *point; for (it = coordinate_vec->begin(); it != coordinate_vec->end(); ++it) { point = *it; if (point) cout << "value: x = " << point->x << " y = " << point->y << " z = " << point->z << endl; } } /*************************************************************************************/ /*************************************************************************************/ void *read_point(void *args) { Point *point = NULL; string tokn = ""; double tmp; int valid_flag; int flag = 0; int count = 0; double x, y, z; vector<Point *> *coordinate_vec = NULL; cout << "Hello read point" << endl; coordinate_vec = new vector<Point *>; while (tokn.find("]") == string::npos) { tokn = get_tokn(); flag = 0; if (find_comma_and_remove_it(&tokn) || tokn.find(",") != string::npos || count == 3) { //cout << "tokn " << tokn << endl; flag = 1; } if (is_number(tokn)) { valid_flag = 1; tmp = str2double(tokn, &valid_flag); if (valid_flag) { if (count == 0) { x = tmp; } else if (count == 1) { y = tmp; } else if (count == 2) { z = tmp; } } count ++; } if (flag == 1) { point = new_point(); if (point) { point->x = x; point->y = y; point->z = z; count = 0; flag = 0; //cout << "read point value: x = " << point->x << " y = " << point->y << " z = " << point->z << endl; } if (coordinate_vec) { coordinate_vec->push_back(point); } point = NULL; } } //debug_read_point(coordinate_vec); return coordinate_vec; } /*************************************************************************************/ /* CoordIndex */ /*************************************************************************************/ CoordIndex *new_coord_index() { CoordIndex *coord_index = NULL; vector<int> *coord_index_vec = NULL; coord_index = new CoordIndex; if (coord_index) { coord_index_vec = new vector<int>; coord_index->coord_index_vec = coord_index_vec; } return coord_index; } /*************************************************************************************/ /*************************************************************************************/ void delete_coord_index(CoordIndex *coord_index) { delete coord_index->coord_index_vec; delete coord_index; } /*************************************************************************************/ /* Coordinate */ /*************************************************************************************/ Coordinate *new_coordinate() { Coordinate *coordinate = NULL; vector<Point *> *coordinate_vec = NULL; coordinate = new Coordinate; if (coordinate) { //coordinate_vec = new vector<Point *>; coordinate->info = new Info; coordinate->coordinate_vec = coordinate_vec; } return coordinate; } /*************************************************************************************/ /*************************************************************************************/ void delete_coordinate(Coordinate *coordinate) { vector<Point *>::iterator it; vector<Point *> *coordinate_vec; coordinate_vec = coordinate->coordinate_vec; for (it = coordinate_vec->begin(); it != coordinate_vec->end(); ++it) { delete_point(*it); } delete coordinate->coordinate_vec; delete coordinate; } /*************************************************************************************/ /*************************************************************************************/ void debug_read_coordinate(Coordinate *coordinate) { vector<Point *> *coordinate_vec = NULL; vector<Point *>::iterator it; Point *point = NULL; if (coordinate) { coordinate_vec = coordinate->coordinate_vec; if (coordinate_vec) { for (it = coordinate_vec->begin(); it != coordinate_vec->end(); ++it) { point = *it; if (point) cout << "read_coordinate value: x = " << point->x << " y = " << point->y << " z = " << point->z << endl; } } } } /*************************************************************************************/ /*************************************************************************************/ void *read_coordinate(void *data) { cout << "Hello coordinate" << endl; string tokn = ""; Coordinate *coordinate = NULL; coordinate = new_coordinate(); if (coordinate) { while (tokn.find("}") == string::npos) { tokn = get_tokn(); if (tokn.find("point") != string::npos) { coordinate->coordinate_vec = (vector<Point *> *)read_point(coordinate); } } set_node_type(coordinate, COORDINATE); } //debug_read_coordinate(coordinate); return coordinate; } /*************************************************************************************/ /* IndexedLineSet */ /*************************************************************************************/ IndexedLineSet *new_indexed_line_set() { IndexedLineSet *indexed_line_set = NULL; Coordinate *coordinate = NULL; vector<CoordIndex *> *indexed_line_set_vec = NULL; indexed_line_set = new IndexedLineSet; if (indexed_line_set) { coordinate = new_coordinate(); indexed_line_set_vec = new vector<CoordIndex *>; indexed_line_set->coordinate = coordinate; indexed_line_set->indexed_line_set_vec = indexed_line_set_vec; } return indexed_line_set; } /*************************************************************************************/ /*************************************************************************************/ void delete_indexed_line_set(IndexedLineSet *indexed_line_set) { vector<CoordIndex *>::iterator it; vector<CoordIndex *> *indexed_line_set_vec; indexed_line_set_vec = indexed_line_set->indexed_line_set_vec; for (it = indexed_line_set_vec->begin(); it != indexed_line_set_vec->end(); ++it) { delete_coord_index(*it); } delete_coordinate(indexed_line_set->coordinate); delete indexed_line_set; } /*************************************************************************************/ /* IndexedFaceSet */ /*************************************************************************************/ IndexedFaceSet *new_indexed_face_set() { IndexedFaceSet *indexed_face_set = NULL; Coordinate *coordinate = NULL; vector<CoordIndex *> *indexed_face_set_vec = NULL; indexed_face_set = new IndexedFaceSet; if (indexed_face_set) { coordinate = new_coordinate(); indexed_face_set_vec = new vector<CoordIndex *>; indexed_face_set->coordinate = coordinate; indexed_face_set->indexed_face_set_vec = indexed_face_set_vec; } return indexed_face_set; } /*************************************************************************************/ /*************************************************************************************/ void delete_indexed_face_set(IndexedFaceSet *indexed_face_set) { vector<CoordIndex *>::iterator it; vector<CoordIndex *> *indexed_face_set_vec; indexed_face_set_vec = indexed_face_set->indexed_face_set_vec; for (it = indexed_face_set_vec->begin(); it != indexed_face_set_vec->end(); ++it) { delete_coord_index(*it); } delete_coordinate(indexed_face_set->coordinate); delete indexed_face_set; } /*************************************************************************************/ /* Material */ /*************************************************************************************/ Material *new_material() { Material *material = NULL; material = new Material; return material; } /*************************************************************************************/ /*************************************************************************************/ void delete_material(Material *material) { delete material; } /*************************************************************************************/ /* PointSet */ /*************************************************************************************/ PointSet *new_point_set() { PointSet *point_set = NULL; Coordinate *coordinate = NULL; point_set = new PointSet; if (point_set) { //coordinate = new_coordinate(); point_set->info = new Info; point_set->coordinate = coordinate; } return point_set; } /*************************************************************************************/ /*************************************************************************************/ void delete_point_set(PointSet *point_set) { delete_coordinate(point_set->coordinate); delete point_set->coordinate; } /*************************************************************************************/ /*************************************************************************************/ void debug_read_point_set(PointSet *point_set) { Coordinate *coordinate = NULL; vector<Point *> *coordinate_vec = NULL; vector<Point *>::iterator it; Point *point = NULL; if (point_set) { coordinate = point_set->coordinate; if (coordinate) { coordinate_vec = coordinate->coordinate_vec; if (coordinate_vec) { for (it = coordinate_vec->begin(); it != coordinate_vec->end(); ++it) { point = *it; if (point) cout << "r_point_set value: x = " << point->x << " y = " << point->y << " z = " << point->z << endl; } } } } } /*************************************************************************************/ /*************************************************************************************/ void store_data_point_set(PointSet *point_set, void *data) { DataType type = UNKNOWN; if (data) { type = get_node_type(data); switch (type) { case COORDINATE: point_set->coordinate = (Coordinate *)data; break; } } } /*************************************************************************************/ /*************************************************************************************/ void *read_point_set(void *args) { cout << "Hello point set" << endl; PointSet *point_set = NULL; string tokn = ""; void *data = NULL; int def_flag = 0; string def_tokn = ""; point_set = new_point_set(); if (point_set) { while (tokn.find("}") == string::npos) { // tokn = get_tokn(); //------------------------------ //Edw prepei na to ksanadw to vrady... if (gvar->use_flag) { data = (*gvar->def_map2)[gvar->use_tokn]; store_data_point_set(point_set, data); } if (gvar->def_flag) { def_flag = 1; def_tokn = gvar->def_tokn; } data = NULL; tokn = get_tokn(); data = call_node_read_function(tokn, NULL); store_data_point_set(point_set, data); if (def_flag && data !=NULL) { add_to_def_map(def_tokn, data); } //------------------------------ /*if (tokn.find("Coordinate") != string::npos) { point_set->coordinate = (Coordinate *)read_coordinate(point_set); } else if (tokn.find("Color") != string::npos) { ; }*/ } set_node_type(point_set, POINT_SET); } debug_read_point_set(point_set); return point_set; } /*************************************************************************************/ /* Appearance */ /*************************************************************************************/ Appearance *new_appearance() { Appearance *appearance = NULL; appearance = new Appearance; return appearance; } /*************************************************************************************/ /*************************************************************************************/ void delete_appearance(Appearance *appearance) { delete appearance; } /*************************************************************************************/ /* Shape */ /*************************************************************************************/ Shape *new_shape() { Shape *shape = NULL; shape = new Shape; if (shape) { //shape->appearance = new_appearance(); //shape->point_set = new_point_set(); //shape->indexed_line_set = new_indexed_line_set(); //shape->indexed_face_set = new_indexed_face_set(); shape->info = new Info; set_node_type(shape, SHAPE); shape->appearance = NULL; shape->point_set = NULL; shape->indexed_line_set = NULL; shape->indexed_face_set = NULL; } return shape; } /*************************************************************************************/ /*************************************************************************************/ void delete_shape(Shape *shape) { //delete_appearance(shape->appearance); //delete_point_set(shape->point_set); //delete_indexed_line_set(shape->indexed_line_set); //delete_indexed_face_set(shape->indexed_face_set); delete shape; } /*************************************************************************************/ /*************************************************************************************/ void debug_read_shape(void *args) { PointSet *point_set = NULL; Coordinate *coordinate = NULL; vector<Point *> *coordinate_vec = NULL; vector<Point *>::iterator it; Point *point = NULL; Shape *shape = NULL; shape = (Shape *) args; if (shape) { point_set = shape->point_set; if (point_set) { coordinate = point_set->coordinate; if (coordinate) { coordinate_vec = coordinate->coordinate_vec; if (coordinate_vec) { for (it = coordinate_vec->begin(); it != coordinate_vec->end(); ++it) { point = *it; if (point) cout << "r_shape value: x = " << point->x << " y = " << point->y << " z = " << point->z << endl; } } } } } } /*************************************************************************************/ /*************************************************************************************/ void store_data_shape(Shape *shape, void *data) { DataType type = UNKNOWN; if (data) { type = get_node_type(data); switch (type) { case POINT_SET: shape->point_set = (PointSet *)data; break; case INDEXED_LINE_SET: break; case INDEXED_FACE_SET: break; } } } /*************************************************************************************/ /*************************************************************************************/ void *read_shape(void *args) { cout << "Hello Shape" << endl; Shape *shape = NULL; Container *container = NULL; string tokn = ""; void *data = NULL; int def_flag = 0; string def_tokn = ""; shape = new_shape(); container = new_container(); if (gvar->def_flag) { add_to_def(gvar->def_tokn, container); } if (shape) { while (tokn.find("}") == string::npos) { //------------------------------ // (1) Thelw mia sinattisi pou na tsimpaei apo to def map to swsto data // (2) Apo to data tha tsimpaei to type // (3) Apo to type tha apofasizei pou tha to apothikevei -> store_data_shape() prepei na volevei kai edw // (4) break gia na stamatisei i while, gia auto den eimai poly sigouros, mallon den xriazetai // giati mporei na exeis kai alla pedia // // opote ta data exoun apothikeutei mia xara... elpizw if (gvar->use_flag) { data = (*gvar->def_map2)[gvar->use_tokn]; store_data_shape(shape, data); } //------------------------------ if (gvar->def_flag) { def_flag = 1; def_tokn = gvar->def_tokn; } data = NULL; tokn = get_tokn(); data = call_node_read_function(tokn, NULL); store_data_shape(shape, data); if (def_flag && data !=NULL) { add_to_def_map(def_tokn, data); } } //set_node_type(shape, SHAPE); } //debug_read_shape(shape); return shape; } /*************************************************************************************/ /* Transform */ /*************************************************************************************/ Transform *new_transform() { Transform *transform = NULL; transform = new Transform; if (transform) { transform->info = new Info; transform->children = NULL; } return transform; } /*************************************************************************************/ /*************************************************************************************/ void delete_transform(Transform *transform) { delete transform; } /*************************************************************************************/ /*************************************************************************************/ void *read_translation(void *args) { string tokn = ""; int valid_flag = 1; double tmp; int i = 0; double *translation = NULL; Transform *transform = NULL; transform = (Transform *)args; if (transform) { translation = transform->translation; } if (translation) { for (i = 0; i < 3; ++i) { tokn = get_token(); if (is_number(tokn)) { tmp = str2double(tokn, &valid_flag); if (valid_flag) { translation[i] = tmp; } } } } return translation; } /*************************************************************************************/ /*************************************************************************************/ void *read_scale(void *args) { string tokn = ""; int valid_flag = 1; double tmp; int i = 0; double *scale = NULL; Transform *transform = NULL; transform = (Transform *)args; if (transform) { scale = transform->rotation; } if (scale) { for (i = 0; i < 3; ++i) { tokn = get_token(); if (is_number(tokn)) { tmp = str2double(tokn, &valid_flag); if (valid_flag) { scale[i] = tmp; } } } } return scale; } /*************************************************************************************/ /*************************************************************************************/ void *read_rotation(void *args) { string tokn = ""; int valid_flag = 1; double tmp; int i = 0; double *rotation = NULL; Transform *transform = NULL; transform = (Transform *)args; if (transform) { rotation = transform->rotation; } if (rotation) { for (i = 0; i < 4; ++i) { tokn = get_token(); if (is_number(tokn)) { tmp = str2double(tokn, &valid_flag); if (valid_flag) { rotation[i] = tmp; } } } } return rotation; } /*************************************************************************************/ /*************************************************************************************/ void debug_read_transform(void *args) { void *data = NULL; int i = 0; data = args; if (data) { if (get_node_type(data) == SHAPE) { debug_read_shape(data); } else if (get_node_type(data) == TRANSFORM) { Transform *transform = (Transform *)data; if (transform) { for (i = 0; i < 3; i++) { cout << "translation[" << i << "] -> " << transform->translation[i] << endl; } for (i = 0; i < 3; i++) { cout << "scale[" << i << "] -> " << transform->scale[i] << endl; } for (i = 0; i < 4; i++) { cout << "rotation[" << i << "] -> " << transform->rotation[i] << endl; } } data = transform->children; debug_read_transform(data); } } } /*************************************************************************************/ /*************************************************************************************/ void store_data_transform(Transform *transform, void *data) { DataType type = UNKNOWN; if (data) { type = get_node_type(data); switch (type) { case SHAPE: transform->children = data; break; case TRANSFORM: transform->children = data; break; case GROUP: transform->children = data; break; } } } /*************************************************************************************/ /*************************************************************************************/ void *read_transform(void *args) { cout << "Hello Transform" << endl; Transform *transform = NULL; string tokn = ""; void *data = NULL; int def_flag = 0; string def_tokn = ""; transform = new_transform(); if (transform) { while (tokn.find("children") == string::npos && tokn.find("}") == string::npos) { data = NULL; tokn = get_tokn(); data = call_field_read_function(tokn, transform); } if (tokn.find("children") != string::npos) { while(tokn.find("]") == string::npos) { if (gvar->def_flag) { def_flag = 1; def_tokn = gvar->def_tokn; } data = NULL; tokn = get_tokn(); data = call_node_read_function(tokn, NULL); store_data_transform(transform, data); if (def_flag && data !=NULL) { add_to_def_map(def_tokn, data); } } } } set_node_type(transform, TRANSFORM); //debug_read_transform(transform); return transform; } /*************************************************************************************/ /* Group */ /*************************************************************************************/ Group *new_group() { Group *group = NULL; group = new Group; if (group) { group->children = NULL; } return group; } /*************************************************************************************/ /*************************************************************************************/ void delete_group(Group *group) { delete group; } /*************************************************************************************/ /*************************************************************************************/ This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,158 @@ #ifndef DATA_TYPES_H #define DATA_TYPES_H #include <map> #include <string> #include <vector> using namespace std; typedef enum DataType { UNKNOWN = 0, SHAPE = 1, COORDINATE, INDEXED_LINE_SET, INDEXED_FACE_SET, TRANSFORM, MATERIAL, POINT_SET, GROUP, APPEARANCE, ROTATION, TRANSLATION, SCALE, POINT } DataType; typedef struct Container { DataType type; void *data; } Container; typedef struct Info { int id; DataType type; } Id; typedef struct Point { struct Info *info; double x; double y; double z; } Point; typedef struct CoordIndex { struct Info *info; vector<int> *coord_index_vec; } CoordIndex; typedef struct Coordinate { struct Info *info; vector<Point *> *coordinate_vec; } Coord; typedef struct IndexedLineSet { struct Info *info; Coordinate *coordinate; vector<CoordIndex *> *indexed_line_set_vec; } IndexedLineSet; typedef struct IndexedFaceSet { struct Info *info; Coordinate *coordinate; vector<CoordIndex *> *indexed_face_set_vec; } IndexedFaceSet; typedef struct Material { struct Info *info; double diffuse_color[3]; }Material; typedef struct PointSet { struct Info *info; Coordinate *coordinate; } Pointset; typedef struct Appearance { struct Info *info; Material *material; } Appearance; typedef struct Shape { struct Info *info; Appearance *appearance; Pointset *point_set; IndexedLineSet *indexed_line_set; IndexedFaceSet *indexed_face_set; } Shape; typedef struct Transform { struct Info *info; double translation[3]; double rotation[4]; double scale[3]; void *children; } Transform; typedef struct Group { struct Info *info; double b_boc_center[3]; double b_box_size[3]; void *children; } Group; typedef void *(*READ_NODE_FUN)(void *args); typedef void *(*CREATE_FUN)(void *args); typedef void *(*READ_FIELD_FUN)(void *args); typedef struct DataSup { string keyword; DataType type; READ_NODE_FUN read_node_fun; READ_FIELD_FUN read_field_fun; CREATE_FUN create_fun; } DataSup; /* FORWARD DECLARATION */ void init_node_type_map(map<string, DataType> **data_map); void init_field_type_map(map<string, DataType> **data_map); void init_type_sup_map(map<DataType, DataSup *> **data_sup_map); void init_frame(vector<Container *> **frame); void *read_coordinate(void *data); void *read_point_set(void *data); void *read_shape(void *data); void *read_transform(void *data); DataType get_container_type(Container *container); void *get_container_data(Container *container); void init_def(map<string, Container *> **def); void check_def_tokn(string tokn); void check_use_tokn(string tokn); void add_to_def(string tokn, Container *container); void* get_from_def(string tokn); void check_def_use_tokn(string tokn); void *read_point(void *args); void *read_translation(void *args); void *read_rotation(void *args); void *read_scale(void *args); int get_node_id(void *node); DataType get_node_type(void *node); void init_def_map2(map<string, void *> **def_map2); void add_to_def_map(string tokn, void *data); #endif // DATA_TYPES_H This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,154 @@ #include "file_handler.h" using namespace std; vector<string> *token_stack = NULL; ifstream *fp = NULL; void init_token_stack() { if (token_stack == NULL) { token_stack = new vector<string>; } } void close_file(ifstream *fp) { fp->close(); } ifstream *open_file(string file_name) { fp = new ifstream(); fp->open(file_name.c_str()); if (fp->is_open()) { init_token_stack(); return fp; } else { cout << "Unable to open file" << endl; close_file(fp); return NULL; } } void empty_token_stack() { // opote adeiazei to stack to programma paei kai tsimpaei nea grammi // apo to arxeio token_stack->erase(token_stack->begin(), token_stack->end()); } void trim(string *s) { size_t p = s->find_first_not_of(" \t"); s->erase(0, p); p = s->find_last_not_of(" \t"); if (string::npos != p) s->erase(p+1); } string *read_line(string *line) { if (fp->good()) { getline(*fp, *line); trim(line); //cout << "line: " << *line << endl; } else { line->clear(); } return line; } void go_to_next_line() { empty_token_stack(); } int is_blank(string token) { size_t value = 0; if (token.find_first_not_of("\t\n ") == string::npos) { //string is blank value = 1; } return value; } void tokenize_line(string line) { size_t next = 0; size_t prev = 0; string delimiter = " "; string substring; while ((next = line.find_first_of(delimiter, prev)) != string::npos) { if (next - prev != 0) { substring = line.substr(prev, next - prev); if (!is_blank(substring)) { token_stack->push_back(substring); } } prev = next + 1; } if (prev < line.size()) { substring = line.substr(prev); if (!is_blank(substring)) { token_stack->push_back(substring); } } } string get_token() { string value, line; if (!token_stack->empty()) { value = token_stack->front(); token_stack->erase(token_stack->begin()); } else { read_line(&line); if (line.size() != 0) { tokenize_line(line); value = token_stack->front(); token_stack->erase(token_stack->begin()); } } //cout << "tokn: " << value << endl; return value; } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,15 @@ #ifndef FILE_HANDLER_H #define FILE_HANDLER_H #include <iostream> #include <fstream> #include <string> #include <vector> using namespace std; ifstream *open_file(string file_name); string get_token(); void go_to_next_line(); #endif // FILE_HANDLER_H This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,111 @@ import random import string from typing import BinaryIO def generate_random_input(out: BinaryIO): # Generate a random number of nodes (between 1 and 10) num_nodes = random.randint(1, 10) out.write("#VRML V2.0 utf8\n".encode()) for _ in range(num_nodes): # Randomly select a node type node_type = random.choice(["Shape", "Transform", "PointSet"]) if node_type == "Shape": out.write(f"Shape {{\n".encode()) # Generate random fields for Shape node if random.random() < 0.5: out.write("appearance Appearance {\n".encode()) out.write("material Material {\n".encode()) out.write(f"diffuseColor {random.random()} {random.random()} {random.random()}\n".encode()) out.write("}\n".encode()) out.write("}\n".encode()) geometry_type = random.choice(["PointSet", "IndexedLineSet", "IndexedFaceSet"]) out.write(f"geometry {geometry_type} {{\n".encode()) if geometry_type == "PointSet": num_points = random.randint(1, 10) out.write("coord Coordinate {\n".encode()) out.write("point [\n".encode()) for _ in range(num_points): out.write(f"{random.random()} {random.random()} {random.random()},\n".encode()) out.write("]\n".encode()) out.write("}\n".encode()) elif geometry_type == "IndexedLineSet": num_points = random.randint(2, 10) out.write("coord Coordinate {\n".encode()) out.write("point [\n".encode()) for _ in range(num_points): out.write(f"{random.random()} {random.random()} {random.random()},\n".encode()) out.write("]\n".encode()) out.write("}\n".encode()) out.write("coordIndex [\n".encode()) for i in range(num_points - 1): out.write(f"{i}, {i+1}, -1,\n".encode()) out.write("]\n".encode()) elif geometry_type == "IndexedFaceSet": num_points = random.randint(3, 10) out.write("coord Coordinate {\n".encode()) out.write("point [\n".encode()) for _ in range(num_points): out.write(f"{random.random()} {random.random()} {random.random()},\n".encode()) out.write("]\n".encode()) out.write("}\n".encode()) out.write("coordIndex [\n".encode()) indices = list(range(num_points)) random.shuffle(indices) for i in range(0, num_points, 3): out.write(f"{indices[i]}, {indices[i+1]}, {indices[i+2]}, -1,\n".encode()) out.write("]\n".encode()) out.write("}\n".encode()) # Close geometry out.write("}\n".encode()) # Close Shape elif node_type == "Transform": out.write(f"Transform {{\n".encode()) # Generate random fields for Transform node if random.random() < 0.5: out.write(f"translation {random.random()} {random.random()} {random.random()}\n".encode()) if random.random() < 0.5: out.write(f"rotation {random.random()} {random.random()} {random.random()} {random.random()}\n".encode()) if random.random() < 0.5: out.write(f"scale {random.random()} {random.random()} {random.random()}\n".encode()) # Recursively generate children nodes num_children = random.randint(0, 3) if num_children > 0: out.write("children [\n".encode()) for _ in range(num_children): generate_random_input(out) out.write("]\n".encode()) out.write("}\n".encode()) # Close Transform elif node_type == "PointSet": out.write(f"PointSet {{\n".encode()) num_points = random.randint(1, 10) out.write("coord Coordinate {\n".encode()) out.write("point [\n".encode()) for _ in range(num_points): out.write(f"{random.random()} {random.random()} {random.random()},\n".encode()) out.write("]\n".encode()) out.write("}\n".encode()) out.write("}\n".encode()) # Close PointSet # Optionally add DEF/USE statements if random.random() < 0.3: def_name = ''.join(random.choices(string.ascii_letters, k=8)) out.write(f"DEF {def_name} ".encode()) generate_random_input(out) if random.random() < 0.5: out.write(f"USE {def_name}\n".encode()) # Example usage with open("random.wrl", "wb") as file: generate_random_input(file) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,111 @@ import random import string from typing import BinaryIO def generate_random_input(out: BinaryIO): # Generate a random number of nodes (between 1 and 10) num_nodes = random.randint(1, 10) out.write("#VRML V2.0 utf8\n".encode()) for _ in range(num_nodes): # Randomly select a node type node_type = random.choice(["Shape", "Transform", "PointSet"]) if node_type == "Shape": out.write(f"Shape {{\n".encode()) # Generate random fields for Shape node if random.random() < 0.5: out.write("appearance Appearance {\n".encode()) out.write("material Material {\n".encode()) out.write(f"diffuseColor {random.random()} {random.random()} {random.random()}\n".encode()) out.write("}\n".encode()) out.write("}\n".encode()) geometry_type = random.choice(["PointSet", "IndexedLineSet", "IndexedFaceSet"]) out.write(f"geometry {geometry_type} {{\n".encode()) if geometry_type == "PointSet": num_points = random.randint(1, 10) out.write("coord Coordinate {\n".encode()) out.write("point [\n".encode()) for _ in range(num_points): out.write(f"{random.random()} {random.random()} {random.random()},\n".encode()) out.write("]\n".encode()) out.write("}\n".encode()) elif geometry_type == "IndexedLineSet": num_points = random.randint(2, 10) out.write("coord Coordinate {\n".encode()) out.write("point [\n".encode()) for _ in range(num_points): out.write(f"{random.random()} {random.random()} {random.random()},\n".encode()) out.write("]\n".encode()) out.write("}\n".encode()) out.write("coordIndex [\n".encode()) for i in range(num_points - 1): out.write(f"{i}, {i+1}, -1,\n".encode()) out.write("]\n".encode()) elif geometry_type == "IndexedFaceSet": num_points = random.randint(3, 10) out.write("coord Coordinate {\n".encode()) out.write("point [\n".encode()) for _ in range(num_points): out.write(f"{random.random()} {random.random()} {random.random()},\n".encode()) out.write("]\n".encode()) out.write("}\n".encode()) out.write("coordIndex [\n".encode()) indices = list(range(num_points)) random.shuffle(indices) for i in range(0, num_points - 2, 3): out.write(f"{indices[i]}, {indices[i+1]}, {indices[i+2]}, -1,\n".encode()) out.write("]\n".encode()) out.write("}\n".encode()) # Close geometry out.write("}\n".encode()) # Close Shape elif node_type == "Transform": out.write(f"Transform {{\n".encode()) # Generate random fields for Transform node if random.random() < 0.5: out.write(f"translation {random.random()} {random.random()} {random.random()}\n".encode()) if random.random() < 0.5: out.write(f"rotation {random.random()} {random.random()} {random.random()} {random.random()}\n".encode()) if random.random() < 0.5: out.write(f"scale {random.random()} {random.random()} {random.random()}\n".encode()) # Recursively generate children nodes num_children = random.randint(0, 3) if num_children > 0: out.write("children [\n".encode()) for _ in range(num_children): generate_random_input(out) out.write("]\n".encode()) out.write("}\n".encode()) # Close Transform elif node_type == "PointSet": out.write(f"PointSet {{\n".encode()) num_points = random.randint(1, 10) out.write("coord Coordinate {\n".encode()) out.write("point [\n".encode()) for _ in range(num_points): out.write(f"{random.random()} {random.random()} {random.random()},\n".encode()) out.write("]\n".encode()) out.write("}\n".encode()) out.write("}\n".encode()) # Close PointSet # Optionally add DEF/USE statements if random.random() < 0.3: def_name = ''.join(random.choices(string.ascii_letters, k=8)) out.write(f"DEF {def_name} ".encode()) generate_random_input(out) if random.random() < 0.5: out.write(f"USE {def_name}\n".encode()) # Example usage with open("random.wrl", "wb") as file: generate_random_input(file) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,115 @@ import random import string from typing import BinaryIO def generate_random_input(out: BinaryIO, max_depth: int = 5, current_depth: int = 0): if current_depth >= max_depth: return # Generate a random number of nodes (between 1 and 5) num_nodes = random.randint(1, 5) if current_depth == 0: out.write("#VRML V2.0 utf8\n".encode()) for _ in range(num_nodes): # Randomly select a node type node_type = random.choice(["Shape", "Transform", "PointSet"]) if node_type == "Shape": out.write(f"Shape {{\n".encode()) # Generate random fields for Shape node if random.random() < 0.5: out.write("appearance Appearance {\n".encode()) out.write("material Material {\n".encode()) out.write(f"diffuseColor {random.random()} {random.random()} {random.random()}\n".encode()) out.write("}\n".encode()) out.write("}\n".encode()) geometry_type = random.choice(["PointSet", "IndexedLineSet", "IndexedFaceSet"]) out.write(f"geometry {geometry_type} {{\n".encode()) if geometry_type == "PointSet": num_points = random.randint(1, 10) out.write("coord Coordinate {\n".encode()) out.write("point [\n".encode()) for _ in range(num_points): out.write(f"{random.random()} {random.random()} {random.random()},\n".encode()) out.write("]\n".encode()) out.write("}\n".encode()) elif geometry_type == "IndexedLineSet": num_points = random.randint(2, 10) out.write("coord Coordinate {\n".encode()) out.write("point [\n".encode()) for _ in range(num_points): out.write(f"{random.random()} {random.random()} {random.random()},\n".encode()) out.write("]\n".encode()) out.write("}\n".encode()) out.write("coordIndex [\n".encode()) for i in range(num_points - 1): out.write(f"{i}, {i+1}, -1,\n".encode()) out.write("]\n".encode()) elif geometry_type == "IndexedFaceSet": num_points = random.randint(3, 10) out.write("coord Coordinate {\n".encode()) out.write("point [\n".encode()) for _ in range(num_points): out.write(f"{random.random()} {random.random()} {random.random()},\n".encode()) out.write("]\n".encode()) out.write("}\n".encode()) out.write("coordIndex [\n".encode()) indices = list(range(num_points)) random.shuffle(indices) for i in range(0, num_points - 2, 3): out.write(f"{indices[i]}, {indices[i+1]}, {indices[i+2]}, -1,\n".encode()) out.write("]\n".encode()) out.write("}\n".encode()) # Close geometry out.write("}\n".encode()) # Close Shape elif node_type == "Transform": out.write(f"Transform {{\n".encode()) # Generate random fields for Transform node if random.random() < 0.5: out.write(f"translation {random.random()} {random.random()} {random.random()}\n".encode()) if random.random() < 0.5: out.write(f"rotation {random.random()} {random.random()} {random.random()} {random.random()}\n".encode()) if random.random() < 0.5: out.write(f"scale {random.random()} {random.random()} {random.random()}\n".encode()) # Recursively generate children nodes num_children = random.randint(0, 3) if num_children > 0: out.write("children [\n".encode()) for _ in range(num_children): generate_random_input(out, max_depth, current_depth + 1) out.write("]\n".encode()) out.write("}\n".encode()) # Close Transform elif node_type == "PointSet": out.write(f"PointSet {{\n".encode()) num_points = random.randint(1, 10) out.write("coord Coordinate {\n".encode()) out.write("point [\n".encode()) for _ in range(num_points): out.write(f"{random.random()} {random.random()} {random.random()},\n".encode()) out.write("]\n".encode()) out.write("}\n".encode()) out.write("}\n".encode()) # Close PointSet # Optionally add DEF/USE statements if random.random() < 0.3: def_name = ''.join(random.choices(string.ascii_letters, k=8)) out.write(f"DEF {def_name} ".encode()) generate_random_input(out, max_depth, current_depth + 1) if random.random() < 0.5: out.write(f"USE {def_name}\n".encode()) # Example usage with open("random.wrl", "wb") as file: generate_random_input(file) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,16 @@ #include <iostream> #include "vrml_parser.h" using namespace std; int main(int argc, char **argv) { if (argc != 2) { cerr << "usage: " << argv[0] << " <filename>" << endl; return 1; } read_vrml(argv[1]); return 0; } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,39 @@ #include "str_and_math.h" using namespace std; int is_number(string s) { string::const_iterator it = s.begin(); while (it != s.end() && ( isdigit(*it) || *it == '.' || *it == '-')) { ++it; } return !s.empty() && it == s.end(); } double str2double(string str, int *valid_flag) { char *endptr = NULL; double value = strtod(str.c_str(), &endptr); if (*endptr) { *valid_flag = 0; } return value; } int find_comma_and_remove_it(string *tokn) { int pos = 0; int value = 0; if ( (pos = tokn->find_first_of(",")) != string::npos) { *tokn = tokn->substr(0, pos); value = 1; } return value; } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,14 @@ #ifndef STR_AND_MATH_H #define STR_AND_MATH_H #include <string> #include <cstdlib> using namespace std; int is_number(string s); double str2double(string str, int *valid_flag); int find_comma_and_remove_it(string *tokn); #endif // STR_AND_MATH_H This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,674 @@ #include "vrml_parser.h" GlobalVar *gvar = NULL; /*************************************************************************************/ /*************************************************************************************/ void init_gvar(map<string, DataType> *node_type_map, map<DataType, DataSup *> *type_sup_map, map<string, DataType> *field_type_map, stack<string> *file_stack, map<string, Container *> *def_map, map<string, void *> *def_map2) { if (gvar == NULL) { gvar = new GlobalVar; } gvar->node_type_map = node_type_map; gvar->type_sup_map = type_sup_map; gvar->field_type_map = field_type_map; gvar->file_stack = file_stack; gvar->def_map = def_map; gvar->def_map2 = def_map2; gvar->frame = NULL; gvar->def_flag = 0; gvar->use_flag = 0; gvar->def_tokn = ""; gvar->use_tokn = ""; } /*************************************************************************************/ /*************************************************************************************/ map<string, DataType> *get_node_type_map() { return gvar->node_type_map; } /*************************************************************************************/ /*************************************************************************************/ map<DataType, DataSup *> *get_type_sup_map() { return gvar->type_sup_map; } /*************************************************************************************/ /*************************************************************************************/ map<string, Container *> *get_def_map() { return gvar->def_map; } /*************************************************************************************/ /*************************************************************************************/ map<string, DataType> *get_field_type_map() { return gvar->field_type_map; } /*************************************************************************************/ /* Stack */ /*************************************************************************************/ void init_stack(stack<string> **file_stack) { if (*file_stack == NULL) { *file_stack = new stack<string>; } } /*************************************************************************************/ /*************************************************************************************/ int check_tokn_to_add_stack(string tokn) { int value = 0; map<string, DataType> *node_type_map = NULL; map<string, DataType>::iterator node_type_map_it; node_type_map = gvar->node_type_map; node_type_map_it = node_type_map->find(tokn); if (node_type_map) { if (tokn.find("{") != string::npos) { value = 1; } else if (tokn.find("}") != string::npos) { value = 1; } else if (node_type_map_it != node_type_map->end()) { value = 1; } } return value; } /*************************************************************************************/ /*************************************************************************************/ string top_stack() { stack<string> *file_stack = NULL; file_stack = gvar->file_stack; string value; if (file_stack) { value = file_stack->top(); } return value; } /*************************************************************************************/ /*************************************************************************************/ int check_matching_bracket(string tokn) { int value = 0; if (top_stack() == "{" && tokn == "}") { value = 1; } return value; } /*************************************************************************************/ /*************************************************************************************/ int top_is_bracket() { int value = 0; string top; top = top_stack(); if (top == "}" || top == "{") { value = 1; } return value; } /*************************************************************************************/ /*************************************************************************************/ int size_stack() { stack<string> *file_stack = NULL; file_stack = gvar->file_stack; int value = 0; if (file_stack) { value = file_stack->size(); } return value; } /*************************************************************************************/ /*************************************************************************************/ void push_stack(string tokn) { stack<string> *file_stack = NULL; file_stack = gvar->file_stack; string value; if (file_stack) { file_stack->push(tokn); } } /*************************************************************************************/ /*************************************************************************************/ void pop_stack() { stack<string> *file_stack = NULL; file_stack = gvar->file_stack; string value; if (file_stack) { file_stack->pop(); } } /*************************************************************************************/ /*************************************************************************************/ void perform_stack_operations(string tokn) { if (check_tokn_to_add_stack(tokn)) { if (size_stack()) { if (check_matching_bracket(tokn)) { // pop brackets pop_stack(); if (!top_is_bracket()) { //pop keyword pop_stack(); } } else { push_stack(tokn); } } else { push_stack(tokn); } } } /*************************************************************************************/ /*************************************************************************************/ void stack_operations(string tokn) { perform_stack_operations(tokn); } /*************************************************************************************/ /*************************************************************************************/ void debug_stack(string msg) { cout << msg <<endl; while (size_stack()) { cout << " stack: "<<top_stack() << endl; pop_stack(); } } /*************************************************************************************/ /*************************************************************************************/ string get_tokn() { string tokn; //tokn = get_token(); //stack_operations(tokn); tokn = get_token(); stack_operations(tokn); // for comments inline while (tokn.find_first_of("#") != string::npos) { go_to_next_line(); tokn = get_token(); stack_operations(tokn); } check_def_tokn(tokn); check_use_tokn(tokn); return tokn; } /*************************************************************************************/ /*************************************************************************************/ void check_shape(Container *container) { PointSet *point_set = NULL; Coordinate *coordinate = NULL; vector<Point *> *coordinate_vec = NULL; vector<Point *>::iterator it; Point *point = NULL; Shape *shape = NULL; shape = (Shape *) get_container_data(container); if (shape) { point_set = shape->point_set; if (point_set) { coordinate = point_set->coordinate; if (coordinate) { coordinate_vec = coordinate->coordinate_vec; if (coordinate_vec) { for (it = coordinate_vec->begin(); it != coordinate_vec->end(); ++it) { point = *it; if (point) cout << "r_shape value: x = " << point->x << " y = " << point->y << " z = " << point->z << endl; } } } } } } /*************************************************************************************/ /*************************************************************************************/ void check_read_point_set(void *args) { Coordinate *coordinate = NULL; vector<Point *> *coordinate_vec = NULL; vector<Point *>::iterator it; Point *point = NULL; PointSet *point_set = NULL; point_set = (PointSet *)args; if (point_set) { coordinate = point_set->coordinate; if (coordinate) { coordinate_vec = coordinate->coordinate_vec; if (coordinate_vec) { for (it = coordinate_vec->begin(); it != coordinate_vec->end(); ++it) { point = *it; if (point) cout << "r_point_set value: x = " << point->x << " y = " << point->y << " z = " << point->z << endl; } } } } } void check_shape2(void *args) { PointSet *point_set = NULL; Coordinate *coordinate = NULL; vector<Point *> *coordinate_vec = NULL; vector<Point *>::iterator it; Point *point = NULL; Shape *shape = NULL; shape = (Shape *)args; if (shape) { point_set = shape->point_set; if (point_set) { coordinate = point_set->coordinate; if (coordinate) { coordinate_vec = coordinate->coordinate_vec; if (coordinate_vec) { for (it = coordinate_vec->begin(); it != coordinate_vec->end(); ++it) { point = *it; if (point) cout << "r_shape value: x = " << point->x << " y = " << point->y << " z = " << point->z << endl; } } } } } } void check_transform2(void *args) { int i; DataType type; void *data = NULL; data = args; if (data) { while (data != NULL) { type = get_node_type(data); if (type == SHAPE) { check_shape2(data); data = NULL; } else if ( type == TRANSFORM) { Transform *transform = (Transform *)data; for (i = 0; i < 3; i++) { cout << "translation[" << i << "] -> " << transform->translation[i] << endl; } for (i = 0; i < 3; i++) { cout << "scale[" << i << "] -> " << transform->scale[i] << endl; } for (i = 0; i < 4; i++) { cout << "rotation[" << i << "] -> " << transform->rotation[i] << endl; } data = transform->children; } else { data = NULL; } } } } /*************************************************************************************/ /*************************************************************************************/ void check_frame(vector<Container *> *frame) { vector<Container *>::iterator it; DataType type = UNKNOWN; for (it = frame->begin(); it != frame->end(); ++it) { type = get_container_type((Container *)*it); if (type == SHAPE) { cout << "SHAPE" << endl; check_shape(*it); } else if (type == TRANSFORM) { //check_transform(*it); } } } /*************************************************************************************/ /*************************************************************************************/ void debug_def2() { map<string, void *>::iterator def_map_it; map<string, void *> *def_map = NULL; def_map = gvar->def_map2; int i = 0; if (def_map) { for (def_map_it = def_map->begin(); def_map_it != def_map->end(); ++def_map_it) { cout << "def map key: " << def_map_it->first <<" value: " << def_map_it->second << endl; i++; if (i == 1) { cout << endl << "@@@@@@@@@@ TRANSFORM @@@@@@@@@@@" << endl; check_transform2(def_map_it->second); } if (i == 2) { cout << endl << "@@@@@@@@@@ SHAPE @@@@@@@@@@@" << endl; check_shape2(def_map_it->second); } if (i == 3) { cout << endl << "@@@@@@@@@@ POINTSET @@@@@@@@@@@" << endl; check_read_point_set(def_map_it->second); } } } } /*************************************************************************************/ /*************************************************************************************/ void *call_node_read_function(string tokn, void *args) { map<string, DataType> *node_type_map = NULL; map<string, DataType>::iterator node_type_map_it; map<DataType, DataSup *> *type_sup_map = NULL; map<DataType, DataSup *>::iterator type_sup_map_it; void *data = NULL; node_type_map = get_node_type_map(); type_sup_map = get_type_sup_map(); node_type_map_it = node_type_map->find(tokn); if (node_type_map_it != node_type_map->end()) { type_sup_map_it = type_sup_map->find(node_type_map_it->second); if (type_sup_map_it != type_sup_map->end()) { data = type_sup_map_it->second->read_node_fun(args); } } return data; } /*************************************************************************************/ /*************************************************************************************/ void *call_field_read_function(string tokn, void *args) { map<string, DataType> *field_type_map = NULL; map<string, DataType>::iterator field_type_map_it; map<DataType, DataSup *> *type_sup_map = NULL; map<DataType, DataSup *>::iterator type_sup_map_it; void *data = NULL; field_type_map = get_field_type_map(); type_sup_map = get_type_sup_map(); field_type_map_it = field_type_map->find(tokn); if (field_type_map_it != field_type_map->end()) { type_sup_map_it = type_sup_map->find(field_type_map_it->second); if (type_sup_map_it != type_sup_map->end()) { data = type_sup_map_it->second->read_field_fun(args); } } return data; } /*************************************************************************************/ /*************************************************************************************/ void read_vrml(char *filename) { string tokn; ifstream *fp = NULL; map<string, DataType> *node_type_map = NULL; map<DataType, DataSup *> *type_sup_map = NULL; map<string, DataType> *field_type_map = NULL; stack<string> *file_stack = NULL; vector<Container *> *frame = NULL; map<string, Container *> *def = NULL; map<string, void *> *def_map2 = NULL; void *data = NULL; DataType data_type = UNKNOWN; init_node_type_map(&node_type_map); init_field_type_map(&field_type_map); init_type_sup_map(&type_sup_map); init_stack(&file_stack); init_frame(&frame); init_def(&def); init_def_map2(&def_map2); init_gvar(node_type_map, type_sup_map, field_type_map, file_stack, def, def_map2); gvar->frame = frame; int i = 0; int def_flag = 0; string def_tokn; //fp = open_file("/home/alepapadop/VRML/5pointset.wrl"); //fp = open_file("/home/alepapadop/VRML/a.wrl"); fp = open_file(filename); while (fp->good()) { tokn = get_tokn(); if (gvar->def_flag) { def_flag = 1; def_tokn = gvar->def_tokn; //gvar->def_flag = 0; //gvar->def_tokn = ""; } data = call_node_read_function(tokn, NULL); if (def_flag && data !=NULL) { add_to_def(def_tokn, (Container *)data); add_to_def_map(def_tokn, data); //(*(gvar->def_map2))[def_tokn] = data; } if (data != NULL) { frame->push_back((Container *)data); } data = NULL; // lthos auto, edw einai pou tha mpainei sto file data to frame if (!size_stack()) { init_frame(&frame); gvar->frame = frame; } data_type = UNKNOWN; i ++; if (i == 100) break; } check_frame(frame); debug_stack("\nSTACK \n\n"); // debug_def(); debug_def2(); } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,40 @@ #ifndef VRML_PARSER_H #define VRML_PARSER_H #include <string> #include <stack> #include "file_handler.h" #include "data_types.h" using namespace std; typedef struct GlobalVar { map<string, DataType> *node_type_map; map<DataType, DataSup *> *type_sup_map; map<string, DataType> *field_type_map; map<string, Container *> *def_map; map<string, void *> *def_map2; stack<string> *file_stack; vector<Container *> *frame; int def_flag; int use_flag; string def_tokn; string use_tokn; } GlobalVar; void read_vrml(char *); string get_tokn(); void *call_node_read_function(string tokn, void *args); void *call_field_read_function(string tokn, void *args); extern GlobalVar *gvar; #endif // VRML_PARSER_H