Example #1
0
bool MeshProjection::projectLineOnMesh(const MeshFacetGrid& grid,
                                       const Base::Vector3f& v1, unsigned long f1,
                                       const Base::Vector3f& v2, unsigned long f2,
                                       const Base::Vector3f& vd,
                                       std::vector<Base::Vector3f>& polyline)
{
    Base::Vector3f dir(v2 - v1);
    Base::Vector3f base(v1), normal(vd % dir);
    normal.Normalize();
    dir.Normalize();


    std::vector<unsigned long> facets;

    // special case: start and endpoint inside same facet
    if (f1 == f2) {
        polyline.push_back(v1);
        polyline.push_back(v2);
        return true;
    }

    // cut all facets between the two endpoints
    MeshGridIterator gridIter(grid);
    for (gridIter.Init(); gridIter.More(); gridIter.Next()) {
        // bbox cuts plane
        if (bboxInsideRectangle(gridIter.GetBoundBox(), v1, v2, vd))
            gridIter.GetElements(facets);
    }

    std::sort(facets.begin(), facets.end());
    facets.erase(std::unique(facets.begin(), facets.end()), facets.end());

    // cut all facets with plane
    std::list< std::pair<Base::Vector3f, Base::Vector3f> > cutLine;
    //unsigned long start = 0, end = 0;
    for (std::vector<unsigned long>::iterator it = facets.begin(); it != facets.end(); ++it) {
        Base::Vector3f e1, e2;
        MeshGeomFacet tria = kernel.GetFacet(*it);
        if (bboxInsideRectangle(tria.GetBoundBox(), v1, v2, vd)) {
            if (tria.IntersectWithPlane(base, normal, e1, e2)) {
                if ((*it != f1) && (*it != f2)) {
                    // inside cut line
                    if ((isPointInsideDistance(v1, v2, e1) == false) ||
                        (isPointInsideDistance(v1, v2, e2) == false)) {
                        continue;
                    }

                    cutLine.push_back(std::pair<Base::Vector3f, Base::Vector3f>(e1, e2));
                }
                else {
                    if (*it == f1) { // start facet
                        if (((e2 - v1) * dir) > 0.0f)
                            cutLine.push_back(std::pair<Base::Vector3f, Base::Vector3f>(v1, e2));
                        else
                            cutLine.push_back(std::pair<Base::Vector3f, Base::Vector3f>(v1, e1));

                        //start = it - facets.begin();
                    }

                    if (*it == f2) { // end facet
                        if (((e2 - v2) * -dir) > 0.0f)
                            cutLine.push_back(std::pair<Base::Vector3f, Base::Vector3f>(v2, e2));
                        else
                            cutLine.push_back(std::pair<Base::Vector3f, Base::Vector3f>(v2, e1));

                        //end = it - facets.begin();
                    }
                }
            }
        }
    }

    return connectLines(cutLine, v1, v2, polyline);
}