Blender V2.61 - r43446
|
00001 /* 00002 * Copyright 2011, Blender Foundation. 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 #include <stdio.h> 00020 00021 #include <sstream> 00022 #include <algorithm> 00023 #include <iterator> 00024 00025 #include "camera.h" 00026 #include "film.h" 00027 #include "graph.h" 00028 #include "integrator.h" 00029 #include "light.h" 00030 #include "mesh.h" 00031 #include "nodes.h" 00032 #include "object.h" 00033 #include "shader.h" 00034 #include "scene.h" 00035 00036 #include "subd_mesh.h" 00037 #include "subd_patch.h" 00038 #include "subd_split.h" 00039 00040 #include "util_debug.h" 00041 #include "util_foreach.h" 00042 #include "util_path.h" 00043 #include "util_transform.h" 00044 #include "util_xml.h" 00045 00046 #include "cycles_xml.h" 00047 00048 CCL_NAMESPACE_BEGIN 00049 00050 /* XML reading state */ 00051 00052 struct XMLReadState { 00053 Scene *scene; /* scene pointer */ 00054 Transform tfm; /* current transform state */ 00055 bool smooth; /* smooth normal state */ 00056 int shader; /* current shader */ 00057 string base; /* base path to current file*/ 00058 float dicing_rate; /* current dicing rate */ 00059 Mesh::DisplacementMethod displacement_method; 00060 }; 00061 00062 /* Attribute Reading */ 00063 00064 static bool xml_read_bool(bool *value, pugi::xml_node node, const char *name) 00065 { 00066 pugi::xml_attribute attr = node.attribute(name); 00067 00068 if(attr) { 00069 *value = (string_iequals(attr.value(), "true")) || (atoi(attr.value()) != 0); 00070 return true; 00071 } 00072 00073 return false; 00074 } 00075 00076 static bool xml_read_int(int *value, pugi::xml_node node, const char *name) 00077 { 00078 pugi::xml_attribute attr = node.attribute(name); 00079 00080 if(attr) { 00081 *value = atoi(attr.value()); 00082 return true; 00083 } 00084 00085 return false; 00086 } 00087 00088 static bool xml_read_int_array(vector<int>& value, pugi::xml_node node, const char *name) 00089 { 00090 pugi::xml_attribute attr = node.attribute(name); 00091 00092 if(attr) { 00093 vector<string> tokens; 00094 string_split(tokens, attr.value()); 00095 00096 foreach(const string& token, tokens) 00097 value.push_back(atoi(token.c_str())); 00098 00099 return true; 00100 } 00101 00102 return false; 00103 } 00104 00105 static bool xml_read_float(float *value, pugi::xml_node node, const char *name) 00106 { 00107 pugi::xml_attribute attr = node.attribute(name); 00108 00109 if(attr) { 00110 *value = atof(attr.value()); 00111 return true; 00112 } 00113 00114 return false; 00115 } 00116 00117 static bool xml_read_float_array(vector<float>& value, pugi::xml_node node, const char *name) 00118 { 00119 pugi::xml_attribute attr = node.attribute(name); 00120 00121 if(attr) { 00122 vector<string> tokens; 00123 string_split(tokens, attr.value()); 00124 00125 foreach(const string& token, tokens) 00126 value.push_back(atof(token.c_str())); 00127 00128 return true; 00129 } 00130 00131 return false; 00132 } 00133 00134 static bool xml_read_float3(float3 *value, pugi::xml_node node, const char *name) 00135 { 00136 vector<float> array; 00137 00138 if(xml_read_float_array(array, node, name) && array.size() == 3) { 00139 *value = make_float3(array[0], array[1], array[2]); 00140 return true; 00141 } 00142 00143 return false; 00144 } 00145 00146 static bool xml_read_float3_array(vector<float3>& value, pugi::xml_node node, const char *name) 00147 { 00148 vector<float> array; 00149 00150 if(xml_read_float_array(array, node, name)) { 00151 for(size_t i = 0; i < array.size(); i += 3) 00152 value.push_back(make_float3(array[i+0], array[i+1], array[i+2])); 00153 00154 return true; 00155 } 00156 00157 return false; 00158 } 00159 00160 static bool xml_read_float4(float4 *value, pugi::xml_node node, const char *name) 00161 { 00162 vector<float> array; 00163 00164 if(xml_read_float_array(array, node, name) && array.size() == 4) { 00165 *value = make_float4(array[0], array[1], array[2], array[3]); 00166 return true; 00167 } 00168 00169 return false; 00170 } 00171 00172 static bool xml_read_string(string *str, pugi::xml_node node, const char *name) 00173 { 00174 pugi::xml_attribute attr = node.attribute(name); 00175 00176 if(attr) { 00177 *str = attr.value(); 00178 return true; 00179 } 00180 00181 return false; 00182 } 00183 00184 static bool xml_read_ustring(ustring *str, pugi::xml_node node, const char *name) 00185 { 00186 pugi::xml_attribute attr = node.attribute(name); 00187 00188 if(attr) { 00189 *str = ustring(attr.value()); 00190 return true; 00191 } 00192 00193 return false; 00194 } 00195 00196 static bool xml_equal_string(pugi::xml_node node, const char *name, const char *value) 00197 { 00198 pugi::xml_attribute attr = node.attribute(name); 00199 00200 if(attr) 00201 return string_iequals(attr.value(), value); 00202 00203 return false; 00204 } 00205 00206 static bool xml_read_enum(ustring *str, ShaderEnum& enm, pugi::xml_node node, const char *name) 00207 { 00208 pugi::xml_attribute attr = node.attribute(name); 00209 00210 if(attr) { 00211 ustring ustr(attr.value()); 00212 00213 if(enm.exists(ustr)) { 00214 *str = ustr; 00215 return true; 00216 } 00217 else 00218 fprintf(stderr, "Unknown value \"%s\" for attribute \"%s\".\n", ustr.c_str(), name); 00219 } 00220 00221 return false; 00222 } 00223 00224 /* Film */ 00225 00226 static void xml_read_film(const XMLReadState& state, pugi::xml_node node) 00227 { 00228 Camera *cam = state.scene->camera; 00229 00230 xml_read_int(&cam->width, node, "width"); 00231 xml_read_int(&cam->height, node, "height"); 00232 00233 float aspect = (float)cam->width/(float)cam->height; 00234 00235 if(cam->width >= cam->height) { 00236 cam->left = -aspect; 00237 cam->right = aspect; 00238 cam->bottom = -1.0f; 00239 cam->top = 1.0f; 00240 } 00241 else { 00242 cam->left = -1.0f; 00243 cam->right = 1.0f; 00244 cam->bottom = -1.0f/aspect; 00245 cam->top = 1.0f/aspect; 00246 } 00247 00248 cam->need_update = true; 00249 cam->update(); 00250 } 00251 00252 /* Integrator */ 00253 00254 static void xml_read_integrator(const XMLReadState& state, pugi::xml_node node) 00255 { 00256 Integrator *integrator = state.scene->integrator; 00257 00258 xml_read_int(&integrator->min_bounce, node, "min_bounce"); 00259 xml_read_int(&integrator->max_bounce, node, "max_bounce"); 00260 00261 xml_read_int(&integrator->max_diffuse_bounce, node, "max_diffuse_bounce"); 00262 xml_read_int(&integrator->max_glossy_bounce, node, "max_glossy_bounce"); 00263 xml_read_int(&integrator->max_transmission_bounce, node, "max_transmission_bounce"); 00264 00265 xml_read_int(&integrator->transparent_min_bounce, node, "transparent_min_bounce"); 00266 xml_read_int(&integrator->transparent_max_bounce, node, "transparent_max_bounce"); 00267 00268 xml_read_bool(&integrator->transparent_shadows, node, "transparent_shadows"); 00269 xml_read_bool(&integrator->no_caustics, node, "no_caustics"); 00270 00271 xml_read_int(&integrator->seed, node, "seed"); 00272 } 00273 00274 /* Camera */ 00275 00276 static void xml_read_camera(const XMLReadState& state, pugi::xml_node node) 00277 { 00278 Camera *cam = state.scene->camera; 00279 00280 if(xml_read_float(&cam->fov, node, "fov")) 00281 cam->fov *= M_PI/180.0f; 00282 00283 xml_read_float(&cam->nearclip, node, "nearclip"); 00284 xml_read_float(&cam->farclip, node, "farclip"); 00285 xml_read_float(&cam->aperturesize, node, "aperturesize"); // 0.5*focallength/fstop 00286 xml_read_float(&cam->focaldistance, node, "focaldistance"); 00287 xml_read_float(&cam->shutteropen, node, "shutteropen"); 00288 xml_read_float(&cam->shutterclose, node, "shutterclose"); 00289 00290 if(xml_equal_string(node, "type", "orthographic")) 00291 cam->ortho = true; 00292 else if(xml_equal_string(node, "type", "perspective")) 00293 cam->ortho = false; 00294 00295 cam->matrix = state.tfm; 00296 00297 cam->need_update = true; 00298 cam->update(); 00299 } 00300 00301 /* Shader */ 00302 00303 static string xml_socket_name(const char *name) 00304 { 00305 string sname = name; 00306 size_t i; 00307 00308 while((i = sname.find(" ")) != string::npos) 00309 sname.replace(i, 1, ""); 00310 00311 return sname; 00312 } 00313 00314 static void xml_read_shader_graph(const XMLReadState& state, Shader *shader, pugi::xml_node graph_node) 00315 { 00316 ShaderGraph *graph = new ShaderGraph(); 00317 00318 map<string, ShaderNode*> nodemap; 00319 00320 nodemap["output"] = graph->output(); 00321 00322 for(pugi::xml_node node = graph_node.first_child(); node; node = node.next_sibling()) { 00323 ShaderNode *snode = NULL; 00324 00325 if(string_iequals(node.name(), "image_texture")) { 00326 ImageTextureNode *img = new ImageTextureNode(); 00327 00328 xml_read_string(&img->filename, node, "src"); 00329 img->filename = path_join(state.base, img->filename); 00330 00331 snode = img; 00332 } 00333 else if(string_iequals(node.name(), "environment_texture")) { 00334 EnvironmentTextureNode *env = new EnvironmentTextureNode(); 00335 00336 xml_read_string(&env->filename, node, "src"); 00337 env->filename = path_join(state.base, env->filename); 00338 00339 snode = env; 00340 } 00341 else if(string_iequals(node.name(), "sky_texture")) { 00342 SkyTextureNode *sky = new SkyTextureNode(); 00343 00344 xml_read_float3(&sky->sun_direction, node, "sun_direction"); 00345 xml_read_float(&sky->turbidity, node, "turbidity"); 00346 00347 snode = sky; 00348 } 00349 else if(string_iequals(node.name(), "noise_texture")) { 00350 snode = new NoiseTextureNode(); 00351 } 00352 else if(string_iequals(node.name(), "checker_texture")) { 00353 snode = new CheckerTextureNode(); 00354 } 00355 else if(string_iequals(node.name(), "gradient_texture")) { 00356 GradientTextureNode *blend = new GradientTextureNode(); 00357 xml_read_enum(&blend->type, GradientTextureNode::type_enum, node, "type"); 00358 snode = blend; 00359 } 00360 else if(string_iequals(node.name(), "voronoi_texture")) { 00361 VoronoiTextureNode *voronoi = new VoronoiTextureNode(); 00362 xml_read_enum(&voronoi->coloring, VoronoiTextureNode::coloring_enum, node, "coloring"); 00363 snode = voronoi; 00364 } 00365 else if(string_iequals(node.name(), "musgrave_texture")) { 00366 MusgraveTextureNode *musgrave = new MusgraveTextureNode(); 00367 xml_read_enum(&musgrave->type, MusgraveTextureNode::type_enum, node, "type"); 00368 snode = musgrave; 00369 } 00370 else if(string_iequals(node.name(), "magic_texture")) { 00371 MagicTextureNode *magic = new MagicTextureNode(); 00372 xml_read_int(&magic->depth, node, "depth"); 00373 snode = magic; 00374 } 00375 else if(string_iequals(node.name(), "noise_texture")) { 00376 NoiseTextureNode *dist = new NoiseTextureNode(); 00377 snode = dist; 00378 } 00379 else if(string_iequals(node.name(), "wave_texture")) { 00380 WaveTextureNode *wood = new WaveTextureNode(); 00381 xml_read_enum(&wood->type, WaveTextureNode::type_enum, node, "type"); 00382 snode = wood; 00383 } 00384 else if(string_iequals(node.name(), "normal")) { 00385 snode = new NormalNode(); 00386 } 00387 else if(string_iequals(node.name(), "mapping")) { 00388 snode = new MappingNode(); 00389 } 00390 else if(string_iequals(node.name(), "ward_bsdf")) { 00391 snode = new WardBsdfNode(); 00392 } 00393 else if(string_iequals(node.name(), "diffuse_bsdf")) { 00394 snode = new DiffuseBsdfNode(); 00395 } 00396 else if(string_iequals(node.name(), "translucent_bsdf")) { 00397 snode = new TranslucentBsdfNode(); 00398 } 00399 else if(string_iequals(node.name(), "transparent_bsdf")) { 00400 snode = new TransparentBsdfNode(); 00401 } 00402 else if(string_iequals(node.name(), "velvet_bsdf")) { 00403 snode = new VelvetBsdfNode(); 00404 } 00405 else if(string_iequals(node.name(), "glossy_bsdf")) { 00406 GlossyBsdfNode *glossy = new GlossyBsdfNode(); 00407 xml_read_enum(&glossy->distribution, GlossyBsdfNode::distribution_enum, node, "distribution"); 00408 snode = glossy; 00409 } 00410 else if(string_iequals(node.name(), "glass_bsdf")) { 00411 GlassBsdfNode *diel = new GlassBsdfNode(); 00412 xml_read_enum(&diel->distribution, GlassBsdfNode::distribution_enum, node, "distribution"); 00413 snode = diel; 00414 } 00415 else if(string_iequals(node.name(), "emission")) { 00416 EmissionNode *emission = new EmissionNode(); 00417 xml_read_bool(&emission->total_power, node, "total_power"); 00418 snode = emission; 00419 } 00420 else if(string_iequals(node.name(), "background")) { 00421 snode = new BackgroundNode(); 00422 } 00423 else if(string_iequals(node.name(), "transparent_volume")) { 00424 snode = new TransparentVolumeNode(); 00425 } 00426 else if(string_iequals(node.name(), "isotropic_volume")) { 00427 snode = new IsotropicVolumeNode(); 00428 } 00429 else if(string_iequals(node.name(), "geometry")) { 00430 snode = new GeometryNode(); 00431 } 00432 else if(string_iequals(node.name(), "texture_coordinate")) { 00433 snode = new TextureCoordinateNode(); 00434 } 00435 else if(string_iequals(node.name(), "lightPath")) { 00436 snode = new LightPathNode(); 00437 } 00438 else if(string_iequals(node.name(), "value")) { 00439 ValueNode *value = new ValueNode(); 00440 xml_read_float(&value->value, node, "value"); 00441 snode = value; 00442 } 00443 else if(string_iequals(node.name(), "color")) { 00444 ColorNode *color = new ColorNode(); 00445 xml_read_float3(&color->value, node, "value"); 00446 snode = color; 00447 } 00448 else if(string_iequals(node.name(), "mix_closure")) { 00449 snode = new MixClosureNode(); 00450 } 00451 else if(string_iequals(node.name(), "add_closure")) { 00452 snode = new AddClosureNode(); 00453 } 00454 else if(string_iequals(node.name(), "invert")) { 00455 snode = new InvertNode(); 00456 } 00457 else if(string_iequals(node.name(), "mix")) { 00458 MixNode *mix = new MixNode(); 00459 xml_read_enum(&mix->type, MixNode::type_enum, node, "type"); 00460 snode = mix; 00461 } 00462 else if(string_iequals(node.name(), "gamma")) { 00463 snode = new GammaNode(); 00464 } 00465 else if(string_iequals(node.name(), "combine_rgb")) { 00466 snode = new CombineRGBNode(); 00467 } 00468 else if(string_iequals(node.name(), "separate_rgb")) { 00469 snode = new SeparateRGBNode(); 00470 } 00471 else if(string_iequals(node.name(), "hsv")) { 00472 snode = new HSVNode(); 00473 } 00474 else if(string_iequals(node.name(), "attribute")) { 00475 AttributeNode *attr = new AttributeNode(); 00476 xml_read_ustring(&attr->attribute, node, "attribute"); 00477 snode = attr; 00478 } 00479 else if(string_iequals(node.name(), "camera")) { 00480 snode = new CameraNode(); 00481 } 00482 else if(string_iequals(node.name(), "fresnel")) { 00483 snode = new FresnelNode(); 00484 } 00485 else if(string_iequals(node.name(), "math")) { 00486 MathNode *math = new MathNode(); 00487 xml_read_enum(&math->type, MathNode::type_enum, node, "type"); 00488 snode = math; 00489 } 00490 else if(string_iequals(node.name(), "vector_math")) { 00491 VectorMathNode *vmath = new VectorMathNode(); 00492 xml_read_enum(&vmath->type, VectorMathNode::type_enum, node, "type"); 00493 snode = vmath; 00494 } 00495 else if(string_iequals(node.name(), "connect")) { 00496 /* connect nodes */ 00497 vector<string> from_tokens, to_tokens; 00498 00499 string_split(from_tokens, node.attribute("from").value()); 00500 string_split(to_tokens, node.attribute("to").value()); 00501 00502 if(from_tokens.size() == 2 && to_tokens.size() == 2) { 00503 /* find nodes and sockets */ 00504 ShaderOutput *output = NULL; 00505 ShaderInput *input = NULL; 00506 00507 if(nodemap.find(from_tokens[0]) != nodemap.end()) { 00508 ShaderNode *fromnode = nodemap[from_tokens[0]]; 00509 00510 foreach(ShaderOutput *out, fromnode->outputs) 00511 if(string_iequals(xml_socket_name(out->name), from_tokens[1])) 00512 output = out; 00513 00514 if(!output) 00515 fprintf(stderr, "Unknown output socket name \"%s\" on \"%s\".\n", from_tokens[1].c_str(), from_tokens[0].c_str()); 00516 } 00517 else 00518 fprintf(stderr, "Unknown shader node name \"%s\".\n", from_tokens[0].c_str()); 00519 00520 if(nodemap.find(to_tokens[0]) != nodemap.end()) { 00521 ShaderNode *tonode = nodemap[to_tokens[0]]; 00522 00523 foreach(ShaderInput *in, tonode->inputs) 00524 if(string_iequals(xml_socket_name(in->name), to_tokens[1])) 00525 input = in; 00526 00527 if(!input) 00528 fprintf(stderr, "Unknown input socket name \"%s\" on \"%s\".\n", to_tokens[1].c_str(), to_tokens[0].c_str()); 00529 } 00530 else 00531 fprintf(stderr, "Unknown shader node name \"%s\".\n", to_tokens[0].c_str()); 00532 00533 /* connect */ 00534 if(output && input) 00535 graph->connect(output, input); 00536 } 00537 else 00538 fprintf(stderr, "Invalid from or to value for connect node.\n"); 00539 } 00540 else 00541 fprintf(stderr, "Unknown shader node \"%s\".\n", node.name()); 00542 00543 if(snode) { 00544 /* add to graph */ 00545 graph->add(snode); 00546 00547 /* add to map for name lookups */ 00548 string name = ""; 00549 xml_read_string(&name, node, "name"); 00550 00551 nodemap[name] = snode; 00552 00553 /* read input values */ 00554 for(pugi::xml_attribute attr = node.first_attribute(); attr; attr = attr.next_attribute()) { 00555 foreach(ShaderInput *in, snode->inputs) { 00556 if(string_iequals(in->name, attr.name())) { 00557 switch(in->type) { 00558 case SHADER_SOCKET_FLOAT: 00559 xml_read_float(&in->value.x, node, attr.name()); 00560 break; 00561 case SHADER_SOCKET_COLOR: 00562 case SHADER_SOCKET_VECTOR: 00563 case SHADER_SOCKET_POINT: 00564 case SHADER_SOCKET_NORMAL: 00565 xml_read_float3(&in->value, node, attr.name()); 00566 break; 00567 default: 00568 break; 00569 } 00570 } 00571 } 00572 } 00573 } 00574 } 00575 00576 shader->set_graph(graph); 00577 shader->tag_update(state.scene); 00578 } 00579 00580 static void xml_read_shader(const XMLReadState& state, pugi::xml_node node) 00581 { 00582 Shader *shader = new Shader(); 00583 xml_read_string(&shader->name, node, "name"); 00584 xml_read_shader_graph(state, shader, node); 00585 state.scene->shaders.push_back(shader); 00586 } 00587 00588 /* Background */ 00589 00590 static void xml_read_background(const XMLReadState& state, pugi::xml_node node) 00591 { 00592 Shader *shader = state.scene->shaders[state.scene->default_background]; 00593 00594 xml_read_shader_graph(state, shader, node); 00595 } 00596 00597 /* Mesh */ 00598 00599 static Mesh *xml_add_mesh(Scene *scene, const Transform& tfm) 00600 { 00601 /* create mesh */ 00602 Mesh *mesh = new Mesh(); 00603 scene->meshes.push_back(mesh); 00604 00605 /* create object*/ 00606 Object *object = new Object(); 00607 object->mesh = mesh; 00608 object->tfm = tfm; 00609 scene->objects.push_back(object); 00610 00611 return mesh; 00612 } 00613 00614 static void xml_read_mesh(const XMLReadState& state, pugi::xml_node node) 00615 { 00616 /* add mesh */ 00617 Mesh *mesh = xml_add_mesh(state.scene, state.tfm); 00618 mesh->used_shaders.push_back(state.shader); 00619 00620 /* read state */ 00621 int shader = state.shader; 00622 bool smooth = state.smooth; 00623 00624 mesh->displacement_method = state.displacement_method; 00625 00626 /* read vertices and polygons, RIB style */ 00627 vector<float3> P; 00628 vector<int> verts, nverts; 00629 00630 xml_read_float3_array(P, node, "P"); 00631 xml_read_int_array(verts, node, "verts"); 00632 xml_read_int_array(nverts, node, "nverts"); 00633 00634 if(xml_equal_string(node, "subdivision", "catmull-clark")) { 00635 /* create subd mesh */ 00636 SubdMesh sdmesh; 00637 00638 /* create subd vertices */ 00639 for(size_t i = 0; i < P.size(); i++) 00640 sdmesh.add_vert(P[i]); 00641 00642 /* create subd faces */ 00643 int index_offset = 0; 00644 00645 for(size_t i = 0; i < nverts.size(); i++) { 00646 if(nverts[i] == 4) { 00647 int v0 = verts[index_offset + 0]; 00648 int v1 = verts[index_offset + 1]; 00649 int v2 = verts[index_offset + 2]; 00650 int v3 = verts[index_offset + 3]; 00651 00652 sdmesh.add_face(v0, v1, v2, v3); 00653 } 00654 else { 00655 for(int j = 0; j < nverts[i]-2; j++) { 00656 int v0 = verts[index_offset]; 00657 int v1 = verts[index_offset + j + 1]; 00658 int v2 = verts[index_offset + j + 2];; 00659 00660 sdmesh.add_face(v0, v1, v2); 00661 } 00662 } 00663 00664 index_offset += nverts[i]; 00665 } 00666 00667 /* finalize subd mesh */ 00668 sdmesh.link_boundary(); 00669 00670 /* subdivide */ 00671 DiagSplit dsplit; 00672 //dsplit.camera = state.scene->camera; 00673 //dsplit.dicing_rate = 5.0f; 00674 dsplit.dicing_rate = state.dicing_rate; 00675 xml_read_float(&dsplit.dicing_rate, node, "dicing_rate"); 00676 sdmesh.tesselate(&dsplit, false, mesh, shader, smooth); 00677 } 00678 else { 00679 /* create vertices */ 00680 mesh->verts = P; 00681 00682 /* create triangles */ 00683 int index_offset = 0; 00684 00685 for(size_t i = 0; i < nverts.size(); i++) { 00686 for(int j = 0; j < nverts[i]-2; j++) { 00687 int v0 = verts[index_offset]; 00688 int v1 = verts[index_offset + j + 1]; 00689 int v2 = verts[index_offset + j + 2]; 00690 00691 assert(v0 < (int)P.size()); 00692 assert(v1 < (int)P.size()); 00693 assert(v2 < (int)P.size()); 00694 00695 mesh->add_triangle(v0, v1, v2, shader, smooth); 00696 } 00697 00698 index_offset += nverts[i]; 00699 } 00700 } 00701 00702 /* temporary for test compatibility */ 00703 mesh->attributes.remove(Attribute::STD_VERTEX_NORMAL); 00704 } 00705 00706 /* Patch */ 00707 00708 static void xml_read_patch(const XMLReadState& state, pugi::xml_node node) 00709 { 00710 /* read patch */ 00711 Patch *patch = NULL; 00712 00713 vector<float3> P; 00714 xml_read_float3_array(P, node, "P"); 00715 00716 if(xml_equal_string(node, "type", "bilinear")) { 00717 /* bilinear patch */ 00718 if(P.size() == 4) { 00719 LinearQuadPatch *bpatch = new LinearQuadPatch(); 00720 00721 for(int i = 0; i < 4; i++) 00722 P[i] = transform(&state.tfm, P[i]); 00723 memcpy(bpatch->hull, &P[0], sizeof(bpatch->hull)); 00724 00725 patch = bpatch; 00726 } 00727 else 00728 fprintf(stderr, "Invalid number of control points for bilinear patch.\n"); 00729 } 00730 else if(xml_equal_string(node, "type", "bicubic")) { 00731 /* bicubic patch */ 00732 if(P.size() == 16) { 00733 BicubicPatch *bpatch = new BicubicPatch(); 00734 00735 for(int i = 0; i < 16; i++) 00736 P[i] = transform(&state.tfm, P[i]); 00737 memcpy(bpatch->hull, &P[0], sizeof(bpatch->hull)); 00738 00739 patch = bpatch; 00740 } 00741 else 00742 fprintf(stderr, "Invalid number of control points for bicubic patch.\n"); 00743 } 00744 else 00745 fprintf(stderr, "Unknown patch type.\n"); 00746 00747 if(patch) { 00748 /* add mesh */ 00749 Mesh *mesh = xml_add_mesh(state.scene, transform_identity()); 00750 00751 mesh->used_shaders.push_back(state.shader); 00752 00753 /* split */ 00754 DiagSplit dsplit; 00755 //dsplit.camera = state.scene->camera; 00756 //dsplit.dicing_rate = 5.0f; 00757 dsplit.dicing_rate = state.dicing_rate; 00758 xml_read_float(&dsplit.dicing_rate, node, "dicing_rate"); 00759 dsplit.split_quad(mesh, patch, state.shader, state.smooth); 00760 00761 delete patch; 00762 00763 /* temporary for test compatibility */ 00764 mesh->attributes.remove(Attribute::STD_VERTEX_NORMAL); 00765 } 00766 } 00767 00768 /* Light */ 00769 00770 static void xml_read_light(const XMLReadState& state, pugi::xml_node node) 00771 { 00772 Light *light = new Light(); 00773 light->shader = state.shader; 00774 xml_read_float3(&light->co, node, "P"); 00775 light->co = transform(&state.tfm, light->co); 00776 00777 state.scene->lights.push_back(light); 00778 } 00779 00780 /* Transform */ 00781 00782 static void xml_read_transform(pugi::xml_node node, Transform& tfm) 00783 { 00784 if(node.attribute("matrix")) { 00785 vector<float> matrix; 00786 if(xml_read_float_array(matrix, node, "matrix") && matrix.size() == 16) 00787 tfm = tfm * transform_transpose((*(Transform*)&matrix[0])); 00788 } 00789 00790 if(node.attribute("translate")) { 00791 float3 translate = make_float3(0.0f, 0.0f, 0.0f); 00792 xml_read_float3(&translate, node, "translate"); 00793 tfm = tfm * transform_translate(translate); 00794 } 00795 00796 if(node.attribute("rotate")) { 00797 float4 rotate = make_float4(0.0f, 0.0f, 0.0f, 0.0f); 00798 xml_read_float4(&rotate, node, "rotate"); 00799 tfm = tfm * transform_rotate(rotate.x*M_PI/180.0f, make_float3(rotate.y, rotate.z, rotate.w)); 00800 } 00801 00802 if(node.attribute("scale")) { 00803 float3 scale = make_float3(0.0f, 0.0f, 0.0f); 00804 xml_read_float3(&scale, node, "scale"); 00805 tfm = tfm * transform_scale(scale); 00806 } 00807 } 00808 00809 /* State */ 00810 00811 static void xml_read_state(XMLReadState& state, pugi::xml_node node) 00812 { 00813 /* read shader */ 00814 string shadername; 00815 00816 if(xml_read_string(&shadername, node, "shader")) { 00817 int i = 0; 00818 bool found = false; 00819 00820 foreach(Shader *shader, state.scene->shaders) { 00821 if(shader->name == shadername) { 00822 state.shader = i; 00823 found = true; 00824 break; 00825 } 00826 00827 i++; 00828 } 00829 00830 if(!found) 00831 fprintf(stderr, "Unknown shader \"%s\".\n", shadername.c_str()); 00832 } 00833 00834 xml_read_float(&state.dicing_rate, node, "dicing_rate"); 00835 00836 /* read smooth/flat */ 00837 if(xml_equal_string(node, "interpolation", "smooth")) 00838 state.smooth = true; 00839 else if(xml_equal_string(node, "interpolation", "flat")) 00840 state.smooth = false; 00841 00842 /* read displacement method */ 00843 if(xml_equal_string(node, "displacement_method", "true")) 00844 state.displacement_method = Mesh::DISPLACE_TRUE; 00845 else if(xml_equal_string(node, "displacement_method", "bump")) 00846 state.displacement_method = Mesh::DISPLACE_BUMP; 00847 else if(xml_equal_string(node, "displacement_method", "both")) 00848 state.displacement_method = Mesh::DISPLACE_BOTH; 00849 } 00850 00851 /* Scene */ 00852 00853 static void xml_read_include(const XMLReadState& state, const string& src); 00854 00855 static void xml_read_scene(const XMLReadState& state, pugi::xml_node scene_node) 00856 { 00857 for(pugi::xml_node node = scene_node.first_child(); node; node = node.next_sibling()) { 00858 if(string_iequals(node.name(), "film")) { 00859 xml_read_film(state, node); 00860 } 00861 else if(string_iequals(node.name(), "integrator")) { 00862 xml_read_integrator(state, node); 00863 } 00864 else if(string_iequals(node.name(), "camera")) { 00865 xml_read_camera(state, node); 00866 } 00867 else if(string_iequals(node.name(), "shader")) { 00868 xml_read_shader(state, node); 00869 } 00870 else if(string_iequals(node.name(), "background")) { 00871 xml_read_background(state, node); 00872 } 00873 else if(string_iequals(node.name(), "mesh")) { 00874 xml_read_mesh(state, node); 00875 } 00876 else if(string_iequals(node.name(), "patch")) { 00877 xml_read_patch(state, node); 00878 } 00879 else if(string_iequals(node.name(), "light")) { 00880 xml_read_light(state, node); 00881 } 00882 else if(string_iequals(node.name(), "transform")) { 00883 XMLReadState substate = state; 00884 00885 xml_read_transform(node, substate.tfm); 00886 xml_read_scene(substate, node); 00887 } 00888 else if(string_iequals(node.name(), "state")) { 00889 XMLReadState substate = state; 00890 00891 xml_read_state(substate, node); 00892 xml_read_scene(substate, node); 00893 } 00894 else if(string_iequals(node.name(), "include")) { 00895 string src; 00896 00897 if(xml_read_string(&src, node, "src")) 00898 xml_read_include(state, src); 00899 } 00900 else 00901 fprintf(stderr, "Unknown node \"%s\".\n", node.name()); 00902 } 00903 } 00904 00905 /* Include */ 00906 00907 static void xml_read_include(const XMLReadState& state, const string& src) 00908 { 00909 /* open XML document */ 00910 pugi::xml_document doc; 00911 pugi::xml_parse_result parse_result; 00912 00913 string path = path_join(state.base, src); 00914 parse_result = doc.load_file(path.c_str()); 00915 00916 if(parse_result) { 00917 XMLReadState substate = state; 00918 substate.base = path_dirname(path); 00919 00920 xml_read_scene(substate, doc); 00921 } 00922 else 00923 fprintf(stderr, "%s read error: %s\n", src.c_str(), parse_result.description()); 00924 } 00925 00926 /* File */ 00927 00928 void xml_read_file(Scene *scene, const char *filepath) 00929 { 00930 XMLReadState state; 00931 00932 state.scene = scene; 00933 state.tfm = transform_identity(); 00934 state.shader = scene->default_surface; 00935 state.smooth = false; 00936 state.dicing_rate = 0.1f; 00937 state.base = path_dirname(filepath); 00938 00939 xml_read_include(state, path_filename(filepath)); 00940 00941 scene->params.bvh_type = SceneParams::BVH_STATIC; 00942 } 00943 00944 CCL_NAMESPACE_END 00945