Example #1
0
std::list<Polygon_with_holes_2> CstmCGAL::splitPoly(const Polygon_with_holes_2& poly) {
    std::vector<Point_2> outerBoundary = std::vector<Point_2>(
            poly.outer_boundary().vertices_begin(),poly.outer_boundary().vertices_end());

    std::list<Polygon_with_holes_2> result;

    for (unsigned int i = 0 ; i < outerBoundary.size() ; i++) {
        for (unsigned int j = i+1 ; j < outerBoundary.size() ; j++) {
            if (outerBoundary[i] == outerBoundary[j]) {
                result.splice(result.end(), splitPoly(Polygon_with_holes_2(
                        Polygon_2(outerBoundary.begin() + i, outerBoundary.begin() + j)
                                                      )));

                for (unsigned int k = i+1 ; k < outerBoundary.size() ; k++) {
                    outerBoundary[k] = outerBoundary[k + j - i];
                }

                outerBoundary.resize(outerBoundary.size() - j + i);
                break;
            }
        }
    }

    result.push_back(Polygon_with_holes_2(
                         Polygon_2(outerBoundary.begin(), outerBoundary.end())));

    return result;
}
//------------------------------------------------------------------------------
void ShadowVolumeBSP::clipPoly(SVNode * root, SVPoly ** store, SVPoly * poly)
{
    if(!root)
    {
        recyclePoly(poly);
        return;
    }

    const PlaneF & plane = getPlane(root->mPlaneIndex);

    switch(whichSide(poly, plane))
    {
    case SVNode::On:
    case SVNode::Back:
        if(root->mBack)
            clipPoly(root->mBack, store, poly);
        else
            addToPolyList(store, poly);
        break;

    case SVNode::Front:
        // encountered POLY node?
        if(!root->mFront)
        {
            recyclePoly(poly);
            return;
        }
        else
            clipPoly(root->mFront, store, poly);
        break;

    case SVNode::Split:
    {
        SVPoly * front;
        SVPoly * back;

        splitPoly(poly, plane, &front, &back);
        AssertFatal(front && back, "ShadowVolumeBSP::clipPoly: invalid split");
        recyclePoly(poly);

        // front
        if(!root->mFront)
        {
            recyclePoly(front);
            return;
        }
        else
            clipPoly(root->mFront, store, front);

        // back
        if(root->mBack)
            clipPoly(root->mBack, store, back);
        else
            addToPolyList(store, back);
        break;
    }
    }
}
//------------------------------------------------------------------------------
bool ShadowVolumeBSP::testPoly(SVNode * root, SVPoly * poly)
{
    const PlaneF & plane = getPlane(root->mPlaneIndex);
    switch(whichSide(poly, plane))
    {
    case SVNode::On:
    case SVNode::Front:
        if(root->mFront)
            return(testPoly(root->mFront, poly));

        recyclePoly(poly);
        return(true);

    case SVNode::Back:
        if(root->mBack)
            return(testPoly(root->mBack, poly));
        recyclePoly(poly);
        break;

    case SVNode::Split:
    {
        if(!root->mFront)
        {
            recyclePoly(poly);
            return(true);
        }

        SVPoly * front;
        SVPoly * back;

        splitPoly(poly, plane, &front, &back);
        recyclePoly(poly);

        if(testPoly(root->mFront, front))
        {
            recyclePoly(back);
            return(true);
        }

        if(root->mBack)
            return(testPoly(root->mBack, back));

        recyclePoly(back);
        break;
    }
    }
    return(false);
}
void ShadowVolumeBSP::insertPoly(SVNode ** root, SVPoly * poly)
{
    if(!(*root))
    {
        insertShadowVolume(root, poly->mShadowVolume);

        if(poly->mSurfaceInfo && !mFirstInteriorNode)
            mFirstInteriorNode = mShadowVolumes[poly->mShadowVolume];

        if(poly->mTarget)
            addUniqueVolume(poly->mTarget->mSurfaceInfo, poly->mShadowVolume);

        recyclePoly(poly);
        return;
    }

    const PlaneF & plane = getPlane((*root)->mPlaneIndex);

    //
    switch(whichSide(poly, plane))
    {
    case SVNode::On:
    case SVNode::Front:
        insertPolyFront(root, poly);
        break;

    case SVNode::Back:
        insertPolyBack(root, poly);
        break;

    case SVNode::Split:
    {
        SVPoly * front;
        SVPoly * back;

        splitPoly(poly, plane, &front, &back);
        recyclePoly(poly);

        insertPolyFront(root, front);
        insertPolyBack(root, back);

        break;
    }
    }
}
void SludgeFloorMaker::button1Release(int local_pointx, int local_pointy)
{
		int xx, yy;

		awaitButton1Release = FALSE;

		selx2 = xx = (local_pointx+x)*zmul;
		sely2 = yy = (local_pointy-y)*zmul;

		lit = snapToClosest(&xx, &yy, getFloor());
		litX = xx; 
		litY = yy;
						
		if (lit && (xx != selx1 || yy != sely1)) {
			selx2 = xx;
			sely2 = yy;
		}
												
		selection = 0;

		switch (mode) {
			case 1: // Move vertices
				if (moveVertices(selx1, sely1, selx2, sely2, getFloor())) {
					setFileChanged();
				} else {
					errorBox("Can't move vertex", "Sorry - that vertex is already contained in one or more of the polygons you're changing.");
					return;
				}
			
				break;

			case 4: // Split lines
				splitLine(selx1, sely1, selx2, sely2, getFloor());
				setFileChanged();
				break;
			case 5: // Split segments
				struct polyList * firstPoly = getFloor();
				splitPoly(selx1, sely1, selx2, sely2, &firstPoly);
				setFloor(firstPoly);
				setFileChanged();
				break;
		}
}
// clip a poly to it's own shadow volume
void ShadowVolumeBSP::clipToSelf(SVNode * root, SVPoly ** store, SVPoly * poly)
{
    if(!root)
    {
        addToPolyList(store, poly);
        return;
    }

    const PlaneF & plane = getPlane(root->mPlaneIndex);

    switch(whichSide(poly, plane))
    {
    case SVNode::Front:
        clipToSelf(root->mFront, store, poly);
        break;

    case SVNode::On:
        addToPolyList(store, poly);
        break;

    case SVNode::Back:
        recyclePoly(poly);
        break;

    case SVNode::Split:
    {
        SVPoly * front = 0;
        SVPoly * back = 0;
        splitPoly(poly, plane, &front, &back);
        AssertFatal(front && back, "ShadowVolumeBSP::clipToSelf: invalid split");

        recyclePoly(poly);
        recyclePoly(back);

        clipToSelf(root->mFront, store, front);
        break;
    }
    }
}