diff options
Diffstat (limited to 'drawinglayer/source/primitive3d/sdrextrudelathetools3d.cxx')
-rw-r--r-- | drawinglayer/source/primitive3d/sdrextrudelathetools3d.cxx | 190 |
1 files changed, 156 insertions, 34 deletions
diff --git a/drawinglayer/source/primitive3d/sdrextrudelathetools3d.cxx b/drawinglayer/source/primitive3d/sdrextrudelathetools3d.cxx index 93b0555055dc..973a82c8eca4 100644 --- a/drawinglayer/source/primitive3d/sdrextrudelathetools3d.cxx +++ b/drawinglayer/source/primitive3d/sdrextrudelathetools3d.cxx @@ -4,9 +4,9 @@ * * $RCSfile: sdrextrudelathetools3d.cxx,v $ * - * $Revision: 1.10 $ + * $Revision: 1.11 $ * - * last change: $Author: aw $ $Date: 2008-05-27 14:11:21 $ + * last change: $Author: aw $ $Date: 2008-06-24 15:31:08 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -48,6 +48,7 @@ #include <basegfx/range/b3drange.hxx> #include <basegfx/matrix/b3dhommatrix.hxx> #include <basegfx/polygon/b2dpolygontools.hxx> +#include <drawinglayer/geometry/viewinformation3d.hxx> #include <numeric> ////////////////////////////////////////////////////////////////////////////// @@ -327,6 +328,36 @@ namespace rPolA.setB3DPolygon(a, aSubA); } } + + bool impHasCutWith(const basegfx::B2DPolygon& rPoly, const basegfx::B2DPoint& rStart, const basegfx::B2DPoint& rEnd) + { + // polygon is closed, one of the points is a member + const sal_uInt32 nPointCount(rPoly.count()); + + if(nPointCount) + { + basegfx::B2DPoint aCurrent(rPoly.getB2DPoint(0)); + const basegfx::B2DVector aVector(rEnd - rStart); + + for(sal_uInt32 a(0); a < nPointCount; a++) + { + const sal_uInt32 nNextIndex((a + 1) % nPointCount); + const basegfx::B2DPoint aNext(rPoly.getB2DPoint(nNextIndex)); + const basegfx::B2DVector aEdgeVector(aNext - aCurrent); + + if(basegfx::tools::findCut( + rStart, aVector, + aCurrent, aEdgeVector)) + { + return true; + } + + aCurrent = aNext; + } + } + + return false; + } } // end of anonymous namespace ////////////////////////////////////////////////////////////////////////////// @@ -501,52 +532,52 @@ namespace drawinglayer } } - void extractLinesFromSlice( - basegfx::B3DPolyPolygon& rLine, - const Slice3DVector& rSliceVector, - bool bClosed, - bool bAddHorizontal, - bool bAddVertical) + basegfx::B3DPolyPolygon extractHorizontalLinesFromSlice(const Slice3DVector& rSliceVector, bool bCloseHorLines) { + basegfx::B3DPolyPolygon aRetval; const sal_uInt32 nNumSlices(rSliceVector.size()); if(nNumSlices) { - // Slice3Ds self - if(bAddVertical) - { - for(sal_uInt32 a(0L); a < nNumSlices; a++) - { - rLine.append(rSliceVector[a].getB3DPolyPolygon()); - } - } + const sal_uInt32 nSlideSubPolygonCount(rSliceVector[0].getB3DPolyPolygon().count()); - // horizontal - if(bAddHorizontal) - { - const basegfx::B3DPolyPolygon& aFirstPolyPolygon(rSliceVector[0L].getB3DPolyPolygon()); - const sal_uInt32 nPolygonCount(aFirstPolyPolygon.count()); + for(sal_uInt32 b(0); b < nSlideSubPolygonCount; b++) + { + const sal_uInt32 nSubPolygonPointCount(rSliceVector[0].getB3DPolyPolygon().getB3DPolygon(b).count()); - for(sal_uInt32 b(0L); b < nPolygonCount; b++) + for(sal_uInt32 c(0); c < nSubPolygonPointCount; c++) { - const basegfx::B3DPolygon& aFirstPolygon(aFirstPolyPolygon.getB3DPolygon(0L)); - const sal_uInt32 nPointCount(aFirstPolygon.count()); + basegfx::B3DPolygon aNew; - for(sal_uInt32 c(0L); c < nPointCount; c++) + for(sal_uInt32 d(0); d < nNumSlices; d++) { - basegfx::B3DPolygon aNew; - - for(sal_uInt32 d(0L); d < nNumSlices; d++) - { - aNew.append(rSliceVector[d].getB3DPolyPolygon().getB3DPolygon(b).getB3DPoint(c)); - } - - aNew.setClosed(bClosed); - rLine.append(aNew); + OSL_ENSURE(nSlideSubPolygonCount == rSliceVector[d].getB3DPolyPolygon().count(), + "Slice PolyPolygon with different Polygon count (!)"); + OSL_ENSURE(nSubPolygonPointCount == rSliceVector[d].getB3DPolyPolygon().getB3DPolygon(b).count(), + "Slice Polygon with different point count (!)"); + aNew.append(rSliceVector[d].getB3DPolyPolygon().getB3DPolygon(b).getB3DPoint(c)); } + + aNew.setClosed(bCloseHorLines); + aRetval.append(aNew); } } } + + return aRetval; + } + + basegfx::B3DPolyPolygon extractVerticalLinesFromSlice(const Slice3DVector& rSliceVector) + { + basegfx::B3DPolyPolygon aRetval; + const sal_uInt32 nNumSlices(rSliceVector.size()); + + for(sal_uInt32 a(0L); a < nNumSlices; a++) + { + aRetval.append(rSliceVector[a].getB3DPolyPolygon()); + } + + return aRetval; } void extractPlanesFromSlice( @@ -870,6 +901,97 @@ namespace drawinglayer } } + void createReducedOutlines( + const geometry::ViewInformation3D& rViewInformation, + const basegfx::B3DHomMatrix& rObjectTransform, + const basegfx::B3DPolygon& rLoopA, + const basegfx::B3DPolygon& rLoopB, + basegfx::B3DPolyPolygon& rTarget) + { + const sal_uInt32 nPointCount(rLoopA.count()); + + // with idetic polygons there are no outlines + if(rLoopA != rLoopB) + { + if(nPointCount && nPointCount == rLoopB.count()) + { + const basegfx::B3DHomMatrix aObjectTransform(rViewInformation.getObjectToView() * rObjectTransform); + const basegfx::B2DPolygon a2DLoopA(basegfx::tools::createB2DPolygonFromB3DPolygon(rLoopA, aObjectTransform)); + const basegfx::B2DPolygon a2DLoopB(basegfx::tools::createB2DPolygonFromB3DPolygon(rLoopB, aObjectTransform)); + const basegfx::B2DPoint a2DCenterA(a2DLoopA.getB2DRange().getCenter()); + const basegfx::B2DPoint a2DCenterB(a2DLoopB.getB2DRange().getCenter()); + + // without detectable Y-Axis there are no outlines + if(!a2DCenterA.equal(a2DCenterB)) + { + // search for outmost left and right inter-loop-edges which do not cut the loops + const basegfx::B2DPoint aCommonCenter(basegfx::average(a2DCenterA, a2DCenterB)); + const basegfx::B2DVector aAxisVector(a2DCenterA - a2DCenterB); + double fMaxLeft(0.0); + double fMaxRight(0.0); + sal_uInt32 nIndexLeft(0); + sal_uInt32 nIndexRight(0); + + for(sal_uInt32 a(0); a < nPointCount; a++) + { + const basegfx::B2DPoint aStart(a2DLoopA.getB2DPoint(a)); + const basegfx::B2DPoint aEnd(a2DLoopB.getB2DPoint(a)); + const basegfx::B2DPoint aMiddle(basegfx::average(aStart, aEnd)); + + if(!basegfx::tools::isInside(a2DLoopA, aMiddle)) + { + if(!basegfx::tools::isInside(a2DLoopB, aMiddle)) + { + if(!impHasCutWith(a2DLoopA, aStart, aEnd)) + { + if(!impHasCutWith(a2DLoopB, aStart, aEnd)) + { + const basegfx::B2DVector aCandidateVector(aMiddle - aCommonCenter); + const double fCross(aCandidateVector.cross(aAxisVector)); + const double fDistance(aCandidateVector.getLength()); + + if(fCross > 0.0) + { + if(fDistance > fMaxLeft) + { + fMaxLeft = fDistance; + nIndexLeft = a; + } + } + else if(fCross < 0.0) + { + if(fDistance > fMaxRight) + { + fMaxRight = fDistance; + nIndexRight = a; + } + } + } + } + } + } + } + + if(fMaxLeft != 0.0) + { + basegfx::B3DPolygon aToBeAdded; + aToBeAdded.append(rLoopA.getB3DPoint(nIndexLeft)); + aToBeAdded.append(rLoopB.getB3DPoint(nIndexLeft)); + rTarget.append(aToBeAdded); + } + + if(fMaxRight != 0.0) + { + basegfx::B3DPolygon aToBeAdded; + aToBeAdded.append(rLoopA.getB3DPoint(nIndexRight)); + aToBeAdded.append(rLoopB.getB3DPoint(nIndexRight)); + rTarget.append(aToBeAdded); + } + } + } + } + } + } // end of namespace primitive3d } // end of namespace drawinglayer |