59    template <
class triangulationType = AbstractTriangulation>
 
   85    template <
class scalarT>
 
   92    template <
class triangulationType = AbstractTriangulation>
 
   97    template <
class triangulationType = AbstractTriangulation>
 
  100    template <
typename scalarT, 
class triangulationType = AbstractTriangulation>
 
  108    template <
typename scalarT, 
class triangulationType = AbstractTriangulation>
 
  115    template <
typename scalarT, 
class triangulationType = AbstractTriangulation>
 
  116    void extendOutPts(
const std::vector<SimplexId> &vertices,
 
  122    template <
class triangulationType = AbstractTriangulation>
 
  125        float x = 0, y = 0, z = 0;
 
  128        _radius = std::sqrt(x * x + y * y + z * z);
 
  130        _radius = std::numeric_limits<double>::signaling_NaN();
 
 
  171    template <
class Po
intIterable, 
class WeightIterable>
 
  173      array<double, std::tuple_size<typename PointIterable::value_type>::value>
 
  174      average(
const PointIterable &pts, 
const WeightIterable &ws);
 
 
  225  _outContoursCinfos.resize(0);
 
  227  _outContoursCoords.resize(0);
 
  228  _outContoursScalars.resize(0);
 
  229  _outContoursFlags.resize(0);
 
  231  _outCentroidsCoords.resize(0);
 
  232  _outCentroidsScalars.resize(0);
 
  233  _outCentroidsFlags.resize(0);
 
  235#ifndef TTK_ENABLE_KAMIKAZE 
  257  for(
size_t p = 0; p < _inpPtsNum; ++p) {
 
  258    handleOneInpPt<scalarT>(
 
  259      findInpFldVert(p), _inpPtsIsovals[p], _inpPtsFlags[p], _inpPtsScalars[p]);
 
 
  303                                             float scalar)
 const {
 
  304  auto triang = 
reinterpret_cast<Triang *
>(_inpFldTriang);
 
  305  auto inpScalars = 
reinterpret_cast<const scalarT *
>(_inpFldScalars);
 
  306  const bool vBegIsMin = flag == 0;
 
  315  auto innerVerts = std::vector<SimplexId>{vBeg};
 
  316  std::set<SimplexId> xEdges; 
 
  322  std::vector<VertEdge> q;
 
  323  std::set<SimplexId> handledEdges;
 
  325  auto enqueueNeighbors = [triang, &q, &handledEdges](
SimplexId vSrc) {
 
  326    const auto n = triang->getVertexEdgeNumber(vSrc);
 
  329      triang->getVertexEdge(vSrc, i, e);
 
  330      if(handledEdges.count(e))
 
  332      handledEdges.insert(e);
 
  336      triang->getVertexNeighbor(vSrc, i, vTgt);
 
  337      q.push_back({vTgt, e});
 
  341  enqueueNeighbors(vBeg);
 
  343    const auto ve = q.back();
 
  346    const bool vIsAboveIso = inpScalars[v] > isoval;
 
  347    if(vBegIsMin == vIsAboveIso) { 
 
  350      innerVerts.push_back(v);
 
  355  if(innerVerts.size() < _sizeMin)
 
  357  extendOutFld<scalarT>(xEdges, isoval, flag);
 
  358  extendOutPts<scalarT>(innerVerts, isoval, flag, scalar);
 
 
  366  auto triang = 
reinterpret_cast<Triang *
>(_inpFldTriang);
 
  367  auto inpScalars = 
reinterpret_cast<const scalarT *
>(_inpFldScalars);
 
  376  std::map<SimplexId, SimplexId> inpe2outv;
 
  378  auto getOrMakeOutVert = [&](
SimplexId e) {
 
  379    if(inpe2outv.count(e))
 
  383    const SimplexId v = _outContoursScalars.size();
 
  387    triang->getEdgeVertex(e, 0, p);
 
  389    triang->getEdgeVertex(e, 1, q);
 
  391    const float pVal = 
static_cast<float>(inpScalars[p]);
 
  392    const float qVal = 
static_cast<float>(inpScalars[q]);
 
  393    const double pFac = (qVal - isoval) / (qVal - pVal);
 
  394    const double qFac = 1 - pFac;
 
  397    triang->getVertexPoint(p, px, py, pz);
 
  399    triang->getVertexPoint(q, qx, qy, qz);
 
  400    const float x = px * pFac + qx * qFac;
 
  401    const float y = py * pFac + qy * qFac;
 
  402    const float z = pz * pFac + qz * qFac;
 
  403    _outContoursCoords.push_back(x);
 
  404    _outContoursCoords.push_back(y);
 
  405    _outContoursCoords.push_back(z);
 
  407    _outContoursScalars.push_back(isoval);
 
  408    _outContoursFlags.push_back(flag);
 
  413  std::set<SimplexId> handledTris;
 
  416    printWrn(
"Currently only the *edges* of contour surfaces are computed");
 
  418  for(
const auto e : inpEdges) {
 
  419    const auto nTriLoc = triang->getEdgeTriangleNumber(e);
 
  423    const auto v = getOrMakeOutVert(e);
 
  425    for(
SimplexId tLoc = 0; tLoc < nTriLoc; ++tLoc) {
 
  427      triang->getEdgeTriangle(e, tLoc, tGlo);
 
  428      if(handledTris.count(tGlo))
 
  431      handledTris.insert(tGlo);
 
  433      for(
SimplexId eLoc = 0; eLoc < 3; ++eLoc) {
 
  435        triang->getTriangleEdge(tGlo, eLoc, eGlo);
 
  436        if(eGlo == e || !inpEdges.count(eGlo))
 
  440        _outContoursCinfos.push_back(2);
 
  441        _outContoursCinfos.push_back(v);
 
  442        _outContoursCinfos.push_back(getOrMakeOutVert(eGlo));
 
 
  452  const std::vector<SimplexId> &vertices,
 
  455  float extremeVal)
 const {
 
  457  auto triang = 
reinterpret_cast<Triang *
>(_inpFldTriang);
 
  458  auto inpScalars = 
reinterpret_cast<const scalarT *
>(_inpFldScalars);
 
  460  const double radius = _radius;
 
  461  const bool spherical = radius > 0.;
 
  466  const double scalarDiffMax = std::abs(isoval - extremeVal);
 
  469  const double kernelInputScaler = 
M_PI / scalarDiffMax;
 
  471  auto scalar_w = [kernelInputScaler](
double d) {
 
  472    return (std::cos(d * kernelInputScaler) + 1.) / 2.;
 
  479  const bool regularLonLat = spherical;
 
  483  const auto numVerts = vertices.size();
 
  484  auto pts4d = std::vector<std::array<float, 4>>(numVerts);
 
  485  auto ws = std::vector<double>(numVerts);
 
  486  for(std::size_t i = 0; i < numVerts; ++i) {
 
  488    const auto v = vertices[i];
 
  489    const scalarT vSca = inpScalars[v];
 
  492    const double scalarDiff = vSca - extremeVal;
 
  493    const double scalarW = scalar_w(scalarDiff);
 
  496    triang->getVertexPoint(v, x, y, z);
 
  497    pts4d[i] = {x, y, z, 
static_cast<float>(vSca)};
 
  503        printWrn(
"Vertex weighting does not consider vertex density of this " 
  513        static const auto compDist
 
  514          = [](
float ax, 
float ay, 
float az, 
float bx, 
float by, 
float bz) {
 
  515              const auto dx = bx - ax;
 
  516              const auto dy = by - ay;
 
  517              const auto dz = bz - az;
 
  518              return std::sqrt(dx * dx + dy * dy + dz * dz);
 
  523        static const auto compArea = [](
double a, 
double b, 
double c) {
 
  524          const double s = (a + b + c) / 2.; 
 
  527            3 * s * s - s * a - s * b
 
  534        float x2, y2, z2, x3, y3, z3;
 
  536        triang->getVertexNeighbor(v, 0, u);
 
  537        triang->getVertexPoint(u, x2, y2, z2);
 
  538        double a = compDist(x, y, z, x2, y2, z2);
 
  541        const float x2Bak = x2, y2Bak = y2, z2Bak = z2;
 
  542        const double aBak = a;
 
  544        const SimplexId n = triang->getVertexNeighborNumber(v);
 
  546          triang->getVertexNeighbor(v, j, u);
 
  547          triang->getVertexPoint(u, x3, y3, z3);
 
  548          const double b = compDist(x, y, z, x3, y3, z3);
 
  549          const double c = compDist(x2, y2, z2, x3, y3, z3);
 
  550          area += compArea(a, b, c);
 
  557        const double b = aBak;
 
  558        const double c = compDist(x2, y2, z2, x2Bak, y2Bak, z2Bak);
 
  559        area += compArea(a, b, c);
 
  561        ws[i] = scalarW * area;
 
  565      const double latInRad = std::asin(z / radius);
 
  567      const double spatialW = std::cos(latInRad);
 
  568      ws[i] = scalarW * spatialW;
 
  576  const auto res = average(pts4d, ws);
 
  582    const auto radiusCur = std::sqrt(x * x + y * y + z * z);
 
  583    const auto radiusScaler = radius / radiusCur;
 
  590  _outCentroidsCoords.push_back(
static_cast<float>(x));
 
  591  _outCentroidsCoords.push_back(
static_cast<float>(y));
 
  592  _outCentroidsCoords.push_back(
static_cast<float>(z));
 
  593  _outCentroidsScalars.push_back(
static_cast<float>(res[3]));
 
  594  _outCentroidsFlags.push_back(flag);