[Bf-blender-cvs] [2221389d6e8] master: Bake: vertex color baking support for Cycles
Brecht Van Lommel
noreply at git.blender.org
Thu Dec 24 12:41:48 CET 2020
Commit: 2221389d6e8e799ae1a001e4a3457fa5c3fd90fb
Author: Brecht Van Lommel
Date: Wed Dec 23 21:03:00 2020 +0100
Branches: master
https://developer.blender.org/rB2221389d6e8e799ae1a001e4a3457fa5c3fd90fb
Bake: vertex color baking support for Cycles
In the Bake > Output panel, there is now a choice between Image Textures and
Vertex Colors. The active vertex color layer is used for baking. This works
with both existing per-corner and sculpt per-vertex vertex colors.
===================================================================
M intern/cycles/blender/addon/ui.py
M source/blender/editors/object/object_bake_api.c
M source/blender/makesdna/DNA_scene_types.h
M source/blender/makesrna/RNA_enum_types.h
M source/blender/makesrna/intern/rna_scene.c
===================================================================
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 1bddacbb7a0..579f0c1b040 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -1969,9 +1969,11 @@ class CYCLES_RENDER_PT_bake_output(CyclesButtonsPanel, Panel):
if rd.bake_type == 'DISPLACEMENT':
layout.prop(rd, "use_bake_lores_mesh")
else:
+ layout.prop(cbk, "target")
- layout.prop(cbk, "margin")
- layout.prop(cbk, "use_clear", text="Clear Image")
+ if cbk.target == 'IMAGE_TEXTURES':
+ layout.prop(cbk, "margin")
+ layout.prop(cbk, "use_clear", text="Clear Image")
class CYCLES_RENDER_PT_debug(CyclesButtonsPanel, Panel):
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index 2dba883d866..53dc10f8f15 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -83,6 +83,8 @@ typedef struct BakeAPIRender {
ListBase selected_objects;
/* Baking settings. */
+ eBakeTarget target;
+
eScenePassType pass_type;
int pass_filter;
int margin;
@@ -416,7 +418,10 @@ static bool is_noncolor_pass(eScenePassType pass_type)
}
/* if all is good tag image and return true */
-static bool bake_object_check(ViewLayer *view_layer, Object *ob, ReportList *reports)
+static bool bake_object_check(ViewLayer *view_layer,
+ Object *ob,
+ const eBakeTarget target,
+ ReportList *reports)
{
Base *base = BKE_view_layer_base_find(view_layer, ob);
@@ -442,67 +447,69 @@ static bool bake_object_check(ViewLayer *view_layer, Object *ob, ReportList *rep
return false;
}
- for (int i = 0; i < ob->totcol; i++) {
- bNodeTree *ntree = NULL;
- bNode *node = NULL;
- const int mat_nr = i + 1;
- Image *image;
- ED_object_get_active_image(ob, mat_nr, &image, NULL, &node, &ntree);
+ if (target == R_BAKE_TARGET_IMAGE_TEXTURES) {
+ for (int i = 0; i < ob->totcol; i++) {
+ bNodeTree *ntree = NULL;
+ bNode *node = NULL;
+ const int mat_nr = i + 1;
+ Image *image;
+ ED_object_get_active_image(ob, mat_nr, &image, NULL, &node, &ntree);
+
+ if (image) {
+ ImBuf *ibuf;
+
+ if (node) {
+ if (BKE_node_is_connected_to_output(ntree, node)) {
+ /* we don't return false since this may be a false positive
+ * this can't be RPT_ERROR though, otherwise it prevents
+ * multiple highpoly objects to be baked at once */
+ BKE_reportf(reports,
+ RPT_INFO,
+ "Circular dependency for image \"%s\" from object \"%s\"",
+ image->id.name + 2,
+ ob->id.name + 2);
+ }
+ }
- if (image) {
- ImBuf *ibuf;
+ void *lock;
+ ibuf = BKE_image_acquire_ibuf(image, NULL, &lock);
- if (node) {
- if (BKE_node_is_connected_to_output(ntree, node)) {
- /* we don't return false since this may be a false positive
- * this can't be RPT_ERROR though, otherwise it prevents
- * multiple highpoly objects to be baked at once */
+ if (ibuf) {
+ BKE_image_release_ibuf(image, ibuf, lock);
+ }
+ else {
BKE_reportf(reports,
- RPT_INFO,
- "Circular dependency for image \"%s\" from object \"%s\"",
+ RPT_ERROR,
+ "Uninitialized image \"%s\" from object \"%s\"",
image->id.name + 2,
ob->id.name + 2);
- }
- }
-
- void *lock;
- ibuf = BKE_image_acquire_ibuf(image, NULL, &lock);
- if (ibuf) {
- BKE_image_release_ibuf(image, ibuf, lock);
- }
- else {
- BKE_reportf(reports,
- RPT_ERROR,
- "Uninitialized image \"%s\" from object \"%s\"",
- image->id.name + 2,
- ob->id.name + 2);
-
- BKE_image_release_ibuf(image, ibuf, lock);
- return false;
- }
- }
- else {
- Material *mat = BKE_object_material_get(ob, mat_nr);
- if (mat != NULL) {
- BKE_reportf(reports,
- RPT_INFO,
- "No active image found in material \"%s\" (%d) for object \"%s\"",
- mat->id.name + 2,
- i,
- ob->id.name + 2);
+ BKE_image_release_ibuf(image, ibuf, lock);
+ return false;
+ }
}
else {
- BKE_reportf(reports,
- RPT_INFO,
- "No active image found in material slot (%d) for object \"%s\"",
- i,
- ob->id.name + 2);
+ Material *mat = BKE_object_material_get(ob, mat_nr);
+ if (mat != NULL) {
+ BKE_reportf(reports,
+ RPT_INFO,
+ "No active image found in material \"%s\" (%d) for object \"%s\"",
+ mat->id.name + 2,
+ i,
+ ob->id.name + 2);
+ }
+ else {
+ BKE_reportf(reports,
+ RPT_INFO,
+ "No active image found in material slot (%d) for object \"%s\"",
+ i,
+ ob->id.name + 2);
+ }
+ continue;
}
- continue;
- }
- image->id.tag |= LIB_TAG_DOIT;
+ image->id.tag |= LIB_TAG_DOIT;
+ }
}
return true;
@@ -576,7 +583,8 @@ static bool bake_objects_check(Main *bmain,
Object *ob,
ListBase *selected_objects,
ReportList *reports,
- const bool is_selected_to_active)
+ const bool is_selected_to_active,
+ const eBakeTarget target)
{
CollectionPointerLink *link;
@@ -586,7 +594,7 @@ static bool bake_objects_check(Main *bmain,
if (is_selected_to_active) {
int tot_objects = 0;
- if (!bake_object_check(view_layer, ob, reports)) {
+ if (!bake_object_check(view_layer, ob, target, reports)) {
return false;
}
@@ -620,7 +628,7 @@ static bool bake_objects_check(Main *bmain,
}
for (link = selected_objects->first; link; link = link->next) {
- if (!bake_object_check(view_layer, link->ptr.data, reports)) {
+ if (!bake_object_check(view_layer, link->ptr.data, target, reports)) {
return false;
}
}
@@ -895,6 +903,161 @@ static bool bake_targets_output_external(const BakeAPIRender *bkr,
return all_ok;
}
+/* Vertex Color Bake Targets */
+
+static bool bake_targets_init_vertex_colors(BakeTargets *targets, Object *ob, ReportList *reports)
+{
+ if (ob->type != OB_MESH) {
+ BKE_report(
+ reports, RPT_ERROR, "Vertex color baking not support with object types other than mesh");
+ return false;
+ }
+
+ Mesh *me = ob->data;
+ MPropCol *mcol = CustomData_get_layer(&me->vdata, CD_PROP_COLOR);
+ MLoopCol *mloopcol = CustomData_get_layer(&me->ldata, CD_MLOOPCOL);
+ if (mcol == NULL && mloopcol == NULL) {
+ BKE_report(reports, RPT_ERROR, "No vertex colors layer found to bake to");
+ return false;
+ }
+
+ targets->images = MEM_callocN(sizeof(BakeImage), "BakeTargets.images");
+ targets->num_images = 1;
+
+ targets->material_to_image = MEM_callocN(sizeof(int) * ob->totcol,
+ "BakeTargets.material_to_image");
+ targets->num_materials = ob->totcol;
+
+ BakeImage *bk_image = &targets->images[0];
+ bk_image->width = me->totvert;
+ bk_image->height = 1;
+ bk_image->offset = 0;
+ bk_image->image = NULL;
+
+ targets->num_pixels = bk_image->width * bk_image->height;
+
+ return true;
+}
+
+static void bake_targets_populate_pixels_vertex_colors(BakeTargets *targets,
+ Mesh *me,
+ BakePixel *pixel_array)
+{
+ const int num_pixels = targets->num_pixels;
+
+ /* Initialize blank pixels. */
+ for (int i = 0; i < num_pixels; i++) {
+ BakePixel *pixel = &pixel_array[i];
+
+ pixel->primitive_id = -1;
+ pixel->object_id = 0;
+ pixel->du_dx = 0.0f;
+ pixel->du_dy = 0.0f;
+ pixel->dv_dx = 0.0f;
+ pixel->dv_dy = 0.0f;
+ pixel->uv[0] = 0.0f;
+ pixel->uv[1] = 0.0f;
+ }
+
+ /* Populate through adjacent triangles, first triangle wins. */
+ const int tottri = poly_to_tri_count(me->totpoly, me->totloop);
+ MLoopTri *looptri = MEM_mallocN(sizeof(*looptri) * tottri, __func__);
+
+ BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, looptri);
+
+ for (int i = 0; i < tottri; i++) {
+ const MLoopTri *lt = &looptri[i];
+
+ for (int j = 0; j < 3; j++) {
+ const unsigned int v = me->mloop[lt->tri[j]].v;
+ BakePixel *pixel = &pixel_array[v];
+
+ if (pixel->primitive_id != -1) {
+ continue;
+ }
+
+ pixel->primitive_id = i;
+
+ /* Barycentric coordinates, nudged a bit to avoid precision issues that
+ * may happen when exactly at the vertex coordinate. */
+ if (j == 0) {
+ pixel->uv[0] = 1.0f - FLT_EPSILON;
+ pixel->uv[1] = FLT_EPSILON / 2.0f;
+ }
+ else if (j == 1) {
+ pixel->uv[0] = FLT_EPSILON / 2.0f;
+ pixel->uv[1] = 1.0f - FLT_EPSILON;
+ }
+ else if (j == 2) {
+ pixel->uv[0] = FLT_EPSILON / 2.0f;
+ pixel->uv[1] = FLT_EPSILON / 2.0f;
+ }
+ }
+ }
+
+ MEM_freeN(looptri);
+}
+
+static void bake_result_to_rgba(float rgba[4], const float *result, const int num_channels)
+{
+ if (num_channels == 4) {
+ copy_v4_v4(rgba, result);
+ }
+ else if (num_channels == 3) {
+ copy_v3_v3(rgba, result);
+ rgba[3] = 1.0f;
+ }
+ else {
+ rgba[0] = result[0];
+ rgba[1] = result[0];
+ rgba[2] = result[0];
+ rgba[3] = 1.0f;
+ }
+}
+
+static bool bake_targets_ou
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list