14 #include <boost/multi_array.hpp>
31 this->spreadAngles = newSpreadAngles;
32 this->center = center;
37 Matrix SLE = Matrix::Constant(nControlPoints, nControlPoints, 1.0);
38 using CacheType = boost::multi_array<Real, 3>;
39 CacheType cache(boost::extents[this->nDoF][3][3]);
41 for (
int iDoF = 0; iDoF < this->nDoF; iDoF++)
43 for (
int idx = 0; idx < 3; idx++)
44 for (
int idx2 = 0; idx2 < 3; idx2++)
47 if (
static_cast<unsigned int>(iDoF) != subdividedDoF)
51 cache[iDoF][idx][idx2] = 0.0f;
55 cache[iDoF][idx][idx2] = 1.0f;
65 a1 = (newCenter - this->center(iDoF)) - newSpreadAngle;
66 a2 = (newCenter - this->center(iDoF)) - newSpreadAngle;
70 a1 = (newCenter - this->center(iDoF)) - newSpreadAngle;
71 a2 = (newCenter - this->center(iDoF)) + newSpreadAngle;
75 a1 = (newCenter - this->center(iDoF)) + newSpreadAngle;
76 a2 = (newCenter - this->center(iDoF)) + newSpreadAngle;
81 Real t1 = std::tan(a1 / 2.0) / tan(this->spreadAngles[iDoF] / 2.0) / 2.0 + 0.5;
82 Real t2 = std::tan(a2 / 2.0) / tan(this->spreadAngles[iDoF] / 2.0) / 2.0 + 0.5;
88 cache[iDoF][idx][idx2] = (1 - t1) * (1 - t2);
92 cache[iDoF][idx][idx2] = ((1 - t1) * t2 + (1 - t2) * t1) * std::cos(this->spreadAngles[iDoF]);
96 cache[iDoF][idx][idx2] = t1 * t2;
107 for (
int iSamples = 0; iSamples < nControlPoints; iSamples++)
111 for (
int iControlPoints = 0; iControlPoints < nControlPoints; iControlPoints++)
115 for (
int iDoF = 0; iDoF < this->nDoF; iDoF++)
117 int idx = this->index(iControlPoints, iDoF);
118 int idx2 = this->index(iSamples, iDoF);
120 SLE(iControlPoints, iSamples) *= cache[iDoF][idx][idx2];
124 weight += SLE(iControlPoints, iSamples);
127 for (
int iControlPoints = 0; iControlPoints < nControlPoints; iControlPoints++)
129 SLE(iControlPoints, iSamples) /= weight;
134 resultingControlNet = this->controlNet * SLE;
141 Matrix SLE = Matrix::Constant(nControlPoints, nControlPoints, 1.0);
143 using CacheType = boost::multi_array<Real, 3>;
144 CacheType cache(boost::extents[this->nDoF][3][3]);
146 for (
int iDoF = 0; iDoF < this->nDoF; iDoF++)
148 for (
int idx = 0; idx < 3; idx++)
149 for (
int idx2 = 0; idx2 < 3; idx2++)
156 a1 = (newCenter(iDoF) - this->center(iDoF)) - newSpreadAngles[iDoF];
157 a2 = (newCenter(iDoF) - this->center(iDoF)) - newSpreadAngles[iDoF];
161 a1 = (newCenter(iDoF) - this->center(iDoF)) - newSpreadAngles[iDoF];
162 a2 = (newCenter(iDoF) - this->center(iDoF)) + newSpreadAngles[iDoF];
166 a1 = (newCenter(iDoF) - this->center(iDoF)) + newSpreadAngles[iDoF];
167 a2 = (newCenter(iDoF) - this->center(iDoF)) + newSpreadAngles[iDoF];
172 Real t1 = std::tan(a1 / 2.0) / tan(this->spreadAngles[iDoF] / 2.0) / 2.0 + 0.5;
173 Real t2 = std::tan(a2 / 2.0) / tan(this->spreadAngles[iDoF] / 2.0) / 2.0 + 0.5;
179 cache[iDoF][idx][idx2] = (1 - t1) * (1 - t2);
183 cache[iDoF][idx][idx2] = ((1 - t1) * t2 + (1 - t2) * t1) * std::cos(this->spreadAngles[iDoF]);
187 cache[iDoF][idx][idx2] = t1 * t2;
195 for (
int iSamples = 0; iSamples < nControlPoints; iSamples++)
199 for (
int iControlPoints = 0; iControlPoints < nControlPoints; iControlPoints++)
203 for (
int iDoF = 0; iDoF < this->nDoF; iDoF++)
205 int idx = this->index(iControlPoints, iDoF);
206 int idx2 = this->index(iSamples, iDoF);
207 SLE(iControlPoints, iSamples) *= cache[iDoF][idx][idx2];
211 weight += SLE(iControlPoints, iSamples);
214 for (
int iControlPoints = 0; iControlPoints < nControlPoints; iControlPoints++)
216 SLE(iControlPoints, iSamples) /= weight;
221 resultingControlNet = this->controlNet * SLE;
243 bool included =
true;
245 for (
int i = 0; i < lower.size(); i++)
247 if ((BBlower(i) > (upper(i)) + tolerance) || BBupper(i) <= (lower(i) - tolerance))
252 if ((BBlower(i) < lower(i)) || (BBupper(i) > upper(i)))
257 if ((BBlower(i) > lower(i)) || (BBupper(i) < upper(i)))
285 lower = controlNet.rowwise().minCoeff();
286 upper = controlNet.rowwise().maxCoeff();
291 getBBox(lower, upper, this->controlNet);
298 Vector size = upper - lower;
305 return volume / targetVolume;
311 this->
getBBox(BBlower, BBupper);
314 for (
int i = 0; i < lower.size(); i++)
356 kbm->getSubdivisedNet(center, spreadAngles, controlNet);
364 Solution solution(center, spreadAngles, BBupper, BBlower, check);
369 solutionSet.push_back(solution);
370 ARMARX_DEBUG_S <<
"Disjoint: " << std::string(recursion * 2,
'-') << recursion <<
":" << side << std::endl;
380 solutionSet.push_back(solution);
381 ARMARX_DEBUG_S <<
"Covered: " << std::string(recursion * 2,
'-') << recursion <<
":" << side << std::endl;
388 if (spreadAngles.maxCoeff() <= resolution)
393 ARMARX_DEBUG_S <<
"Max Res: " << std::string(recursion * 2,
'-') << recursion <<
":" << side << std::endl <<
"center: " << center.transpose() <<
", max. angle: " << spreadAngles.maxCoeff()
394 <<
", lower: " << lower.transpose() <<
", upper: " << upper.transpose()
395 <<
", BB-lower: " << BBlower.transpose() <<
", BB-upper: " << BBupper.transpose() << std::endl;
399 solutionSet.push_back(solution);
402 ARMARX_DEBUG_S <<
"Max Res: " << std::string(recursion * 2,
'-') << recursion <<
":" << side << std::endl;
411 ARMARX_DEBUG_S <<
"Subdivide: " << std::string(recursion * 2,
'-') << recursion <<
":" << side << std::endl;
415 unsigned int dof = recursion % kbm->getNDoF();
416 center1(dof) = center(dof) + spreadAngles[dof] / 2.0f;
417 center2(dof) = center(dof) - spreadAngles[dof] / 2.0f;
418 spreadAngles[dof] /= 2.0f;
419 solveGlobalIK(recursion + 1, 1, solutionSet, kbm, lower, upper, resolution, spreadAngles, center1);
420 solveGlobalIK(recursion + 1, 2, solutionSet, kbm, lower, upper, resolution, spreadAngles, center2);
427 solveGlobalIK(0, 0, solution, kbm, lower, upper, resolution, kbm->getSpreadAngles(), kbm->getCenter());
454 unsigned int dof = recursion % kbm->getNDoF();
455 kbm->getSubdivisedNet(dof, center[dof], spreadAngles[dof], controlNet);
458 kbm->getSubdivisedNet(center, spreadAngles, controlNet2);
459 ARMARX_DEBUG_S <<
"Similarity of Dof " << dof <<
": " << controlNet.isApprox(controlNet2) << std::endl;
468 unsigned int dof = recursion % kbm->getNDoF();
469 center = kbm->getCenter();
470 spreadAngles = kbm->getSpreadAngles();
474 center(dof) = center(dof) - spreadAngles[dof] / 2.0f;
478 center(dof) = center(dof) + spreadAngles[dof] / 2.0f;
481 spreadAngles[dof] /= 2.0f;
489 kbm->getBBox(BBupper, BBlower);
490 Solution solution(kbm->getCenter(), kbm->getSpreadAngles(), BBupper, BBlower, check);
506 if (kbm->getSpreadAngles().maxCoeff() <=
resolution)
538 ARMARX_DEBUG_S <<
"breadth " << std::string(level * 2,
'-') << level << std::endl;
542 ARMARX_DEBUG_S <<
"depth " << std::string(level * 2,
'-') << level <<
": " << kbm->getSpreadAngles().maxCoeff() /
M_PI * 180.0f << std::endl;
554 assert(overlap == 0.0f);
568 if (kbm->getSpreadAngles().maxCoeff() <=
resolution)
587 GraphNode initial(kbm, ratio, level, kbm->getVolume());
601 ARMARX_DEBUG_S <<
"Reduction by subdivision: " << 100.f* sub1->getVolume() / kbm->getVolume() <<
"%, " << sub2->getVolume() / kbm->getVolume() * 100.f <<
"%" << std::endl;
602 ARMARX_DEBUG_S <<
"Target overlapping: " << ratio1 * 100.f <<
"%, " << ratio2 * 100.f <<
"%, " << this->
targetVolume << std::endl;
613 n = this->
recurse(level + 1, sub1);
617 n = this->
recurse(level + 1, sub2);
620 if (breadth || n == 0)
626 n += this->
recurse(level + 1, sub2);
630 n += this->
recurse(level + 1, sub1);
661 std::priority_queue<GraphNode> priority_queue;
663 priority_queue.push(initial);
666 while (!priority_queue.empty())
668 GraphNode topNode = priority_queue.top();
670 priority_queue.pop();
672 if (topNode.
ratio == 1.0)
682 Real volume = child->getVolume();
688 priority_queue.push(
GraphNode(child, ratio, topNode.
level + 1, volume));
689 std::cout << side + 1 <<
". Ratio: " << ratio <<
" (" << ratio / topNode.
ratio * 100.0f <<
"%), Vol.: " << volume / topNode.
volume * 100.f <<
"%, ";
698 std::cout <<
"Resolution: " << topNode.
model->getSpreadAngles().maxCoeff() ;
701 std::cout <<
", " << topNode.
model->getSpreadAngles().maxCoeff() /
M_PI * 180.0f <<
"(" <<
resolution /
M_PI * 180.0f <<
")" <<
", Level: " << topNode.
level << std::endl;