diff options
Diffstat (limited to 'basegfx/source/polygon/b3dpolygonclipper.cxx')
-rw-r--r-- | basegfx/source/polygon/b3dpolygonclipper.cxx | 577 |
1 files changed, 0 insertions, 577 deletions
diff --git a/basegfx/source/polygon/b3dpolygonclipper.cxx b/basegfx/source/polygon/b3dpolygonclipper.cxx deleted file mode 100644 index d8099b3e7b..0000000000 --- a/basegfx/source/polygon/b3dpolygonclipper.cxx +++ /dev/null @@ -1,577 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_basegfx.hxx" - -#include <basegfx/polygon/b3dpolygonclipper.hxx> -#include <osl/diagnose.h> -#include <basegfx/polygon/b3dpolygontools.hxx> -#include <basegfx/numeric/ftools.hxx> -#include <basegfx/matrix/b3dhommatrix.hxx> -#include <basegfx/polygon/b3dpolygontools.hxx> -#include <basegfx/range/b3drange.hxx> -#include <basegfx/point/b2dpoint.hxx> -#include <basegfx/range/b2drange.hxx> -#include <basegfx/color/bcolor.hxx> - -////////////////////////////////////////////////////////////////////////////// - -namespace basegfx -{ - namespace - { - inline bool impIsInside(const B3DPoint& rCandidate, double fPlaneOffset, tools::B3DOrientation ePlaneOrthogonal) - { - if(tools::B3DORIENTATION_X == ePlaneOrthogonal) - { - return fTools::moreOrEqual(rCandidate.getX(), fPlaneOffset); - } - else if(tools::B3DORIENTATION_Y == ePlaneOrthogonal) - { - return fTools::moreOrEqual(rCandidate.getY(), fPlaneOffset); - } - else - { - return fTools::moreOrEqual(rCandidate.getZ(), fPlaneOffset); - } - } - - inline double impGetCut(const B3DPoint& rCurrent, const B3DPoint& rNext, double fPlaneOffset, tools::B3DOrientation ePlaneOrthogonal) - { - if(tools::B3DORIENTATION_X == ePlaneOrthogonal) - { - return ((fPlaneOffset - rCurrent.getX())/(rNext.getX() - rCurrent.getX())); - } - else if(tools::B3DORIENTATION_Y == ePlaneOrthogonal) - { - return ((fPlaneOffset - rCurrent.getY())/(rNext.getY() - rCurrent.getY())); - } - else - { - return ((fPlaneOffset - rCurrent.getZ())/(rNext.getZ() - rCurrent.getZ())); - } - } - - void impAppendCopy(B3DPolygon& rDest, const B3DPolygon& rSource, sal_uInt32 nIndex) - { - rDest.append(rSource.getB3DPoint(nIndex)); - - if(rSource.areBColorsUsed()) - { - rDest.setBColor(rDest.count() - 1L, rSource.getBColor(nIndex)); - } - - if(rSource.areNormalsUsed()) - { - rDest.setNormal(rDest.count() - 1L, rSource.getNormal(nIndex)); - } - - if(rSource.areTextureCoordinatesUsed()) - { - rDest.setTextureCoordinate(rDest.count() - 1L, rSource.getTextureCoordinate(nIndex)); - } - } - - void impAppendInterpolate(B3DPolygon& rDest, const B3DPolygon& rSource, sal_uInt32 nIndA, sal_uInt32 nIndB, double fCut) - { - const B3DPoint aCurrPoint(rSource.getB3DPoint(nIndA)); - const B3DPoint aNextPoint(rSource.getB3DPoint(nIndB)); - rDest.append(interpolate(aCurrPoint, aNextPoint, fCut)); - - if(rSource.areBColorsUsed()) - { - const BColor aCurrBColor(rSource.getBColor(nIndA)); - const BColor aNextBColor(rSource.getBColor(nIndB)); - rDest.setBColor(rDest.count() - 1L, interpolate(aCurrBColor, aNextBColor, fCut)); - } - - if(rSource.areNormalsUsed()) - { - const B3DVector aCurrVector(rSource.getNormal(nIndA)); - const B3DVector aNextVector(rSource.getNormal(nIndB)); - rDest.setNormal(rDest.count() - 1L, interpolate(aCurrVector, aNextVector, fCut)); - } - - if(rSource.areTextureCoordinatesUsed()) - { - const B2DPoint aCurrTxCo(rSource.getTextureCoordinate(nIndA)); - const B2DPoint aNextTxCo(rSource.getTextureCoordinate(nIndB)); - rDest.setTextureCoordinate(rDest.count() - 1L, interpolate(aCurrTxCo, aNextTxCo, fCut)); - } - } - } -} // end of namespace basegfx - -////////////////////////////////////////////////////////////////////////////// - -namespace basegfx -{ - namespace tools - { - B3DPolyPolygon clipPolygonOnOrthogonalPlane(const B3DPolygon& rCandidate, B3DOrientation ePlaneOrthogonal, bool bClipPositive, double fPlaneOffset, bool bStroke) - { - B3DPolyPolygon aRetval; - - if(rCandidate.count()) - { - const B3DRange aCandidateRange(getRange(rCandidate)); - - if(B3DORIENTATION_X == ePlaneOrthogonal && fTools::moreOrEqual(aCandidateRange.getMinX(), fPlaneOffset)) - { - // completely above and on the clip plane. - if(bClipPositive) - { - // add completely - aRetval.append(rCandidate); - } - } - else if(B3DORIENTATION_X == ePlaneOrthogonal && fTools::lessOrEqual(aCandidateRange.getMaxX(), fPlaneOffset)) - { - // completely below and on the clip plane. - if(!bClipPositive) - { - // add completely - aRetval.append(rCandidate); - } - } - else if(B3DORIENTATION_Y == ePlaneOrthogonal && fTools::moreOrEqual(aCandidateRange.getMinY(), fPlaneOffset)) - { - // completely above and on the clip plane. - if(bClipPositive) - { - // add completely - aRetval.append(rCandidate); - } - } - else if(B3DORIENTATION_Y == ePlaneOrthogonal && fTools::lessOrEqual(aCandidateRange.getMaxY(), fPlaneOffset)) - { - // completely below and on the clip plane. - if(!bClipPositive) - { - // add completely - aRetval.append(rCandidate); - } - } - else if(B3DORIENTATION_Z == ePlaneOrthogonal && fTools::moreOrEqual(aCandidateRange.getMinZ(), fPlaneOffset)) - { - // completely above and on the clip plane. - if(bClipPositive) - { - // add completely - aRetval.append(rCandidate); - } - } - else if(B3DORIENTATION_Z == ePlaneOrthogonal && fTools::lessOrEqual(aCandidateRange.getMaxZ(), fPlaneOffset)) - { - // completely below and on the clip plane. - if(!bClipPositive) - { - // add completely - aRetval.append(rCandidate); - } - } - else - { - // prepare loop(s) - B3DPolygon aNewPolygon; - B3DPoint aCurrent(rCandidate.getB3DPoint(0L)); - const sal_uInt32 nPointCount(rCandidate.count()); - const sal_uInt32 nEdgeCount(rCandidate.isClosed() ? nPointCount : nPointCount - 1L); - bool bCurrentInside(impIsInside(aCurrent, fPlaneOffset, ePlaneOrthogonal) == bClipPositive); - - if(bCurrentInside) - { - impAppendCopy(aNewPolygon, rCandidate, 0L); - } - - if(bStroke) - { - // open polygon, create clipped line snippets. - for(sal_uInt32 a(0L); a < nEdgeCount; a++) - { - // get next point data - const sal_uInt32 nNextIndex((a + 1L == nPointCount) ? 0L : a + 1L); - const B3DPoint aNext(rCandidate.getB3DPoint(nNextIndex)); - const bool bNextInside(impIsInside(aNext, fPlaneOffset, ePlaneOrthogonal) == bClipPositive); - - if(bCurrentInside != bNextInside) - { - // change inside/outside - if(bNextInside) - { - // entering, finish existing and start new line polygon - if(aNewPolygon.count() > 1L) - { - aRetval.append(aNewPolygon); - } - - aNewPolygon.clear(); - } - - // calculate and add cut point - const double fCut(impGetCut(aCurrent, aNext, fPlaneOffset, ePlaneOrthogonal)); - impAppendInterpolate(aNewPolygon, rCandidate, a, nNextIndex, fCut); - - // pepare next step - bCurrentInside = bNextInside; - } - - if(bNextInside) - { - impAppendCopy(aNewPolygon, rCandidate, nNextIndex); - } - - // pepare next step - aCurrent = aNext; - } - - if(aNewPolygon.count() > 1L) - { - aRetval.append(aNewPolygon); - } - } - else - { - // closed polygon, create single clipped closed polygon - for(sal_uInt32 a(0L); a < nEdgeCount; a++) - { - // get next point data, use offset - const sal_uInt32 nNextIndex((a + 1L == nPointCount) ? 0L : a + 1L); - const B3DPoint aNext(rCandidate.getB3DPoint(nNextIndex)); - const bool bNextInside(impIsInside(aNext, fPlaneOffset, ePlaneOrthogonal) == bClipPositive); - - if(bCurrentInside != bNextInside) - { - // calculate and add cut point - const double fCut(impGetCut(aCurrent, aNext, fPlaneOffset, ePlaneOrthogonal)); - impAppendInterpolate(aNewPolygon, rCandidate, a, nNextIndex, fCut); - - // pepare next step - bCurrentInside = bNextInside; - } - - if(bNextInside && nNextIndex) - { - impAppendCopy(aNewPolygon, rCandidate, nNextIndex); - } - - // pepare next step - aCurrent = aNext; - } - - if(aNewPolygon.count() > 2L) - { - aNewPolygon.setClosed(true); - aRetval.append(aNewPolygon); - } - } - } - } - - return aRetval; - } - - B3DPolyPolygon clipPolyPolygonOnOrthogonalPlane(const B3DPolyPolygon& rCandidate, B3DOrientation ePlaneOrthogonal, bool bClipPositive, double fPlaneOffset, bool bStroke) - { - B3DPolyPolygon aRetval; - - for(sal_uInt32 a(0L); a < rCandidate.count(); a++) - { - aRetval.append(clipPolygonOnOrthogonalPlane(rCandidate.getB3DPolygon(a), ePlaneOrthogonal, bClipPositive, fPlaneOffset, bStroke)); - } - - return aRetval; - } - - B3DPolyPolygon clipPolyPolygonOnRange(const B3DPolyPolygon& rCandidate, const B2DRange& rRange, bool bInside, bool bStroke) - { - B3DPolyPolygon aRetval; - - for(sal_uInt32 a(0L); a < rCandidate.count(); a++) - { - aRetval.append(clipPolygonOnRange(rCandidate.getB3DPolygon(a), rRange, bInside, bStroke)); - } - - return aRetval; - } - - B3DPolyPolygon clipPolygonOnRange(const B3DPolygon& rCandidate, const B2DRange& rRange, bool bInside, bool bStroke) - { - B3DPolyPolygon aRetval; - - if(rRange.isEmpty()) - { - // clipping against an empty range. Nothing is inside an empty range, so the polygon - // is outside the range. So only return if not inside is wanted - if(!bInside && rCandidate.count()) - { - aRetval.append(rCandidate); - } - } - else if(rCandidate.count()) - { - const B3DRange aCandidateRange3D(getRange(rCandidate)); - const B2DRange aCandidateRange( - aCandidateRange3D.getMinX(), aCandidateRange3D.getMinY(), - aCandidateRange3D.getMaxX(), aCandidateRange3D.getMaxY()); - - if(rRange.isInside(aCandidateRange)) - { - // candidate is completely inside given range, nothing to do. Is also true with curves. - if(bInside) - { - aRetval.append(rCandidate); - } - } - else if(!rRange.overlaps(aCandidateRange)) - { - // candidate is completely outside given range, nothing to do. Is also true with curves. - if(!bInside) - { - aRetval.append(rCandidate); - } - } - else - { - // clip against the six planes of the range - // against lower X - aRetval = clipPolygonOnOrthogonalPlane(rCandidate, tools::B3DORIENTATION_X, bInside, rRange.getMinX(), bStroke); - - if(aRetval.count()) - { - // against lower Y - if(1L == aRetval.count()) - { - aRetval = clipPolygonOnOrthogonalPlane(aRetval.getB3DPolygon(0L), tools::B3DORIENTATION_Y, bInside, rRange.getMinY(), bStroke); - } - else - { - aRetval = clipPolyPolygonOnOrthogonalPlane(aRetval, tools::B3DORIENTATION_Y, bInside, rRange.getMinY(), bStroke); - } - - if(aRetval.count()) - { - // against higher X - if(1L == aRetval.count()) - { - aRetval = clipPolygonOnOrthogonalPlane(aRetval.getB3DPolygon(0L), tools::B3DORIENTATION_X, !bInside, rRange.getMaxX(), bStroke); - } - else - { - aRetval = clipPolyPolygonOnOrthogonalPlane(aRetval, tools::B3DORIENTATION_X, !bInside, rRange.getMaxX(), bStroke); - } - - if(aRetval.count()) - { - // against higher Y - if(1L == aRetval.count()) - { - aRetval = clipPolygonOnOrthogonalPlane(aRetval.getB3DPolygon(0L), tools::B3DORIENTATION_Y, !bInside, rRange.getMaxY(), bStroke); - } - else - { - aRetval = clipPolyPolygonOnOrthogonalPlane(aRetval, tools::B3DORIENTATION_Y, !bInside, rRange.getMaxY(), bStroke); - } - } - } - } - } - } - - return aRetval; - } - - B3DPolyPolygon clipPolyPolygonOnRange(const B3DPolyPolygon& rCandidate, const B3DRange& rRange, bool bInside, bool bStroke) - { - B3DPolyPolygon aRetval; - - for(sal_uInt32 a(0L); a < rCandidate.count(); a++) - { - aRetval.append(clipPolygonOnRange(rCandidate.getB3DPolygon(a), rRange, bInside, bStroke)); - } - - return aRetval; - } - - B3DPolyPolygon clipPolygonOnRange(const B3DPolygon& rCandidate, const B3DRange& rRange, bool bInside, bool bStroke) - { - B3DPolyPolygon aRetval; - - if(rRange.isEmpty()) - { - // clipping against an empty range. Nothing is inside an empty range, so the polygon - // is outside the range. So only return if not inside is wanted - if(!bInside && rCandidate.count()) - { - aRetval.append(rCandidate); - } - } - else if(rCandidate.count()) - { - const B3DRange aCandidateRange(getRange(rCandidate)); - - if(rRange.isInside(aCandidateRange)) - { - // candidate is completely inside given range, nothing to do. Is also true with curves. - if(bInside) - { - aRetval.append(rCandidate); - } - } - else if(!rRange.overlaps(aCandidateRange)) - { - // candidate is completely outside given range, nothing to do. Is also true with curves. - if(!bInside) - { - aRetval.append(rCandidate); - } - } - else - { - // clip against X,Y first and see if there's something left - const B2DRange aCandidateRange2D(rRange.getMinX(), rRange.getMinY(), rRange.getMaxX(), rRange.getMaxY()); - aRetval = clipPolygonOnRange(rCandidate, aCandidateRange2D, bInside, bStroke); - - if(aRetval.count()) - { - // against lower Z - if(1L == aRetval.count()) - { - aRetval = clipPolygonOnOrthogonalPlane(aRetval.getB3DPolygon(0L), tools::B3DORIENTATION_Z, bInside, rRange.getMinZ(), bStroke); - } - else - { - aRetval = clipPolyPolygonOnOrthogonalPlane(aRetval, tools::B3DORIENTATION_Z, bInside, rRange.getMinZ(), bStroke); - } - - if(aRetval.count()) - { - // against higher Z - if(1L == aRetval.count()) - { - aRetval = clipPolygonOnOrthogonalPlane(aRetval.getB3DPolygon(0L), tools::B3DORIENTATION_Z, !bInside, rRange.getMaxZ(), bStroke); - } - else - { - aRetval = clipPolyPolygonOnOrthogonalPlane(aRetval, tools::B3DORIENTATION_Z, !bInside, rRange.getMaxZ(), bStroke); - } - } - } - } - } - - return aRetval; - } - - B3DPolyPolygon clipPolygonOnPlane(const B3DPolygon& rCandidate, const B3DPoint& rPointOnPlane, const B3DVector& rPlaneNormal, bool bClipPositive, bool bStroke) - { - B3DPolyPolygon aRetval; - - if(rPlaneNormal.equalZero()) - { - // not really a plane definition, return polygon - aRetval.append(rCandidate); - } - else if(rCandidate.count()) - { - // build transform to project planeNormal on X-Axis and pointOnPlane to null point - B3DHomMatrix aMatrixTransform; - aMatrixTransform.translate(-rPointOnPlane.getX(), -rPointOnPlane.getY(), -rPointOnPlane.getZ()); - const double fRotInXY(atan2(rPlaneNormal.getY(), rPlaneNormal.getX())); - const double fRotInXZ(atan2(-rPlaneNormal.getZ(), rPlaneNormal.getXYLength())); - if(!fTools::equalZero(fRotInXY) || !fTools::equalZero(fRotInXZ)) - { - aMatrixTransform.rotate(0.0, fRotInXZ, fRotInXY); - } - - // transform polygon to clip scenario - B3DPolygon aCandidate(rCandidate); - aCandidate.transform(aMatrixTransform); - - // clip on YZ plane - aRetval = clipPolygonOnOrthogonalPlane(aCandidate, tools::B3DORIENTATION_X, bClipPositive, 0.0, bStroke); - - if(aRetval.count()) - { - // if there is a result, it needs to be transformed back - aMatrixTransform.invert(); - aRetval.transform(aMatrixTransform); - } - } - - return aRetval; - } - - B3DPolyPolygon clipPolyPolygonOnPlane(const B3DPolyPolygon& rCandidate, const B3DPoint& rPointOnPlane, const B3DVector& rPlaneNormal, bool bClipPositive, bool bStroke) - { - B3DPolyPolygon aRetval; - - if(rPlaneNormal.equalZero()) - { - // not really a plane definition, return polygon - aRetval = rCandidate; - } - else if(rCandidate.count()) - { - // build transform to project planeNormal on X-Axis and pointOnPlane to null point - B3DHomMatrix aMatrixTransform; - aMatrixTransform.translate(-rPointOnPlane.getX(), -rPointOnPlane.getY(), -rPointOnPlane.getZ()); - const double fRotInXY(atan2(rPlaneNormal.getY(), rPlaneNormal.getX())); - const double fRotInXZ(atan2(-rPlaneNormal.getZ(), rPlaneNormal.getXYLength())); - if(!fTools::equalZero(fRotInXY) || !fTools::equalZero(fRotInXZ)) - { - aMatrixTransform.rotate(0.0, fRotInXZ, fRotInXY); - } - - // transform polygon to clip scenario - aRetval = rCandidate; - aRetval.transform(aMatrixTransform); - - // clip on YZ plane - aRetval = clipPolyPolygonOnOrthogonalPlane(aRetval, tools::B3DORIENTATION_X, bClipPositive, 0.0, bStroke); - - if(aRetval.count()) - { - // if there is a result, it needs to be transformed back - aMatrixTransform.invert(); - aRetval.transform(aMatrixTransform); - } - } - - return aRetval; - } - - } // end of namespace tools -} // end of namespace basegfx - -////////////////////////////////////////////////////////////////////////////// - -// eof - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |