#include "btMiniSDF.h" // //Based on code from DiscreGrid, https://github.com/InteractiveComputerGraphics/Discregrid //example: //GenerateSDF.exe -r "32 32 32" -d "-1.6 -1.6 -.6 1.6 1.6 .6" concave_box.obj //The MIT License (MIT) // //Copyright (c) 2017 Dan Koschier // #include #include //memcpy struct btSdfDataStream { const char* m_data; int m_size; int m_currentOffset; btSdfDataStream(const char* data, int size) :m_data(data), m_size(size), m_currentOffset(0) { } template bool read(T& val) { int bytes = sizeof(T); if (m_currentOffset+bytes<=m_size) { char* dest = (char*)&val; memcpy(dest,&m_data[m_currentOffset],bytes); m_currentOffset+=bytes; return true; } btAssert(0); return false; } }; bool btMiniSDF::load(const char* data, int size) { int fileSize = -1; btSdfDataStream ds(data,size); { double buf[6]; ds.read(buf); m_domain.m_min[0] = buf[0]; m_domain.m_min[1] = buf[1]; m_domain.m_min[2] = buf[2]; m_domain.m_min[3] = 0; m_domain.m_max[0] = buf[3]; m_domain.m_max[1] = buf[4]; m_domain.m_max[2] = buf[5]; m_domain.m_max[3] = 0; } { unsigned int buf2[3]; ds.read(buf2); m_resolution[0] = buf2[0]; m_resolution[1] = buf2[1]; m_resolution[2] = buf2[2]; } { double buf[3]; ds.read(buf); m_cell_size[0] = buf[0]; m_cell_size[1] = buf[1]; m_cell_size[2] = buf[2]; } { double buf[3]; ds.read(buf); m_inv_cell_size[0] = buf[0]; m_inv_cell_size[1] = buf[1]; m_inv_cell_size[2] = buf[2]; } { unsigned long long int cells; ds.read(cells); m_n_cells = cells; } { unsigned long long int fields; ds.read(fields); m_n_fields = fields; } unsigned long long int nodes0; std::size_t n_nodes0; ds.read(nodes0); n_nodes0 = nodes0; if (n_nodes0 > 1024 * 1024 * 1024) { return m_isValid; } m_nodes.resize(n_nodes0); for (unsigned int i=0;i& nodes = m_nodes[i]; nodes.resize(n_nodes1); for ( int j=0;j& cells = m_cells[i]; ds.read(n_cells1); cells.resize(n_cells1); for (int j=0;j& cell_maps = m_cell_map[i]; ds.read(n_cell_maps1); cell_maps.resize(n_cell_maps1); for (int j=0;j().eval(); unsigned int mi[3] = {(unsigned int )tmpmi[0],(unsigned int )tmpmi[1],(unsigned int )tmpmi[2]}; if (mi[0] >= m_resolution[0]) mi[0] = m_resolution[0]-1; if (mi[1] >= m_resolution[1]) mi[1] = m_resolution[1]-1; if (mi[2] >= m_resolution[2]) mi[2] = m_resolution[2]-1; btMultiIndex mui; mui.ijk[0] = mi[0]; mui.ijk[1] = mi[1]; mui.ijk[2] = mi[2]; int i = multiToSingleIndex(mui); unsigned int i_ = m_cell_map[field_id][i]; if (i_ == UINT_MAX) return false; btAlignedBox3d sd = subdomain(i); i = i_; btVector3 d = sd.m_max-sd.m_min;//.diagonal().eval(); btVector3 denom = (sd.max() - sd.min()); btVector3 c0 = btVector3(2.0,2.0,2.0)/denom; btVector3 c1 = (sd.max() + sd.min())/denom; btVector3 xi = (c0*x - c1); btCell32 const& cell = m_cells[field_id][i]; if (!gradient) { //auto phi = m_coefficients[field_id][i].dot(shape_function_(xi, 0)); double phi = 0.0; btShapeMatrix N = shape_function_(xi, 0); for (unsigned int j = 0u; j < 32u; ++j) { unsigned int v = cell.m_cells[j]; double c = m_nodes[field_id][v]; if (c == DBL_MAX) { return false;; } phi += c * N[j]; } dist = phi; return true; } btShapeGradients dN; btShapeMatrix N = shape_function_(xi, &dN); double phi = 0.0; gradient->setZero(); for (unsigned int j = 0u; j < 32u; ++j) { unsigned int v = cell.m_cells[j]; double c = m_nodes[field_id][v]; if (c == DBL_MAX) { gradient->setZero(); return false; } phi += c * N[j]; (*gradient)[0] += c * dN(j, 0); (*gradient)[1] += c * dN(j, 1); (*gradient)[2] += c * dN(j, 2); } (*gradient) *= c0; dist = phi; return true; }