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; } } }