/************************************************************************* * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: lathe3d.cxx,v $ * * $Revision: 1.25 $ * * last change: $Author: hr $ $Date: 2007-06-27 18:03:44 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. * * * GNU Lesser General Public License Version 2.1 * ============================================= * Copyright 2005 by Sun Microsystems, Inc. * 901 San Antonio Road, Palo Alto, CA 94303, USA * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software Foundation. * * This library 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 for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_svx.hxx" #include "svdstr.hrc" #include "svdglob.hxx" #ifndef _TL_POLY_HXX #include #endif #ifndef _SVDPAGE_HXX #include #endif #ifndef _XOUTX_HXX #include #endif #ifndef _E3D_GLOBL3D_HXX #include "globl3d.hxx" #endif #ifndef _E3D_LATHE3D_HXX #include #endif #ifndef _XPOLY_HXX #include #endif #ifndef _SVX_SVXIDS_HRC #include #endif #ifndef _SVDOPATH_HXX #include #endif #ifndef _SVDMODEL_HXX #include #endif #ifndef _SVX3DITEMS_HXX #include #endif #ifndef _SDR_PROPERTIES_E3DLATHEPROPERTIES_HXX #include #endif #ifndef _BGFX_POLYPOLYGON_B2DPOLYGONTOOLS_HXX #include #endif #ifndef _BGFX_POLYGON_B2DPOLYGONTOOLS_HXX #include #endif #ifndef _BGFX_MATRIX_B2DHOMMATRIX_HXX #include #endif ////////////////////////////////////////////////////////////////////////////// sdr::properties::BaseProperties* E3dLatheObj::CreateObjectSpecificProperties() { return new sdr::properties::E3dLatheProperties(*this); } ////////////////////////////////////////////////////////////////////////////// TYPEINIT1(E3dLatheObj, E3dCompoundObject); /************************************************************************* |* |* Konstruktor aus 3D-Polygon, Scale gibt den Umrechnungsfaktor fuer |* die Koordinaten an |* \************************************************************************/ E3dLatheObj::E3dLatheObj(E3dDefaultAttributes& rDefault, const basegfx::B2DPolyPolygon rPoly2D) : E3dCompoundObject(rDefault), maPolyPoly2D(rPoly2D) { // since the old class PolyPolygon3D did mirror the given PolyPolygons in Y, do the same here basegfx::B2DHomMatrix aMirrorY; aMirrorY.scale(1.0, -1.0); maPolyPoly2D.transform(aMirrorY); // Defaults setzen SetDefaultAttributes(rDefault); // Ueberfluessige Punkte entfernen, insbesondere doppelte // Start- und Endpunkte verhindern maPolyPoly2D.removeDoublePoints(); if(maPolyPoly2D.count()) { const basegfx::B2DPolygon rPoly(maPolyPoly2D.getB2DPolygon(0L)); sal_uInt32 nSegCnt(rPoly.count()); if(nSegCnt && !rPoly.isClosed()) { nSegCnt -= 1; } GetProperties().SetObjectItemDirect(Svx3DVerticalSegmentsItem(nSegCnt)); } // Geometrie erzeugen CreateGeometry(); } /************************************************************************* |* |* Leer-Konstruktor |* \************************************************************************/ E3dLatheObj::E3dLatheObj() : E3dCompoundObject() { // Defaults setzen E3dDefaultAttributes aDefault; SetDefaultAttributes(aDefault); } void E3dLatheObj::SetDefaultAttributes(E3dDefaultAttributes& rDefault) { GetProperties().SetObjectItemDirect(Svx3DSmoothNormalsItem(rDefault.GetDefaultLatheSmoothed())); GetProperties().SetObjectItemDirect(Svx3DSmoothLidsItem(rDefault.GetDefaultLatheSmoothFrontBack())); GetProperties().SetObjectItemDirect(Svx3DCharacterModeItem(rDefault.GetDefaultLatheCharacterMode())); GetProperties().SetObjectItemDirect(Svx3DCloseFrontItem(rDefault.GetDefaultLatheCloseFront())); GetProperties().SetObjectItemDirect(Svx3DCloseBackItem(rDefault.GetDefaultLatheCloseBack())); } /************************************************************************* |* |* Give out simple line geometry |* \************************************************************************/ basegfx::B3DPolyPolygon E3dLatheObj::Get3DLineGeometry() const { return maLinePolyPolygon; } /************************************************************************* |* |* Die eigentliche Konstruktionmethode, erzeugt einen Koerper durch |* Rotation des uebergebenen Polygons um die senkrechte Y-Achse. Wenn |* nEndAngle < 3600 ist, werden ausserdem zwei Deckelflaechen-Polygone |* erzeugt, die den Koerper abschliessen. Das Polygon sollte in der |* XY-Ebene liegen, mit X-Koordinaten >= 0; wenn die Anfangs- und End- |* X-Koordinaten nicht 0 sind, sollte das Polygon geschlossen sein. |* Wenn bDblSided TRUE ist, werden die Rotationsflaechen doppelseitig |* angelegt und keine Deckelflaechen erzeugt. |* \************************************************************************/ // Geometrieerzeugung void E3dLatheObj::CreateGeometry() { // Start der Geometrieerzeugung ankuendigen StartCreateGeometry(); // #78972# maLinePolyPolygon.clear(); if(maPolyPoly2D.count()) { // Polygon erzeugen // Eventuelle Anpassung der Segmentanzahlen basegfx::B2DPolyPolygon aLathePoly2D(CreateLathePolyPoly(maPolyPoly2D, GetVerticalSegments())); aLathePoly2D = basegfx::tools::correctOrientations(aLathePoly2D); const basegfx::B2VectorOrientation aOrient = basegfx::tools::getOrientation(aLathePoly2D.getB2DPolygon(0L)); if(basegfx::ORIENTATION_NEGATIVE == aOrient) { aLathePoly2D.flip(); } // #i28528# basegfx::B3DPolyPolygon aFrontLines; basegfx::B3DPolyPolygon aBackLines; basegfx::B3DPolyPolygon aInBetweenLines; basegfx::B3DPolyPolygon aLathePoly3D(basegfx::tools::createB3DPolyPolygonFromB2DPolyPolygon(aLathePoly2D)); // Spezialfall Einzelnes Polygon erzeugen BOOL bSinglePoly = (GetEndAngle() == 0 || GetHorizontalSegments() == 0); if(bSinglePoly) { // nur ein Polygon erzeugen GetProperties().SetObjectItemDirect(Svx3DDoubleSidedItem(TRUE)); // Fuer evtl. selbst erzeugte Normalen basegfx::B3DPolyPolygon aNormalsFront(ImpCreateByPattern(aLathePoly3D)); // Normalen und Vorderseite selbst erzeugen aNormalsFront = ImpAddFrontNormals(aNormalsFront, basegfx::B3DVector(0.0, 0.0, 1.0)); ImpCreateFront(aLathePoly3D, aNormalsFront, GetCreateNormals(), GetCreateTexture()); // #i28528# aInBetweenLines.append(aLathePoly3D); } else { // Eventuell doppelseitig erzeugen? if(!aLathePoly3D.isClosed()) { GetProperties().SetObjectItemDirect(Svx3DDoubleSidedItem(TRUE)); } // Seiten genenrieren? BOOL bCreateSides = ((GetEndAngle() < 3600 && !GetDoubleSided()) || (GetBackScale() != 100)); // Polygone vorbereiten basegfx::B3DPolyPolygon aPrev, aFront, aBack, aNext; // Rotation vorbereiten double fAng = DEG2RAD(double(GetEndAngle()) / 10); basegfx::B3DHomMatrix aRotMat; // Skalierung vorbereiten double fScalePerStep(1.0); if(GetBackScale() != 100) { fScalePerStep = (((double)GetBackScale() - 100.0) / 100.0) / (double)GetHorizontalSegments(); } // Texturen erzeugen? double fTextureDepth(1.0); double fTextureStart(0.0); if(!GetCreateTexture()) { fTextureStart = fTextureDepth = 0.0; } // aPrev bis aBack ausfuellen als Startvorbereitung aRotMat.rotate(0.0, -(fAng / (double)GetHorizontalSegments()), 0.0); aPrev = aLathePoly3D; aPrev.transform(aRotMat); if(GetBackScale() != 100) { // #i74056# aPrev = ImpScalePoly(aPrev, 1.0 - fScalePerStep); } aRotMat.identity(); aRotMat.rotate(0.0, fAng / (double)GetHorizontalSegments(), 0.0); aFront = aLathePoly3D; aBack = aLathePoly3D; aBack.transform(aRotMat); if(GetBackScale() != 100) { // #i74056# aBack = ImpScalePoly(aBack, 1.0 + fScalePerStep); } // Werte fuer Textur-Zwischensegmenterzeugung berechnen double fTmpStart(0.0); double fTmpLength(fTextureDepth / (double)GetHorizontalSegments()); sal_uInt16 nUpperBound((sal_uInt16)GetHorizontalSegments()); for(UINT16 a=0;aSetMergedItemSet(aSet); } return pPathObj; } // eof