123 C,
"The remesher cannot run with a Multires modifier in the modifier stack");
142 float isovalue = 0.0f;
207 ot->
name =
"Voxel Remesh";
209 "Calculates a new manifold mesh based on the volume of the current mesh. All data layers "
211 ot->
idname =
"OBJECT_OT_voxel_remesh";
226 #define VOXEL_SIZE_EDIT_MAX_GRIDS_LINES 500
227 #define VOXEL_SIZE_EDIT_MAX_STR_LEN 20
248 const float initial_co[3],
249 const float end_co[3],
250 const float length_co[3],
253 const float total_len =
len_v3v3(initial_co, end_co);
254 const int tot_lines = (int)(total_len / spacing);
255 const int tot_lines_half = (tot_lines / 2) + 1;
256 float spacing_dir[3], lines_start[3];
270 for (
int i = 0; i < tot_lines_half; i++) {
273 madd_v3_v3v3fl(line_start, lines_start, spacing_dir, spacing * i);
283 for (
int i = 1; i < tot_lines_half; i++) {
286 madd_v3_v3v3fl(line_start, lines_start, spacing_dir, spacing * i);
328 const int tot_lines = (int)(total_len / cd->
voxel_size);
333 const float x =
clamp_f((tot_lines -
a) / (b -
a), 0.0f, 1.0);
334 const float alpha_factor = 1.0f - (
x *
x * (3.0f - 2.0f *
x));
346 float strwidth, strheight;
347 short fstyle_points = fstyle->
points;
349 short strdrawlen = 0;
358 BLF_size(fontid, 10.0f * fstyle_points,
U.dpi);
361 BLF_position(fontid, -0.5f * strwidth, -0.5f * strheight, 0.0f);
410 const float mval[2] = {
event->mval[0],
event->mval[1]};
458 "Voxel Size Edit OP Custom Data");
463 cd->active_object = active_object;
464 cd->init_mval[0] =
event->mval[0];
465 cd->init_mval[1] =
event->mval[1];
474 const int BB_faces[6][4] = {
491 float current_normal[3];
492 float view_normal[3] = {0.0f, 0.0f, 1.0f};
502 normal_tri_v3(current_normal, cd->preview_plane[0], cd->preview_plane[1], cd->preview_plane[2]);
504 float min_dot =
dot_v3v3(current_normal, view_normal);
505 float current_dot = 1;
508 for (
int i = 0; i < 6; i++) {
510 current_normal, bb->
vec[BB_faces[i][0]], bb->
vec[BB_faces[i][1]], bb->
vec[BB_faces[i][2]]);
511 current_dot =
dot_v3v3(current_normal, view_normal);
513 if (current_dot < min_dot) {
514 min_dot = current_dot;
524 float scale_mat[4][4];
526 float d_a[3], d_b[3];
527 float d_a_proj[2], d_b_proj[2];
528 float preview_plane_proj[4][3];
529 const float y_axis_proj[2] = {0.0f, 1.0f};
531 mid_v3_v3v3(text_pos, cd->preview_plane[0], cd->preview_plane[2]);
534 for (
int i = 0; i < 4; i++) {
535 float preview_plane_world_space[3];
536 mul_v3_m4v3(preview_plane_world_space, active_object->
obmat, cd->preview_plane[i]);
541 sub_v3_v3v3(d_a, cd->preview_plane[1], cd->preview_plane[0]);
542 sub_v3_v3v3(d_b, cd->preview_plane[3], cd->preview_plane[0]);
547 sub_v2_v2v2(d_a_proj, preview_plane_proj[1], preview_plane_proj[0]);
548 sub_v2_v2v2(d_b_proj, preview_plane_proj[3], preview_plane_proj[0]);
560 if (d_b_proj[0] < 0.0f) {
563 if (d_a_proj[1] < 0.0f) {
570 if (d_a_proj[0] < 0.0f) {
573 if (d_b_proj[1] < 0.0f) {
579 normal_tri_v3(cd->text_mat[2], cd->preview_plane[0], cd->preview_plane[1], cd->preview_plane[2]);
585 float text_pos_word_space[3];
595 const char *status_str =
TIP_(
596 "Move the mouse to change the voxel size. LMB: confirm size, ESC/RMB: cancel");
610 ot->
name =
"Edit Voxel Size";
611 ot->
description =
"Modify the mesh voxel size interactively used in the voxel remesher";
612 ot->
idname =
"OBJECT_OT_voxel_size_edit";
629 #define QUADRIFLOW_MIRROR_BISECT_TOLERANCE 0.005f
673 bool is_manifold_consistent =
true;
684 const MLoop *loop = &mloop[loop_idx];
685 edge_faces[loop->
e] += 1;
686 if (edge_faces[loop->
e] > 2) {
687 is_manifold_consistent =
false;
691 if (edge_vert[loop->
e] == -1) {
692 edge_vert[loop->
e] = loop->
v;
694 else if (edge_vert[loop->
e] == loop->
v) {
696 is_manifold_consistent =
false;
701 if (is_manifold_consistent) {
704 if (edge_faces[i] == 0) {
705 is_manifold_consistent =
false;
712 is_manifold_consistent =
false;
721 return is_manifold_consistent;
739 bool should_break = (
G.is_break);
769 Mesh *mesh_bisect, *mesh_bisect_temp;
773 float plane_co[3], plane_no[3];
776 for (
char i = 0; i < 3; i++) {
778 if (symmetry_axes & symm_it) {
783 plane_no[axis] = -1.0f;
784 mesh_bisect_temp = mesh_bisect;
786 &mmd, mesh_bisect, axis, plane_co, plane_no);
787 if (mesh_bisect_temp != mesh_bisect) {
802 Mesh *mesh_mirror, *mesh_mirror_temp;
808 for (
char i = 0; i < 3; i++) {
810 if (symmetry_axes & symm_it) {
814 mesh_mirror_temp = mesh_mirror;
816 if (mesh_mirror_temp != mesh_mirror) {
862 #ifdef USE_MESH_CURVATURE
872 if (new_mesh ==
NULL) {
937 "QuadriFlow: The mesh needs to be manifold and have face normals that point in a "
938 "consistent direction");
958 #ifdef USE_MESH_CURVATURE
970 for (
char i = 0; i < 3; i++) {
985 short stop = 0, do_update =
true;
1027 num_faces =
area / (edge_len * edge_len);
1056 if (
STREQ(prop_id,
"target_faces")) {
1087 "Specify target number of faces relative to the current mesh"},
1092 "Input target edge length in the new mesh"},
1100 ot->
name =
"QuadriFlow Remesh";
1102 "Create a new quad based mesh using the surface data of the current mesh. All data "
1103 "layers will be lost";
1104 ot->
idname =
"OBJECT_OT_quadriflow_remesh";
1119 "use_mesh_symmetry",
1121 "Use Mesh Symmetry",
1122 "Generates a symmetrical mesh using the mesh symmetry configuration");
1125 "use_preserve_sharp",
1128 "Try to preserve sharp features on the mesh");
1131 "use_preserve_boundary",
1133 "Preserve Mesh Boundary",
1134 "Try to preserve mesh boundary on the mesh");
1135 #ifdef USE_MESH_CURVATURE
1137 "use_mesh_curvature",
1139 "Use Mesh Curvature",
1140 "Take the mesh curvature into account when remeshing");
1143 "preserve_paint_mask",
1145 "Preserve Paint Mask",
1146 "Reproject the paint mask onto the new mesh");
1152 "Set the output mesh normals to smooth");
1159 "How to specify the amount of detail for the new mesh");
1167 "Relative number of faces compared to the current mesh",
1172 "target_edge_length",
1177 "Target edge length in the new mesh",
1187 "Approximate number of faces (quads) in the new mesh",
1197 "Old Object Face Area",
1198 "This property is only used to cache the object area for later calculations",
1209 "Random seed to use with the solver. Different seeds will cause the remesher to "
1210 "come up with different quad layouts on the mesh",
struct Scene * CTX_data_scene(const bContext *C)
struct wmWindowManager * CTX_wm_manager(const bContext *C)
struct Object * CTX_data_active_object(const bContext *C)
struct ARegion * CTX_wm_region(const bContext *C)
void CTX_wm_operator_poll_msg_set(struct bContext *C, const char *msg)
struct RegionView3D * CTX_wm_region_view3d(const bContext *C)
struct wmWindow * CTX_wm_window(const bContext *C)
CustomData interface, see also DNA_customdata_types.h.
const CustomData_MeshMasks CD_MASK_MESH
void BKE_id_free(struct Main *bmain, void *idv)
struct BoundBox * BKE_mesh_boundbox_get(struct Object *ob)
struct Mesh * BKE_mesh_from_object(struct Object *ob)
void BKE_mesh_nomain_to_mesh(struct Mesh *mesh_src, struct Mesh *mesh_dst, struct Object *ob, const struct CustomData_MeshMasks *mask, bool take_ownership)
struct Mesh * BKE_mesh_copy_for_eval(struct Mesh *source, bool reference)
void BKE_mesh_calc_normals(struct Mesh *me)
void BKE_mesh_batch_cache_dirty_tag(struct Mesh *me, eMeshBatchDirtyMode mode)
void BKE_mesh_smooth_flag_set(struct Mesh *me, const bool use_smooth)
float BKE_mesh_calc_area(const struct Mesh *me)
struct Mesh * BKE_mesh_mirror_bisect_on_mirror_plane_for_modifier(struct MirrorModifierData *mmd, const struct Mesh *mesh, int axis, const float plane_co[3], float plane_no[3])
struct Mesh * BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(struct MirrorModifierData *mmd, struct Object *ob, const struct Mesh *mesh, const int axis)
void BKE_mesh_remesh_reproject_paint_mask(struct Mesh *target, struct Mesh *source)
void BKE_remesh_reproject_vertex_paint(struct Mesh *target, struct Mesh *source)
struct Mesh * BKE_mesh_remesh_quadriflow_to_mesh_nomain(struct Mesh *mesh, int target_faces, int seed, bool preserve_sharp, bool preserve_boundary, bool adaptive_scale, void *update_cb, void *update_cb_data)
struct Mesh * BKE_mesh_remesh_voxel_to_mesh_nomain(struct Mesh *mesh, float voxel_size, float adaptivity, float isovalue)
struct Mesh * BKE_mesh_remesh_voxel_fix_poles(struct Mesh *mesh)
void BKE_remesh_reproject_sculpt_face_sets(struct Mesh *target, struct Mesh *source)
void BKE_mesh_runtime_clear_geometry(struct Mesh *mesh)
@ BKE_MESH_BATCH_DIRTY_ALL
bool BKE_modifiers_uses_multires(struct Object *ob)
General operations, lookup, etc. for blender objects.
bool BKE_object_is_in_editmode(const struct Object *ob)
void BKE_sculpt_ensure_orig_mesh_data(struct Scene *scene, struct Object *object)
void BKE_report(ReportList *reports, ReportType type, const char *message)
void BKE_shrinkwrap_remesh_target_project(struct Mesh *src_me, struct Mesh *target_me, struct Object *ob_target)
void BLF_color3f(int fontid, float r, float g, float b)
void BLF_width_and_height(int fontid, const char *str, size_t len, float *r_width, float *r_height) ATTR_NONNULL()
void BLF_draw(int fontid, const char *str, size_t len) ATTR_NONNULL(2)
void BLF_size(int fontid, int size, int dpi)
void BLF_position(int fontid, float x, float y, float z)
MINLINE float pow2f(float x)
MINLINE float clamp_f(float value, float min, float max)
MINLINE float min_ff(float a, float b)
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
void mul_m3_v3(const float M[3][3], float r[3])
void copy_m3_m4(float m1[3][3], const float m2[4][4])
void unit_m4(float m[4][4])
bool invert_m4_m4(float R[4][4], const float A[4][4])
void scale_m4_fl(float R[4][4], float scale)
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
void mul_m4_m4_post(float R[4][4], const float B[4][4])
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE bool compare_v3v3(const float a[3], const float b[3], const float limit) ATTR_WARN_UNUSED_RESULT
MINLINE float normalize_v3(float r[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE float dot_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
void mid_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
MINLINE void zero_v3(float r[3])
MINLINE float normalize_v2(float r[2])
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
size_t BLI_strlen_utf8(const char *strc) ATTR_NONNULL()
void DEG_id_tag_update(struct ID *id, int flag)
#define ID_IS_LINKED(_id)
#define ID_IS_OVERRIDE_LIBRARY(_id)
@ ME_REMESH_REPROJECT_VOLUME
@ ME_REMESH_REPROJECT_VERTEX_COLORS
@ ME_REMESH_REPROJECT_SCULPT_FACE_SETS
@ ME_REMESH_SMOOTH_NORMALS
@ ME_REMESH_REPROJECT_PAINT_MASK
Object is a sort of wrapper for general info.
bool ED_operator_object_active_editable_mesh(struct bContext *C)
void ED_region_tag_redraw(struct ARegion *region)
void ED_workspace_status_text(struct bContext *C, const char *str)
void ED_sculpt_undo_geometry_begin(struct Object *ob, const char *name)
void ED_sculpt_undo_geometry_end(struct Object *ob)
#define REGION_DRAW_POST_VIEW
void * ED_region_draw_cb_activate(struct ARegionType *art, void(*draw)(const struct bContext *, struct ARegion *, void *), void *customdata, int type)
void ED_region_draw_cb_exit(struct ARegionType *, void *)
float ED_view3d_pixel_size(const struct RegionView3D *rv3d, const float co[3])
void ED_view3d_project(const struct ARegion *region, const float world[3], float r_region_co[3])
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
void GPU_matrix_pop(void)
#define GPU_matrix_mul(x)
void GPU_matrix_push(void)
@ GPU_SHADER_3D_UNIFORM_COLOR
void GPU_blend(eGPUBlend blend)
void GPU_line_width(float width)
void GPU_line_smooth(bool enable)
Read Guarded memory(de)allocation.
const struct uiStyle * UI_style_get(void)
@ WM_JOB_TYPE_QUADRIFLOW_REMESH
ATTR_WARN_UNUSED_RESULT const BMVert * v2
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
void(* MEM_freeN)(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
void *(* MEM_mallocN)(size_t len, const char *str)
static void area(int d1, int d2, int e1, int e2, float weights[2])
struct QuadriFlowJob QuadriFlowJob
static int quadriflow_break_job(void *customdata)
struct VoxelSizeEditCustomData VoxelSizeEditCustomData
static void quadriflow_end_job(void *customdata)
static bool voxel_size_edit_poll(bContext *C)
#define VOXEL_SIZE_EDIT_MAX_GRIDS_LINES
static int voxel_size_edit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static int voxel_remesh_exec(bContext *C, wmOperator *op)
static void quadriflow_free_job(void *customdata)
static bool object_remesh_poll(bContext *C)
static void quadriflow_start_job(void *customdata, short *stop, short *do_update, float *progress)
#define VOXEL_SIZE_EDIT_MAX_STR_LEN
static void voxel_size_edit_cancel(bContext *C, wmOperator *op)
static bool mesh_is_manifold_consistent(Mesh *mesh)
static void voxel_size_parallel_lines_draw(uint pos3d, const float initial_co[3], const float end_co[3], const float length_co[3], const float spacing)
static bool quadriflow_check(bContext *C, wmOperator *op)
void OBJECT_OT_voxel_size_edit(wmOperatorType *ot)
static Mesh * remesh_symmetry_mirror(Object *ob, Mesh *mesh, eSymmetryAxes symmetry_axes)
static const EnumPropertyItem mode_type_items[]
static void voxel_size_edit_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *arg)
static int quadriflow_remesh_exec(bContext *C, wmOperator *op)
static int voxel_size_edit_modal(bContext *C, wmOperator *op, const wmEvent *event)
@ QUADRIFLOW_REMESH_RATIO
@ QUADRIFLOW_REMESH_FACES
@ QUADRIFLOW_REMESH_EDGE_LENGTH
#define QUADRIFLOW_MIRROR_BISECT_TOLERANCE
static void quadriflow_update_job(void *customdata, float progress, int *cancel)
void OBJECT_OT_quadriflow_remesh(wmOperatorType *ot)
void OBJECT_OT_voxel_remesh(wmOperatorType *ot)
static Mesh * remesh_symmetry_bisect(Mesh *mesh, eSymmetryAxes symmetry_axes)
static bool quadriflow_poll_property(const bContext *C, wmOperator *op, const PropertyRNA *prop)
const char * RNA_property_identifier(const PropertyRNA *prop)
void RNA_int_set(PointerRNA *ptr, const char *name, int value)
int RNA_int_get(PointerRNA *ptr, const char *name)
float RNA_float_get(PointerRNA *ptr, const char *name)
void RNA_float_set(PointerRNA *ptr, const char *name, float value)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_clear_flag(PropertyRNA *prop, PropertyFlag flag)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int default_value, int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
struct ARegionType * type
float remesh_voxel_adaptivity
struct SculptSession * sculpt
eSymmetryAxes symmetry_axes
bool use_preserve_boundary
float preview_plane[4][3]
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
int(* modal)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
bool(* poll_property)(const struct bContext *C, struct wmOperator *op, const PropertyRNA *prop) ATTR_WARN_UNUSED_RESULT
void(* cancel)(struct bContext *, struct wmOperator *)
bool(* check)(struct bContext *, struct wmOperator *)
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
struct ReportList * reports
struct wmOperatorType * type
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
void WM_report(ReportType type, const char *message)
void WM_reportf(ReportType type, const char *format,...)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
void WM_set_locked_interface(wmWindowManager *wm, bool lock)
void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job)
wmJob * WM_jobs_get(wmWindowManager *wm, wmWindow *win, void *owner, const char *name, int flag, int job_type)
void WM_jobs_callbacks(wmJob *wm_job, wm_jobs_start_callback startjob, void(*initjob)(void *), void(*update)(void *), void(*endjob)(void *))
void WM_jobs_customdata_set(wmJob *wm_job, void *customdata, void(*free)(void *))
void WM_jobs_timer(wmJob *wm_job, double timestep, unsigned int note, unsigned int endnote)
int WM_operator_props_popup_confirm(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))