diff --git a/examples/scene_caustics.xml b/examples/scene_caustics.xml new file mode 100644 index 000000000..f7cc32990 --- /dev/null +++ b/examples/scene_caustics.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/app/cycles_xml.cpp b/src/app/cycles_xml.cpp index 086351972..5f134e88d 100644 --- a/src/app/cycles_xml.cpp +++ b/src/app/cycles_xml.cpp @@ -46,8 +46,9 @@ struct XMLReadState : public XMLReader { Shader *shader; /* Current shader. */ string base; /* Base path to current file. */ float dicing_rate; /* Current dicing rate. */ + Object *object; /* Current object. */ - XMLReadState() : scene(NULL), smooth(false), shader(NULL), dicing_rate(1.0f) + XMLReadState() : scene(NULL), smooth(false), shader(NULL), dicing_rate(1.0f), object(NULL) { tfm = transform_identity(); } @@ -405,25 +406,33 @@ static void xml_read_background(XMLReadState &state, xml_node node) /* Mesh */ -static Mesh *xml_add_mesh(Scene *scene, const Transform &tfm) +static Mesh *xml_add_mesh(Scene *scene, const Transform &tfm, Object *object) { - /* create mesh */ - Mesh *mesh = new Mesh(); - scene->geometry.push_back(mesh); + if (object && object->get_geometry()->is_mesh()) { + /* Use existing object and mesh */ + object->set_tfm(tfm); + Geometry *geometry = object->get_geometry(); + return static_cast(geometry); + } + else { + /* Create mesh */ + Mesh *mesh = new Mesh(); + scene->geometry.push_back(mesh); - /* Create object. */ - Object *object = new Object(); - object->set_geometry(mesh); - object->set_tfm(tfm); - scene->objects.push_back(object); + /* Create object. */ + Object *object = new Object(); + object->set_geometry(mesh); + object->set_tfm(tfm); + scene->objects.push_back(object); - return mesh; + return mesh; + } } static void xml_read_mesh(const XMLReadState &state, xml_node node) { /* add mesh */ - Mesh *mesh = xml_add_mesh(state.scene, state.tfm); + Mesh *mesh = xml_add_mesh(state.scene, state.tfm, state.object); array used_shaders = mesh->get_used_shaders(); used_shaders.push_back_slow(state.shader); mesh->set_used_shaders(used_shaders); @@ -613,7 +622,7 @@ static void xml_read_transform(xml_node node, Transform &tfm) static void xml_read_state(XMLReadState &state, xml_node node) { - /* read shader */ + /* Read shader */ string shadername; if (xml_read_string(&shadername, node, "shader")) { @@ -632,6 +641,25 @@ static void xml_read_state(XMLReadState &state, xml_node node) } } + /* Read object */ + string objectname; + + if (xml_read_string(&objectname, node, "object")) { + bool found = false; + + foreach (Object *object, state.scene->objects) { + if (object->name == objectname) { + state.object = object; + found = true; + break; + } + } + + if (!found) { + fprintf(stderr, "Unknown object \"%s\".\n", objectname.c_str()); + } + } + xml_read_float(&state.dicing_rate, node, "dicing_rate"); /* read smooth/flat */ @@ -643,6 +671,26 @@ static void xml_read_state(XMLReadState &state, xml_node node) } } +/* Object */ + +static void xml_read_object(XMLReadState &state, xml_node node) +{ + Scene *scene = state.scene; + + /* create mesh */ + Mesh *mesh = new Mesh(); + scene->geometry.push_back(mesh); + + /* create object */ + Object *object = new Object(); + object->set_geometry(mesh); + object->set_tfm(state.tfm); + + xml_read_node(state, object, node); + + scene->objects.push_back(object); +} + /* Scene */ static void xml_read_include(XMLReadState &state, const string &src); @@ -690,6 +738,12 @@ static void xml_read_scene(XMLReadState &state, xml_node scene_node) xml_read_include(state, src); } } + else if (string_iequals(node.name(), "object")) { + XMLReadState substate = state; + + xml_read_object(substate, node); + xml_read_scene(substate, node); + } #ifdef WITH_ALEMBIC else if (string_iequals(node.name(), "alembic")) { xml_read_alembic(state, node);