Skip to content

Commit

Permalink
lib+blender: Implement vec->color node, and partially hook it up
Browse files Browse the repository at this point in the history
  • Loading branch information
vkoskiv committed Jul 2, 2024
1 parent b83fe33 commit 70439b4
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 8 deletions.
2 changes: 1 addition & 1 deletion bindings/blender_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ def sync_scene(self, depsgraph):
for bl_mat in me.materials:
if not bl_mat:
print("Huh, array contains NoneType?")
cr_mat_set.add(None, bl_mat.name)
cr_mat_set.add(None, "MissingMaterial")
elif bl_mat.use_nodes:
print("Fetching material {}".format(bl_mat.name))
if bl_mat.name not in cr_materials:
Expand Down
21 changes: 21 additions & 0 deletions bindings/nodes/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@ def parse_color(input, group_inputs):
return parse_color(input.links[0].from_node, group_inputs)
vals = input.default_value
return NodeColorConstant(cr_color(vals[0], vals[1], vals[2], vals[3]))
case 'NodeSocketVector':
if input.is_linked:
if input.links[0].from_node.bl_idname == 'NodeGroupInput':
return group_inputs[input.links[0].from_socket.name]
return NodeColorVecToColor(parse_vector(input.links[0].from_node, group_inputs))
vec = input.default_value
return NodeColorVecToColor(NodeVectorConstant(vec))
case 'ShaderNodeTexImage':
if input.image is None:
print("No image set in blender image texture {}".format(input.name))
Expand Down Expand Up @@ -257,6 +264,13 @@ def parse_value(input, group_inputs):
return parse_subtree(input, ['NodeSocketFloat', 'NodeSocketfloatFactor'], parse_value, group_inputs, NodeValueConstant(0.0))
case 'NodeReroute':
return parse_value(input.inputs[0], group_inputs)
case 'NodeSocketColor':
if input.is_linked:
if input.links[0].from_node.bl_idname == 'NodeGroupInput':
return group_inputs[input.links[0].from_socket.name]
return NodeValueGrayscale(parse_color(input.links[0].from_node, group_inputs))
vals = input.default_value
return NodeValueGrayscale(NodeColorConstant(cr_color(vals[0], vals[1], vals[2], vals[3])))
case 'NodeSocketFloat':
if input.is_linked:
if input.links[0].from_node.bl_idname == 'NodeGroupInput':
Expand Down Expand Up @@ -382,6 +396,13 @@ def parse_vector(input, group_inputs):
return parse_subtree(input, ['NodeSocketVector'], parse_vector, group_inputs, zero_vec)
case 'NodeReroute':
return parse_vector(input.inputs[0], group_inputs)
case 'NodeSocketColor':
if input.is_linked:
if input.links[0].from_node.bl_idname == 'NodeGroupInput':
return group_inputs[input.links[0].from_socket.name]
return NodeVectorFromColor(parse_color(input.links[0].from_node, group_inputs))
vals = input.default_value
return NodeVectorFromColor(NodeColorConstant(cr_color(vals[0], vals[1], vals[2], vals[3])))
case 'NodeSocketVector':
if input.is_linked:
if input.links[0].from_node.bl_idname == 'NodeGroupInput':
Expand Down
28 changes: 21 additions & 7 deletions bindings/nodes/vector.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,20 +65,27 @@ class _vector_arg_vec_mix(ct.Structure):
("factor", ct.POINTER(_value))
]

class _vector_arg_from_color(ct.Structure):
_fields_ = [
("C", ct.POINTER(_color))
]

class _vector_arg(ct.Union):
_fields_ = [
("constant", cr_vector),
("vecmath", _vector_arg_vecmath),
("vec_mix", _vector_arg_vec_mix)
("vec_mix", _vector_arg_vec_mix),
("vec_from_color", _vector_arg_from_color)
]

class _vector_type(IntEnum):
unknown = 0
constant = 1
normal = 2
uv = 3
vecmath = 4
mix = 5
unknown = 0
constant = 1
normal = 2
uv = 3
vecmath = 4
mix = 5
from_color = 6

_vector._anonymous_ = ("arg",)
_vector._fields_ = [
Expand Down Expand Up @@ -121,6 +128,13 @@ def __init__(self, a, b, c, f, op):
self.cr_struct.type = _vector_type.vecmath
self.cr_struct.vecmath = _vector_arg_vecmath(self.a.castref(), self.b.castref(), self.c.castref(), self.f.castref(), self.op)

class NodeVectorFromColor(NodeVectorBase):
def __init__(self, c):
super().__init__()
self.c = c
self.cr_struct.type =_vector_type.from_color
self.cr_struct.from_color =_vector_arg_from_color(self.c.castref())

class NodeVectorVecMix(NodeVectorBase):
def __init__(self, a, b, factor):
super().__init__()
Expand Down
5 changes: 5 additions & 0 deletions include/c-ray/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ struct cr_vector_node {
cr_vec_uv,
cr_vec_vecmath,
cr_vec_mix,
cr_vec_from_color,
} type;

// TODO: Maybe express vectorValue vec/coord/float union a bit better here?
Expand All @@ -293,6 +294,10 @@ struct cr_vector_node {
struct cr_value_node *factor;
} vec_mix;

struct cr_vec_from_color_params {
struct cr_color_node *C;
} vec_from_color;

} arg;
};

Expand Down
9 changes: 9 additions & 0 deletions src/common/node_parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,12 @@ struct cr_vector_node *cr_vector_node_build(const struct cJSON *node) {
}
});
}
if (stringEquals(type->valuestring, "vec_from_color")) {
return vecn_alloc((struct cr_vector_node){
.type = cr_vec_from_color,
.arg.vec_from_color.C = cr_color_node_build(cJSON_GetObjectItem(node, "c"))
});
}
return NULL;
}

Expand All @@ -625,6 +631,9 @@ void cr_vector_node_free(struct cr_vector_node *d) {
cr_vector_node_free(d->arg.vec_mix.B);
cr_value_node_free(d->arg.vec_mix.factor);
break;
case cr_vec_from_color:
cr_color_node_free(d->arg.vec_from_color.C);
break;
}
free(d);
}
Expand Down
46 changes: 46 additions & 0 deletions src/lib/nodes/vectornode.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,50 @@ const struct vectorNode *newConstantUV(const struct node_storage *s, const struc
});
}


struct color_to_vec {
struct vectorNode node;
const struct colorNode *c;
};

static bool compare_color_to_vec(const void *A, const void *B) {
const struct color_to_vec *this = A;
const struct color_to_vec *other = B;
return this->c == other->c;
}

static uint32_t hash_color_to_vec(const void *p) {
const struct color_to_vec *this = p;
uint32_t h = hashInit();
h = hashBytes(h, &this->c, sizeof(this->c));
return h;
}

static void dump_color_to_vec(const void *node, char *dumpbuf, int bufsize) {
struct color_to_vec *this = (struct color_to_vec *)node;
char C[DUMPBUF_SIZE / 2] = "";
if (this->c->base.dump) this->c->base.dump(this->c, C, sizeof(C));
snprintf(dumpbuf, bufsize, "color_to_vec { %s }", C);
}

static union vector_value eval_color_to_vec(const struct vectorNode *node, sampler *sampler, const struct hitRecord *record) {
(void)record;
(void)sampler;
struct color_to_vec *this = (struct color_to_vec *)node;
const struct color c = this->c->eval(this->c, sampler, record);
return (union vector_value){ .v = { c.red, c.green, c.blue } };
}

const struct vectorNode *new_color_to_vec(const struct node_storage *s, const struct colorNode *c) {
HASH_CONS(s->node_table, hash_color_to_vec, struct color_to_vec, {
.c = c ? c : newConstantTexture(s, g_white_color),
.node = {
.eval = eval_color_to_vec,
.base = { .compare = compare_color_to_vec, .dump = dump_color_to_vec }
}
});
}

const struct vectorNode *build_vector_node(struct cr_scene *s_ext, const struct cr_vector_node *desc) {
if (!s_ext || !desc) return NULL;
struct world *scene = (struct world *)s_ext;
Expand All @@ -123,6 +167,8 @@ const struct vectorNode *build_vector_node(struct cr_scene *s_ext, const struct
build_vector_node(s_ext, desc->arg.vec_mix.A),
build_vector_node(s_ext, desc->arg.vec_mix.B),
build_value_node(s_ext, desc->arg.vec_mix.factor));
case cr_vec_from_color:
return new_color_to_vec(&s, build_color_node(s_ext, desc->arg.vec_from_color.C));
default:
return NULL;
};
Expand Down
1 change: 1 addition & 0 deletions src/lib/nodes/vectornode.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,6 @@ struct vectorNode {

const struct vectorNode *newConstantVector(const struct node_storage *storage, struct vector vector);
const struct vectorNode *newConstantUV(const struct node_storage *s, const struct coord c);
const struct vectorNode *new_color_to_vec(const struct node_storage *s, const struct colorNode *c);

const struct vectorNode *build_vector_node(struct cr_scene *s_ext, const struct cr_vector_node *desc);
4 changes: 4 additions & 0 deletions src/lib/protocol/protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,10 @@ static cJSON *serialize_vector_node(const struct cr_vector_node *in) {
cJSON_AddItemToObject(out, "b", serialize_vector_node(in->arg.vec_mix.B));
cJSON_AddItemToObject(out, "f", serialize_value_node(in->arg.vec_mix.factor));
break;
case cr_vec_from_color:
cJSON_AddStringToObject(out, "type", "vec_from_color");
cJSON_AddItemToObject(out, "c", serialize_color_node(in->arg.vec_from_color.C));
break;
}
return out;
}
Expand Down

0 comments on commit 70439b4

Please sign in to comment.