PeriDyno 1.0.0
Loading...
Searching...
No Matches
DistanceField3D.h
Go to the documentation of this file.
1
11#pragma once
12
13#include <string>
14#include "Platform.h"
15#include "Array/Array3D.h"
16
17namespace dyno {
18
19#define FARWAY_DISTANCE 10^6
20
21 template<typename TDataType>
23 public:
24 typedef typename TDataType::Real Real;
25 typedef typename TDataType::Coord Coord;
26
28
29 DistanceField3D(std::string filename);
30
35
40 void release();
41
47 void translate(const Coord& t);
48
54 void scale(const Real s);
55
63 GPU_FUNC void getDistance(const Coord &p, Real &d, Coord &normal);
64
65 DYN_FUNC uint nx() { return mDistances.nx(); }
66
67 DYN_FUNC uint ny() { return mDistances.ny(); }
68
69 DYN_FUNC uint nz() { return mDistances.nz(); }
70
71 public:
78 void loadSDF(std::string filename, bool inverted = false);
79
85 void loadBox(Coord& lo, Coord& hi, bool inverted = false);
86
87 void loadCylinder(Coord& center, Real radius, Real height, int axis, bool inverted = false);
88
89 void loadSphere(Coord& center, Real radius, bool inverted = false);
90
91 void setSpace(const Coord p0, const Coord p1, Real h);
92
93 inline Coord lowerBound() { return mOrigin; }
94
95 inline Coord upperBound() { return Coord(mOrigin[0] + (mDistances.nx() - 1) * mH, mOrigin[1] + (mDistances.ny() - 1) * mH, mOrigin[2] + (mDistances.nz() - 1) * mH); }
96
97
99 mOrigin = sdf.mOrigin;
100 mH = sdf.mH;
101 mInverted = sdf.mInverted;
102 mDistances.assign(sdf.mDistances);
103 }
104
106
108 mDistances.assign(distance);
109 }
110
111 Real getGridSpacing() { return mH; }
112
117 void invertSDF();
118
119 private:
120 GPU_FUNC inline Real lerp(Real a, Real b, Real alpha) const {
121 return (1.0f - alpha)*a + alpha *b;
122 }
123
129
135
136 bool mInverted = false;
137
143 };
144
145 template<typename TDataType>
146 GPU_FUNC void DistanceField3D<TDataType>::getDistance(const Coord &p, Real &d, Coord &normal)
147 {
148 // get cell and lerp values
149 Coord fp = (p - mOrigin) / mH;
150 const int i = (int)floor(fp[0]);
151 const int j = (int)floor(fp[1]);
152 const int k = (int)floor(fp[2]);
153 if (i < 0 || i >= mDistances.nx() - 1 || j < 0 || j >= mDistances.ny() - 1 || k < 0 || k >= mDistances.nz() - 1) {
154 if (mInverted) d = -FARWAY_DISTANCE;
155 else d = FARWAY_DISTANCE;
156 normal = Coord(0);
157 return;
158 }
159 Coord ip = Coord(i, j, k);
160
161 Coord alphav = fp - ip;
162 Real alpha = alphav[0];
163 Real beta = alphav[1];
164 Real gamma = alphav[2];
165
166 Real d000 = mDistances(i, j, k);
167 Real d100 = mDistances(i + 1, j, k);
168 Real d010 = mDistances(i, j + 1, k);
169 Real d110 = mDistances(i + 1, j + 1, k);
170 Real d001 = mDistances(i, j, k + 1);
171 Real d101 = mDistances(i + 1, j, k + 1);
172 Real d011 = mDistances(i, j + 1, k + 1);
173 Real d111 = mDistances(i + 1, j + 1, k + 1);
174
175 Real dx00 = lerp(d000, d100, alpha);
176 Real dx10 = lerp(d010, d110, alpha);
177 Real dxy0 = lerp(dx00, dx10, beta);
178
179 Real dx01 = lerp(d001, d101, alpha);
180 Real dx11 = lerp(d011, d111, alpha);
181 Real dxy1 = lerp(dx01, dx11, beta);
182
183 Real d0y0 = lerp(d000, d010, beta);
184 Real d0y1 = lerp(d001, d011, beta);
185 Real d0yz = lerp(d0y0, d0y1, gamma);
186
187 Real d1y0 = lerp(d100, d110, beta);
188 Real d1y1 = lerp(d101, d111, beta);
189 Real d1yz = lerp(d1y0, d1y1, gamma);
190
191 Real dx0z = lerp(dx00, dx01, gamma);
192 Real dx1z = lerp(dx10, dx11, gamma);
193
194 normal[0] = d0yz - d1yz;
195 normal[1] = dx0z - dx1z;
196 normal[2] = dxy0 - dxy1;
197
198 Real l = normal.norm();
199 if (l < 0.0001f) normal = Coord(0);
200 else normal = normal.normalize();
201
202 d = (1.0f - gamma) * dxy0 + gamma * dxy1;
203 }
204}
#define FARWAY_DISTANCE
void loadSphere(Coord &center, Real radius, bool inverted=false)
void loadSDF(std::string filename, bool inverted=false)
load signed distance field from a file
void translate(const Coord &t)
Translate the distance field with a displacement.
void loadCylinder(Coord &center, Real radius, Real height, int axis, bool inverted=false)
void setDistance(CArray3D< Real > distance)
DArray3D< Real > & distances()
GPU_FUNC void getDistance(const Coord &p, Real &d, Coord &normal)
Query the signed distance for p.
~DistanceField3D()
Should not release data here, call release() explicitly.
TDataType::Coord Coord
void loadBox(Coord &lo, Coord &hi, bool inverted=false)
load signed distance field from a Box (lo, hi)
Coord mOrigin
Lower left corner.
void assign(DistanceField3D< TDataType > &sdf)
void setSpace(const Coord p0, const Coord p1, Real h)
void release()
Release m_distance Should be explicitly called before destruction to avoid GPU memory leak.
DArray3D< Real > mDistances
Storing the signed distance field as a 3D array.
void invertSDF()
Invert the signed distance field.
DistanceField3D(std::string filename)
GPU_FUNC Real lerp(Real a, Real b, Real alpha) const
void scale(const Real s)
Scale the distance field.
This is an implementation of AdditiveCCD based on peridyno.
Definition Array.h:25
DYN_FUNC T lerp(Array< T, deviceType > &array1d, float x, LerpMode mode=LerpMode::REPEAT)
Definition Lerp.h:36
Array3D< T, DeviceType::GPU > DArray3D
Definition Array3D.inl:90
unsigned int uint
Definition VkProgram.h:14
Array3D< T, DeviceType::CPU > CArray3D
Definition Array3D.h:136