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, ¢roid); 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); }
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(); }