Sculpt-dev: fix compile errors for quadriflow
. . .when compiled with threading on (for quadriflow). Still off however.
This commit is contained in:
parent
779aeb72ab
commit
3bcfe9b5ac
|
@ -67,6 +67,18 @@ set(INC_SYS
|
|||
${EIGEN3_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
#if(WITH_TBB)
|
||||
# add_definitions(-DWITH_TBB)
|
||||
#
|
||||
# list(APPEND INC_SYS
|
||||
# ${TBB_INCLUDE_DIRS}
|
||||
# )
|
||||
#
|
||||
# list(APPEND LIB
|
||||
# ${TBB_LIBRARIES}
|
||||
# )
|
||||
#endif()
|
||||
|
||||
set(SRC
|
||||
src/adjacent-matrix.cpp
|
||||
src/adjacent-matrix.hpp
|
||||
|
|
|
@ -13,6 +13,13 @@
|
|||
#include "flow.hpp"
|
||||
#include "parametrizer.hpp"
|
||||
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
|
||||
namespace qflow {
|
||||
|
||||
#ifdef WITH_CUDA
|
||||
|
|
|
@ -6,6 +6,16 @@
|
|||
#include <random>
|
||||
#include "optimizer.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
|
||||
|
||||
namespace qflow {
|
||||
|
||||
|
||||
|
|
|
@ -8,6 +8,16 @@
|
|||
#include "dedge.hpp"
|
||||
#include <queue>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
|
||||
|
||||
namespace qflow {
|
||||
|
||||
void Parametrizer::NormalizeMesh() {
|
||||
|
|
|
@ -2,6 +2,14 @@
|
|||
#include "field-math.hpp"
|
||||
#include "parametrizer.hpp"
|
||||
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
|
||||
|
||||
namespace qflow {
|
||||
|
||||
void Parametrizer::ComputeOrientationSingularities() {
|
||||
|
|
|
@ -19,6 +19,13 @@
|
|||
#include "post-solver.hpp"
|
||||
#include "serialize.hpp"
|
||||
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
|
||||
namespace qflow {
|
||||
|
||||
using namespace Eigen;
|
||||
|
|
|
@ -8,6 +8,14 @@
|
|||
#include "field-math.hpp"
|
||||
#include "parametrizer.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
|
||||
namespace qflow {
|
||||
|
||||
void subdivide(MatrixXi &F, MatrixXd &V, VectorXd& rho, VectorXi &V2E, VectorXi &E2E, VectorXi &boundary,
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
//#define INSTANT_MESHES_VIS_COLOR
|
||||
|
||||
/* clang-format off */
|
||||
//remeshedge->flag
|
||||
enum {
|
||||
|
@ -10,6 +12,9 @@ enum {
|
|||
|
||||
typedef struct RemeshVertex {
|
||||
float co[3], no[3];
|
||||
#ifdef INSTANT_MESHES_VIS_COLOR
|
||||
float viscolor[3];
|
||||
#endif
|
||||
} RemeshVertex;
|
||||
|
||||
// edge constraint
|
||||
|
@ -41,6 +46,8 @@ typedef struct RemeshMesh {
|
|||
|
||||
int totoutface;
|
||||
int totoutvert;
|
||||
|
||||
int goal_faces, iterations;
|
||||
} RemeshMesh;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
int instant_meshes_nprocs = 1;
|
||||
|
||||
const float len_v3v3(const float *a, const float *b)
|
||||
static const float len_v3v3(const float *a, const float *b)
|
||||
{
|
||||
float dx = a[0] - b[0];
|
||||
float dy = a[1] - b[1];
|
||||
|
@ -30,6 +30,34 @@ const float len_v3v3(const float *a, const float *b)
|
|||
return len > 0.0f ? sqrtf(len) : 0.0f;
|
||||
}
|
||||
|
||||
static void cross_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
|
||||
{
|
||||
float n1[3], n2[3];
|
||||
|
||||
n1[0] = v1[0] - v2[0];
|
||||
n2[0] = v2[0] - v3[0];
|
||||
n1[1] = v1[1] - v2[1];
|
||||
n2[1] = v2[1] - v3[1];
|
||||
n1[2] = v1[2] - v2[2];
|
||||
n2[2] = v2[2] - v3[2];
|
||||
n[0] = n1[1] * n2[2] - n1[2] * n2[1];
|
||||
n[1] = n1[2] * n2[0] - n1[0] * n2[2];
|
||||
n[2] = n1[0] * n2[1] - n1[1] * n2[0];
|
||||
}
|
||||
|
||||
/* Triangles */
|
||||
static float area_tri_v3(const float v1[3], const float v2[3], const float v3[3])
|
||||
{
|
||||
float n[3];
|
||||
cross_tri_v3(n, v1, v2, v3);
|
||||
return sqrtf(n[0] * n[0] + n[1] * n[1] + n[2] * n[2]) * 0.5f;
|
||||
}
|
||||
|
||||
static float fract(float f)
|
||||
{
|
||||
return f - floorf(f);
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
void instant_meshes_run(RemeshMesh *mesh)
|
||||
{
|
||||
|
@ -47,18 +75,22 @@ void instant_meshes_run(RemeshMesh *mesh)
|
|||
V.resize(3, mesh->totvert);
|
||||
N.resize(3, mesh->totvert);
|
||||
|
||||
// F.resize(mesh->tottri * 3);
|
||||
// V.resize(mesh->totvert * 3);
|
||||
// N.resize(mesh->totvert * 3);
|
||||
float area = 0.0f;
|
||||
|
||||
for (int i = 0; i < mesh->tottri; i++) {
|
||||
RemeshTri *tri = mesh->tris + i;
|
||||
|
||||
elen += len_v3v3(mesh->verts[tri->v1].co, mesh->verts[tri->v2].co);
|
||||
elen += len_v3v3(mesh->verts[tri->v2].co, mesh->verts[tri->v3].co);
|
||||
elen += len_v3v3(mesh->verts[tri->v3].co, mesh->verts[tri->v1].co);
|
||||
float *co1 = mesh->verts[tri->v1].co;
|
||||
float *co2 = mesh->verts[tri->v2].co;
|
||||
float *co3 = mesh->verts[tri->v3].co;
|
||||
|
||||
elen += len_v3v3(co1, co2);
|
||||
elen += len_v3v3(co2, co3);
|
||||
elen += len_v3v3(co3, co1);
|
||||
totlen += 3;
|
||||
|
||||
area += area_tri_v3(co1, co2, co3);
|
||||
|
||||
F(0, i) = tri->v1;
|
||||
F(1, i) = tri->v2;
|
||||
F(2, i) = tri->v3;
|
||||
|
@ -75,14 +107,18 @@ void instant_meshes_run(RemeshMesh *mesh)
|
|||
|
||||
if (totlen > 0) {
|
||||
elen /= totlen;
|
||||
scale = elen * 4.0f;
|
||||
}
|
||||
|
||||
scale = sqrt(area / (float)mesh->goal_faces);
|
||||
if (scale == 0.0f) {
|
||||
return; // error
|
||||
}
|
||||
|
||||
const bool extrinsic = true;
|
||||
const bool deterministic = false;
|
||||
const int rosy = 4, posy = 4;
|
||||
const int rosy = 2, posy = 4;
|
||||
|
||||
printf("scale: %.5f\n", scale);
|
||||
printf("totarea: %.4f, scale: %.5f\n", area, scale);
|
||||
|
||||
VectorXu V2E, E2E;
|
||||
VectorXb boundary;
|
||||
|
@ -161,8 +197,10 @@ void instant_meshes_run(RemeshMesh *mesh)
|
|||
opt.setRoSy(rosy);
|
||||
opt.setPoSy(posy);
|
||||
|
||||
const int iterations = mesh->iterations;
|
||||
|
||||
printf("optimizing orientation field\n");
|
||||
for (int step = 0; step < 1; step++) {
|
||||
for (int step = 0; step < iterations; step++) {
|
||||
opt.optimizeOrientations(-1);
|
||||
opt.notify();
|
||||
opt.wait();
|
||||
|
@ -173,7 +211,7 @@ void instant_meshes_run(RemeshMesh *mesh)
|
|||
cout << "Orientation field has " << sing.size() << " singularities." << endl;
|
||||
|
||||
printf("optimizing position field\n");
|
||||
for (int step = 0; step < 1; step++) {
|
||||
for (int step = 0; step < iterations; step++) {
|
||||
opt.optimizePositions(-1);
|
||||
opt.notify();
|
||||
opt.wait();
|
||||
|
@ -183,8 +221,50 @@ void instant_meshes_run(RemeshMesh *mesh)
|
|||
compute_position_singularities(mRes, sing, pos_sing, extrinsic, rosy, posy);
|
||||
cout << "Position field has " << pos_sing.size() << " singularities." << endl;
|
||||
|
||||
#ifdef INSTANT_MESHES_VIS_COLOR
|
||||
{
|
||||
mesh->totoutface = mesh->tottri;
|
||||
mesh->totoutvert = mesh->totvert;
|
||||
|
||||
mesh->outfaces = (RemeshOutFace *)MEM_malloc_arrayN(
|
||||
mesh->tottri, sizeof(RemeshOutFace), "RemeshOutFace");
|
||||
mesh->outverts = (RemeshVertex *)MEM_malloc_arrayN(
|
||||
mesh->totvert, sizeof(RemeshVertex), "RemeshVertex");
|
||||
memcpy(mesh->outverts, mesh->verts, sizeof(*mesh->outverts) * mesh->totvert);
|
||||
mesh->out_scracth = (int *)MEM_malloc_arrayN(mesh->tottri * 3, sizeof(int), "out_scratch");
|
||||
|
||||
int li = 0;
|
||||
RemeshOutFace *f = mesh->outfaces;
|
||||
RemeshTri *tri = mesh->tris;
|
||||
RemeshVertex *v = mesh->outverts;
|
||||
|
||||
auto O = mRes.O(0);
|
||||
printf("O size: [%d][%d]\n", (int)O.cols(), (int)O.rows());
|
||||
|
||||
for (int i = 0; i < mesh->totvert; i++, v++) {
|
||||
v->viscolor[0] = O(0, i);
|
||||
v->viscolor[1] = O(1, i);
|
||||
// v->viscolor[2] = O(2, i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < mesh->tottri; i++, f++, tri++) {
|
||||
f->verts = mesh->out_scracth + li;
|
||||
li += 3;
|
||||
|
||||
f->verts[0] = tri->v1;
|
||||
f->verts[1] = tri->v2;
|
||||
f->verts[2] = tri->v3;
|
||||
f->totvert = 3;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
opt.shutdown();
|
||||
|
||||
#ifdef INSTANT_MESHES_VIS_COLOR
|
||||
return;
|
||||
#endif
|
||||
|
||||
std::vector<std::vector<TaggedLink>> adj_extracted;
|
||||
|
||||
MatrixXu F_extracted;
|
||||
|
@ -219,7 +299,7 @@ void instant_meshes_run(RemeshMesh *mesh)
|
|||
mRes.scale(),
|
||||
creaseOut,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
nullptr,
|
||||
0);
|
||||
|
||||
|
|
|
@ -172,13 +172,13 @@ void QFLOW_quadriflow_remesh(QuadriflowRemeshData *qrd,
|
|||
const int steps = 2;
|
||||
|
||||
/* Setup mesh boundary constraints if needed */
|
||||
#if 0
|
||||
#if 1
|
||||
if (true) { // field.flag_preserve_boundary) {
|
||||
Hierarchy &mRes = field.hierarchy;
|
||||
mRes.clearConstraints();
|
||||
|
||||
for (uint32_t i = 0; i < 3 * mRes.mF.cols(); ++i) {
|
||||
if (mRes.mFF((i) % 3, i / 3) & QFLOW_CONSTRAINED) {
|
||||
if (qrd->faces[i / 3].eflag[i % 3] & QFLOW_CONSTRAINED) {
|
||||
// if (mRes.mE2E[i] == -1) {
|
||||
uint32_t i0 = mRes.mF(i % 3, i / 3);
|
||||
uint32_t i1 = mRes.mF((i + 1) % 3, i / 3);
|
||||
|
@ -193,7 +193,8 @@ void QFLOW_quadriflow_remesh(QuadriflowRemeshData *qrd,
|
|||
}
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < 10; j++) {
|
||||
|
||||
for (int j = 0; j < 2; j++) {
|
||||
mRes.propagateConstraints();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ struct Mesh *BKE_mesh_remesh_quadriflow(const struct Mesh *mesh,
|
|||
|
||||
struct Mesh *BKE_mesh_remesh_instant_meshes(const Mesh *input_mesh,
|
||||
int target_faces,
|
||||
int iterations,
|
||||
void (*update_cb)(void *, float progress, int *cancel),
|
||||
void *update_cb_data);
|
||||
|
||||
|
|
|
@ -257,6 +257,7 @@ extern "C" int closest_vec_to_perp(
|
|||
|
||||
ATTR_NO_OPT Mesh *BKE_mesh_remesh_instant_meshes(const Mesh *input_mesh,
|
||||
int target_faces,
|
||||
int iterations,
|
||||
void (*update_cb)(void *,
|
||||
float progress,
|
||||
int *cancel),
|
||||
|
@ -397,7 +398,10 @@ ATTR_NO_OPT Mesh *BKE_mesh_remesh_instant_meshes(const Mesh *input_mesh,
|
|||
}
|
||||
|
||||
RemeshMesh remesh;
|
||||
|
||||
remesh.goal_faces = target_faces;
|
||||
remesh.tris = faces.data();
|
||||
remesh.iterations = iterations;
|
||||
remesh.tottri = (int)faces.size();
|
||||
|
||||
remesh.verts = verts.data();
|
||||
|
@ -414,12 +418,22 @@ ATTR_NO_OPT Mesh *BKE_mesh_remesh_instant_meshes(const Mesh *input_mesh,
|
|||
|
||||
Mesh *mesh = BKE_mesh_new_nomain(remesh.totoutvert, 0, 0, totloop, remesh.totoutface);
|
||||
|
||||
#ifdef INSTANT_MESHES_VIS_COLOR
|
||||
MPropCol *cols = (MPropCol *)CustomData_add_layer(
|
||||
&mesh->vdata, CD_PROP_COLOR, CD_DEFAULT, NULL, remesh.totoutvert);
|
||||
#endif
|
||||
|
||||
for (int i : IndexRange(remesh.totoutvert)) {
|
||||
MVert *mv = mesh->mvert + i;
|
||||
RemeshVertex *v = remesh.outverts + i;
|
||||
|
||||
copy_v3_v3(mv->co, v->co);
|
||||
normal_float_to_short_v3(mv->no, v->no);
|
||||
|
||||
#ifdef INSTANT_MESHES_VIS_COLOR
|
||||
copy_v3_v3(cols[i].color, v->viscolor);
|
||||
cols[i].color[3] = 1.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
int li = 0;
|
||||
|
|
|
@ -1249,9 +1249,10 @@ static int instant_meshes_remesh_exec(bContext *C, wmOperator *op)
|
|||
ob, bisect_mesh, (eSymmetryAxes)0); //(eSymmetryAxes)mesh->symmetry);
|
||||
|
||||
int target_faces = RNA_int_get(op->ptr, "target_faces");
|
||||
int iterations = RNA_int_get(op->ptr, "iterations");
|
||||
|
||||
Mesh *new_mesh = BKE_mesh_remesh_instant_meshes(
|
||||
bisect_mesh, target_faces, instant_mesh_update_cb, nullptr);
|
||||
bisect_mesh, target_faces, iterations, instant_mesh_update_cb, nullptr);
|
||||
|
||||
if (!new_mesh) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Remesher failed to create mesh");
|
||||
|
@ -1310,6 +1311,7 @@ void OBJECT_OT_instant_meshes_remesh(wmOperatorType *ot)
|
|||
|
||||
PropertyRNA *prop;
|
||||
prop = RNA_def_int(ot->srna, "target_faces", 5000, 8, 1 << 23, "Face Count", "", 8, 100000);
|
||||
prop = RNA_def_int(ot->srna, "iterations", 1, 1, 100, "Iterations", "Iterations", 1, 100);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
Loading…
Reference in New Issue