Skip to content

Commit

Permalink
Finish 2D dynamic level set
Browse files Browse the repository at this point in the history
  • Loading branch information
fangy14 committed Apr 6, 2017
1 parent 1d8c85b commit e151d37
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 4 deletions.
49 changes: 49 additions & 0 deletions include/taichi/math/dynamic_levelset_2d.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*******************************************************************************
Taichi - Physically based Computer Graphics Library
Copyright (c) 2017 Yu Fang <squarefk@gmail.com>
All rights reserved. Use of this source code is governed by
the MIT license as written in the LICENSE file.
*******************************************************************************/

#include "dynamic_levelset_2d.h"

TC_NAMESPACE_BEGIN

void DynamicLevelSet2D::initialize(real _t0, real _t1, const LevelSet2D &_ls0, const LevelSet2D &_ls1) {
t0 = _t0;
t1 = _t1;
levelset0 = std::make_shared<LevelSet2D>(_ls0);
levelset1 = std::make_shared<LevelSet2D>(_ls1);
}

Vector2 DynamicLevelSet2D::get_spatial_gradient(const Vector2 &pos, real t) {
Vector2 gxy0 = levelset0->get_gradient(pos);
Vector2 gxy1 = levelset1->get_gradient(pos);
real gx = lerp((t - t0) / (t1 - t0), gxy0.x, gxy1.x);
real gy = lerp((t - t0) / (t1 - t0), gxy0.y, gxy1.y);
return Vector2(gx, gy);
}

real DynamicLevelSet2D::get_temporal_gradient(const Vector2 &pos, real t) {
real l1 = levelset0->get(pos);
real l2 = levelset1->get(pos);
return (l2 - l1) / (t1 - t0);
}

Array2D<real> DynamicLevelSet2D::rasterize(int width, int height, real t) {
Array2D<real> r0 = levelset0->rasterize(width, height);
Array2D<real> r1 = levelset1->rasterize(width, height);
Array2D<real> out(width, height);
for (auto &ind : Region2D(0, width, 0, height, Vector2(0.5f, 0.5f))) {
out[ind] = lerp((t - t0) / (t1 - t0), r0[ind], r1[ind]);
if (std::isnan(out[ind])) {
out[ind] = std::numeric_limits<real>::infinity();
}
}
return out;
}


TC_NAMESPACE_END
35 changes: 35 additions & 0 deletions include/taichi/math/dynamic_levelset_2d.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*******************************************************************************
Taichi - Physically based Computer Graphics Library
Copyright (c) 2017 Yu Fang <squarefk@gmail.com>
All rights reserved. Use of this source code is governed by
the MIT license as written in the LICENSE file.
*******************************************************************************/

#pragma once


#include <limits>
#include <memory>
#include <taichi/math/levelset_2d.h>


TC_NAMESPACE_BEGIN

class DynamicLevelSet2D {
public:
real t0, t1;
std::shared_ptr<LevelSet2D> levelset0, levelset1;

void initialize(real _t0, real _t1, const LevelSet2D &_ls0, const LevelSet2D &_ls1);

Vector2 get_spatial_gradient(const Vector2 &pos, real t);

real get_temporal_gradient(const Vector2 &pos, real t);

Array2D<real> rasterize(int width, int height, real t);
};

TC_NAMESPACE_END

25 changes: 21 additions & 4 deletions include/taichi/math/levelset_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Taichi - Physically based Computer Graphics Library
Copyright (c) 2016 Yuanming Hu <yuanmhu@gmail.com>
2017 Yu Fang <squarefk@gmail.com>
All rights reserved. Use of this source code is governed by
the MIT license as written in the LICENSE file.
Expand All @@ -16,7 +17,7 @@ void LevelSet2D::add_sphere(Vector2 center, real radius, bool inside_out) {
for (auto &ind : get_region()) {
Vector2 sample = ind.get_pos();
real dist = (inside_out ? -1 : 1) * (length(center - sample) - radius);
set(ind, std::min(get(ind), dist));
set(ind, std::min(Array2D::get(ind), dist));
}
}

Expand All @@ -25,7 +26,7 @@ void LevelSet2D::add_polygon(std::vector<Vector2> polygon, bool inside_out)
for (auto &ind : get_region()) {
Vector2 p = ind.get_pos();
real dist = ((inside_polygon(p, polygon) ^ inside_out) ? -1 : 1) * (nearest_distance(p, polygon));
set(ind, std::min(get(ind), dist));
set(ind, std::min(Array2D::get(ind), dist));
}
}

Expand All @@ -39,8 +40,8 @@ Vector2 LevelSet2D::get_gradient(const Vector2 &pos) const
const int y_i = clamp(int(y), 0, height - 2);
const real x_r = x - x_i;
const real y_r = y - y_i;
const real gx = lerp(y_r, get(x_i + 1, y_i) - get(x_i, y_i), get(x_i + 1, y_i + 1) - get(x_i, y_i + 1));
const real gy = lerp(x_r, get(x_i, y_i + 1) - get(x_i, y_i), get(x_i + 1, y_i + 1) - get(x_i + 1, y_i));
const real gx = lerp(y_r, Array2D::get(x_i + 1, y_i) - Array2D::get(x_i, y_i), Array2D::get(x_i + 1, y_i + 1) - Array2D::get(x_i, y_i + 1));
const real gy = lerp(x_r, Array2D::get(x_i, y_i + 1) - Array2D::get(x_i, y_i), Array2D::get(x_i + 1, y_i + 1) - Array2D::get(x_i + 1, y_i));
return Vector2(gx, gy);
}

Expand All @@ -53,6 +54,22 @@ Vector2 LevelSet2D::get_normalized_gradient(const Vector2 &pos) const
return normalize(gradient);
}

real LevelSet2D::get(const Vector2 &pos) const
{
assert_info(inside(pos), "LevelSet Gradient Query out of Bound! (" + std::to_string(pos.x) + ", " + std::to_string(pos.y) + ")");
real x = pos.x, y = pos.y;
x = clamp(x - storage_offset.x, 0.f, width - 1.f - eps);
y = clamp(y - storage_offset.y, 0.f, height - 1.f - eps);
const int x_i = clamp(int(x), 0, width - 2);
const int y_i = clamp(int(y), 0, height - 2);
const real x_r = x - x_i;
const real y_r = y - y_i;
const real ly0 = lerp(x_r, Array2D::get(x_i, y_i), Array2D::get(x_i + 1, y_i));
const real ly1 = lerp(x_r, Array2D::get(x_i, y_i + 1), Array2D::get(x_i + 1, y_i + 1));
return lerp(y_r, ly0, ly1);
}


Array2D<real> LevelSet2D::rasterize(int width, int height) {
for (auto &p : (*this)) {
if (std::isnan(p)) {
Expand Down
3 changes: 3 additions & 0 deletions include/taichi/math/levelset_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Taichi - Physically based Computer Graphics Library
Copyright (c) 2016 Yuanming Hu <yuanmhu@gmail.com>
2017 Yu Fang <squarefk@gmail.com>
All rights reserved. Use of this source code is governed by
the MIT license as written in the LICENSE file.
Expand Down Expand Up @@ -49,6 +50,8 @@ class LevelSet2D : public Array2D<real> {

Vector2 get_normalized_gradient(const Vector2 &pos) const;

real get(const Vector2 &pos) const;

static real fraction_outside(real phi_a, real phi_b) {
return 1.0f - fraction_inside(phi_a, phi_b);
}
Expand Down

0 comments on commit e151d37

Please sign in to comment.