void Parser::Parse(const char * filepath) { std::ifstream in(filepath); std::ostringstream oss; oss << in.rdbuf(); buffer = oss.str(); in.close(); index = 0; while (HasNextTag()) { std::string tag = NextTag(); if (tag == "camera") { ParseCamera(); } else if (tag == "renderer") { ParseRenderer(); } else if (tag == "scene") { ParseScene(); } } }
void Parser::ParseCamera() { Point position, focus; Vector up; double filedOfView; int xResolution, yResolution; while (HasNextTag()) { std::string tag = NextTag(); if (tag == "position") { SkipSpace(); ParseTripleDouble(&position.x, &position.y, &position.z); } else if (tag == "up") { SkipSpace(); ParseTripleDouble(&up.x, &up.y, &up.z); } else if (tag == "focus") { SkipSpace(); ParseTripleDouble(&focus.x, &focus.y, &focus.z); } else if (tag == "fov") { SkipSpace(); filedOfView = ParseDouble(); } else if (tag == "resolution") { SkipSpace(); xResolution = ParseInteger(); ++index; yResolution = ParseInteger(); } else if (tag == "/camera") { double aspect = static_cast<double>(xResolution) / static_cast<double>(yResolution); camera = new Camera(position, focus, up, filedOfView, aspect); image = new Image(xResolution,yResolution); break; } } }
void Parser::ParseRenderer() { unsigned int bounce = 5; unsigned int samplesPerPixel = 4; while (HasNextTag()) { std::string tag = NextTag(); if (tag == "bounce") { SkipSpace(); bounce = ParseInteger(); } else if (tag == "sample") { SkipSpace(); samplesPerPixel = ParseInteger(); } else if (tag == "/renderer") { renderer = new Renderer(bounce, samplesPerPixel); break; } } }
static bool Render(Buffer *out, const char *start, const char *input, Seq *hash_stack, char *delim_start, size_t *delim_start_len, char *delim_end, size_t *delim_end_len, bool skip_content, const char *section, const char **section_end) { while (true) { if (!input) { Log(LOG_LEVEL_ERR, "Unexpected end to Mustache template"); return false; } Mustache tag = NextTag(input, delim_start, *delim_start_len, delim_end, *delim_end_len); { const char *line_begin = NULL; const char *line_end = NULL; if (!IsTagTypeRenderable(tag.type) && IsTagStandalone(start, tag.begin, tag.end, &line_begin, &line_end)) { RenderContent(out, input, line_begin - input, false, skip_content); input = line_end; } else { RenderContent(out, input, tag.begin - input, false, skip_content); input = tag.end; } } switch (tag.type) { case TAG_TYPE_ERR: return false; case TAG_TYPE_DELIM: if (!SetDelimiters(tag.content, tag.content_len, delim_start, delim_start_len, delim_end, delim_end_len)) { return false; } continue; case TAG_TYPE_COMMENT: continue; case TAG_TYPE_NONE: return true; case TAG_TYPE_VAR_SERIALIZED: case TAG_TYPE_VAR_SERIALIZED_COMPACT: case TAG_TYPE_VAR_UNESCAPED: case TAG_TYPE_VAR: if (!skip_content) { if (tag.content_len > 0) { if (!RenderVariable(out, tag.content, tag.content_len, tag.type, hash_stack)) { return false; } } else { RenderContent(out, delim_start, *delim_start_len, false, false); RenderContent(out, delim_end, *delim_end_len, false, false); } } continue; case TAG_TYPE_INVERTED: case TAG_TYPE_SECTION: { char *section = xstrndup(tag.content, tag.content_len); JsonElement *var = LookupVariable(hash_stack, tag.content, tag.content_len); SeqAppend(hash_stack, var); if (!var) { const char *cur_section_end = NULL; if (!Render(out, start, input, hash_stack, delim_start, delim_start_len, delim_end, delim_end_len, skip_content || tag.type != TAG_TYPE_INVERTED, section, &cur_section_end)) { free(section); return false; } free(section); input = cur_section_end; continue; } switch (JsonGetElementType(var)) { case JSON_ELEMENT_TYPE_PRIMITIVE: switch (JsonGetPrimitiveType(var)) { case JSON_PRIMITIVE_TYPE_BOOL: { bool skip = skip_content || (!JsonPrimitiveGetAsBool(var) ^ (tag.type == TAG_TYPE_INVERTED)); const char *cur_section_end = NULL; if (!Render(out, start, input, hash_stack, delim_start, delim_start_len, delim_end, delim_end_len, skip, section, &cur_section_end)) { free(section); return false; } free(section); input = cur_section_end; } continue; default: Log(LOG_LEVEL_WARNING, "Mustache sections can only take a boolean or a container (array or map) value, but section '%s' isn't getting one of those.", section); return false; } break; case JSON_ELEMENT_TYPE_CONTAINER: switch (JsonGetContainerType(var)) { case JSON_CONTAINER_TYPE_OBJECT: case JSON_CONTAINER_TYPE_ARRAY: if (JsonLength(var) > 0) { const char *cur_section_end = NULL; for (size_t i = 0; i < JsonLength(var); i++) { JsonElement *child_hash = JsonAt(var, i); SeqAppend(hash_stack, child_hash); if (!Render(out, start, input, hash_stack, delim_start, delim_start_len, delim_end, delim_end_len, skip_content || tag.type == TAG_TYPE_INVERTED, section, &cur_section_end)) { free(section); return false; } } input = cur_section_end; free(section); } else { const char *cur_section_end = NULL; if (!Render(out, start, input, hash_stack, delim_start, delim_start_len, delim_end, delim_end_len, tag.type != TAG_TYPE_INVERTED, section, &cur_section_end)) { free(section); return false; } free(section); input = cur_section_end; } break; } break; } } continue; case TAG_TYPE_SECTION_END: if (!section) { char *varname = xstrndup(tag.content, tag.content_len); Log(LOG_LEVEL_WARNING, "Unknown section close in mustache template '%s'", varname); free(varname); return false; } else { SeqRemove(hash_stack, SeqLength(hash_stack) - 1); *section_end = input; return true; } break; default: assert(false); return false; } } assert(false); }
void Parser::ParseScene() { scene = new Scene(); while (HasNextTag()) { std::string tag = NextTag(); if (tag == "model") { Model *model = new Model; while (HasNextTag()) { tag = NextTag(); if (tag == "mesh") { MeshParser meshParser; meshParser.Parse(model, ParseString().c_str()); } else if (tag == "sphere") { Point center; double radius; while (HasNextTag()) { tag = NextTag(); if (tag == "center") { SkipSpace(); ParseTripleDouble(¢er.x, ¢er.y, ¢er.z); } else if (tag == "radius") { SkipSpace(); radius = ParseDouble(); } else if (tag == "/sphere") { Sphere *sphere = new Sphere(center, radius); model->AddGeometry(sphere); break; } } } else if (tag == "diffuse") { Color diffuse; SkipSpace(); ParseTripleDouble(&diffuse.r, &diffuse.g, &diffuse.b); model->bsdf = new DiffuseReflection(diffuse); } else if (tag == "specular") { Color specular; SkipSpace(); ParseTripleDouble(&specular.r, &specular.g, &specular.b); model->bsdf = new SpecularReflection(specular); } else if (tag == "blinn") { Color color; double exponent; while (HasNextTag()) { tag = NextTag(); if (tag == "color") { SkipSpace(); ParseTripleDouble(&color.r, &color.g, &color.b); } else if (tag == "exponent") { SkipSpace(); exponent = ParseDouble(); } else if (tag == "/blinn") { model->bsdf = new BlinnGlossy(color, exponent); break; } } } else if (tag == "transparent") { Color color; double eta; while (HasNextTag()) { tag = NextTag(); if (tag == "color") { SkipSpace(); ParseTripleDouble(&color.r, &color.g, &color.b); } else if (tag == "eta") { SkipSpace(); eta = ParseDouble(); } else if (tag == "/transparent") { model->bsdf = new SpecularTransmission(color, eta); break; } } } else if (tag == "emit") { Color emit; while (HasNextTag()) { tag = NextTag(); if (tag == "color") { SkipSpace(); ParseTripleDouble(&emit.r, &emit.g, &emit.b); } else if (tag == "scale") { SkipSpace(); emit *= ParseDouble(); } else if (tag == "/emit") { break; } } model->emit = emit; model->bsdf = new DiffuseReflection(Color::WHITE); } else if (tag == "/model") { break; } } scene->AddModel(model); } else if (tag == "environment") { Color environment; SkipSpace(); ParseTripleDouble(&environment.r, &environment.g, &environment.b); scene->Environment = environment; } else if (tag == "/scene") { break; } } }