Пример #1
0
static void
computeBestFitOBB(TheaArray<Vector3> const & points, Box3 & result, bool has_up, Vector3 const & up)
{
  if (points.empty())
  {
    result = Box3();
    return;
  }
  else if (points.size() == 1)
  {
    result = Box3(AxisAlignedBox3(points[0]));
    return;
  }

  Vector3 centroid;
  CoordinateFrame3 cframe;

  if (has_up)
  {
    centroid = CentroidN<Vector3, 3>::compute(points.begin(), points.end());
    Vector3 u, v;
    up.createOrthonormalBasis(u, v);
    cframe = CoordinateFrame3::_fromAffine(AffineTransform3(basisMatrix(u, v, up), centroid));
  }
  else
  {
    Plane3 plane;
    LinearLeastSquares3<Vector3>::fitPlane(points.begin(), points.end(), plane, &centroid);
    planeToCFrame(plane, centroid, cframe);
  }

  OBB best_obb;
  computeOBB(points, cframe, best_obb, true);

  Matrix3 rot = Matrix3::rotationAxisAngle((has_up ? up : Vector3::unitY()), Math::degreesToRadians(10));
  for (int a = 10;  a < 180; a += 10)
  {
    cframe._setRotation(cframe.getRotation() * rot);
    computeOBB(points, cframe, best_obb, false);
  }

  result = Box3(AxisAlignedBox3(best_obb.lo, best_obb.hi), best_obb.cframe);
}
Пример #2
0
    static long findEdgeConnected(MeshT & mesh, TheaArray< TheaArray<FaceHandleT> > & components,
                                  typename boost::enable_if< Graphics::IsCGALMesh<MeshT> >::type * dummy = NULL)
    {
      // Begin with all faces as separate components
      TheaArray<typename MeshT::Facet *> facets;
      for (typename MeshT::Facet_iterator fi = mesh.facets_begin(); fi != mesh.facets_end(); fi++)
        facets.push_back(&(*fi));

      typedef UnionFind<typename MeshT::Facet *> FacetUnionFind;
      FacetUnionFind uf(facets.begin(), facets.end());

      // Now go over all edges, connecting the faces on either side
      for (typename MeshT::Edge_iterator ei = mesh.edges_begin(); ei != mesh.edges_end(); ei++)
      {
        if (!ei->is_border_edge())
        {
          long handle1 = uf.getObjectID(&(*ei->facet()));
          long handle2 = uf.getObjectID(&(*ei->opposite()->facet()));
          uf.merge(handle1, handle2);
        }
      }

      // Reserve space for the result
      components.resize((array_size_t)uf.numSets());

      typedef TheaUnorderedMap<long, array_size_t> ComponentIndexMap;
      ComponentIndexMap component_indices;

      // Loop over facets, adding each to the appropriate result subarray
      array_size_t component_index;
      for (typename MeshT::Facet_iterator fi = mesh.facets_begin(); fi != mesh.facets_end(); fi++)
      {
        long rep = uf.find(uf.getObjectID(&(*fi)));
        typename ComponentIndexMap::const_iterator existing = component_indices.find(rep);
        if (existing == component_indices.end())
        {
          component_index = component_indices.size();
          component_indices[rep] = component_index;
          components[component_index].clear();
          components[component_index].reserve(uf.sizeOfSet(rep));
        }
        else
          component_index = existing->second;

        components[component_index].push_back(fi);
      }

      return (long)components.size();
    }