예제 #1
0
//static int matchCounter = 0;
bool SetOperations::CollectFacetVisitor::AllowVisit (const MeshFacet& rclFacet, const MeshFacet& rclFrom, unsigned long ulFInd, unsigned long ulLevel, unsigned short neighbourIndex)
{
  if (rclFacet.IsFlag(MeshFacet::MARKED) && rclFrom.IsFlag(MeshFacet::MARKED))
  { // facet connected to an edge
    unsigned long pt0 = rclFrom._aulPoints[neighbourIndex], pt1 = rclFrom._aulPoints[(neighbourIndex+1)%3];
    Edge edge(_mesh.GetPoint(pt0), _mesh.GetPoint(pt1));

    std::map<Edge, EdgeInfo>::iterator it = _edges.find(edge);

    if (it != _edges.end())
    {
      if (_addFacets == -1)
      { // detemine if the facets shoud add or not only once
        MeshGeomFacet facet = _mesh.GetFacet(rclFrom); // triangulated facet
        MeshGeomFacet facetOther = it->second.facets[1-_side][0]; // triangulated facet from same edge and other mesh
        Vector3f normalOther = facetOther.GetNormal();
        //Vector3f normal = facet.GetNormal();

        Vector3f edgeDir = it->first.pt1 - it->first.pt2;
        Vector3f ocDir = (edgeDir % (facet.GetGravityPoint() - it->first.pt1)) % edgeDir;
        ocDir.Normalize();
        Vector3f ocDirOther = (edgeDir % (facetOther.GetGravityPoint() - it->first.pt1)) % edgeDir;
        ocDirOther.Normalize();

        //Vector3f dir = ocDir % normal;
        //Vector3f dirOther = ocDirOther % normalOther;

        bool match = ((ocDir * normalOther) * _mult) < 0.0f;

        //if (matchCounter == 1)
        //{
        //  // _builder.addSingleArrow(it->second.pt1, it->second.pt1 + edgeDir, 3, 0.0, 1.0, 0.0);

        //  _builder.addSingleTriangle(facet._aclPoints[0], facet._aclPoints[1], facet._aclPoints[2], true, 3.0, 1.0, 0.0, 0.0);
        //  // _builder.addSingleArrow(facet.GetGravityPoint(), facet.GetGravityPoint() + ocDir, 3, 1.0, 0.0, 0.0);
        //  _builder.addSingleArrow(facet.GetGravityPoint(), facet.GetGravityPoint() + normal, 3, 1.0, 0.5, 0.0);
        //  // _builder.addSingleArrow(facet.GetGravityPoint(), facet.GetGravityPoint() + dir, 3, 1.0, 1.0, 0.0);

        //  _builder.addSingleTriangle(facetOther._aclPoints[0], facetOther._aclPoints[1], facetOther._aclPoints[2], true, 3.0, 0.0, 0.0, 1.0);
        //  // _builder.addSingleArrow(facetOther.GetGravityPoint(), facetOther.GetGravityPoint() + ocDirOther, 3, 0.0, 0.0, 1.0);
        //  _builder.addSingleArrow(facetOther.GetGravityPoint(), facetOther.GetGravityPoint() + normalOther, 3, 0.0, 0.5, 1.0);
        //  // _builder.addSingleArrow(facetOther.GetGravityPoint(), facetOther.GetGravityPoint() + dirOther, 3, 0.0, 1.0, 1.0);

        //}

       // float scalar = dir * dirOther * _mult;
       // bool match = scalar > 0.0f;


        //MeshPoint pt0 = it->first.pt1;
        //MeshPoint pt1 = it->first.pt2;

        //int i, n0 = -1, n1 = -1, m0 = -1, m1 = -1;
        //for (i = 0; i < 3; i++)
        //{
        //  if ((n0 == -1) && (facet._aclPoints[i] == pt0))
        //    n0 = i;
        //  if ((n1 == -1) && (facet._aclPoints[i] == pt1))
        //    n1 = i;
        //  if ((m0 == -1) && (facetOther._aclPoints[i] == pt0))
        //    m0 = i;
        //  if ((m1 == -1) && (facetOther._aclPoints[i] == pt1))
        //    m1 = i;
        //}

        //if ((n0 != -1) && (n1 != -1) && (m0 != -1) && (m1 != -1))
        //{
        //  bool orient_n = n1 > n0;
        //  bool orient_m = m1 > m0;

        //  Vector3f dirN = facet._aclPoints[n1] - facet._aclPoints[n0];
        //  Vector3f dirM = facetOther._aclPoints[m1] - facetOther._aclPoints[m0];

        //  if (matchCounter == 1)
        //  {
        //    _builder.addSingleArrow(facet.GetGravityPoint(), facet.GetGravityPoint() + dirN, 3, 1.0, 1.0, 0.0);
        //    _builder.addSingleArrow(facetOther.GetGravityPoint(), facetOther.GetGravityPoint() + dirM, 3, 0.0, 1.0, 1.0);
        //  }

        //  if (_mult > 0.0)
        //    match = orient_n == orient_m;
        //  else
        //    match = orient_n != orient_m;
        //}
  
        if (match)
          _addFacets = 0;
        else
          _addFacets = 1;

        //matchCounter++;
      }

      return false;
    }    
  }

  return true;
}
예제 #2
0
CurvatureInfo FacetCurvature::Compute(unsigned long index) const
{
    Base::Vector3f rkDir0, rkDir1, rkPnt;
    Base::Vector3f rkNormal;

    MeshGeomFacet face = myKernel.GetFacet(index);
    Base::Vector3f face_gravity = face.GetGravityPoint();
    Base::Vector3f face_normal = face.GetNormal();
    std::set<unsigned long> point_indices;
    FitPointCollector collect(point_indices);

    float searchDist = myRadius;
    int attempts=0;
    do {
        mySearch.Neighbours(index, searchDist, collect);
        if (point_indices.empty())
            break;
        float min_points = myMinPoints;
        float use_points = point_indices.size();
        searchDist = searchDist * sqrt(min_points/use_points);
    }
    while((point_indices.size() < myMinPoints) && (attempts++ < 3));

    std::vector<Base::Vector3f> fitPoints;
    const MeshPointArray& verts = myKernel.GetPoints();
    fitPoints.reserve(point_indices.size());
    for (std::set<unsigned long>::iterator it = point_indices.begin(); it != point_indices.end(); ++it) {
        fitPoints.push_back(verts[*it] - face_gravity);
    }

    float fMin, fMax;
    if (fitPoints.size() >= myMinPoints) {
        SurfaceFit surf_fit;
        surf_fit.AddPoints(fitPoints);
        surf_fit.Fit();
        rkNormal = surf_fit.GetNormal();
        double dMin, dMax, dDistance;
        if (surf_fit.GetCurvatureInfo(0.0, 0.0, 0.0, dMin, dMax, rkDir1, rkDir0, dDistance)) {
            fMin = (float)dMin;
            fMax = (float)dMax;
        }
        else {
            fMin = FLT_MAX;
            fMax = FLT_MAX;
        }
    }
    else {
        // too few points => cannot calc any properties
        fMin = FLT_MAX;
        fMax = FLT_MAX;
    }

    CurvatureInfo info;
    if (fMin < fMax) {
        info.fMaxCurvature = fMax;
        info.fMinCurvature = fMin;
        info.cMaxCurvDir = rkDir1;
        info.cMinCurvDir = rkDir0;
    }
    else {
        info.fMaxCurvature = fMin;
        info.fMinCurvature = fMax;
        info.cMaxCurvDir = rkDir0;
        info.cMinCurvDir = rkDir1;
    }

    // Reverse the direction of the normal vector if required
    // (Z component of "local" normal vectors should be opposite in sign to the "local" view vector)
    if (rkNormal * face_normal < 0.0) {
        // Note: Changing the normal directions is similar to flipping over the object.
        // In this case we must adjust the curvature information as well.
        std::swap(info.cMaxCurvDir,info.cMinCurvDir);
        std::swap(info.fMaxCurvature,info.fMinCurvature);
        info.fMaxCurvature *= (-1.0);
        info.fMinCurvature *= (-1.0);
    }

    return info;
}