Skip to content

Action #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 53 commits into from
Apr 15, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
b850ff4
fixing conda?
teseoch Nov 26, 2020
9910f2b
removed activate
teseoch Nov 26, 2020
b536c6d
added wich python
teseoch Nov 26, 2020
c118242
updated pybind and tmp disabled python versions
teseoch Nov 26, 2020
2abbe6c
other conda action?
teseoch Nov 26, 2020
93ec32f
activate?
teseoch Nov 26, 2020
71f8a7f
base?
teseoch Nov 26, 2020
79ac0ea
?
teseoch Nov 26, 2020
75ebcf8
old conda thing
teseoch Nov 26, 2020
5e51559
skipping windows release?
teseoch Nov 26, 2020
a43fef6
?
teseoch Nov 26, 2020
4fc8802
?
teseoch Nov 26, 2020
de438b5
disabling windows release
teseoch Nov 26, 2020
dcfeca6
all python versions
teseoch Nov 26, 2020
36c3a83
added command
teseoch Dec 1, 2020
9c50621
added initial stuff for time dependent
teseoch Dec 1, 2020
a72bd6e
updated polyfem
teseoch Aug 19, 2021
f1597f4
updated polyfem and added substepping
teseoch Aug 20, 2021
937f55f
updated polyfem
teseoch Aug 20, 2021
b341a6c
update BC
teseoch Aug 20, 2021
8656964
added raster, untested
teseoch Aug 23, 2021
c9ad320
commented get_sampled_traction_forces
teseoch Aug 23, 2021
5a0b7e0
update pybind11
teseoch Aug 24, 2021
1d8bc7f
updated polyfem and new python include in setup
teseoch Aug 31, 2021
dcd32a7
Merge branch 'master' into action
teseoch Aug 31, 2021
898a16a
fixed (hopefully) nasty eigen linker error
teseoch Sep 1, 2021
26fc540
fixed TF test
teseoch Sep 1, 2021
88f2209
added febio command, new febio test, and updated polyfem. New pythoni…
teseoch Sep 2, 2021
13b9c0b
added pybind11 to json conversion
teseoch Sep 2, 2021
c50e352
beter febio interface and added pythonic function
teseoch Sep 3, 2021
9256d2d
fixed rendering
teseoch Sep 3, 2021
13d9bbe
get_sampled_solution now returns el_id
teseoch Sep 3, 2021
5b10756
fixed test
teseoch Sep 3, 2021
ec82197
export of bid
teseoch Sep 3, 2021
8c6f0fd
Pull in rendering changes (#6)
arvigj Sep 16, 2021
ab11908
Fixed BC update
zfergus Sep 22, 2021
525478b
Fix step_in_time bindings.
arvigj Sep 22, 2021
00ca5c5
Merge pull request #7 from arvigj/action_fix
teseoch Sep 22, 2021
8170505
fixed pythonic binding
teseoch Nov 18, 2021
330249f
updated polyfem
teseoch Nov 18, 2021
bce625e
updated cmake with recipes
teseoch Feb 22, 2022
0d0402b
fixed cmake versions
teseoch Feb 22, 2022
642512a
fixed test paths
teseoch Feb 22, 2022
59ae76c
updated polyfem
teseoch Feb 22, 2022
19cf7d7
updated polyfem
teseoch Mar 15, 2022
d13d847
fixed step in time
teseoch Apr 5, 2022
842336d
updated polyfem + update_obstacle_displacement
teseoch Apr 9, 2022
f64e824
using env vars to changeopts
teseoch Apr 15, 2022
9d1f2e7
disabled cholmod in windows
teseoch Apr 15, 2022
2e9108d
better way to set env
teseoch Apr 15, 2022
4843f11
update polyfem and removed unecessary cmake flags
teseoch Apr 15, 2022
a91c059
updated pybind11
teseoch Apr 15, 2022
f998f0e
added tracy lib to ignore
teseoch Apr 15, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
added raster, untested
  • Loading branch information
teseoch committed Aug 23, 2021
commit 8656964cd4008766aae0c910c38595c09a919d51
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ polyfem_python_download_data()
################################################################################
# Subdirectories
################################################################################
add_library(polyfempy MODULE src/binding.cpp)
add_library(polyfempy MODULE src/binding.cpp src/raster.cpp)
target_link_libraries(polyfempy PRIVATE polyfem)
target_link_libraries(polyfempy PRIVATE pybind11::module)
set_target_properties(polyfempy PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}" SUFFIX "${PYTHON_MODULE_EXTENSION}")
Expand Down
154 changes: 153 additions & 1 deletion src/binding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include <polyfem/GenericProblem.hpp>
#include <polyfem/StringUtils.hpp>

#include "raster.hpp"

#include <geogram/basic/command_line.h>
#include <geogram/basic/command_line_args.h>

Expand Down Expand Up @@ -659,7 +661,157 @@ PYBIND11_MODULE(polyfempy, m)
throw "Updating BC works only for Tensor GenericProblems";
}
},
"updates pressure boundary", py::arg("id"), py::arg("val"), py::arg("interp") = std::string(""));
"updates pressure boundary", py::arg("id"), py::arg("val"), py::arg("interp") = std::string(""))
.def(
"render", [](polyfem::State &self, int width, int height, const Eigen::Vector3d &camera_position, const double camera_fov, const double camera_fl, const bool is_perspective, const Eigen::Vector3d &left, const Eigen::Vector3d &up, const Eigen::Vector3d &ambient_light, const std::vector<std::pair<Eigen::Vector3d, Eigen::Vector3d>> &lights, const Eigen::Vector3d &diffuse_color, const Eigen::Vector3d &specular_color, const double specular_exponent)
{
using namespace renderer;
using namespace Eigen;

Material material;
material.diffuse_color = diffuse_color;
material.specular_color = specular_color;
material.specular_exponent = specular_exponent;

Eigen::Matrix<FrameBufferAttributes, Eigen::Dynamic, Eigen::Dynamic> frameBuffer(width, height);
UniformAttributes uniform;

const Vector3d w = -left.normalized();
const Vector3d u = up.cross(w).normalized();
const Vector3d v = w.cross(u);

Matrix4d M_cam_inv;
M_cam_inv << u(0), v(0), w(0), camera_position(0),
u(1), v(1), w(1), camera_position(1),
u(2), v(2), w(2), camera_position(2),
0, 0, 0, 1;

uniform.M_cam = M_cam_inv.inverse();

{
const double camera_ar = double(width) / height;
double t = tan(camera_fov / 2) * camera_fl;
double b = -t;
double r = t * camera_ar;
double l = -r;
double n = -camera_fl;
double f = 5 * n;

uniform.M_orth << 2 / (r - l), 0, 0, -(r + l) / (r - l),
0, 2 / (t - b), 0, -(t + b) / (t - b),
0, 0, 2 / (n - f), -(n + f) / (n - f),
0, 0, 0, 1;
Matrix4d P;
if (is_perspective)
{
P << n, 0, 0, 0,
0, n, 0, 0,
0, 0, n + f, -f * n,
0, 0, 1, 0;
}
else
{
P << 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1;
}

uniform.M = uniform.M_orth * P * uniform.M_cam;
}

Program program;
program.VertexShader = [&](const VertexAttributes &va, const UniformAttributes &uniform)
{
VertexAttributes out;
out.position = uniform.M * va.position;
Vector3d color = ambient_light;

Vector3d hit(va.position(0), va.position(1), va.position(2));
for (const auto &l : lights)
{
Vector3d Li = (l.first - hit).normalized();
Vector3d N = va.normal;
Vector3d diffuse = va.material.diffuse_color * std::max(Li.dot(N), 0.0);
Vector3d H;
if (is_perspective)
{
H = (Li + (camera_position - hit).normalized()).normalized();
}
else
{
H = (Li - left.normalized()).normalized();
}
const Vector3d specular = va.material.specular_color * std::pow(std::max(N.dot(H), 0.0), va.material.specular_exponent);
const Vector3d D = l.first - hit;
color += (diffuse + specular).cwiseProduct(l.second) / D.squaredNorm();
}
out.color = color;
return out;
};

program.FragmentShader = [](const VertexAttributes &va, const UniformAttributes &uniform)
{
FragmentAttributes out(va.color(0), va.color(1), va.color(2));
out.depth = -va.position(2);
return out;
};

program.BlendingShader = [](const FragmentAttributes &fa, const FrameBufferAttributes &previous)
{
if (fa.depth < previous.depth)
{
FrameBufferAttributes out(fa.color[0] * 255, fa.color[1] * 255, fa.color[2] * 255, fa.color[3] * 255);
out.depth = fa.depth;
return out;
}
else
{
return previous;
}
};

const Eigen::MatrixXd tmp = self.boundary_nodes_pos + self.sol;
Eigen::MatrixXd vnormals(tmp.rows(), 3);
// Eigen::MatrixXd areas(tmp.rows(), 1);
vnormals.setZero();
// areas.setZero();
Eigen::MatrixXd fnormals(self.boundary_triangles.rows(), 3);

for (int i = 0; i < self.boundary_triangles.rows(); ++i)
{
const Vector3d l1 = tmp.row(self.boundary_triangles(i, 1)) - tmp.row(self.boundary_triangles(i, 0));
const Vector3d l2 = tmp.row(self.boundary_triangles(i, 2)) - tmp.row(self.boundary_triangles(i, 0));
const auto nn = l1.cross(l2);
const double area = nn.norm();
fnormals.row(i) = nn / area;

for (int j = 0; j < 3; j++)
{
int vid = self.boundary_triangles(i, j);
vnormals.row(vid) += nn;
// areas(vid) += area;
}
}

std::vector<VertexAttributes> vertices;
for (int i = 0; i < self.boundary_triangles.rows(); ++i)
{
for (int j = 0; j < 3; j++)
{
int vid = self.boundary_triangles(i, j);
VertexAttributes va(tmp(vid, 0), tmp(vid, 1), tmp(vid, 2));
va.material = material;
va.normal = vnormals.row(vid).normalized();
vertices.push_back(va);
}
}

rasterize_triangles(program, uniform, vertices, frameBuffer);

std::vector<uint8_t> image;
framebuffer_to_uint8(frameBuffer, image);

return image;
},
"renders scene");

solver.doc() = "Polyfem solver";

Expand Down
147 changes: 147 additions & 0 deletions src/raster.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
#include "raster.hpp"
#include <iostream>

namespace renderer
{
void rasterize_triangle(const Program &program, const UniformAttributes &uniform, const VertexAttributes &v1, const VertexAttributes &v2, const VertexAttributes &v3, Eigen::Matrix<FrameBufferAttributes, Eigen::Dynamic, Eigen::Dynamic> &frameBuffer)
{
Eigen::Matrix<double, 3, 4> p;
p.row(0) = v1.position.array() / v1.position[3];
p.row(1) = v2.position.array() / v2.position[3];
p.row(2) = v3.position.array() / v3.position[3];

p.col(0) = ((p.col(0).array() + 1.0) / 2.0) * frameBuffer.rows();
p.col(1) = ((p.col(1).array() + 1.0) / 2.0) * frameBuffer.cols();

int lx = std::floor(p.col(0).minCoeff());
int ly = std::floor(p.col(1).minCoeff());
int ux = std::ceil(p.col(0).maxCoeff());
int uy = std::ceil(p.col(1).maxCoeff());

lx = std::min(std::max(lx, int(0)), int(frameBuffer.rows() - 1));
ly = std::min(std::max(ly, int(0)), int(frameBuffer.cols() - 1));
ux = std::max(std::min(ux, int(frameBuffer.rows() - 1)), int(0));
uy = std::max(std::min(uy, int(frameBuffer.cols() - 1)), int(0));

Eigen::Matrix3d A;
A.col(0) = p.row(0).segment(0, 3);
A.col(1) = p.row(1).segment(0, 3);
A.col(2) = p.row(2).segment(0, 3);
A.row(2) << 1.0, 1.0, 1.0;

Eigen::Matrix3d Ai = A.inverse();

for (unsigned i = lx; i <= ux; i++)
{
for (unsigned j = ly; j <= uy; j++)
{

Eigen::Vector3d pixel(i + 0.5, j + 0.5, 1);
Eigen::Vector3d b = Ai * pixel;
if (b.minCoeff() >= 0)
{
VertexAttributes va = VertexAttributes::interpolate(v1, v2, v3, b[0], b[1], b[2]);

if (va.position[2] >= -1 && va.position[2] <= 1)
{
FragmentAttributes frag = program.FragmentShader(va, uniform);
frameBuffer(i, j) = program.BlendingShader(frag, frameBuffer(i, j));
}
}
}
}
}

void rasterize_triangles(const Program &program, const UniformAttributes &uniform, const std::vector<VertexAttributes> &vertices, Eigen::Matrix<FrameBufferAttributes, Eigen::Dynamic, Eigen::Dynamic> &frameBuffer)
{
std::vector<VertexAttributes> v(vertices.size());
for (unsigned i = 0; i < vertices.size(); i++)
v[i] = program.VertexShader(vertices[i], uniform);

for (unsigned i = 0; i < vertices.size() / 3; i++)
rasterize_triangle(program, uniform, v[i * 3 + 0], v[i * 3 + 1], v[i * 3 + 2], frameBuffer);
}

void rasterize_line(const Program &program, const UniformAttributes &uniform, const VertexAttributes &v1, const VertexAttributes &v2, double line_thickness, Eigen::Matrix<FrameBufferAttributes, Eigen::Dynamic, Eigen::Dynamic> &frameBuffer)
{
Eigen::Matrix<double, 2, 4> p;
p.row(0) = v1.position.array() / v1.position[3];
p.row(1) = v2.position.array() / v2.position[3];

p.col(0) = ((p.col(0).array() + 1.0) / 2.0) * frameBuffer.rows();
p.col(1) = ((p.col(1).array() + 1.0) / 2.0) * frameBuffer.cols();

int lx = std::floor(p.col(0).minCoeff() - line_thickness);
int ly = std::floor(p.col(1).minCoeff() - line_thickness);
int ux = std::ceil(p.col(0).maxCoeff() + line_thickness);
int uy = std::ceil(p.col(1).maxCoeff() + line_thickness);

lx = std::min(std::max(lx, int(0)), int(frameBuffer.rows() - 1));
ly = std::min(std::max(ly, int(0)), int(frameBuffer.cols() - 1));
ux = std::max(std::min(ux, int(frameBuffer.rows() - 1)), int(0));
uy = std::max(std::min(uy, int(frameBuffer.cols() - 1)), int(0));

Eigen::Vector2f l1(p(0, 0), p(0, 1));
Eigen::Vector2f l2(p(1, 0), p(1, 1));

double t = -1;
double ll = (l1 - l2).squaredNorm();

for (unsigned i = lx; i <= ux; i++)
{
for (unsigned j = ly; j <= uy; j++)
{

Eigen::Vector2f pixel(i + 0.5, j + 0.5);

if (ll == 0.0)
t = 0;
else
{
t = (pixel - l1).dot(l2 - l1) / ll;
t = std::fmax(0, std::fmin(1, t));
}

Eigen::Vector2f pixel_p = l1 + t * (l2 - l1);

if ((pixel - pixel_p).squaredNorm() < (line_thickness * line_thickness))
{
VertexAttributes va = VertexAttributes::interpolate(v1, v2, v1, 1 - t, t, 0);
FragmentAttributes frag = program.FragmentShader(va, uniform);
frameBuffer(i, j) = program.BlendingShader(frag, frameBuffer(i, j));
}
}
}
}

void rasterize_lines(const Program &program, const UniformAttributes &uniform, const std::vector<VertexAttributes> &vertices, double line_thickness, Eigen::Matrix<FrameBufferAttributes, Eigen::Dynamic, Eigen::Dynamic> &frameBuffer)
{
std::vector<VertexAttributes> v(vertices.size());
for (unsigned i = 0; i < vertices.size(); i++)
v[i] = program.VertexShader(vertices[i], uniform);

for (unsigned i = 0; i < vertices.size() / 2; i++)
rasterize_line(program, uniform, v[i * 2 + 0], v[i * 2 + 1], line_thickness, frameBuffer);
}

void framebuffer_to_uint8(const Eigen::Matrix<FrameBufferAttributes, Eigen::Dynamic, Eigen::Dynamic> &frameBuffer, std::vector<uint8_t> &image)
{
const int w = frameBuffer.rows();
const int h = frameBuffer.cols();
const int comp = 4;
const int stride_in_bytes = w * comp;
image.resize(w * h * comp, 0);

for (unsigned wi = 0; wi < w; ++wi)
{
for (unsigned hi = 0; hi < h; ++hi)
{
unsigned hif = h - 1 - hi;
image[(hi * w * 4) + (wi * 4) + 0] = frameBuffer(wi, hif).color[0];
image[(hi * w * 4) + (wi * 4) + 1] = frameBuffer(wi, hif).color[1];
image[(hi * w * 4) + (wi * 4) + 2] = frameBuffer(wi, hif).color[2];
image[(hi * w * 4) + (wi * 4) + 3] = frameBuffer(wi, hif).color[3];
}
}
}
}
Loading