/* Calculates the signed supplement of an angle*/ double calculateSupplement(double theta){ return findSign(theta)*(PI-abs(theta)); }
void HoleRepairer::computeSignedDistanceField() { // distance field from the mesh std::cout << "Computing mesh distance field..." << std::endl; computeUDFmesh(&m_distanceGrid); // distance field from the hole std::cout << "Computing holes distance field..." << std::endl; computeUDFhole(&m_holeDistance); // compute the mask and final distance field std::cout << "Computing mask..." << std::endl; for (int i = 0; i < VOX_SAMPLES; i++) { for (int j = 0; j < VOX_SAMPLES; j++) { for (int k = 0; k < VOX_SAMPLES; k++) { float mdist = m_distanceGrid.get(i, j, k); float hdist = m_holeDistance.get(i, j, k); if (hdist < mdist + 0.5*glm::length(m_voxelSize)) { m_triangleMask.set(i, j, k, true); m_distanceGrid.set(i, j, k, mdist); } else { m_triangleMask.set(i, j, k, false); m_distanceGrid.set(i, j, k, mdist); } } } } std::cout << "Generating signed distance field..." << std::endl; // compute regions in the mask to propagate the sign Grid3D<int> regionGrid(VOX_SAMPLES, 0); int numRegions = 0; bool foundRegion = true; while (foundRegion) { foundRegion = false; for (int i = 0; i < VOX_SAMPLES; i++) { for (int j = 0; j < VOX_SAMPLES; j++) { for (int k = 0; k < VOX_SAMPLES; k++) { if (!m_triangleMask.get(i, j, k) && regionGrid.get(i, j, k) == 0) { numRegions++; foundRegion = true; floodRegion(®ionGrid, &m_triangleMask, m_surfaceSticks, i, j, k, numRegions); } } } } } // votes based on sticks std::vector<int> positiveVotes(numRegions+1, 0); std::vector<int> negativeVotes(numRegions+1, 0); for (std::set<std::pair<int, int> >::const_iterator it = m_surfaceSticks.begin(); it != m_surfaceSticks.end(); it++) { int v1id = it->first; int v2id = it->second; int i1 = v1id/(VOX_SAMPLES*VOX_SAMPLES); int j1 = (v1id%(VOX_SAMPLES*VOX_SAMPLES))/VOX_SAMPLES; int k1 = (v1id%(VOX_SAMPLES*VOX_SAMPLES))%VOX_SAMPLES; int i2 = v2id/(VOX_SAMPLES*VOX_SAMPLES); int j2 = (v2id%(VOX_SAMPLES*VOX_SAMPLES))/VOX_SAMPLES; int k2 = (v2id%(VOX_SAMPLES*VOX_SAMPLES))%VOX_SAMPLES; int r1 = regionGrid.get(i1, j1, k1); int r2 = regionGrid.get(i2, j2, k2); // if both endpoints are marked as positive, this is not a safe sign sample if (m_positivePoints.find(v1id) != m_positivePoints.end() && m_positivePoints.find(v2id) == m_positivePoints.end()) { positiveVotes[r1]++; negativeVotes[r2]++; } else if (m_positivePoints.find(v2id) != m_positivePoints.end() && m_positivePoints.find(v1id) == m_positivePoints.end()) { positiveVotes[r2]++; negativeVotes[r1]++; } } // define sign to regions according to votes std::vector<bool> setSign(numRegions+1, false); std::vector<bool> posRegion(numRegions+1, false); for (int i = 1; i <= numRegions; i++) { if (positiveVotes[i] != negativeVotes[i]) { setSign[i] = true; posRegion[i] = positiveVotes[i] > negativeVotes[i]; } } // assign sign for (int i = 0; i < VOX_SAMPLES; i++) { for (int j = 0; j < VOX_SAMPLES; j++) { for (int k = 0; k < VOX_SAMPLES; k++) { int rid = regionGrid.get(i, j, k); if (rid > 0) { float dist = m_distanceGrid.get(i, j, k); if (!setSign[rid]) { bool positive; findSign(®ionGrid, setSign, posRegion, m_surfaceSticks, i, j, k, positive); posRegion[rid] = positive; setSign[rid] = true; } if (!posRegion[rid]) { m_distanceGrid.set(i, j, k, -dist); } } } } } }