Preparte curvature fairing and Fairing edit mode operator

This commit is contained in:
Pablo Dobarro 2020-12-24 16:30:12 +01:00
parent f32d3f7b06
commit ac8c589b7c
8 changed files with 286 additions and 9 deletions

View File

@ -3624,6 +3624,8 @@ class VIEW3D_MT_edit_mesh(Menu):
if with_bullet:
layout.operator("mesh.convex_hull")
layout.operator("mesh.fair_vertices", text="Fair")
layout.separator()
layout.operator("mesh.symmetrize")

View File

@ -36,6 +36,7 @@ extern "C" {
typedef enum eMeshFairingDepth {
MESH_FAIRING_DEPTH_POSITION = 1,
MESH_FAIRING_DEPTH_TANGENCY = 2,
MESH_FAIRING_DEPTH_CURVATURE = 3,
} eMeshFairingDepth;
/* affect_vertices is used to define the fairing area. Indexed by vertex index, set to true when

View File

@ -67,6 +67,9 @@ class FairingContext {
/* Get the other vertex index for a loop. */
virtual int other_vertex_index_from_loop(const int loop, const unsigned int v) = 0;
virtual int vertex_index_from_loop(const int loop) = 0;
virtual float cotangent_loop_weight_get(const int loop) = 0;
int vertex_count_get()
{
return totvert_;
@ -74,7 +77,7 @@ class FairingContext {
int loop_count_get()
{
return totvert_;
return totloop_;
}
MeshElemMap *vertex_loop_map_get(const int v)
@ -219,6 +222,15 @@ class MeshFairingContext : public FairingContext {
mesh->totpoly,
mesh->totloop);
BKE_mesh_edge_loop_map_create(&elmap_,
&elmap_mem_,
mesh->medge,
mesh->totedge,
mesh->mpoly,
mesh->totpoly,
mesh->mloop,
mesh->totloop);
/* Deformation coords. */
co_.reserve(mesh->totvert);
if (deform_mverts) {
@ -244,6 +256,8 @@ class MeshFairingContext : public FairingContext {
{
MEM_SAFE_FREE(vlmap_);
MEM_SAFE_FREE(vlmap_mem_);
MEM_SAFE_FREE(elmap_);
MEM_SAFE_FREE(elmap_mem_);
}
void adjacents_coords_from_loop(const int loop,
@ -266,12 +280,26 @@ class MeshFairingContext : public FairingContext {
return e->v1;
}
int vertex_index_from_loop(const int loop) override
{
return mloop_[loop].v;
}
float cotangent_loop_weight_get(const int UNUSED(loop)) override
{
/* TODO: Implement cotangent loop weights for meshes. */
return 1.0f;
}
protected:
Mesh *mesh_;
MLoop *mloop_;
MPoly *mpoly_;
MEdge *medge_;
Vector<int> loop_to_poly_map_;
MeshElemMap *elmap_;
int *elmap_mem_;
};
class BMeshFairingContext : public FairingContext {
@ -307,6 +335,7 @@ class BMeshFairingContext : public FairingContext {
int loop_count = 0;
const int vert_index = BM_elem_index_get(v);
vlmap_[vert_index].indices = &vlmap_mem_[index_iter];
BM_ITER_ELEM (l, &loop_iter, v, BM_LOOPS_OF_VERT) {
const int loop_index = BM_elem_index_get(l);
bmloop_[loop_index] = l;
@ -340,6 +369,47 @@ class BMeshFairingContext : public FairingContext {
return BM_elem_index_get(bm_other_vert);
}
int vertex_index_from_loop(const int loop) override
{
return BM_elem_index_get(bmloop_[loop]->v);
}
float cotangent_loop_weight_get(const int loop) override
{
return 1.0f;
/* TODO: enable this when it works. */
BMLoop *l = bmloop_[loop];
float *co_c[2];
int co_c_count = 1;
float *co_a = l->v->co;
float *co_b = l->next->v->co;
co_c[0] = l->prev->v->co;
if (!BM_edge_is_boundary(l->e)) {
co_c_count = 2;
co_c[1] = l->radial_next->next->next->v->co;
}
float weight = 0.0f;
for (int c = 0; c < co_c_count; c++) {
float v1[3];
float v2[3];
sub_v3_v3v3(v1, co_a, co_c[c]);
sub_v3_v3v3(v2, co_b, co_c[c]);
const float angle = angle_v3v3(v1, v2);
const float tangent = tan(angle);
if (tangent != 0) {
weight += 1.0f / tangent;
}
else {
weight += 1e-4;
}
}
weight *= 0.5f;
return weight;
}
protected:
BMesh *bm;
Vector<BMLoop *> bmloop_;
@ -464,6 +534,27 @@ class UniformLoopWeight : public LoopWeight {
}
};
class CotangentLoopWeight : public LoopWeight {
public:
CotangentLoopWeight(FairingContext *fairing_context)
{
const int totloop = fairing_context->loop_count_get();
loop_weights_.reserve(totloop);
for (int i = 0; i < totloop; i++) {
loop_weights_[i] = fairing_context->cotangent_loop_weight_get(i);
}
}
~CotangentLoopWeight() = default;
float weight_at_index(const int index) override
{
return loop_weights_[index];
}
private:
Vector<float> loop_weights_;
};
static void prefair_and_fair_vertices(FairingContext *fairing_context,
bool *affected_vertices,
const eMeshFairingDepth depth)
@ -471,18 +562,22 @@ static void prefair_and_fair_vertices(FairingContext *fairing_context,
/* Prefair. */
UniformVertexWeight *uniform_vertex_weights = new UniformVertexWeight(fairing_context);
UniformLoopWeight *uniform_loop_weights = new UniformLoopWeight();
fairing_context->fair_vertices(
affected_vertices, depth, uniform_vertex_weights, uniform_loop_weights);
fairing_context->fair_vertices(affected_vertices,
MESH_FAIRING_DEPTH_POSITION,
uniform_vertex_weights,
uniform_loop_weights);
delete uniform_vertex_weights;
delete uniform_loop_weights;
/* Fair. */
VoronoiVertexWeight *voronoi_vertex_weights = new VoronoiVertexWeight(fairing_context);
/* TODO: Implemente cotangent loop weights. */
CotangentLoopWeight *cotangent_loop_weights = new CotangentLoopWeight(fairing_context);
fairing_context->fair_vertices(
affected_vertices, depth, voronoi_vertex_weights, uniform_loop_weights);
affected_vertices, depth, voronoi_vertex_weights, cotangent_loop_weights);
delete uniform_loop_weights;
delete voronoi_vertex_weights;
delete cotangent_loop_weights;
}
void BKE_mesh_prefair_and_fair_vertices(struct Mesh *mesh,

View File

@ -46,6 +46,7 @@ set(SRC
editmesh_extrude_screw.c
editmesh_extrude_spin.c
editmesh_extrude_spin_gizmo.c
editmesh_fair.c
editmesh_inset.c
editmesh_intersect.c
editmesh_knife.c

View File

@ -0,0 +1,162 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2020 Blender Foundation.
* All rights reserved.
*/
/** \file
* \ingroup edmesh
*
* Interactive editmesh knife tool.
*/
#ifdef _MSC_VER
# define _USE_MATH_DEFINES
#endif
#include "MEM_guardedalloc.h"
#include "DNA_object_types.h"
#include "BLI_alloca.h"
#include "BLI_array.h"
#include "BLI_linklist.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_memarena.h"
#include "BLI_smallhash.h"
#include "BLI_string.h"
#include "BLT_translation.h"
#include "BKE_bvhutils.h"
#include "BKE_mesh_fair.h"
#include "BKE_context.h"
#include "BKE_editmesh.h"
#include "BKE_layer.h"
#include "BKE_editmesh_bvh.h"
#include "BKE_report.h"
#include "ED_mesh.h"
#include "ED_screen.h"
#include "ED_space_api.h"
#include "ED_view3d.h"
#include "WM_api.h"
#include "WM_types.h"
#include "DNA_object_types.h"
#include "UI_interface.h"
#include "UI_resources.h"
#include "RNA_access.h"
#include "RNA_define.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
#include "mesh_intern.h" /* own include */
static EnumPropertyItem prop_edit_mesh_fair_selection_mode_items[] = {
{
MESH_FAIRING_DEPTH_POSITION,
"POSITION",
0,
"Position",
"Fair positions",
},
{
MESH_FAIRING_DEPTH_TANGENCY,
"TANGENCY",
0,
"Tangency",
"Fair tangency",
},
/*
{
MESH_FAIRING_DEPTH_CURVATURE,
"CURVATURE",
0,
"Curvature",
"Fair curvature",
},
*/
{0, NULL, 0, NULL, NULL},
};
static int edbm_fair_vertices_exec(bContext *C, wmOperator *op)
{
const int mode = RNA_enum_get(op->ptr, "mode");
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
if ((em->bm->totvertsel == 0)) {
continue;
}
BMesh *bm = em->bm;
BMVert *v;
BMIter iter;
int i;
bool *fairing_mask = MEM_calloc_arrayN(bm->totvert, sizeof(bool), "fairing mask");
BM_ITER_MESH_INDEX(v, &iter, bm, BM_VERTS_OF_MESH, i) {
if (!BM_elem_flag_test(v, BM_ELEM_SELECT)) {
continue;
}
if (BM_vert_is_boundary(v)) {
continue;
}
if (!BM_vert_is_manifold(v)) {
continue;
}
fairing_mask[i] = true;
}
BKE_bmesh_prefair_and_fair_vertices(bm, fairing_mask, mode);
MEM_freeN(fairing_mask);
EDBM_mesh_normals_update(em);
EDBM_update_generic(obedit->data, true, true);
}
MEM_freeN(objects);
return OPERATOR_FINISHED;
}
void MESH_OT_fair_vertices(wmOperatorType *ot)
{
/* description */
ot->name = "Fair Vertices";
ot->idname = "MESH_OT_fair_vertices";
ot->description = "Create a smooth as possible geometry patch";
/* callbacks */
ot->exec = edbm_fair_vertices_exec;
ot->poll = ED_operator_editmesh;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
RNA_def_enum(
ot->srna, "mode", prop_edit_mesh_fair_selection_mode_items, MESH_FAIRING_DEPTH_POSITION, "Mode", "");
}

View File

@ -265,6 +265,9 @@ void MESH_OT_paint_mask_extract(struct wmOperatorType *ot);
void MESH_OT_face_set_extract(struct wmOperatorType *ot);
void MESH_OT_paint_mask_slice(struct wmOperatorType *ot);
/* *** editmesh_fair.c *** */
void MESH_OT_fair_vertices(struct wmOperatorType *ot);
struct wmKeyMap *point_normals_modal_keymap(wmKeyConfig *keyconf);
#ifdef WITH_FREESTYLE

View File

@ -178,6 +178,8 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_bevel);
WM_operatortype_append(MESH_OT_fair_vertices);
WM_operatortype_append(MESH_OT_bridge_edge_loops);
WM_operatortype_append(MESH_OT_inset);
WM_operatortype_append(MESH_OT_offset_edge_loops);

View File

@ -1027,10 +1027,7 @@ typedef enum eSculptFaceSetEditMode {
SCULPT_FACE_SET_EDIT_DELETE_GEOMETRY = 2,
SCULPT_FACE_SET_EDIT_FAIR_POSITIONS = 3,
SCULPT_FACE_SET_EDIT_FAIR_TANGENCY = 4,
/* TODO(pablodp606): enable this after supporting cotangent weights in fairing. */
/*
SCULPT_FACE_SET_EDIT_FAIR_CURVATURE = 5,
*/
SCULPT_FACE_SET_EDIT_FILL_COMPONENT = 6,
} eSculptFaceSetEditMode;
@ -1072,6 +1069,16 @@ static EnumPropertyItem prop_sculpt_face_sets_edit_types[] = {
"Creates a smooth as possible geometry patch from the Face Set minimizing changes in "
"vertex tangents",
},
/*
{
SCULPT_FACE_SET_EDIT_FAIR_CURVATURE,
"FAIR_CURVATURE",
0,
"Fair Curvature",
"Creates a smooth as possible geometry patch from the Face Set minimizing changes in "
"surface curvature",
},
*/
{
SCULPT_FACE_SET_EDIT_FILL_COMPONENT,
"FILL_COMPONENT",
@ -1300,6 +1307,9 @@ static void sculpt_face_set_apply_edit(Object *ob,
case SCULPT_FACE_SET_EDIT_FAIR_TANGENCY:
sculpt_face_set_edit_fair_face_set(ob, active_face_set_id, MESH_FAIRING_DEPTH_TANGENCY);
break;
case SCULPT_FACE_SET_EDIT_FAIR_CURVATURE:
sculpt_face_set_edit_fair_face_set(ob, active_face_set_id, MESH_FAIRING_DEPTH_CURVATURE);
break;
}
}
@ -1456,6 +1466,7 @@ static int sculpt_face_set_edit_invoke(bContext *C, wmOperator *op, const wmEven
break;
case SCULPT_FACE_SET_EDIT_FAIR_POSITIONS:
case SCULPT_FACE_SET_EDIT_FAIR_TANGENCY:
case SCULPT_FACE_SET_EDIT_FAIR_CURVATURE:
sculpt_face_set_edit_modify_coordinates(C, ob, active_face_set, mode);
break;
}