53static bool xml_read_int(
int *value,
const xml_node node,
const char *name)
55 const xml_attribute attr = node.attribute(name);
58 *value = atoi(attr.value());
67 const xml_attribute attr = node.attribute(name);
73 for (
const string &token : tokens) {
74 value.push_back(atoi(token.c_str()));
83static bool xml_read_float(
float *value,
const xml_node node,
const char *name)
85 const xml_attribute attr = node.attribute(name);
88 *value = (float)atof(attr.value());
97 const xml_attribute attr = node.attribute(name);
103 for (
const string &token : tokens) {
104 value.push_back((
float)atof(token.c_str()));
154 const xml_attribute attr = node.attribute(name);
166 const xml_attribute attr = node.attribute(name);
186 cam->set_full_width(width);
187 cam->set_full_height(height);
189 xml_read_node(
state, cam, node);
191 cam->set_matrix(
state.tfm);
202 AlembicProcedural *proc =
state.scene->create_node<AlembicProcedural>();
203 xml_read_node(
state, proc, graph_node);
205 for (xml_node node = graph_node.first_child(); node; node = node.next_sibling()) {
209 const ustring object_path(path, 0);
210 AlembicObject *
object = proc->get_or_create_object(object_path);
214 object->set_used_shaders(used_shaders);
225 xml_read_node(
state, shader, graph_node);
230 XMLReader graph_reader;
231 graph_reader.node_map[ustring(
"output")] = graph->output();
233 for (xml_node node = graph_node.first_child(); node; node = node.next_sibling()) {
234 ustring node_name(node.name());
236 if (node_name ==
"connect") {
241 string_split(from_tokens, node.attribute(
"from").value());
244 if (from_tokens.size() == 2 && to_tokens.size() == 2) {
245 const ustring from_node_name(from_tokens[0]);
246 const ustring from_socket_name(from_tokens[1]);
247 const ustring to_node_name(to_tokens[0]);
248 const ustring to_socket_name(to_tokens[1]);
254 if (graph_reader.node_map.find(from_node_name) != graph_reader.node_map.end()) {
265 "Unknown output socket name \"%s\" on \"%s\".\n",
266 from_node_name.c_str(),
267 from_socket_name.c_str());
271 fprintf(stderr,
"Unknown shader node name \"%s\".\n", from_node_name.c_str());
274 if (graph_reader.node_map.find(to_node_name) != graph_reader.node_map.end()) {
278 if (
string_iequals(
in->socket_type.name.string(), to_socket_name.string())) {
285 "Unknown input socket name \"%s\" on \"%s\".\n",
286 to_socket_name.c_str(),
287 to_node_name.c_str());
291 fprintf(stderr,
"Unknown shader node name \"%s\".\n", to_node_name.c_str());
300 fprintf(stderr,
"Invalid from or to value for connect node.\n");
309 if (node_name ==
"osl_shader") {
313 std::string filepath;
320 snode = OSLShaderManager::osl_node(graph.get(),
state.scene, filepath,
"");
323 fprintf(stderr,
"Failed to create OSL node from \"%s\".\n", filepath.c_str());
328 fprintf(stderr,
"OSL node missing \"src\" attribute.\n");
333 fprintf(stderr,
"OSL node without using --shadingsys osl.\n");
341 if (node_name ==
"background") {
342 node_name =
"background_shader";
348 fprintf(stderr,
"Unknown shader node \"%s\".\n", node.name());
352 fprintf(stderr,
"Node type \"%s\" is not a shader node.\n", node_type->
name.c_str());
355 if (node_type->
create ==
nullptr) {
356 fprintf(stderr,
"Can't create abstract node type \"%s\".\n", node_type->
name.c_str());
360 snode = graph->create_node(node_type);
363 xml_read_node(graph_reader, snode, node);
365 if (node_name ==
"image_texture") {
367 const ustring filename(
path_join(
state.base, img->get_filename().string()));
368 img->set_filename(filename);
370 else if (node_name ==
"environment_texture") {
372 const ustring filename(
path_join(
state.base, env->get_filename().string()));
373 env->set_filename(filename);
392 xml_read_node(
state,
state.scene->background, node);
403 if (
object && object->get_geometry()->is_mesh()) {
405 object->set_tfm(tfm);
406 Geometry *geometry =
object->get_geometry();
407 return static_cast<Mesh *
>(geometry);
415 object->set_geometry(mesh);
416 object->set_tfm(tfm);
427 mesh->set_used_shaders(used_shaders);
430 const int shader = 0;
431 const bool smooth =
state.smooth;
459 mesh->set_verts(P_array);
461 size_t num_triangles = 0;
462 for (
size_t i = 0;
i < nverts.size();
i++) {
463 num_triangles += nverts[
i] - 2;
465 mesh->
reserve_mesh(mesh->get_verts().size(), num_triangles);
468 int index_offset = 0;
470 for (
size_t i = 0;
i < nverts.size();
i++) {
471 for (
int j = 0; j < nverts[
i] - 2; j++) {
472 const int v0 =
verts[index_offset];
473 const int v1 =
verts[index_offset + j + 1];
474 const int v2 =
verts[index_offset + j + 2];
483 index_offset += nverts[
i];
507 for (
size_t i = 0;
i < nverts.size();
i++) {
508 for (
int j = 0; j < nverts[
i] - 2; j++) {
509 const int v0 = index_offset;
510 const int v1 = index_offset + j + 1;
511 const int v2 = index_offset + j + 2;
513 assert(v0 * 2 + 1 < (
int)UV.size());
514 assert(v1 * 2 + 1 < (
int)UV.size());
515 assert(
v2 * 2 + 1 < (
int)UV.size());
517 fdata[0] =
make_float2(UV[v0 * 2], UV[v0 * 2 + 1]);
518 fdata[1] =
make_float2(UV[v1 * 2], UV[v1 * 2 + 1]);
523 index_offset += nverts[
i];
534 for (
size_t i = 0;
i < nverts.size();
i++) {
535 for (
int j = 0; j < nverts[
i] - 2; j++) {
536 const int v0 = index_offset;
537 const int v1 = index_offset + j + 1;
538 const int v2 = index_offset + j + 2;
540 assert(v0 * 3 + 2 < (
int)
T.size());
541 assert(v1 * 3 + 2 < (
int)
T.size());
549 index_offset += nverts[
i];
560 for (
size_t i = 0;
i < nverts.size();
i++) {
561 for (
int j = 0; j < nverts[
i] - 2; j++) {
562 const int v0 = index_offset;
563 const int v1 = index_offset + j + 1;
564 const int v2 = index_offset + j + 2;
566 assert(v0 < (
int)TS.size());
567 assert(v1 < (
int)TS.size());
575 index_offset += nverts[
i];
581 mesh->set_verts(P_array);
583 size_t num_corners = 0;
584 for (
size_t i = 0;
i < nverts.size();
i++) {
585 num_corners += nverts[
i];
590 int index_offset = 0;
592 for (
size_t i = 0;
i < nverts.size();
i++) {
594 index_offset += nverts[
i];
605 for (
size_t i = 0;
i < nverts.size();
i++) {
606 for (
int j = 0; j < nverts[
i]; j++) {
613 float dicing_rate =
state.dicing_rate;
615 dicing_rate = std::max(0.1f, dicing_rate);
617 mesh->set_subd_dicing_rate(dicing_rate);
618 mesh->set_subd_objecttoworld(
state.tfm);
625 std::copy_n(mesh->get_verts().data(), mesh->get_verts().size(), attr->
data_float3());
640 light->set_used_shaders(used_shaders);
644 object->set_tfm(
state.tfm);
646 object->set_geometry(light);
648 xml_read_node(
state, light, node);
655 if (node.attribute(
"matrix")) {
663 if (node.attribute(
"translate")) {
669 if (node.attribute(
"rotate")) {
675 if (node.attribute(
"scale")) {
693 if (shader->
name == shadername) {
694 state.shader = shader;
701 fprintf(stderr,
"Unknown shader \"%s\".\n", shadername.c_str());
712 if (object->
name == objectname) {
713 state.object = object;
720 fprintf(stderr,
"Unknown object \"%s\".\n", objectname.c_str());
731 state.smooth =
false;
746 object->set_geometry(mesh);
747 object->set_tfm(
state.tfm);
749 xml_read_node(
state,
object, node);
758 for (xml_node node = scene_node.first_child(); node; node = node.next_sibling()) {
760 xml_read_node(
state,
state.scene->film, node);
763 xml_read_node(
state,
state.scene->integrator, node);
807 xml_read_alembic(
state, node);
811 fprintf(stderr,
"Unknown node \"%s\".\n", node.name());
822 xml_parse_result parse_result;
825 parse_result = doc.load_file(path.c_str());
831 const xml_node cycles = doc.child(
"cycles");
835 fprintf(stderr,
"%s read error: %s\n", src.c_str(), parse_result.description());
849 state.smooth =
false;
850 state.dicing_rate = 1.0f;
ATTR_WARN_UNUSED_RESULT const BMVert * v2
Attribute * add(ustring name, const TypeDesc type, AttributeElement element)
bool need_attribute(Scene *scene, AttributeStandard std)
unique_ptr_vector< ShaderInput > inputs
unique_ptr_vector< ShaderOutput > outputs
void set_graph(unique_ptr< ShaderGraph > &&graph)
void tag_update(Scene *scene)
void push_back_slow(const T &t)
ccl_device_inline Transform projection_to_transform(const ProjectionTransform &a)
ccl_device_inline ProjectionTransform projection_transpose(const ProjectionTransform a)
static void xml_read_object(XMLReadState &state, const xml_node node)
static bool xml_read_float3(float3 *value, const xml_node node, const char *name)
static bool xml_read_int_array(vector< int > &value, const xml_node node, const char *name)
static bool xml_read_float(float *value, const xml_node node, const char *name)
static void xml_read_include(XMLReadState &state, const string &src)
static void xml_read_background(XMLReadState &state, const xml_node node)
static bool xml_read_string(string *str, const xml_node node, const char *name)
static void xml_read_transform(const xml_node node, Transform &tfm)
static bool xml_read_int(int *value, const xml_node node, const char *name)
static Mesh * xml_add_mesh(Scene *scene, const Transform &tfm, Object *object)
void xml_read_file(Scene *scene, const char *filepath)
static void xml_read_scene(XMLReadState &state, const xml_node scene_node)
static bool xml_read_float4(float4 *value, const xml_node node, const char *name)
static void xml_read_state(XMLReadState &state, const xml_node node)
static void xml_read_shader_graph(XMLReadState &state, Shader *shader, const xml_node graph_node)
static bool xml_read_float_array(vector< float > &value, const xml_node node, const char *name)
static void xml_read_camera(XMLReadState &state, const xml_node node)
static void xml_read_light(XMLReadState &state, const xml_node node)
static bool xml_equal_string(const xml_node node, const char *name, const char *value)
static void xml_read_mesh(const XMLReadState &state, const xml_node node)
static bool xml_read_float3_array(vector< float3 > &value, const xml_node node, const char *name)
static void xml_read_shader(XMLReadState &state, const xml_node node)
#define CCL_NAMESPACE_END
VecBase< float, 4 > float4
#define assert(assertion)
@ ATTR_STD_UV_TANGENT_SIGN
@ PATH_RAY_ALL_VISIBILITY
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()
CCL_NAMESPACE_BEGIN ccl_device_inline float4 zero_float4()
static void rotate(float new_co[3], float a, const float ax[3], const float co[3])
string path_dirname(const string &path)
bool path_is_relative(const string &path)
string path_join(const string &dir, const string &file)
string path_filename(const string &path)
bool string_iequals(const string &a, const string &b)
void string_split(vector< string > &tokens, const string &str, const string &separators, bool skip_empty_tokens)
static const char * standard_name(AttributeStandard std)
void update(Scene *scene)
void add_triangle(const int v0, const int v1, const int v2, const int shader, bool smooth)
AttributeSet subd_attributes
void reserve_mesh(const int numverts, const int numtris)
@ SUBDIVISION_CATMULL_CLARK
void add_subd_face(const int *corners, const int num_corners, const int shader_, bool smooth_)
void reserve_subd_faces(const int numfaces, const int numcorners)
static const NodeType * find(ustring name)
T * create_node(Args &&...)=delete