1
1

Compare commits

...

6 Commits

6 changed files with 179 additions and 1 deletions

View File

@@ -33,6 +33,7 @@ set(SRC
paint_image_ops_paint.cc
paint_image_2d.c
paint_image_2d_curve_mask.cc
paint_image_3d.cc
paint_image_proj.c
paint_mask.c
paint_ops.c

View File

@@ -0,0 +1,89 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2022 Blender Foundation. All rights reserved. */
/** \file
* \ingroup edsculpt
* \brief 3D perspective painting.
*/
#include "MEM_guardedalloc.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
#include "BKE_context.h"
#include "BKE_mesh.h"
#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_pbvh.h"
#include "BLI_math.h"
#include "paint_image_3d.hh"
#include "CLG_log.h"
static CLG_LogRef LOG = {"ed.sculpt_paint.image3d"};
namespace blender::ed::sculpt_paint::image3d {
struct StrokeHandle {
Object *ob = nullptr;
Image *image = nullptr;
virtual ~StrokeHandle()
{
image = nullptr;
ob = nullptr;
}
PBVH *get_pbvh()
{
BLI_assert(ob != nullptr);
BLI_assert(ob->sculpt != nullptr);
BLI_assert(ob->sculpt->pbvh != nullptr);
return ob->sculpt->pbvh;
}
};
struct StrokeHandle *stroke_new(bContext *C, Object *ob)
{
CLOG_INFO(&LOG, 2, "create new stroke");
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
ToolSettings *ts = CTX_data_tool_settings(C);
BLI_assert_msg(ts->imapaint.mode == IMAGEPAINT_MODE_IMAGE, "Only Image mode implemented");
Image *image = ts->imapaint.canvas;
CLOG_INFO(&LOG, 2, " paint target image: %s", image->id.name);
if (ob->sculpt == nullptr) {
BKE_object_sculpt_data_create(ob);
}
PBVH *pbvh = BKE_sculpt_object_pbvh_ensure(depsgraph, ob);
BLI_assert_msg(pbvh != nullptr, "Unable to retrieve PBVH from sculptsession");
StrokeHandle *stroke_handle = MEM_new<StrokeHandle>("StrokeHandle");
stroke_handle->image = image;
stroke_handle->ob = ob;
return stroke_handle;
}
void stroke_update(struct StrokeHandle *stroke_handle, float2 prev_mouse, float2 mouse)
{
CLOG_INFO(&LOG, 2, "new stroke step");
// See SCULPT_do_paint_brush?
}
void stroke_free(struct StrokeHandle *stroke_handle)
{
CLOG_INFO(&LOG, 2, "free stroke");
MEM_delete(stroke_handle);
}
} // namespace blender::ed::sculpt_paint::image3d

View File

@@ -0,0 +1,25 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2022 Blender Foundation. All rights reserved. */
/** \file
* \ingroup edsculpt
*/
#pragma once
extern "C" {
/* Forward declarations. */
struct bContext;
struct Object;
}
#include "BLI_math_vec_types.hh"
namespace blender::ed::sculpt_paint::image3d {
struct StrokeHandle;
struct StrokeHandle *stroke_new(bContext *C, Object *ob);
void stroke_update(struct StrokeHandle *stroke_handle, float2 prev_mouse, float2 mouse);
void stroke_free(struct StrokeHandle *stroke_handle);
} // namespace blender::ed::sculpt_paint::image3d

View File

@@ -36,6 +36,8 @@
#include "paint_intern.h"
#include "paint_image_3d.hh"
namespace blender::ed::sculpt_paint::image::ops::paint {
/**
@@ -211,6 +213,57 @@ class ProjectionPaintMode : public AbstractPaintMode {
}
};
class PerspectivePaintMode : public AbstractPaintMode {
public:
void *paint_new_stroke(
bContext *C, wmOperator *UNUSED(op), Object *ob, const float mouse[2], int mode) override
{
return image3d::stroke_new(C, ob);
}
void paint_stroke(bContext *C,
void *stroke_handle,
float prev_mouse[2],
float mouse[2],
int eraser,
float pressure,
float distance,
float size) override
{
image3d::stroke_update(static_cast<image3d::StrokeHandle *>(stroke_handle), prev_mouse, mouse);
};
void paint_stroke_redraw(const bContext *C, void *stroke_handle, bool final) override
{
}
void paint_stroke_done(void *stroke_handle) override
{
image3d::stroke_free(static_cast<image3d::StrokeHandle *>(stroke_handle));
}
void paint_gradient_fill(const bContext *C,
const Scene *scene,
Brush *brush,
struct PaintStroke *stroke,
void *stroke_handle,
float mouse_start[2],
float mouse_end[2]) override
{
}
void paint_bucket_fill(const bContext *C,
const Scene *scene,
Brush *brush,
struct PaintStroke *stroke,
void *stroke_handle,
float mouse_start[2],
float mouse_end[2]) override
{
}
};
struct PaintOperation {
AbstractPaintMode *mode = nullptr;
@@ -301,7 +354,13 @@ static PaintOperation *texture_paint_init(bContext *C, wmOperator *op, const flo
WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, nullptr);
return nullptr;
}
/* Set to 1 to switch back to original implementation. */
#if 0
pop->mode = MEM_new<ProjectionPaintMode>("ProjectionPaintMode");
#else
pop->mode = MEM_new<PerspectivePaintMode>("PerspectivePaintMode");
#endif
}
else {
pop->mode = MEM_new<ImagePaintMode>("ImagePaintMode");

View File

@@ -154,6 +154,9 @@ void ED_editors_init(bContext *C)
else if (mode == OB_MODE_WEIGHT_PAINT) {
ED_object_wpaintmode_enter_ex(bmain, depsgraph, scene, ob);
}
else if (mode == OB_MODE_TEXTURE_PAINT) {
ED_object_texture_paint_mode_enter_ex(bmain, scene, ob);
}
else {
BLI_assert_unreachable();
}

View File

@@ -49,7 +49,8 @@ typedef enum eDrawType {
OB_MODE_VERTEX_GPENCIL)
/** Any mode that uses Object.sculpt. */
#define OB_MODE_ALL_SCULPT (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)
#define OB_MODE_ALL_SCULPT \
(OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)
/** Any mode that uses weightpaint. */
#define OB_MODE_ALL_WEIGHT_PAINT (OB_MODE_WEIGHT_PAINT | OB_MODE_WEIGHT_GPENCIL)