diff options
Diffstat (limited to 'svx/source/engine3d')
27 files changed, 13951 insertions, 0 deletions
diff --git a/svx/source/engine3d/camera3d.cxx b/svx/source/engine3d/camera3d.cxx new file mode 100644 index 000000000000..813f25c1f75b --- /dev/null +++ b/svx/source/engine3d/camera3d.cxx @@ -0,0 +1,392 @@ +/************************************************************************* + * + * 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_svx.hxx" +#include <svx/camera3d.hxx> +#include <tools/stream.hxx> + +/************************************************************************* +|* +|* Konstruktor +|* +\************************************************************************/ + +Camera3D::Camera3D(const basegfx::B3DPoint& rPos, const basegfx::B3DPoint& rLookAt, + double fFocalLen, double fBankAng) : + aResetPos(rPos), + aResetLookAt(rLookAt), + fResetFocalLength(fFocalLen), + fResetBankAngle(fBankAng), + fBankAngle(fBankAng), + bAutoAdjustProjection(TRUE) +{ + SetVPD(0); + SetPosition(rPos); + SetLookAt(rLookAt); + SetFocalLength(fFocalLen); +} + +/************************************************************************* +|* +|* Default-Konstruktor +|* +\************************************************************************/ + +Camera3D::Camera3D() +{ + basegfx::B3DPoint aVector3D(0.0 ,0.0 ,1.0); + Camera3D(aVector3D, basegfx::B3DPoint()); +} + +/************************************************************************* +|* +|* Konstruktor +|* +\************************************************************************/ + +void Camera3D::Reset() +{ + SetVPD(0); + fBankAngle = fResetBankAngle; + SetPosition(aResetPos); + SetLookAt(aResetLookAt); + SetFocalLength(fResetFocalLength); +} + +/************************************************************************* +|* +|* Defaultwerte fuer Reset setzen +|* +\************************************************************************/ + +void Camera3D::SetDefaults(const basegfx::B3DPoint& rPos, const basegfx::B3DPoint& rLookAt, + double fFocalLen, double fBankAng) +{ + aResetPos = rPos; + aResetLookAt = rLookAt; + fResetFocalLength = fFocalLen; + fResetBankAngle = fBankAng; +} + +/************************************************************************* +|* +|* ViewWindow setzen und PRP anpassen +|* +\************************************************************************/ + +void Camera3D::SetViewWindow(double fX, double fY, double fW, double fH) +{ + Viewport3D::SetViewWindow(fX, fY, fW, fH); + if ( bAutoAdjustProjection ) + SetFocalLength(fFocalLength); +} + +/************************************************************************* +|* +|* Kameraposition setzen +|* +\************************************************************************/ + +void Camera3D::SetPosition(const basegfx::B3DPoint& rNewPos) +{ + if ( rNewPos != aPosition ) + { + aPosition = rNewPos; + SetVRP(aPosition); + SetVPN(aPosition - aLookAt); + SetBankAngle(fBankAngle); + } +} + +/************************************************************************* +|* +|* Blickpunkt setzen +|* +\************************************************************************/ + +void Camera3D::SetLookAt(const basegfx::B3DPoint& rNewLookAt) +{ + if ( rNewLookAt != aLookAt ) + { + aLookAt = rNewLookAt; + SetVPN(aPosition - aLookAt); + SetBankAngle(fBankAngle); + } +} + +/************************************************************************* +|* +|* Position und Blickpunkt setzen +|* +\************************************************************************/ + +void Camera3D::SetPosAndLookAt(const basegfx::B3DPoint& rNewPos, + const basegfx::B3DPoint& rNewLookAt) +{ + if ( rNewPos != aPosition || rNewLookAt != aLookAt ) + { + aPosition = rNewPos; + aLookAt = rNewLookAt; + + SetVRP(aPosition); + SetVPN(aPosition - aLookAt); + SetBankAngle(fBankAngle); + } +} + +/************************************************************************* +|* +|* seitlichen Neigungswinkel setzen +|* +\************************************************************************/ + +void Camera3D::SetBankAngle(double fAngle) +{ + basegfx::B3DVector aDiff(aPosition - aLookAt); + basegfx::B3DVector aPrj(aDiff); + fBankAngle = fAngle; + + if ( aDiff.getY() == 0 ) + { + aPrj.setY(-1.0); + } + else + { // aPrj = Projektion von aDiff auf die XZ-Ebene + aPrj.setY(0.0); + + if ( aDiff.getY() < 0.0 ) + { + aPrj = -aPrj; + } + } + + // von aDiff nach oben zeigenden View-Up-Vektor berechnen + aPrj = aPrj.getPerpendicular(aDiff); + aPrj = aPrj.getPerpendicular(aDiff); + aDiff.normalize(); + + // auf Z-Achse rotieren, dort um BankAngle drehen und zurueck + basegfx::B3DHomMatrix aTf; + const double fV(sqrt(aDiff.getY() * aDiff.getY() + aDiff.getZ() * aDiff.getZ())); + + if ( fV != 0.0 ) + { + basegfx::B3DHomMatrix aTemp; + const double fSin(aDiff.getY() / fV); + const double fCos(aDiff.getZ() / fV); + + aTemp.set(1, 1, fCos); + aTemp.set(2, 2, fCos); + aTemp.set(2, 1, fSin); + aTemp.set(1, 2, -fSin); + + aTf *= aTemp; + } + + { + basegfx::B3DHomMatrix aTemp; + const double fSin(-aDiff.getX()); + const double fCos(fV); + + aTemp.set(0, 0, fCos); + aTemp.set(2, 2, fCos); + aTemp.set(0, 2, fSin); + aTemp.set(2, 0, -fSin); + + aTf *= aTemp; + } + + aTf.rotate(0.0, 0.0, fBankAngle); + + { + basegfx::B3DHomMatrix aTemp; + const double fSin(aDiff.getX()); + const double fCos(fV); + + aTemp.set(0, 0, fCos); + aTemp.set(2, 2, fCos); + aTemp.set(0, 2, fSin); + aTemp.set(2, 0, -fSin); + + aTf *= aTemp; + } + + if ( fV != 0.0 ) + { + basegfx::B3DHomMatrix aTemp; + const double fSin(-aDiff.getY() / fV); + const double fCos(aDiff.getZ() / fV); + + aTemp.set(1, 1, fCos); + aTemp.set(2, 2, fCos); + aTemp.set(2, 1, fSin); + aTemp.set(1, 2, -fSin); + + aTf *= aTemp; + } + + SetVUV(aTf * aPrj); +} + +/************************************************************************* +|* +|* Brennweite setzen +|* +\************************************************************************/ + +void Camera3D::SetFocalLength(double fLen) +{ + if ( fLen < 5 ) + fLen = 5; + SetPRP(basegfx::B3DPoint(0.0, 0.0, fLen / 35.0 * aViewWin.W)); + fFocalLength = fLen; +} + +/************************************************************************* +|* +|* Um die Kameraposition drehen, LookAt wird dabei veraendert +|* +\************************************************************************/ + +void Camera3D::Rotate(double fHAngle, double fVAngle) +{ + basegfx::B3DHomMatrix aTf; + basegfx::B3DVector aDiff(aLookAt - aPosition); + const double fV(sqrt(aDiff.getX() * aDiff.getX() + aDiff.getZ() * aDiff.getZ())); + + if ( fV != 0.0 ) + { + basegfx::B3DHomMatrix aTemp; + const double fSin(aDiff.getZ() / fV); + const double fCos(aDiff.getX() / fV); + + aTemp.set(0, 0, fCos); + aTemp.set(2, 2, fCos); + aTemp.set(0, 2, fSin); + aTemp.set(2, 0, -fSin); + + aTf *= aTemp; + } + + { + aTf.rotate(0.0, 0.0, fVAngle); + } + + if ( fV != 0.0 ) + { + basegfx::B3DHomMatrix aTemp; + const double fSin(-aDiff.getZ() / fV); + const double fCos(aDiff.getX() / fV); + + aTemp.set(0, 0, fCos); + aTemp.set(2, 2, fCos); + aTemp.set(0, 2, fSin); + aTemp.set(2, 0, -fSin); + + aTf *= aTemp; + } + + { + aTf.rotate(0.0, fHAngle, 0.0); + } + + aDiff *= aTf; + SetLookAt(aPosition + aDiff); +} + + +/************************************************************************* +|* +|* Um den Blickpunkt drehen, Position wird dabei veraendert +|* +\************************************************************************/ + +void Camera3D::RotateAroundLookAt(double fHAngle, double fVAngle) +{ + basegfx::B3DHomMatrix aTf; + basegfx::B3DVector aDiff(aPosition - aLookAt); + const double fV(sqrt(aDiff.getX() * aDiff.getX() + aDiff.getZ() * aDiff.getZ())); + + if ( fV != 0.0 ) + { + basegfx::B3DHomMatrix aTemp; + const double fSin(aDiff.getZ() / fV); + const double fCos(aDiff.getX() / fV); + + aTemp.set(0, 0, fCos); + aTemp.set(2, 2, fCos); + aTemp.set(0, 2, fSin); + aTemp.set(2, 0, -fSin); + + aTf *= aTemp; + } + + { + aTf.rotate(0.0, 0.0, fVAngle); + } + + if ( fV != 0.0 ) + { + basegfx::B3DHomMatrix aTemp; + const double fSin(-aDiff.getZ() / fV); + const double fCos(aDiff.getX() / fV); + + aTemp.set(0, 0, fCos); + aTemp.set(2, 2, fCos); + aTemp.set(0, 2, fSin); + aTemp.set(2, 0, -fSin); + + aTf *= aTemp; + } + + { + aTf.rotate(0.0, fHAngle, 0.0); + } + + aDiff *= aTf; + SetPosition(aLookAt + aDiff); +} + +/************************************************************************* +|* +|* FG: ??? Setzt wohl die Projektionsebene in eine bestimmte Tiefe +|* +\************************************************************************/ + +void Camera3D::SetFocalLengthWithCorrect(double fLen) +{ + if ( fLen < 5.0 ) + { + fLen = 5.0; + } + + SetPRP(basegfx::B3DPoint(0.0, 0.0, aPRP.getZ() * fLen / fFocalLength)); + fFocalLength = fLen; +} + +// eof diff --git a/svx/source/engine3d/cube3d.cxx b/svx/source/engine3d/cube3d.cxx new file mode 100644 index 000000000000..626ee80d46e3 --- /dev/null +++ b/svx/source/engine3d/cube3d.cxx @@ -0,0 +1,199 @@ +/************************************************************************* + * + * 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_svx.hxx" + +#include "svdstr.hrc" +#include "svdglob.hxx" +#include <svx/cube3d.hxx> +#include "globl3d.hxx" +#include <basegfx/point/b3dpoint.hxx> +#include <basegfx/polygon/b3dpolygon.hxx> +#include <svx/sdr/contact/viewcontactofe3dcube.hxx> + +////////////////////////////////////////////////////////////////////////////// +// #110094# DrawContact section + +sdr::contact::ViewContact* E3dCubeObj::CreateObjectSpecificViewContact() +{ + return new sdr::contact::ViewContactOfE3dCube(*this); +} + +TYPEINIT1(E3dCubeObj, E3dCompoundObject); + +/************************************************************************* +|* +|* Konstruktor: | +|* 3D-Quader erzeugen; aPos: Zentrum oder links, unten, hinten |__ +|* (abhaengig von bPosIsCenter) / +|* +\************************************************************************/ + +E3dCubeObj::E3dCubeObj(E3dDefaultAttributes& rDefault, basegfx::B3DPoint aPos, const basegfx::B3DVector& r3DSize) +: E3dCompoundObject(rDefault) +{ + // Defaults setzen + SetDefaultAttributes(rDefault); + + // uebergebene drueberbuegeln + aCubePos = aPos; + aCubeSize = r3DSize; +} + +E3dCubeObj::E3dCubeObj() +: E3dCompoundObject() +{ + // Defaults setzen + E3dDefaultAttributes aDefault; + SetDefaultAttributes(aDefault); +} + +void E3dCubeObj::SetDefaultAttributes(E3dDefaultAttributes& rDefault) +{ + aCubePos = rDefault.GetDefaultCubePos(); + aCubeSize = rDefault.GetDefaultCubeSize(); + nSideFlags = rDefault.GetDefaultCubeSideFlags(); + bPosIsCenter = rDefault.GetDefaultCubePosIsCenter(); +} + +/************************************************************************* +|* +|* Identifier zurueckgeben +|* +\************************************************************************/ + +UINT16 E3dCubeObj::GetObjIdentifier() const +{ + return E3D_CUBEOBJ_ID; +} + +/************************************************************************* +|* +|* Wandle das Objekt in ein Gruppenobjekt bestehend aus 6 Polygonen +|* +\************************************************************************/ + +SdrObject *E3dCubeObj::DoConvertToPolyObj(BOOL /*bBezier*/) const +{ + return NULL; +} + +/************************************************************************* +|* +|* Zuweisungsoperator +|* +\************************************************************************/ + +void E3dCubeObj::operator=(const SdrObject& rObj) +{ + // erstmal alle Childs kopieren + E3dCompoundObject::operator=(rObj); + + // weitere Parameter kopieren + const E3dCubeObj& r3DObj = (const E3dCubeObj&)rObj; + + aCubePos = r3DObj.aCubePos; + aCubeSize = r3DObj.aCubeSize; + bPosIsCenter = r3DObj.bPosIsCenter; + nSideFlags = r3DObj.nSideFlags; +} + +/************************************************************************* +|* +|* Lokale Parameter setzen mit Geometrieneuerzeugung +|* +\************************************************************************/ + +void E3dCubeObj::SetCubePos(const basegfx::B3DPoint& rNew) +{ + if(aCubePos != rNew) + { + aCubePos = rNew; + ActionChanged(); + } +} + +void E3dCubeObj::SetCubeSize(const basegfx::B3DVector& rNew) +{ + if(aCubeSize != rNew) + { + aCubeSize = rNew; + ActionChanged(); + } +} + +void E3dCubeObj::SetPosIsCenter(BOOL bNew) +{ + if(bPosIsCenter != bNew) + { + bPosIsCenter = bNew; + ActionChanged(); + } +} + +void E3dCubeObj::SetSideFlags(UINT16 nNew) +{ + if(nSideFlags != nNew) + { + nSideFlags = nNew; + ActionChanged(); + } +} + +/************************************************************************* +|* +|* Get the name of the object (singular) +|* +\************************************************************************/ + +void E3dCubeObj::TakeObjNameSingul(XubString& rName) const +{ + rName=ImpGetResStr(STR_ObjNameSingulCube3d); + + String aName( GetName() ); + if(aName.Len()) + { + rName += sal_Unicode(' '); + rName += sal_Unicode('\''); + rName += aName; + rName += sal_Unicode('\''); + } +} + +/************************************************************************* +|* +|* Get the name of the object (plural) +|* +\************************************************************************/ + +void E3dCubeObj::TakeObjNamePlural(XubString& rName) const +{ + rName=ImpGetResStr(STR_ObjNamePluralCube3d); +} + +// eof diff --git a/svx/source/engine3d/deflt3d.cxx b/svx/source/engine3d/deflt3d.cxx new file mode 100644 index 000000000000..9e703abd7d0b --- /dev/null +++ b/svx/source/engine3d/deflt3d.cxx @@ -0,0 +1,81 @@ +/************************************************************************* + * + * 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_svx.hxx" + +#include <svx/deflt3d.hxx> +#include <svx/cube3d.hxx> +#include <svx/svxids.hrc> +#include <editeng/colritem.hxx> +#include <svx/e3ditem.hxx> + +/************************************************************************* +|* +|* Klasse zum verwalten der 3D-Default Attribute +|* +\************************************************************************/ + +// Konstruktor +E3dDefaultAttributes::E3dDefaultAttributes() +{ + Reset(); +} + +void E3dDefaultAttributes::Reset() +{ + // Compound-Objekt + bDefaultCreateNormals = TRUE; + bDefaultCreateTexture = TRUE; + + // Cube-Objekt + aDefaultCubePos = basegfx::B3DPoint(-500.0, -500.0, -500.0); + aDefaultCubeSize = basegfx::B3DVector(1000.0, 1000.0, 1000.0); + nDefaultCubeSideFlags = CUBE_FULL; + bDefaultCubePosIsCenter = FALSE; + + // Sphere-Objekt + aDefaultSphereCenter = basegfx::B3DPoint(0.0, 0.0, 0.0); + aDefaultSphereSize = basegfx::B3DPoint(1000.0, 1000.0, 1000.0); + + // Lathe-Objekt + nDefaultLatheEndAngle = 3600; + bDefaultLatheSmoothed = TRUE; + bDefaultLatheSmoothFrontBack = FALSE; + bDefaultLatheCharacterMode = FALSE; + bDefaultLatheCloseFront = TRUE; + bDefaultLatheCloseBack = TRUE; + + // Extrude-Objekt + bDefaultExtrudeSmoothed = TRUE; + bDefaultExtrudeSmoothFrontBack = FALSE; + bDefaultExtrudeCharacterMode = FALSE; + bDefaultExtrudeCloseFront = TRUE; + bDefaultExtrudeCloseBack = TRUE; +} + +// eof diff --git a/svx/source/engine3d/dragmt3d.cxx b/svx/source/engine3d/dragmt3d.cxx new file mode 100644 index 000000000000..fd44db7b02d9 --- /dev/null +++ b/svx/source/engine3d/dragmt3d.cxx @@ -0,0 +1,789 @@ +/************************************************************************* + * + * 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_svx.hxx" + +#include <dragmt3d.hxx> +#include <tools/shl.hxx> +#include <svx/svdpagv.hxx> +#include <svx/dialmgr.hxx> +#include <svx/svddrgmt.hxx> +#include <svx/svdtrans.hxx> +#include <svx/obj3d.hxx> +#include <svx/polysc3d.hxx> +#include <svx/e3dundo.hxx> +#include <svx/dialogs.hrc> +#include <svx/sdr/overlay/overlaypolypolygon.hxx> +#include <svx/sdr/overlay/overlaymanager.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <svx/sdr/contact/viewcontactofe3dscene.hxx> +#include <drawinglayer/geometry/viewinformation3d.hxx> +#include <svx/e3dsceneupdater.hxx> + +TYPEINIT1(E3dDragMethod, SdrDragMethod); + +/************************************************************************* +|* +|* Konstruktor aller 3D-DragMethoden +|* +\************************************************************************/ + +E3dDragMethod::E3dDragMethod ( + SdrDragView &_rView, + const SdrMarkList& rMark, + E3dDragConstraint eConstr, + BOOL bFull) +: SdrDragMethod(_rView), + meConstraint(eConstr), + mbMoveFull(bFull), + mbMovedAtAll(FALSE) +{ + // Fuer alle in der selektion befindlichen 3D-Objekte + // eine Unit anlegen + const long nCnt(rMark.GetMarkCount()); + static bool bDoInvalidate(false); + long nObjs(0); + + if(mbMoveFull) + { + // for non-visible 3D objects fallback to wireframe interaction + bool bInvisibleObjects(false); + + for(nObjs = 0;!bInvisibleObjects && nObjs < nCnt;nObjs++) + { + E3dObject* pE3dObj = dynamic_cast< E3dObject* >(rMark.GetMark(nObjs)->GetMarkedSdrObj()); + + if(pE3dObj) + { + if(!pE3dObj->HasFillStyle() && !pE3dObj->HasLineStyle()) + { + bInvisibleObjects = true; + } + } + } + + if(bInvisibleObjects) + { + mbMoveFull = false; + } + } + + for(nObjs = 0;nObjs < nCnt;nObjs++) + { + E3dObject* pE3dObj = dynamic_cast< E3dObject* >(rMark.GetMark(nObjs)->GetMarkedSdrObj()); + + if(pE3dObj) + { + // fill new interaction unit + E3dDragMethodUnit aNewUnit; + aNewUnit.mp3DObj = pE3dObj; + + // get transformations + aNewUnit.maInitTransform = aNewUnit.maTransform = pE3dObj->GetTransform(); + + if(pE3dObj->GetParentObj()) + { + // get transform between object and world, normally scene transform + aNewUnit.maInvDisplayTransform = aNewUnit.maDisplayTransform = pE3dObj->GetParentObj()->GetFullTransform(); + aNewUnit.maInvDisplayTransform.invert(); + } + + // SnapRects der beteiligten Objekte invalidieren, um eine + // Neuberechnung beim Setzen der Marker zu erzwingen + if(bDoInvalidate) + { + pE3dObj->SetRectsDirty(); + } + + if(!mbMoveFull) + { + // create wireframe visualisation for parent coordinate system + aNewUnit.maWireframePoly.clear(); + aNewUnit.maWireframePoly = pE3dObj->CreateWireframe(); + aNewUnit.maWireframePoly.transform(aNewUnit.maTransform); + } + + // FullBound ermitteln + maFullBound.Union(pE3dObj->GetSnapRect()); + + // Unit einfuegen + maGrp.push_back(aNewUnit); + } + } +} + +/************************************************************************* +|* +\************************************************************************/ + +void E3dDragMethod::TakeSdrDragComment(XubString& /*rStr*/) const +{ +} + +/************************************************************************* +|* +|* Erstelle das Drahtgittermodel fuer alle Aktionen +|* +\************************************************************************/ + +bool E3dDragMethod::BeginSdrDrag() +{ + if(E3DDRAG_CONSTR_Z == meConstraint) + { + const sal_uInt32 nCnt(maGrp.size()); + DragStat().Ref1() = maFullBound.Center(); + + for(sal_uInt32 nOb(0); nOb < nCnt; nOb++) + { + E3dDragMethodUnit& rCandidate = maGrp[nOb]; + rCandidate.mnStartAngle = GetAngle(DragStat().GetStart() - DragStat().GetRef1()); + rCandidate.mnLastAngle = 0; + } + } + else + { + maLastPos = DragStat().GetStart(); + } + + if(!mbMoveFull) + { + Show(); + } + + return TRUE; +} + +/************************************************************************* +|* +|* Schluss +|* +\************************************************************************/ + +bool E3dDragMethod::EndSdrDrag(bool /*bCopy*/) +{ + const sal_uInt32 nCnt(maGrp.size()); + + if(!mbMoveFull) + { + // WireFrame ausblenden + Hide(); + } + + // Alle Transformationen anwenden und UnDo's anlegen + if(mbMovedAtAll) + { + const bool bUndo = getSdrDragView().IsUndoEnabled(); + if( bUndo ) + getSdrDragView().BegUndo(SVX_RESSTR(RID_SVX_3D_UNDO_ROTATE)); + sal_uInt32 nOb(0); + + for(nOb=0;nOb<nCnt;nOb++) + { + E3dDragMethodUnit& rCandidate = maGrp[nOb]; + E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj); + rCandidate.mp3DObj->SetTransform(rCandidate.maTransform); + if( bUndo ) + { + getSdrDragView().AddUndo(new E3dRotateUndoAction(rCandidate.mp3DObj->GetModel(), + rCandidate.mp3DObj, rCandidate.maInitTransform, + rCandidate.maTransform)); + } + } + if( bUndo ) + getSdrDragView().EndUndo(); + } + + return TRUE; +} + +/************************************************************************* +|* +|* Abbruch +|* +\************************************************************************/ + +void E3dDragMethod::CancelSdrDrag() +{ + if(mbMoveFull) + { + if(mbMovedAtAll) + { + const sal_uInt32 nCnt(maGrp.size()); + + for(sal_uInt32 nOb(0); nOb < nCnt; nOb++) + { + // Transformation restaurieren + E3dDragMethodUnit& rCandidate = maGrp[nOb]; + E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj); + rCandidate.mp3DObj->SetTransform(rCandidate.maInitTransform); + } + } + } + else + { + // WireFrame ausblenden + Hide(); + } +} + +/************************************************************************* +|* +|* Gemeinsames MoveSdrDrag() +|* +\************************************************************************/ + +void E3dDragMethod::MoveSdrDrag(const Point& /*rPnt*/) +{ + mbMovedAtAll = true; +} + +/************************************************************************* +|* +|* Zeichne das Drahtgittermodel +|* +\************************************************************************/ + +// for migration from XOR to overlay +void E3dDragMethod::CreateOverlayGeometry(::sdr::overlay::OverlayManager& rOverlayManager) +{ + const sal_uInt32 nCnt(maGrp.size()); + basegfx::B2DPolyPolygon aResult; + + for(sal_uInt32 nOb(0); nOb < nCnt; nOb++) + { + E3dDragMethodUnit& rCandidate = maGrp[nOb]; + SdrPageView* pPV = getSdrDragView().GetSdrPageView(); + + if(pPV && pPV->HasMarkedObjPageView()) + { + const basegfx::B3DPolyPolygon aCandidate(rCandidate.maWireframePoly); + const sal_uInt32 nPlyCnt(aCandidate.count()); + + if(nPlyCnt) + { + const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(rCandidate.mp3DObj->GetScene()->GetViewContact()); + const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D()); + const basegfx::B3DHomMatrix aWorldToView(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection() * aViewInfo3D.getOrientation()); + const basegfx::B3DHomMatrix aTransform(aWorldToView * rCandidate.maDisplayTransform); + + // transform to relative scene coordinates + basegfx::B2DPolyPolygon aPolyPolygon(basegfx::tools::createB2DPolyPolygonFromB3DPolyPolygon(aCandidate, aTransform)); + + // transform to 2D view coordinates + aPolyPolygon.transform(rVCScene.getObjectTransformation()); + + aResult.append(aPolyPolygon); + } + } + } + + if(aResult.count()) + { + ::sdr::overlay::OverlayPolyPolygonStriped* pNew = new ::sdr::overlay::OverlayPolyPolygonStriped(aResult); + rOverlayManager.add(*pNew); + addToOverlayObjectList(*pNew); + } +} + +/************************************************************************* + + E3dDragRotate + +*************************************************************************/ + +TYPEINIT1(E3dDragRotate, E3dDragMethod); + +E3dDragRotate::E3dDragRotate(SdrDragView &_rView, + const SdrMarkList& rMark, + E3dDragConstraint eConstr, + BOOL bFull) +: E3dDragMethod(_rView, rMark, eConstr, bFull) +{ + // Zentrum aller selektierten Objekte in Augkoordinaten holen + const sal_uInt32 nCnt(maGrp.size()); + + if(nCnt) + { + const E3dScene *pScene = maGrp[0].mp3DObj->GetScene(); + + if(pScene) + { + const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pScene->GetViewContact()); + const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D()); + + for(sal_uInt32 nOb(0); nOb < nCnt; nOb++) + { + E3dDragMethodUnit& rCandidate = maGrp[nOb]; + basegfx::B3DPoint aObjCenter = rCandidate.mp3DObj->GetBoundVolume().getCenter(); + const basegfx::B3DHomMatrix aTransform(aViewInfo3D.getOrientation() * rCandidate.maDisplayTransform * rCandidate.maInitTransform); + + aObjCenter = aTransform * aObjCenter; + maGlobalCenter += aObjCenter; + } + + // Teilen durch Anzahl + if(nCnt > 1) + { + maGlobalCenter /= (double)nCnt; + } + + // get rotate center and transform to 3D eye coordinates + basegfx::B2DPoint aRotCenter2D(Ref1().X(), Ref1().Y()); + + // from world to relative scene using inverse getObjectTransformation() + basegfx::B2DHomMatrix aInverseObjectTransform(rVCScene.getObjectTransformation()); + aInverseObjectTransform.invert(); + aRotCenter2D = aInverseObjectTransform * aRotCenter2D; + + // from 3D view to 3D eye + basegfx::B3DPoint aRotCenter3D(aRotCenter2D.getX(), aRotCenter2D.getY(), 0.0); + basegfx::B3DHomMatrix aInverseViewToEye(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection()); + aInverseViewToEye.invert(); + aRotCenter3D = aInverseViewToEye * aRotCenter3D; + + // X,Y des RotCenter und Tiefe der gemeinsamen Objektmitte aus + // Rotationspunkt im Raum benutzen + maGlobalCenter.setX(aRotCenter3D.getX()); + maGlobalCenter.setY(aRotCenter3D.getY()); + } + } +} + +/************************************************************************* +|* +|* Das Objekt wird bewegt, bestimme die Winkel +|* +\************************************************************************/ + +void E3dDragRotate::MoveSdrDrag(const Point& rPnt) +{ + // call parent + E3dDragMethod::MoveSdrDrag(rPnt); + + if(DragStat().CheckMinMoved(rPnt)) + { + // Modifier holen + sal_uInt16 nModifier = 0; + if(getSdrDragView().ISA(E3dView)) + { + const MouseEvent& rLastMouse = ((E3dView&)getSdrDragView()).GetMouseEvent(); + nModifier = rLastMouse.GetModifier(); + } + + // Alle Objekte rotieren + const sal_uInt32 nCnt(maGrp.size()); + + for(sal_uInt32 nOb(0); nOb < nCnt; nOb++) + { + // Rotationswinkel bestimmen + double fWAngle, fHAngle; + E3dDragMethodUnit& rCandidate = maGrp[nOb]; + + if(E3DDRAG_CONSTR_Z == meConstraint) + { + fWAngle = NormAngle360(GetAngle(rPnt - DragStat().GetRef1()) - + rCandidate.mnStartAngle) - rCandidate.mnLastAngle; + rCandidate.mnLastAngle = (long)fWAngle + rCandidate.mnLastAngle; + fWAngle /= 100.0; + fHAngle = 0.0; + } + else + { + fWAngle = 90.0 * (double)(rPnt.X() - maLastPos.X()) + / (double)maFullBound.GetWidth(); + fHAngle = 90.0 * (double)(rPnt.Y() - maLastPos.Y()) + / (double)maFullBound.GetHeight(); + } + long nSnap = 0; + + if(!getSdrDragView().IsRotateAllowed(FALSE)) + nSnap = 90; + + if(nSnap != 0) + { + fWAngle = (double)(((long) fWAngle + nSnap/2) / nSnap * nSnap); + fHAngle = (double)(((long) fHAngle + nSnap/2) / nSnap * nSnap); + } + + // nach radiant + fWAngle *= F_PI180; + fHAngle *= F_PI180; + + // Transformation bestimmen + basegfx::B3DHomMatrix aRotMat; + if(E3DDRAG_CONSTR_Y & meConstraint) + { + if(nModifier & KEY_MOD2) + aRotMat.rotate(0.0, 0.0, fWAngle); + else + aRotMat.rotate(0.0, fWAngle, 0.0); + } + else if(E3DDRAG_CONSTR_Z & meConstraint) + { + if(nModifier & KEY_MOD2) + aRotMat.rotate(0.0, fWAngle, 0.0); + else + aRotMat.rotate(0.0, 0.0, fWAngle); + } + if(E3DDRAG_CONSTR_X & meConstraint) + { + aRotMat.rotate(fHAngle, 0.0, 0.0); + } + + // Transformation in Eye-Koordinaten, dort rotieren + // und zurueck + const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(rCandidate.mp3DObj->GetScene()->GetViewContact()); + const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D()); + basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation()); + aInverseOrientation.invert(); + + basegfx::B3DHomMatrix aTransMat(rCandidate.maDisplayTransform); + aTransMat *= aViewInfo3D.getOrientation(); + aTransMat.translate(-maGlobalCenter.getX(), -maGlobalCenter.getY(), -maGlobalCenter.getZ()); + aTransMat *= aRotMat; + aTransMat.translate(maGlobalCenter.getX(), maGlobalCenter.getY(), maGlobalCenter.getZ()); + aTransMat *= aInverseOrientation; + aTransMat *= rCandidate.maInvDisplayTransform; + + // ...und anwenden + rCandidate.maTransform *= aTransMat; + + if(mbMoveFull) + { + E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj); + rCandidate.mp3DObj->SetTransform(rCandidate.maTransform); + } + else + { + Hide(); + rCandidate.maWireframePoly.transform(aTransMat); + Show(); + } + } + maLastPos = rPnt; + DragStat().NextMove(rPnt); + } +} + +/************************************************************************* +|* +\************************************************************************/ + +Pointer E3dDragRotate::GetSdrDragPointer() const +{ + return Pointer(POINTER_ROTATE); +} + +/************************************************************************* +|* +|* E3dDragMove +|* Diese DragMethod wird nur bei Translationen innerhalb von 3D-Scenen +|* benoetigt. Wird eine 3D-Scene selbst verschoben, so wird diese DragMethod +|* nicht verwendet. +|* +\************************************************************************/ + +TYPEINIT1(E3dDragMove, E3dDragMethod); + +E3dDragMove::E3dDragMove(SdrDragView &_rView, + const SdrMarkList& rMark, + SdrHdlKind eDrgHdl, + E3dDragConstraint eConstr, + BOOL bFull) +: E3dDragMethod(_rView, rMark, eConstr, bFull), + meWhatDragHdl(eDrgHdl) +{ + switch(meWhatDragHdl) + { + case HDL_LEFT: + maScaleFixPos = maFullBound.RightCenter(); + break; + case HDL_RIGHT: + maScaleFixPos = maFullBound.LeftCenter(); + break; + case HDL_UPPER: + maScaleFixPos = maFullBound.BottomCenter(); + break; + case HDL_LOWER: + maScaleFixPos = maFullBound.TopCenter(); + break; + case HDL_UPLFT: + maScaleFixPos = maFullBound.BottomRight(); + break; + case HDL_UPRGT: + maScaleFixPos = maFullBound.BottomLeft(); + break; + case HDL_LWLFT: + maScaleFixPos = maFullBound.TopRight(); + break; + case HDL_LWRGT: + maScaleFixPos = maFullBound.TopLeft(); + break; + default: + // Bewegen des Objektes, HDL_MOVE + break; + } + + // Override wenn IsResizeAtCenter() + if(getSdrDragView().IsResizeAtCenter()) + { + meWhatDragHdl = HDL_USER; + maScaleFixPos = maFullBound.Center(); + } +} + +/************************************************************************* +|* +|* Das Objekt wird bewegt, bestimme die Translation +|* +\************************************************************************/ + +void E3dDragMove::MoveSdrDrag(const Point& rPnt) +{ + // call parent + E3dDragMethod::MoveSdrDrag(rPnt); + + if(DragStat().CheckMinMoved(rPnt)) + { + if(HDL_MOVE == meWhatDragHdl) + { + // Translation + // Bewegungsvektor bestimmen + basegfx::B3DPoint aGlobalMoveHead((double)(rPnt.X() - maLastPos.X()), (double)(rPnt.Y() - maLastPos.Y()), 32768.0); + basegfx::B3DPoint aGlobalMoveTail(0.0, 0.0, 32768.0); + const sal_uInt32 nCnt(maGrp.size()); + + // Modifier holen + sal_uInt16 nModifier(0); + + if(getSdrDragView().ISA(E3dView)) + { + const MouseEvent& rLastMouse = ((E3dView&)getSdrDragView()).GetMouseEvent(); + nModifier = rLastMouse.GetModifier(); + } + + for(sal_uInt32 nOb(0); nOb < nCnt; nOb++) + { + E3dDragMethodUnit& rCandidate = maGrp[nOb]; + const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(rCandidate.mp3DObj->GetScene()->GetViewContact()); + const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D()); + + // move coor from 2d world to 3d Eye + basegfx::B2DPoint aGlobalMoveHead2D((double)(rPnt.X() - maLastPos.X()), (double)(rPnt.Y() - maLastPos.Y())); + basegfx::B2DPoint aGlobalMoveTail2D(0.0, 0.0); + basegfx::B2DHomMatrix aInverseSceneTransform(rVCScene.getObjectTransformation()); + + aInverseSceneTransform.invert(); + aGlobalMoveHead2D = aInverseSceneTransform * aGlobalMoveHead2D; + aGlobalMoveTail2D = aInverseSceneTransform * aGlobalMoveTail2D; + + basegfx::B3DPoint aMoveHead3D(aGlobalMoveHead2D.getX(), aGlobalMoveHead2D.getY(), 0.5); + basegfx::B3DPoint aMoveTail3D(aGlobalMoveTail2D.getX(), aGlobalMoveTail2D.getY(), 0.5); + basegfx::B3DHomMatrix aInverseViewToEye(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection()); + aInverseViewToEye.invert(); + + aMoveHead3D = aInverseViewToEye * aMoveHead3D; + aMoveTail3D = aInverseViewToEye * aMoveTail3D; + + // eventually switch movement from XY to XZ plane + if(nModifier & KEY_MOD2) + { + double fZwi = aMoveHead3D.getY(); + aMoveHead3D.setY(aMoveHead3D.getZ()); + aMoveHead3D.setZ(fZwi); + + fZwi = aMoveTail3D.getY(); + aMoveTail3D.setY(aMoveTail3D.getZ()); + aMoveTail3D.setZ(fZwi); + } + + // Bewegungsvektor von Aug-Koordinaten nach Parent-Koordinaten + basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation()); + aInverseOrientation.invert(); + basegfx::B3DHomMatrix aCompleteTrans(rCandidate.maInvDisplayTransform * aInverseOrientation); + + aMoveHead3D = aCompleteTrans * aMoveHead3D; + aMoveTail3D = aCompleteTrans* aMoveTail3D; + + // build transformation + basegfx::B3DHomMatrix aTransMat; + basegfx::B3DPoint aTranslate(aMoveHead3D - aMoveTail3D); + aTransMat.translate(aTranslate.getX(), aTranslate.getY(), aTranslate.getZ()); + + // ...and apply + rCandidate.maTransform *= aTransMat; + + if(mbMoveFull) + { + E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj); + rCandidate.mp3DObj->SetTransform(rCandidate.maTransform); + } + else + { + Hide(); + rCandidate.maWireframePoly.transform(aTransMat); + Show(); + } + } + } + else + { + // Skalierung + // Skalierungsvektor bestimmen + Point aStartPos = DragStat().GetStart(); + const sal_uInt32 nCnt(maGrp.size()); + + for(sal_uInt32 nOb(0); nOb < nCnt; nOb++) + { + E3dDragMethodUnit& rCandidate = maGrp[nOb]; + const basegfx::B3DPoint aObjectCenter(rCandidate.mp3DObj->GetBoundVolume().getCenter()); + + // transform from 2D world view to 3D eye + const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(rCandidate.mp3DObj->GetScene()->GetViewContact()); + const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D()); + + basegfx::B2DPoint aGlobalScaleStart2D((double)(aStartPos.X()), (double)(aStartPos.Y())); + basegfx::B2DPoint aGlobalScaleNext2D((double)(rPnt.X()), (double)(rPnt.Y())); + basegfx::B2DPoint aGlobalScaleFixPos2D((double)(maScaleFixPos.X()), (double)(maScaleFixPos.Y())); + basegfx::B2DHomMatrix aInverseSceneTransform(rVCScene.getObjectTransformation()); + + aInverseSceneTransform.invert(); + aGlobalScaleStart2D = aInverseSceneTransform * aGlobalScaleStart2D; + aGlobalScaleNext2D = aInverseSceneTransform * aGlobalScaleNext2D; + aGlobalScaleFixPos2D = aInverseSceneTransform * aGlobalScaleFixPos2D; + + basegfx::B3DPoint aGlobalScaleStart3D(aGlobalScaleStart2D.getX(), aGlobalScaleStart2D.getY(), aObjectCenter.getZ()); + basegfx::B3DPoint aGlobalScaleNext3D(aGlobalScaleNext2D.getX(), aGlobalScaleNext2D.getY(), aObjectCenter.getZ()); + basegfx::B3DPoint aGlobalScaleFixPos3D(aGlobalScaleFixPos2D.getX(), aGlobalScaleFixPos2D.getY(), aObjectCenter.getZ()); + basegfx::B3DHomMatrix aInverseViewToEye(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection()); + + aInverseViewToEye.invert(); + basegfx::B3DPoint aScStart(aInverseViewToEye * aGlobalScaleStart3D); + basegfx::B3DPoint aScNext(aInverseViewToEye * aGlobalScaleNext3D); + basegfx::B3DPoint aScFixPos(aInverseViewToEye * aGlobalScaleFixPos3D); + + // constraints? + switch(meWhatDragHdl) + { + case HDL_LEFT: + case HDL_RIGHT: + // constrain to auf X -> Y equal + aScNext.setY(aScFixPos.getY()); + break; + case HDL_UPPER: + case HDL_LOWER: + // constrain to auf Y -> X equal + aScNext.setX(aScFixPos.getX()); + break; + default: + break; + } + + // get scale vector in eye coordinates + basegfx::B3DPoint aScaleVec(aScStart - aScFixPos); + aScaleVec.setZ(1.0); + + if(aScaleVec.getX() != 0.0) + { + aScaleVec.setX((aScNext.getX() - aScFixPos.getX()) / aScaleVec.getX()); + } + else + { + aScaleVec.setX(1.0); + } + + if(aScaleVec.getY() != 0.0) + { + aScaleVec.setY((aScNext.getY() - aScFixPos.getY()) / aScaleVec.getY()); + } + else + { + aScaleVec.setY(1.0); + } + + // SHIFT-key used? + if(getSdrDragView().IsOrtho()) + { + if(fabs(aScaleVec.getX()) > fabs(aScaleVec.getY())) + { + // X is biggest + aScaleVec.setY(aScaleVec.getX()); + } + else + { + // Y is biggest + aScaleVec.setX(aScaleVec.getY()); + } + } + + // build transformation + basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation()); + aInverseOrientation.invert(); + + basegfx::B3DHomMatrix aNewTrans = rCandidate.maInitTransform; + aNewTrans *= rCandidate.maDisplayTransform; + aNewTrans *= aViewInfo3D.getOrientation(); + aNewTrans.translate(-aScFixPos.getX(), -aScFixPos.getY(), -aScFixPos.getZ()); + aNewTrans.scale(aScaleVec.getX(), aScaleVec.getY(), aScaleVec.getZ()); + aNewTrans.translate(aScFixPos.getX(), aScFixPos.getY(), aScFixPos.getZ()); + aNewTrans *= aInverseOrientation; + aNewTrans *= rCandidate.maInvDisplayTransform; + + // ...und anwenden + rCandidate.maTransform = aNewTrans; + + if(mbMoveFull) + { + E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj); + rCandidate.mp3DObj->SetTransform(rCandidate.maTransform); + } + else + { + Hide(); + rCandidate.maWireframePoly.clear(); + rCandidate.maWireframePoly = rCandidate.mp3DObj->CreateWireframe(); + rCandidate.maWireframePoly.transform(rCandidate.maTransform); + Show(); + } + } + } + maLastPos = rPnt; + DragStat().NextMove(rPnt); + } +} + +/************************************************************************* +|* +\************************************************************************/ + +Pointer E3dDragMove::GetSdrDragPointer() const +{ + return Pointer(POINTER_MOVE); +} + +// eof diff --git a/svx/source/engine3d/e3dsceneupdater.cxx b/svx/source/engine3d/e3dsceneupdater.cxx new file mode 100644 index 000000000000..8fdaaf3ffc29 --- /dev/null +++ b/svx/source/engine3d/e3dsceneupdater.cxx @@ -0,0 +1,130 @@ +/************************************************************************* + * + * 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_svx.hxx" +#include <svx/e3dsceneupdater.hxx> +#include <drawinglayer/geometry/viewinformation3d.hxx> +#include <svx/obj3d.hxx> +#include <svx/scene3d.hxx> +#include <svx/sdr/contact/viewcontactofe3dscene.hxx> + +////////////////////////////////////////////////////////////////////////////// + +E3DModifySceneSnapRectUpdater::E3DModifySceneSnapRectUpdater(const SdrObject* pObject) +: mpScene(0), + mpViewInformation3D(0) +{ + // Secure old 3D transformation stack before modification + if(pObject) + { + const E3dObject* pE3dObject = dynamic_cast< const E3dObject* >(pObject); + + if(pE3dObject) + { + mpScene = pE3dObject->GetScene(); + + if(mpScene && mpScene->GetScene() == mpScene) + { + // if there is a scene and it's the outmost scene, get current 3D range + const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(mpScene->GetViewContact()); + const basegfx::B3DRange aAllContentRange(rVCScene.getAllContentRange3D()); + + if(aAllContentRange.isEmpty()) + { + // no content, nothing to do + mpScene = 0; + } + else + { + // secure current 3D transformation stack + mpViewInformation3D = new drawinglayer::geometry::ViewInformation3D(rVCScene.getViewInformation3D(aAllContentRange)); + } + } + } + } +} + +E3DModifySceneSnapRectUpdater::~E3DModifySceneSnapRectUpdater() +{ + if(mpScene && mpViewInformation3D) + { + // after changing parts of the scene, use the secured last 3d transformation stack and the new content + // range to calculate a new, eventually expanded or shrunk, 2D geometry for the scene and apply it. + // Get new content range + const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(mpScene->GetViewContact()); + basegfx::B3DRange aAllContentRange(rVCScene.getAllContentRange3D()); + + // only change when there is still content; else let scene stay at old SnapRect + if(!aAllContentRange.isEmpty()) + { + // check if object transform of scene has changed + if(mpViewInformation3D->getObjectTransformation() != mpScene->GetTransform()) + { + // If Yes, it needs to be updated since it's - for historical reasons - + // part of the basic 3d transformation stack of the scene + drawinglayer::geometry::ViewInformation3D* pNew = new drawinglayer::geometry::ViewInformation3D( + mpScene->GetTransform(), // replace object transformation with new local transform + mpViewInformation3D->getOrientation(), + mpViewInformation3D->getProjection(), + mpViewInformation3D->getDeviceToView(), + mpViewInformation3D->getViewTime(), + mpViewInformation3D->getExtendedInformationSequence()); + delete mpViewInformation3D; + mpViewInformation3D = pNew; + } + + // transform content range to scene-relative coordinates using old 3d transformation stack + aAllContentRange.transform(mpViewInformation3D->getObjectToView()); + + // build 2d relative content range + basegfx::B2DRange aSnapRange( + aAllContentRange.getMinX(), aAllContentRange.getMinY(), + aAllContentRange.getMaxX(), aAllContentRange.getMaxY()); + + // transform to 2D world coordiantes using scene's 2D transformation + aSnapRange.transform(rVCScene.getObjectTransformation()); + + // snap to (old) integer + const Rectangle aNewSnapRect( + sal_Int32(floor(aSnapRange.getMinX())), sal_Int32(floor(aSnapRange.getMinY())), + sal_Int32(ceil(aSnapRange.getMaxX())), sal_Int32(ceil(aSnapRange.getMaxY()))); + + // set as new SnapRect and invalidate bound volume + if(mpScene->GetSnapRect() != aNewSnapRect) + { + mpScene->SetSnapRect(aNewSnapRect); + mpScene->InvalidateBoundVolume(); + } + } + } + + delete mpViewInformation3D; +} + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/engine3d/e3dundo.cxx b/svx/source/engine3d/e3dundo.cxx new file mode 100644 index 000000000000..6c9a541b8c7c --- /dev/null +++ b/svx/source/engine3d/e3dundo.cxx @@ -0,0 +1,180 @@ +/************************************************************************* + * + * 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_svx.hxx" +#include <svx/e3dundo.hxx> +#include <svx/svdmodel.hxx> +#include <editeng/outlobj.hxx> +#include <svx/view3d.hxx> +#include <svx/scene3d.hxx> +#include <svx/e3dsceneupdater.hxx> + +/************************************************************************/ + +TYPEINIT1(E3dUndoAction, SfxUndoAction); + +/************************************************************************\ +|* +|* Destruktor der Basisklasse +|* +\************************************************************************/ +E3dUndoAction::~E3dUndoAction () +{ +} + +/************************************************************************\ +|* +|* Repeat gibt es nicht +|* +\************************************************************************/ +BOOL E3dUndoAction::CanRepeat(SfxRepeatTarget&) const +{ + return FALSE; +} + +/************************************************************************/ + +TYPEINIT1(E3dRotateUndoAction, E3dUndoAction); + +/************************************************************************ + + E3dRotateUndoAction + +************************************************************************/ + +/************************************************************************\ +|* +|* Undodestruktor fuer 3D-Rotation +|* +\************************************************************************/ +E3dRotateUndoAction::~E3dRotateUndoAction () +{ +} + +/************************************************************************\ +|* +|* Undo fuer 3D-Rotation ueber die Rotationsmatrizen +|* +\************************************************************************/ +void E3dRotateUndoAction::Undo () +{ + E3DModifySceneSnapRectUpdater aUpdater(pMy3DObj); + pMy3DObj->SetTransform(aMyOldRotation); +} + +/************************************************************************\ +|* +|* Undo fuer 3D-Rotation ueber die Rotationsmatrizen +|* +\************************************************************************/ +void E3dRotateUndoAction::Redo () +{ + E3DModifySceneSnapRectUpdater aUpdater(pMy3DObj); + pMy3DObj->SetTransform(aMyNewRotation); +} + +/************************************************************************* +|* +|* E3dAttributesUndoAction +|* +\************************************************************************/ + +TYPEINIT1(E3dAttributesUndoAction, SdrUndoAction); + +/************************************************************************* +|* +|* Konstruktor +|* +\************************************************************************/ +E3dAttributesUndoAction::E3dAttributesUndoAction( SdrModel &rModel, + E3dView* p3dView, + E3dObject* pInObject, + const SfxItemSet& rNewSet, + const SfxItemSet& rOldSet, + BOOL bUseSubObj) +: SdrUndoAction( rModel ), + pObject ( pInObject ), + pView ( p3dView ), + bUseSubObjects(bUseSubObj), + aNewSet ( rNewSet ), + aOldSet ( rOldSet ) +{ +} + +/************************************************************************* +|* +|* Destruktor +|* +\************************************************************************/ +E3dAttributesUndoAction::~E3dAttributesUndoAction() +{ +} + +/************************************************************************* +|* +|* Undo() +|* Implementiert ueber Set3DAttributes(), um die Attribute nur an einer +|* Stelle pflegen zu muessen! +|* +\************************************************************************/ +void E3dAttributesUndoAction::Undo() +{ + E3DModifySceneSnapRectUpdater aUpdater(pObject); + pObject->SetMergedItemSetAndBroadcast(aOldSet); +} + +/************************************************************************* +|* +|* Redo() +|* +\************************************************************************/ +void E3dAttributesUndoAction::Redo() +{ + E3DModifySceneSnapRectUpdater aUpdater(pObject); + pObject->SetMergedItemSetAndBroadcast(aNewSet); +} + +/************************************************************************* +|* +|* Mehrfaches Undo nicht moeglich +|* +\************************************************************************/ +BOOL E3dAttributesUndoAction::CanRepeat(SfxRepeatTarget& /*rView*/) const +{ + return FALSE; +} + +/************************************************************************* +|* +|* Mehrfaches Undo nicht moeglich +|* +\************************************************************************/ +void E3dAttributesUndoAction::Repeat() +{ +} + diff --git a/svx/source/engine3d/extrud3d.cxx b/svx/source/engine3d/extrud3d.cxx new file mode 100644 index 000000000000..7261586947c4 --- /dev/null +++ b/svx/source/engine3d/extrud3d.cxx @@ -0,0 +1,264 @@ +/************************************************************************* + * + * 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_svx.hxx" + +#include "svdstr.hrc" +#include "svdglob.hxx" +#include <svx/svdpage.hxx> +#include "globl3d.hxx" +#include <svx/extrud3d.hxx> +#include <svx/scene3d.hxx> + +#include <svx/svxids.hrc> +#include <svx/xpoly.hxx> +#include <svx/svdopath.hxx> +#include <svx/svdmodel.hxx> +#include <svx/svx3ditems.hxx> +#include <svx/sdr/properties/e3dextrudeproperties.hxx> +#include <svx/sdr/contact/viewcontactofe3dextrude.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b3dpolygontools.hxx> +#include <basegfx/polygon/b3dpolypolygontools.hxx> + +////////////////////////////////////////////////////////////////////////////// +// #110094# DrawContact section + +sdr::contact::ViewContact* E3dExtrudeObj::CreateObjectSpecificViewContact() +{ + return new sdr::contact::ViewContactOfE3dExtrude(*this); +} + +////////////////////////////////////////////////////////////////////////////// + +sdr::properties::BaseProperties* E3dExtrudeObj::CreateObjectSpecificProperties() +{ + return new sdr::properties::E3dExtrudeProperties(*this); +} + +////////////////////////////////////////////////////////////////////////////// + +TYPEINIT1(E3dExtrudeObj, E3dCompoundObject); + +/************************************************************************* +|* +|* Konstruktor, erzeugt zwei Deckelflaechen-PolyPolygone und (PointCount-1) +|* Seitenflaechen-Rechtecke aus dem uebergebenen PolyPolygon +|* +\************************************************************************/ + +E3dExtrudeObj::E3dExtrudeObj(E3dDefaultAttributes& rDefault, const basegfx::B2DPolyPolygon& rPP, double fDepth) +: E3dCompoundObject(rDefault), + maExtrudePolygon(rPP) +{ + // 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); + maExtrudePolygon.transform(aMirrorY); + + // Defaults setzen + SetDefaultAttributes(rDefault); + + // set extrude depth + GetProperties().SetObjectItemDirect(Svx3DDepthItem((sal_uInt32)(fDepth + 0.5))); +} + +E3dExtrudeObj::E3dExtrudeObj() +: E3dCompoundObject() +{ + // Defaults setzen + E3dDefaultAttributes aDefault; + SetDefaultAttributes(aDefault); +} + +void E3dExtrudeObj::SetDefaultAttributes(E3dDefaultAttributes& rDefault) +{ + GetProperties().SetObjectItemDirect(Svx3DSmoothNormalsItem(rDefault.GetDefaultExtrudeSmoothed())); + GetProperties().SetObjectItemDirect(Svx3DSmoothLidsItem(rDefault.GetDefaultExtrudeSmoothFrontBack())); + GetProperties().SetObjectItemDirect(Svx3DCharacterModeItem(rDefault.GetDefaultExtrudeCharacterMode())); + GetProperties().SetObjectItemDirect(Svx3DCloseFrontItem(rDefault.GetDefaultExtrudeCloseFront())); + GetProperties().SetObjectItemDirect(Svx3DCloseBackItem(rDefault.GetDefaultExtrudeCloseBack())); + + // Bei extrudes defaultmaessig StdTexture in X und Y + GetProperties().SetObjectItemDirect(Svx3DTextureProjectionXItem(1)); + GetProperties().SetObjectItemDirect(Svx3DTextureProjectionYItem(1)); +} + +/************************************************************************* +|* +|* Identifier zurueckgeben +|* +\************************************************************************/ + +UINT16 E3dExtrudeObj::GetObjIdentifier() const +{ + return E3D_EXTRUDEOBJ_ID; +} + +/************************************************************************* +|* +|* Zuweisungsoperator +|* +\************************************************************************/ + +void E3dExtrudeObj::operator=(const SdrObject& rObj) +{ + // erstmal alle Childs kopieren + E3dCompoundObject::operator=(rObj); + + // weitere Parameter kopieren + const E3dExtrudeObj& r3DObj = (const E3dExtrudeObj&)rObj; + + maExtrudePolygon = r3DObj.maExtrudePolygon; +} + +/************************************************************************* +|* +|* Lokale Parameter setzen mit Geometrieneuerzeugung +|* +\************************************************************************/ + +void E3dExtrudeObj::SetExtrudePolygon(const basegfx::B2DPolyPolygon &rNew) +{ + if(maExtrudePolygon != rNew) + { + maExtrudePolygon = rNew; + ActionChanged(); + } +} + +/************************************************************************* +|* +|* Get the name of the object (singular) +|* +\************************************************************************/ + +void E3dExtrudeObj::TakeObjNameSingul(XubString& rName) const +{ + rName=ImpGetResStr(STR_ObjNameSingulExtrude3d); + + String aName( GetName() ); + if(aName.Len()) + { + rName += sal_Unicode(' '); + rName += sal_Unicode('\''); + rName += aName; + rName += sal_Unicode('\''); + } +} + +/************************************************************************* +|* +|* Get the name of the object (plural) +|* +\************************************************************************/ + +void E3dExtrudeObj::TakeObjNamePlural(XubString& rName) const +{ + rName=ImpGetResStr(STR_ObjNamePluralExtrude3d); +} + +/************************************************************************* +|* +|* Aufbrechen +|* +\************************************************************************/ + +BOOL E3dExtrudeObj::IsBreakObjPossible() +{ + return TRUE; +} + +SdrAttrObj* E3dExtrudeObj::GetBreakObj() +{ + basegfx::B3DPolyPolygon aFrontSide; + basegfx::B3DPolyPolygon aBackSide; + + if(maExtrudePolygon.count()) + { + basegfx::B2DPolyPolygon aTemp(maExtrudePolygon); + aTemp.removeDoublePoints(); + aTemp = basegfx::tools::correctOrientations(aTemp); + const basegfx::B2VectorOrientation aOrient = basegfx::tools::getOrientation(aTemp.getB2DPolygon(0L)); + + if(basegfx::ORIENTATION_POSITIVE == aOrient) + { + aTemp.flip(); + } + + aFrontSide = basegfx::tools::createB3DPolyPolygonFromB2DPolyPolygon(aTemp); + } + + if(aFrontSide.count()) + { + aBackSide = aFrontSide; + + if(GetExtrudeDepth()) + { + basegfx::B3DHomMatrix aTransform; + + if(100 != GetPercentBackScale()) + { + // scale polygon from center + const double fScaleFactor(GetPercentBackScale() / 100.0); + const basegfx::B3DRange aPolyPolyRange(basegfx::tools::getRange(aBackSide)); + const basegfx::B3DPoint aCenter(aPolyPolyRange.getCenter()); + + aTransform.translate(-aCenter.getX(), -aCenter.getY(), -aCenter.getZ()); + aTransform.scale(fScaleFactor, fScaleFactor, fScaleFactor); + aTransform.translate(aCenter.getX(), aCenter.getY(), aCenter.getZ()); + } + + // translate by extrude depth + aTransform.translate(0.0, 0.0, (double)GetExtrudeDepth()); + + aBackSide.transform(aTransform); + } + } + + if(aBackSide.count()) + { + // create PathObj + basegfx::B2DPolyPolygon aPoly = TransformToScreenCoor(aBackSide); + SdrPathObj* pPathObj = new SdrPathObj(OBJ_PLIN, aPoly); + + if(pPathObj) + { + SfxItemSet aSet(GetObjectItemSet()); + aSet.Put(XLineStyleItem(XLINE_SOLID)); + pPathObj->SetMergedItemSet(aSet); + } + + return pPathObj; + } + + return 0; +} + +// eof diff --git a/svx/source/engine3d/float3d.cxx b/svx/source/engine3d/float3d.cxx new file mode 100644 index 000000000000..8ff6af906eaa --- /dev/null +++ b/svx/source/engine3d/float3d.cxx @@ -0,0 +1,3333 @@ +/************************************************************************* + * + * 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_svx.hxx" +#include <sfx2/dispatch.hxx> +#include <sfx2/module.hxx> +#include <sfx2/viewfrm.hxx> +#include <svl/eitem.hxx> +#include <svtools/colrdlg.hxx> +#include <vcl/msgbox.hxx> +#include <sfx2/viewsh.hxx> +#include <tools/shl.hxx> +#include <svx/xflclit.hxx> +#include <svx/svdmodel.hxx> +#include <globl3d.hxx> +#include <svx/view3d.hxx> +#include <svx/obj3d.hxx> +#include <svx/sphere3d.hxx> +#include <svx/scene3d.hxx> +#include <svx/camera3d.hxx> +#include <svx/fmmodel.hxx> +#include <svx/fmpage.hxx> +#include <svx/polysc3d.hxx> +#include <editeng/eeitem.hxx> +#include <svl/style.hxx> +#include <dlgutil.hxx> + +#include <dlgutil.hxx> +#include <svx/dialmgr.hxx> +#include <svx/viewpt3d.hxx> // ProjectionType + +#include <svx/svxids.hrc> +#include <svx/dialogs.hrc> + +#include <editeng/colritem.hxx> +#include <svx/e3ditem.hxx> + +#include <gallery.hxx> +#define GALLERY_THEME "3D" +#include <svl/whiter.hxx> + +#include <svx/float3d.hxx> +#include "float3d.hrc" + +SFX_IMPL_DOCKINGWINDOW( Svx3DChildWindow, SID_3D_WIN ) + +struct Svx3DWinImpl +{ + SfxItemPool* pPool; + Image maImgLightOnH; + Image maImgLightOffH; +}; + +#define SETHCIMAGE(btn,res) \ +{ \ + Bitmap aBmp( SVX_RES( res ) ); \ + Image aImage( aBmp, COL_LIGHTMAGENTA ); \ + btn.SetModeImage( aImage, BMP_COLOR_HIGHCONTRAST ); \ +} + +namespace { + /** Get the dispatcher from the current view frame, or, if that is not + available, from the given bindings. + @param pBindings + May be NULL. + @returns NULL when both the current view frame is NULL and the given + bindings are NULL. + */ + SfxDispatcher* LocalGetDispatcher (const SfxBindings* pBindings) + { + SfxDispatcher* pDispatcher = NULL; + + if (SfxViewFrame::Current() != NULL) + pDispatcher = SfxViewFrame::Current()->GetDispatcher(); + else if (pBindings != NULL) + pDispatcher = pBindings->GetDispatcher(); + + return pDispatcher; + } +} + + +/************************************************************************* +|* Svx3DWin - FloatingWindow +\************************************************************************/ +__EXPORT Svx3DWin::Svx3DWin( SfxBindings* pInBindings, + SfxChildWindow *pCW, Window* pParent ) : + SfxDockingWindow ( pInBindings, pCW, pParent, + SVX_RES( RID_SVXFLOAT_3D ) ), + aBtnGeo ( this, SVX_RES( BTN_GEO ) ), + aBtnRepresentation ( this, SVX_RES( BTN_REPRESENTATION ) ), + aBtnLight ( this, SVX_RES( BTN_LIGHT ) ), + aBtnTexture ( this, SVX_RES( BTN_TEXTURE ) ), + aBtnMaterial ( this, SVX_RES( BTN_MATERIAL ) ), + aBtnUpdate ( this, SVX_RES( BTN_UPDATE ) ), + aBtnAssign ( this, SVX_RES( BTN_ASSIGN ) ), + + // Geometrie + aFtPercentDiagonal ( this, SVX_RES( FT_PERCENT_DIAGONAL ) ), + aMtrPercentDiagonal ( this, SVX_RES( MTR_PERCENT_DIAGONAL ) ), + aFtBackscale ( this, SVX_RES( FT_BACKSCALE ) ), + aMtrBackscale ( this, SVX_RES( MTR_BACKSCALE ) ), + aFtEndAngle ( this, SVX_RES( FT_END_ANGLE ) ), + aMtrEndAngle ( this, SVX_RES( MTR_END_ANGLE ) ), + aFtDepth ( this, SVX_RES( FT_DEPTH ) ), + aMtrDepth ( this, SVX_RES( MTR_DEPTH ) ), + aFLGeometrie ( this, SVX_RES( FL_GEOMETRIE ) ), + + aFtHorizontal ( this, SVX_RES( FT_HORIZONTAL ) ), + aNumHorizontal ( this, SVX_RES( NUM_HORIZONTAL ) ), + aFtVertical ( this, SVX_RES( FT_VERTICAL ) ), + aNumVertical ( this, SVX_RES( NUM_VERTICAL ) ), + aFLSegments ( this, SVX_RES( FL_SEGMENTS ) ), + + aBtnNormalsObj ( this, SVX_RES( BTN_NORMALS_OBJ ) ), + aBtnNormalsFlat ( this, SVX_RES( BTN_NORMALS_FLAT ) ), + aBtnNormalsSphere ( this, SVX_RES( BTN_NORMALS_SPHERE ) ), + aBtnNormalsInvert ( this, SVX_RES( BTN_NORMALS_INVERT ) ), + aBtnTwoSidedLighting( this, SVX_RES( BTN_TWO_SIDED_LIGHTING ) ), + aFLNormals ( this, SVX_RES( FL_NORMALS ) ), + + aBtnDoubleSided ( this, SVX_RES( BTN_DOUBLE_SIDED ) ), + + // Darstellung + aFtShademode ( this, SVX_RES( FT_SHADEMODE ) ), + aLbShademode ( this, SVX_RES( LB_SHADEMODE ) ), + aBtnShadow3d ( this, SVX_RES( BTN_SHADOW_3D ) ), + aFtSlant ( this, SVX_RES( FT_SLANT ) ), + aMtrSlant ( this, SVX_RES( MTR_SLANT ) ), + aFLShadow ( this, SVX_RES( FL_SHADOW ) ), + aFtDistance ( this, SVX_RES( FT_DISTANCE ) ), + aMtrDistance ( this, SVX_RES( MTR_DISTANCE ) ), + aFtFocalLeng ( this, SVX_RES( FT_FOCAL_LENGTH ) ), + aMtrFocalLength ( this, SVX_RES( MTR_FOCAL_LENGTH ) ), + aFLCamera ( this, SVX_RES( FL_CAMERA ) ), + aFLRepresentation ( this, SVX_RES( FL_REPRESENTATION ) ), + + // Beleuchtung + aBtnLight1 ( this, SVX_RES( BTN_LIGHT_1 ) ), + aBtnLight2 ( this, SVX_RES( BTN_LIGHT_2 ) ), + aBtnLight3 ( this, SVX_RES( BTN_LIGHT_3 ) ), + aBtnLight4 ( this, SVX_RES( BTN_LIGHT_4 ) ), + aBtnLight5 ( this, SVX_RES( BTN_LIGHT_5 ) ), + aBtnLight6 ( this, SVX_RES( BTN_LIGHT_6 ) ), + aBtnLight7 ( this, SVX_RES( BTN_LIGHT_7 ) ), + aBtnLight8 ( this, SVX_RES( BTN_LIGHT_8 ) ), + aLbLight1 ( this, SVX_RES( LB_LIGHT_1 ) ), + aLbLight2 ( this, SVX_RES( LB_LIGHT_2 ) ), + aLbLight3 ( this, SVX_RES( LB_LIGHT_3 ) ), + aLbLight4 ( this, SVX_RES( LB_LIGHT_4 ) ), + aLbLight5 ( this, SVX_RES( LB_LIGHT_5 ) ), + aLbLight6 ( this, SVX_RES( LB_LIGHT_6 ) ), + aLbLight7 ( this, SVX_RES( LB_LIGHT_7 ) ), + aLbLight8 ( this, SVX_RES( LB_LIGHT_8 ) ), + + aBtnLightColor ( this, SVX_RES( BTN_LIGHT_COLOR ) ), + aFTLightsource ( this, SVX_RES( FT_LIGHTSOURCE ) ), + + // #99694# Keyboard shortcuts activate the next control, so the + // order needed to be changed here + aFTAmbientlight ( this, SVX_RES( FT_AMBIENTLIGHT ) ), // Text label + aLbAmbientlight ( this, SVX_RES( LB_AMBIENTLIGHT ) ), // ListBox + aBtnAmbientColor ( this, SVX_RES( BTN_AMBIENT_COLOR ) ), // color button + + aFLLight ( this, SVX_RES( FL_LIGHT ) ), + + // Texturen + aFtTexKind ( this, SVX_RES( FT_TEX_KIND ) ), + aBtnTexLuminance ( this, SVX_RES( BTN_TEX_LUMINANCE ) ), + aBtnTexColor ( this, SVX_RES( BTN_TEX_COLOR ) ), + aFtTexMode ( this, SVX_RES( FT_TEX_MODE ) ), + aBtnTexReplace ( this, SVX_RES( BTN_TEX_REPLACE ) ), + aBtnTexModulate ( this, SVX_RES( BTN_TEX_MODULATE ) ), + aBtnTexBlend ( this, SVX_RES( BTN_TEX_BLEND ) ), + aFtTexProjectionX ( this, SVX_RES( FT_TEX_PROJECTION_X ) ), + aBtnTexObjectX ( this, SVX_RES( BTN_TEX_OBJECT_X ) ), + aBtnTexParallelX ( this, SVX_RES( BTN_TEX_PARALLEL_X ) ), + aBtnTexCircleX ( this, SVX_RES( BTN_TEX_CIRCLE_X ) ), + aFtTexProjectionY ( this, SVX_RES( FT_TEX_PROJECTION_Y ) ), + aBtnTexObjectY ( this, SVX_RES( BTN_TEX_OBJECT_Y ) ), + aBtnTexParallelY ( this, SVX_RES( BTN_TEX_PARALLEL_Y ) ), + aBtnTexCircleY ( this, SVX_RES( BTN_TEX_CIRCLE_Y ) ), + aFtTexFilter ( this, SVX_RES( FT_TEX_FILTER ) ), + aBtnTexFilter ( this, SVX_RES( BTN_TEX_FILTER ) ), + aFLTexture ( this, SVX_RES( FL_TEXTURE ) ), + + // Material + aFtMatFavorites ( this, SVX_RES( FT_MAT_FAVORITES ) ), + aLbMatFavorites ( this, SVX_RES( LB_MAT_FAVORITES ) ), + aFtMatColor ( this, SVX_RES( FT_MAT_COLOR ) ), + aLbMatColor ( this, SVX_RES( LB_MAT_COLOR ) ), + aBtnMatColor ( this, SVX_RES( BTN_MAT_COLOR ) ), + aFtMatEmission ( this, SVX_RES( FT_MAT_EMISSION ) ), + aLbMatEmission ( this, SVX_RES( LB_MAT_EMISSION ) ), + aBtnEmissionColor ( this, SVX_RES( BTN_EMISSION_COLOR ) ), + aFtMatSpecular ( this, SVX_RES( FT_MAT_SPECULAR ) ), + aLbMatSpecular ( this, SVX_RES( LB_MAT_SPECULAR ) ), + aBtnSpecularColor ( this, SVX_RES( BTN_SPECULAR_COLOR ) ), + aFtMatSpecularIntensity( this, SVX_RES( FT_MAT_SPECULAR_INTENSITY ) ), + aMtrMatSpecularIntensity( this, SVX_RES( MTR_MAT_SPECULAR_INTENSITY ) ), + aFLMatSpecular ( this, SVX_RES( FL_MAT_SPECULAR ) ), + aFLMaterial ( this, SVX_RES( FL_MATERIAL ) ), + + // Unterer Bereich + aBtnConvertTo3D ( this, SVX_RES( BTN_CHANGE_TO_3D ) ), + aBtnLatheObject ( this, SVX_RES( BTN_LATHE_OBJ ) ), + aBtnPerspective ( this, SVX_RES( BTN_PERSPECTIVE ) ), + aCtlPreview ( this, SVX_RES( CTL_PREVIEW ) ), + aCtlLightPreview ( this, SVX_RES( CTL_LIGHT_PREVIEW ) ), + + aImgLightOn ( SVX_RES( RID_SVXIMAGE_LIGHT_ON ) ), + aImgLightOff ( SVX_RES( RID_SVXIMAGE_LIGHT_OFF ) ), + + bUpdate ( FALSE ), + eViewType ( VIEWTYPE_GEO ), + + pModel ( NULL ), + pFmPage ( NULL ), + pVDev ( NULL ), + p3DView ( NULL ), + pFavorSetList ( NULL ), + pMatFavSetList ( NULL ), + + pBindings ( pInBindings ), + pControllerItem(0L), + pConvertTo3DItem(0L), + pConvertTo3DLatheItem(0L), +// pPool ( NULL ), + mpImpl ( new Svx3DWinImpl() ), + mpRemember2DAttributes(NULL), + bOnly3DChanged ( FALSE ) +{ + SETHCIMAGE( aBtnGeo, BMP_GEO_H ); + SETHCIMAGE( aBtnRepresentation, BMP_REPRESENTATION_H ); + SETHCIMAGE( aBtnLight, BMP_3DLIGHT_H ); + SETHCIMAGE( aBtnTexture, BMP_TEXTURE_H ); + SETHCIMAGE( aBtnMaterial, BMP_MATERIAL_H ); + SETHCIMAGE( aBtnUpdate, BMP_UPDATE_H ); + SETHCIMAGE( aBtnAssign, BMP_ASSIGN_H ); + SETHCIMAGE( aBtnNormalsObj, BMP_NORMALS_OBJ_H ); + SETHCIMAGE( aBtnNormalsFlat, BMP_NORMALS_FLAT_H ); + SETHCIMAGE( aBtnNormalsSphere, BMP_NORMALS_SPHERE_H ); + SETHCIMAGE( aBtnTwoSidedLighting, BMP_TWO_SIDED_LIGHTING_H ); + SETHCIMAGE( aBtnNormalsInvert, BMP_NORMALS_INVERT_H ); + SETHCIMAGE( aBtnDoubleSided, BMP_DOUBLE_SIDED_H ); + SETHCIMAGE( aBtnShadow3d, BMP_SHADOW_3D_H ); + SETHCIMAGE( aBtnLight1, BMP_LIGHT_H ); + SETHCIMAGE( aBtnLight2, BMP_LIGHT_H ); + SETHCIMAGE( aBtnLight3, BMP_LIGHT_H ); + SETHCIMAGE( aBtnLight4, BMP_LIGHT_H ); + SETHCIMAGE( aBtnLight5, BMP_LIGHT_H ); + SETHCIMAGE( aBtnLight6, BMP_LIGHT_H ); + SETHCIMAGE( aBtnLight7, BMP_LIGHT_H ); + SETHCIMAGE( aBtnLight8, BMP_LIGHT_H ); + SETHCIMAGE( aBtnLightColor, BMP_LIGHT_COLOR_H ); + SETHCIMAGE( aBtnAmbientColor, BMP_AMBIENT_COLOR_H ); + SETHCIMAGE( aBtnTexLuminance, BMP_TEX_LUMINANCE_H ); + SETHCIMAGE( aBtnTexColor, BMP_TEX_COLOR_H ); + SETHCIMAGE( aBtnTexReplace, BMP_TEX_REPLACE_H ); + SETHCIMAGE( aBtnTexModulate, BMP_TEX_MODULATE_H ); + SETHCIMAGE( aBtnTexBlend, BMP_TEX_BLEND_H ); + SETHCIMAGE( aBtnTexParallelX, BMP_TEX_PARALLEL_H ); + SETHCIMAGE( aBtnTexCircleX, BMP_TEX_CIRCLE_H ); + SETHCIMAGE( aBtnTexObjectX, BMP_TEX_OBJECT_H ); + SETHCIMAGE( aBtnTexParallelY, BMP_TEX_PARALLEL_H ); + SETHCIMAGE( aBtnTexCircleY, BMP_TEX_CIRCLE_H ); + SETHCIMAGE( aBtnTexObjectY, BMP_TEX_OBJECT_H ); + SETHCIMAGE( aBtnTexFilter, BMP_TEX_FILTER_H ); + SETHCIMAGE( aBtnMatColor, BMP_COLORDLG_H ); + SETHCIMAGE( aBtnEmissionColor, BMP_COLORDLG_H ); + SETHCIMAGE( aBtnSpecularColor, BMP_COLORDLG_H ); + SETHCIMAGE( aBtnPerspective, BMP_PERSPECTIVE_H ); + SETHCIMAGE( aBtnConvertTo3D, BMP_CHANGE_TO_3D_H ); + SETHCIMAGE( aBtnLatheObject, BMP_LATHE_OBJ_H ); + + mpImpl->pPool = NULL; + mpImpl->maImgLightOnH = Image( SVX_RES( RID_SVXIMAGE_LIGHT_ON_H ) ); + mpImpl->maImgLightOffH = Image( SVX_RES( RID_SVXIMAGE_LIGHT_OFF_H ) ); + FreeResource(); + + // Metrik einstellen + eFUnit = pInBindings->GetDispatcher()->GetModule()->GetFieldUnit(); + + aMtrDepth.SetUnit( eFUnit ); + aMtrDistance.SetUnit( eFUnit ); + aMtrFocalLength.SetUnit( eFUnit ); + + pControllerItem = new Svx3DCtrlItem(SID_3D_STATE, this, pBindings); + pConvertTo3DItem = new SvxConvertTo3DItem(SID_CONVERT_TO_3D, pBindings); + pConvertTo3DLatheItem = new SvxConvertTo3DItem(SID_CONVERT_TO_3D_LATHE_FAST, pBindings); + + aBtnAssign.SetClickHdl( LINK( this, Svx3DWin, ClickAssignHdl ) ); + aBtnUpdate.SetClickHdl( LINK( this, Svx3DWin, ClickUpdateHdl ) ); + + Link aLink( LINK( this, Svx3DWin, ClickViewTypeHdl ) ); + aBtnGeo.SetClickHdl( aLink ); + aBtnRepresentation.SetClickHdl( aLink ); + aBtnLight.SetClickHdl( aLink ); + aBtnTexture.SetClickHdl( aLink ); + aBtnMaterial.SetClickHdl( aLink ); + + aLink = LINK( this, Svx3DWin, ClickHdl ); + aBtnPerspective.SetClickHdl( aLink ); + aBtnConvertTo3D.SetClickHdl( aLink ); + aBtnLatheObject.SetClickHdl( aLink ); + + // Geometrie + aBtnNormalsObj.SetClickHdl( aLink ); + aBtnNormalsFlat.SetClickHdl( aLink ); + aBtnNormalsSphere.SetClickHdl( aLink ); + aBtnTwoSidedLighting.SetClickHdl( aLink ); + aBtnNormalsInvert.SetClickHdl( aLink ); + aBtnDoubleSided.SetClickHdl( aLink ); + + // Darstellung + aBtnShadow3d.SetClickHdl( aLink ); + + // Beleuchtung + aBtnLight1.SetClickHdl( aLink ); + aBtnLight2.SetClickHdl( aLink ); + aBtnLight3.SetClickHdl( aLink ); + aBtnLight4.SetClickHdl( aLink ); + aBtnLight5.SetClickHdl( aLink ); + aBtnLight6.SetClickHdl( aLink ); + aBtnLight7.SetClickHdl( aLink ); + aBtnLight8.SetClickHdl( aLink ); + + // Texturen + aBtnTexLuminance.SetClickHdl( aLink ); + aBtnTexColor.SetClickHdl( aLink ); + aBtnTexReplace.SetClickHdl( aLink ); + aBtnTexModulate.SetClickHdl( aLink ); + //aBtnTexBlend.SetClickHdl( aLink ); + aBtnTexParallelX.SetClickHdl( aLink ); + aBtnTexCircleX.SetClickHdl( aLink ); + aBtnTexObjectX.SetClickHdl( aLink ); + aBtnTexParallelY.SetClickHdl( aLink ); + aBtnTexCircleY.SetClickHdl( aLink ); + aBtnTexObjectY.SetClickHdl( aLink ); + aBtnTexFilter.SetClickHdl( aLink ); + + // Material + aLink = LINK( this, Svx3DWin, ClickColorHdl ); + aBtnLightColor.SetClickHdl( aLink ); + aBtnAmbientColor.SetClickHdl( aLink ); + aBtnMatColor.SetClickHdl( aLink ); + aBtnEmissionColor.SetClickHdl( aLink ); + aBtnSpecularColor.SetClickHdl( aLink ); + + + aLink = LINK( this, Svx3DWin, SelectHdl ); + aLbMatFavorites.SetSelectHdl( aLink ); + aLbMatColor.SetSelectHdl( aLink ); + aLbMatEmission.SetSelectHdl( aLink ); + aLbMatSpecular.SetSelectHdl( aLink ); + aLbLight1.SetSelectHdl( aLink ); + aLbLight2.SetSelectHdl( aLink ); + aLbLight3.SetSelectHdl( aLink ); + aLbLight4.SetSelectHdl( aLink ); + aLbLight5.SetSelectHdl( aLink ); + aLbLight6.SetSelectHdl( aLink ); + aLbLight7.SetSelectHdl( aLink ); + aLbLight8.SetSelectHdl( aLink ); + aLbAmbientlight.SetSelectHdl( aLink ); + aLbShademode.SetSelectHdl( aLink ); + + aLink = LINK( this, Svx3DWin, ModifyHdl ); + aMtrMatSpecularIntensity.SetModifyHdl( aLink ); + aNumHorizontal.SetModifyHdl( aLink ); + aNumVertical.SetModifyHdl( aLink ); + aMtrSlant.SetModifyHdl( aLink ); + + // Preview-Callback + aLink = LINK( this, Svx3DWin, ChangeLightCallbackHdl ); + aCtlLightPreview.SetUserInteractiveChangeCallback(aLink); + aLink = LINK( this, Svx3DWin, ChangeSelectionCallbackHdl ); + aCtlLightPreview.SetUserSelectionChangeCallback(aLink); + + aSize = GetOutputSizePixel(); + SetMinOutputSizePixel( aSize ); + + Construct(); + + // Initiierung der Initialisierung der ColorLBs + SfxDispatcher* pDispatcher = LocalGetDispatcher(pBindings); + if (pDispatcher != NULL) + { + SfxBoolItem aItem( SID_3D_INIT, TRUE ); + pDispatcher->Execute( + SID_3D_INIT, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD, &aItem, 0L ); + } + + Reset(); +} + +// ----------------------------------------------------------------------- +__EXPORT Svx3DWin::~Svx3DWin() +{ + //delete pMatFavSetList; + delete p3DView; + delete pVDev; + delete pModel; + + delete pControllerItem; + delete pConvertTo3DItem; + delete pConvertTo3DLatheItem; + + if(mpRemember2DAttributes) + delete mpRemember2DAttributes; + + delete mpImpl; +} + +// ----------------------------------------------------------------------- +void Svx3DWin::Construct() +{ + aBtnGeo.Check(); + Link aLink( LINK( this, Svx3DWin, ClickViewTypeHdl ) ); + aLink.Call( &aBtnGeo ); + aCtlLightPreview.Hide(); +} + +// ----------------------------------------------------------------------- +void Svx3DWin::Reset() +{ + // Diverse Initialisierungen, default ist AllAttributes + aLbShademode.SelectEntryPos( 0 ); + aMtrMatSpecularIntensity.SetValue( 50 ); + + aBtnLight1.Check(); + ClickUpdateHdl( NULL ); + + // Nichts selektieren, um Fehler beim erstselektieren zu vermeiden + aCtlLightPreview.GetSvx3DLightControl().SelectLight(0); +} + +bool Svx3DWin::GetUILightState( ImageButton& aBtn ) const +{ + return (aBtn.GetModeImage() == aImgLightOn) || (aBtn.GetModeImage() == mpImpl->maImgLightOnH); +} + +void Svx3DWin::SetUILightState( ImageButton& aBtn, bool bState ) +{ + aBtn.SetModeImage( bState ? aImgLightOn : aImgLightOff ); + aBtn.SetModeImage( bState ? mpImpl->maImgLightOnH : mpImpl->maImgLightOffH, BMP_COLOR_HIGHCONTRAST ); +} + +// ----------------------------------------------------------------------- +void Svx3DWin::Update( SfxItemSet& rAttrs ) +{ + // remember 2d attributes + if(mpRemember2DAttributes) + mpRemember2DAttributes->ClearItem(); + else + mpRemember2DAttributes = new SfxItemSet(*rAttrs.GetPool(), + SDRATTR_START, SDRATTR_SHADOW_LAST, + SDRATTR_3D_FIRST, SDRATTR_3D_LAST, + 0, 0); + + SfxWhichIter aIter(*mpRemember2DAttributes); + sal_uInt16 nWhich(aIter.FirstWhich()); + + while(nWhich) + { + SfxItemState eState = rAttrs.GetItemState(nWhich, FALSE); + if(SFX_ITEM_DONTCARE == eState) + mpRemember2DAttributes->InvalidateItem(nWhich); + else if(SFX_ITEM_SET == eState) + mpRemember2DAttributes->Put(rAttrs.Get(nWhich, FALSE)); + + nWhich = aIter.NextWhich(); + } + + // construct field values + const SfxPoolItem* pItem; + //BOOL bUpdate = FALSE; + + // evtl. PoolUnit ermitteln + if( !mpImpl->pPool ) + { + mpImpl->pPool = rAttrs.GetPool(); + DBG_ASSERT( mpImpl->pPool, "Wo ist der Pool?" ); + ePoolUnit = mpImpl->pPool->GetMetric( SID_ATTR_LINE_WIDTH ); + } + eFUnit = GetModuleFieldUnit( rAttrs ); + + +// Segmentanzahl aenderbar ? und andere Stati + SfxItemState eState = rAttrs.GetItemState( SID_ATTR_3D_INTERN, FALSE, &pItem ); + if( SFX_ITEM_SET == eState ) + { + UINT32 nState = ( ( const SfxUInt32Item* )pItem )->GetValue(); + //BOOL bLathe = (BOOL) ( nState & 1 ); + BOOL bExtrude = (BOOL) ( nState & 2 ); + BOOL bSphere = (BOOL) ( nState & 4 ); + BOOL bCube = (BOOL) ( nState & 8 ); + + BOOL bChart = (BOOL) ( nState & 32 ); // Chart + + if( !bChart ) + { + // Bei Cube-Objekten werden keine Segmente eingestellt + aFtHorizontal.Enable( !bCube ); + aNumHorizontal.Enable( !bCube ); + aFtVertical.Enable( !bCube ); + aNumVertical.Enable( !bCube ); + aFLSegments.Enable( !bCube ); + + aFtPercentDiagonal.Enable( !bCube && !bSphere ); + aMtrPercentDiagonal.Enable( !bCube && !bSphere ); + aFtBackscale.Enable( !bCube && !bSphere ); + aMtrBackscale.Enable( !bCube && !bSphere ); + aFtDepth.Enable( !bCube && !bSphere ); + aMtrDepth.Enable( !bCube && !bSphere ); + if( bCube ) + { + aNumHorizontal.SetEmptyFieldValue(); + aNumVertical.SetEmptyFieldValue(); + } + if( bCube || bSphere ) + { + aMtrPercentDiagonal.SetEmptyFieldValue(); + aMtrBackscale.SetEmptyFieldValue(); + aMtrDepth.SetEmptyFieldValue(); + } + + // Nur bei Lathe-Objekten gibt es einen Endwinkel + aFtEndAngle.Enable( !bExtrude && !bCube && !bSphere ); + aMtrEndAngle.Enable( !bExtrude && !bCube && !bSphere ); + if( bExtrude || bCube || bSphere ) + aMtrEndAngle.SetEmptyFieldValue(); + } + else + { + // Geometrie + aFtHorizontal.Enable( FALSE ); + aNumHorizontal.Enable( FALSE ); + aNumHorizontal.SetEmptyFieldValue(); + aFtVertical.Enable( FALSE ); + aNumVertical.Enable( FALSE ); + aNumVertical.SetEmptyFieldValue(); + aFLSegments.Enable( FALSE ); + aFtEndAngle.Enable( FALSE ); + aMtrEndAngle.Enable( FALSE ); + aMtrEndAngle.SetEmptyFieldValue(); + aFtDepth.Enable( FALSE ); + aMtrDepth.Enable( FALSE ); + aMtrDepth.SetEmptyFieldValue(); + + // Darstellung + aBtnShadow3d.Enable( FALSE ); + aFtSlant.Enable( FALSE ); + aMtrSlant.Enable( FALSE ); + aFLShadow.Enable( FALSE ); + + aFtDistance.Enable( FALSE ); + aMtrDistance.Enable( FALSE ); + aMtrDistance.SetEmptyFieldValue(); + aFtFocalLeng.Enable( FALSE ); + aMtrFocalLength.Enable( FALSE ); + aMtrFocalLength.SetEmptyFieldValue(); + aFLCamera.Enable( FALSE ); + + // Unterer Bereich + aBtnConvertTo3D.Enable( FALSE ); + aBtnLatheObject.Enable( FALSE ); + } + } +// Bitmapfuellung ? -> Status + BOOL bBitmap(FALSE); + eState = rAttrs.GetItemState(XATTR_FILLSTYLE); + if(eState != SFX_ITEM_DONTCARE) + { + XFillStyle eXFS = (XFillStyle)((const XFillStyleItem&)rAttrs.Get(XATTR_FILLSTYLE)).GetValue(); + bBitmap = (eXFS == XFILL_BITMAP || eXFS == XFILL_GRADIENT || eXFS == XFILL_HATCH); + } + + aFtTexKind.Enable( bBitmap ); + aBtnTexLuminance.Enable( bBitmap ); + aBtnTexColor.Enable( bBitmap ); + aFtTexMode.Enable( bBitmap ); + aBtnTexReplace.Enable( bBitmap ); + aBtnTexModulate.Enable( bBitmap ); + aBtnTexBlend.Enable( bBitmap ); + aFtTexProjectionX.Enable( bBitmap ); + aBtnTexParallelX.Enable( bBitmap ); + aBtnTexCircleX.Enable( bBitmap ); + aBtnTexObjectX.Enable( bBitmap ); + aFtTexProjectionY.Enable( bBitmap ); + aBtnTexParallelY.Enable( bBitmap ); + aBtnTexCircleY.Enable( bBitmap ); + aBtnTexObjectY.Enable( bBitmap ); + aFtTexFilter.Enable( bBitmap ); + aBtnTexFilter.Enable( bBitmap ); + aFLTexture.Enable( bBitmap ); + + +// Geometrie + // Anzahl Segmente (horizontal) + if( aNumHorizontal.IsEnabled() ) + { + eState = rAttrs.GetItemState(SDRATTR_3DOBJ_HORZ_SEGS); + if(eState != SFX_ITEM_DONTCARE) + { + sal_uInt32 nValue = ((const Svx3DHorizontalSegmentsItem&)rAttrs.Get(SDRATTR_3DOBJ_HORZ_SEGS)).GetValue(); + if(nValue != (sal_uInt32 )aNumHorizontal.GetValue()) + { + aNumHorizontal.SetValue( nValue ); + // evtl. am Ende... + // aCtlLightPreview.GetSvx3DLightControl().SetHorizontalSegments( (UINT16)nValue ); + bUpdate = TRUE; + } + else if( aNumHorizontal.IsEmptyFieldValue() ) + aNumHorizontal.SetValue( nValue ); + } + else + { + if( !aNumHorizontal.IsEmptyFieldValue() ) + { + aNumHorizontal.SetEmptyFieldValue(); + bUpdate = TRUE; + } + } + } + + // Anzahl Segmente (vertikal) + if( aNumVertical.IsEnabled() ) + { + eState = rAttrs.GetItemState(SDRATTR_3DOBJ_VERT_SEGS); + if( eState != SFX_ITEM_DONTCARE ) + { + UINT32 nValue = ((const Svx3DVerticalSegmentsItem&)rAttrs.Get(SDRATTR_3DOBJ_VERT_SEGS)).GetValue(); + if( nValue != (UINT32) aNumVertical.GetValue() ) + { + aNumVertical.SetValue( nValue ); + // evtl. am Ende... + //aCtlLightPreview.GetSvx3DLightControl().SetVerticalSegments( (UINT16)nValue ); + bUpdate = TRUE; + } + else if( aNumVertical.IsEmptyFieldValue() ) + aNumVertical.SetValue( nValue ); + } + else + { + if( !aNumVertical.IsEmptyFieldValue() ) + { + aNumVertical.SetEmptyFieldValue(); + bUpdate = TRUE; + } + } + } + + // Tiefe + if( aMtrDepth.IsEnabled() ) + { + eState = rAttrs.GetItemState(SDRATTR_3DOBJ_DEPTH); + if( eState != SFX_ITEM_DONTCARE ) + { + UINT32 nValue = ((const Svx3DDepthItem&)rAttrs.Get(SDRATTR_3DOBJ_DEPTH)).GetValue(); + UINT32 nValue2 = GetCoreValue( aMtrDepth, ePoolUnit ); + if( nValue != nValue2 ) + { + if( eFUnit != aMtrDepth.GetUnit() ) + SetFieldUnit( aMtrDepth, eFUnit ); + + SetMetricValue( aMtrDepth, nValue, ePoolUnit ); + bUpdate = TRUE; + } + else if( aMtrDepth.IsEmptyFieldValue() ) + aMtrDepth.SetValue( aMtrDepth.GetValue() ); + } + else + { + if( !aMtrDepth.IsEmptyFieldValue() ) + { + aMtrDepth.SetEmptyFieldValue(); + bUpdate = TRUE; + } + } + } + + // Doppelwandig/-seitig + eState = rAttrs.GetItemState(SDRATTR_3DOBJ_DOUBLE_SIDED); + if( eState != SFX_ITEM_DONTCARE ) + { + BOOL bValue = ((const Svx3DDoubleSidedItem&)rAttrs.Get(SDRATTR_3DOBJ_DOUBLE_SIDED)).GetValue(); + if( bValue != aBtnDoubleSided.IsChecked() ) + { + aBtnDoubleSided.Check( bValue ); + bUpdate = TRUE; + } + else if( aBtnDoubleSided.GetState() == STATE_DONTKNOW ) + aBtnDoubleSided.Check( bValue ); + } + else + { + if( aBtnDoubleSided.GetState() != STATE_DONTKNOW ) + { + aBtnDoubleSided.SetState( STATE_DONTKNOW ); + bUpdate = TRUE; + } + } + + // Kantenrundung + if( aMtrPercentDiagonal.IsEnabled() ) + { + eState = rAttrs.GetItemState(SDRATTR_3DOBJ_PERCENT_DIAGONAL); + if( eState != SFX_ITEM_DONTCARE ) + { + UINT16 nValue = ((const Svx3DPercentDiagonalItem&)rAttrs.Get(SDRATTR_3DOBJ_PERCENT_DIAGONAL)).GetValue(); + if( nValue != aMtrPercentDiagonal.GetValue() ) + { + aMtrPercentDiagonal.SetValue( nValue ); + bUpdate = TRUE; + } + else if( aMtrPercentDiagonal.IsEmptyFieldValue() ) + aMtrPercentDiagonal.SetValue( nValue ); + } + else + { + if( !aMtrPercentDiagonal.IsEmptyFieldValue() ) + { + aMtrPercentDiagonal.SetEmptyFieldValue(); + bUpdate = TRUE; + } + } + } + + // Tiefenskalierung + if( aMtrBackscale.IsEnabled() ) + { + eState = rAttrs.GetItemState(SDRATTR_3DOBJ_BACKSCALE); + if( eState != SFX_ITEM_DONTCARE ) + { + UINT16 nValue = ((const Svx3DBackscaleItem&)rAttrs.Get(SDRATTR_3DOBJ_BACKSCALE)).GetValue(); + if( nValue != aMtrBackscale.GetValue() ) + { + aMtrBackscale.SetValue( nValue ); + bUpdate = TRUE; + } + else if( aMtrBackscale.IsEmptyFieldValue() ) + aMtrBackscale.SetValue( nValue ); + } + else + { + if( !aMtrBackscale.IsEmptyFieldValue() ) + { + aMtrBackscale.SetEmptyFieldValue(); + bUpdate = TRUE; + } + } + } + + // Endwinkel + if( aMtrEndAngle.IsEnabled() ) + { + eState = rAttrs.GetItemState(SDRATTR_3DOBJ_END_ANGLE); + if( eState != SFX_ITEM_DONTCARE ) + { + INT32 nValue = ((const Svx3DEndAngleItem&)rAttrs.Get(SDRATTR_3DOBJ_END_ANGLE)).GetValue(); + if( nValue != aMtrEndAngle.GetValue() ) + { + aMtrEndAngle.SetValue( nValue ); + bUpdate = TRUE; + } + } + else + { + if( !aMtrEndAngle.IsEmptyFieldValue() ) + { + aMtrEndAngle.SetEmptyFieldValue(); + bUpdate = TRUE; + } + } + } + + // Normalentyp + eState = rAttrs.GetItemState(SDRATTR_3DOBJ_NORMALS_KIND); + if( eState != SFX_ITEM_DONTCARE ) + { + UINT16 nValue = ((const Svx3DNormalsKindItem&)rAttrs.Get(SDRATTR_3DOBJ_NORMALS_KIND)).GetValue(); + + if( ( !aBtnNormalsObj.IsChecked() && nValue == 0 ) || + ( !aBtnNormalsFlat.IsChecked() && nValue == 1 ) || + ( !aBtnNormalsSphere.IsChecked() && nValue == 2 ) ) + { + aBtnNormalsObj.Check( nValue == 0 ); + aBtnNormalsFlat.Check( nValue == 1 ); + aBtnNormalsSphere.Check( nValue == 2 ); + bUpdate = TRUE; + } + } + else + { + if( aBtnNormalsObj.IsChecked() || + aBtnNormalsFlat.IsChecked() || + aBtnNormalsSphere.IsChecked() ) + { + aBtnNormalsObj.Check( FALSE ); + aBtnNormalsFlat.Check( FALSE ); + aBtnNormalsSphere.Check( FALSE ); + bUpdate = TRUE; + } + } + + // Normalen invertieren + eState = rAttrs.GetItemState(SDRATTR_3DOBJ_NORMALS_INVERT); + if( eState != SFX_ITEM_DONTCARE ) + { + BOOL bValue = ((const Svx3DNormalsInvertItem&)rAttrs.Get(SDRATTR_3DOBJ_NORMALS_INVERT)).GetValue(); + if( bValue != aBtnNormalsInvert.IsChecked() ) + { + aBtnNormalsInvert.Check( bValue ); + bUpdate = TRUE; + } + else if( aBtnNormalsInvert.GetState() == STATE_DONTKNOW ) + aBtnNormalsInvert.Check( bValue ); + } + else + { + if( aBtnNormalsInvert.GetState() != STATE_DONTKNOW ) + { + aBtnNormalsInvert.SetState( STATE_DONTKNOW ); + bUpdate = TRUE; + } + } + + // 2-seitige Beleuchtung + eState = rAttrs.GetItemState(SDRATTR_3DSCENE_TWO_SIDED_LIGHTING); + if( eState != SFX_ITEM_DONTCARE ) + { + BOOL bValue = ((const Svx3DTwoSidedLightingItem&)rAttrs.Get(SDRATTR_3DSCENE_TWO_SIDED_LIGHTING)).GetValue(); + if( bValue != aBtnTwoSidedLighting.IsChecked() ) + { + aBtnTwoSidedLighting.Check( bValue ); + bUpdate = TRUE; + } + else if( aBtnTwoSidedLighting.GetState() == STATE_DONTKNOW ) + aBtnTwoSidedLighting.Check( bValue ); + } + else + { + if( aBtnTwoSidedLighting.GetState() != STATE_DONTKNOW ) + { + aBtnTwoSidedLighting.SetState( STATE_DONTKNOW ); + bUpdate = TRUE; + } + } + +// Darstellung + // Shademode + eState = rAttrs.GetItemState(SDRATTR_3DSCENE_SHADE_MODE); + if( eState != SFX_ITEM_DONTCARE ) + { + UINT16 nValue = ((const Svx3DShadeModeItem&)rAttrs.Get(SDRATTR_3DSCENE_SHADE_MODE)).GetValue(); + if( nValue != aLbShademode.GetSelectEntryPos() ) + { + aLbShademode.SelectEntryPos( nValue ); + bUpdate = TRUE; + } + } + else + { + if( aLbShademode.GetSelectEntryCount() != 0 ) + { + aLbShademode.SetNoSelection(); + bUpdate = TRUE; + } + } + + // 3D-Shatten + eState = rAttrs.GetItemState(SDRATTR_3DOBJ_SHADOW_3D); + if( eState != SFX_ITEM_DONTCARE ) + { + BOOL bValue = ((const Svx3DShadow3DItem&)rAttrs.Get(SDRATTR_3DOBJ_SHADOW_3D)).GetValue(); + if( bValue != aBtnShadow3d.IsChecked() ) + { + aBtnShadow3d.Check( bValue ); + aFtSlant.Enable( bValue ); + aMtrSlant.Enable( bValue ); + bUpdate = TRUE; + } + else if( aBtnShadow3d.GetState() == STATE_DONTKNOW ) + aBtnShadow3d.Check( bValue ); + } + else + { + if( aBtnShadow3d.GetState() != STATE_DONTKNOW ) + { + aBtnShadow3d.SetState( STATE_DONTKNOW ); + bUpdate = TRUE; + } + } + + // Neigung (Schatten) + eState = rAttrs.GetItemState(SDRATTR_3DSCENE_SHADOW_SLANT); + if( eState != SFX_ITEM_DONTCARE ) + { + UINT16 nValue = ((const Svx3DShadowSlantItem&)rAttrs.Get(SDRATTR_3DSCENE_SHADOW_SLANT)).GetValue(); + if( nValue != aMtrSlant.GetValue() ) + { + aMtrSlant.SetValue( nValue ); + bUpdate = TRUE; + } + } + else + { + if( !aMtrSlant.IsEmptyFieldValue() ) + { + aMtrSlant.SetEmptyFieldValue(); + bUpdate = TRUE; + } + } + + // Distanz + eState = rAttrs.GetItemState(SDRATTR_3DSCENE_DISTANCE); + if( eState != SFX_ITEM_DONTCARE ) + { + UINT32 nValue = ((const Svx3DDistanceItem&)rAttrs.Get(SDRATTR_3DSCENE_DISTANCE)).GetValue(); + UINT32 nValue2 = GetCoreValue( aMtrDistance, ePoolUnit ); + if( nValue != nValue2 ) + { + if( eFUnit != aMtrDistance.GetUnit() ) + SetFieldUnit( aMtrDistance, eFUnit ); + + SetMetricValue( aMtrDistance, nValue, ePoolUnit ); + bUpdate = TRUE; + } + } + else + { + if( !aMtrDepth.IsEmptyFieldValue() ) + { + aMtrDepth.SetEmptyFieldValue(); + bUpdate = TRUE; + } + } + + // Brennweite + eState = rAttrs.GetItemState(SDRATTR_3DSCENE_FOCAL_LENGTH); + if( eState != SFX_ITEM_DONTCARE ) + { + UINT32 nValue = ((const Svx3DFocalLengthItem&)rAttrs.Get(SDRATTR_3DSCENE_FOCAL_LENGTH)).GetValue(); + UINT32 nValue2 = GetCoreValue( aMtrFocalLength, ePoolUnit ); + if( nValue != nValue2 ) + { + if( eFUnit != aMtrFocalLength.GetUnit() ) + SetFieldUnit( aMtrFocalLength, eFUnit ); + + SetMetricValue( aMtrFocalLength, nValue, ePoolUnit ); + bUpdate = TRUE; + } + } + else + { + if( !aMtrFocalLength.IsEmptyFieldValue() ) + { + aMtrFocalLength.SetEmptyFieldValue(); + bUpdate = TRUE; + } + } + +// Beleuchtung + Color aColor; + basegfx::B3DVector aVector; + // Licht 1 (Farbe) + eState = rAttrs.GetItemState(SDRATTR_3DSCENE_LIGHTCOLOR_1); + if( eState != SFX_ITEM_DONTCARE ) + { + aColor = ((const Svx3DLightcolor1Item&)rAttrs.Get(SDRATTR_3DSCENE_LIGHTCOLOR_1)).GetValue(); + ColorLB* pLb = &aLbLight1; + if( aColor != pLb->GetSelectEntryColor() ) + { + LBSelectColor( pLb, aColor ); + bUpdate = TRUE; + } + } + else + { + if( aLbLight1.GetSelectEntryCount() != 0 ) + { + aLbLight1.SetNoSelection(); + bUpdate = TRUE; + } + } + // Licht 1 (an/aus) + eState = rAttrs.GetItemState(SDRATTR_3DSCENE_LIGHTON_1); + if( eState != SFX_ITEM_DONTCARE ) + { + bool bOn = ((const Svx3DLightOnOff1Item&)rAttrs.Get(SDRATTR_3DSCENE_LIGHTON_1)).GetValue() != 0; + if( ( bOn && !GetUILightState( aBtnLight1 )) || + ( !bOn && GetUILightState( aBtnLight1 )) ) + { + SetUILightState( aBtnLight1, bOn ); + bUpdate = TRUE; + } + if( aBtnLight1.GetState() == STATE_DONTKNOW ) + aBtnLight1.Check( aBtnLight1.IsChecked() ); + } + else + { + if( aBtnLight1.GetState() != STATE_DONTKNOW ) + { + aBtnLight1.SetState( STATE_DONTKNOW ); + bUpdate = TRUE; + } + } + // Licht 1 (Richtung) + eState = rAttrs.GetItemState(SDRATTR_3DSCENE_LIGHTDIRECTION_1); + if( eState != SFX_ITEM_DONTCARE ) + { + bUpdate = TRUE; + } + + // Licht 2 (Farbe) + eState = rAttrs.GetItemState(SDRATTR_3DSCENE_LIGHTCOLOR_2); + if( eState != SFX_ITEM_DONTCARE ) + { + aColor = ((const Svx3DLightcolor2Item&)rAttrs.Get(SDRATTR_3DSCENE_LIGHTCOLOR_2)).GetValue(); + ColorLB* pLb = &aLbLight2; + if( aColor != pLb->GetSelectEntryColor() ) + { + LBSelectColor( pLb, aColor ); + bUpdate = TRUE; + } + } + else + { + if( aLbLight2.GetSelectEntryCount() != 0 ) + { + aLbLight2.SetNoSelection(); + bUpdate = TRUE; + } + } + // Licht 2 (an/aus) + eState = rAttrs.GetItemState(SDRATTR_3DSCENE_LIGHTON_2); + if( eState != SFX_ITEM_DONTCARE ) + { + bool bOn = ((const Svx3DLightOnOff2Item&)rAttrs.Get(SDRATTR_3DSCENE_LIGHTON_2)).GetValue() != 0; + if( ( bOn && !GetUILightState( aBtnLight2 )) || + ( !bOn && GetUILightState( aBtnLight2 )) ) + { + SetUILightState( aBtnLight2, bOn ); + bUpdate = TRUE; + } + if( aBtnLight2.GetState() == STATE_DONTKNOW ) + aBtnLight2.Check( aBtnLight2.IsChecked() ); + } + else + { + if( aBtnLight2.GetState() != STATE_DONTKNOW ) + { + aBtnLight2.SetState( STATE_DONTKNOW ); + bUpdate = TRUE; + } + } + // Licht 2 (Richtung) + eState = rAttrs.GetItemState(SDRATTR_3DSCENE_LIGHTDIRECTION_2); + if( eState != SFX_ITEM_DONTCARE ) + { + bUpdate = TRUE; + } + + // Licht 3 (Farbe) + eState = rAttrs.GetItemState(SDRATTR_3DSCENE_LIGHTCOLOR_3); + if( eState != SFX_ITEM_DONTCARE ) + { + aColor = ((const Svx3DLightcolor3Item&)rAttrs.Get(SDRATTR_3DSCENE_LIGHTCOLOR_3)).GetValue(); + ColorLB* pLb = &aLbLight3; + if( aColor != pLb->GetSelectEntryColor() ) + { + LBSelectColor( pLb, aColor ); + bUpdate = TRUE; + } + } + else + { + if( aLbLight3.GetSelectEntryCount() != 0 ) + { + aLbLight3.SetNoSelection(); + bUpdate = TRUE; + } + } + // Licht 3 (an/aus) + eState = rAttrs.GetItemState(SDRATTR_3DSCENE_LIGHTON_3); + if( eState != SFX_ITEM_DONTCARE ) + { + bool bOn = ((const Svx3DLightOnOff3Item&)rAttrs.Get(SDRATTR_3DSCENE_LIGHTON_3)).GetValue() != 0; + if( ( bOn && !GetUILightState( aBtnLight3)) || + ( !bOn && GetUILightState( aBtnLight3)) ) + { + SetUILightState( aBtnLight3, bOn ); + bUpdate = TRUE; + } + if( aBtnLight3.GetState() == STATE_DONTKNOW ) + aBtnLight3.Check( aBtnLight3.IsChecked() ); + } + else + { + if( aBtnLight3.GetState() != STATE_DONTKNOW ) + { + aBtnLight3.SetState( STATE_DONTKNOW ); + bUpdate = TRUE; + } + } + // Licht 3 (Richtung) + eState = rAttrs.GetItemState(SDRATTR_3DSCENE_LIGHTDIRECTION_3); + if( eState != SFX_ITEM_DONTCARE ) + { + bUpdate = TRUE; + } + + // Licht 4 (Farbe) + eState = rAttrs.GetItemState(SDRATTR_3DSCENE_LIGHTCOLOR_4); + if( eState != SFX_ITEM_DONTCARE ) + { + aColor = ((const Svx3DLightcolor4Item&)rAttrs.Get(SDRATTR_3DSCENE_LIGHTCOLOR_4)).GetValue(); + ColorLB* pLb = &aLbLight4; + if( aColor != pLb->GetSelectEntryColor() ) + { + LBSelectColor( pLb, aColor ); + bUpdate = TRUE; + } + } + else + { + if( aLbLight4.GetSelectEntryCount() != 0 ) + { + aLbLight4.SetNoSelection(); + bUpdate = TRUE; + } + } + // Licht 4 (an/aus) + eState = rAttrs.GetItemState(SDRATTR_3DSCENE_LIGHTON_4); + if( eState != SFX_ITEM_DONTCARE ) + { + bool bOn = ((const Svx3DLightOnOff4Item&)rAttrs.Get(SDRATTR_3DSCENE_LIGHTON_4)).GetValue() != 0; + if( ( bOn && !GetUILightState( aBtnLight4 )) || + ( !bOn && GetUILightState( aBtnLight4 )) ) + { + SetUILightState( aBtnLight4, bOn ); + bUpdate = TRUE; + } + if( aBtnLight4.GetState() == STATE_DONTKNOW ) + aBtnLight4.Check( aBtnLight4.IsChecked() ); + } + else + { + if( aBtnLight4.GetState() != STATE_DONTKNOW ) + { + aBtnLight4.SetState( STATE_DONTKNOW ); + bUpdate = TRUE; + } + } + // Licht 4 (Richtung) + eState = rAttrs.GetItemState(SDRATTR_3DSCENE_LIGHTDIRECTION_4); + if( eState != SFX_ITEM_DONTCARE ) + { + bUpdate = TRUE; + } + + // Licht 5 (Farbe) + eState = rAttrs.GetItemState(SDRATTR_3DSCENE_LIGHTCOLOR_5); + if( eState != SFX_ITEM_DONTCARE ) + { + aColor = ((const Svx3DLightcolor5Item&)rAttrs.Get(SDRATTR_3DSCENE_LIGHTCOLOR_5)).GetValue(); + ColorLB* pLb = &aLbLight5; + if( aColor != pLb->GetSelectEntryColor() ) + { + LBSelectColor( pLb, aColor ); + bUpdate = TRUE; + } + } + else + { + if( aLbLight5.GetSelectEntryCount() != 0 ) + { + aLbLight5.SetNoSelection(); + bUpdate = TRUE; + } + } + // Licht 5 (an/aus) + eState = rAttrs.GetItemState(SDRATTR_3DSCENE_LIGHTON_5); + if( eState != SFX_ITEM_DONTCARE ) + { + bool bOn = ((const Svx3DLightOnOff5Item&)rAttrs.Get(SDRATTR_3DSCENE_LIGHTON_5)).GetValue() != 0; + if( ( bOn && !GetUILightState( aBtnLight5 )) || + ( !bOn && GetUILightState( aBtnLight5 )) ) + { + SetUILightState( aBtnLight5, bOn ); + bUpdate = TRUE; + } + if( aBtnLight5.GetState() == STATE_DONTKNOW ) + aBtnLight5.Check( aBtnLight5.IsChecked() ); + } + else + { + if( aBtnLight5.GetState() != STATE_DONTKNOW ) + { + aBtnLight5.SetState( STATE_DONTKNOW ); + bUpdate = TRUE; + } + } + // Licht 5 (Richtung) + eState = rAttrs.GetItemState(SDRATTR_3DSCENE_LIGHTDIRECTION_5); + if( eState != SFX_ITEM_DONTCARE ) + { + bUpdate = TRUE; + } + + // Licht 6 (Farbe) + eState = rAttrs.GetItemState(SDRATTR_3DSCENE_LIGHTCOLOR_6); + if( eState != SFX_ITEM_DONTCARE ) + { + aColor = ((const Svx3DLightcolor6Item&)rAttrs.Get(SDRATTR_3DSCENE_LIGHTCOLOR_6)).GetValue(); + ColorLB* pLb = &aLbLight6; + if( aColor != pLb->GetSelectEntryColor() ) + { + LBSelectColor( pLb, aColor ); + bUpdate = TRUE; + } + } + else + { + if( aLbLight6.GetSelectEntryCount() != 0 ) + { + aLbLight6.SetNoSelection(); + bUpdate = TRUE; + } + } + // Licht 6 (an/aus) + eState = rAttrs.GetItemState(SDRATTR_3DSCENE_LIGHTON_6); + if( eState != SFX_ITEM_DONTCARE ) + { + bool bOn = ((const Svx3DLightOnOff6Item&)rAttrs.Get(SDRATTR_3DSCENE_LIGHTON_6)).GetValue() != 0; + if( ( bOn && !GetUILightState( aBtnLight6 )) || + ( !bOn && GetUILightState( aBtnLight6 )) ) + { + SetUILightState( aBtnLight6, bOn ); + bUpdate = TRUE; + } + if( aBtnLight6.GetState() == STATE_DONTKNOW ) + aBtnLight6.Check( aBtnLight6.IsChecked() ); + } + else + { + if( aBtnLight6.GetState() != STATE_DONTKNOW ) + { + aBtnLight6.SetState( STATE_DONTKNOW ); + bUpdate = TRUE; + } + } + // Licht 6 (Richtung) + eState = rAttrs.GetItemState(SDRATTR_3DSCENE_LIGHTDIRECTION_6); + if( eState != SFX_ITEM_DONTCARE ) + { + bUpdate = TRUE; + } + + // Licht 7 (Farbe) + eState = rAttrs.GetItemState(SDRATTR_3DSCENE_LIGHTCOLOR_7); + if( eState != SFX_ITEM_DONTCARE ) + { + aColor = ((const Svx3DLightcolor7Item&)rAttrs.Get(SDRATTR_3DSCENE_LIGHTCOLOR_7)).GetValue(); + ColorLB* pLb = &aLbLight7; + if( aColor != pLb->GetSelectEntryColor() ) + { + LBSelectColor( pLb, aColor ); + bUpdate = TRUE; + } + } + else + { + if( aLbLight7.GetSelectEntryCount() != 0 ) + { + aLbLight7.SetNoSelection(); + bUpdate = TRUE; + } + } + // Licht 7 (an/aus) + eState = rAttrs.GetItemState(SDRATTR_3DSCENE_LIGHTON_7); + if( eState != SFX_ITEM_DONTCARE ) + { + bool bOn = ((const Svx3DLightOnOff7Item&)rAttrs.Get(SDRATTR_3DSCENE_LIGHTON_7)).GetValue() != 0; + if( ( bOn && !GetUILightState( aBtnLight7 )) || + ( !bOn && GetUILightState( aBtnLight7 )) ) + { + SetUILightState( aBtnLight7 , bOn ); + bUpdate = TRUE; + } + if( aBtnLight7.GetState() == STATE_DONTKNOW ) + aBtnLight7.Check( aBtnLight7.IsChecked() ); + } + else + { + if( aBtnLight7.GetState() != STATE_DONTKNOW ) + { + aBtnLight7.SetState( STATE_DONTKNOW ); + bUpdate = TRUE; + } + } + // Licht 7 (Richtung) + eState = rAttrs.GetItemState(SDRATTR_3DSCENE_LIGHTDIRECTION_7); + if( eState != SFX_ITEM_DONTCARE ) + { + bUpdate = TRUE; + } + + // Licht 8 (Farbe) + eState = rAttrs.GetItemState(SDRATTR_3DSCENE_LIGHTCOLOR_8); + if( eState != SFX_ITEM_DONTCARE ) + { + aColor = ((const Svx3DLightcolor8Item&)rAttrs.Get(SDRATTR_3DSCENE_LIGHTCOLOR_8)).GetValue(); + ColorLB* pLb = &aLbLight8; + if( aColor != pLb->GetSelectEntryColor() ) + { + LBSelectColor( pLb, aColor ); + bUpdate = TRUE; + } + } + else + { + if( aLbLight8.GetSelectEntryCount() != 0 ) + { + aLbLight8.SetNoSelection(); + bUpdate = TRUE; + } + } + // Licht 8 (an/aus) + eState = rAttrs.GetItemState(SDRATTR_3DSCENE_LIGHTON_8); + if( eState != SFX_ITEM_DONTCARE ) + { + bool bOn = ((const Svx3DLightOnOff8Item&)rAttrs.Get(SDRATTR_3DSCENE_LIGHTON_8)).GetValue() != 0; + if( ( bOn && !GetUILightState( aBtnLight8 )) || + ( !bOn && GetUILightState( aBtnLight8 )) ) + { + SetUILightState( aBtnLight8, bOn ); + bUpdate = TRUE; + } + if( aBtnLight8.GetState() == STATE_DONTKNOW ) + aBtnLight8.Check( aBtnLight8.IsChecked() ); + } + else + { + if( aBtnLight8.GetState() != STATE_DONTKNOW ) + { + aBtnLight8.SetState( STATE_DONTKNOW ); + bUpdate = TRUE; + } + } + // Licht 8 (Richtung) + eState = rAttrs.GetItemState(SDRATTR_3DSCENE_LIGHTDIRECTION_8); + if( eState != SFX_ITEM_DONTCARE ) + { + bUpdate = TRUE; + } + + // Umgebungslicht + eState = rAttrs.GetItemState(SDRATTR_3DSCENE_AMBIENTCOLOR); + if( eState != SFX_ITEM_DONTCARE ) + { + aColor = ((const Svx3DAmbientcolorItem&)rAttrs.Get(SDRATTR_3DSCENE_AMBIENTCOLOR)).GetValue(); + ColorLB* pLb = &aLbAmbientlight; + if( aColor != pLb->GetSelectEntryColor() ) + { + LBSelectColor( pLb, aColor ); + bUpdate = TRUE; + } + } + else + { + if( aLbAmbientlight.GetSelectEntryCount() != 0 ) + { + aLbAmbientlight.SetNoSelection(); + bUpdate = TRUE; + } + } + + +// Texturen + // Art + if( bBitmap ) + { + eState = rAttrs.GetItemState(SDRATTR_3DOBJ_TEXTURE_KIND); + if( eState != SFX_ITEM_DONTCARE ) + { + UINT16 nValue = ((const Svx3DTextureKindItem&)rAttrs.Get(SDRATTR_3DOBJ_TEXTURE_KIND)).GetValue(); + + if( ( !aBtnTexLuminance.IsChecked() && nValue == 1 ) || + ( !aBtnTexColor.IsChecked() && nValue == 3 ) ) + { + aBtnTexLuminance.Check( nValue == 1 ); + aBtnTexColor.Check( nValue == 3 ); + bUpdate = TRUE; + } + } + else + { + if( aBtnTexLuminance.IsChecked() || + aBtnTexColor.IsChecked() ) + { + aBtnTexLuminance.Check( FALSE ); + aBtnTexColor.Check( FALSE ); + bUpdate = TRUE; + } + } + + // Modus + eState = rAttrs.GetItemState(SDRATTR_3DOBJ_TEXTURE_MODE); + if( eState != SFX_ITEM_DONTCARE ) + { + UINT16 nValue = ((const Svx3DTextureModeItem&)rAttrs.Get(SDRATTR_3DOBJ_TEXTURE_MODE)).GetValue(); + + if( ( !aBtnTexReplace.IsChecked() && nValue == 1 ) || + ( !aBtnTexModulate.IsChecked() && nValue == 2 ) ) + { + aBtnTexReplace.Check( nValue == 1 ); + aBtnTexModulate.Check( nValue == 2 ); + //aBtnTexBlend.Check( nValue == 2 ); + bUpdate = TRUE; + } + } + else + { + if( aBtnTexReplace.IsChecked() || + aBtnTexModulate.IsChecked() ) + { + aBtnTexReplace.Check( FALSE ); + aBtnTexModulate.Check( FALSE ); + //aBtnTexBlend.Check( FALSE ); + bUpdate = TRUE; + } + } + + // Projektion X + eState = rAttrs.GetItemState(SDRATTR_3DOBJ_TEXTURE_PROJ_X); + if( eState != SFX_ITEM_DONTCARE ) + { + UINT16 nValue = ((const Svx3DTextureProjectionXItem&)rAttrs.Get(SDRATTR_3DOBJ_TEXTURE_PROJ_X)).GetValue(); + + if( ( !aBtnTexObjectX.IsChecked() && nValue == 0 ) || + ( !aBtnTexParallelX.IsChecked() && nValue == 1 ) || + ( !aBtnTexCircleX.IsChecked() && nValue == 2 ) ) + { + aBtnTexObjectX.Check( nValue == 0 ); + aBtnTexParallelX.Check( nValue == 1 ); + aBtnTexCircleX.Check( nValue == 2 ); + bUpdate = TRUE; + } + } + else + { + if( aBtnTexObjectX.IsChecked() || + aBtnTexParallelX.IsChecked() || + aBtnTexCircleX.IsChecked() ) + { + aBtnTexObjectX.Check( FALSE ); + aBtnTexParallelX.Check( FALSE ); + aBtnTexCircleX.Check( FALSE ); + bUpdate = TRUE; + } + } + + // Projektion Y + eState = rAttrs.GetItemState(SDRATTR_3DOBJ_TEXTURE_PROJ_Y); + if( eState != SFX_ITEM_DONTCARE ) + { + UINT16 nValue = ((const Svx3DTextureProjectionYItem&)rAttrs.Get(SDRATTR_3DOBJ_TEXTURE_PROJ_Y)).GetValue(); + + if( ( !aBtnTexObjectY.IsChecked() && nValue == 0 ) || + ( !aBtnTexParallelY.IsChecked() && nValue == 1 ) || + ( !aBtnTexCircleY.IsChecked() && nValue == 2 ) ) + { + aBtnTexObjectY.Check( nValue == 0 ); + aBtnTexParallelY.Check( nValue == 1 ); + aBtnTexCircleY.Check( nValue == 2 ); + bUpdate = TRUE; + } + } + else + { + if( aBtnTexObjectY.IsChecked() || + aBtnTexParallelY.IsChecked() || + aBtnTexCircleY.IsChecked() ) + { + aBtnTexObjectY.Check( FALSE ); + aBtnTexParallelY.Check( FALSE ); + aBtnTexCircleY.Check( FALSE ); + bUpdate = TRUE; + } + } + + // Filter + eState = rAttrs.GetItemState(SDRATTR_3DOBJ_TEXTURE_FILTER); + if( eState != SFX_ITEM_DONTCARE ) + { + BOOL bValue = ((const Svx3DTextureFilterItem&)rAttrs.Get(SDRATTR_3DOBJ_TEXTURE_FILTER)).GetValue(); + if( bValue != aBtnTexFilter.IsChecked() ) + { + aBtnTexFilter.Check( bValue ); + bUpdate = TRUE; + } + if( aBtnTexFilter.GetState() == STATE_DONTKNOW ) + aBtnTexFilter.Check( bValue ); + } + else + { + if( aBtnTexFilter.GetState() != STATE_DONTKNOW ) + { + aBtnTexFilter.SetState( STATE_DONTKNOW ); + bUpdate = TRUE; + } + } + } + + + // Material Favoriten + aLbMatFavorites.SelectEntryPos( 0 ); + + // Objektfarbe + eState = rAttrs.GetItemState(XATTR_FILLCOLOR); + if( eState != SFX_ITEM_DONTCARE ) + { + aColor = ((const XFillColorItem&)rAttrs.Get(XATTR_FILLCOLOR)).GetColorValue(); + ColorLB* pLb = &aLbMatColor; + if( aColor != pLb->GetSelectEntryColor() ) + { + LBSelectColor( pLb, aColor ); + bUpdate = TRUE; + } + } + else + { + if( aLbMatColor.GetSelectEntryCount() != 0 ) + { + aLbMatColor.SetNoSelection(); + bUpdate = TRUE; + } + } + + // Slebstleuchtfarbe + eState = rAttrs.GetItemState(SDRATTR_3DOBJ_MAT_EMISSION); + if( eState != SFX_ITEM_DONTCARE ) + { + aColor = ((const Svx3DMaterialEmissionItem&)rAttrs.Get(SDRATTR_3DOBJ_MAT_EMISSION)).GetValue(); + ColorLB* pLb = &aLbMatEmission; + if( aColor != pLb->GetSelectEntryColor() ) + { + LBSelectColor( pLb, aColor ); + bUpdate = TRUE; + } + } + else + { + if( aLbMatEmission.GetSelectEntryCount() != 0 ) + { + aLbMatEmission.SetNoSelection(); + bUpdate = TRUE; + } + } + + // Glanzpunkt + eState = rAttrs.GetItemState(SDRATTR_3DOBJ_MAT_SPECULAR); + if( eState != SFX_ITEM_DONTCARE ) + { + aColor = ((const Svx3DMaterialSpecularItem&)rAttrs.Get(SDRATTR_3DOBJ_MAT_SPECULAR)).GetValue(); + ColorLB* pLb = &aLbMatSpecular; + if( aColor != pLb->GetSelectEntryColor() ) + { + LBSelectColor( pLb, aColor ); + bUpdate = TRUE; + } + } + else + { + if( aLbMatSpecular.GetSelectEntryCount() != 0 ) + { + aLbMatSpecular.SetNoSelection(); + bUpdate = TRUE; + } + } + + // Glanzpunkt Intensitaet + eState = rAttrs.GetItemState(SDRATTR_3DOBJ_MAT_SPECULAR_INTENSITY); + if( eState != SFX_ITEM_DONTCARE ) + { + UINT16 nValue = ((const Svx3DMaterialSpecularIntensityItem&)rAttrs.Get(SDRATTR_3DOBJ_MAT_SPECULAR_INTENSITY)).GetValue(); + if( nValue != aMtrMatSpecularIntensity.GetValue() ) + { + aMtrMatSpecularIntensity.SetValue( nValue ); + bUpdate = TRUE; + } + } + else + { + if( !aMtrMatSpecularIntensity.IsEmptyFieldValue() ) + { + aMtrMatSpecularIntensity.SetEmptyFieldValue(); + bUpdate = TRUE; + } + } + + +// Sonstige + // Perspektive + eState = rAttrs.GetItemState(SDRATTR_3DSCENE_PERSPECTIVE); + if( eState != SFX_ITEM_DONTCARE ) + { + ProjectionType ePT = (ProjectionType)((const Svx3DPerspectiveItem&)rAttrs.Get(SDRATTR_3DSCENE_PERSPECTIVE)).GetValue(); + if( ( !aBtnPerspective.IsChecked() && ePT == PR_PERSPECTIVE ) || + ( aBtnPerspective.IsChecked() && ePT == PR_PARALLEL ) ) + { + aBtnPerspective.Check( ePT == PR_PERSPECTIVE ); + bUpdate = TRUE; + } + if( aBtnPerspective.GetState() == STATE_DONTKNOW ) + aBtnPerspective.Check( ePT == PR_PERSPECTIVE ); + } + else + { + if( aBtnPerspective.GetState() != STATE_DONTKNOW ) + { + aBtnPerspective.SetState( STATE_DONTKNOW ); + bUpdate = TRUE; + } + } + + if( !bUpdate && !bOnly3DChanged ) + { + // Eventuell sind aber die 2D-Attribute unterschiedlich. Vergleiche + // diese und entscheide + + + bUpdate = TRUE; + } + + if( bUpdate || bOnly3DChanged ) + { + // Preview updaten + SfxItemSet aSet(rAttrs); + + // set LineStyle hard to XLINE_NONE when it's not set so that + // the default (XLINE_SOLID) is not used for 3d preview + if(SFX_ITEM_SET != aSet.GetItemState(XATTR_LINESTYLE, FALSE)) + aSet.Put(XLineStyleItem(XLINE_NONE)); + + // set FillColor hard to WHITE when it's SFX_ITEM_DONTCARE so that + // the default (Blue7) is not used for 3d preview + if(SFX_ITEM_DONTCARE == aSet.GetItemState(XATTR_FILLCOLOR, FALSE)) + aSet.Put(XFillColorItem(String(), Color(COL_WHITE))); + + aCtlPreview.Set3DAttributes(aSet); + aCtlLightPreview.GetSvx3DLightControl().Set3DAttributes(aSet); + + // try to select light corresponding to active button + sal_uInt32 nNumber(0xffffffff); + + if(aBtnLight1.IsChecked()) + nNumber = 0; + else if(aBtnLight2.IsChecked()) + nNumber = 1; + else if(aBtnLight3.IsChecked()) + nNumber = 2; + else if(aBtnLight4.IsChecked()) + nNumber = 3; + else if(aBtnLight5.IsChecked()) + nNumber = 4; + else if(aBtnLight6.IsChecked()) + nNumber = 5; + else if(aBtnLight7.IsChecked()) + nNumber = 6; + else if(aBtnLight8.IsChecked()) + nNumber = 7; + + if(nNumber != 0xffffffff) + { + aCtlLightPreview.GetSvx3DLightControl().SelectLight(nNumber); + } + } + + // handle state of converts possible + aBtnConvertTo3D.Enable(pConvertTo3DItem->GetState()); + aBtnLatheObject.Enable(pConvertTo3DLatheItem->GetState()); +} + +// ----------------------------------------------------------------------- +void Svx3DWin::GetAttr( SfxItemSet& rAttrs ) +{ + // get remembered 2d attributes from the dialog + if(mpRemember2DAttributes) + { + SfxWhichIter aIter(*mpRemember2DAttributes); + sal_uInt16 nWhich(aIter.FirstWhich()); + + while(nWhich) + { + SfxItemState eState = mpRemember2DAttributes->GetItemState(nWhich, FALSE); + if(SFX_ITEM_DONTCARE == eState) + rAttrs.InvalidateItem(nWhich); + else if(SFX_ITEM_SET == eState) + rAttrs.Put(mpRemember2DAttributes->Get(nWhich, FALSE)); + + nWhich = aIter.NextWhich(); + } + } + +// Sonstige, muss vorne stehen da auf allen Seiten + // Perspektive + if( aBtnPerspective.GetState() != STATE_DONTKNOW ) + { + UINT16 nValue; + if( aBtnPerspective.IsChecked() ) + nValue = PR_PERSPECTIVE; + else + nValue = PR_PARALLEL; + rAttrs.Put(Svx3DPerspectiveItem(nValue)); + } + else + rAttrs.InvalidateItem(SDRATTR_3DSCENE_PERSPECTIVE); + +// Geometrie + // evtl. PoolUnit ermitteln (Falls dies in Update() nicht passiert ist) + if( !mpImpl->pPool ) + { + DBG_ERROR( "Kein Pool in GetAttr()! Evtl. inkompatibel zu drviewsi.cxx ?" ); + mpImpl->pPool = rAttrs.GetPool(); + DBG_ASSERT( mpImpl->pPool, "Wo ist der Pool?" ); + ePoolUnit = mpImpl->pPool->GetMetric( SID_ATTR_LINE_WIDTH ); + + eFUnit = GetModuleFieldUnit( rAttrs ); + } + + // Anzahl Segmente (horizontal) + if( !aNumHorizontal.IsEmptyFieldValue() ) + { + sal_uInt32 nValue = static_cast<sal_uInt32>(aNumHorizontal.GetValue()); + rAttrs.Put(Svx3DHorizontalSegmentsItem(nValue)); + } + else + rAttrs.InvalidateItem(SDRATTR_3DOBJ_HORZ_SEGS); + + // Anzahl Segmente (vertikal) + if( !aNumVertical.IsEmptyFieldValue() ) + { + UINT32 nValue = static_cast<UINT32>(aNumVertical.GetValue()); + rAttrs.Put(Svx3DVerticalSegmentsItem(nValue)); + } + else + rAttrs.InvalidateItem(SDRATTR_3DOBJ_VERT_SEGS); + + // Tiefe + if( !aMtrDepth.IsEmptyFieldValue() ) + { + UINT32 nValue = GetCoreValue( aMtrDepth, ePoolUnit ); + rAttrs.Put(Svx3DDepthItem(nValue)); + } + else + rAttrs.InvalidateItem(SDRATTR_3DOBJ_DEPTH); + + // Doppelseitig + TriState eState = aBtnDoubleSided.GetState(); + if( eState != STATE_DONTKNOW ) + { + BOOL bValue = STATE_CHECK == eState; + rAttrs.Put(Svx3DDoubleSidedItem(bValue)); + } + else + rAttrs.InvalidateItem(SDRATTR_3DOBJ_DOUBLE_SIDED); + + // Kantenrundung + if( !aMtrPercentDiagonal.IsEmptyFieldValue() ) + { + UINT16 nValue = (UINT16) aMtrPercentDiagonal.GetValue(); + rAttrs.Put(Svx3DPercentDiagonalItem(nValue)); + } + else + rAttrs.InvalidateItem(SDRATTR_3DOBJ_PERCENT_DIAGONAL); + + // Tiefenskalierung + if( !aMtrBackscale.IsEmptyFieldValue() ) + { + UINT16 nValue = (UINT16)aMtrBackscale.GetValue(); + rAttrs.Put(Svx3DBackscaleItem(nValue)); + } + else + rAttrs.InvalidateItem(SDRATTR_3DOBJ_BACKSCALE); + + // Endwinkel + if( !aMtrEndAngle.IsEmptyFieldValue() ) + { + UINT16 nValue = (UINT16)aMtrEndAngle.GetValue(); + rAttrs.Put(Svx3DEndAngleItem(nValue)); + } + else + rAttrs.InvalidateItem(SDRATTR_3DOBJ_END_ANGLE); + + // Normalentyp + UINT16 nValue = 99; + if( aBtnNormalsObj.IsChecked() ) + nValue = 0; + else if( aBtnNormalsFlat.IsChecked() ) + nValue = 1; + else if( aBtnNormalsSphere.IsChecked() ) + nValue = 2; + + if( nValue <= 2 ) + rAttrs.Put(Svx3DNormalsKindItem(nValue)); + else + rAttrs.InvalidateItem(SDRATTR_3DOBJ_NORMALS_KIND); + + // Normalen invertieren + eState = aBtnNormalsInvert.GetState(); + if( eState != STATE_DONTKNOW ) + { + BOOL bValue = STATE_CHECK == eState; + rAttrs.Put(Svx3DNormalsInvertItem(bValue)); + } + else + rAttrs.InvalidateItem(SDRATTR_3DOBJ_NORMALS_INVERT); + + // 2-seitige Beleuchtung + eState = aBtnTwoSidedLighting.GetState(); + if( eState != STATE_DONTKNOW ) + { + BOOL bValue = STATE_CHECK == eState; + rAttrs.Put(Svx3DTwoSidedLightingItem(bValue)); + } + else + rAttrs.InvalidateItem(SDRATTR_3DSCENE_TWO_SIDED_LIGHTING); + +// Darstellung + // Shademode + if( aLbShademode.GetSelectEntryCount() ) + { + nValue = aLbShademode.GetSelectEntryPos(); + rAttrs.Put(Svx3DShadeModeItem(nValue)); + } + else + rAttrs.InvalidateItem(SDRATTR_3DSCENE_SHADE_MODE); + + // 3D-Shatten + eState = aBtnShadow3d.GetState(); + if( eState != STATE_DONTKNOW ) + { + BOOL bValue = STATE_CHECK == eState; + rAttrs.Put(Svx3DShadow3DItem(bValue)); + rAttrs.Put(SdrShadowItem(bValue)); + } + else + { + rAttrs.InvalidateItem(SDRATTR_3DOBJ_SHADOW_3D); + rAttrs.InvalidateItem(SDRATTR_SHADOW); + } + + // Neigung (Schatten) + if( !aMtrSlant.IsEmptyFieldValue() ) + { + UINT16 nValue2 = (UINT16) aMtrSlant.GetValue(); + rAttrs.Put(Svx3DShadowSlantItem(nValue2)); + } + else + rAttrs.InvalidateItem(SDRATTR_3DSCENE_SHADOW_SLANT); + + // Distanz + if( !aMtrDistance.IsEmptyFieldValue() ) + { + UINT32 nValue2 = GetCoreValue( aMtrDistance, ePoolUnit ); + rAttrs.Put(Svx3DDistanceItem(nValue2)); + } + else + rAttrs.InvalidateItem(SDRATTR_3DSCENE_DISTANCE); + + // Brennweite + if( !aMtrFocalLength.IsEmptyFieldValue() ) + { + UINT32 nValue2 = GetCoreValue( aMtrFocalLength, ePoolUnit ); + rAttrs.Put(Svx3DFocalLengthItem(nValue2)); + } + else + rAttrs.InvalidateItem(SDRATTR_3DSCENE_FOCAL_LENGTH); + +// Beleuchtung + Image aImg; + basegfx::B3DVector aVector; + Color aColor; + const SfxItemSet aLightItemSet(aCtlLightPreview.GetSvx3DLightControl().Get3DAttributes()); + + // Licht 1 Farbe + if( aLbLight1.GetSelectEntryCount() ) + { + aColor = aLbLight1.GetSelectEntryColor(); + rAttrs.Put(Svx3DLightcolor1Item(aColor)); + } + else + rAttrs.InvalidateItem(SDRATTR_3DSCENE_LIGHTCOLOR_1); + // Licht 1 (an/aus) + eState = aBtnLight1.GetState(); + if( eState != STATE_DONTKNOW ) + { + BOOL bValue = GetUILightState( aBtnLight1 ); + rAttrs.Put(Svx3DLightOnOff1Item(bValue)); + + // Licht 1 (Richtung) + if( bValue ) + { + rAttrs.Put(aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_1)); + } + } + else + rAttrs.InvalidateItem(SDRATTR_3DSCENE_LIGHTON_1); + + + // Licht 2 Farbe + if( aLbLight2.GetSelectEntryCount() ) + { + aColor = aLbLight2.GetSelectEntryColor(); + rAttrs.Put(Svx3DLightcolor2Item(aColor)); + } + else + rAttrs.InvalidateItem(SDRATTR_3DSCENE_LIGHTCOLOR_2); + // Licht 2 (an/aus) + eState = aBtnLight2.GetState(); + if( eState != STATE_DONTKNOW ) + { + BOOL bValue = GetUILightState( aBtnLight2 ); + rAttrs.Put(Svx3DLightOnOff2Item(bValue)); + + // Licht 2 (Richtung) + if( bValue ) + { + rAttrs.Put(aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_2)); + } + } + else + rAttrs.InvalidateItem(SDRATTR_3DSCENE_LIGHTON_2); + + // Licht 3 Farbe + if( aLbLight3.GetSelectEntryCount() ) + { + aColor = aLbLight3.GetSelectEntryColor(); + rAttrs.Put(Svx3DLightcolor3Item(aColor)); + } + else + rAttrs.InvalidateItem(SDRATTR_3DSCENE_LIGHTCOLOR_3); + // Licht 3 (an/aus) + eState = aBtnLight3.GetState(); + if( eState != STATE_DONTKNOW ) + { + BOOL bValue = GetUILightState( aBtnLight3 ); + rAttrs.Put(Svx3DLightOnOff3Item(bValue)); + + // Licht 3 (Richtung) + if( bValue ) + { + rAttrs.Put(aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_3)); + } + } + else + rAttrs.InvalidateItem(SDRATTR_3DSCENE_LIGHTON_3); + + // Licht 4 Farbe + if( aLbLight4.GetSelectEntryCount() ) + { + aColor = aLbLight4.GetSelectEntryColor(); + rAttrs.Put(Svx3DLightcolor4Item(aColor)); + } + else + rAttrs.InvalidateItem(SDRATTR_3DSCENE_LIGHTCOLOR_4); + // Licht 4 (an/aus) + eState = aBtnLight4.GetState(); + if( eState != STATE_DONTKNOW ) + { + BOOL bValue = GetUILightState( aBtnLight4 ); + rAttrs.Put(Svx3DLightOnOff4Item(bValue)); + + // Licht 4 (Richtung) + if( bValue ) + { + rAttrs.Put(aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_4)); + } + } + else + rAttrs.InvalidateItem(SDRATTR_3DSCENE_LIGHTON_4); + + // Licht 5 Farbe + if( aLbLight5.GetSelectEntryCount() ) + { + aColor = aLbLight5.GetSelectEntryColor(); + rAttrs.Put(Svx3DLightcolor5Item(aColor)); + } + else + rAttrs.InvalidateItem(SDRATTR_3DSCENE_LIGHTCOLOR_5); + // Licht 5 (an/aus) + eState = aBtnLight5.GetState(); + if( eState != STATE_DONTKNOW ) + { + BOOL bValue = GetUILightState( aBtnLight5 ); + rAttrs.Put(Svx3DLightOnOff5Item(bValue)); + + // Licht 5 (Richtung) + if( bValue ) + { + rAttrs.Put(aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_5)); + } + } + else + rAttrs.InvalidateItem(SDRATTR_3DSCENE_LIGHTON_5); + + // Licht 6 Farbe + if( aLbLight6.GetSelectEntryCount() ) + { + aColor = aLbLight6.GetSelectEntryColor(); + rAttrs.Put(Svx3DLightcolor6Item(aColor)); + } + else + rAttrs.InvalidateItem(SDRATTR_3DSCENE_LIGHTCOLOR_6); + // Licht 6 (an/aus) + eState = aBtnLight6.GetState(); + if( eState != STATE_DONTKNOW ) + { + BOOL bValue = GetUILightState( aBtnLight6 ); + rAttrs.Put(Svx3DLightOnOff6Item(bValue)); + + // Licht 6 (Richtung) + if( bValue ) + { + rAttrs.Put(aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_6)); + } + } + else + rAttrs.InvalidateItem(SDRATTR_3DSCENE_LIGHTON_6); + + // Licht 7 Farbe + if( aLbLight7.GetSelectEntryCount() ) + { + aColor = aLbLight7.GetSelectEntryColor(); + rAttrs.Put(Svx3DLightcolor7Item(aColor)); + } + else + rAttrs.InvalidateItem(SDRATTR_3DSCENE_LIGHTCOLOR_7); + // Licht 7 (an/aus) + eState = aBtnLight7.GetState(); + if( eState != STATE_DONTKNOW ) + { + BOOL bValue = GetUILightState( aBtnLight7 ); + rAttrs.Put(Svx3DLightOnOff7Item(bValue)); + + // Licht 7 (Richtung) + if( bValue ) + { + rAttrs.Put(aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_7)); + } + } + else + rAttrs.InvalidateItem(SDRATTR_3DSCENE_LIGHTON_7); + + // Licht 8 Farbe + if( aLbLight8.GetSelectEntryCount() ) + { + aColor = aLbLight8.GetSelectEntryColor(); + rAttrs.Put(Svx3DLightcolor8Item(aColor)); + } + else + rAttrs.InvalidateItem(SDRATTR_3DSCENE_LIGHTCOLOR_8); + // Licht 8 (an/aus) + eState = aBtnLight8.GetState(); + if( eState != STATE_DONTKNOW ) + { + BOOL bValue = GetUILightState( aBtnLight8 ); + rAttrs.Put(Svx3DLightOnOff8Item(bValue)); + + // Licht 8 (Richtung) + if( bValue ) + { + rAttrs.Put(aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_8)); + } + } + else + rAttrs.InvalidateItem(SDRATTR_3DSCENE_LIGHTON_8); + + // Umgebungslicht + if( aLbAmbientlight.GetSelectEntryCount() ) + { + aColor = aLbAmbientlight.GetSelectEntryColor(); + rAttrs.Put(Svx3DAmbientcolorItem(aColor)); + } + else + rAttrs.InvalidateItem(SDRATTR_3DSCENE_AMBIENTCOLOR); + +// Texturen + // Art + nValue = 3; + if( aBtnTexLuminance.IsChecked() ) + nValue = 1; + else if( aBtnTexColor.IsChecked() ) + nValue = 3; + + if( nValue == 1 || nValue == 3 ) + rAttrs.Put(Svx3DTextureKindItem(nValue)); + else + rAttrs.InvalidateItem(SDRATTR_3DOBJ_TEXTURE_KIND); + + + // Modus + nValue = 99; + if( aBtnTexReplace.IsChecked() ) + nValue = 1; + else if( aBtnTexModulate.IsChecked() ) + nValue = 2; + //else if( aBtnTexBlend.IsChecked() ) + // nValue = 2; + + if( nValue == 1 || nValue == 2 ) + rAttrs.Put(Svx3DTextureModeItem(nValue)); + else + rAttrs.InvalidateItem(SDRATTR_3DOBJ_TEXTURE_MODE); + + // Projektion X + nValue = 99; + if( aBtnTexObjectX.IsChecked() ) + nValue = 0; + else if( aBtnTexParallelX.IsChecked() ) + nValue = 1; + else if( aBtnTexCircleX.IsChecked() ) + nValue = 2; + + if( nValue <= 2 ) + rAttrs.Put(Svx3DTextureProjectionXItem(nValue)); + else + rAttrs.InvalidateItem(SDRATTR_3DOBJ_TEXTURE_PROJ_X); + + // Projektion Y + nValue = 99; + if( aBtnTexObjectY.IsChecked() ) + nValue = 0; + else if( aBtnTexParallelY.IsChecked() ) + nValue = 1; + else if( aBtnTexCircleY.IsChecked() ) + nValue = 2; + + if( nValue <= 2 ) + rAttrs.Put(Svx3DTextureProjectionYItem(nValue)); + else + rAttrs.InvalidateItem(SDRATTR_3DOBJ_TEXTURE_PROJ_Y); + + + // Filter + eState = aBtnTexFilter.GetState(); + if( eState != STATE_DONTKNOW ) + { + BOOL bValue = STATE_CHECK == eState; + rAttrs.Put(Svx3DTextureFilterItem(bValue)); + } + else + rAttrs.InvalidateItem(SDRATTR_3DOBJ_TEXTURE_FILTER); + + +// Material + // Objektfarbe + if( aLbMatColor.GetSelectEntryCount() ) + { + aColor = aLbMatColor.GetSelectEntryColor(); + rAttrs.Put( XFillColorItem( String(), aColor) ); + } + else + { + rAttrs.InvalidateItem( XATTR_FILLCOLOR ); + } + + // Slebstleuchtfarbe + if( aLbMatEmission.GetSelectEntryCount() ) + { + aColor = aLbMatEmission.GetSelectEntryColor(); + rAttrs.Put(Svx3DMaterialEmissionItem(aColor)); + } + else + rAttrs.InvalidateItem(SDRATTR_3DOBJ_MAT_EMISSION); + + // Glanzpunkt + if( aLbMatSpecular.GetSelectEntryCount() ) + { + aColor = aLbMatSpecular.GetSelectEntryColor(); + rAttrs.Put(Svx3DMaterialSpecularItem(aColor)); + } + else + rAttrs.InvalidateItem(SDRATTR_3DOBJ_MAT_SPECULAR); + + // Glanzpunkt Intensitaet + if( !aMtrMatSpecularIntensity.IsEmptyFieldValue() ) + { + UINT16 nValue2 = (UINT16) aMtrMatSpecularIntensity.GetValue(); + rAttrs.Put(Svx3DMaterialSpecularIntensityItem(nValue2)); + } + else + rAttrs.InvalidateItem(SDRATTR_3DOBJ_MAT_SPECULAR_INTENSITY); +} + +// ----------------------------------------------------------------------- +void __EXPORT Svx3DWin::Resize() +{ + if ( !IsFloatingMode() || + !GetFloatingWindow()->IsRollUp() ) + { + Size aWinSize( GetOutputSizePixel() ); // vorher rSize im Resizing() + + if( aWinSize.Height() >= GetMinOutputSizePixel().Height() && + aWinSize.Width() >= GetMinOutputSizePixel().Width() ) + { + Size aDiffSize; + aDiffSize.Width() = aWinSize.Width() - aSize.Width(); + aDiffSize.Height() = aWinSize.Height() - aSize.Height(); + + Point aXPt; + Point aYPt; + aXPt.X() = aDiffSize.Width(); + aYPt.Y() = aDiffSize.Height(); + + Size aObjSize; + + // Hide + aBtnUpdate.Hide(); + aBtnAssign.Hide(); + + aBtnConvertTo3D.Hide(); + aBtnLatheObject.Hide(); + aBtnPerspective.Hide(); + + aCtlPreview.Hide(); + aCtlLightPreview.Hide(); + + aFLGeometrie.Hide(); + aFLRepresentation.Hide(); + aFLLight.Hide(); + aFLTexture.Hide(); + aFLMaterial.Hide(); + + // Verschieben / Resizen + aBtnUpdate.SetPosPixel( aBtnUpdate.GetPosPixel() + aXPt ); + aBtnAssign.SetPosPixel( aBtnAssign.GetPosPixel() + aXPt ); + + // Preview-Controls + aObjSize = aCtlPreview.GetOutputSizePixel(); + aObjSize.Width() += aDiffSize.Width(); + aObjSize.Height() += aDiffSize.Height(); + aCtlPreview.SetOutputSizePixel( aObjSize ); + aCtlLightPreview.SetOutputSizePixel( aObjSize ); + + // Groups + aObjSize = aFLGeometrie.GetOutputSizePixel(); + aObjSize.Width() += aDiffSize.Width(); + aFLGeometrie.SetOutputSizePixel( aObjSize ); + aFLSegments.SetOutputSizePixel( aObjSize ); + aFLShadow.SetOutputSizePixel( aObjSize ); + aFLCamera.SetOutputSizePixel( aObjSize ); + aFLRepresentation.SetOutputSizePixel( aObjSize ); + aFLLight.SetOutputSizePixel( aObjSize ); + aFLTexture.SetOutputSizePixel( aObjSize ); + aFLMaterial.SetOutputSizePixel( aObjSize ); + + // Y-Position der unteren Buttons + aBtnConvertTo3D.SetPosPixel( aBtnConvertTo3D.GetPosPixel() + aYPt ); + aBtnLatheObject.SetPosPixel( aBtnLatheObject.GetPosPixel() + aYPt ); + aBtnPerspective.SetPosPixel( aBtnPerspective.GetPosPixel() + aYPt ); + + // Show + aBtnUpdate.Show(); + aBtnAssign.Show(); + + aBtnConvertTo3D.Show(); + aBtnLatheObject.Show(); + aBtnPerspective.Show(); + + if( aBtnGeo.IsChecked() ) + ClickViewTypeHdl( &aBtnGeo ); + if( aBtnRepresentation.IsChecked() ) + ClickViewTypeHdl( &aBtnRepresentation ); + if( aBtnLight.IsChecked() ) + ClickViewTypeHdl( &aBtnLight ); + if( aBtnTexture.IsChecked() ) + ClickViewTypeHdl( &aBtnTexture ); + if( aBtnMaterial.IsChecked() ) + ClickViewTypeHdl( &aBtnMaterial ); + + aSize = aWinSize; + } + } + + SfxDockingWindow::Resize(); +} + +// ----------------------------------------------------------------------- +IMPL_LINK( Svx3DWin, ClickUpdateHdl, void *, EMPTYARG ) +{ + bUpdate = !aBtnUpdate.IsChecked(); + aBtnUpdate.Check( bUpdate ); + + if( bUpdate ) + { + SfxDispatcher* pDispatcher = LocalGetDispatcher(pBindings); + if (pDispatcher != NULL) + { + SfxBoolItem aItem( SID_3D_STATE, TRUE ); + pDispatcher->Execute( + SID_3D_STATE, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD, &aItem, 0L ); + } + } + else + { + // Controls koennen u.U. disabled sein + } + + return( 0L ); +} + +// ----------------------------------------------------------------------- +IMPL_LINK( Svx3DWin, ClickAssignHdl, void *, EMPTYARG ) +{ + SfxDispatcher* pDispatcher = LocalGetDispatcher(pBindings); + if (pDispatcher != NULL) + { + SfxBoolItem aItem( SID_3D_ASSIGN, TRUE ); + pDispatcher->Execute( + SID_3D_ASSIGN, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD, &aItem, 0L ); + } + + return( 0L ); +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( Svx3DWin, ClickViewTypeHdl, void *, pBtn ) +{ + + if( pBtn ) + { + // Da das permanente Updaten der Preview zu teuer waere + BOOL bUpdatePreview = aBtnLight.IsChecked(); + + aBtnGeo.Check( &aBtnGeo == pBtn ); + aBtnRepresentation.Check( &aBtnRepresentation == pBtn ); + aBtnLight.Check( &aBtnLight == pBtn ); + aBtnTexture.Check( &aBtnTexture == pBtn ); + aBtnMaterial.Check( &aBtnMaterial == pBtn ); + + if( aBtnGeo.IsChecked() ) + eViewType = VIEWTYPE_GEO; + if( aBtnRepresentation.IsChecked() ) + eViewType = VIEWTYPE_REPRESENTATION; + if( aBtnLight.IsChecked() ) + eViewType = VIEWTYPE_LIGHT; + if( aBtnTexture.IsChecked() ) + eViewType = VIEWTYPE_TEXTURE; + if( aBtnMaterial.IsChecked() ) + eViewType = VIEWTYPE_MATERIAL; + + // Geometrie + if( eViewType == VIEWTYPE_GEO ) + { + aFtHorizontal.Show(); + aNumHorizontal.Show(); + aFtVertical.Show(); + aNumVertical.Show(); + aFLSegments.Show(); + aFtPercentDiagonal.Show(); + aMtrPercentDiagonal.Show(); + aFtBackscale.Show(); + aMtrBackscale.Show(); + aFtEndAngle.Show(); + aMtrEndAngle.Show(); + aFtDepth.Show(); + aMtrDepth.Show(); + aFLGeometrie.Show(); + + aBtnNormalsObj.Show(); + aBtnNormalsFlat.Show(); + aBtnNormalsSphere.Show(); + aBtnTwoSidedLighting.Show(); + aBtnNormalsInvert.Show(); + aFLNormals.Show(); + aBtnDoubleSided.Show(); + } + else + { + aFtHorizontal.Hide(); + aNumHorizontal.Hide(); + aFtVertical.Hide(); + aNumVertical.Hide(); + aFLSegments.Hide(); + aFtPercentDiagonal.Hide(); + aMtrPercentDiagonal.Hide(); + aFtBackscale.Hide(); + aMtrBackscale.Hide(); + aFtEndAngle.Hide(); + aMtrEndAngle.Hide(); + aFtDepth.Hide(); + aMtrDepth.Hide(); + aFLGeometrie.Hide(); + + aBtnNormalsObj.Hide(); + aBtnNormalsFlat.Hide(); + aBtnNormalsSphere.Hide(); + aBtnTwoSidedLighting.Hide(); + aBtnNormalsInvert.Hide(); + aFLNormals.Hide(); + aBtnDoubleSided.Hide(); + } + + // Darstellung + if( eViewType == VIEWTYPE_REPRESENTATION ) + { + aFtShademode.Show(); + aLbShademode.Show(); + aBtnShadow3d.Show(); + aFtSlant.Show(); + aMtrSlant.Show(); + aFLShadow.Show(); + aFtDistance.Show(); + aMtrDistance.Show(); + aFtFocalLeng.Show(); + aMtrFocalLength.Show(); + aFLCamera.Show(); + aFLRepresentation.Show(); + } + else + { + aFtShademode.Hide(); + aLbShademode.Hide(); + aBtnShadow3d.Hide(); + aFtSlant.Hide(); + aMtrSlant.Hide(); + aFLShadow.Hide(); + aFtDistance.Hide(); + aMtrDistance.Hide(); + aFtFocalLeng.Hide(); + aMtrFocalLength.Hide(); + aFLCamera.Hide(); + aFLRepresentation.Hide(); + } + + // Beleuchtung + if( eViewType == VIEWTYPE_LIGHT ) + { + aBtnLight1.Show(); + aBtnLight2.Show(); + aBtnLight3.Show(); + aBtnLight4.Show(); + aBtnLight5.Show(); + aBtnLight6.Show(); + aBtnLight7.Show(); + aBtnLight8.Show(); + //aLbLight1.Show(); + aBtnLightColor.Show(); + aFTLightsource.Show(); + aLbAmbientlight.Show(); + aBtnAmbientColor.Show(); + aFTAmbientlight.Show(); + aFLLight.Show(); + //aFtLightX.Show(); + //aFtLightY.Show(); + //aFtLightZ.Show(); + //aGrpLightInfo.Show(); + + ColorLB* pLb = GetLbByButton(); + if( pLb ) + pLb->Show(); + + aCtlLightPreview.Show(); + aCtlPreview.Hide(); + } + else + { + aBtnLight1.Hide(); + aBtnLight2.Hide(); + aBtnLight3.Hide(); + aBtnLight4.Hide(); + aBtnLight5.Hide(); + aBtnLight6.Hide(); + aBtnLight7.Hide(); + aBtnLight8.Hide(); + aLbLight1.Hide(); + aLbLight2.Hide(); + aLbLight3.Hide(); + aLbLight4.Hide(); + aLbLight5.Hide(); + aLbLight6.Hide(); + aLbLight7.Hide(); + aLbLight8.Hide(); + aBtnLightColor.Hide(); + aFTLightsource.Hide(); + aLbAmbientlight.Hide(); + aBtnAmbientColor.Hide(); + aFTAmbientlight.Hide(); + aFLLight.Hide(); + + if( !aCtlPreview.IsVisible() ) + { + aCtlPreview.Show(); + aCtlLightPreview.Hide(); + } + } + + // Texturen + if( eViewType == VIEWTYPE_TEXTURE ) + { + aFtTexKind.Show(); + aBtnTexLuminance.Show(); + aBtnTexColor.Show(); + aFtTexMode.Show(); + aBtnTexReplace.Show(); + aBtnTexModulate.Show(); + //aBtnTexBlend.Show(); + aFtTexProjectionX.Show(); + aBtnTexParallelX.Show(); + aBtnTexCircleX.Show(); + aBtnTexObjectX.Show(); + aFtTexProjectionY.Show(); + aBtnTexParallelY.Show(); + aBtnTexCircleY.Show(); + aBtnTexObjectY.Show(); + aFtTexFilter.Show(); + aBtnTexFilter.Show(); + aFLTexture.Show(); + } + else + { + aFtTexKind.Hide(); + aBtnTexLuminance.Hide(); + aBtnTexColor.Hide(); + aFtTexMode.Hide(); + aBtnTexReplace.Hide(); + aBtnTexModulate.Hide(); + aBtnTexBlend.Hide(); + aFtTexProjectionX.Hide(); + aBtnTexParallelX.Hide(); + aBtnTexCircleX.Hide(); + aBtnTexObjectX.Hide(); + aFtTexProjectionY.Hide(); + aBtnTexParallelY.Hide(); + aBtnTexCircleY.Hide(); + aBtnTexObjectY.Hide(); + aFtTexFilter.Hide(); + aBtnTexFilter.Hide(); + aFLTexture.Hide(); + } + + // Material + if( eViewType == VIEWTYPE_MATERIAL ) + { + aFtMatFavorites.Show(); + aLbMatFavorites.Show(); + aFtMatColor.Show(); + aLbMatColor.Show(); + aBtnMatColor.Show(); + aFtMatEmission.Show(); + aLbMatEmission.Show(); + aBtnEmissionColor.Show(); + aFtMatSpecular.Show(); + aLbMatSpecular.Show(); + aBtnSpecularColor.Show(); + aFtMatSpecularIntensity.Show(); + aMtrMatSpecularIntensity.Show(); + aFLMatSpecular.Show(); + aFLMaterial.Show(); + } + else + { + aFtMatFavorites.Hide(); + aLbMatFavorites.Hide(); + aFtMatColor.Hide(); + aLbMatColor.Hide(); + aBtnMatColor.Hide(); + aFtMatEmission.Hide(); + aLbMatEmission.Hide(); + aBtnEmissionColor.Hide(); + aFtMatSpecular.Hide(); + aLbMatSpecular.Hide(); + aBtnSpecularColor.Hide(); + aFtMatSpecularIntensity.Hide(); + aMtrMatSpecularIntensity.Hide(); + aFLMatSpecular.Hide(); + aFLMaterial.Hide(); + } + if( bUpdatePreview && !aBtnLight.IsChecked() ) + UpdatePreview(); + + } + else + { + aBtnGeo.Check( eViewType == VIEWTYPE_GEO ); + aBtnRepresentation.Check( eViewType == VIEWTYPE_REPRESENTATION ); + aBtnLight.Check( eViewType == VIEWTYPE_LIGHT ); + aBtnTexture.Check( eViewType == VIEWTYPE_TEXTURE ); + aBtnMaterial.Check( eViewType == VIEWTYPE_MATERIAL ); + } + return( 0L ); +} + +// ----------------------------------------------------------------------- +IMPL_LINK( Svx3DWin, ClickHdl, PushButton *, pBtn ) +{ + BOOL bUpdatePreview = FALSE; + + if( pBtn ) + { + USHORT nSId = 0; + + if( pBtn == &aBtnConvertTo3D ) + { + nSId = SID_CONVERT_TO_3D; + } + else if( pBtn == &aBtnLatheObject ) + { + nSId = SID_CONVERT_TO_3D_LATHE_FAST; + } + // Geometrie + else if( pBtn == &aBtnNormalsObj || + pBtn == &aBtnNormalsFlat || + pBtn == &aBtnNormalsSphere ) + { + aBtnNormalsObj.Check( pBtn == &aBtnNormalsObj ); + aBtnNormalsFlat.Check( pBtn == &aBtnNormalsFlat ); + aBtnNormalsSphere.Check( pBtn == &aBtnNormalsSphere ); + bUpdatePreview = TRUE; + } + else if( pBtn == &aBtnLight1 || + pBtn == &aBtnLight2 || + pBtn == &aBtnLight3 || + pBtn == &aBtnLight4 || + pBtn == &aBtnLight5 || + pBtn == &aBtnLight6 || + pBtn == &aBtnLight7 || + pBtn == &aBtnLight8 ) + { + // Beleuchtung + ColorLB* pLb = GetLbByButton( pBtn ); + pLb->Show(); + + if( pBtn->IsChecked() ) + { + SetUILightState( *(ImageButton*)pBtn, !GetUILightState( *(ImageButton*)pBtn ) ); + } + else + { + pBtn->Check(); + + if( pBtn != &aBtnLight1 && aBtnLight1.IsChecked() ) + { + aBtnLight1.Check( FALSE ); + aLbLight1.Hide(); + } + if( pBtn != &aBtnLight2 && aBtnLight2.IsChecked() ) + { + aBtnLight2.Check( FALSE ); + aLbLight2.Hide(); + } + if( pBtn != &aBtnLight3 && aBtnLight3.IsChecked() ) + { + aBtnLight3.Check( FALSE ); + aLbLight3.Hide(); + } + if( pBtn != &aBtnLight4 && aBtnLight4.IsChecked() ) + { + aBtnLight4.Check( FALSE ); + aLbLight4.Hide(); + } + if( pBtn != &aBtnLight5 && aBtnLight5.IsChecked() ) + { + aBtnLight5.Check( FALSE ); + aLbLight5.Hide(); + } + if( pBtn != &aBtnLight6 && aBtnLight6.IsChecked() ) + { + aBtnLight6.Check( FALSE ); + aLbLight6.Hide(); + } + if( pBtn != &aBtnLight7 && aBtnLight7.IsChecked() ) + { + aBtnLight7.Check( FALSE ); + aLbLight7.Hide(); + } + if( pBtn != &aBtnLight8 && aBtnLight8.IsChecked() ) + { + aBtnLight8.Check( FALSE ); + aLbLight8.Hide(); + } + } + BOOL bEnable = GetUILightState( *(ImageButton*)pBtn ); + aBtnLightColor.Enable( bEnable ); + pLb->Enable( bEnable ); + + ClickLightHdl( pBtn ); + bUpdatePreview = TRUE; + } + // Texturen + else if( pBtn == &aBtnTexLuminance || + pBtn == &aBtnTexColor ) + { + aBtnTexLuminance.Check( pBtn == &aBtnTexLuminance ); + aBtnTexColor.Check( pBtn == &aBtnTexColor ); + bUpdatePreview = TRUE; + } + else if( pBtn == &aBtnTexReplace || + pBtn == &aBtnTexModulate )// || + //pBtn == &aBtnTexBlend ) + { + aBtnTexReplace.Check( pBtn == &aBtnTexReplace ); + aBtnTexModulate.Check( pBtn == &aBtnTexModulate ); + //aBtnTexBlend.Check( pBtn == &aBtnTexBlend ); + bUpdatePreview = TRUE; + } + else if( pBtn == &aBtnTexParallelX || + pBtn == &aBtnTexCircleX || + pBtn == &aBtnTexObjectX ) + { + aBtnTexParallelX.Check( pBtn == &aBtnTexParallelX ); + aBtnTexCircleX.Check( pBtn == &aBtnTexCircleX ); + aBtnTexObjectX.Check( pBtn == &aBtnTexObjectX ); + bUpdatePreview = TRUE; + } + else if( pBtn == &aBtnTexParallelY || + pBtn == &aBtnTexCircleY || + pBtn == &aBtnTexObjectY ) + { + aBtnTexParallelY.Check( pBtn == &aBtnTexParallelY ); + aBtnTexCircleY.Check( pBtn == &aBtnTexCircleY ); + aBtnTexObjectY.Check( pBtn == &aBtnTexObjectY ); + bUpdatePreview = TRUE; + } + else if( pBtn == &aBtnShadow3d ) + { + pBtn->Check( !pBtn->IsChecked() ); + aFtSlant.Enable( pBtn->IsChecked() ); + aMtrSlant.Enable( pBtn->IsChecked() ); + bUpdatePreview = TRUE; + } + // Sonstige (keine Gruppen) + else if( pBtn != NULL ) + { + pBtn->Check( !pBtn->IsChecked() ); + bUpdatePreview = TRUE; + } + + if( nSId > 0 ) + { + SfxDispatcher* pDispatcher = LocalGetDispatcher(pBindings); + if (pDispatcher != NULL) + { + SfxBoolItem aItem( nSId, TRUE ); + pDispatcher->Execute( + nSId, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD, &aItem, 0L ); + } + } + else if( bUpdatePreview == TRUE ) + UpdatePreview(); + } + return( 0L ); +} + +//------------------------------------------------------------------------ + +IMPL_LINK( Svx3DWin, ClickColorHdl, PushButton *, pBtn ) +{ + SvColorDialog aColorDlg( this ); + ColorLB* pLb; + + if( pBtn == &aBtnLightColor ) + pLb = GetLbByButton(); + else if( pBtn == &aBtnAmbientColor ) + pLb = &aLbAmbientlight; + else if( pBtn == &aBtnMatColor ) + pLb = &aLbMatColor; + else if( pBtn == &aBtnEmissionColor ) + pLb = &aLbMatEmission; + else // if( pBtn == &aBtnSpecularColor ) + pLb = &aLbMatSpecular; + + Color aColor = pLb->GetSelectEntryColor(); + + aColorDlg.SetColor( aColor ); + if( aColorDlg.Execute() == RET_OK ) + { + aColor = aColorDlg.GetColor(); + if( LBSelectColor( pLb, aColor ) ) + SelectHdl( pLb ); + } + return( 0L ); +} + +// ----------------------------------------------------------------------- +IMPL_LINK( Svx3DWin, SelectHdl, void *, p ) +{ + if( p ) + { + Color aColor; + BOOL bUpdatePreview = FALSE; + + // Material + if( p == &aLbMatFavorites ) + { + Color aColObj( COL_WHITE ); + Color aColEmis( COL_BLACK ); + Color aColSpec( COL_WHITE ); + USHORT nSpecIntens = 20; + + USHORT nPos = aLbMatFavorites.GetSelectEntryPos(); + switch( nPos ) + { + case 1: // Metall + { + aColObj = Color(230,230,255); + aColEmis = Color(10,10,30); + aColSpec = Color(200,200,200); + nSpecIntens = 20; + } + break; + + case 2: // Gold + { + aColObj = Color(230,255,0); + aColEmis = Color(51,0,0); + aColSpec = Color(255,255,240); + nSpecIntens = 20; + } + break; + + case 3: // Chrom + { + aColObj = Color(36,117,153); + aColEmis = Color(18,30,51); + aColSpec = Color(230,230,255); + nSpecIntens = 2; + } + break; + + case 4: // Plastik + { + aColObj = Color(255,48,57); + aColEmis = Color(35,0,0); + aColSpec = Color(179,202,204); + nSpecIntens = 60; + } + break; + + case 5: // Holz + { + aColObj = Color(153,71,1); + aColEmis = Color(21,22,0); + aColSpec = Color(255,255,153); + nSpecIntens = 75; + } + break; + } + LBSelectColor( &aLbMatColor, aColObj ); + LBSelectColor( &aLbMatEmission, aColEmis ); + LBSelectColor( &aLbMatSpecular, aColSpec ); + aMtrMatSpecularIntensity.SetValue( nSpecIntens ); + + bUpdatePreview = TRUE; + } + else if( p == &aLbMatColor || + p == &aLbMatEmission || + p == &aLbMatSpecular ) + { + aLbMatFavorites.SelectEntryPos( 0 ); + bUpdatePreview = TRUE; + } + // Beleuchtung + else if( p == &aLbAmbientlight ) + { + bUpdatePreview = TRUE; + } + else if( p == &aLbLight1 || + p == &aLbLight2 || + p == &aLbLight3 || + p == &aLbLight4 || + p == &aLbLight5 || + p == &aLbLight6 || + p == &aLbLight7 || + p == &aLbLight8 ) + { + bUpdatePreview = TRUE; + } + else if( p == &aLbShademode ) + bUpdatePreview = TRUE; + + if( bUpdatePreview == TRUE ) + UpdatePreview(); + } + return( 0L ); +} + +// ----------------------------------------------------------------------- +IMPL_LINK( Svx3DWin, ModifyHdl, void*, pField ) +{ + if( pField ) + { + BOOL bUpdatePreview = FALSE; + + // Material + if( pField == &aMtrMatSpecularIntensity ) + { + bUpdatePreview = TRUE; + } + else if( pField == &aNumHorizontal ) + { + bUpdatePreview = TRUE; + } + else if( pField == &aNumVertical ) + { + bUpdatePreview = TRUE; + } + else if( pField == &aMtrSlant ) + { + bUpdatePreview = TRUE; + } + + if( bUpdatePreview == TRUE ) + UpdatePreview(); + } + return( 0L ); +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( Svx3DWin, ClickLightHdl, PushButton*, pBtn ) +{ + + if( pBtn ) + { + USHORT nLightSource = GetLightSource( pBtn ); + ColorLB* pLb = GetLbByButton( pBtn ); + Color aColor( pLb->GetSelectEntryColor() ); + SfxItemSet aLightItemSet(aCtlLightPreview.GetSvx3DLightControl().Get3DAttributes()); + const bool bOnOff(GetUILightState( *(ImageButton*)pBtn )); + + switch(nLightSource) + { + case 0: aLightItemSet.Put(Svx3DLightcolor1Item(aColor)); aLightItemSet.Put(Svx3DLightOnOff1Item(bOnOff)); break; + case 1: aLightItemSet.Put(Svx3DLightcolor2Item(aColor)); aLightItemSet.Put(Svx3DLightOnOff2Item(bOnOff)); break; + case 2: aLightItemSet.Put(Svx3DLightcolor3Item(aColor)); aLightItemSet.Put(Svx3DLightOnOff3Item(bOnOff)); break; + case 3: aLightItemSet.Put(Svx3DLightcolor4Item(aColor)); aLightItemSet.Put(Svx3DLightOnOff4Item(bOnOff)); break; + case 4: aLightItemSet.Put(Svx3DLightcolor5Item(aColor)); aLightItemSet.Put(Svx3DLightOnOff5Item(bOnOff)); break; + case 5: aLightItemSet.Put(Svx3DLightcolor6Item(aColor)); aLightItemSet.Put(Svx3DLightOnOff6Item(bOnOff)); break; + case 6: aLightItemSet.Put(Svx3DLightcolor7Item(aColor)); aLightItemSet.Put(Svx3DLightOnOff7Item(bOnOff)); break; + default: + case 7: aLightItemSet.Put(Svx3DLightcolor8Item(aColor)); aLightItemSet.Put(Svx3DLightOnOff8Item(bOnOff)); break; + } + + aCtlLightPreview.GetSvx3DLightControl().Set3DAttributes(aLightItemSet); + aCtlLightPreview.GetSvx3DLightControl().SelectLight(nLightSource); + aCtlLightPreview.CheckSelection(); + } + return( 0L ); +} + + +// ----------------------------------------------------------------------- +IMPL_LINK( Svx3DWin, DoubleClickHdl, void*, EMPTYARG ) +{ + //USHORT nItemId = aCtlFavorites.GetSelectItemId(); + + //SfxItemSet* pSet = (SfxItemSet*) pFavorSetList->GetObject( nItemId - 1 ); + //Update( *pSet ); + + // und zuweisen + ClickAssignHdl( NULL ); + + return( 0L ); +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( Svx3DWin, ChangeLightCallbackHdl, void*, EMPTYARG ) +{ + return( 0L ); +} + + +// ----------------------------------------------------------------------- + +IMPL_LINK( Svx3DWin, ChangeSelectionCallbackHdl, void*, EMPTYARG ) +{ + const sal_uInt32 nLight(aCtlLightPreview.GetSvx3DLightControl().GetSelectedLight()); + PushButton* pBtn = 0; + + switch( nLight ) + { + case 0: pBtn = &aBtnLight1; break; + case 1: pBtn = &aBtnLight2; break; + case 2: pBtn = &aBtnLight3; break; + case 3: pBtn = &aBtnLight4; break; + case 4: pBtn = &aBtnLight5; break; + case 5: pBtn = &aBtnLight6; break; + case 6: pBtn = &aBtnLight7; break; + case 7: pBtn = &aBtnLight8; break; + default: break; + } + + if( pBtn ) + ClickHdl( pBtn ); + else + { + // Zustand: Keine Lampe selektiert + if( aBtnLight1.IsChecked() ) + { + aBtnLight1.Check( FALSE ); + aLbLight1.Enable( FALSE ); + } + else if( aBtnLight2.IsChecked() ) + { + aBtnLight2.Check( FALSE ); + aLbLight2.Enable( FALSE ); + } + else if( aBtnLight3.IsChecked() ) + { + aBtnLight3.Check( FALSE ); + aLbLight3.Enable( FALSE ); + } + else if( aBtnLight4.IsChecked() ) + { + aBtnLight4.Check( FALSE ); + aLbLight4.Enable( FALSE ); + } + else if( aBtnLight5.IsChecked() ) + { + aBtnLight5.Check( FALSE ); + aLbLight5.Enable( FALSE ); + } + else if( aBtnLight6.IsChecked() ) + { + aBtnLight6.Check( FALSE ); + aLbLight6.Enable( FALSE ); + } + else if( aBtnLight7.IsChecked() ) + { + aBtnLight7.Check( FALSE ); + aLbLight7.Enable( FALSE ); + } + else if( aBtnLight8.IsChecked() ) + { + aBtnLight8.Check( FALSE ); + aLbLight8.Enable( FALSE ); + } + aBtnLightColor.Enable( FALSE ); + } + + return( 0L ); +} + +// ----------------------------------------------------------------------- +// Methode um sicherzustellen, dass die LB auch mit einer Farbe gesetzt ist +// Liefert TRUE zurueck, falls Farbe hinzugefuegt wurde +// ----------------------------------------------------------------------- +BOOL Svx3DWin::LBSelectColor( ColorLB* pLb, const Color& rColor ) +{ + BOOL bRet = FALSE; + + pLb->SetNoSelection(); + pLb->SelectEntry( rColor ); + if( pLb->GetSelectEntryCount() == 0 ) + { + String aStr(SVX_RES(RID_SVXFLOAT3D_FIX_R)); + + aStr += String::CreateFromInt32((INT32)rColor.GetRed()); + aStr += sal_Unicode(' '); + aStr += String(SVX_RES(RID_SVXFLOAT3D_FIX_G)); + aStr += String::CreateFromInt32((INT32)rColor.GetGreen()); + aStr += sal_Unicode(' '); + aStr += String(SVX_RES(RID_SVXFLOAT3D_FIX_B)); + aStr += String::CreateFromInt32((INT32)rColor.GetBlue()); + + USHORT nPos = pLb->InsertEntry( rColor, aStr ); + pLb->SelectEntryPos( nPos ); + bRet = TRUE; + } + return( bRet ); +} + +// ----------------------------------------------------------------------- +void Svx3DWin::UpdatePreview() +{ + if( pModel == NULL ) + pModel = new FmFormModel(); + + if(bOnly3DChanged) + { + // slot executen + SfxDispatcher* pDispatcher = LocalGetDispatcher(pBindings); + if (pDispatcher != NULL) + { + SfxBoolItem aItem( SID_3D_STATE, TRUE ); + pDispatcher->Execute( + SID_3D_STATE, SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD, &aItem, 0L ); + } + // Flag zuruecksetzen + bOnly3DChanged = FALSE; + } + + // ItemSet besorgen + SfxItemSet aSet( pModel->GetItemPool(), SDRATTR_START, SDRATTR_END); + + // Attribute holen und im Preview setzen + GetAttr( aSet ); + aCtlPreview.Set3DAttributes( aSet ); + aCtlLightPreview.GetSvx3DLightControl().Set3DAttributes( aSet ); +} + +////////////////////////////////////////////////////////////////////////////// +// document is to be reloaded, destroy remembered ItemSet (#83951#) +void Svx3DWin::DocumentReload() +{ + if(mpRemember2DAttributes) + delete mpRemember2DAttributes; + mpRemember2DAttributes = 0L; +} + +// ----------------------------------------------------------------------- +void Svx3DWin::InitColorLB( const SdrModel* pDoc ) +{ + aLbLight1.Fill( pDoc->GetColorTable() ); + aLbLight2.CopyEntries( aLbLight1 ); + aLbLight3.CopyEntries( aLbLight1 ); + aLbLight4.CopyEntries( aLbLight1 ); + aLbLight5.CopyEntries( aLbLight1 ); + aLbLight6.CopyEntries( aLbLight1 ); + aLbLight7.CopyEntries( aLbLight1 ); + aLbLight8.CopyEntries( aLbLight1 ); + aLbAmbientlight.CopyEntries( aLbLight1 ); + aLbMatColor.CopyEntries( aLbLight1 ); + aLbMatEmission.CopyEntries( aLbLight1 ); + aLbMatSpecular.CopyEntries( aLbLight1 ); + + // Erstmal... + Color aColWhite( COL_WHITE ); + Color aColBlack( COL_BLACK ); + aLbLight1.SelectEntry( aColWhite ); + aLbLight2.SelectEntry( aColWhite ); + aLbLight3.SelectEntry( aColWhite ); + aLbLight4.SelectEntry( aColWhite ); + aLbLight5.SelectEntry( aColWhite ); + aLbLight6.SelectEntry( aColWhite ); + aLbLight7.SelectEntry( aColWhite ); + aLbLight8.SelectEntry( aColWhite ); + aLbAmbientlight.SelectEntry( aColBlack ); + aLbMatColor.SelectEntry( aColWhite ); + aLbMatEmission.SelectEntry( aColBlack ); + aLbMatSpecular.SelectEntry( aColWhite ); +} + +// ----------------------------------------------------------------------- +USHORT Svx3DWin::GetLightSource( const PushButton* pBtn ) +{ + USHORT nLight = 8; + + if( pBtn == NULL ) + { + if( aBtnLight1.IsChecked() ) + nLight = 0; + else if( aBtnLight2.IsChecked() ) + nLight = 1; + else if( aBtnLight3.IsChecked() ) + nLight = 2; + else if( aBtnLight4.IsChecked() ) + nLight = 3; + else if( aBtnLight5.IsChecked() ) + nLight = 4; + else if( aBtnLight6.IsChecked() ) + nLight = 5; + else if( aBtnLight7.IsChecked() ) + nLight = 6; + else if( aBtnLight8.IsChecked() ) + nLight = 7; + } + else + { + if( pBtn == &aBtnLight1 ) + nLight = 0; + else if( pBtn == &aBtnLight2 ) + nLight = 1; + else if( pBtn == &aBtnLight3 ) + nLight = 2; + else if( pBtn == &aBtnLight4 ) + nLight = 3; + else if( pBtn == &aBtnLight5 ) + nLight = 4; + else if( pBtn == &aBtnLight6 ) + nLight = 5; + else if( pBtn == &aBtnLight7 ) + nLight = 6; + else if( pBtn == &aBtnLight8 ) + nLight = 7; + } + return( nLight ); +}; + +// ----------------------------------------------------------------------- +ColorLB* Svx3DWin::GetLbByButton( const PushButton* pBtn ) +{ + ColorLB* pLb = NULL; + + if( pBtn == NULL ) + { + if( aBtnLight1.IsChecked() ) + pLb = &aLbLight1; + else if( aBtnLight2.IsChecked() ) + pLb = &aLbLight2; + else if( aBtnLight3.IsChecked() ) + pLb = &aLbLight3; + else if( aBtnLight4.IsChecked() ) + pLb = &aLbLight4; + else if( aBtnLight5.IsChecked() ) + pLb = &aLbLight5; + else if( aBtnLight6.IsChecked() ) + pLb = &aLbLight6; + else if( aBtnLight7.IsChecked() ) + pLb = &aLbLight7; + else if( aBtnLight8.IsChecked() ) + pLb = &aLbLight8; + } + else + { + if( pBtn == &aBtnLight1 ) + pLb = &aLbLight1; + else if( pBtn == &aBtnLight2 ) + pLb = &aLbLight2; + else if( pBtn == &aBtnLight3 ) + pLb = &aLbLight3; + else if( pBtn == &aBtnLight4 ) + pLb = &aLbLight4; + else if( pBtn == &aBtnLight5 ) + pLb = &aLbLight5; + else if( pBtn == &aBtnLight6 ) + pLb = &aLbLight6; + else if( pBtn == &aBtnLight7 ) + pLb = &aLbLight7; + else if( pBtn == &aBtnLight8 ) + pLb = &aLbLight8; + } + return( pLb ); +}; + +/************************************************************************* +|* +|* Ableitung vom SfxChildWindow als "Behaelter" fuer Effekte +|* +\************************************************************************/ +__EXPORT Svx3DChildWindow::Svx3DChildWindow( Window* _pParent, + USHORT nId, + SfxBindings* pBindings, + SfxChildWinInfo* pInfo ) : + SfxChildWindow( _pParent, nId ) +{ + Svx3DWin* pWin = new Svx3DWin( pBindings, this, _pParent ); + pWindow = pWin; + + eChildAlignment = SFX_ALIGN_NOALIGNMENT; + + pWin->Initialize( pInfo ); +} + +/************************************************************************* +|* +|* ControllerItem fuer 3DStatus +|* +\************************************************************************/ +Svx3DCtrlItem::Svx3DCtrlItem( USHORT _nId, + Svx3DWin* pWin, + SfxBindings* _pBindings) : + SfxControllerItem( _nId, *_pBindings ), + p3DWin( pWin ) +{ +} + +// ----------------------------------------------------------------------- +void __EXPORT Svx3DCtrlItem::StateChanged( USHORT /*nSId*/, + SfxItemState /*eState*/, const SfxPoolItem* /*pItem*/ ) +{ +} + +/************************************************************************* +|* +|* ControllerItem fuer Status Slot SID_CONVERT_TO_3D +|* +\************************************************************************/ + +SvxConvertTo3DItem::SvxConvertTo3DItem(UINT16 _nId, SfxBindings* _pBindings) +: SfxControllerItem(_nId, *_pBindings), + bState(FALSE) +{ +} + +void SvxConvertTo3DItem::StateChanged(UINT16 /*_nId*/, SfxItemState eState, const SfxPoolItem* /*pState*/) +{ + BOOL bNewState = (eState != SFX_ITEM_DISABLED); + if(bNewState != bState) + { + bState = bNewState; + SfxDispatcher* pDispatcher = LocalGetDispatcher(&GetBindings()); + if (pDispatcher != NULL) + { + SfxBoolItem aItem( SID_3D_STATE, TRUE ); + pDispatcher->Execute( + SID_3D_STATE, SFX_CALLMODE_ASYNCHRON|SFX_CALLMODE_RECORD, &aItem, 0L); + } + } +} + + diff --git a/svx/source/engine3d/float3d.src b/svx/source/engine3d/float3d.src new file mode 100644 index 000000000000..b3e8992f4338 --- /dev/null +++ b/svx/source/engine3d/float3d.src @@ -0,0 +1,1420 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include <svx/dialogs.hrc> +#include "float3d.hrc" +#define WIDTH 158 +#define HEIGHT 209 +#define BORDER 3 +#define BUTTON_WIDTH 13 +#define BUTTON_HEIGHT 13 +#define VT_BUTTON_WIDTH 18 +#define GROUP_Y (BORDER + BUTTON_HEIGHT + 3) +#define GROUP_HEIGHT 95 +#define GROUP_WIDTH (WIDTH - 2 * BORDER) +#define GROUP_PREV_X 60 +#define GROUP_PREV_Y (GROUP_Y + GROUP_HEIGHT + 1) +#define GROUP_PREV_WIDTH (WIDTH - BORDER - GROUP_PREV_X) +#define GROUP_PREV_HEIGHT (HEIGHT - GROUP_PREV_Y - BORDER) +#define IMG_BUTTON_HEIGHT 15 +#define IMG_BUTTON_NEXT (IMG_BUTTON_HEIGHT + 2) +#define IMG_BUTTON_SIZE MAP_APPFONT( BUTTON_WIDTH, IMG_BUTTON_HEIGHT ) +#define FIXED_LINE_HEIGHT 8 +#define FIXED_LINE_SIZE MAP_APPFONT( GROUP_WIDTH, FIXED_LINE_HEIGHT ) +#define TOP_FIXED_LINE_POS MAP_APPFONT( BORDER, 2+BORDER + IMG_BUTTON_HEIGHT ) +#define FT_WIDTH_SHORT 56 +#define FT_WIDTH_LONG 89 +#define FT_HEIGHT 8 +#define FT_OFFSET_NEXT (FT_HEIGHT + 6) +#define FT_INDENT (BORDER + 6) +#define FIRST_FT_START_Y (2+BORDER+IMG_BUTTON_HEIGHT + 13) +#define SEGMENTS_START_Y (FIRST_FT_START_Y + 3*FT_OFFSET_NEXT + 13) +#define NORMALS_START_Y (SEGMENTS_START_Y + 2*13) +#define NORMALS_BT_START_Y (SEGMENTS_START_Y + 2*13 +11) +#define SHADOW_START_Y (FIRST_FT_START_Y + 13) +#define CAMERA_START_Y (SHADOW_START_Y + FT_OFFSET_NEXT + 13) +#define SPECULAR_START_Y (FIRST_FT_START_Y + 2*FT_OFFSET_NEXT + 13) + +#define MASKCOLOR MaskColor = Color { Red=0xFFFF; Green=0x0000; Blue=0xFFFF; }; + + +DockingWindow RID_SVXFLOAT_3D +{ + HelpID = SID_3D_WIN ; + Border = TRUE ; + Hide = TRUE ; + SVLook = TRUE ; + Sizeable = TRUE ; + Moveable = TRUE ; + Closeable = TRUE ; + Zoomable = TRUE ; + Dockable = TRUE ; + EnableResizing = TRUE ; + Size = MAP_APPFONT ( WIDTH , HEIGHT ) ; + Text [ en-US ] = "3D Effects" ; + Closeable = TRUE ; + Zoomable = TRUE ; + + ImageButton BTN_GEO + { + Pos = MAP_APPFONT ( 4 , BORDER ) ; + Size = MAP_APPFONT ( VT_BUTTON_WIDTH , IMG_BUTTON_HEIGHT ) ; + TabStop = TRUE ; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "3dgeo.bmp" ; }; + MASKCOLOR + }; + QuickHelpText [ en-US ] = "Geometry" ; + }; + ImageButton BTN_REPRESENTATION + { + Pos = MAP_APPFONT ( 22 , BORDER ) ; + Size = MAP_APPFONT ( VT_BUTTON_WIDTH , IMG_BUTTON_HEIGHT ) ; + TabStop = TRUE ; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "3drepres.bmp" ; }; + MASKCOLOR + }; + QuickHelpText [ en-US ] = "Shading" ; + }; + ImageButton BTN_LIGHT + { + Pos = MAP_APPFONT ( 40 , BORDER ) ; + Size = MAP_APPFONT ( VT_BUTTON_WIDTH , IMG_BUTTON_HEIGHT ) ; + TabStop = TRUE ; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "3dlight.bmp" ; }; + MASKCOLOR + }; + QuickHelpText [ en-US ] = "Illumination" ; + }; + ImageButton BTN_TEXTURE + { + Pos = MAP_APPFONT ( 58 , BORDER ) ; + Size = MAP_APPFONT ( VT_BUTTON_WIDTH , IMG_BUTTON_HEIGHT ) ; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "3dtextur.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Textures" ; + }; + ImageButton BTN_MATERIAL + { + Pos = MAP_APPFONT ( 76 , BORDER ) ; + Size = MAP_APPFONT ( VT_BUTTON_WIDTH , IMG_BUTTON_HEIGHT ) ; + TabStop = TRUE ; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "material.bmp" ; }; + MASKCOLOR + }; + QuickHelpText [ en-US ] = "Material" ; + }; + + ImageButton BTN_UPDATE + { + Pos = MAP_APPFONT ( WIDTH - BORDER - BUTTON_WIDTH * 2 , BORDER ) ; + Size = IMG_BUTTON_SIZE; + TabStop = TRUE ; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "sc10350.bmp" ; }; + MASKCOLOR + }; + QuickHelpText [ en-US ] = "Update" ; + }; + ImageButton BTN_ASSIGN + { + Pos = MAP_APPFONT ( WIDTH - BORDER - BUTTON_WIDTH , BORDER ) ; + Size = IMG_BUTTON_SIZE; + TabStop = TRUE ; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "apply.bmp" ; }; + MASKCOLOR + }; + QuickHelpText [ en-US ] = "Assign" ; + }; + // Unterer Teil + ImageButton BTN_CHANGE_TO_3D + { + Pos = MAP_APPFONT ( 9 , 200 - BUTTON_HEIGHT ) ; + Size = IMG_BUTTON_SIZE; + TabStop = TRUE ; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "convrt3d.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Convert to 3D" ; + }; + ImageButton BTN_LATHE_OBJ + { + Pos = MAP_APPFONT ( 9 + BUTTON_WIDTH + 1 , 200 - BUTTON_HEIGHT ) ; + Size = IMG_BUTTON_SIZE; + TabStop = TRUE ; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "rotate3d.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Convert to Lathe Object" ; + }; + ImageButton BTN_PERSPECTIVE + { + Pos = MAP_APPFONT ( 9 + ( BUTTON_WIDTH + 1 ) * 2 , 200 - BUTTON_HEIGHT ) ; + Size = IMG_BUTTON_SIZE; + TabStop = TRUE ; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "persp3d.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Perspective On/Off" ; + }; + Control CTL_PREVIEW + { + Border = TRUE ; + Pos = MAP_APPFONT ( 66 , 124 ) ; + Size = MAP_APPFONT ( 83 , 76 ) ; + TabStop = TRUE ; + }; + Control CTL_LIGHT_PREVIEW + { + Border = TRUE ; + Pos = MAP_APPFONT ( 66 , 124 ) ; + Size = MAP_APPFONT ( 83 , 76 ) ; + TabStop = TRUE ; + }; + FixedLine FL_GEOMETRIE + { + Pos = TOP_FIXED_LINE_POS; + Size = FIXED_LINE_SIZE; + Text [ en-US ] = "Geometry" ; + }; + FixedText FT_PERCENT_DIAGONAL + { + Pos = MAP_APPFONT ( FT_INDENT, FIRST_FT_START_Y ); + Size = MAP_APPFONT ( FT_WIDTH_LONG , FT_HEIGHT ) ; + Text [ en-US ] = "R~ounded edges" ; + }; + MetricField MTR_PERCENT_DIAGONAL + { + Border = TRUE ; + Pos = MAP_APPFONT ( FT_INDENT + FT_WIDTH_LONG + 1 , FIRST_FT_START_Y - 2 ) ; + Size = MAP_APPFONT ( 50 , 12 ) ; + TabStop = TRUE ; + Repeat = TRUE ; + Spin = TRUE ; + SpinSize = 5 ; + Maximum = 100 ; + Last = 100 ; + Unit = FUNIT_CUSTOM ; + CustomUnitText = " %" ; + }; + FixedText FT_BACKSCALE + { + Pos = MAP_APPFONT ( FT_INDENT , FIRST_FT_START_Y + FT_OFFSET_NEXT ) ; + Size = MAP_APPFONT ( FT_WIDTH_LONG , FT_HEIGHT ) ; + Text [ en-US ] = "~Scaled depth" ; + }; + MetricField MTR_BACKSCALE + { + Border = TRUE ; + Pos = MAP_APPFONT ( FT_INDENT + FT_WIDTH_LONG + 1, + FIRST_FT_START_Y + FT_OFFSET_NEXT - 2 ) ; + Size = MAP_APPFONT ( 50 , 12 ) ; + TabStop = TRUE ; + Repeat = TRUE ; + Spin = TRUE ; + SpinSize = 5 ; + Maximum = 10000 ; + Unit = FUNIT_CUSTOM ; + CustomUnitText = " %" ; + Last = 10000 ; + }; + FixedText FT_END_ANGLE + { + Pos = MAP_APPFONT ( FT_INDENT , FIRST_FT_START_Y + 2*FT_OFFSET_NEXT ) ; + Size = MAP_APPFONT ( FT_WIDTH_LONG , FT_HEIGHT ) ; + Text [ en-US ] = "~Rotation angle" ; + }; + MetricField MTR_END_ANGLE + { + Border = TRUE ; + Pos = MAP_APPFONT ( FT_INDENT + FT_WIDTH_LONG + 1, + FIRST_FT_START_Y + 2*FT_OFFSET_NEXT - 2 ) ; + Size = MAP_APPFONT ( 50 , 12 ) ; + TabStop = TRUE ; + Repeat = TRUE ; + Spin = TRUE ; + SpinSize = 5 ; + Unit = FUNIT_CUSTOM ; + Maximum = 36000 ; + Last = 36000 ; + DecimalDigits = 1 ; + CustomUnitText [ en-US ] = " degree(s)"; + }; + FixedText FT_DEPTH + { + Pos = MAP_APPFONT ( FT_INDENT , FIRST_FT_START_Y + 3*FT_OFFSET_NEXT ) ; + Size = MAP_APPFONT ( FT_WIDTH_LONG , FT_HEIGHT ) ; + Text [ en-US ] = "~Depth" ; + }; + MetricField MTR_DEPTH + { + Border = TRUE ; + Pos = MAP_APPFONT ( FT_INDENT + FT_WIDTH_LONG + 1, + FIRST_FT_START_Y + 3*FT_OFFSET_NEXT - 2 ) ; + Size = MAP_APPFONT ( 50 , 12 ) ; + TabStop = TRUE ; + Repeat = TRUE ; + Spin = TRUE ; + Unit = FUNIT_MM ; + StrictFormat = TRUE ; + Minimum = 0 ; + First = 0 ; + Maximum = 10000000 ; + Last = 10000000 ; + DecimalDigits = 2 ; + SpinSize = 100 ; + }; + FixedLine FL_SEGMENTS + { + Pos = MAP_APPFONT ( BORDER , SEGMENTS_START_Y ) ; + Size = FIXED_LINE_SIZE; + Text [ en-US ] = "Segments" ; + }; + // Geometrie + FixedText FT_HORIZONTAL + { + Pos = MAP_APPFONT ( FT_INDENT , SEGMENTS_START_Y+13 ) ; + Size = MAP_APPFONT ( 40 , 8 ) ; + Text [ en-US ] = "~Horizontal" ; + }; + NumericField NUM_HORIZONTAL + { + Border = TRUE ; + Pos = MAP_APPFONT ( FT_INDENT + 42, SEGMENTS_START_Y+13-2 ) ; + Size = MAP_APPFONT ( 22 , 12 ) ; + TabStop = TRUE ; + Repeat = TRUE ; + Spin = TRUE ; + Minimum = 2 ; + First = 2 ; + Maximum = 256 ; + Last = 256 ; + }; + FixedText FT_VERTICAL + { + Pos = MAP_APPFONT ( FT_INDENT + 74 , SEGMENTS_START_Y+13 ) ; + Size = MAP_APPFONT ( 40 , 8 ) ; + Text [ en-US ] = "~Vertical" ; + }; + NumericField NUM_VERTICAL + { + Border = TRUE ; + Pos = MAP_APPFONT ( FT_INDENT + 114+2 , SEGMENTS_START_Y+13-2 ) ; + Size = MAP_APPFONT ( 22 , 12 ) ; + TabStop = TRUE ; + Repeat = TRUE ; + Spin = TRUE ; + Minimum = 2 ; + First = 2 ; + Maximum = 256 ; + Last = 256 ; + }; + + FixedLine FL_NORMALS + { + Pos = MAP_APPFONT ( BORDER , NORMALS_START_Y ) ; + Size = MAP_APPFONT ( 54 , 8 ) ; + Text [ en-US ] = "Normals" ; + }; + ImageButton BTN_NORMALS_OBJ + { + Pos = MAP_APPFONT ( FT_INDENT , NORMALS_BT_START_Y ) ; + Size = IMG_BUTTON_SIZE; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "normobjs.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Object-Specific" ; + }; + ImageButton BTN_NORMALS_FLAT + { + Pos = MAP_APPFONT ( FT_INDENT + (1+BUTTON_WIDTH) , NORMALS_BT_START_Y ) ; + Size = IMG_BUTTON_SIZE; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "normflat.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Flat" ; + }; + ImageButton BTN_NORMALS_SPHERE + { + Pos = MAP_APPFONT ( FT_INDENT + (1+BUTTON_WIDTH) * 2 , NORMALS_BT_START_Y ) ; + Size = IMG_BUTTON_SIZE; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "normsphe.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Spherical" ; + }; + ImageButton BTN_NORMALS_INVERT + { + Pos = MAP_APPFONT ( FT_INDENT , NORMALS_BT_START_Y + IMG_BUTTON_NEXT ) ; + Size = IMG_BUTTON_SIZE; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "invert3d.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Invert Normals" ; + }; + ImageButton BTN_TWO_SIDED_LIGHTING + { + Pos = MAP_APPFONT ( FT_INDENT + (1+BUTTON_WIDTH) * 2 , + NORMALS_BT_START_Y + IMG_BUTTON_NEXT ) ; + Size = IMG_BUTTON_SIZE; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "lght2sid.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Double-Sided Illumination" ; + }; + ImageButton BTN_DOUBLE_SIDED + { + Pos = MAP_APPFONT ( FT_INDENT , NORMALS_BT_START_Y + 2*IMG_BUTTON_NEXT ) ; + Size = IMG_BUTTON_SIZE; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "doublesi.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Double-Sided" ; + }; + + // Darstellung + FixedText FT_SHADEMODE + { + Pos = MAP_APPFONT ( FT_INDENT , FIRST_FT_START_Y ) ; + Size = MAP_APPFONT ( FT_WIDTH_SHORT , FT_HEIGHT ) ; + Text [ en-US ] = "~Mode" ; + }; + ListBox LB_SHADEMODE + { + Border = TRUE ; + Pos = MAP_APPFONT ( 66 , 30 ) ; + Size = MAP_APPFONT ( 83 , 100 ) ; + TabStop = TRUE ; + DropDown = TRUE ; + StringList [ en-US ] = + { + < "Flat" ; > ; + < "Phong" ; > ; + < "Gouraud" ; > ; + }; + }; + FixedLine FL_SHADOW + { + Pos = MAP_APPFONT ( BORDER , SHADOW_START_Y ) ; + Size = FIXED_LINE_SIZE; + Text [ en-US ] = "Shadow" ; + }; + ImageButton BTN_SHADOW_3D + { + Pos = MAP_APPFONT ( FT_INDENT , SHADOW_START_Y + 11 ) ; + Size = IMG_BUTTON_SIZE; + TabStop = TRUE ; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "shadow3d.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "3D Shadowing On/Off" ; + }; + FixedText FT_SLANT + { + Pos = MAP_APPFONT ( FT_INDENT + BUTTON_WIDTH + 3 , SHADOW_START_Y + 11 + 2 ) ; + Size = MAP_APPFONT ( 68 , FT_HEIGHT ) ; + Right = TRUE; + Text [ en-US ] = "S~urface angle" ; + }; + MetricField MTR_SLANT + { + Border = TRUE ; + Pos = MAP_APPFONT ( 99 , SHADOW_START_Y + 11 ) ; + Size = MAP_APPFONT ( 50 , 12 ) ; + TabStop = TRUE ; + Repeat = TRUE ; + Spin = TRUE ; + SpinSize = 5 ; + Maximum = 90 ; + Unit = FUNIT_CUSTOM ; + Last = 90 ; + CustomUnitText [ en-US ] = " degree(s)"; + }; + + FixedLine FL_CAMERA + { + Pos = MAP_APPFONT ( BORDER , CAMERA_START_Y ) ; + Size = FIXED_LINE_SIZE; + Text [ en-US ] = "Camera" ; + }; + FixedText FT_DISTANCE + { + Pos = MAP_APPFONT ( FT_INDENT , CAMERA_START_Y + 11 ) ; + Size = MAP_APPFONT ( FT_WIDTH_LONG , FT_HEIGHT ) ; + Text [ en-US ] = "~Distance" ; + }; + MetricField MTR_DISTANCE + { + Border = TRUE ; + Pos = MAP_APPFONT ( FT_INDENT + FT_WIDTH_LONG + 1 , + CAMERA_START_Y + 11 - 2 ) ; + Size = MAP_APPFONT ( 50 , 12 ) ; + TabStop = TRUE ; + Repeat = TRUE ; + Spin = TRUE ; + StrictFormat = TRUE ; + Unit = FUNIT_MM ; + Minimum = 1 ; + First = 1 ; + Maximum = 1000000 ; + Last = 1000000 ; + DecimalDigits = 2 ; + SpinSize = 100 ; + }; + FixedText FT_FOCAL_LENGTH + { + Pos = MAP_APPFONT ( FT_INDENT , CAMERA_START_Y + 11 + FT_OFFSET_NEXT ) ; + Size = MAP_APPFONT ( FT_WIDTH_LONG , FT_HEIGHT ) ; + Text [ en-US ] = "~Focal length" ; + }; + MetricField MTR_FOCAL_LENGTH + { + Border = TRUE ; + Pos = MAP_APPFONT ( FT_INDENT + FT_WIDTH_LONG + 1 , + CAMERA_START_Y + 11 + FT_OFFSET_NEXT - 2 ) ; + Size = MAP_APPFONT ( 50 , 12 ) ; + TabStop = TRUE ; + Repeat = TRUE ; + Spin = TRUE ; + StrictFormat = TRUE ; + Unit = FUNIT_MM ; + Minimum = 1 ; + First = 1 ; + Maximum = 1000000 ; + Last = 1000000 ; + DecimalDigits = 2 ; + SpinSize = 100 ; + }; + FixedLine FL_REPRESENTATION + { + Pos = TOP_FIXED_LINE_POS; + Size = FIXED_LINE_SIZE; + Text [ en-US ] = "Shading" ; + }; + // Beleuchtung + FixedText FT_LIGHTSOURCE + { + Pos = MAP_APPFONT ( FT_INDENT , FIRST_FT_START_Y ) ; + Size = MAP_APPFONT ( FT_WIDTH_LONG , FT_HEIGHT ) ; + Text [ en-US ] = "~Light source" ; + }; + ImageButton BTN_LIGHT_1 + { + Pos = MAP_APPFONT ( FT_INDENT , FIRST_FT_START_Y + 11 ) ; + Size = MAP_APPFONT ( 12 , 14 ) ; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "light.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Light Source 1" ; + }; + ImageButton BTN_LIGHT_2 + { + Pos = MAP_APPFONT ( FT_INDENT + 13 , FIRST_FT_START_Y + 11 ) ; + Size = MAP_APPFONT ( 12 , 14 ) ; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "light.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Light Source 2" ; + }; + ImageButton BTN_LIGHT_3 + { + Pos = MAP_APPFONT ( FT_INDENT + 2*13 , FIRST_FT_START_Y + 11 ) ; + Size = MAP_APPFONT ( 12 , 14 ) ; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "light.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Light Source 3" ; + }; + ImageButton BTN_LIGHT_4 + { + Pos = MAP_APPFONT ( FT_INDENT + 3*13 , FIRST_FT_START_Y + 11 ) ; + Size = MAP_APPFONT ( 12 , 14 ) ; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "light.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Light Source 4" ; + }; + ImageButton BTN_LIGHT_5 + { + Pos = MAP_APPFONT ( FT_INDENT , FIRST_FT_START_Y + 26 ) ; + Size = MAP_APPFONT ( 12 , 14 ) ; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "light.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Light Source 5" ; + }; + ImageButton BTN_LIGHT_6 + { + Pos = MAP_APPFONT ( FT_INDENT + 13, FIRST_FT_START_Y + 26 ) ; + Size = MAP_APPFONT ( 12 , 14 ) ; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "light.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Light Source 6" ; + }; + ImageButton BTN_LIGHT_7 + { + Pos = MAP_APPFONT ( FT_INDENT + 2*13, FIRST_FT_START_Y + 26 ) ; + Size = MAP_APPFONT ( 12 , 14 ) ; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "light.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Light Source 7" ; + }; + ImageButton BTN_LIGHT_8 + { + Pos = MAP_APPFONT ( FT_INDENT +3*13 , FIRST_FT_START_Y + 26 ) ; + Size = MAP_APPFONT ( 12 , 14 ) ; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "light.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Light Source 8" ; + }; + ListBox LB_LIGHT_1 + { + Border = TRUE ; + Pos = MAP_APPFONT ( 66 , FIRST_FT_START_Y + 11 ) ; + Size = MAP_APPFONT ( 68 , 100 ) ; + TabStop = TRUE ; + DropDown = TRUE ; + }; + ListBox LB_LIGHT_2 + { + Border = TRUE ; + Pos = MAP_APPFONT ( 66 , FIRST_FT_START_Y + 11 ) ; + Size = MAP_APPFONT ( 68 , 100 ) ; + TabStop = TRUE ; + DropDown = TRUE ; + }; + ListBox LB_LIGHT_3 + { + Border = TRUE ; + Pos = MAP_APPFONT ( 66 , FIRST_FT_START_Y + 11 ) ; + Size = MAP_APPFONT ( 68 , 100 ) ; + TabStop = TRUE ; + DropDown = TRUE ; + }; + ListBox LB_LIGHT_4 + { + Border = TRUE ; + Pos = MAP_APPFONT ( 66 , FIRST_FT_START_Y + 11 ) ; + Size = MAP_APPFONT ( 68 , 100 ) ; + TabStop = TRUE ; + DropDown = TRUE ; + }; + ListBox LB_LIGHT_5 + { + Border = TRUE ; + Pos = MAP_APPFONT ( 66 , FIRST_FT_START_Y + 11 ) ; + Size = MAP_APPFONT ( 68 , 100 ) ; + TabStop = TRUE ; + DropDown = TRUE ; + }; + ListBox LB_LIGHT_6 + { + Border = TRUE ; + Pos = MAP_APPFONT ( 66 , FIRST_FT_START_Y + 11 ) ; + Size = MAP_APPFONT ( 68 , 100 ) ; + TabStop = TRUE ; + DropDown = TRUE ; + }; + ListBox LB_LIGHT_7 + { + Border = TRUE ; + Pos = MAP_APPFONT ( 66 , FIRST_FT_START_Y + 11 ) ; + Size = MAP_APPFONT ( 68 , 100 ) ; + TabStop = TRUE ; + DropDown = TRUE ; + }; + ListBox LB_LIGHT_8 + { + Border = TRUE ; + Pos = MAP_APPFONT ( 66 , FIRST_FT_START_Y + 11 ) ; + Size = MAP_APPFONT ( 68 , 100 ) ; + TabStop = TRUE ; + DropDown = TRUE ; + }; + ImageButton BTN_LIGHT_COLOR + { + Pos = MAP_APPFONT ( 137 , FIRST_FT_START_Y + 11 ) ; + Size = MAP_APPFONT ( 12 , 14 ) ; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "colordlg.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Colors Dialog" ; + }; + FixedText FT_AMBIENTLIGHT + { + Pos = MAP_APPFONT ( FT_INDENT, FIRST_FT_START_Y + 53 ) ; + Size = MAP_APPFONT ( FT_WIDTH_SHORT , FT_HEIGHT ) ; + Text [ en-US ] = "~Ambient light" ; + }; + ListBox LB_AMBIENTLIGHT + { + Border = TRUE ; + Pos = MAP_APPFONT ( FT_INDENT + FT_WIDTH_SHORT + 1 , FIRST_FT_START_Y + 53 ) ; + Size = MAP_APPFONT ( 68 , 100 ) ; + TabStop = TRUE ; + DropDown = TRUE ; + }; + ImageButton BTN_AMBIENT_COLOR + { + Pos = MAP_APPFONT ( 137 , FIRST_FT_START_Y + 53 ) ; + Size = MAP_APPFONT ( 12 , 14 ) ; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "colordlg.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Colors Dialog" ; + }; + + FixedLine FL_LIGHT + { + Pos = TOP_FIXED_LINE_POS; + Size = FIXED_LINE_SIZE ; + Text [ en-US ] = "Illumination" ; + }; + // Texturen + FixedText FT_TEX_KIND + { + Pos = MAP_APPFONT ( FT_INDENT , FIRST_FT_START_Y ) ; + Size = MAP_APPFONT ( FT_WIDTH_SHORT , FT_HEIGHT ) ; + Text [ en-US ] = "~Type" ; + }; + ImageButton BTN_TEX_LUMINANCE + { + Pos = MAP_APPFONT ( FT_INDENT + FT_WIDTH_SHORT + 1, + FIRST_FT_START_Y - 2 ) ; + Size = IMG_BUTTON_SIZE; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "luminanc.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Black & White" ; + }; + ImageButton BTN_TEX_COLOR + { + Pos = MAP_APPFONT ( FT_INDENT + FT_WIDTH_SHORT + 1 + BUTTON_WIDTH, + FIRST_FT_START_Y - 2 ) ; + Size = IMG_BUTTON_SIZE; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "color.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Color" ; + }; + FixedText FT_TEX_MODE + { + Pos = MAP_APPFONT ( FT_INDENT , FIRST_FT_START_Y + IMG_BUTTON_NEXT ) ; + Size = MAP_APPFONT ( FT_WIDTH_SHORT , FT_HEIGHT ) ; + Text [ en-US ] = "~Mode" ; + }; + ImageButton BTN_TEX_REPLACE + { + Pos = MAP_APPFONT ( FT_INDENT + FT_WIDTH_SHORT + 1, + FIRST_FT_START_Y + IMG_BUTTON_NEXT - 2 ) ; + Size = IMG_BUTTON_SIZE; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "replac3d.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Only Texture" ; + }; + ImageButton BTN_TEX_MODULATE + { + Pos = MAP_APPFONT ( FT_INDENT + FT_WIDTH_SHORT + 1 + BUTTON_WIDTH, + FIRST_FT_START_Y + IMG_BUTTON_NEXT - 2 ) ; + Size = IMG_BUTTON_SIZE; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "modula3d.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Texture and Shading" ; + }; + ImageButton BTN_TEX_BLEND + { + Pos = MAP_APPFONT ( FT_INDENT + FT_WIDTH_SHORT + 1 + 2*BUTTON_WIDTH, + FIRST_FT_START_Y + IMG_BUTTON_NEXT - 2 ) ; + Size = IMG_BUTTON_SIZE; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "blend3d.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Texture, Shadow and Color" ; + }; + FixedText FT_TEX_PROJECTION_X + { + Pos = MAP_APPFONT ( FT_INDENT , FIRST_FT_START_Y + 2*IMG_BUTTON_NEXT ) ; + Size = MAP_APPFONT ( FT_WIDTH_SHORT , FT_HEIGHT ) ; + Text [ en-US ] = "~Projection X" ; + }; + ImageButton BTN_TEX_OBJECT_X + { + Pos = MAP_APPFONT ( FT_INDENT + FT_WIDTH_SHORT + 1, + FIRST_FT_START_Y + 2*IMG_BUTTON_NEXT - 2 ) ; + Size = IMG_BUTTON_SIZE; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "objspc3d.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Object-Specific" ; + }; + ImageButton BTN_TEX_PARALLEL_X + { + Pos = MAP_APPFONT ( FT_INDENT + FT_WIDTH_SHORT + 1 + BUTTON_WIDTH, + FIRST_FT_START_Y + 2*IMG_BUTTON_NEXT - 2 ) ; + Size = IMG_BUTTON_SIZE; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "parallel.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Parallel" ; + }; + ImageButton BTN_TEX_CIRCLE_X + { + Pos = MAP_APPFONT ( FT_INDENT + FT_WIDTH_SHORT + 1 + 2*BUTTON_WIDTH, + FIRST_FT_START_Y + 2*IMG_BUTTON_NEXT - 2 ) ; + Size = IMG_BUTTON_SIZE; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "sphere3d.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Circular" ; + }; + FixedText FT_TEX_PROJECTION_Y + { + Pos = MAP_APPFONT ( FT_INDENT , FIRST_FT_START_Y + 3*IMG_BUTTON_NEXT ) ; + Size = MAP_APPFONT ( FT_WIDTH_SHORT , FT_HEIGHT ) ; + Text [ en-US ] = "P~rojection Y" ; + }; + ImageButton BTN_TEX_OBJECT_Y + { + Pos = MAP_APPFONT ( FT_INDENT + FT_WIDTH_SHORT + 1, + FIRST_FT_START_Y + 3*IMG_BUTTON_NEXT - 2 ) ; + Size = IMG_BUTTON_SIZE; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "objspc3d.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Object-Specific" ; + }; + ImageButton BTN_TEX_PARALLEL_Y + { + Pos = MAP_APPFONT ( FT_INDENT + FT_WIDTH_SHORT + 1 + BUTTON_WIDTH, + FIRST_FT_START_Y + 3*IMG_BUTTON_NEXT - 2 ) ; + Size = IMG_BUTTON_SIZE; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "parallel.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Parallel" ; + }; + ImageButton BTN_TEX_CIRCLE_Y + { + Pos = MAP_APPFONT ( FT_INDENT + FT_WIDTH_SHORT + 1 + 2*BUTTON_WIDTH, + FIRST_FT_START_Y + 3*IMG_BUTTON_NEXT - 2 ) ; + Size = IMG_BUTTON_SIZE; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "sphere3d.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Circular" ; + }; + FixedText FT_TEX_FILTER + { + Pos = MAP_APPFONT ( FT_INDENT , FIRST_FT_START_Y + 4*IMG_BUTTON_NEXT ) ; + Size = MAP_APPFONT ( FT_WIDTH_SHORT , FT_HEIGHT ) ; + Text [ en-US ] = "~Filtering" ; + }; + ImageButton BTN_TEX_FILTER + { + Pos = MAP_APPFONT ( FT_INDENT + FT_WIDTH_SHORT + 1, + FIRST_FT_START_Y + 4*IMG_BUTTON_NEXT - 2 ) ; + Size = IMG_BUTTON_SIZE; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "filter3d.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Filtering On/Off" ; + }; + FixedLine FL_TEXTURE + { + Pos = TOP_FIXED_LINE_POS; + Size = FIXED_LINE_SIZE; + Text [ en-US ] = "Textures" ; + }; + // Material + /* Control CTL_MATERIAL + { + //HelpId = HID_SD_CTL_FAVORITES ; + Border = TRUE ; + Pos = MAP_APPFONT ( BORDER + 6 , GROUP_Y + 9 ) ; + Size = MAP_APPFONT ( GROUP_WIDTH - 12 , GROUP_HEIGHT - 15 ) ; + TabStop = TRUE ; + Hide = TRUE ; + }; +*/ + // Materialeditor + FixedText FT_MAT_FAVORITES + { + Pos = MAP_APPFONT ( FT_INDENT , FIRST_FT_START_Y ) ; + Size = MAP_APPFONT ( FT_WIDTH_SHORT , FT_HEIGHT ) ; + Text [ en-US ] = "~Favorites" ; + }; + ListBox LB_MAT_FAVORITES + { + Border = TRUE ; + Pos = MAP_APPFONT ( FT_INDENT + FT_WIDTH_SHORT + 1, + FIRST_FT_START_Y - 2 ) ; + Size = MAP_APPFONT ( 83 , 100 ) ; + TabStop = TRUE ; + DropDown = TRUE ; + StringList [ en-US ] = + { + < "User-defined" ; > ; + < "Metal" ; > ; + < "Gold" ; > ; + < "Chrome" ; > ; + < "Plastic" ; > ; + < "Wood" ; > ; + }; + }; + FixedText FT_MAT_COLOR + { + Pos = MAP_APPFONT ( FT_INDENT , FIRST_FT_START_Y + FT_OFFSET_NEXT ) ; + Size = MAP_APPFONT ( FT_WIDTH_SHORT , FT_HEIGHT ) ; + Text [ en-US ] = "~Object color" ; + }; + ListBox LB_MAT_COLOR + { + Border = TRUE ; + Pos = MAP_APPFONT ( FT_INDENT + FT_WIDTH_SHORT + 1 , + FIRST_FT_START_Y + FT_OFFSET_NEXT - 2 ) ; + Size = MAP_APPFONT ( 68 , 100 ) ; + TabStop = TRUE ; + DropDown = TRUE ; + }; + ImageButton BTN_MAT_COLOR + { + Pos = MAP_APPFONT ( FT_INDENT + FT_WIDTH_SHORT + 72 , + FIRST_FT_START_Y + FT_OFFSET_NEXT - 2 ) ; + Size = MAP_APPFONT ( 12, 14 ) ; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "colordlg.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Colors Dialog" ; + }; + FixedText FT_MAT_EMISSION + { + Pos = MAP_APPFONT ( FT_INDENT , FIRST_FT_START_Y + 2*FT_OFFSET_NEXT ) ; + Size = MAP_APPFONT ( FT_WIDTH_SHORT , FT_HEIGHT ) ; + Text [ en-US ] = "~Illumination color" ; + }; + ListBox LB_MAT_EMISSION + { + Border = TRUE ; + Pos = MAP_APPFONT ( FT_INDENT + FT_WIDTH_SHORT + 1 , + FIRST_FT_START_Y + 2*FT_OFFSET_NEXT - 2 ) ; + Size = MAP_APPFONT ( 68 , 100 ) ; + TabStop = TRUE ; + DropDown = TRUE ; + }; + ImageButton BTN_EMISSION_COLOR + { + Pos = MAP_APPFONT ( FT_INDENT + FT_WIDTH_SHORT + 72 , + FIRST_FT_START_Y + 2*FT_OFFSET_NEXT - 2 ) ; + Size = MAP_APPFONT ( 12, 14 ) ; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "colordlg.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Colors Dialog" ; + }; + + FixedLine FL_MAT_SPECULAR + { + Pos = MAP_APPFONT ( BORDER , SPECULAR_START_Y ) ; + Size = FIXED_LINE_SIZE; + Text [ en-US ] = "Specular" ; + }; + FixedText FT_MAT_SPECULAR + { + Pos = MAP_APPFONT ( FT_INDENT , SPECULAR_START_Y + 13 ) ; + Size = MAP_APPFONT ( FT_WIDTH_SHORT , FT_HEIGHT ) ; + Text [ en-US ] = "~Color" ; + }; + ListBox LB_MAT_SPECULAR + { + Border = TRUE ; + Pos = MAP_APPFONT ( FT_INDENT + FT_WIDTH_SHORT + 1, SPECULAR_START_Y + 13 - 2 ) ; + Size = MAP_APPFONT ( 68 , 100 ) ; + TabStop = TRUE ; + DropDown = TRUE ; + }; + ImageButton BTN_SPECULAR_COLOR + { + Pos = MAP_APPFONT ( 137 , SPECULAR_START_Y + 13 - 2 ) ; + Size = MAP_APPFONT ( 12, 14 ) ; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "colordlg.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE ; + QuickHelpText [ en-US ] = "Colors Dialog" ; + }; + FixedText FT_MAT_SPECULAR_INTENSITY + { + Pos = MAP_APPFONT ( FT_INDENT , SPECULAR_START_Y + 13 + FT_OFFSET_NEXT ) ; + Size = MAP_APPFONT ( FT_WIDTH_SHORT , FT_HEIGHT ) ; + Text [ en-US ] = "I~ntensity" ; + }; + MetricField MTR_MAT_SPECULAR_INTENSITY + { + Border = TRUE ; + Pos = MAP_APPFONT ( FT_INDENT + FT_WIDTH_SHORT + 1 , + SPECULAR_START_Y + 13 + FT_OFFSET_NEXT ) ; + Size = MAP_APPFONT ( 68 , 12 ) ; + TabStop = TRUE ; + Repeat = TRUE ; + Spin = TRUE ; + Unit = FUNIT_CUSTOM ; + CustomUnitText = " %" ; + Minimum = 1 ; + First = 1 ; + Maximum = 100 ; + Last = 100 ; + SpinSize = 1 ; + }; + /* + ImageButton BTN_MAT_FAVORITES { + Pos = MAP_APPFONT( BORDER, GROUP_PREV_Y+1 ); + Size = IMG_BUTTON_SIZE; + QuickHelpText = "Material Favoriten" ; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "matfavor.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE; + }; + ImageButton BTN_MAT_EDITOR { + Pos = MAP_APPFONT( BORDER + BUTTON_WIDTH, GROUP_PREV_Y+1 ); + Size = IMG_BUTTON_SIZE; + QuickHelpText = "Material Editor" ; + ButtonImage = Image + { + ImageBitmap = Bitmap { File = "matedit.bmp" ; }; + MASKCOLOR + }; + TabStop = TRUE; + }; +*/ + FixedLine FL_MATERIAL + { + Pos = TOP_FIXED_LINE_POS; + Size = FIXED_LINE_SIZE; + Text [ en-US ] = "Material" ; + }; + + Bitmap BMP_GEO_H + { + File = "3dgeo_h.bmp"; + }; + + Bitmap BMP_REPRESENTATION_H + { + File = "3drepres_h.bmp"; + }; + + Bitmap BMP_3DLIGHT_H + { + File = "3dlight_h.bmp"; + }; + + Bitmap BMP_TEXTURE_H + { + File = "3dtextur_h.bmp"; + }; + + Bitmap BMP_MATERIAL_H + { + File = "material_h.bmp"; + }; + + Bitmap BMP_UPDATE_H + { + File = "sc10350_h.bmp"; + }; + + Bitmap BMP_ASSIGN_H + { + File = "apply_h.bmp"; + }; + + Bitmap BMP_CHANGE_TO_3D_H + { + File = "convrt3d_h.bmp"; + }; + + Bitmap BMP_LATHE_OBJ_H + { + File = "rotate3d_h.bmp"; + }; + + Bitmap BMP_PERSPECTIVE_H + { + File = "persp3d_h.bmp"; + }; + + Bitmap BMP_NORMALS_OBJ_H + { + File = "normobjs_h.bmp"; + }; + + Bitmap BMP_NORMALS_FLAT_H + { + File = "normflat_h.bmp"; + }; + + Bitmap BMP_NORMALS_SPHERE_H + { + File = "normsphe_h.bmp"; + }; + + Bitmap BMP_NORMALS_INVERT_H + { + File = "invert3d_h.bmp"; + }; + + Bitmap BMP_TWO_SIDED_LIGHTING_H + { + File = "lght2sid_h.bmp"; + }; + + Bitmap BMP_DOUBLE_SIDED_H + { + File = "doublesi_h.bmp"; + }; + + Bitmap BMP_SHADOW_3D_H + { + File = "shadow3d_h.bmp"; + }; + + Bitmap BMP_LIGHT_H + { + File = "light_h.bmp"; + }; + + Bitmap BMP_LIGHT_COLOR_H + { + File = "colordlg_h.bmp"; + }; + + Bitmap BMP_AMBIENT_COLOR_H + { + File = "colordlg_h.bmp"; + }; + + Bitmap BMP_TEX_LUMINANCE_H + { + File = "luminanc_h.bmp"; + }; + + Bitmap BMP_TEX_COLOR_H + { + File = "color_h.bmp"; + }; + + Bitmap BMP_TEX_REPLACE_H + { + File = "replac3d_h.bmp"; + }; + + Bitmap BMP_TEX_MODULATE_H + { + File = "modula3d_h.bmp"; + }; + + Bitmap BMP_TEX_BLEND_H + { + File = "blend3d_h.bmp"; + }; + + Bitmap BMP_TEX_OBJECT_H + { + File = "objspc3d_h.bmp"; + }; + + Bitmap BMP_TEX_PARALLEL_H + { + File = "parallel_h.bmp"; + }; + + Bitmap BMP_TEX_CIRCLE_H + { + File = "sphere3d_h.bmp"; + }; + + Bitmap BMP_TEX_FILTER_H + { + File = "filter3d_h.bmp"; + }; + + Bitmap BMP_COLORDLG_H + { + File = "colordlg_h.bmp"; + }; +}; + +Image RID_SVXIMAGE_LIGHT_ON +{ + ImageBitmap = Bitmap { File = "lighton.bmp" ; }; + MASKCOLOR +}; + +Image RID_SVXIMAGE_LIGHT_OFF +{ + ImageBitmap = Bitmap { File = "light.bmp" ; }; + MASKCOLOR +}; + +Image RID_SVXIMAGE_LIGHT_ON_H +{ + ImageBitmap = Bitmap { File = "lighton_h.bmp" ; }; + MASKCOLOR +}; + +Image RID_SVXIMAGE_LIGHT_OFF_H +{ + ImageBitmap = Bitmap { File = "light_h.bmp" ; }; + MASKCOLOR +}; + +Image RID_SVXIMAGE_COLORDLG +{ + ImageBitmap = Bitmap { File = "colordlg.bmp" ; }; + MASKCOLOR +}; + +Image RID_SVXIMAGE_COLORDLG_H +{ + ImageBitmap = Bitmap { File = "colordlg_h.bmp" ; }; + MASKCOLOR +}; + +/*Image RID_SVXIMAGE_LIGHT_ON_SELECTED { + ImageBitmap = Bitmap { File = "lightons.bmp" ; }; + MASKCOLOR +}; +Image RID_SVXIMAGE_LIGHT_OFF_SELECTED { + ImageBitmap = Bitmap { File = "lightsel.bmp" ; }; + MASKCOLOR +};*/ + +String RID_SVXFLOAT3D_FAVORITE +{ + Text [ en-US ] = "Favorite"; +}; +String RID_SVXFLOAT3D_FIX_X +{ + Text [ en-US ] = "X"; +}; +String RID_SVXFLOAT3D_FIX_Y +{ + Text [ en-US ] = "Y"; +}; +String RID_SVXFLOAT3D_FIX_Z +{ + Text [ en-US ] = "Z"; +}; +String RID_SVXFLOAT3D_FIX_R +{ + Text [ en-US ] = "R:"; +}; +String RID_SVXFLOAT3D_FIX_G +{ + Text [ en-US ] = "G:"; +}; +String RID_SVXFLOAT3D_FIX_B +{ + Text [ en-US ] = "B:"; + +}; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/svx/source/engine3d/helperhittest3d.cxx b/svx/source/engine3d/helperhittest3d.cxx new file mode 100644 index 000000000000..78324c22ed27 --- /dev/null +++ b/svx/source/engine3d/helperhittest3d.cxx @@ -0,0 +1,295 @@ +/************************************************************************* + * + * 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_svx.hxx" + +#include <svx/helperhittest3d.hxx> +#include <basegfx/point/b2dpoint.hxx> +#include <svx/svdpage.hxx> +#include <svx/scene3d.hxx> +#include <svditer.hxx> +#include <drawinglayer/processor3d/cutfindprocessor3d.hxx> +#include <svx/sdr/contact/viewcontactofe3d.hxx> +#include <svx/sdr/contact/viewcontactofe3dscene.hxx> +#include <com/sun/star/uno/Sequence.h> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +class ImplPairDephAndObject +{ +private: + const E3dCompoundObject* mpObject; + double mfDepth; + +public: + ImplPairDephAndObject(const E3dCompoundObject* pObject, double fDepth) + : mpObject(pObject), + mfDepth(fDepth) + {} + + // for ::std::sort + bool operator<(const ImplPairDephAndObject& rComp) const + { + return (mfDepth < rComp.mfDepth); + } + + // data read access + const E3dCompoundObject* getObject() const { return mpObject; } + double getDepth() const { return mfDepth; } +}; + +////////////////////////////////////////////////////////////////////////////// + +void getAllHit3DObjectWithRelativePoint( + const basegfx::B3DPoint& rFront, + const basegfx::B3DPoint& rBack, + const E3dCompoundObject& rObject, + const drawinglayer::geometry::ViewInformation3D& rObjectViewInformation3D, + ::std::vector< basegfx::B3DPoint >& o_rResult, + bool bAnyHit) +{ + o_rResult.clear(); + + if(!rFront.equal(rBack)) + { + // rObject is a E3dCompoundObject, so it cannot be a scene (which is a E3dObject) + const sdr::contact::ViewContactOfE3d& rVCObject = static_cast< sdr::contact::ViewContactOfE3d& >(rObject.GetViewContact()); + const drawinglayer::primitive3d::Primitive3DSequence aPrimitives(rVCObject.getViewIndependentPrimitive3DSequence()); + + if(aPrimitives.hasElements()) + { + // make BoundVolume empty and overlapping test for speedup + const basegfx::B3DRange aObjectRange(drawinglayer::primitive3d::getB3DRangeFromPrimitive3DSequence(aPrimitives, rObjectViewInformation3D)); + + if(!aObjectRange.isEmpty()) + { + const basegfx::B3DRange aFrontBackRange(rFront, rBack); + + if(aObjectRange.overlaps(aFrontBackRange)) + { + // bound volumes hit, geometric cut tests needed + drawinglayer::processor3d::CutFindProcessor aCutFindProcessor(rObjectViewInformation3D, rFront, rBack, bAnyHit); + aCutFindProcessor.process(aPrimitives); + o_rResult = aCutFindProcessor.getCutPoints(); + } + } + } + } +} + +////////////////////////////////////////////////////////////////////////////// + +E3dScene* fillViewInformation3DForCompoundObject(drawinglayer::geometry::ViewInformation3D& o_rViewInformation3D, const E3dCompoundObject& rCandidate) +{ + // Search for root scene (outmost scene) of the 3d object since e.g. in chart, multiple scenes may + // be placed between object and outmost scene. On that search, remember the in-between scene's + // transformation for the correct complete ObjectTransformation. For historical reasons, the + // root scene's own object transformation is part of the scene's ViewTransformation, o do not + // add it. For more details, see ViewContactOfE3dScene::createViewInformation3D. + E3dScene* pParentScene = dynamic_cast< E3dScene* >(rCandidate.GetParentObj()); + E3dScene* pRootScene = 0; + basegfx::B3DHomMatrix aInBetweenSceneMatrix; + + while(pParentScene) + { + E3dScene* pParentParentScene = dynamic_cast< E3dScene* >(pParentScene->GetParentObj()); + + if(pParentParentScene) + { + // pParentScene is a in-between scene + aInBetweenSceneMatrix = pParentScene->GetTransform() * aInBetweenSceneMatrix; + } + else + { + // pParentScene is the root scene + pRootScene = pParentScene; + } + + pParentScene = pParentParentScene; + } + + if(pRootScene) + { + const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pRootScene->GetViewContact()); + + if(aInBetweenSceneMatrix.isIdentity()) + { + o_rViewInformation3D = rVCScene.getViewInformation3D(); + } + else + { + // build new ViewInformation containing all transforms for the candidate + const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D()); + + o_rViewInformation3D = drawinglayer::geometry::ViewInformation3D( + aViewInfo3D.getObjectTransformation() * aInBetweenSceneMatrix, + aViewInfo3D.getOrientation(), + aViewInfo3D.getProjection(), + aViewInfo3D.getDeviceToView(), + aViewInfo3D.getViewTime(), + aViewInfo3D.getExtendedInformationSequence()); + } + } + else + { + const uno::Sequence< beans::PropertyValue > aEmptyParameters; + o_rViewInformation3D = drawinglayer::geometry::ViewInformation3D(aEmptyParameters); + } + + return pRootScene; +} + +////////////////////////////////////////////////////////////////////////////// + +SVX_DLLPUBLIC void getAllHit3DObjectsSortedFrontToBack( + const basegfx::B2DPoint& rPoint, + const E3dScene& rScene, + ::std::vector< const E3dCompoundObject* >& o_rResult) +{ + o_rResult.clear(); + SdrObjList* pList = rScene.GetSubList(); + + if(pList && pList->GetObjCount()) + { + // prepare relative HitPoint. To do so, get the VC of the 3DScene and from there + // the Scene's 2D transformation. Multiplying with the inverse transformation + // will create a point relative to the 3D scene as unit-2d-object + const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(rScene.GetViewContact()); + basegfx::B2DHomMatrix aInverseSceneTransform(rVCScene.getObjectTransformation()); + aInverseSceneTransform.invert(); + const basegfx::B2DPoint aRelativePoint(aInverseSceneTransform * rPoint); + + // check if test point is inside scene's area at all + if(aRelativePoint.getX() >= 0.0 && aRelativePoint.getX() <= 1.0 && aRelativePoint.getY() >= 0.0 && aRelativePoint.getY() <= 1.0) + { + SdrObjListIter aIterator(*pList, IM_DEEPNOGROUPS); + ::std::vector< ImplPairDephAndObject > aDepthAndObjectResults; + const uno::Sequence< beans::PropertyValue > aEmptyParameters; + drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters); + + while(aIterator.IsMore()) + { + const E3dCompoundObject* pCandidate = dynamic_cast< const E3dCompoundObject* >(aIterator.Next()); + + if(pCandidate) + { + fillViewInformation3DForCompoundObject(aViewInfo3D, *pCandidate); + + // create HitPoint Front and Back, transform to object coordinates + basegfx::B3DHomMatrix aViewToObject(aViewInfo3D.getObjectToView()); + aViewToObject.invert(); + const basegfx::B3DPoint aFront(aViewToObject * basegfx::B3DPoint(aRelativePoint.getX(), aRelativePoint.getY(), 0.0)); + const basegfx::B3DPoint aBack(aViewToObject * basegfx::B3DPoint(aRelativePoint.getX(), aRelativePoint.getY(), 1.0)); + + if(!aFront.equal(aBack)) + { + // get all hit points with object + ::std::vector< basegfx::B3DPoint > aHitsWithObject; + getAllHit3DObjectWithRelativePoint(aFront, aBack, *pCandidate, aViewInfo3D, aHitsWithObject, false); + + for(sal_uInt32 a(0); a < aHitsWithObject.size(); a++) + { + const basegfx::B3DPoint aPointInViewCoordinates(aViewInfo3D.getObjectToView() * aHitsWithObject[a]); + aDepthAndObjectResults.push_back(ImplPairDephAndObject(pCandidate, aPointInViewCoordinates.getZ())); + } + } + } + } + + // fill nRetval + const sal_uInt32 nCount(aDepthAndObjectResults.size()); + + if(nCount) + { + // sort aDepthAndObjectResults by depth + ::std::sort(aDepthAndObjectResults.begin(), aDepthAndObjectResults.end()); + + // copy SdrObject pointers to return result set + ::std::vector< ImplPairDephAndObject >::iterator aIterator2(aDepthAndObjectResults.begin()); + + for(;aIterator2 != aDepthAndObjectResults.end(); aIterator2++) + { + o_rResult.push_back(aIterator2->getObject()); + } + } + } + } +} + +////////////////////////////////////////////////////////////////////////////// + +bool checkHitSingle3DObject( + const basegfx::B2DPoint& rPoint, + const E3dCompoundObject& rCandidate) +{ + const uno::Sequence< beans::PropertyValue > aEmptyParameters; + drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters); + E3dScene* pRootScene = fillViewInformation3DForCompoundObject(aViewInfo3D, rCandidate); + + if(pRootScene) + { + // prepare relative HitPoint. To do so, get the VC of the 3DScene and from there + // the Scene's 2D transformation. Multiplying with the inverse transformation + // will create a point relative to the 3D scene as unit-2d-object + const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pRootScene->GetViewContact()); + basegfx::B2DHomMatrix aInverseSceneTransform(rVCScene.getObjectTransformation()); + aInverseSceneTransform.invert(); + const basegfx::B2DPoint aRelativePoint(aInverseSceneTransform * rPoint); + + // check if test point is inside scene's area at all + if(aRelativePoint.getX() >= 0.0 && aRelativePoint.getX() <= 1.0 && aRelativePoint.getY() >= 0.0 && aRelativePoint.getY() <= 1.0) + { + // create HitPoint Front and Back, transform to object coordinates + basegfx::B3DHomMatrix aViewToObject(aViewInfo3D.getObjectToView()); + aViewToObject.invert(); + const basegfx::B3DPoint aFront(aViewToObject * basegfx::B3DPoint(aRelativePoint.getX(), aRelativePoint.getY(), 0.0)); + const basegfx::B3DPoint aBack(aViewToObject * basegfx::B3DPoint(aRelativePoint.getX(), aRelativePoint.getY(), 1.0)); + + if(!aFront.equal(aBack)) + { + // get all hit points with object + ::std::vector< basegfx::B3DPoint > aHitsWithObject; + getAllHit3DObjectWithRelativePoint(aFront, aBack, rCandidate, aViewInfo3D, aHitsWithObject, true); + + if(aHitsWithObject.size()) + { + return true; + } + } + } + } + + return false; +} + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/engine3d/helperminimaldepth3d.cxx b/svx/source/engine3d/helperminimaldepth3d.cxx new file mode 100644 index 000000000000..b0f774c26fda --- /dev/null +++ b/svx/source/engine3d/helperminimaldepth3d.cxx @@ -0,0 +1,212 @@ +/************************************************************************* + * + * 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_svx.hxx" + +#include <helperminimaldepth3d.hxx> +#include <drawinglayer/processor3d/baseprocessor3d.hxx> +#include <drawinglayer/primitive3d/drawinglayer_primitivetypes3d.hxx> +#include <drawinglayer/primitive3d/transformprimitive3d.hxx> +#include <drawinglayer/primitive3d/polygonprimitive3d.hxx> +#include <drawinglayer/primitive3d/polypolygonprimitive3d.hxx> +#include <svx/sdr/contact/viewcontactofe3d.hxx> +#include <svx/sdr/contact/viewcontactofe3dscene.hxx> +#include <svx/obj3d.hxx> +#include <svx/scene3d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace processor3d + { + class MinimalDephInViewExtractor : public BaseProcessor3D + { + private: + // the value which will be fetched as result + double mfMinimalDepth; + + // as tooling, the process() implementation takes over API handling and calls this + // virtual render method when the primitive implementation is BasePrimitive3D-based. + virtual void processBasePrimitive3D(const primitive3d::BasePrimitive3D& rCandidate); + + public: + MinimalDephInViewExtractor(const geometry::ViewInformation3D& rViewInformation) + : BaseProcessor3D(rViewInformation), + mfMinimalDepth(DBL_MAX) + {} + + // data access + double getMinimalDepth() const { return mfMinimalDepth; } + }; + + void MinimalDephInViewExtractor::processBasePrimitive3D(const primitive3d::BasePrimitive3D& rCandidate) + { + // it is a BasePrimitive3D implementation, use getPrimitive3DID() call for switch + switch(rCandidate.getPrimitive3DID()) + { + case PRIMITIVE3D_ID_TRANSFORMPRIMITIVE3D : + { + // transform group. Remember current transformations + const primitive3d::TransformPrimitive3D& rPrimitive = static_cast< const primitive3d::TransformPrimitive3D& >(rCandidate); + const geometry::ViewInformation3D aLastViewInformation3D(getViewInformation3D()); + + // create new transformation; add new object transform from right side + const geometry::ViewInformation3D aNewViewInformation3D( + aLastViewInformation3D.getObjectTransformation() * rPrimitive.getTransformation(), + aLastViewInformation3D.getOrientation(), + aLastViewInformation3D.getProjection(), + aLastViewInformation3D.getDeviceToView(), + aLastViewInformation3D.getViewTime(), + aLastViewInformation3D.getExtendedInformationSequence()); + updateViewInformation(aNewViewInformation3D); + + // let break down + process(rPrimitive.getChildren()); + + // restore transformations + updateViewInformation(aLastViewInformation3D); + break; + } + case PRIMITIVE3D_ID_POLYGONHAIRLINEPRIMITIVE3D : + { + // PolygonHairlinePrimitive3D + const primitive3d::PolygonHairlinePrimitive3D& rPrimitive = static_cast< const primitive3d::PolygonHairlinePrimitive3D& >(rCandidate); + const basegfx::B3DPolygon& rPolygon = rPrimitive.getB3DPolygon(); + const sal_uInt32 nCount(rPolygon.count()); + + for(sal_uInt32 a(0); a < nCount; a++) + { + const basegfx::B3DPoint aPointInView(getViewInformation3D().getObjectToView() * rPolygon.getB3DPoint(a)); + + if(aPointInView.getZ() < mfMinimalDepth) + { + mfMinimalDepth = aPointInView.getZ(); + } + } + + break; + } + case PRIMITIVE3D_ID_POLYPOLYGONMATERIALPRIMITIVE3D : + { + // PolyPolygonMaterialPrimitive3D + const primitive3d::PolyPolygonMaterialPrimitive3D& rPrimitive = static_cast< const primitive3d::PolyPolygonMaterialPrimitive3D& >(rCandidate); + const basegfx::B3DPolyPolygon& rPolyPolygon = rPrimitive.getB3DPolyPolygon(); + const sal_uInt32 nPolyCount(rPolyPolygon.count()); + + for(sal_uInt32 a(0); a < nPolyCount; a++) + { + const basegfx::B3DPolygon aPolygon(rPolyPolygon.getB3DPolygon(a)); + const sal_uInt32 nCount(aPolygon.count()); + + for(sal_uInt32 b(0); b < nCount; b++) + { + const basegfx::B3DPoint aPointInView(getViewInformation3D().getObjectToView() * aPolygon.getB3DPoint(b)); + + if(aPointInView.getZ() < mfMinimalDepth) + { + mfMinimalDepth = aPointInView.getZ(); + } + } + } + + break; + } + default : + { + // process recursively + process(rCandidate.get3DDecomposition(getViewInformation3D())); + break; + } + } + } + } // end of namespace processor3d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// changed to create values using VCs, Primitive3DSequence and ViewInformation3D to allow +// removal of old 3D bucket geometry. There is one slight difference in the result, it's +// in [0.0 .. 1.0] for Z-Depth since the scaling of the scene as 2D object is no longer +// part of the 3D transformations. This could be added since the ViewContactOfE3dScene is +// given, but is not needed since the permutation of the depth values needs only be correct +// relative to each other + +double getMinimalDepthInViewCoordinates(const E3dCompoundObject& rObject) +{ + // this is a E3dCompoundObject, so it cannot be a scene (which is a E3dObject). + // Get primitive sequence using VC + const sdr::contact::ViewContactOfE3d& rVCObject = static_cast< sdr::contact::ViewContactOfE3d& >(rObject.GetViewContact()); + const drawinglayer::primitive3d::Primitive3DSequence aPrimitives = rVCObject.getViewIndependentPrimitive3DSequence(); + double fRetval(DBL_MAX); + + if(aPrimitives.hasElements()) + { + const E3dScene* pScene = rObject.GetScene(); + + if(pScene) + { + // get ViewInformation3D from scene using VC + const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pScene->GetViewContact()); + const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D()); + + // the scene's object transformation is already part of aViewInfo3D.getObjectTransformation() + // for historical reasons (see ViewContactOfE3dScene::createViewInformation3D for more info) + // and the object's transform is part of aPrimitives (and taken into account when decomposing + // to PolygonHairlinePrimitive3D and PolyPolygonMaterialPrimitive3D). The missing part may be + // some Scene SdrObjects lying in-between which may need to be added. This is e.g. used in chart, + // and generally allowed in 3d scenes an their 3d object hierarchy + basegfx::B3DHomMatrix aInBetweenSceneMatrix; + E3dScene* pParentScene = dynamic_cast< E3dScene* >(rObject.GetParentObj()); + + while(pParentScene && pParentScene != pScene) + { + aInBetweenSceneMatrix = pParentScene->GetTransform() * aInBetweenSceneMatrix; + pParentScene = dynamic_cast< E3dScene* >(pParentScene->GetParentObj()); + } + + // build new ViewInformation containing all transforms + const drawinglayer::geometry::ViewInformation3D aNewViewInformation3D( + aViewInfo3D.getObjectTransformation() * aInBetweenSceneMatrix, + aViewInfo3D.getOrientation(), + aViewInfo3D.getProjection(), + aViewInfo3D.getDeviceToView(), + aViewInfo3D.getViewTime(), + aViewInfo3D.getExtendedInformationSequence()); + + // create extractor helper, proccess geometry and get return value + drawinglayer::processor3d::MinimalDephInViewExtractor aExtractor(aNewViewInformation3D); + aExtractor.process(aPrimitives); + fRetval = aExtractor.getMinimalDepth(); + } + } + + return fRetval; +} + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/engine3d/helperminimaldepth3d.hxx b/svx/source/engine3d/helperminimaldepth3d.hxx new file mode 100644 index 000000000000..7fa1b11a8768 --- /dev/null +++ b/svx/source/engine3d/helperminimaldepth3d.hxx @@ -0,0 +1,60 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef INCLUDED_SVX_HELPERMINIMALDEPTH_HXX +#define INCLUDED_SVX_HELPERMINIMALDEPTH_HXX + +#include <sal/types.h> + +////////////////////////////////////////////////////////////////////////////// +// predefines + +class E3dCompoundObject; +class E3dScene; + +////////////////////////////////////////////////////////////////////////////// +/** support extracting the minimal depth of a 3d object in it's scene + + @param rObject + The 3D Object from which the minimal depth needs to be calculated. The scene + is defined by the object already + + @return + The minimal depth of this object in unified ViewCoordinates. This is the + Z-Coordinate of one object point in the range of [0.0 .. 1.0]. ViewCoordinates + means the transformations (esp. rotation) of the scene are taken into account + +*/ +// support extracting the minimal depth of a 3d object in it's scene + +double getMinimalDepthInViewCoordinates(const E3dCompoundObject& rObject); + +////////////////////////////////////////////////////////////////////////////// + +#endif // INCLUDED_SVX_HELPERMINIMALDEPTH_HXX + +// eof diff --git a/svx/source/engine3d/lathe3d.cxx b/svx/source/engine3d/lathe3d.cxx new file mode 100644 index 000000000000..e6953f96f766 --- /dev/null +++ b/svx/source/engine3d/lathe3d.cxx @@ -0,0 +1,277 @@ +/************************************************************************* + * + * 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_svx.hxx" + +#include "svdstr.hrc" +#include "svdglob.hxx" +#include <tools/poly.hxx> +#include <svx/svdpage.hxx> +#include "globl3d.hxx" +#include <svx/lathe3d.hxx> +#include <svx/xpoly.hxx> +#include <svx/svxids.hrc> +#include <svx/svdopath.hxx> +#include <svx/svdmodel.hxx> +#include <svx/svx3ditems.hxx> +#include <svx/sdr/properties/e3dlatheproperties.hxx> +#include <svx/sdr/contact/viewcontactofe3dlathe.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> + +////////////////////////////////////////////////////////////////////////////// +// #110094# DrawContact section + +sdr::contact::ViewContact* E3dLatheObj::CreateObjectSpecificViewContact() +{ + return new sdr::contact::ViewContactOfE3dLathe(*this); +} + +////////////////////////////////////////////////////////////////////////////// + +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)); + } +} + +/************************************************************************* +|* +|* 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())); +} + +/************************************************************************* +|* +|* Identifier zurueckgeben +|* +\************************************************************************/ + +UINT16 E3dLatheObj::GetObjIdentifier() const +{ + return E3D_LATHEOBJ_ID; +} + +/************************************************************************* +|* +|* Zuweisungsoperator +|* +\************************************************************************/ + +void E3dLatheObj::operator=(const SdrObject& rObj) +{ + // erstmal alle Childs kopieren + E3dCompoundObject::operator=(rObj); + + // weitere Parameter kopieren + const E3dLatheObj& r3DObj = (const E3dLatheObj&)rObj; + + maPolyPoly2D = r3DObj.maPolyPoly2D; +} + +/************************************************************************* +|* +|* Wandle das Objekt in ein Gruppenobjekt bestehend aus n Polygonen +|* +\************************************************************************/ + +SdrObject *E3dLatheObj::DoConvertToPolyObj(BOOL /*bBezier*/) const +{ + return NULL; +} + +/************************************************************************* +|* +|* Neue Segmentierung (Beschreibung siehe Header-File) +|* +\************************************************************************/ + +void E3dLatheObj::ReSegment(sal_uInt32 nHSegs, sal_uInt32 nVSegs) +{ + if ((nHSegs != GetHorizontalSegments() || nVSegs != GetVerticalSegments()) && + (nHSegs != 0 || nVSegs != 0)) + { + GetProperties().SetObjectItemDirect(Svx3DHorizontalSegmentsItem(nHSegs)); + GetProperties().SetObjectItemDirect(Svx3DVerticalSegmentsItem(nVSegs)); + + ActionChanged(); + } +} + +/************************************************************************* +|* +|* Lokale Parameter setzen mit Geometrieneuerzeugung +|* +\************************************************************************/ + +void E3dLatheObj::SetPolyPoly2D(const basegfx::B2DPolyPolygon& rNew) +{ + if(maPolyPoly2D != rNew) + { + maPolyPoly2D = rNew; + 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)); + } + + ActionChanged(); + } +} + +/************************************************************************* +|* +|* Get the name of the object (singular) +|* +\************************************************************************/ + +void E3dLatheObj::TakeObjNameSingul(XubString& rName) const +{ + rName=ImpGetResStr(STR_ObjNameSingulLathe3d); + + String aName( GetName() ); + if(aName.Len()) + { + rName += sal_Unicode(' '); + rName += sal_Unicode('\''); + rName += aName; + rName += sal_Unicode('\''); + } +} + +/************************************************************************* +|* +|* Get the name of the object (plural) +|* +\************************************************************************/ + +void E3dLatheObj::TakeObjNamePlural(XubString& rName) const +{ + rName=ImpGetResStr(STR_ObjNamePluralLathe3d); +} + +/************************************************************************* +|* +|* Aufbrechen +|* +\************************************************************************/ + +BOOL E3dLatheObj::IsBreakObjPossible() +{ + return TRUE; +} + +SdrAttrObj* E3dLatheObj::GetBreakObj() +{ + // create PathObj + basegfx::B3DPolyPolygon aLathePoly3D(basegfx::tools::createB3DPolyPolygonFromB2DPolyPolygon(maPolyPoly2D)); + basegfx::B2DPolyPolygon aTransPoly(TransformToScreenCoor(aLathePoly3D)); + SdrPathObj* pPathObj = new SdrPathObj(OBJ_PLIN, aTransPoly); + + if(pPathObj) + { + // Attribute setzen + SfxItemSet aSet(GetObjectItemSet()); + + // Linien aktivieren, um Objekt garantiert sichtbar zu machen + aSet.Put(XLineStyleItem(XLINE_SOLID)); + + pPathObj->SetMergedItemSet(aSet); + } + + return pPathObj; +} + +// eof diff --git a/svx/source/engine3d/makefile.mk b/svx/source/engine3d/makefile.mk new file mode 100644 index 000000000000..6e6e3f97c550 --- /dev/null +++ b/svx/source/engine3d/makefile.mk @@ -0,0 +1,84 @@ +#************************************************************************* +# +# 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. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=svx +TARGET=engine3d +LIBTARGET=NO +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +LIB1TARGET= $(SLB)$/$(TARGET)-core.lib +LIB1OBJFILES= \ + $(SLO)$/e3dsceneupdater.obj \ + $(SLO)$/helperminimaldepth3d.obj \ + $(SLO)$/helperhittest3d.obj \ + $(SLO)$/obj3d.obj \ + $(SLO)$/scene3d.obj \ + $(SLO)$/polysc3d.obj \ + $(SLO)$/cube3d.obj \ + $(SLO)$/sphere3d.obj \ + $(SLO)$/extrud3d.obj \ + $(SLO)$/lathe3d.obj \ + $(SLO)$/polygn3d.obj \ + $(SLO)$/svx3ditems.obj \ + $(SLO)$/deflt3d.obj \ + $(SLO)$/e3dundo.obj \ + $(SLO)$/viewpt3d2.obj \ + $(SLO)$/camera3d.obj \ + $(SLO)$/objfac3d.obj \ + $(SLO)$/dragmt3d.obj \ + $(SLO)$/view3d.obj \ + $(SLO)$/view3d1.obj + +LIB2TARGET= $(SLB)$/$(TARGET).lib +LIB2OBJFILES= \ + $(SLO)$/volume3d.obj \ + $(SLO)$/viewpt3d.obj \ + $(SLO)$/float3d.obj + +SLOFILES = $(LIB1OBJFILES) $(LIB2OBJFILES) + +#disable optimizer for MSCompiler and ICC +.IF "$(COM)"=="ICC" || "$(COM)"=="MSC" +NOOPTFILES=\ + $(SLO)$/viewpt3d.obj +.ENDIF + +SRS1NAME=engine3d +SRC1FILES=\ + string3d.src \ + float3d.src + +.INCLUDE : target.mk diff --git a/svx/source/engine3d/obj3d.cxx b/svx/source/engine3d/obj3d.cxx new file mode 100644 index 000000000000..9f284d826d9f --- /dev/null +++ b/svx/source/engine3d/obj3d.cxx @@ -0,0 +1,1280 @@ +/************************************************************************* + * + * 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_svx.hxx" + +#include "svdstr.hrc" +#include "svdglob.hxx" +#include <svx/svdview.hxx> +#include <svx/svdattr.hxx> +#include <svx/svdpage.hxx> +#include <svx/svdmodel.hxx> +#include "svditer.hxx" +#include "globl3d.hxx" +#include <svx/camera3d.hxx> +#include <svx/scene3d.hxx> +#include <svx/polysc3d.hxx> +#include <svx/cube3d.hxx> +#include <svx/lathe3d.hxx> +#include <svx/sphere3d.hxx> +#include <svx/extrud3d.hxx> +#include <svx/obj3d.hxx> +#include <svx/xtable.hxx> +#include <svx/xflclit.hxx> +#include <vcl/svapp.hxx> +#include <vcl/settings.hxx> +#include <svx/xlnclit.hxx> +#include <svl/metitem.hxx> +#include <svx/xtable.hxx> +#include <svx/xfillit.hxx> +#include <svx/xlnwtit.hxx> +#include <vcl/virdev.hxx> +#include <tools/poly.hxx> +#include <tools/b3dtrans.hxx> +#include <svx/svxids.hrc> +#include <editeng/colritem.hxx> +#include <svx/e3ditem.hxx> +#include <svx/xlntrit.hxx> +#include <svx/xfltrit.hxx> +#include <svx/svdpagv.hxx> +#include <vcl/gradient.hxx> +#include <vcl/metaact.hxx> +#include <svx/svx3ditems.hxx> +#include <svl/whiter.hxx> +#include <svtools/colorcfg.hxx> +#include <editeng/eeitem.hxx> +#include <svx/xgrscit.hxx> +#include "svdoimp.hxx" +#include <svx/sdr/properties/e3dproperties.hxx> +#include <svx/sdr/properties/e3dcompoundproperties.hxx> +#include <basegfx/polygon/b3dpolypolygontools.hxx> +#include <basegfx/point/b3dpoint.hxx> +#include <basegfx/vector/b3dvector.hxx> +#include <svx/xlndsit.hxx> +#include <basegfx/matrix/b3dhommatrix.hxx> +#include <basegfx/polygon/b3dpolygon.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <basegfx/polygon/b3dpolygontools.hxx> +#include <svx/helperhittest3d.hxx> +#include <svx/sdr/contact/viewcontactofe3d.hxx> +#include <drawinglayer/geometry/viewinformation3d.hxx> +#include <com/sun/star/uno/Sequence.h> +#include <svx/sdr/contact/viewcontactofe3dscene.hxx> +#include <basegfx/polygon/b3dpolypolygontools.hxx> +#include <svx/e3dsceneupdater.hxx> + +#define ITEMVALUE(ItemSet,Id,Cast) ((const Cast&)(ItemSet).Get(Id)).GetValue() + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +/************************************************************************* +|* +|* Liste fuer 3D-Objekte +|* +\************************************************************************/ + +TYPEINIT1(E3dObjList, SdrObjList); + +E3dObjList::E3dObjList(SdrModel* pNewModel, SdrPage* pNewPage, E3dObjList* pNewUpList) +: SdrObjList(pNewModel, pNewPage, pNewUpList) +{ +} + +E3dObjList::E3dObjList(const E3dObjList& rSrcList) +: SdrObjList(rSrcList) +{ +} + +E3dObjList::~E3dObjList() +{ +} + +void E3dObjList::NbcInsertObject(SdrObject* pObj, ULONG nPos, const SdrInsertReason* pReason) +{ + // Owner holen + DBG_ASSERT(GetOwnerObj()->ISA(E3dObject), "AW: Einfuegen 3DObject in Parent != 3DObject"); + + // Ist es ueberhaupt ein 3D-Objekt? + if(pObj && pObj->ISA(E3dObject)) + { + // Normales 3D Objekt, einfuegen mittels + // call parent + SdrObjList::NbcInsertObject(pObj, nPos, pReason); + } + else + { + // Kein 3D Objekt, fuege in Seite statt in Szene ein... + GetOwnerObj()->GetPage()->InsertObject(pObj, nPos); + } +} + +void E3dObjList::InsertObject(SdrObject* pObj, ULONG nPos, const SdrInsertReason* pReason) +{ + OSL_ENSURE(GetOwnerObj()->ISA(E3dObject), "Insert 3DObject in non-3D Parent"); + //E3DModifySceneSnapRectUpdater aUpdater(GetOwnerObj()); + + // call parent + SdrObjList::InsertObject(pObj, nPos, pReason); + + E3dScene* pScene = ((E3dObject*)GetOwnerObj())->GetScene(); + if(pScene) + { + pScene->Cleanup3DDepthMapper(); + } +} + +SdrObject* E3dObjList::NbcRemoveObject(ULONG nObjNum) +{ + DBG_ASSERT(GetOwnerObj()->ISA(E3dObject), "AW: Entfernen 3DObject aus Parent != 3DObject"); + //E3DModifySceneSnapRectUpdater aUpdater(GetOwnerObj()); + + // call parent + SdrObject* pRetval = SdrObjList::NbcRemoveObject(nObjNum); + + E3dScene* pScene = ((E3dObject*)GetOwnerObj())->GetScene(); + if(pScene) + { + pScene->Cleanup3DDepthMapper(); + } + + return pRetval; +} + +SdrObject* E3dObjList::RemoveObject(ULONG nObjNum) +{ + OSL_ENSURE(GetOwnerObj()->ISA(E3dObject), "3DObject is removed from non-3D Parent"); + //E3DModifySceneSnapRectUpdater aUpdater(GetOwnerObj()); + + // call parent + SdrObject* pRetval = SdrObjList::RemoveObject(nObjNum); + + E3dScene* pScene = ((E3dObject*)GetOwnerObj())->GetScene(); + if(pScene) + { + pScene->Cleanup3DDepthMapper(); + } + + return pRetval; +} + +/************************************************************************* +|* +|* Konstruktor +|* +\************************************************************************/ + +////////////////////////////////////////////////////////////////////////////// + +sdr::properties::BaseProperties* E3dObject::CreateObjectSpecificProperties() +{ + return new sdr::properties::E3dProperties(*this); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +TYPEINIT1(E3dObject, SdrAttrObj); + +E3dObject::E3dObject() +: maSubList(), + maLocalBoundVol(), + maTransformation(), + maFullTransform(), + mbTfHasChanged(true), + mbIsSelected(false) +{ + bIs3DObj = true; + maSubList.SetOwnerObj(this); + maSubList.SetListKind(SDROBJLIST_GROUPOBJ); + bClosedObj = true; +} + +/************************************************************************* +|* +|* Destruktor +|* +\************************************************************************/ + +E3dObject::~E3dObject() +{ +} + +/************************************************************************* +|* +|* Selektions-Flag setzen +|* +\************************************************************************/ + +void E3dObject::SetSelected(bool bNew) +{ + if((bool)mbIsSelected != bNew) + { + mbIsSelected = bNew; + } + + for(sal_uInt32 a(0); a < maSubList.GetObjCount(); a++) + { + E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a)); + + if(pCandidate) + { + pCandidate->SetSelected(bNew); + } + } +} + +/************************************************************************* +|* +|* Aufbrechen, default-Implementierungen +|* +\************************************************************************/ + +BOOL E3dObject::IsBreakObjPossible() +{ + return FALSE; +} + +SdrAttrObj* E3dObject::GetBreakObj() +{ + return 0L; +} + +/************************************************************************* +|* +|* SetRectsDirty muss ueber die lokale SdrSubList gehen +|* +\************************************************************************/ + +void E3dObject::SetRectsDirty(sal_Bool bNotMyself) +{ + // call parent + SdrAttrObj::SetRectsDirty(bNotMyself); + + for(sal_uInt32 a(0); a < maSubList.GetObjCount(); a++) + { + E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a)); + + if(pCandidate) + { + pCandidate->SetRectsDirty(bNotMyself); + } + } +} + +/************************************************************************* +|* +|* Inventor zurueckgeben +|* +\************************************************************************/ + +UINT32 E3dObject::GetObjInventor() const +{ + return E3dInventor; +} + +/************************************************************************* +|* +|* Identifier zurueckgeben +|* +\************************************************************************/ + +UINT16 E3dObject::GetObjIdentifier() const +{ + return E3D_OBJECT_ID; +} + +/************************************************************************* +|* +|* Faehigkeiten des Objektes feststellen +|* +\************************************************************************/ + +void E3dObject::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const +{ + rInfo.bResizeFreeAllowed = TRUE; + rInfo.bResizePropAllowed = TRUE; + rInfo.bRotateFreeAllowed = TRUE; + rInfo.bRotate90Allowed = TRUE; + rInfo.bMirrorFreeAllowed = FALSE; + rInfo.bMirror45Allowed = FALSE; + rInfo.bMirror90Allowed = FALSE; + rInfo.bShearAllowed = FALSE; + rInfo.bEdgeRadiusAllowed = FALSE; + rInfo.bCanConvToPath = FALSE; + + // no transparence for 3d objects + rInfo.bTransparenceAllowed = FALSE; + + // gradient depends on fillstyle + // BM *** check if SetItem is NULL *** + XFillStyle eFillStyle = ((XFillStyleItem&)(GetMergedItem(XATTR_FILLSTYLE))).GetValue(); + rInfo.bGradientAllowed = (eFillStyle == XFILL_GRADIENT); + + // Umwandeln von 3D-Koerpern in Gruppe von Polygonen: + // + // Erst mal nicht moeglich, da die Erzeugung einer Gruppe von + // 2D-Polygonen notwendig waere, die tiefensortiert werden muessten, + // also bei Durchdringugnen auch gegeneinander geschnitten werden + // muessten. Auch die Texturkoorinaten waeren ein ungeloestes + // Problem. + rInfo.bCanConvToPoly = FALSE; + rInfo.bCanConvToContour = FALSE; + rInfo.bCanConvToPathLineToArea = FALSE; + rInfo.bCanConvToPolyLineToArea = FALSE; +} + +/************************************************************************* +|* +|* Layer setzen +|* +\************************************************************************/ + +void E3dObject::NbcSetLayer(SdrLayerID nLayer) +{ + SdrAttrObj::NbcSetLayer(nLayer); + + for(sal_uInt32 a(0); a < maSubList.GetObjCount(); a++) + { + E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a)); + + if(pCandidate) + { + pCandidate->NbcSetLayer(nLayer); + } + } +} + +/************************************************************************* +|* +|* ObjList auch an SubList setzen +|* +\************************************************************************/ + +void E3dObject::SetObjList(SdrObjList* pNewObjList) +{ + SdrObject::SetObjList(pNewObjList); + maSubList.SetUpList(pNewObjList); +} + +/************************************************************************* +|* +|* Layer setzen +|* +\************************************************************************/ + +void E3dObject::SetPage(SdrPage* pNewPage) +{ + SdrAttrObj::SetPage(pNewPage); + maSubList.SetPage(pNewPage); +} + +/************************************************************************* +|* +|* Layer setzen +|* +\************************************************************************/ + +void E3dObject::SetModel(SdrModel* pNewModel) +{ + SdrAttrObj::SetModel(pNewModel); + maSubList.SetModel(pNewModel); +} + +/************************************************************************* +|* +|* resize object, used from old 2d interfaces, e.g. in Move/Scale dialog +|* (F4) +|* +\************************************************************************/ +void E3dObject::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact) +{ + // Bewegung in X,Y im Augkoordinatensystem + E3dScene* pScene = GetScene(); + + if(pScene) + { + // transform pos from 2D world to 3D eye + const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pScene->GetViewContact()); + const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D()); + basegfx::B2DPoint aScaleCenter2D((double)rRef.X(), (double)rRef.Y()); + basegfx::B2DHomMatrix aInverseSceneTransform(rVCScene.getObjectTransformation()); + + aInverseSceneTransform.invert(); + aScaleCenter2D = aInverseSceneTransform * aScaleCenter2D; + + basegfx::B3DPoint aScaleCenter3D(aScaleCenter2D.getX(), aScaleCenter2D.getY(), 0.5); + basegfx::B3DHomMatrix aInverseViewToEye(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection()); + + aInverseViewToEye.invert(); + aScaleCenter3D = aInverseViewToEye * aScaleCenter3D; + + // scale-faktoren holen + double fScaleX(xFact); + double fScaleY(yFact); + + // build transform + basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation()); + aInverseOrientation.invert(); + basegfx::B3DHomMatrix mFullTransform(GetFullTransform()); + basegfx::B3DHomMatrix mTrans(mFullTransform); + + mTrans *= aViewInfo3D.getOrientation(); + mTrans.translate(-aScaleCenter3D.getX(), -aScaleCenter3D.getY(), -aScaleCenter3D.getZ()); + mTrans.scale(fScaleX, fScaleY, 1.0); + mTrans.translate(aScaleCenter3D.getX(), aScaleCenter3D.getY(), aScaleCenter3D.getZ()); + mTrans *= aInverseOrientation; + mFullTransform.invert(); + mTrans *= mFullTransform; + + // anwenden + basegfx::B3DHomMatrix mObjTrans(GetTransform()); + mObjTrans *= mTrans; + + E3DModifySceneSnapRectUpdater aUpdater(this); + SetTransform(mObjTrans); + } +} + +/************************************************************************* +|* +|* Objekt verschieben in 2D, wird bei Cursortasten benoetigt +|* +\************************************************************************/ +void E3dObject::NbcMove(const Size& rSize) +{ + // Bewegung in X,Y im Augkoordinatensystem + E3dScene* pScene = GetScene(); + + if(pScene) + { + // Abmessungen der Szene in 3D und 2D als Vergleich + Rectangle aRect = pScene->GetSnapRect(); + + // Transformation Weltkoordinaten bis eine VOR Objektkoordinaten holen + basegfx::B3DHomMatrix mInvDispTransform; + if(GetParentObj()) + { + mInvDispTransform = GetParentObj()->GetFullTransform(); + mInvDispTransform.invert(); + } + + // BoundVolume from 3d world to 3d eye + const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pScene->GetViewContact()); + const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D()); + basegfx::B3DRange aEyeVol(pScene->GetBoundVolume()); + aEyeVol.transform(aViewInfo3D.getOrientation()); + + // build relative movement vector in eye coordinates + basegfx::B3DPoint aMove( + (double)rSize.Width() * aEyeVol.getWidth() / (double)aRect.GetWidth(), + (double)-rSize.Height() * aEyeVol.getHeight() / (double)aRect.GetHeight(), + 0.0); + basegfx::B3DPoint aPos(0.0, 0.0, 0.0); + + // movement vektor to local coordinates of objects' parent + basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation()); + aInverseOrientation.invert(); + basegfx::B3DHomMatrix aCompleteTrans(mInvDispTransform * aInverseOrientation); + + aMove = aCompleteTrans * aMove; + aPos = aCompleteTrans * aPos; + + // build transformation and apply + basegfx::B3DHomMatrix aTranslate; + aTranslate.translate(aMove.getX() - aPos.getX(), aMove.getY() - aPos.getY(), aMove.getZ() - aPos.getZ()); + + E3DModifySceneSnapRectUpdater aUpdater(pScene); + SetTransform(aTranslate * GetTransform()); + } +} + +/************************************************************************* +|* +|* liefere die Sublist, aber nur dann, wenn darin Objekte enthalten sind ! +|* +\************************************************************************/ + +SdrObjList* E3dObject::GetSubList() const +{ + return &(const_cast< E3dObjList& >(maSubList)); +} + +/************************************************************************* +|* +|* SnapRect berechnen +|* +\************************************************************************/ + +void E3dObject::RecalcSnapRect() +{ + maSnapRect = Rectangle(); + + for(sal_uInt32 a(0); a < maSubList.GetObjCount(); a++) + { + E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a)); + + if(pCandidate) + { + maSnapRect.Union(pCandidate->GetSnapRect()); + } + } +} + +/************************************************************************* +|* +|* Einfuegen eines 3D-Objekts an den Parent weitermelden, damit dieser +|* ggf. eine Sonderbehandlung fuer spezielle Objekte durchfuehren kann +|* (z.B. Light/Label in E3dScene) +|* +\************************************************************************/ + +void E3dObject::NewObjectInserted(const E3dObject* p3DObj) +{ + if(GetParentObj()) + GetParentObj()->NewObjectInserted(p3DObj); +} + +/************************************************************************* +|* +|* Parent ueber Aenderung der Struktur (z.B. durch Transformation) +|* informieren; dabei wird das Objekt, in welchem die Aenderung +|* aufgetreten ist, uebergeben +|* +\************************************************************************/ + +void E3dObject::StructureChanged() +{ + if ( GetParentObj() ) + { + GetParentObj()->InvalidateBoundVolume(); + GetParentObj()->StructureChanged(); + } +} + +/************************************************************************* +|* +|* 3D-Objekt einfuegen +|* +\************************************************************************/ + +void E3dObject::Insert3DObj(E3dObject* p3DObj) +{ + DBG_ASSERT(p3DObj, "Insert3DObj mit NULL-Zeiger!"); + SdrPage* pPg = pPage; + maSubList.InsertObject(p3DObj); + pPage = pPg; + InvalidateBoundVolume(); + NewObjectInserted(p3DObj); + StructureChanged(); +} + +void E3dObject::Remove3DObj(E3dObject* p3DObj) +{ + DBG_ASSERT(p3DObj, "Remove3DObj mit NULL-Zeiger!"); + + if(p3DObj->GetParentObj() == this) + { + SdrPage* pPg = pPage; + maSubList.RemoveObject(p3DObj->GetOrdNum()); + pPage = pPg; + + InvalidateBoundVolume(); + StructureChanged(); + } +} + +/************************************************************************* +|* +|* Parent holen +|* +\************************************************************************/ + +E3dObject* E3dObject::GetParentObj() const +{ + E3dObject* pRetval = NULL; + + if(GetObjList() + && GetObjList()->GetOwnerObj() + && GetObjList()->GetOwnerObj()->ISA(E3dObject)) + pRetval = ((E3dObject*)GetObjList()->GetOwnerObj()); + return pRetval; +} + +/************************************************************************* +|* +|* Uebergeordnetes Szenenobjekt bestimmen +|* +\************************************************************************/ + +E3dScene* E3dObject::GetScene() const +{ + if(GetParentObj()) + return GetParentObj()->GetScene(); + return NULL; +} + +/************************************************************************* +|* +|* umschliessendes Volumen inklusive aller Kindobjekte berechnen +|* +\************************************************************************/ + +basegfx::B3DRange E3dObject::RecalcBoundVolume() const +{ + basegfx::B3DRange aRetval; + const sal_uInt32 nObjCnt(maSubList.GetObjCount()); + + if(nObjCnt) + { + for(sal_uInt32 a(0); a < nObjCnt; a++) + { + const E3dObject* p3DObject = dynamic_cast< const E3dObject* >(maSubList.GetObj(a)); + + if(p3DObject) + { + basegfx::B3DRange aLocalRange(p3DObject->GetBoundVolume()); + aLocalRange.transform(p3DObject->GetTransform()); + aRetval.expand(aLocalRange); + } + } + } + else + { + // single 3D object + const sdr::contact::ViewContactOfE3d* pVCOfE3D = dynamic_cast< const sdr::contact::ViewContactOfE3d* >(&GetViewContact()); + + if(pVCOfE3D) + { + // BoundVolume is without 3D object transformation, use correct sequence + const drawinglayer::primitive3d::Primitive3DSequence xLocalSequence(pVCOfE3D->getVIP3DSWithoutObjectTransform()); + + if(xLocalSequence.hasElements()) + { + const uno::Sequence< beans::PropertyValue > aEmptyParameters; + const drawinglayer::geometry::ViewInformation3D aLocalViewInformation3D(aEmptyParameters); + + aRetval = drawinglayer::primitive3d::getB3DRangeFromPrimitive3DSequence( + xLocalSequence, aLocalViewInformation3D); + } + } + } + + return aRetval; +} + +/************************************************************************* +|* +|* umschliessendes Volumen zurueckgeben und ggf. neu berechnen +|* +\************************************************************************/ + +const basegfx::B3DRange& E3dObject::GetBoundVolume() const +{ + if(maLocalBoundVol.isEmpty()) + { + const_cast< E3dObject* >(this)->maLocalBoundVol = RecalcBoundVolume(); + } + + return maLocalBoundVol; +} + +void E3dObject::InvalidateBoundVolume() +{ + maLocalBoundVol.reset(); +} + +/************************************************************************* +|* +|* Aederung des BoundVolumes an alle Kindobjekte weitergeben +|* +\************************************************************************/ + +void E3dObject::SetBoundVolInvalid() +{ + InvalidateBoundVolume(); + + for(sal_uInt32 a(0); a < maSubList.GetObjCount(); a++) + { + E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a)); + + if(pCandidate) + { + pCandidate->SetBoundVolInvalid(); + } + } +} + +/************************************************************************* +|* +|* Aederung der Transformation an alle Kindobjekte weitergeben +|* +\************************************************************************/ + +void E3dObject::SetTransformChanged() +{ + InvalidateBoundVolume(); + mbTfHasChanged = true; + + for(sal_uInt32 a(0); a < maSubList.GetObjCount(); a++) + { + E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a)); + + if(pCandidate) + { + pCandidate->SetTransformChanged(); + } + } +} + +/************************************************************************* +|* +|* hierarchische Transformation ueber alle Parents bestimmen, in +|* maFullTransform ablegen und diese zurueckgeben +|* +\************************************************************************/ + +const basegfx::B3DHomMatrix& E3dObject::GetFullTransform() const +{ + if(mbTfHasChanged) + { + basegfx::B3DHomMatrix aNewFullTransformation(maTransformation); + + if ( GetParentObj() ) + { + aNewFullTransformation = GetParentObj()->GetFullTransform() * aNewFullTransformation; + } + + const_cast< E3dObject* >(this)->maFullTransform = aNewFullTransformation; + const_cast< E3dObject* >(this)->mbTfHasChanged = false; + } + + return maFullTransform; +} + +/************************************************************************* +|* +|* Transformationsmatrix abfragen +|* +\************************************************************************/ + +const basegfx::B3DHomMatrix& E3dObject::GetTransform() const +{ + return maTransformation; +} + +/************************************************************************* +|* +|* Transformationsmatrix setzen +|* +\************************************************************************/ + +void E3dObject::NbcSetTransform(const basegfx::B3DHomMatrix& rMatrix) +{ + if(maTransformation != rMatrix) + { + maTransformation = rMatrix; + SetTransformChanged(); + StructureChanged(); + } +} + +/************************************************************************* +|* +|* Transformationsmatrix setzen mit Repaint-Broadcast +|* +\************************************************************************/ + +void E3dObject::SetTransform(const basegfx::B3DHomMatrix& rMatrix) +{ + if(rMatrix != maTransformation) + { + // #110094#-14 SendRepaintBroadcast(); + NbcSetTransform(rMatrix); + SetChanged(); + BroadcastObjectChange(); + if (pUserCall != NULL) pUserCall->Changed(*this, SDRUSERCALL_RESIZE, Rectangle()); + } +} + +/************************************************************************* +|* +|* Linien fuer die Wireframe-Darstellung des Objekts dem uebergebenen +|* basegfx::B3DPolygon hinzufuegen +|* +\************************************************************************/ + +basegfx::B3DPolyPolygon E3dObject::CreateWireframe() const +{ + const basegfx::B3DRange aBoundVolume(GetBoundVolume()); + return basegfx::tools::createCubePolyPolygonFromB3DRange(aBoundVolume); +} + +/************************************************************************* +|* +|* Get the name of the object (singular) +|* +\************************************************************************/ + +void E3dObject::TakeObjNameSingul(XubString& rName) const +{ + rName=ImpGetResStr(STR_ObjNameSingulObj3d); + + String aName( GetName() ); + if(aName.Len()) + { + rName += sal_Unicode(' '); + rName += sal_Unicode('\''); + rName += aName; + rName += sal_Unicode('\''); + } +} + +/************************************************************************* +|* +|* Get the name of the object (plural) +|* +\************************************************************************/ + +void E3dObject::TakeObjNamePlural(XubString& rName) const +{ + rName=ImpGetResStr(STR_ObjNamePluralObj3d); +} + +/************************************************************************* +|* +|* Zuweisungsoperator +|* +\************************************************************************/ + +void E3dObject::operator=(const SdrObject& rObj) +{ + SdrObject::operator=(rObj); + + const E3dObject& r3DObj = (const E3dObject&) rObj; + if (r3DObj.GetSubList()) + { + maSubList.CopyObjects(*r3DObj.GetSubList()); + } + + // BoundVol kann uebernommen werden, da die Childs auch kopiert werden + maLocalBoundVol = r3DObj.maLocalBoundVol; + maTransformation = r3DObj.maTransformation; + + // Da sich der Parent geaendert haben kann, Gesamttransformation beim + // naechsten Mal auf jeden Fall neu bestimmen + SetTransformChanged(); + + // Selektionsstatus kopieren + mbIsSelected = r3DObj.mbIsSelected; +} + +/************************************************************************* +|* +|* erstelle neues GeoData-Objekt +|* +\************************************************************************/ + +SdrObjGeoData *E3dObject::NewGeoData() const +{ + // Theoretisch duerfen auch nur Szenen ihre GeoDatas erstellen und verwalten !! + // AW: Dies stimmt nicht mehr, diese Stelle ist mit der neuen Engine OK! + return new E3DObjGeoData; +} + +/************************************************************************* +|* +|* uebergebe aktuelle werte an das GeoData-Objekt +|* +\************************************************************************/ + +void E3dObject::SaveGeoData(SdrObjGeoData& rGeo) const +{ + SdrAttrObj::SaveGeoData (rGeo); + + ((E3DObjGeoData &) rGeo).maLocalBoundVol = maLocalBoundVol; + ((E3DObjGeoData &) rGeo).maTransformation = maTransformation; +} + +/************************************************************************* +|* +|* uebernehme werte aus dem GeoData-Objekt +|* +\************************************************************************/ + +void E3dObject::RestGeoData(const SdrObjGeoData& rGeo) +{ + maLocalBoundVol = ((E3DObjGeoData &) rGeo).maLocalBoundVol; + E3DModifySceneSnapRectUpdater aUpdater(this); + NbcSetTransform(((E3DObjGeoData &) rGeo).maTransformation); + SdrAttrObj::RestGeoData (rGeo); +} + +/************************************************************************* +|* +|* Rotation eines 3d-Koerpers +|* +\************************************************************************/ +// 2D-rotation eines 3D-Koerpers, normalerweise macht das die Szene selbst +// Ist aber eine korrekte Implementierung, denn alles was passiert ist eine +// Rotation um die Achse die senkrecht auf dem Bildschirm steht und zwar +// unabhaengig davon, wie die Szene bisher gedreht worden ist. + +void E3dObject::NbcRotate(const Point& rRef, long nWink, double sn, double cs) +{ + // Also derzeit sind die Klebepunkte relativ zum aOutRect der Szene definiert. Vor dem Drehen + // werden die Klebepunkte relativ zur Seite definiert. Sie nehmen an der Drehung der Szene noch nicht Teil + // dafuer gibt es den + SetGlueReallyAbsolute(TRUE); + + // SendRepaintBroadcast(); + double fWinkelInRad = nWink/100 * F_PI180; + + basegfx::B3DHomMatrix aRotateZ; + aRotateZ.rotate(0.0, 0.0, fWinkelInRad); + NbcSetTransform(aRotateZ * GetTransform()); + + SetRectsDirty(); // Veranlasst eine Neuberechnung aller BoundRects + NbcRotateGluePoints(rRef,nWink,sn,cs); // Rotiert die Klebepunkte (die haben noch Koordinaten relativ + // zum Urpsung des Blattes + SetGlueReallyAbsolute(FALSE); // ab jetzt sind sie wieder relativ zum BoundRect (also dem aOutRect definiert) +} + +/*************************************************************************/ + +////////////////////////////////////////////////////////////////////////////// + +sdr::properties::BaseProperties* E3dCompoundObject::CreateObjectSpecificProperties() +{ + return new sdr::properties::E3dCompoundProperties(*this); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +TYPEINIT1(E3dCompoundObject, E3dObject); + +/************************************************************************* +|* +|* Konstruktor +|* +\************************************************************************/ + +E3dCompoundObject::E3dCompoundObject() +: E3dObject(), + aMaterialAmbientColor(), + bCreateNormals(false), + bCreateTexture(false) +{ + // Defaults setzen + E3dDefaultAttributes aDefault; + SetDefaultAttributes(aDefault); +} + +E3dCompoundObject::E3dCompoundObject(E3dDefaultAttributes& rDefault) +: E3dObject(), + aMaterialAmbientColor(), + bCreateNormals(false), + bCreateTexture(false) +{ + // Defaults setzen + SetDefaultAttributes(rDefault); +} + +void E3dCompoundObject::SetDefaultAttributes(E3dDefaultAttributes& rDefault) +{ + // Defaults setzen + aMaterialAmbientColor = rDefault.GetDefaultAmbientColor(); + + bCreateNormals = rDefault.GetDefaultCreateNormals(); + bCreateTexture = rDefault.GetDefaultCreateTexture(); +} + +/************************************************************************* +|* +|* Destruktor +|* +\************************************************************************/ + +E3dCompoundObject::~E3dCompoundObject () +{ +} + +/************************************************************************* +|* +|* Drag-Polygon zurueckgeben +|* +\************************************************************************/ + +basegfx::B2DPolyPolygon E3dCompoundObject::TakeXorPoly() const +{ + basegfx::B2DPolyPolygon aRetval; + const uno::Sequence< beans::PropertyValue > aEmptyParameters; + drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters); + E3dScene* pRootScene = fillViewInformation3DForCompoundObject(aViewInfo3D, *this); + + if(pRootScene) + { + const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pRootScene->GetViewContact()); + const basegfx::B3DPolyPolygon aCubePolyPolygon(CreateWireframe()); + aRetval = basegfx::tools::createB2DPolyPolygonFromB3DPolyPolygon(aCubePolyPolygon, + aViewInfo3D.getObjectToView() * GetTransform()); + aRetval.transform(rVCScene.getObjectTransformation()); + } + + return aRetval; +} + +/************************************************************************* +|* +|* Anzahl der Handles zurueckgeben +|* +\************************************************************************/ + +sal_uInt32 E3dCompoundObject::GetHdlCount() const +{ + // 8 Eckpunkte + 1 E3dVolumeMarker (= Wireframe-Darstellung) + return 9L; +} + +/************************************************************************* +|* +|* Handle-Liste fuellen +|* +\************************************************************************/ + +void E3dCompoundObject::AddToHdlList(SdrHdlList& rHdlList) const +{ + const uno::Sequence< beans::PropertyValue > aEmptyParameters; + drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters); + E3dScene* pRootScene = fillViewInformation3DForCompoundObject(aViewInfo3D, *this); + + if(pRootScene) + { + const basegfx::B3DRange aBoundVolume(GetBoundVolume()); + + if(!aBoundVolume.isEmpty()) + { + const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pRootScene->GetViewContact()); + + for(sal_uInt32 a(0); a < 8; a++) + { + basegfx::B3DPoint aPos3D; + + switch(a) + { + case 0 : aPos3D.setX(aBoundVolume.getMinX()); aPos3D.setY(aBoundVolume.getMinY()); aPos3D.setZ(aBoundVolume.getMinZ()); break; + case 1 : aPos3D.setX(aBoundVolume.getMinX()); aPos3D.setY(aBoundVolume.getMinY()); aPos3D.setZ(aBoundVolume.getMaxZ()); break; + case 2 : aPos3D.setX(aBoundVolume.getMinX()); aPos3D.setY(aBoundVolume.getMaxY()); aPos3D.setZ(aBoundVolume.getMinZ()); break; + case 3 : aPos3D.setX(aBoundVolume.getMinX()); aPos3D.setY(aBoundVolume.getMaxY()); aPos3D.setZ(aBoundVolume.getMaxZ()); break; + case 4 : aPos3D.setX(aBoundVolume.getMaxX()); aPos3D.setY(aBoundVolume.getMinY()); aPos3D.setZ(aBoundVolume.getMinZ()); break; + case 5 : aPos3D.setX(aBoundVolume.getMaxX()); aPos3D.setY(aBoundVolume.getMinY()); aPos3D.setZ(aBoundVolume.getMaxZ()); break; + case 6 : aPos3D.setX(aBoundVolume.getMaxX()); aPos3D.setY(aBoundVolume.getMaxY()); aPos3D.setZ(aBoundVolume.getMinZ()); break; + case 7 : aPos3D.setX(aBoundVolume.getMaxX()); aPos3D.setY(aBoundVolume.getMaxY()); aPos3D.setZ(aBoundVolume.getMaxZ()); break; + } + + // to 3d view coor + aPos3D *= aViewInfo3D.getObjectToView() * GetTransform(); + + // create 2d relative scene + basegfx::B2DPoint aPos2D(aPos3D.getX(), aPos3D.getY()); + + // to 2d world coor + aPos2D *= rVCScene.getObjectTransformation(); + + rHdlList.AddHdl(new SdrHdl(Point(basegfx::fround(aPos2D.getX()), basegfx::fround(aPos2D.getY())), HDL_BWGT)); + } + } + } + + const basegfx::B2DPolyPolygon aPolyPolygon(TakeXorPoly()); + + if(aPolyPolygon.count()) + { + E3dVolumeMarker* pVolMarker = new E3dVolumeMarker(aPolyPolygon); + rHdlList.AddHdl(pVolMarker); + } +} + +/************************************************************************* +|* +|* Identifier zurueckgeben +|* +\************************************************************************/ + +UINT16 E3dCompoundObject::GetObjIdentifier() const +{ + return E3D_COMPOUNDOBJ_ID; +} + +/************************************************************************* +|* +|* SnapRect berechnen +|* +\************************************************************************/ + +void E3dCompoundObject::RecalcSnapRect() +{ + const uno::Sequence< beans::PropertyValue > aEmptyParameters; + drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters); + E3dScene* pRootScene = fillViewInformation3DForCompoundObject(aViewInfo3D, *this); + maSnapRect = Rectangle(); + + if(pRootScene) + { + // get VC of 3D candidate + const sdr::contact::ViewContactOfE3d* pVCOfE3D = dynamic_cast< const sdr::contact::ViewContactOfE3d* >(&GetViewContact()); + + if(pVCOfE3D) + { + // get 3D primitive sequence + const drawinglayer::primitive3d::Primitive3DSequence xLocalSequence(pVCOfE3D->getViewIndependentPrimitive3DSequence()); + + if(xLocalSequence.hasElements()) + { + // get BoundVolume + basegfx::B3DRange aBoundVolume(drawinglayer::primitive3d::getB3DRangeFromPrimitive3DSequence( + xLocalSequence, aViewInfo3D)); + + // transform bound volume to relative scene coordinates + aBoundVolume.transform(aViewInfo3D.getObjectToView()); + + // build 2d relative scene range + basegfx::B2DRange aSnapRange( + aBoundVolume.getMinX(), aBoundVolume.getMinY(), + aBoundVolume.getMaxX(), aBoundVolume.getMaxY()); + + // transform to 2D world coordiantes + const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pRootScene->GetViewContact()); + aSnapRange.transform(rVCScene.getObjectTransformation()); + + // snap to integer + maSnapRect = Rectangle( + sal_Int32(floor(aSnapRange.getMinX())), sal_Int32(floor(aSnapRange.getMinY())), + sal_Int32(ceil(aSnapRange.getMaxX())), sal_Int32(ceil(aSnapRange.getMaxY()))); + } + } + } +} + +/************************************************************************* +|* +|* Copy-Operator +|* +\************************************************************************/ + +void E3dCompoundObject::operator=(const SdrObject& rObj) +{ + // erstmal alle Childs kopieren + E3dObject::operator=(rObj); + + // weitere Parameter kopieren + const E3dCompoundObject& r3DObj = (const E3dCompoundObject&) rObj; + + bCreateNormals = r3DObj.bCreateNormals; + bCreateTexture = r3DObj.bCreateTexture; + aMaterialAmbientColor = r3DObj.aMaterialAmbientColor; +} + +/************************************************************************* +|* +|* Parameter Geometrieerzeugung setzen +|* +\************************************************************************/ + +void E3dCompoundObject::SetCreateNormals(BOOL bNew) +{ + if(bCreateNormals != bNew) + { + bCreateNormals = bNew; + ActionChanged(); + } +} + +void E3dCompoundObject::SetCreateTexture(BOOL bNew) +{ + if(bCreateTexture != bNew) + { + bCreateTexture = bNew; + ActionChanged(); + } +} + +/************************************************************************* +|* +|* Material des Objektes +|* +\************************************************************************/ + +void E3dCompoundObject::SetMaterialAmbientColor(const Color& rColor) +{ + if(aMaterialAmbientColor != rColor) + { + aMaterialAmbientColor = rColor; + } +} + +/************************************************************************* +|* +|* convert given basegfx::B3DPolyPolygon to screen coor +|* +\************************************************************************/ + +basegfx::B2DPolyPolygon E3dCompoundObject::TransformToScreenCoor(const basegfx::B3DPolyPolygon& rCandidate) +{ + const uno::Sequence< beans::PropertyValue > aEmptyParameters; + drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters); + E3dScene* pRootScene = fillViewInformation3DForCompoundObject(aViewInfo3D, *this); + basegfx::B2DPolyPolygon aRetval; + + if(pRootScene) + { + aRetval = basegfx::tools::createB2DPolyPolygonFromB3DPolyPolygon(rCandidate, + aViewInfo3D.getObjectToView() * GetTransform()); + const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pRootScene->GetViewContact()); + aRetval.transform(rVCScene.getObjectTransformation()); + } + + return aRetval; +} + +sal_Bool E3dCompoundObject::IsAOrdNumRemapCandidate(E3dScene*& prScene) const +{ + if(GetObjList() + && GetObjList()->GetOwnerObj() + && GetObjList()->GetOwnerObj()->ISA(E3dScene)) + { + prScene = (E3dScene*)GetObjList()->GetOwnerObj(); + return sal_True; + } + + return sal_False; +} + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/engine3d/objfac3d.cxx b/svx/source/engine3d/objfac3d.cxx new file mode 100644 index 000000000000..3b06b249558e --- /dev/null +++ b/svx/source/engine3d/objfac3d.cxx @@ -0,0 +1,110 @@ +/************************************************************************* + * + * 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_svx.hxx" +#include <svx/svdpage.hxx> +#include "globl3d.hxx" +#include <svx/polysc3d.hxx> +#include <svx/cube3d.hxx> +#include <svx/sphere3d.hxx> +#include <svx/extrud3d.hxx> +#include <svx/lathe3d.hxx> +#include <svx/polygn3d.hxx> +#include "objfac3d.hxx" +#include <svx/svdobj.hxx> + +/************************************************************************* +|* +|* Konstruktor +|* +\************************************************************************/ + +static BOOL bInit = FALSE; + +E3dObjFactory::E3dObjFactory() +{ + if ( !bInit ) + { + SdrObjFactory::InsertMakeObjectHdl(LINK(this, E3dObjFactory, MakeObject)); + bInit = TRUE; + } +} + +/************************************************************************* +|* +|* Destruktor +|* +\************************************************************************/ + +E3dObjFactory::~E3dObjFactory() +{ +} + +/************************************************************************* +|* +|* Chart-interne Objekte erzeugen +|* +\************************************************************************/ + +IMPL_LINK( E3dObjFactory, MakeObject, SdrObjFactory*, pObjFactory) +{ + if ( pObjFactory->nInventor == E3dInventor ) + { + switch ( pObjFactory->nIdentifier ) + { + case E3D_POLYSCENE_ID: + pObjFactory->pNewObj = new E3dPolyScene(); + break; + case E3D_POLYGONOBJ_ID : + pObjFactory->pNewObj = new E3dPolygonObj(); + break; + case E3D_CUBEOBJ_ID : + pObjFactory->pNewObj = new E3dCubeObj(); + break; + case E3D_SPHEREOBJ_ID: + // FG: ruft den dummy constructor, da dieser Aufruf nur beim Laden von Dokumenten erfolgt. + // die wirkliche Anzahkl Segmente wird aber erst nach dem Laden der Member festgelegt. + // dies hat zur Folge das die erste Kugel gleich wieder zerstoert wird, obwohl sie nie + // gebraucht worden ist. + pObjFactory->pNewObj = new E3dSphereObj(123); + break; + case E3D_EXTRUDEOBJ_ID: + pObjFactory->pNewObj = new E3dExtrudeObj(); + break; + case E3D_LATHEOBJ_ID: + pObjFactory->pNewObj = new E3dLatheObj(); + break; + case E3D_COMPOUNDOBJ_ID: + pObjFactory->pNewObj = new E3dCompoundObject(); + break; + } + } + return 0; +} + + diff --git a/svx/source/engine3d/polygn3d.cxx b/svx/source/engine3d/polygn3d.cxx new file mode 100644 index 000000000000..e91689424e18 --- /dev/null +++ b/svx/source/engine3d/polygn3d.cxx @@ -0,0 +1,361 @@ +/************************************************************************* + * + * 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_svx.hxx" +#include <svx/polygn3d.hxx> +#include <svx/svdpage.hxx> +#include "globl3d.hxx" +#include <basegfx/point/b3dpoint.hxx> +#include <svx/sdr/contact/viewcontactofe3dpolygon.hxx> +#include <basegfx/polygon/b3dpolygon.hxx> +#include <basegfx/polygon/b3dpolygontools.hxx> + +TYPEINIT1(E3dPolygonObj, E3dCompoundObject); + +////////////////////////////////////////////////////////////////////////////// +// #110094# DrawContact section + +sdr::contact::ViewContact* E3dPolygonObj::CreateObjectSpecificViewContact() +{ + return new sdr::contact::ViewContactOfE3dPolygon(*this); +} + +/************************************************************************* +|* +|* Konstruktor +|* +\************************************************************************/ + +E3dPolygonObj::E3dPolygonObj( + E3dDefaultAttributes& rDefault, + const basegfx::B3DPolyPolygon& rPolyPoly3D, + BOOL bLinOnly) +: E3dCompoundObject(rDefault), + bLineOnly(bLinOnly) +{ + // Geometrie setzen + SetPolyPolygon3D(rPolyPoly3D); + + // Default-Normals erzeugen + CreateDefaultNormals(); + + // Default-Texturkoordinaten erzeugen + CreateDefaultTexture(); +} + +/************************************************************************* +|* +|* Konstruktor +|* +\************************************************************************/ + +E3dPolygonObj::E3dPolygonObj( + E3dDefaultAttributes& rDefault, + const basegfx::B3DPolyPolygon& rPolyPoly3D, + const basegfx::B3DPolyPolygon& rPolyNormals3D, + BOOL bLinOnly) +: E3dCompoundObject(rDefault), + bLineOnly(bLinOnly) +{ + // Geometrie und Normalen setzen + SetPolyPolygon3D(rPolyPoly3D); + SetPolyNormals3D(rPolyNormals3D); + + // Default-Texturkoordinaten erzeugen + CreateDefaultTexture(); +} + +/************************************************************************* +|* +|* Konstruktor +|* +\************************************************************************/ + +E3dPolygonObj::E3dPolygonObj( + E3dDefaultAttributes& rDefault, + const basegfx::B3DPolyPolygon& rPolyPoly3D, + const basegfx::B3DPolyPolygon& rPolyNormals3D, + const basegfx::B2DPolyPolygon& rPolyTexture2D, + BOOL bLinOnly) +: E3dCompoundObject(rDefault), + bLineOnly(bLinOnly) +{ + SetPolyPolygon3D(rPolyPoly3D); + SetPolyNormals3D(rPolyNormals3D); + SetPolyTexture2D(rPolyTexture2D); +} + +/************************************************************************* +|* +|* Leer-Konstruktor +|* +\************************************************************************/ + +E3dPolygonObj::E3dPolygonObj() +: E3dCompoundObject(), + bLineOnly(false) // added missing initialisation +{ + // Keine Geometrie erzeugen +} + +/************************************************************************* +|* +|* Default-Normalen erzeugen +|* +\************************************************************************/ + +void E3dPolygonObj::CreateDefaultNormals() +{ + basegfx::B3DPolyPolygon aPolyNormals; + + // Komplettes PolyPolygon mit den Ebenennormalen anlegen + for(sal_uInt32 a(0L); a < aPolyPoly3D.count(); a++) + { + // Quellpolygon finden + const basegfx::B3DPolygon aPolygon(aPolyPoly3D.getB3DPolygon(a)); + + // Neues Polygon fuer Normalen anlegen + basegfx::B3DPolygon aNormals; + + // Normale holen (und umdrehen) + basegfx::B3DVector aNormal(-basegfx::tools::getNormal(aPolygon)); + + // Neues Polygon fuellen + for(sal_uInt32 b(0L); b < aPolygon.count(); b++) + { + aNormals.append(aNormal); + } + + // Neues Polygon in PolyPolygon einfuegen + aPolyNormals.append(aNormals); + } + + // Default-Normalen setzen + SetPolyNormals3D(aPolyNormals); +} + +/************************************************************************* +|* +|* Default-Texturkoordinaten erzeugen +|* +\************************************************************************/ + +void E3dPolygonObj::CreateDefaultTexture() +{ + basegfx::B2DPolyPolygon aPolyTexture; + + // Komplettes PolyPolygon mit den Texturkoordinaten anlegen + // Die Texturkoordinaten erstrecken sich ueber X,Y und Z + // ueber die gesamten Extremwerte im Bereich 0.0 .. 1.0 + for(sal_uInt32 a(0L); a < aPolyPoly3D.count(); a++) + { + // Quellpolygon finden + const basegfx::B3DPolygon& aPolygon(aPolyPoly3D.getB3DPolygon(a)); + + // Gesamtgroesse des Objektes feststellen + basegfx::B3DRange aVolume(basegfx::tools::getRange(aPolygon)); + + // Normale holen + basegfx::B3DVector aNormal(basegfx::tools::getNormal(aPolygon)); + aNormal.setX(fabs(aNormal.getX())); + aNormal.setY(fabs(aNormal.getY())); + aNormal.setZ(fabs(aNormal.getZ())); + + // Entscheiden, welche Koordinaten als Source fuer das + // Mapping benutzt werden sollen + UINT16 nSourceMode = 0; + + // Groessten Freiheitsgrad ermitteln + if(!(aNormal.getX() > aNormal.getY() && aNormal.getX() > aNormal.getZ())) + { + if(aNormal.getY() > aNormal.getZ()) + { + // Y ist am groessten, benutze X,Z als mapping + nSourceMode = 1; + } + else + { + // Z ist am groessten, benutze X,Y als mapping + nSourceMode = 2; + } + } + + // Neues Polygon fuer Texturkoordinaten anlegen + basegfx::B2DPolygon aTexture; + + // Neues Polygon fuellen + for(sal_uInt32 b(0L); b < aPolygon.count(); b++) + { + basegfx::B2DPoint aTex; + const basegfx::B3DPoint aCandidate(aPolygon.getB3DPoint(b)); + + switch(nSourceMode) + { + case 0: // Quelle ist Y,Z + if(aVolume.getHeight()) + aTex.setX((aCandidate.getY() - aVolume.getMinY()) / aVolume.getHeight()); + if(aVolume.getDepth()) + aTex.setY((aCandidate.getZ() - aVolume.getMinZ()) / aVolume.getDepth()); + break; + + case 1: // Quelle ist X,Z + if(aVolume.getWidth()) + aTex.setX((aCandidate.getX() - aVolume.getMinX()) / aVolume.getWidth()); + if(aVolume.getDepth()) + aTex.setY((aCandidate.getZ() - aVolume.getMinZ()) / aVolume.getDepth()); + break; + + case 2: // Quelle ist X,Y + if(aVolume.getWidth()) + aTex.setX((aCandidate.getX() - aVolume.getMinX()) / aVolume.getWidth()); + if(aVolume.getHeight()) + aTex.setY((aCandidate.getY() - aVolume.getMinY()) / aVolume.getHeight()); + break; + } + + aTexture.append(aTex); + } + + // Neues Polygon in PolyPolygon einfuegen + aPolyTexture.append(aTexture); + } + + // Default-Texturkoordinaten setzen + SetPolyTexture2D(aPolyTexture); +} + +/************************************************************************* +|* +|* Destruktor +|* +\************************************************************************/ + +E3dPolygonObj::~E3dPolygonObj() +{ +} + +/************************************************************************* +|* +|* Identifier zurueckgeben +|* +\************************************************************************/ + +UINT16 E3dPolygonObj::GetObjIdentifier() const +{ + return E3D_POLYGONOBJ_ID; +} + +/************************************************************************* +|* +|* Polygon setzen +|* +\************************************************************************/ + +void E3dPolygonObj::SetPolyPolygon3D(const basegfx::B3DPolyPolygon& rNewPolyPoly3D) +{ + if ( aPolyPoly3D != rNewPolyPoly3D ) + { + // Neues PolyPolygon; kopieren + aPolyPoly3D = rNewPolyPoly3D; + + // Geometrie neu erzeugen + ActionChanged(); + } +} + +void E3dPolygonObj::SetPolyNormals3D(const basegfx::B3DPolyPolygon& rNewPolyNormals3D) +{ + if ( aPolyNormals3D != rNewPolyNormals3D ) + { + // Neue Normalen; kopieren + aPolyNormals3D = rNewPolyNormals3D; + + // Geometrie neu erzeugen + ActionChanged(); + } +} + +void E3dPolygonObj::SetPolyTexture2D(const basegfx::B2DPolyPolygon& rNewPolyTexture2D) +{ + if ( aPolyTexture2D != rNewPolyTexture2D ) + { + // Neue Texturkoordinaten; kopieren + aPolyTexture2D = rNewPolyTexture2D; + + // Geometrie neu erzeugen + ActionChanged(); + } +} + +/************************************************************************* +|* +|* Wandle das Objekt in ein Gruppenobjekt bestehend aus 6 Polygonen +|* +\************************************************************************/ + +SdrObject *E3dPolygonObj::DoConvertToPolyObj(BOOL /*bBezier*/) const +{ + return NULL; +} + +/************************************************************************* +|* +|* Zuweisungsoperator +|* +\************************************************************************/ + +void E3dPolygonObj::operator=(const SdrObject& rObj) +{ + // erstmal alle Childs kopieren + E3dCompoundObject::operator=(rObj); + + // weitere Parameter kopieren + const E3dPolygonObj& r3DObj = (const E3dPolygonObj&)rObj; + + aPolyPoly3D = r3DObj.aPolyPoly3D; + aPolyNormals3D = r3DObj.aPolyNormals3D; + aPolyTexture2D = r3DObj.aPolyTexture2D; + bLineOnly = r3DObj.bLineOnly; +} + +/************************************************************************* +|* +|* LineOnly setzen +|* +\************************************************************************/ + +void E3dPolygonObj::SetLineOnly(BOOL bNew) +{ + if(bNew != bLineOnly) + { + bLineOnly = bNew; + ActionChanged(); + } +} + +// eof diff --git a/svx/source/engine3d/polysc3d.cxx b/svx/source/engine3d/polysc3d.cxx new file mode 100644 index 000000000000..3c002e2533b8 --- /dev/null +++ b/svx/source/engine3d/polysc3d.cxx @@ -0,0 +1,74 @@ +/************************************************************************* + * + * 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_svx.hxx" +#include <svx/xfillit.hxx> +#include <svx/svdopath.hxx> +#include <svx/svdogrp.hxx> +#include "svditer.hxx" +#include <svx/svdetc.hxx> +#include <vcl/virdev.hxx> +#include <vcl/svapp.hxx> +#include <svx/svdpage.hxx> +#include <svx/svdpool.hxx> +#include <svl/style.hxx> +#include "globl3d.hxx" +#include <svx/polysc3d.hxx> +#include <svx/xlnclit.hxx> +#include <svl/metitem.hxx> +#include <svx/xtable.hxx> +#include <svx/xlnwtit.hxx> + +#define ITEMVALUE(ItemSet,Id,Cast) ((const Cast&)(ItemSet).Get(Id)).GetValue() + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +TYPEINIT1(E3dPolyScene, E3dScene); + +E3dPolyScene::E3dPolyScene() +: E3dScene() +{ +} + +E3dPolyScene::E3dPolyScene(E3dDefaultAttributes& rDefault) +: E3dScene(rDefault) +{ +} + +/************************************************************************* +|* +|* Identifier zurueckgeben +|* +\************************************************************************/ + +UINT16 E3dPolyScene::GetObjIdentifier() const +{ + return E3D_POLYSCENE_ID; +} + +// eof diff --git a/svx/source/engine3d/scene3d.cxx b/svx/source/engine3d/scene3d.cxx new file mode 100644 index 000000000000..d799aec38eb7 --- /dev/null +++ b/svx/source/engine3d/scene3d.cxx @@ -0,0 +1,874 @@ +/************************************************************************* + * + * 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_svx.hxx" + +#include "svdstr.hrc" +#include "svdglob.hxx" +#include "svditer.hxx" + +#if defined( UNX ) || defined( ICC ) +#include <stdlib.h> +#endif +#include "globl3d.hxx" +#include <svx/svdpage.hxx> +#include <svl/style.hxx> +#include <svx/scene3d.hxx> +#include <svx/e3dundo.hxx> +#include <svx/svdtrans.hxx> +#include <svx/svxids.hrc> +#include <editeng/colritem.hxx> +#include <svx/e3ditem.hxx> +#include <svx/xlntrit.hxx> +#include <svx/xfltrit.hxx> +#include <svx/svx3ditems.hxx> +#include <svl/whiter.hxx> +#include <svx/xflftrit.hxx> +#include <svx/sdr/properties/e3dsceneproperties.hxx> +#include <svx/sdr/contact/viewcontactofe3dscene.hxx> +#include <svx/svddrag.hxx> +#include <helperminimaldepth3d.hxx> +#include <algorithm> +#include <drawinglayer/geometry/viewinformation3d.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <svx/e3dsceneupdater.hxx> + +#define ITEMVALUE(ItemSet,Id,Cast) ((const Cast&)(ItemSet).Get(Id)).GetValue() + +////////////////////////////////////////////////////////////////////////////// +// #110988# + +class ImpRemap3DDepth +{ + sal_uInt32 mnOrdNum; + double mfMinimalDepth; + + // bitfield + unsigned mbIsScene : 1; + +public: + ImpRemap3DDepth(sal_uInt32 nOrdNum, double fMinimalDepth); + ImpRemap3DDepth(sal_uInt32 nOrdNum); + ~ImpRemap3DDepth(); + + // for ::std::sort + bool operator<(const ImpRemap3DDepth& rComp) const; + + sal_uInt32 GetOrdNum() const { return mnOrdNum; } + sal_Bool IsScene() const { return mbIsScene; } +}; + +ImpRemap3DDepth::ImpRemap3DDepth(sal_uInt32 nOrdNum, double fMinimalDepth) +: mnOrdNum(nOrdNum), + mfMinimalDepth(fMinimalDepth), + mbIsScene(sal_False) +{ +} + +ImpRemap3DDepth::ImpRemap3DDepth(sal_uInt32 nOrdNum) +: mnOrdNum(nOrdNum), + mbIsScene(sal_True) +{ +} + +ImpRemap3DDepth::~ImpRemap3DDepth() +{ +} + +bool ImpRemap3DDepth::operator<(const ImpRemap3DDepth& rComp) const +{ + if(IsScene()) + { + return sal_False; + } + else + { + if(rComp.IsScene()) + { + return sal_True; + } + else + { + return mfMinimalDepth < rComp.mfMinimalDepth; + } + } +} + +// typedefs for a vector of ImpRemap3DDepths +typedef ::std::vector< ImpRemap3DDepth > ImpRemap3DDepthVector; + +////////////////////////////////////////////////////////////////////////////// +// #110988# + +class Imp3DDepthRemapper +{ + ImpRemap3DDepthVector maVector; + +public: + Imp3DDepthRemapper(E3dScene& rScene); + ~Imp3DDepthRemapper(); + + sal_uInt32 RemapOrdNum(sal_uInt32 nOrdNum) const; +}; + +Imp3DDepthRemapper::Imp3DDepthRemapper(E3dScene& rScene) +{ + // only called when rScene.GetSubList() and nObjCount > 1L + SdrObjList* pList = rScene.GetSubList(); + const sal_uInt32 nObjCount(pList->GetObjCount()); + + for(sal_uInt32 a(0L); a < nObjCount; a++) + { + SdrObject* pCandidate = pList->GetObj(a); + + if(pCandidate) + { + if(pCandidate->ISA(E3dCompoundObject)) + { + // single 3d object, calc depth + const double fMinimalDepth(getMinimalDepthInViewCoordinates(static_cast< const E3dCompoundObject& >(*pCandidate))); + ImpRemap3DDepth aEntry(a, fMinimalDepth); + maVector.push_back(aEntry); + } + else + { + // scene, use standard entry for scene + ImpRemap3DDepth aEntry(a); + maVector.push_back(aEntry); + } + } + } + + // now, we need to sort the maVector by it's members minimal depth. The + // smaller, the nearer to the viewer. + ::std::sort(maVector.begin(), maVector.end()); +} + +Imp3DDepthRemapper::~Imp3DDepthRemapper() +{ +} + +sal_uInt32 Imp3DDepthRemapper::RemapOrdNum(sal_uInt32 nOrdNum) const +{ + if(nOrdNum < maVector.size()) + { + nOrdNum = maVector[(maVector.size() - 1) - nOrdNum].GetOrdNum(); + } + + return nOrdNum; +} + +////////////////////////////////////////////////////////////////////////////// +// BaseProperties section + +sdr::properties::BaseProperties* E3dScene::CreateObjectSpecificProperties() +{ + return new sdr::properties::E3dSceneProperties(*this); +} + +////////////////////////////////////////////////////////////////////////////// +// #110094# DrawContact section + +sdr::contact::ViewContact* E3dScene::CreateObjectSpecificViewContact() +{ + return new sdr::contact::ViewContactOfE3dScene(*this); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +TYPEINIT1(E3dScene, E3dObject); + +/************************************************************************* +|* +|* E3dScene-Konstruktor +|* +\************************************************************************/ + +E3dScene::E3dScene() +: E3dObject(), + aCamera(basegfx::B3DPoint(0.0, 0.0, 4.0), basegfx::B3DPoint()), + mp3DDepthRemapper(0L), + bDrawOnlySelected(false) +{ + // Defaults setzen + E3dDefaultAttributes aDefault; + SetDefaultAttributes(aDefault); +} + +E3dScene::E3dScene(E3dDefaultAttributes& rDefault) +: E3dObject(), + aCamera(basegfx::B3DPoint(0.0, 0.0, 4.0), basegfx::B3DPoint()), + mp3DDepthRemapper(0L), + bDrawOnlySelected(false) +{ + // Defaults setzen + SetDefaultAttributes(rDefault); +} + +void E3dScene::SetDefaultAttributes(E3dDefaultAttributes& /*rDefault*/) +{ + // Fuer OS/2 die FP-Exceptions abschalten +#if defined(OS2) +#define SC_FPEXCEPTIONS_ON() _control87( MCW_EM, 0 ) +#define SC_FPEXCEPTIONS_OFF() _control87( MCW_EM, MCW_EM ) + SC_FPEXCEPTIONS_OFF(); +#endif + + // Fuer WIN95/NT die FP-Exceptions abschalten +#if defined(WNT) || defined(WIN) +#define SC_FPEXCEPTIONS_ON() _control87( _MCW_EM, 0 ) +#define SC_FPEXCEPTIONS_OFF() _control87( _MCW_EM, _MCW_EM ) + SC_FPEXCEPTIONS_OFF(); +#endif + + // Defaults setzen + aCamera.SetViewWindow(-2, -2, 4, 4); + aCameraSet.SetDeviceRectangle(-2, 2, -2, 2); + aCamera.SetDeviceWindow(Rectangle(0, 0, 10, 10)); + Rectangle aRect(0, 0, 10, 10); + aCameraSet.SetViewportRectangle(aRect); + + // set defaults for Camera from ItemPool + aCamera.SetProjection(GetPerspective()); + basegfx::B3DPoint aActualPosition(aCamera.GetPosition()); + double fNew = GetDistance(); + + if(fabs(fNew - aActualPosition.getZ()) > 1.0) + { + aCamera.SetPosition( basegfx::B3DPoint( aActualPosition.getX(), aActualPosition.getY(), fNew) ); + } + + fNew = GetFocalLength() / 100.0; + aCamera.SetFocalLength(fNew); +} + +/************************************************************************* +|* +|* Destruktor +|* +\************************************************************************/ + +E3dScene::~E3dScene() +{ + // #110988# + ImpCleanup3DDepthMapper(); +} + +basegfx::B2DPolyPolygon E3dScene::TakeXorPoly() const +{ + const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(GetViewContact()); + const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D()); + const basegfx::B3DPolyPolygon aCubePolyPolygon(CreateWireframe()); + + basegfx::B2DPolyPolygon aRetval(basegfx::tools::createB2DPolyPolygonFromB3DPolyPolygon(aCubePolyPolygon, + aViewInfo3D.getObjectToView())); + aRetval.transform(rVCScene.getObjectTransformation()); + + return aRetval; +} + +// #110988# +void E3dScene::ImpCleanup3DDepthMapper() +{ + if(mp3DDepthRemapper) + { + delete mp3DDepthRemapper; + mp3DDepthRemapper = 0L; + } +} + +// #110988# +sal_uInt32 E3dScene::RemapOrdNum(sal_uInt32 nNewOrdNum) const +{ + if(!mp3DDepthRemapper) + { + const sal_uInt32 nObjCount(GetSubList() ? GetSubList()->GetObjCount() : 0L); + + if(nObjCount > 1L) + { + ((E3dScene*)this)->mp3DDepthRemapper = new Imp3DDepthRemapper((E3dScene&)(*this)); + } + } + + if(mp3DDepthRemapper) + { + return mp3DDepthRemapper->RemapOrdNum(nNewOrdNum); + } + + return nNewOrdNum; +} + +/************************************************************************* +|* +|* Identifier zurueckgeben +|* +\************************************************************************/ + +UINT16 E3dScene::GetObjIdentifier() const +{ + return E3D_SCENE_ID; +} + +void E3dScene::SetBoundRectDirty() +{ + // avoid resetting aOutRect which in case of this object is model data, + // not re-creatable view data +} + +/************************************************************************* +|* +|* SetSnapRect +|* +\************************************************************************/ + +void E3dScene::NbcSetSnapRect(const Rectangle& rRect) +{ + SetRectsDirty(); + E3dObject::NbcSetSnapRect(rRect); + aCamera.SetDeviceWindow(rRect); + aCameraSet.SetViewportRectangle((Rectangle&)rRect); + + // #110988# + ImpCleanup3DDepthMapper(); +} + +/************************************************************************* +|* +|* Objekt verschieben +|* +\************************************************************************/ + +void E3dScene::NbcMove(const Size& rSize) +{ + Rectangle aNewSnapRect = GetSnapRect(); + MoveRect(aNewSnapRect, rSize); + NbcSetSnapRect(aNewSnapRect); +} + +/************************************************************************* +|* +|* Objekt Resizen +|* +\************************************************************************/ + +void E3dScene::NbcResize(const Point& rRef, const Fraction& rXFact, + const Fraction& rYFact) +{ + Rectangle aNewSnapRect = GetSnapRect(); + ResizeRect(aNewSnapRect, rRef, rXFact, rYFact); + NbcSetSnapRect(aNewSnapRect); +} + +/************************************************************************* +|* +|* Neue Kamera setzen, und dabei die Szene und ggf. das BoundVolume +|* als geaendert markieren +|* +\************************************************************************/ + +void E3dScene::SetCamera(const Camera3D& rNewCamera) +{ + // Alte Kamera setzen + aCamera = rNewCamera; + ((sdr::properties::E3dSceneProperties&)GetProperties()).SetSceneItemsFromCamera(); + + SetRectsDirty(); + + // Neue Kamera aus alter fuellen + Camera3D& rCam = (Camera3D&)GetCamera(); + + // Ratio abschalten + if(rCam.GetAspectMapping() == AS_NO_MAPPING) + GetCameraSet().SetRatio(0.0); + + // Abbildungsgeometrie setzen + basegfx::B3DPoint aVRP(rCam.GetViewPoint()); + basegfx::B3DVector aVPN(aVRP - rCam.GetVRP()); + basegfx::B3DVector aVUV(rCam.GetVUV()); + + // #91047# use SetViewportValues() to set VRP, VPN and VUV as vectors, too. + // Else these values would not be exported/imported correctly. + GetCameraSet().SetViewportValues(aVRP, aVPN, aVUV); + + // Perspektive setzen + GetCameraSet().SetPerspective(rCam.GetProjection() == PR_PERSPECTIVE); + GetCameraSet().SetViewportRectangle((Rectangle&)rCam.GetDeviceWindow()); + + // #110988# + ImpCleanup3DDepthMapper(); +} + +/************************************************************************* +|* +|* 3D-Objekt einfuegen +|* +\************************************************************************/ + +void E3dScene::NewObjectInserted(const E3dObject* p3DObj) +{ + E3dObject::NewObjectInserted(p3DObj); + + if ( p3DObj == this ) + return; + + // #110988# + ImpCleanup3DDepthMapper(); +} + +/************************************************************************* +|* +|* Parent ueber Aenderung eines Childs informieren +|* +\************************************************************************/ + +void E3dScene::StructureChanged() +{ + E3dObject::StructureChanged(); + SetRectsDirty(); + + // #110988# + ImpCleanup3DDepthMapper(); +} + +/************************************************************************* +|* +|* Uebergeordnetes Szenenobjekt bestimmen +|* +\************************************************************************/ + +E3dScene* E3dScene::GetScene() const +{ + if(GetParentObj()) + return GetParentObj()->GetScene(); + else + return (E3dScene*)this; +} + +void E3dScene::removeAllNonSelectedObjects() +{ + E3DModifySceneSnapRectUpdater aUpdater(this); + + for(sal_uInt32 a(0); a < maSubList.GetObjCount(); a++) + { + SdrObject* pObj = maSubList.GetObj(a); + + if(pObj) + { + bool bRemoveObject(false); + + if(pObj->ISA(E3dScene)) + { + E3dScene* pScene = (E3dScene*)pObj; + + // iterate over this sub-scene + pScene->removeAllNonSelectedObjects(); + + // check object count. Empty scenes can be deleted + const sal_uInt32 nObjCount(pScene->GetSubList() ? pScene->GetSubList()->GetObjCount() : 0); + + if(!nObjCount) + { + // all objects removed, scene can be removed, too + bRemoveObject = true; + } + } + else if(pObj->ISA(E3dCompoundObject)) + { + E3dCompoundObject* pCompound = (E3dCompoundObject*)pObj; + + if(!pCompound->GetSelected()) + { + bRemoveObject = true; + } + } + + if(bRemoveObject) + { + maSubList.NbcRemoveObject(pObj->GetOrdNum()); + a--; + SdrObject::Free(pObj); + } + } + } +} + +/************************************************************************* +|* +|* Zuweisungsoperator +|* +\************************************************************************/ + +void E3dScene::operator=(const SdrObject& rObj) +{ + E3dObject::operator=(rObj); + + const E3dScene& r3DObj = (const E3dScene&) rObj; + aCamera = r3DObj.aCamera; + + // neu ab 377: + aCameraSet = r3DObj.aCameraSet; + ((sdr::properties::E3dSceneProperties&)GetProperties()).SetSceneItemsFromCamera(); + + // SetSnapRect(r3DObj.GetSnapRect()); + InvalidateBoundVolume(); + RebuildLists(); + SetRectsDirty(); + + // #110988# + ImpCleanup3DDepthMapper(); + + // #i101941# + // After a Scene as model object is cloned, the used + // ViewContactOfE3dScene is created and partially used + // to calculate Bound/SnapRects, but - since quite some + // values are buffered at the VC - not really well + // initialized. It would be possible to always watch for + // preconditions of buffered data, but this would be expensive + // and would create a lot of short living data structures. + // It is currently better to flush that data, e.g. by using + // ActionChanged at the VC which will for this class + // flush that cached data and initalize it's valid reconstruction + GetViewContact().ActionChanged(); +} + +/************************************************************************* +|* +|* Licht- und Labelobjektlisten neu aufbauen (nach Laden, Zuweisung) +|* +\************************************************************************/ + +void E3dScene::RebuildLists() +{ + // zuerst loeschen + SdrLayerID nCurrLayerID = GetLayer(); + + SdrObjListIter a3DIterator(maSubList, IM_FLAT); + + // dann alle Objekte in der Szene pruefen + while ( a3DIterator.IsMore() ) + { + E3dObject* p3DObj = (E3dObject*) a3DIterator.Next(); + p3DObj->NbcSetLayer(nCurrLayerID); + NewObjectInserted(p3DObj); + } +} + +/************************************************************************* +|* +|* erstelle neues GeoData-Objekt +|* +\************************************************************************/ + +SdrObjGeoData *E3dScene::NewGeoData() const +{ + return new E3DSceneGeoData; +} + +/************************************************************************* +|* +|* uebergebe aktuelle werte an das GeoData-Objekt +|* +\************************************************************************/ + +void E3dScene::SaveGeoData(SdrObjGeoData& rGeo) const +{ + E3dObject::SaveGeoData (rGeo); + + ((E3DSceneGeoData &) rGeo).aCamera = aCamera; +} + +/************************************************************************* +|* +|* uebernehme werte aus dem GeoData-Objekt +|* +\************************************************************************/ + +void E3dScene::RestGeoData(const SdrObjGeoData& rGeo) +{ + // #i94832# removed E3DModifySceneSnapRectUpdater here. + // It should not be needed, is already part of E3dObject::RestGeoData + E3dObject::RestGeoData (rGeo); + SetCamera (((E3DSceneGeoData &) rGeo).aCamera); +} + +/************************************************************************* +|* +|* Am StyleSheet wurde etwas geaendert, also Scene aendern +|* +\************************************************************************/ + +void E3dScene::Notify(SfxBroadcaster &rBC, const SfxHint &rHint) +{ + SetRectsDirty(); + E3dObject::Notify(rBC, rHint); +} + +/************************************************************************* +|* +\************************************************************************/ + +void E3dScene::RotateScene (const Point& rRef, long /*nWink*/, double sn, double cs) +{ + Point UpperLeft, LowerRight, Center, NewCenter; + + UpperLeft = aOutRect.TopLeft(); + LowerRight = aOutRect.BottomRight(); + + long dxOutRectHalf = labs(UpperLeft.X() - LowerRight.X()); + dxOutRectHalf /= 2; + long dyOutRectHalf = labs(UpperLeft.Y() - LowerRight.Y()); + dyOutRectHalf /= 2; + + Rectangle RectQuelle(aOutRect), RectZiel(aOutRect); + + // Nur der Mittelpunkt wird bewegt. Die Ecken werden von NbcMove bewegt. + // Fuer das Drehen wird von mir ein kartesisches Koordinatensystem verwendet in dem der Drehpunkt + // der Nullpunkt ist und die Y- Achse nach oben ansteigt, die X-Achse nach rechts. + // Dies muss bei den Y-Werten beachtet werden. (Auf dem Blatt zeigt die Y-Achse nach unten + Center.X() = (UpperLeft.X() + dxOutRectHalf) - rRef.X(); + Center.Y() = -((UpperLeft.Y() + dyOutRectHalf) - rRef.Y()); + // Ein paar Spezialfaelle zuerst abhandeln (n*90 Grad n ganzzahlig) + if (sn==1.0 && cs==0.0) { // 90deg + NewCenter.X() = -Center.Y(); + NewCenter.Y() = -Center.X(); + } else if (sn==0.0 && cs==-1.0) { // 180deg + NewCenter.X() = -Center.X(); + NewCenter.Y() = -Center.Y(); + } else if (sn==-1.0 && cs==0.0) { // 270deg + NewCenter.X() = Center.Y(); + NewCenter.Y() = -Center.X(); + } + else // Hier wird um einen beliebigen Winkel in mathematisch positiver Richtung gedreht! + { // xneu = x * cos(alpha) - y * sin(alpha) + // yneu = x * sin(alpha) + y * cos(alpha) + // Unten Rechts wird nicht gedreht: die Seiten von RectQuelle muessen parallel + // zu den Koordinatenachsen bleiben. + NewCenter.X() = (long) (Center.X() * cs - Center.Y() * sn); + NewCenter.Y() = (long) (Center.X() * sn + Center.Y() * cs); + } + + Size Differenz; + Point DiffPoint = (NewCenter - Center); + Differenz.Width() = DiffPoint.X(); + Differenz.Height() = -DiffPoint.Y(); // Man beachte dass die Y-Achse nach unten positiv gezaehlt wird. + NbcMove (Differenz); // fuehrt die eigentliche Koordinatentransformation durch. +} + +/************************************************************************* +|* +|* Get the name of the object (singular) +|* +\************************************************************************/ + +void E3dScene::TakeObjNameSingul(XubString& rName) const +{ + rName=ImpGetResStr(STR_ObjNameSingulScene3d); + + String aName( GetName() ); + if(aName.Len()) + { + rName += sal_Unicode(' '); + rName += sal_Unicode('\''); + rName += aName; + rName += sal_Unicode('\''); + } +} + +/************************************************************************* +|* +|* Get the name of the object (plural) +|* +\************************************************************************/ + +void E3dScene::TakeObjNamePlural(XubString& rName) const +{ + rName=ImpGetResStr(STR_ObjNamePluralScene3d); +} + +/************************************************************************* +|* +|* Die NbcRotate-Routine ueberlaedt die des SdrObject. Die Idee ist die Scene +|* drehen zu koennen und relativ zur Lage der Scene dann auch die Objekte +|* in der Scene +|* +\************************************************************************/ + +void E3dScene::NbcSetTransform(const basegfx::B3DHomMatrix& rMatrix) +{ + if(maTransformation != rMatrix) + { + // call parent + E3dObject::NbcSetTransform(rMatrix); + } +} + +void E3dScene::SetTransform(const basegfx::B3DHomMatrix& rMatrix) +{ + if(rMatrix != maTransformation) + { + // call parent + E3dObject::SetTransform(rMatrix); + } +} + +void E3dScene::NbcRotate(const Point& rRef, long nWink, double sn, double cs) +{ + // Also derzeit sind die Klebepunkte relativ zum aOutRect der Szene definiert. Vor dem Drehen + // werden die Klebepunkte relativ zur Seite definiert. Sie nehmen an der Drehung der Szene noch nicht Teil + // dafuer gibt es den + SetGlueReallyAbsolute(TRUE); + + // So dass war die Szene, ab jetzt kommen die Objekte in der Szene + // 3D-Objekte gibt es nur ein einziges das kann zwar mehrere Flaechen haben aber die Flaechen + // muessen ja nicht zusammenhaengend sein + // es ermoeglicht den Zugriff auf Kindobjekte + // Ich gehe also die gesamte Liste durch und rotiere um die Z-Achse die durch den + // Mittelpunkt von aOutRect geht (Satz von Steiner), also RotateZ + + RotateScene (rRef, nWink, sn, cs); // Rotiert die Szene + double fWinkelInRad = nWink/100 * F_PI180; + + basegfx::B3DHomMatrix aRotation; + aRotation.rotate(0.0, 0.0, fWinkelInRad); + NbcSetTransform(aRotation * GetTransform()); + + SetRectsDirty(); // Veranlasst eine Neuberechnung aller BoundRects + NbcRotateGluePoints(rRef,nWink,sn,cs); // Rotiert die Klebepunkte (die haben noch Koordinaten relativ + // zum Urpsung des Blattes + SetGlueReallyAbsolute(FALSE); // ab jetzt sind sie wieder relativ zum BoundRect (also dem aOutRect definiert) + SetRectsDirty(); +} + +/************************************************************************* +|* +|* SnapRect berechnen +|* +\************************************************************************/ + +void E3dScene::RecalcSnapRect() +{ + E3dScene* pScene = GetScene(); + + if(pScene == this) + { + // Szene wird als 2D-Objekt benutzt, nimm SnapRect aus der + // 2D Bildschrimdarstellung + Camera3D& rCam = (Camera3D&)pScene->GetCamera(); + maSnapRect = rCam.GetDeviceWindow(); + } + else + { + // Szene ist selbst Mitglied einer anderen Szene, hole das + // SnapRect als zusammengesetztes Objekt + E3dObject::RecalcSnapRect(); + } +} + +/************************************************************************* +|* +|* Aufbrechen +|* +\************************************************************************/ + +BOOL E3dScene::IsBreakObjPossible() +{ + // Szene ist aufzubrechen, wenn alle Mitglieder aufzubrechen sind + SdrObjListIter a3DIterator(maSubList, IM_DEEPWITHGROUPS); + + while ( a3DIterator.IsMore() ) + { + E3dObject* pObj = (E3dObject*) a3DIterator.Next(); + DBG_ASSERT(pObj->ISA(E3dObject), "AW: In Szenen sind nur 3D-Objekte erlaubt!"); + if(!pObj->IsBreakObjPossible()) + return FALSE; + } + + return TRUE; +} + +basegfx::B3DVector E3dScene::GetShadowPlaneDirection() const +{ + double fWink = (double)GetShadowSlant() * F_PI180; + basegfx::B3DVector aShadowPlaneDir(0.0, sin(fWink), cos(fWink)); + aShadowPlaneDir.normalize(); + return aShadowPlaneDir; +} + +void E3dScene::SetShadowPlaneDirection(const basegfx::B3DVector& rVec) +{ + UINT16 nSceneShadowSlant = (UINT16)((atan2(rVec.getY(), rVec.getZ()) / F_PI180) + 0.5); + GetProperties().SetObjectItemDirect(Svx3DShadowSlantItem(nSceneShadowSlant)); +} + +basegfx::B2DPolyPolygon E3dScene::TakeCreatePoly(const SdrDragStat& /*rDrag*/) const +{ + return TakeXorPoly(); +} + +FASTBOOL E3dScene::BegCreate(SdrDragStat& rStat) +{ + rStat.SetOrtho4Possible(); + Rectangle aRect1(rStat.GetStart(), rStat.GetNow()); + aRect1.Justify(); + rStat.SetActionRect(aRect1); + NbcSetSnapRect(aRect1); + return TRUE; +} + +FASTBOOL E3dScene::MovCreate(SdrDragStat& rStat) +{ + Rectangle aRect1; + rStat.TakeCreateRect(aRect1); + aRect1.Justify(); + rStat.SetActionRect(aRect1); + NbcSetSnapRect(aRect1); + SetBoundRectDirty(); + bSnapRectDirty=TRUE; + return TRUE; +} + +FASTBOOL E3dScene::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd) +{ + Rectangle aRect1; + rStat.TakeCreateRect(aRect1); + aRect1.Justify(); + NbcSetSnapRect(aRect1); + SetRectsDirty(); + return (eCmd==SDRCREATE_FORCEEND || rStat.GetPointAnz()>=2); +} + +FASTBOOL E3dScene::BckCreate(SdrDragStat& /*rStat*/) +{ + return FALSE; +} + +void E3dScene::BrkCreate(SdrDragStat& /*rStat*/) +{ +} + +// eof diff --git a/svx/source/engine3d/sphere3d.cxx b/svx/source/engine3d/sphere3d.cxx new file mode 100644 index 000000000000..ab9e3bc87f79 --- /dev/null +++ b/svx/source/engine3d/sphere3d.cxx @@ -0,0 +1,226 @@ +/************************************************************************* + * + * 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_svx.hxx" + +#include "svdstr.hrc" +#include "svdglob.hxx" +#include <svx/svdmodel.hxx> +#include <svx/svdpage.hxx> +#include "globl3d.hxx" +#include <svx/sphere3d.hxx> + +#include <svx/svxids.hrc> +#include <svx/svx3ditems.hxx> +#include <svx/sdr/properties/e3dsphereproperties.hxx> +#include <basegfx/vector/b3dvector.hxx> +#include <basegfx/point/b3dpoint.hxx> +#include <svx/sdr/contact/viewcontactofe3dsphere.hxx> +#include <basegfx/polygon/b3dpolygon.hxx> + +////////////////////////////////////////////////////////////////////////////// +// #110094# DrawContact section + +sdr::contact::ViewContact* E3dSphereObj::CreateObjectSpecificViewContact() +{ + return new sdr::contact::ViewContactOfE3dSphere(*this); +} + +////////////////////////////////////////////////////////////////////////////// + +sdr::properties::BaseProperties* E3dSphereObj::CreateObjectSpecificProperties() +{ + return new sdr::properties::E3dSphereProperties(*this); +} + +////////////////////////////////////////////////////////////////////////////// + +TYPEINIT1(E3dSphereObj, E3dCompoundObject); + +/************************************************************************* +|* +|* Kugel aus Polygonfacetten nach Laengen und Breitengrad aufbauen +|* +\************************************************************************/ + +E3dSphereObj::E3dSphereObj(E3dDefaultAttributes& rDefault, const basegfx::B3DPoint& rCenter, const basegfx::B3DVector& r3DSize) +: E3dCompoundObject(rDefault) +{ + // Defaults setzen + SetDefaultAttributes(rDefault); + + // Uebergebene drueberbuegeln + aCenter = rCenter; + aSize = r3DSize; +} + +E3dSphereObj::E3dSphereObj() +: E3dCompoundObject() +{ + // Defaults setzen + E3dDefaultAttributes aDefault; + SetDefaultAttributes(aDefault); +} + +/************************************************************************* +|* +|* Kugel erzeugen ohne die Polygone darin zu erzeugen +|* +\************************************************************************/ + +// FG: Dieser Aufruf erfolgt von der 3D-Object Factory (objfac3d.cxx) und zwar ausschliesslich beim +// laden von Dokumenten. Hier braucht man keinen CreateSphere-Aufruf, denn die wirkliche +// Anzahl Segmente ist ja noch nicht bekannt. Dies war bis zum 10.2.97 ein (kleines) +// Speicherleck. +E3dSphereObj::E3dSphereObj(int /*dummy*/) // den Parameter braucht es um unterscheiden zu koennen, welcher +{ // der beiden Konstruktoren gemeint ist. Der obige halt per Default + // Defaults setzen + E3dDefaultAttributes aDefault; + SetDefaultAttributes(aDefault); +} + +void E3dSphereObj::SetDefaultAttributes(E3dDefaultAttributes& rDefault) +{ + // Defaults setzen + aCenter = rDefault.GetDefaultSphereCenter(); + aSize = rDefault.GetDefaultSphereSize(); +} + +/************************************************************************* +|* +|* Identifier zurueckgeben +|* +\************************************************************************/ + +UINT16 E3dSphereObj::GetObjIdentifier() const +{ + return E3D_SPHEREOBJ_ID; +} + +/************************************************************************* +|* +|* Wandle das Objekt in ein Gruppenobjekt bestehend aus n Polygonen +|* +\************************************************************************/ + +SdrObject *E3dSphereObj::DoConvertToPolyObj(BOOL /*bBezier*/) const +{ + return NULL; +} + +/************************************************************************* +|* +|* Leer-Konstruktor +|* +\************************************************************************/ + +void E3dSphereObj::ReSegment(sal_uInt32 nHSegs, sal_uInt32 nVSegs) +{ + if((nHSegs != GetHorizontalSegments() || nVSegs != GetVerticalSegments()) && (nHSegs != 0 || nVSegs != 0)) + { + GetProperties().SetObjectItemDirect(Svx3DHorizontalSegmentsItem(nHSegs)); + GetProperties().SetObjectItemDirect(Svx3DVerticalSegmentsItem(nVSegs)); + + ActionChanged(); + } +} + +/************************************************************************* +|* +|* Zuweisungsoperator +|* +\************************************************************************/ + +void E3dSphereObj::operator=(const SdrObject& rObj) +{ + // erstmal alle Childs kopieren + E3dCompoundObject::operator=(rObj); + + // weitere Parameter kopieren + const E3dSphereObj& r3DObj = (const E3dSphereObj&) rObj; + + aCenter = r3DObj.aCenter; + aSize = r3DObj.aSize; +} + +/************************************************************************* +|* +|* Lokale Parameter setzen mit Geometrieneuerzeugung +|* +\************************************************************************/ + +void E3dSphereObj::SetCenter(const basegfx::B3DPoint& rNew) +{ + if(aCenter != rNew) + { + aCenter = rNew; + ActionChanged(); + } +} + +void E3dSphereObj::SetSize(const basegfx::B3DVector& rNew) +{ + if(aSize != rNew) + { + aSize = rNew; + ActionChanged(); + } +} + +/************************************************************************* +|* +|* Get the name of the object (singular) +|* +\************************************************************************/ + +void E3dSphereObj::TakeObjNameSingul(XubString& rName) const +{ + rName=ImpGetResStr(STR_ObjNameSingulSphere3d); + + String aName( GetName() ); + if(aName.Len()) + { + rName += sal_Unicode(' '); + rName += sal_Unicode('\''); + rName += aName; + rName += sal_Unicode('\''); + } +} + +/************************************************************************* +|* +|* Get the name of the object (plural) +|* +\************************************************************************/ + +void E3dSphereObj::TakeObjNamePlural(XubString& rName) const +{ + rName=ImpGetResStr(STR_ObjNamePluralSphere3d); +} + +// eof diff --git a/svx/source/engine3d/string3d.src b/svx/source/engine3d/string3d.src new file mode 100644 index 000000000000..24b0592730ab --- /dev/null +++ b/svx/source/engine3d/string3d.src @@ -0,0 +1,116 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + // include ------------------------------------------------------------------ +#include <svx/dialogs.hrc> + // pragma ------------------------------------------------------------------- + + // Strings fuer die Draw-Dialoge -------------------------------------------- +String RID_SVX_3D_CREATE_LATHE +{ + Text [ en-US ] = "Create 3D rotation object" ; +}; +String RID_SVX_3D_UNDO_EXCHANGE_PASTE +{ + /* ### ACHTUNG: Neuer Text in Resource? Objekt(e) einfügen : Objekt(e) einf³gen */ + /* ### ACHTUNG: Neuer Text in Resource? Objekt(e) einfügen : Objekt(e) einf³gen */ + Text [ en-US ] = "Insert object(s)" ; +}; +String RID_SVX_3D_UNDO_SEGMENTS +{ + Text [ en-US ] = "Number of segments" ; +}; +String RID_SVX_3D_UNDO_DEEPTH +{ + Text [ en-US ] = "Object depth" ; +}; +String RID_SVX_3D_UNDO_FOCAL +{ + Text [ en-US ] = "Focal length" ; +}; +String RID_SVX_3D_UNDO_CAMPOS +{ + Text [ en-US ] = "Camera position" ; +}; +String RID_SVX_3D_UNDO_ROTATE +{ + Text [ en-US ] = "Rotate 3D object" ; +}; +String RID_SVX_3D_UNDO_EXTRUDE +{ + Text [ en-US ] = "Create extrusion object" ; +}; +String RID_SVX_3D_UNDO_LATHE +{ + /* ### ACHTUNG: Neuer Text in Resource? Rotationskörper erstellen : Rotationsk÷rper erstellen */ + /* ### ACHTUNG: Neuer Text in Resource? Rotationskörper erstellen : Rotationsk÷rper erstellen */ + Text [ en-US ] = "Create rotation object" ; +}; +String RID_SVX_3D_UNDO_BREAK_LATHE +{ + /* ### ACHTUNG: Neuer Text in Resource? Rotationskörper aufbrechen : Rotationsk÷rper aufbrechen */ + /* ### ACHTUNG: Neuer Text in Resource? Rotationskörper aufbrechen : Rotationsk÷rper aufbrechen */ + Text [ en-US ] = "Split 3D object" ; +}; +String RID_SVX_3D_UNDO_ATTRIBUTES +{ + Text [ en-US ] = "3D Attributes" ; +}; + // ********************************************************************** EOF + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/svx/source/engine3d/svx3ditems.cxx b/svx/source/engine3d/svx3ditems.cxx new file mode 100644 index 000000000000..68ce67febc25 --- /dev/null +++ b/svx/source/engine3d/svx3ditems.cxx @@ -0,0 +1,547 @@ +/************************************************************************* + * + * 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_svx.hxx" +#include <svx/svx3ditems.hxx> +#include <com/sun/star/drawing/NormalsKind.hpp> +#include <com/sun/star/drawing/TextureProjectionMode.hpp> +#include <com/sun/star/drawing/TextureKind.hpp> +#include <com/sun/star/drawing/TextureMode.hpp> +#include <com/sun/star/drawing/ProjectionMode.hpp> +#include <com/sun/star/drawing/ShadeMode.hpp> + + +////////////////////////////////////////////////////////////////////////////// + +using namespace ::rtl; +using namespace ::com::sun::star; + +////////////////////////////////////////////////////////////////////////////// +Svx3DPercentDiagonalItem::Svx3DPercentDiagonalItem(sal_uInt16 nVal) +: SfxUInt16Item(SDRATTR_3DOBJ_PERCENT_DIAGONAL, nVal) +{} + +Svx3DBackscaleItem::Svx3DBackscaleItem(sal_uInt16 nVal) +: SfxUInt16Item(SDRATTR_3DOBJ_BACKSCALE, nVal) +{} + +Svx3DDepthItem::Svx3DDepthItem(sal_uInt32 nVal) +: SfxUInt32Item(SDRATTR_3DOBJ_DEPTH, nVal) +{} + +Svx3DHorizontalSegmentsItem::Svx3DHorizontalSegmentsItem(sal_uInt32 nVal) +: SfxUInt32Item(SDRATTR_3DOBJ_HORZ_SEGS, nVal) +{} + +Svx3DVerticalSegmentsItem::Svx3DVerticalSegmentsItem(sal_uInt32 nVal) +: SfxUInt32Item(SDRATTR_3DOBJ_VERT_SEGS, nVal) +{} + +Svx3DEndAngleItem::Svx3DEndAngleItem(sal_uInt32 nVal) +: SfxUInt32Item(SDRATTR_3DOBJ_END_ANGLE, nVal) +{} + +Svx3DDoubleSidedItem::Svx3DDoubleSidedItem(BOOL bVal) +: SfxBoolItem(SDRATTR_3DOBJ_DOUBLE_SIDED, bVal) +{} + +////////////////////////////////////////////////////////////////////////////// +// #i28528# +// Added extra Item (Bool) for chart2 to be able to show reduced line geometry + +Svx3DReducedLineGeometryItem::Svx3DReducedLineGeometryItem(BOOL bVal) +: SfxBoolItem(SDRATTR_3DOBJ_REDUCED_LINE_GEOMETRY, bVal) +{} + +sal_uInt16 Svx3DReducedLineGeometryItem::GetVersion(sal_uInt16 /*nFileFormatVersion*/) const +{ + return 1; +} + +SfxPoolItem* Svx3DReducedLineGeometryItem::Create(SvStream& rIn, sal_uInt16 nItemVersion) const +{ + SfxBoolItem* pRetval = new Svx3DReducedLineGeometryItem(); + + if(nItemVersion > 0) + { + SfxBoolItem aBoolItem(Which(), rIn); + pRetval->SetValue(aBoolItem.GetValue()); + } + + return pRetval; +} + +////////////////////////////////////////////////////////////////////////////// + +Svx3DNormalsKindItem::Svx3DNormalsKindItem(sal_uInt16 nVal) +: SfxUInt16Item(SDRATTR_3DOBJ_NORMALS_KIND, nVal) +{} + +Svx3DNormalsInvertItem::Svx3DNormalsInvertItem(BOOL bVal) +: SfxBoolItem(SDRATTR_3DOBJ_NORMALS_INVERT, bVal) +{} + +Svx3DTextureProjectionXItem::Svx3DTextureProjectionXItem(sal_uInt16 nVal) +: SfxUInt16Item(SDRATTR_3DOBJ_TEXTURE_PROJ_X, nVal) +{} + +Svx3DTextureProjectionYItem::Svx3DTextureProjectionYItem(sal_uInt16 nVal) +: SfxUInt16Item(SDRATTR_3DOBJ_TEXTURE_PROJ_Y, nVal) +{} + +Svx3DShadow3DItem::Svx3DShadow3DItem(BOOL bVal) +: SfxBoolItem(SDRATTR_3DOBJ_SHADOW_3D, bVal) +{} + +Svx3DMaterialColorItem::Svx3DMaterialColorItem(const Color& rCol) +: SvxColorItem(rCol, SDRATTR_3DOBJ_MAT_COLOR) +{} + +Svx3DMaterialEmissionItem::Svx3DMaterialEmissionItem(const Color& rCol) +: SvxColorItem(rCol, SDRATTR_3DOBJ_MAT_EMISSION) +{} + +Svx3DMaterialSpecularItem::Svx3DMaterialSpecularItem(const Color& rCol) +: SvxColorItem(rCol, SDRATTR_3DOBJ_MAT_SPECULAR) +{} + +Svx3DMaterialSpecularIntensityItem::Svx3DMaterialSpecularIntensityItem(sal_uInt16 nVal) +: SfxUInt16Item(SDRATTR_3DOBJ_MAT_SPECULAR_INTENSITY, nVal) +{} + +Svx3DTextureKindItem::Svx3DTextureKindItem(sal_uInt16 nVal) +: SfxUInt16Item(SDRATTR_3DOBJ_TEXTURE_KIND, nVal) +{} + +Svx3DTextureModeItem::Svx3DTextureModeItem(sal_uInt16 nVal) +: SfxUInt16Item(SDRATTR_3DOBJ_TEXTURE_MODE, nVal) +{} + +Svx3DTextureFilterItem::Svx3DTextureFilterItem(BOOL bVal) +: SfxBoolItem(SDRATTR_3DOBJ_TEXTURE_FILTER, bVal) +{} + +Svx3DPerspectiveItem::Svx3DPerspectiveItem(sal_uInt16 nVal) +: SfxUInt16Item(SDRATTR_3DSCENE_PERSPECTIVE, nVal) +{} + +Svx3DDistanceItem::Svx3DDistanceItem(sal_uInt32 nVal) +: SfxUInt32Item(SDRATTR_3DSCENE_DISTANCE, nVal) +{} + +Svx3DFocalLengthItem::Svx3DFocalLengthItem(sal_uInt32 nVal) +: SfxUInt32Item(SDRATTR_3DSCENE_FOCAL_LENGTH, nVal) +{} + +Svx3DTwoSidedLightingItem::Svx3DTwoSidedLightingItem(BOOL bVal) +: SfxBoolItem(SDRATTR_3DSCENE_TWO_SIDED_LIGHTING, bVal) +{} + +Svx3DLightcolor1Item::Svx3DLightcolor1Item(const Color& rCol) +: SvxColorItem(rCol, SDRATTR_3DSCENE_LIGHTCOLOR_1) +{} + +Svx3DLightcolor2Item::Svx3DLightcolor2Item(const Color& rCol) +: SvxColorItem(rCol, SDRATTR_3DSCENE_LIGHTCOLOR_2) +{} + +Svx3DLightcolor3Item::Svx3DLightcolor3Item(const Color& rCol) +: SvxColorItem(rCol, SDRATTR_3DSCENE_LIGHTCOLOR_3) +{} + +Svx3DLightcolor4Item::Svx3DLightcolor4Item(const Color& rCol) +: SvxColorItem(rCol, SDRATTR_3DSCENE_LIGHTCOLOR_4) +{} + +Svx3DLightcolor5Item::Svx3DLightcolor5Item(const Color& rCol) +: SvxColorItem(rCol, SDRATTR_3DSCENE_LIGHTCOLOR_5) +{} + +Svx3DLightcolor6Item::Svx3DLightcolor6Item(const Color& rCol) +: SvxColorItem(rCol, SDRATTR_3DSCENE_LIGHTCOLOR_6) +{} + +Svx3DLightcolor7Item::Svx3DLightcolor7Item(const Color& rCol) +: SvxColorItem(rCol, SDRATTR_3DSCENE_LIGHTCOLOR_7) +{} + +Svx3DLightcolor8Item::Svx3DLightcolor8Item(const Color& rCol) +: SvxColorItem(rCol, SDRATTR_3DSCENE_LIGHTCOLOR_8) +{} + +Svx3DAmbientcolorItem::Svx3DAmbientcolorItem(const Color& rCol) +: SvxColorItem(rCol, SDRATTR_3DSCENE_AMBIENTCOLOR) +{} + +Svx3DLightOnOff1Item::Svx3DLightOnOff1Item(BOOL bVal) +: SfxBoolItem(SDRATTR_3DSCENE_LIGHTON_1, bVal) +{} + +Svx3DLightOnOff2Item::Svx3DLightOnOff2Item(BOOL bVal) +: SfxBoolItem(SDRATTR_3DSCENE_LIGHTON_2, bVal) +{} + +Svx3DLightOnOff3Item::Svx3DLightOnOff3Item(BOOL bVal) +: SfxBoolItem(SDRATTR_3DSCENE_LIGHTON_3, bVal) +{} + +Svx3DLightOnOff4Item::Svx3DLightOnOff4Item(BOOL bVal) +: SfxBoolItem(SDRATTR_3DSCENE_LIGHTON_4, bVal) +{} + +Svx3DLightOnOff5Item::Svx3DLightOnOff5Item(BOOL bVal) +: SfxBoolItem(SDRATTR_3DSCENE_LIGHTON_5, bVal) +{} + +Svx3DLightOnOff6Item::Svx3DLightOnOff6Item(BOOL bVal) +: SfxBoolItem(SDRATTR_3DSCENE_LIGHTON_6, bVal) +{} + +Svx3DLightOnOff7Item::Svx3DLightOnOff7Item(BOOL bVal) +: SfxBoolItem(SDRATTR_3DSCENE_LIGHTON_7, bVal) +{} + +Svx3DLightOnOff8Item::Svx3DLightOnOff8Item(BOOL bVal) +: SfxBoolItem(SDRATTR_3DSCENE_LIGHTON_8, bVal) +{} + +Svx3DLightDirection1Item::Svx3DLightDirection1Item(const basegfx::B3DVector& rVec) +: SvxB3DVectorItem(SDRATTR_3DSCENE_LIGHTDIRECTION_1, rVec) +{} + +Svx3DLightDirection2Item::Svx3DLightDirection2Item(const basegfx::B3DVector& rVec) +: SvxB3DVectorItem(SDRATTR_3DSCENE_LIGHTDIRECTION_2, rVec) +{} + +Svx3DLightDirection3Item::Svx3DLightDirection3Item(const basegfx::B3DVector& rVec) +: SvxB3DVectorItem(SDRATTR_3DSCENE_LIGHTDIRECTION_3, rVec) +{} + +Svx3DLightDirection4Item::Svx3DLightDirection4Item(const basegfx::B3DVector& rVec) +: SvxB3DVectorItem(SDRATTR_3DSCENE_LIGHTDIRECTION_4, rVec) +{} + +Svx3DLightDirection5Item::Svx3DLightDirection5Item(const basegfx::B3DVector& rVec) +: SvxB3DVectorItem(SDRATTR_3DSCENE_LIGHTDIRECTION_5, rVec) +{} + +Svx3DLightDirection6Item::Svx3DLightDirection6Item(const basegfx::B3DVector& rVec) +: SvxB3DVectorItem(SDRATTR_3DSCENE_LIGHTDIRECTION_6, rVec) +{} + +Svx3DLightDirection7Item::Svx3DLightDirection7Item(const basegfx::B3DVector& rVec) +: SvxB3DVectorItem(SDRATTR_3DSCENE_LIGHTDIRECTION_7, rVec) +{} + +Svx3DLightDirection8Item::Svx3DLightDirection8Item(const basegfx::B3DVector& rVec) +: SvxB3DVectorItem(SDRATTR_3DSCENE_LIGHTDIRECTION_8, rVec) +{} + +Svx3DShadowSlantItem::Svx3DShadowSlantItem(sal_uInt16 nVal) +: SfxUInt16Item(SDRATTR_3DSCENE_SHADOW_SLANT, nVal) +{} + +Svx3DShadeModeItem::Svx3DShadeModeItem(sal_uInt16 nVal) +: SfxUInt16Item(SDRATTR_3DSCENE_SHADE_MODE, nVal) +{} + +////////////////////////////////////////////////////////////////////////////// +// #107245# + +Svx3DSmoothNormalsItem::Svx3DSmoothNormalsItem(BOOL bVal) +: SfxBoolItem(SDRATTR_3DOBJ_SMOOTH_NORMALS, bVal) +{} + +sal_uInt16 Svx3DSmoothNormalsItem::GetVersion(sal_uInt16 /*nFileFormatVersion*/) const +{ + return 1; +} + +SfxPoolItem* Svx3DSmoothNormalsItem::Create(SvStream& rIn, sal_uInt16 nItemVersion) const +{ + SfxBoolItem* pRetval = new Svx3DSmoothNormalsItem(); + + if(nItemVersion > 0) + { + SfxBoolItem aBoolItem(Which(), rIn); + pRetval->SetValue(aBoolItem.GetValue()); + } + + return pRetval; +} + +////////////////////////////////////////////////////////////////////////////// +// #107245# + +Svx3DSmoothLidsItem::Svx3DSmoothLidsItem(BOOL bVal) +: SfxBoolItem(SDRATTR_3DOBJ_SMOOTH_LIDS, bVal) +{} + +sal_uInt16 Svx3DSmoothLidsItem::GetVersion(sal_uInt16 /*nFileFormatVersion*/) const +{ + return 1; +} + +SfxPoolItem* Svx3DSmoothLidsItem::Create(SvStream& rIn, sal_uInt16 nItemVersion) const +{ + SfxBoolItem* pRetval = new Svx3DSmoothLidsItem(); + + if(nItemVersion > 0) + { + SfxBoolItem aBoolItem(Which(), rIn); + pRetval->SetValue(aBoolItem.GetValue()); + } + + return pRetval; +} + +////////////////////////////////////////////////////////////////////////////// +// #107245# + +Svx3DCharacterModeItem::Svx3DCharacterModeItem(BOOL bVal) +: SfxBoolItem(SDRATTR_3DOBJ_CHARACTER_MODE, bVal) +{} + +sal_uInt16 Svx3DCharacterModeItem::GetVersion(sal_uInt16 /*nFileFormatVersion*/) const +{ + return 1; +} + +SfxPoolItem* Svx3DCharacterModeItem::Create(SvStream& rIn, sal_uInt16 nItemVersion) const +{ + SfxBoolItem* pRetval = new Svx3DCharacterModeItem(); + + if(nItemVersion > 0) + { + SfxBoolItem aBoolItem(Which(), rIn); + pRetval->SetValue(aBoolItem.GetValue()); + } + + return pRetval; +} + +////////////////////////////////////////////////////////////////////////////// +// #107245# + +Svx3DCloseFrontItem::Svx3DCloseFrontItem(BOOL bVal) +: SfxBoolItem(SDRATTR_3DOBJ_CLOSE_FRONT, bVal) +{} + +sal_uInt16 Svx3DCloseFrontItem::GetVersion(sal_uInt16 /*nFileFormatVersion*/) const +{ + return 1; +} + +SfxPoolItem* Svx3DCloseFrontItem::Create(SvStream& rIn, sal_uInt16 nItemVersion) const +{ + SfxBoolItem* pRetval = new Svx3DCloseFrontItem(); + + if(nItemVersion > 0) + { + SfxBoolItem aBoolItem(Which(), rIn); + pRetval->SetValue(aBoolItem.GetValue()); + } + + return pRetval; +} + +////////////////////////////////////////////////////////////////////////////// +// #107245# + +Svx3DCloseBackItem::Svx3DCloseBackItem(BOOL bVal) +: SfxBoolItem(SDRATTR_3DOBJ_CLOSE_BACK, bVal) +{} + +sal_uInt16 Svx3DCloseBackItem::GetVersion(sal_uInt16 /*nFileFormatVersion*/) const +{ + return 1; +} + +SfxPoolItem* Svx3DCloseBackItem::Create(SvStream& rIn, sal_uInt16 nItemVersion) const +{ + SfxBoolItem* pRetval = new Svx3DCloseBackItem(); + + if(nItemVersion > 0) + { + SfxBoolItem aBoolItem(Which(), rIn); + pRetval->SetValue(aBoolItem.GetValue()); + } + + return pRetval; +} + +////////////////////////////////////////////////////////////////////////////// + +// Svx3DNormalsKindItem: use drawing::NormalsKind +sal_Bool Svx3DNormalsKindItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/) const +{ + rVal <<= (drawing::NormalsKind)GetValue(); + return sal_True; +} + +sal_Bool Svx3DNormalsKindItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/) +{ + drawing::NormalsKind eVar; + if(!(rVal >>= eVar)) + return sal_False; + SetValue((sal_Int16)eVar); + return sal_True; +} + +SfxPoolItem* Svx3DNormalsKindItem::Clone(SfxItemPool* /*pPool*/) const +{ + return new Svx3DNormalsKindItem(*this); +} + +// Svx3DTextureProjectionXItem: use drawing::TextureProjectionMode +sal_Bool Svx3DTextureProjectionXItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/) const +{ + rVal <<= (drawing::TextureProjectionMode)GetValue(); + return sal_True; +} + +sal_Bool Svx3DTextureProjectionXItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/) +{ + drawing::TextureProjectionMode eVar; + if(!(rVal >>= eVar)) + return sal_False; + SetValue((sal_Int16)eVar); + return sal_True; +} + +SfxPoolItem* Svx3DTextureProjectionXItem::Clone(SfxItemPool* /*pPool*/) const +{ + return new Svx3DTextureProjectionXItem(*this); +} + +// Svx3DTextureProjectionYItem: use drawing::TextureProjectionMode +sal_Bool Svx3DTextureProjectionYItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/) const +{ + rVal <<= (drawing::TextureProjectionMode)GetValue(); + return sal_True; +} + +sal_Bool Svx3DTextureProjectionYItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/) +{ + drawing::TextureProjectionMode eVar; + if(!(rVal >>= eVar)) + return sal_False; + SetValue((sal_Int16)eVar); + return sal_True; +} + +SfxPoolItem* Svx3DTextureProjectionYItem::Clone(SfxItemPool* /*pPool*/) const +{ + return new Svx3DTextureProjectionYItem(*this); +} + +// Svx3DTextureKindItem: use drawing::TextureKind +sal_Bool Svx3DTextureKindItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/) const +{ + rVal <<= (drawing::TextureKind)GetValue(); + return sal_True; +} + +sal_Bool Svx3DTextureKindItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/) +{ + drawing::TextureKind eVar; + if(!(rVal >>= eVar)) + return sal_False; + SetValue((sal_Int16)eVar); + return sal_True; +} + +SfxPoolItem* Svx3DTextureKindItem::Clone(SfxItemPool* /*pPool*/) const +{ + return new Svx3DTextureKindItem(*this); +} + +// Svx3DTextureModeItem: use drawing:TextureMode +sal_Bool Svx3DTextureModeItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/) const +{ + rVal <<= (drawing::TextureMode)GetValue(); + return sal_True; +} + +sal_Bool Svx3DTextureModeItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/) +{ + drawing::TextureMode eVar; + if(!(rVal >>= eVar)) + return sal_False; + SetValue((sal_Int16)eVar); + return sal_True; +} + +SfxPoolItem* Svx3DTextureModeItem::Clone(SfxItemPool* /*pPool*/) const +{ + return new Svx3DTextureModeItem(*this); +} + +// Svx3DPerspectiveItem: use drawing::ProjectionMode +sal_Bool Svx3DPerspectiveItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/) const +{ + rVal <<= (drawing::ProjectionMode)GetValue(); + return sal_True; +} + +sal_Bool Svx3DPerspectiveItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/) +{ + drawing::ProjectionMode eVar; + if(!(rVal >>= eVar)) + return sal_False; + SetValue((sal_Int16)eVar); + return sal_True; +} + +SfxPoolItem* Svx3DPerspectiveItem::Clone(SfxItemPool* /*pPool*/) const +{ + return new Svx3DPerspectiveItem(*this); +} + +// Svx3DShadeModeItem: use drawing::ShadeMode +sal_Bool Svx3DShadeModeItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/) const +{ + rVal <<= (drawing::ShadeMode)GetValue(); + return sal_True; +} + +sal_Bool Svx3DShadeModeItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/) +{ + drawing::ShadeMode eVar; + if(!(rVal >>= eVar)) + return sal_False; + SetValue((sal_Int16)eVar); + return sal_True; +} + +SfxPoolItem* Svx3DShadeModeItem::Clone(SfxItemPool* /*pPool*/) const +{ + return new Svx3DShadeModeItem(*this); +} + +// EOF diff --git a/svx/source/engine3d/view3d.cxx b/svx/source/engine3d/view3d.cxx new file mode 100644 index 000000000000..97fee2250658 --- /dev/null +++ b/svx/source/engine3d/view3d.cxx @@ -0,0 +1,1959 @@ +/************************************************************************* + * + * 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_svx.hxx" + +#include <vcl/wrkwin.hxx> +#include <svx/svdogrp.hxx> +#include <svx/svdopath.hxx> +#include <tools/shl.hxx> +#include "svditer.hxx" +#include <svx/svdpool.hxx> +#include <svx/svdorect.hxx> +#include <svx/svdmodel.hxx> +#include <svx/svdpagv.hxx> +#include <svx/svxids.hrc> +#include <editeng/colritem.hxx> +#include <svx/xtable.hxx> +#include <svx/svdview.hxx> +#include <svx/dialogs.hrc> +#include <svx/dialmgr.hxx> +#include "globl3d.hxx" +#include <svx/obj3d.hxx> +#include <svx/lathe3d.hxx> +#include <svx/sphere3d.hxx> +#include <svx/extrud3d.hxx> +#include <svx/cube3d.hxx> +#include <svx/polysc3d.hxx> +#include "dragmt3d.hxx" +#include <svx/view3d.hxx> +#include <svx/svdundo.hxx> +#include <svx/xflclit.hxx> +#include <svx/xlnclit.hxx> +#include <svx/svdograf.hxx> +#include <svx/xbtmpit.hxx> +#include <svx/xflbmtit.hxx> +#include <basegfx/range/b2drange.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <svx/xlnwtit.hxx> +#include <svx/sdr/overlay/overlaypolypolygon.hxx> +#include <svx/sdr/overlay/overlaymanager.hxx> +#include <sdrpaintwindow.hxx> +#include <svx/sdr/contact/viewcontactofe3dscene.hxx> +#include <drawinglayer/geometry/viewinformation3d.hxx> +#include <svx/sdrpagewindow.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <svx/sdr/contact/objectcontact.hxx> +#include <svx/sdr/contact/viewobjectcontact.hxx> +#include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx> +#include <svx/sdr/overlay/overlayprimitive2dsequenceobject.hxx> +#include <drawinglayer/primitive2d/transformprimitive2d.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> + +#define ITEMVALUE(ItemSet,Id,Cast) ((const Cast&)(ItemSet).Get(Id)).GetValue() + +TYPEINIT1(E3dView, SdrView); + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Migrate Marking + +class Impl3DMirrorConstructOverlay +{ + // The OverlayObjects + ::sdr::overlay::OverlayObjectList maObjects; + + // the view + const E3dView& mrView; + + // the object count + sal_uInt32 mnCount; + + // the unmirrored polygons + basegfx::B2DPolyPolygon* mpPolygons; + + // the overlay geometry from selected objects + drawinglayer::primitive2d::Primitive2DSequence maFullOverlay; + +public: + Impl3DMirrorConstructOverlay(const E3dView& rView); + ~Impl3DMirrorConstructOverlay(); + + void SetMirrorAxis(Point aMirrorAxisA, Point aMirrorAxisB); +}; + +Impl3DMirrorConstructOverlay::Impl3DMirrorConstructOverlay(const E3dView& rView) +: maObjects(), + mrView(rView), + mnCount(rView.GetMarkedObjectCount()), + mpPolygons(0), + maFullOverlay() +{ + if(mnCount) + { + if(mrView.IsSolidDragging()) + { + SdrPageView* pPV = rView.GetSdrPageView(); + + if(pPV && pPV->PageWindowCount()) + { + sdr::contact::ObjectContact& rOC = pPV->GetPageWindow(0)->GetObjectContact(); + sdr::contact::DisplayInfo aDisplayInfo; + + // Do not use the last ViewPort set at the OC at the last ProcessDisplay() + rOC.resetViewPort(); + + for(sal_uInt32 a(0);a < mnCount;a++) + { + SdrObject* pObject = mrView.GetMarkedObjectByIndex(a); + + if(pObject) + { + sdr::contact::ViewContact& rVC = pObject->GetViewContact(); + sdr::contact::ViewObjectContact& rVOC = rVC.GetViewObjectContact(rOC); + + const drawinglayer::primitive2d::Primitive2DSequence aNewSequence(rVOC.getPrimitive2DSequenceHierarchy(aDisplayInfo)); + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(maFullOverlay, aNewSequence); + } + } + } + } + else + { + mpPolygons = new basegfx::B2DPolyPolygon[mnCount]; + + for(sal_uInt32 a(0); a < mnCount; a++) + { + SdrObject* pObject = mrView.GetMarkedObjectByIndex(a); + mpPolygons[mnCount - (a + 1)] = pObject->TakeXorPoly(); + } + } + } +} + +Impl3DMirrorConstructOverlay::~Impl3DMirrorConstructOverlay() +{ + // The OverlayObjects are cleared using the destructor of OverlayObjectList. + // That destructor calls clear() at the list which removes all objects from the + // OverlayManager and deletes them. + if(!mrView.IsSolidDragging()) + { + delete[] mpPolygons; + } +} + +void Impl3DMirrorConstructOverlay::SetMirrorAxis(Point aMirrorAxisA, Point aMirrorAxisB) +{ + // get rid of old overlay objects + maObjects.clear(); + + // create new ones + for(sal_uInt32 a(0); a < mrView.PaintWindowCount(); a++) + { + SdrPaintWindow* pCandidate = mrView.GetPaintWindow(a); + ::sdr::overlay::OverlayManager* pTargetOverlay = pCandidate->GetOverlayManager(); + + if(pTargetOverlay) + { + // buld transfoprmation: translate and rotate so that given edge is + // on x axis, them mirror in y and translate back + const basegfx::B2DVector aEdge(aMirrorAxisB.X() - aMirrorAxisA.X(), aMirrorAxisB.Y() - aMirrorAxisA.Y()); + basegfx::B2DHomMatrix aMatrixTransform(basegfx::tools::createTranslateB2DHomMatrix( + -aMirrorAxisA.X(), -aMirrorAxisA.Y())); + aMatrixTransform.rotate(-atan2(aEdge.getY(), aEdge.getX())); + aMatrixTransform.scale(1.0, -1.0); + aMatrixTransform.rotate(atan2(aEdge.getY(), aEdge.getX())); + aMatrixTransform.translate(aMirrorAxisA.X(), aMirrorAxisA.Y()); + + if(mrView.IsSolidDragging()) + { + if(maFullOverlay.hasElements()) + { + drawinglayer::primitive2d::Primitive2DSequence aContent(maFullOverlay); + + if(!aMatrixTransform.isIdentity()) + { + // embed in transformation group + drawinglayer::primitive2d::Primitive2DReference aTransformPrimitive2D(new drawinglayer::primitive2d::TransformPrimitive2D(aMatrixTransform, aContent)); + aContent = drawinglayer::primitive2d::Primitive2DSequence(&aTransformPrimitive2D, 1); + } + + // if we have full overlay from selected objects, embed with 50% transparence, the + // transformation is added to the OverlayPrimitive2DSequenceObject + drawinglayer::primitive2d::Primitive2DReference aUnifiedTransparencePrimitive2D(new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(aContent, 0.5)); + aContent = drawinglayer::primitive2d::Primitive2DSequence(&aUnifiedTransparencePrimitive2D, 1); + + sdr::overlay::OverlayPrimitive2DSequenceObject* pNew = new sdr::overlay::OverlayPrimitive2DSequenceObject(aContent); + + pTargetOverlay->add(*pNew); + maObjects.append(*pNew); + } + } + else + { + for(sal_uInt32 b(0); b < mnCount; b++) + { + // apply to polygon + basegfx::B2DPolyPolygon aPolyPolygon(mpPolygons[b]); + aPolyPolygon.transform(aMatrixTransform); + + ::sdr::overlay::OverlayPolyPolygonStriped* pNew = new ::sdr::overlay::OverlayPolyPolygonStriped(aPolyPolygon); + pTargetOverlay->add(*pNew); + maObjects.append(*pNew); + } + } + } + } +} + +/************************************************************************* +|* +|* Konstruktor 1 +|* +\************************************************************************/ + +E3dView::E3dView(SdrModel* pModel, OutputDevice* pOut) : + SdrView(pModel, pOut) +{ + InitView (); +} + +/************************************************************************* +|* +|* DrawMarkedObj ueberladen, da eventuell nur einzelne 3D-Objekte +|* gezeichnet werden sollen +|* +\************************************************************************/ + +void E3dView::DrawMarkedObj(OutputDevice& rOut) const +{ + // Existieren 3D-Objekte, deren Szenen nicht selektiert sind? + BOOL bSpecialHandling = FALSE; + E3dScene *pScene = NULL; + + long nCnt = GetMarkedObjectCount(); + for(long nObjs = 0;nObjs < nCnt;nObjs++) + { + SdrObject *pObj = GetMarkedObjectByIndex(nObjs); + if(pObj && pObj->ISA(E3dCompoundObject)) + { + // zugehoerige Szene + pScene = ((E3dCompoundObject*)pObj)->GetScene(); + if(pScene && !IsObjMarked(pScene)) + bSpecialHandling = TRUE; + } + // Alle SelectionFlags zuruecksetzen + if(pObj && pObj->ISA(E3dObject)) + { + pScene = ((E3dObject*)pObj)->GetScene(); + if(pScene) + pScene->SetSelected(FALSE); + } + } + + if(bSpecialHandling) + { + // SelectionFlag bei allen zu 3D Objekten gehoerigen + // Szenen und deren Objekten auf nicht selektiert setzen + long nObjs; + for(nObjs = 0;nObjs < nCnt;nObjs++) + { + SdrObject *pObj = GetMarkedObjectByIndex(nObjs); + if(pObj && pObj->ISA(E3dCompoundObject)) + { + // zugehoerige Szene + pScene = ((E3dCompoundObject*)pObj)->GetScene(); + if(pScene) + pScene->SetSelected(FALSE); + } + } + + // bei allen direkt selektierten Objekten auf selektiert setzen + SdrMark* pM = NULL; + + for(nObjs = 0;nObjs < nCnt;nObjs++) + { + SdrObject *pObj = GetMarkedObjectByIndex(nObjs); + if(pObj && pObj->ISA(E3dObject)) + { + // Objekt markieren + E3dObject* p3DObj = (E3dObject*)pObj; + p3DObj->SetSelected(TRUE); + pScene = p3DObj->GetScene(); + pM = GetSdrMarkByIndex(nObjs); + } + } + + if(pScene) + { + // code from parent + SortMarkedObjects(); + + pScene->SetDrawOnlySelected(TRUE); + pScene->SingleObjectPainter(rOut); // #110094#-17 + pScene->SetDrawOnlySelected(FALSE); + } + + // SelectionFlag zuruecksetzen + for(nObjs = 0;nObjs < nCnt;nObjs++) + { + SdrObject *pObj = GetMarkedObjectByIndex(nObjs); + if(pObj && pObj->ISA(E3dCompoundObject)) + { + // zugehoerige Szene + pScene = ((E3dCompoundObject*)pObj)->GetScene(); + if(pScene) + pScene->SetSelected(FALSE); + } + } + } + else + { + // call parent + SdrExchangeView::DrawMarkedObj(rOut); + } +} + +/************************************************************************* +|* +|* Model holen ueberladen, da bei einzelnen 3D Objekten noch eine Szene +|* untergeschoben werden muss +|* +\************************************************************************/ + +SdrModel* E3dView::GetMarkedObjModel() const +{ + // Existieren 3D-Objekte, deren Szenen nicht selektiert sind? + bool bSpecialHandling(false); + const sal_uInt32 nCount(GetMarkedObjectCount()); + sal_uInt32 nObjs(0); + E3dScene *pScene = 0; + + for(nObjs = 0; nObjs < nCount; nObjs++) + { + const SdrObject* pObj = GetMarkedObjectByIndex(nObjs); + + if(!bSpecialHandling && pObj && pObj->ISA(E3dCompoundObject)) + { + // if the object is selected, but it's scene not, + // we need special handling + pScene = ((E3dCompoundObject*)pObj)->GetScene(); + + if(pScene && !IsObjMarked(pScene)) + { + bSpecialHandling = true; + } + } + + if(pObj && pObj->ISA(E3dObject)) + { + // reset all selection flags at 3D objects + pScene = ((E3dObject*)pObj)->GetScene(); + + if(pScene) + { + pScene->SetSelected(false); + } + } + } + + if(!bSpecialHandling) + { + // call parent + return SdrView::GetMarkedObjModel(); + } + + SdrModel* pNewModel = 0; + Rectangle aSelectedSnapRect; + + // set 3d selection flags at all directly selected objects + // and collect SnapRect of selected objects + for(nObjs = 0; nObjs < nCount; nObjs++) + { + SdrObject *pObj = GetMarkedObjectByIndex(nObjs); + + if(pObj && pObj->ISA(E3dCompoundObject)) + { + // mark object, but not scenes + E3dCompoundObject* p3DObj = (E3dCompoundObject*)pObj; + p3DObj->SetSelected(true); + aSelectedSnapRect.Union(p3DObj->GetSnapRect()); + } + } + + // create new mark list which contains all indirectly selected3d + // scenes as selected objects + SdrMarkList aOldML(GetMarkedObjectList()); + SdrMarkList aNewML; + SdrMarkList& rCurrentMarkList = ((E3dView*)this)->GetMarkedObjectListWriteAccess(); + rCurrentMarkList = aNewML; + + for(nObjs = 0; nObjs < nCount; nObjs++) + { + SdrObject *pObj = aOldML.GetMark(nObjs)->GetMarkedSdrObj(); + + if(pObj && pObj->ISA(E3dObject)) + { + pScene = ((E3dObject*)pObj)->GetScene(); + + if(pScene && !IsObjMarked(pScene) && GetSdrPageView()) + { + ((E3dView*)this)->MarkObj(pScene, GetSdrPageView(), FALSE, TRUE); + } + } + } + + // call parent. This will copy all scenes and the selection flags at the 3d objectss. So + // it will be possible to delete all non-selected 3d objects from the cloned 3d scenes + pNewModel = SdrView::GetMarkedObjModel(); + + if(pNewModel) + { + for(sal_uInt16 nPg(0); nPg < pNewModel->GetPageCount(); nPg++) + { + const SdrPage* pSrcPg=pNewModel->GetPage(nPg); + const sal_uInt32 nObAnz(pSrcPg->GetObjCount()); + + for(sal_uInt32 nOb(0); nOb < nObAnz; nOb++) + { + const SdrObject* pSrcOb=pSrcPg->GetObj(nOb); + + if(pSrcOb->ISA(E3dScene)) + { + pScene = (E3dScene*)pSrcOb; + + // delete all not intentionally cloned 3d objects + pScene->removeAllNonSelectedObjects(); + + // reset select flags and set SnapRect of all selected objects + pScene->SetSelected(false); + pScene->SetSnapRect(aSelectedSnapRect); + } + } + } + } + + // restore old selection + rCurrentMarkList = aOldML; + + // model zurueckgeben + return pNewModel; +} + +/************************************************************************* +|* +|* Bei Paste muss - falls in eine Scene eingefuegt wird - die +|* Objekte der Szene eingefuegt werden, die Szene selbst aber nicht +|* +\************************************************************************/ + +BOOL E3dView::Paste(const SdrModel& rMod, const Point& rPos, SdrObjList* pLst, UINT32 nOptions) +{ + BOOL bRetval = FALSE; + + // Liste holen + Point aPos(rPos); + SdrObjList* pDstList = pLst; + ImpGetPasteObjList(aPos, pDstList); + + if(!pDstList) + return FALSE; + + // Owner der Liste holen + SdrObject* pOwner = pDstList->GetOwnerObj(); + if(pOwner && pOwner->ISA(E3dScene)) + { + E3dScene* pDstScene = (E3dScene*)pOwner; + BegUndo(SVX_RESSTR(RID_SVX_3D_UNDO_EXCHANGE_PASTE)); + + // Alle Objekte aus E3dScenes kopieren und direkt einfuegen + for(sal_uInt16 nPg(0); nPg < rMod.GetPageCount(); nPg++) + { + const SdrPage* pSrcPg=rMod.GetPage(nPg); + sal_uInt32 nObAnz(pSrcPg->GetObjCount()); + + // calculate offset for paste + Rectangle aR = pSrcPg->GetAllObjBoundRect(); + Point aDist(aPos - aR.Center()); + + // Unterobjekte von Szenen einfuegen + for(sal_uInt32 nOb(0); nOb < nObAnz; nOb++) + { + const SdrObject* pSrcOb = pSrcPg->GetObj(nOb); + if(pSrcOb->ISA(E3dScene)) + { + E3dScene* pSrcScene = (E3dScene*)pSrcOb; + ImpCloneAll3DObjectsToDestScene(pSrcScene, pDstScene, aDist); + } + } + } + EndUndo(); + } + else + { + // call parent + bRetval = SdrView::Paste(rMod, rPos, pLst, nOptions); + } + + // und Rueckgabewert liefern + return bRetval; +} + +// #83403# Service routine used from local Clone() and from SdrCreateView::EndCreateObj(...) +BOOL E3dView::ImpCloneAll3DObjectsToDestScene(E3dScene* pSrcScene, E3dScene* pDstScene, Point /*aOffset*/) +{ + BOOL bRetval(FALSE); + + if(pSrcScene && pDstScene) + { + const sdr::contact::ViewContactOfE3dScene& rVCSceneDst = static_cast< sdr::contact::ViewContactOfE3dScene& >(pDstScene->GetViewContact()); + const drawinglayer::geometry::ViewInformation3D aViewInfo3DDst(rVCSceneDst.getViewInformation3D()); + const sdr::contact::ViewContactOfE3dScene& rVCSceneSrc = static_cast< sdr::contact::ViewContactOfE3dScene& >(pSrcScene->GetViewContact()); + const drawinglayer::geometry::ViewInformation3D aViewInfo3DSrc(rVCSceneSrc.getViewInformation3D()); + + for(sal_uInt32 i(0); i < pSrcScene->GetSubList()->GetObjCount(); i++) + { + E3dCompoundObject* pCompoundObj = dynamic_cast< E3dCompoundObject* >(pSrcScene->GetSubList()->GetObj(i)); + + if(pCompoundObj) + { + // #116235# + E3dCompoundObject* pNewCompoundObj = dynamic_cast< E3dCompoundObject* >(pCompoundObj->Clone()); + + if(pNewCompoundObj) + { + // get dest scene's current range in 3D world coordinates + const basegfx::B3DHomMatrix aSceneToWorldTrans(pDstScene->GetFullTransform()); + basegfx::B3DRange aSceneRange(pDstScene->GetBoundVolume()); + aSceneRange.transform(aSceneToWorldTrans); + + // get new object's implied object transformation + const basegfx::B3DHomMatrix aNewObjectTrans(pNewCompoundObj->GetTransform()); + + // get new object's range in 3D world coordinates in dest scene + // as if it were already added + const basegfx::B3DHomMatrix aObjectToWorldTrans(aSceneToWorldTrans * aNewObjectTrans); + basegfx::B3DRange aObjectRange(pNewCompoundObj->GetBoundVolume()); + aObjectRange.transform(aObjectToWorldTrans); + + // get scale adaption + const basegfx::B3DVector aSceneScale(aSceneRange.getRange()); + const basegfx::B3DVector aObjectScale(aObjectRange.getRange()); + double fScale(1.0); + + // if new object's size in X,Y or Z is bigger that 80% of dest scene, adapt scale + // to not change the scene by the inserted object + const double fSizeFactor(0.5); + + if(aObjectScale.getX() * fScale > aSceneScale.getX() * fSizeFactor) + { + const double fObjSize(aObjectScale.getX() * fScale); + const double fFactor((aSceneScale.getX() * fSizeFactor) / (basegfx::fTools::equalZero(fObjSize) ? 1.0 : fObjSize)); + fScale *= fFactor; + } + + if(aObjectScale.getY() * fScale > aSceneScale.getY() * fSizeFactor) + { + const double fObjSize(aObjectScale.getY() * fScale); + const double fFactor((aSceneScale.getY() * fSizeFactor) / (basegfx::fTools::equalZero(fObjSize) ? 1.0 : fObjSize)); + fScale *= fFactor; + } + + if(aObjectScale.getZ() * fScale > aSceneScale.getZ() * fSizeFactor) + { + const double fObjSize(aObjectScale.getZ() * fScale); + const double fFactor((aSceneScale.getZ() * fSizeFactor) / (basegfx::fTools::equalZero(fObjSize) ? 1.0 : fObjSize)); + fScale *= fFactor; + } + + // get translation adaption + const basegfx::B3DPoint aSceneCenter(aSceneRange.getCenter()); + const basegfx::B3DPoint aObjectCenter(aObjectRange.getCenter()); + + // build full modification transform. The object's transformation + // shall be modified, so start at object coordinates; transform to 3d world coor + basegfx::B3DHomMatrix aModifyingTransform(aObjectToWorldTrans); + + // translate to absolute center in 3d world coor + aModifyingTransform.translate(-aObjectCenter.getX(), -aObjectCenter.getY(), -aObjectCenter.getZ()); + + // scale to dest size in 3d world coor + aModifyingTransform.scale(fScale, fScale, fScale); + + // translate to dest scene center in 3d world coor + aModifyingTransform.translate(aSceneCenter.getX(), aSceneCenter.getY(), aSceneCenter.getZ()); + + // transform from 3d world to dest object coordinates + basegfx::B3DHomMatrix aWorldToObject(aObjectToWorldTrans); + aWorldToObject.invert(); + aModifyingTransform = aWorldToObject * aModifyingTransform; + + // correct implied object transform by applying changing one in object coor + pNewCompoundObj->SetTransform(aModifyingTransform * aNewObjectTrans); + + // fill and insert new object + pNewCompoundObj->SetModel(pDstScene->GetModel()); + pNewCompoundObj->SetPage(pDstScene->GetPage()); + pNewCompoundObj->NbcSetLayer(pCompoundObj->GetLayer()); + pNewCompoundObj->NbcSetStyleSheet(pCompoundObj->GetStyleSheet(), sal_True); + pDstScene->Insert3DObj(pNewCompoundObj); + bRetval = TRUE; + + // Undo anlegen + if( GetModel()->IsUndoEnabled() ) + AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pNewCompoundObj)); + } + } + } + } + + return bRetval; +} + +/************************************************************************* +|* +|* 3D-Konvertierung moeglich? +|* +\************************************************************************/ + +BOOL E3dView::IsConvertTo3DObjPossible() const +{ + BOOL bAny3D(FALSE); + BOOL bGroupSelected(FALSE); + BOOL bRetval(TRUE); + + for(sal_uInt32 a=0;!bAny3D && a<GetMarkedObjectCount();a++) + { + SdrObject *pObj = GetMarkedObjectByIndex(a); + if(pObj) + { + ImpIsConvertTo3DPossible(pObj, bAny3D, bGroupSelected); + } + } + + bRetval = !bAny3D + && ( + IsConvertToPolyObjPossible(FALSE) + || IsConvertToPathObjPossible(FALSE) + || IsImportMtfPossible()); + return bRetval; +} + +void E3dView::ImpIsConvertTo3DPossible(SdrObject* pObj, BOOL& rAny3D, + BOOL& rGroupSelected) const +{ + if(pObj) + { + if(pObj->ISA(E3dObject)) + { + rAny3D = TRUE; + } + else + { + if(pObj->IsGroupObject()) + { + SdrObjListIter aIter(*pObj, IM_DEEPNOGROUPS); + while(aIter.IsMore()) + { + SdrObject* pNewObj = aIter.Next(); + ImpIsConvertTo3DPossible(pNewObj, rAny3D, rGroupSelected); + } + rGroupSelected = TRUE; + } + } + } +} + +/************************************************************************* +|* +|* 3D-Konvertierung zu Extrude ausfuehren +|* +\************************************************************************/ +#include <editeng/eeitem.hxx> + +void E3dView::ImpChangeSomeAttributesFor3DConversion(SdrObject* pObj) +{ + if(pObj->ISA(SdrTextObj)) + { + const SfxItemSet& rSet = pObj->GetMergedItemSet(); + const SvxColorItem& rTextColorItem = (const SvxColorItem&)rSet.Get(EE_CHAR_COLOR); + if(rTextColorItem.GetValue() == RGB_Color(COL_BLACK)) + { + // Bei schwarzen Textobjekten wird die Farbe auf grau gesetzt + if(pObj->GetPage()) + { + // #84864# if black is only default attribute from + // pattern set it hard so that it is used in undo. + pObj->SetMergedItem(SvxColorItem(RGB_Color(COL_BLACK), EE_CHAR_COLOR)); + + // add undo now + if( GetModel()->IsUndoEnabled() ) + AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pObj, false, false)); + } + + pObj->SetMergedItem(SvxColorItem(RGB_Color(COL_GRAY), EE_CHAR_COLOR)); + } + } +} + +void E3dView::ImpChangeSomeAttributesFor3DConversion2(SdrObject* pObj) +{ + if(pObj->ISA(SdrPathObj)) + { + const SfxItemSet& rSet = pObj->GetMergedItemSet(); + sal_Int32 nLineWidth = ((const XLineWidthItem&)(rSet.Get(XATTR_LINEWIDTH))).GetValue(); + XLineStyle eLineStyle = (XLineStyle)((const XLineStyleItem&)rSet.Get(XATTR_LINESTYLE)).GetValue(); + XFillStyle eFillStyle = ITEMVALUE(rSet, XATTR_FILLSTYLE, XFillStyleItem); + + if(((SdrPathObj*)pObj)->IsClosed() + && eLineStyle == XLINE_SOLID + && !nLineWidth + && eFillStyle != XFILL_NONE) + { + if(pObj->GetPage() && GetModel()->IsUndoEnabled() ) + AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pObj, false, false)); + pObj->SetMergedItem(XLineStyleItem(XLINE_NONE)); + pObj->SetMergedItem(XLineWidthItem(0L)); + } + } +} + +void E3dView::ImpCreateSingle3DObjectFlat(E3dScene* pScene, SdrObject* pObj, BOOL bExtrude, double fDepth, basegfx::B2DHomMatrix& rLatheMat) +{ + // Einzelnes PathObject, dieses umwanden + SdrPathObj* pPath = PTR_CAST(SdrPathObj, pObj); + + if(pPath) + { + E3dDefaultAttributes aDefault = Get3DDefaultAttributes(); + if(bExtrude) + aDefault.SetDefaultExtrudeCharacterMode(TRUE); + else + aDefault.SetDefaultLatheCharacterMode(TRUE); + + // ItemSet des Ursprungsobjektes holen + SfxItemSet aSet(pObj->GetMergedItemSet()); + + XFillStyle eFillStyle = ITEMVALUE(aSet, XATTR_FILLSTYLE, XFillStyleItem); + + // Linienstil ausschalten + aSet.Put(XLineStyleItem(XLINE_NONE)); + + // Feststellen, ob ein FILL_Attribut gesetzt ist. + if(!pPath->IsClosed() || eFillStyle == XFILL_NONE) + { + // Das SdrPathObj ist nicht gefuellt, lasse die + // vordere und hintere Flaeche weg. Ausserdem ist + // eine beidseitige Darstellung notwendig. + aDefault.SetDefaultExtrudeCloseFront(FALSE); + aDefault.SetDefaultExtrudeCloseBack(FALSE); + + aSet.Put(Svx3DDoubleSidedItem(TRUE)); + + // Fuellattribut setzen + aSet.Put(XFillStyleItem(XFILL_SOLID)); + + // Fuellfarbe muss auf Linienfarbe, da das Objekt vorher + // nur eine Linie war + Color aColorLine = ((const XLineColorItem&)(aSet.Get(XATTR_LINECOLOR))).GetColorValue(); + aSet.Put(XFillColorItem(String(), aColorLine)); + } + + // Neues Extrude-Objekt erzeugen + E3dObject* p3DObj = NULL; + if(bExtrude) + { + p3DObj = new E3dExtrudeObj(aDefault, pPath->GetPathPoly(), fDepth); + } + else + { + basegfx::B2DPolyPolygon aPolyPoly2D(pPath->GetPathPoly()); + aPolyPoly2D.transform(rLatheMat); + p3DObj = new E3dLatheObj(aDefault, aPolyPoly2D); + } + + // Attribute setzen + if(p3DObj) + { + p3DObj->NbcSetLayer(pObj->GetLayer()); + + p3DObj->SetMergedItemSet(aSet); + + p3DObj->NbcSetStyleSheet(pObj->GetStyleSheet(), sal_True); + + // Neues 3D-Objekt einfuegen + pScene->Insert3DObj(p3DObj); + } + } +} + +void E3dView::ImpCreate3DObject(E3dScene* pScene, SdrObject* pObj, BOOL bExtrude, double fDepth, basegfx::B2DHomMatrix& rLatheMat) +{ + if(pObj) + { + // change text color attribute for not so dark colors + if(pObj->IsGroupObject()) + { + SdrObjListIter aIter(*pObj, IM_DEEPWITHGROUPS); + while(aIter.IsMore()) + { + SdrObject* pGroupMember = aIter.Next(); + ImpChangeSomeAttributesFor3DConversion(pGroupMember); + } + } + else + ImpChangeSomeAttributesFor3DConversion(pObj); + + // convert completely to path objects + SdrObject* pNewObj1 = pObj->ConvertToPolyObj(FALSE, FALSE); + + if(pNewObj1) + { + // change text color attribute for not so dark colors + if(pNewObj1->IsGroupObject()) + { + SdrObjListIter aIter(*pNewObj1, IM_DEEPWITHGROUPS); + while(aIter.IsMore()) + { + SdrObject* pGroupMember = aIter.Next(); + ImpChangeSomeAttributesFor3DConversion2(pGroupMember); + } + } + else + ImpChangeSomeAttributesFor3DConversion2(pNewObj1); + + // convert completely to path objects + SdrObject* pNewObj2 = pObj->ConvertToContourObj(pNewObj1, TRUE); + + if(pNewObj2) + { + // add all to flat scene + if(pNewObj2->IsGroupObject()) + { + SdrObjListIter aIter(*pNewObj2, IM_DEEPWITHGROUPS); + while(aIter.IsMore()) + { + SdrObject* pGroupMember = aIter.Next(); + ImpCreateSingle3DObjectFlat(pScene, pGroupMember, bExtrude, fDepth, rLatheMat); + } + } + else + ImpCreateSingle3DObjectFlat(pScene, pNewObj2, bExtrude, fDepth, rLatheMat); + + // delete zwi object + if(pNewObj2 != pObj && pNewObj2 != pNewObj1 && pNewObj2) + SdrObject::Free( pNewObj2 ); + } + + // delete zwi object + if(pNewObj1 != pObj && pNewObj1) + SdrObject::Free( pNewObj1 ); + } + } +} + +/************************************************************************* +|* +|* 3D-Konvertierung zu Extrude steuern +|* +\************************************************************************/ + +void E3dView::ConvertMarkedObjTo3D(BOOL bExtrude, basegfx::B2DPoint aPnt1, basegfx::B2DPoint aPnt2) +{ + if(AreObjectsMarked()) + { + // Undo anlegen + if(bExtrude) + BegUndo(SVX_RESSTR(RID_SVX_3D_UNDO_EXTRUDE)); + else + BegUndo(SVX_RESSTR(RID_SVX_3D_UNDO_LATHE)); + + // Neue Szene fuer zu erzeugende 3D-Objekte anlegen + E3dScene* pScene = new E3dPolyScene(Get3DDefaultAttributes()); + + // Rechteck bestimmen und evtl. korrigieren + Rectangle aRect = GetAllMarkedRect(); + if(aRect.GetWidth() <= 1) + aRect.SetSize(Size(500, aRect.GetHeight())); + if(aRect.GetHeight() <= 1) + aRect.SetSize(Size(aRect.GetWidth(), 500)); + + // Tiefe relativ zur Groesse der Selektion bestimmen + double fDepth = 0.0; + double fRot3D = 0.0; + basegfx::B2DHomMatrix aLatheMat; + + if(bExtrude) + { + double fW = (double)aRect.GetWidth(); + double fH = (double)aRect.GetHeight(); + fDepth = sqrt(fW*fW + fH*fH) / 6.0; + } + if(!bExtrude) + { + // Transformation fuer Polygone Rotationskoerper erstellen + if(aPnt1 != aPnt2) + { + // Rotation um Kontrollpunkt1 mit eigestelltem Winkel + // fuer 3D Koordinaten + basegfx::B2DPoint aDiff(aPnt1 - aPnt2); + fRot3D = atan2(aDiff.getY(), aDiff.getX()) - F_PI2; + + if(basegfx::fTools::equalZero(fabs(fRot3D))) + fRot3D = 0.0; + + if(fRot3D != 0.0) + { + aLatheMat = basegfx::tools::createRotateAroundPoint(aPnt2, -fRot3D) + * aLatheMat; + } + } + + if(aPnt2.getX() != 0.0) + { + // Translation auf Y=0 - Achse + aLatheMat.translate(-aPnt2.getX(), 0.0); + } + else + { + aLatheMat.translate((double)-aRect.Left(), 0.0); + } + + // Inverse Matrix bilden, um die Zielausdehnung zu bestimmen + basegfx::B2DHomMatrix aInvLatheMat(aLatheMat); + aInvLatheMat.invert(); + + // SnapRect Ausdehnung mittels Spiegelung an der Rotationsachse + // erweitern + for(UINT32 a=0;a<GetMarkedObjectCount();a++) + { + SdrMark* pMark = GetSdrMarkByIndex(a); + SdrObject* pObj = pMark->GetMarkedSdrObj(); + Rectangle aTurnRect = pObj->GetSnapRect(); + basegfx::B2DPoint aRot; + Point aRotPnt; + + aRot = basegfx::B2DPoint(aTurnRect.Left(), -aTurnRect.Top()); + aRot *= aLatheMat; + aRot.setX(-aRot.getX()); + aRot *= aInvLatheMat; + aRotPnt = Point((long)(aRot.getX() + 0.5), (long)(-aRot.getY() - 0.5)); + aRect.Union(Rectangle(aRotPnt, aRotPnt)); + + aRot = basegfx::B2DPoint(aTurnRect.Left(), -aTurnRect.Bottom()); + aRot *= aLatheMat; + aRot.setX(-aRot.getX()); + aRot *= aInvLatheMat; + aRotPnt = Point((long)(aRot.getX() + 0.5), (long)(-aRot.getY() - 0.5)); + aRect.Union(Rectangle(aRotPnt, aRotPnt)); + + aRot = basegfx::B2DPoint(aTurnRect.Right(), -aTurnRect.Top()); + aRot *= aLatheMat; + aRot.setX(-aRot.getX()); + aRot *= aInvLatheMat; + aRotPnt = Point((long)(aRot.getX() + 0.5), (long)(-aRot.getY() - 0.5)); + aRect.Union(Rectangle(aRotPnt, aRotPnt)); + + aRot = basegfx::B2DPoint(aTurnRect.Right(), -aTurnRect.Bottom()); + aRot *= aLatheMat; + aRot.setX(-aRot.getX()); + aRot *= aInvLatheMat; + aRotPnt = Point((long)(aRot.getX() + 0.5), (long)(-aRot.getY() - 0.5)); + aRect.Union(Rectangle(aRotPnt, aRotPnt)); + } + } + + // Ueber die Selektion gehen und in 3D wandeln, komplett mit + // Umwandeln in SdrPathObject, auch Schriften + for(UINT32 a=0;a<GetMarkedObjectCount();a++) + { + SdrMark* pMark = GetSdrMarkByIndex(a); + SdrObject* pObj = pMark->GetMarkedSdrObj(); + + ImpCreate3DObject(pScene, pObj, bExtrude, fDepth, aLatheMat); + } + + if(pScene->GetSubList() && pScene->GetSubList()->GetObjCount() != 0) + { + // Alle angelegten Objekte Tiefenarrangieren + if(bExtrude) + DoDepthArrange(pScene, fDepth); + + // 3D-Objekte auf die Mitte des Gesamtrechtecks zentrieren + basegfx::B3DPoint aCenter(pScene->GetBoundVolume().getCenter()); + basegfx::B3DHomMatrix aMatrix; + + aMatrix.translate(-aCenter.getX(), -aCenter.getY(), -aCenter.getZ()); + pScene->SetTransform(aMatrix * pScene->GetTransform()); // #112587# + + // Szene initialisieren + pScene->NbcSetSnapRect(aRect); + basegfx::B3DRange aBoundVol = pScene->GetBoundVolume(); + InitScene(pScene, (double)aRect.GetWidth(), (double)aRect.GetHeight(), aBoundVol.getDepth()); + + // Szene anstelle des ersten selektierten Objektes einfuegen + // und alle alten Objekte weghauen + SdrObject* pRepObj = GetMarkedObjectByIndex(0); + SdrPageView* pPV = GetSdrPageViewOfMarkedByIndex(0); + MarkObj(pRepObj, pPV, TRUE); + ReplaceObjectAtView(pRepObj, *pPV, pScene, FALSE); + DeleteMarked(); + MarkObj(pScene, pPV); + + // Rotationskoerper um Rotationsachse drehen + basegfx::B3DHomMatrix aRotate; + + if(!bExtrude && fRot3D != 0.0) + { + aRotate.rotate(0.0, 0.0, fRot3D); + } + + // Default-Rotation setzen + { + double XRotateDefault = 20; + aRotate.rotate(DEG2RAD(XRotateDefault), 0.0, 0.0); + } + + if(!aRotate.isIdentity()) + { + pScene->SetTransform(aRotate * pScene->GetTransform()); + } + + // SnapRects der Objekte ungueltig + pScene->SetSnapRect(aRect); + } + else + { + // Es wurden keine 3D Objekte erzeugt, schmeiss alles weg + delete pScene; + } + + // Undo abschliessen + EndUndo(); + } +} + +/************************************************************************* +|* +|* Alle enthaltenen Extrude-Objekte Tiefenarrangieren +|* +\************************************************************************/ + +struct E3dDepthNeighbour +{ + E3dDepthNeighbour* pNext; + E3dExtrudeObj* pObj; + + E3dDepthNeighbour() { pNext = NULL; pObj = NULL; } +}; + +struct E3dDepthLayer +{ + E3dDepthLayer* pDown; + E3dDepthNeighbour* pNext; + + E3dDepthLayer() { pDown = NULL; pNext = NULL; } + ~E3dDepthLayer() { while(pNext) { E3dDepthNeighbour* pSucc = pNext->pNext; delete pNext; pNext = pSucc; }} +}; + +bool ImpDoesOverlap(const basegfx::B2DPolygon& rPolygonA, const basegfx::B2DPolygon& rPolygonB) +{ + bool bRetval(false); + const basegfx::B2DRange aRangeA(basegfx::tools::getRange(rPolygonA)); + const basegfx::B2DRange aRangeB(basegfx::tools::getRange(rPolygonB)); + + if(aRangeA.overlaps(aRangeB)) + { + // A in B ? + if(basegfx::tools::isInside(rPolygonA, rPolygonB)) + return true; + + // B in A ? + if(basegfx::tools::isInside(rPolygonB, rPolygonA)) + return true; + + // A and B the same ? + if(basegfx::tools::isInside(rPolygonB, rPolygonA, true)) + return true; + } + + return bRetval; +} + +bool ImpDoesOverlap(const basegfx::B2DPolyPolygon& rPolyPolygonA, const basegfx::B2DPolyPolygon& rPolyPolygonB) +{ + bool bRetval(false); + const basegfx::B2DRange aRangeA(basegfx::tools::getRange(rPolyPolygonA)); + const basegfx::B2DRange aRangeB(basegfx::tools::getRange(rPolyPolygonB)); + + if(aRangeA.overlaps(aRangeB)) + { + const sal_uInt32 nCntA(rPolyPolygonA.count()); + const sal_uInt32 nCntB(rPolyPolygonB.count()); + + for(sal_uInt32 a(0L); !bRetval && a < nCntA; a++) + { + const basegfx::B2DPolygon aPolygonA(rPolyPolygonA.getB2DPolygon(a)); + + if(aPolygonA.isClosed()) + { + for(sal_uInt32 b(0L); !bRetval && b < nCntB; b++) + { + const basegfx::B2DPolygon aPolygonB(rPolyPolygonB.getB2DPolygon(b)); + + if(aPolygonB.isClosed()) + { + bRetval = ImpDoesOverlap(aPolygonA, aPolygonB); + } + } + } + } + } + + return bRetval; +} + +void E3dView::DoDepthArrange(E3dScene* pScene, double fDepth) +{ + if(pScene && pScene->GetSubList() && pScene->GetSubList()->GetObjCount() > 1) + { + SdrObjList* pSubList = pScene->GetSubList(); + SdrObjListIter aIter(*pSubList, IM_FLAT); + E3dDepthLayer* pBaseLayer = NULL; + E3dDepthLayer* pLayer = NULL; + INT32 nNumLayers = 0; + //SfxItemPool& rPool = pMod->GetItemPool(); + + while(aIter.IsMore()) + { + E3dObject* pSubObj = (E3dObject*)aIter.Next(); + + if(pSubObj && pSubObj->ISA(E3dExtrudeObj)) + { + E3dExtrudeObj* pExtrudeObj = (E3dExtrudeObj*)pSubObj; + const basegfx::B2DPolyPolygon aExtrudePoly(pExtrudeObj->GetExtrudePolygon()); + + const SfxItemSet& rLocalSet = pExtrudeObj->GetMergedItemSet(); + XFillStyle eLocalFillStyle = ITEMVALUE(rLocalSet, XATTR_FILLSTYLE, XFillStyleItem); + Color aLocalColor = ((const XFillColorItem&)(rLocalSet.Get(XATTR_FILLCOLOR))).GetColorValue(); + + // ExtrudeObj einordnen + if(pLayer) + { + // Gibt es eine Ueberschneidung mit einem Objekt dieses + // Layers? + BOOL bOverlap(FALSE); + E3dDepthNeighbour* pAct = pLayer->pNext; + + while(!bOverlap && pAct) + { + // ueberlappen sich pAct->pObj und pExtrudeObj ? + const basegfx::B2DPolyPolygon aActPoly(pAct->pObj->GetExtrudePolygon()); + bOverlap = ImpDoesOverlap(aExtrudePoly, aActPoly); + + if(bOverlap) + { + // second ciriteria: is another fillstyle or color used? + const SfxItemSet& rCompareSet = pAct->pObj->GetMergedItemSet(); + + XFillStyle eCompareFillStyle = ITEMVALUE(rCompareSet, XATTR_FILLSTYLE, XFillStyleItem); + + if(eLocalFillStyle == eCompareFillStyle) + { + if(eLocalFillStyle == XFILL_SOLID) + { + Color aCompareColor = ((const XFillColorItem&)(rCompareSet.Get(XATTR_FILLCOLOR))).GetColorValue(); + + if(aCompareColor == aLocalColor) + { + bOverlap = FALSE; + } + } + else if(eLocalFillStyle == XFILL_NONE) + { + bOverlap = FALSE; + } + } + } + + pAct = pAct->pNext; + } + + if(bOverlap) + { + // ja, beginne einen neuen Layer + pLayer->pDown = new E3dDepthLayer; + pLayer = pLayer->pDown; + nNumLayers++; + pLayer->pNext = new E3dDepthNeighbour; + pLayer->pNext->pObj = pExtrudeObj; + } + else + { + // nein, Objekt kann in aktuellen Layer + E3dDepthNeighbour* pNewNext = new E3dDepthNeighbour; + pNewNext->pObj = pExtrudeObj; + pNewNext->pNext = pLayer->pNext; + pLayer->pNext = pNewNext; + } + } + else + { + // erster Layer ueberhaupt + pBaseLayer = new E3dDepthLayer; + pLayer = pBaseLayer; + nNumLayers++; + pLayer->pNext = new E3dDepthNeighbour; + pLayer->pNext->pObj = pExtrudeObj; + } + } + } + + // Anzahl Layer steht fest + if(nNumLayers > 1) + { + // Arrangement ist notwendig + double fMinDepth = fDepth * 0.8; + double fStep = (fDepth - fMinDepth) / (double)nNumLayers; + pLayer = pBaseLayer; + + while(pLayer) + { + // an pLayer entlangspazieren + E3dDepthNeighbour* pAct = pLayer->pNext; + + while(pAct) + { + // Anpassen + pAct->pObj->SetMergedItem(SfxUInt32Item(SDRATTR_3DOBJ_DEPTH, sal_uInt32(fMinDepth + 0.5))); + + // Naechster Eintrag + pAct = pAct->pNext; + } + + // naechster Layer + pLayer = pLayer->pDown; + fMinDepth += fStep; + } + } + + // angelegte Strukturen aufraeumen + while(pBaseLayer) + { + pLayer = pBaseLayer->pDown; + delete pBaseLayer; + pBaseLayer = pLayer; + } + } +} + +/************************************************************************* +|* +|* Drag beginnen, vorher ggf. Drag-Methode fuer 3D-Objekte erzeugen +|* +\************************************************************************/ + +BOOL E3dView::BegDragObj(const Point& rPnt, OutputDevice* pOut, + SdrHdl* pHdl, short nMinMov, + SdrDragMethod* pForcedMeth) +{ + if(Is3DRotationCreationActive() && GetMarkedObjectCount()) + { + // bestimme alle selektierten Polygone und gebe die gespiegelte Hilfsfigur aus + mpMirrorOverlay->SetMirrorAxis(aRef1, aRef2); + } + else + { + BOOL bOwnActionNecessary; + if (pHdl == NULL) + { + bOwnActionNecessary = TRUE; + } + else if (pHdl->IsVertexHdl() || pHdl->IsCornerHdl()) + { + bOwnActionNecessary = TRUE; + } + else + { + bOwnActionNecessary = FALSE; + } + + if(bOwnActionNecessary && GetMarkedObjectCount() >= 1) + { + E3dDragConstraint eConstraint = E3DDRAG_CONSTR_XYZ; + BOOL bThereAreRootScenes = FALSE; + BOOL bThereAre3DObjects = FALSE; + long nCnt = GetMarkedObjectCount(); + for(long nObjs = 0;nObjs < nCnt;nObjs++) + { + SdrObject *pObj = GetMarkedObjectByIndex(nObjs); + if(pObj) + { + if(pObj->ISA(E3dScene) && ((E3dScene*)pObj)->GetScene() == pObj) + bThereAreRootScenes = TRUE; + if(pObj->ISA(E3dObject)) + bThereAre3DObjects = TRUE; + } + } + if( bThereAre3DObjects ) + { + eDragHdl = ( pHdl == NULL ? HDL_MOVE : pHdl->GetKind() ); + switch ( eDragMode ) + { + case SDRDRAG_ROTATE: + case SDRDRAG_SHEAR: + { + switch ( eDragHdl ) + { + case HDL_LEFT: + case HDL_RIGHT: + { + eConstraint = E3DDRAG_CONSTR_X; + } + break; + + case HDL_UPPER: + case HDL_LOWER: + { + eConstraint = E3DDRAG_CONSTR_Y; + } + break; + + case HDL_UPLFT: + case HDL_UPRGT: + case HDL_LWLFT: + case HDL_LWRGT: + { + eConstraint = E3DDRAG_CONSTR_Z; + } + break; + default: break; + } + + // die nicht erlaubten Rotationen ausmaskieren + eConstraint = E3dDragConstraint(eConstraint& eDragConstraint); + pForcedMeth = new E3dDragRotate(*this, GetMarkedObjectList(), eConstraint, IsSolidDragging()); + } + break; + + case SDRDRAG_MOVE: + { + if(!bThereAreRootScenes) + { + pForcedMeth = new E3dDragMove(*this, GetMarkedObjectList(), eDragHdl, eConstraint, IsSolidDragging()); + } + } + break; + + // spaeter mal + case SDRDRAG_MIRROR: + case SDRDRAG_CROOK: + case SDRDRAG_DISTORT: + case SDRDRAG_TRANSPARENCE: + case SDRDRAG_GRADIENT: + default: + { + } + break; + } + } + } + } + return SdrView::BegDragObj(rPnt, pOut, pHdl, nMinMov, pForcedMeth); +} + +/************************************************************************* +|* +|* Pruefen, obj 3D-Szene markiert ist +|* +\************************************************************************/ + +BOOL E3dView::HasMarkedScene() +{ + return (GetMarkedScene() != NULL); +} + +/************************************************************************* +|* +|* Pruefen, obj 3D-Szene markiert ist +|* +\************************************************************************/ + +E3dScene* E3dView::GetMarkedScene() +{ + ULONG nCnt = GetMarkedObjectCount(); + + for ( ULONG i = 0; i < nCnt; i++ ) + if ( GetMarkedObjectByIndex(i)->ISA(E3dScene) ) + return (E3dScene*) GetMarkedObjectByIndex(i); + + return NULL; +} + +/************************************************************************* +|* +|* aktuelles 3D-Zeichenobjekt setzen, dafuer Szene erzeugen +|* +\************************************************************************/ + +E3dScene* E3dView::SetCurrent3DObj(E3dObject* p3DObj) +{ + DBG_ASSERT(p3DObj != NULL, "Nana, wer steckt denn hier 'nen NULL-Zeiger rein?"); + E3dScene* pScene = NULL; + + // get transformed BoundVolume of the object + basegfx::B3DRange aVolume(p3DObj->GetBoundVolume()); + aVolume.transform(p3DObj->GetTransform()); + double fW(aVolume.getWidth()); + double fH(aVolume.getHeight()); + + Rectangle aRect(0,0, (long) fW, (long) fH); + + pScene = new E3dPolyScene(Get3DDefaultAttributes()); + + InitScene(pScene, fW, fH, aVolume.getMaxZ() + ((fW + fH) / 4.0)); + + pScene->Insert3DObj(p3DObj); + pScene->NbcSetSnapRect(aRect); + + return pScene; +} + +/************************************************************************* +|* +|* neu erzeugte Szene initialisieren +|* +\************************************************************************/ + +void E3dView::InitScene(E3dScene* pScene, double fW, double fH, double fCamZ) +{ + Camera3D aCam(pScene->GetCamera()); + + aCam.SetAutoAdjustProjection(FALSE); + aCam.SetViewWindow(- fW / 2, - fH / 2, fW, fH); + basegfx::B3DPoint aLookAt; + + double fDefaultCamPosZ = GetDefaultCamPosZ(); + basegfx::B3DPoint aCamPos(0.0, 0.0, fCamZ < fDefaultCamPosZ ? fDefaultCamPosZ : fCamZ); + + aCam.SetPosAndLookAt(aCamPos, aLookAt); + aCam.SetFocalLength(GetDefaultCamFocal()); + aCam.SetDefaults(basegfx::B3DPoint(0.0, 0.0, fDefaultCamPosZ), aLookAt, GetDefaultCamFocal()); + pScene->SetCamera(aCam); +} + +/************************************************************************* +|* +|* startsequenz fuer die erstellung eines 3D-Rotationskoerpers +|* +\************************************************************************/ + +void E3dView::Start3DCreation() +{ + if (GetMarkedObjectCount()) + { + // irgendwelche Markierungen ermitteln und ausschalten + //HMHBOOL bVis = IsMarkHdlShown(); + + //HMHif (bVis) HideMarkHdl(); + + // bestimme die koordinaten fuer JOEs Mirrorachse + // entgegen der normalen Achse wird diese an die linke Seite des Objektes + // positioniert + long nOutMin = 0; + long nOutMax = 0; + long nMinLen = 0; + long nObjDst = 0; + long nOutHgt = 0; + OutputDevice* pOut = GetFirstOutputDevice(); //GetWin(0); + + // erstmal Darstellungsgrenzen bestimmen + if (pOut != NULL) + { + nMinLen = pOut->PixelToLogic(Size(0,50)).Height(); + nObjDst = pOut->PixelToLogic(Size(0,20)).Height(); + + long nDst = pOut->PixelToLogic(Size(0,10)).Height(); + + nOutMin = -pOut->GetMapMode().GetOrigin().Y(); + nOutMax = pOut->GetOutputSize().Height() - 1 + nOutMin; + nOutMin += nDst; + nOutMax -= nDst; + + if (nOutMax - nOutMin < nDst) + { + nOutMin += nOutMax + 1; + nOutMin /= 2; + nOutMin -= (nDst + 1) / 2; + nOutMax = nOutMin + nDst; + } + + nOutHgt = nOutMax - nOutMin; + + long nTemp = nOutHgt / 4; + if (nTemp > nMinLen) nMinLen = nTemp; + } + + // und dann die Markierungen oben und unten an das Objekt heften + basegfx::B2DRange aR; + for(sal_uInt32 nMark(0L); nMark < GetMarkedObjectCount(); nMark++) + { + SdrObject* pMark = GetMarkedObjectByIndex(nMark); + basegfx::B2DPolyPolygon aXPP(pMark->TakeXorPoly()); + aR.expand(basegfx::tools::getRange(aXPP)); + } + + basegfx::B2DPoint aCenter(aR.getCenter()); + long nMarkHgt = basegfx::fround(aR.getHeight()) - 1; + long nHgt = nMarkHgt + nObjDst * 2; + + if (nHgt < nMinLen) nHgt = nMinLen; + + long nY1 = basegfx::fround(aCenter.getY()) - (nHgt + 1) / 2; + long nY2 = nY1 + nHgt; + + if (pOut && (nMinLen > nOutHgt)) nMinLen = nOutHgt; + if (pOut) + { + if (nY1 < nOutMin) + { + nY1 = nOutMin; + if (nY2 < nY1 + nMinLen) nY2 = nY1 + nMinLen; + } + if (nY2 > nOutMax) + { + nY2 = nOutMax; + if (nY1 > nY2 - nMinLen) nY1 = nY2 - nMinLen; + } + } + + aRef1.X() = basegfx::fround(aR.getMinX()); // Initial Achse um 2/100mm nach links + aRef1.Y() = nY1; + aRef2.X() = aRef1.X(); + aRef2.Y() = nY2; + + // Markierungen einschalten + SetMarkHandles(); + + //HMHif (bVis) ShowMarkHdl(); + if (AreObjectsMarked()) MarkListHasChanged(); + + // SpiegelPolygone SOFORT zeigen + const SdrHdlList &aHdlList = GetHdlList(); + mpMirrorOverlay = new Impl3DMirrorConstructOverlay(*this); + mpMirrorOverlay->SetMirrorAxis(aHdlList.GetHdl(HDL_REF1)->GetPos(), aHdlList.GetHdl(HDL_REF2)->GetPos()); + //CreateMirrorPolygons (); + //ShowMirrorPolygons (aHdlList.GetHdl (HDL_REF1)->GetPos (), + // aHdlList.GetHdl (HDL_REF2)->GetPos ()); + } +} + +/************************************************************************* +|* +|* was passiert bei einer Mausbewegung, wenn das Objekt erstellt wird ? +|* +\************************************************************************/ + +void E3dView::MovAction(const Point& rPnt) +{ + if(Is3DRotationCreationActive()) + { + SdrHdl* pHdl = GetDragHdl(); + + if (pHdl) + { + SdrHdlKind eHdlKind = pHdl->GetKind(); + + // reagiere nur bei einer spiegelachse + if ((eHdlKind == HDL_REF1) || + (eHdlKind == HDL_REF2) || + (eHdlKind == HDL_MIRX)) + { + const SdrHdlList &aHdlList = GetHdlList (); + + // loesche das gespiegelte Polygon, spiegele das Original und zeichne es neu + //ShowMirrored (); + SdrView::MovAction (rPnt); + mpMirrorOverlay->SetMirrorAxis( + aHdlList.GetHdl (HDL_REF1)->GetPos(), + aHdlList.GetHdl (HDL_REF2)->GetPos()); + } + } + else + { + SdrView::MovAction (rPnt); + } + } + else + { + SdrView::MovAction (rPnt); + } +} + +/************************************************************************* +|* +|* Schluss. Objekt und evtl. Unterobjekte ueber ImpCreate3DLathe erstellen +|* [FG] Mit dem Parameterwert TRUE (SDefault: FALSE) wird einfach ein +|* Rotationskoerper erzeugt, ohne den Benutzer die Lage der +|* Achse fetlegen zu lassen. Es reicht dieser Aufruf, falls +|* ein Objekt selektiert ist. (keine Initialisierung noetig) +|* +\************************************************************************/ + +void E3dView::End3DCreation(BOOL bUseDefaultValuesForMirrorAxes) +{ + ResetCreationActive(); + + if(AreObjectsMarked()) + { + if(bUseDefaultValuesForMirrorAxes) + { + Rectangle aRect = GetAllMarkedRect(); + if(aRect.GetWidth() <= 1) + aRect.SetSize(Size(500, aRect.GetHeight())); + if(aRect.GetHeight() <= 1) + aRect.SetSize(Size(aRect.GetWidth(), 500)); + + basegfx::B2DPoint aPnt1(aRect.Left(), -aRect.Top()); + basegfx::B2DPoint aPnt2(aRect.Left(), -aRect.Bottom()); + + ConvertMarkedObjTo3D(FALSE, aPnt1, aPnt2); + } + else + { + // Hilfsfigur ausschalten + // bestimme aus den Handlepositionen und den Versatz der Punkte + const SdrHdlList &aHdlList = GetHdlList(); + Point aMirrorRef1 = aHdlList.GetHdl(HDL_REF1)->GetPos(); + Point aMirrorRef2 = aHdlList.GetHdl(HDL_REF2)->GetPos(); + + basegfx::B2DPoint aPnt1(aMirrorRef1.X(), -aMirrorRef1.Y()); + basegfx::B2DPoint aPnt2(aMirrorRef2.X(), -aMirrorRef2.Y()); + + ConvertMarkedObjTo3D(FALSE, aPnt1, aPnt2); + } + } +} + +/************************************************************************* +|* +|* Destruktor +|* +\************************************************************************/ + +E3dView::~E3dView () +{ +} + +/************************************************************************* +|* +|* beende das erzeugen und loesche die polygone +|* +\************************************************************************/ + +void E3dView::ResetCreationActive () +{ + if(mpMirrorOverlay) + { + delete mpMirrorOverlay; + mpMirrorOverlay = 0L; + } +} + +/************************************************************************* +|* +|* Klasse initialisieren +|* +\************************************************************************/ + +void E3dView::InitView () +{ + eDragConstraint = E3DDRAG_CONSTR_XYZ; + fDefaultScaleX = + fDefaultScaleY = + fDefaultScaleZ = 1.0; + fDefaultRotateX = + fDefaultRotateY = + fDefaultRotateZ = 0.0; + fDefaultExtrusionDeepth = 1000; // old: 2000; + fDefaultLightIntensity = 0.8; // old: 0.6; + fDefaultAmbientIntensity = 0.4; + nHDefaultSegments = 12; + nVDefaultSegments = 12; + aDefaultLightColor = RGB_Color(COL_WHITE); + aDefaultAmbientColor = RGB_Color(COL_BLACK); + bDoubleSided = FALSE; + mpMirrorOverlay = 0L; +} + +/************************************************************************* +|* +|* Koennen die selektierten Objekte aufgebrochen werden? +|* +\************************************************************************/ + +BOOL E3dView::IsBreak3DObjPossible() const +{ + ULONG nCount = GetMarkedObjectCount(); + + if (nCount > 0) + { + ULONG i = 0; + + while (i < nCount) + { + SdrObject* pObj = GetMarkedObjectByIndex(i); + + if (pObj && pObj->ISA(E3dObject)) + { + if(!(((E3dObject*)pObj)->IsBreakObjPossible())) + return FALSE; + } + else + { + return FALSE; + } + + i++; + } + } + else + { + return FALSE; + } + + return TRUE; +} + +/************************************************************************* +|* +|* Selektierte Lathe-Objekte aufbrechen +|* +\************************************************************************/ + +void E3dView::Break3DObj() +{ + if(IsBreak3DObjPossible()) + { + // ALLE selektierten Objekte werden gewandelt + UINT32 nCount = GetMarkedObjectCount(); + + BegUndo(String(SVX_RESSTR(RID_SVX_3D_UNDO_BREAK_LATHE))); + for(UINT32 a=0;a<nCount;a++) + { + E3dObject* pObj = (E3dObject*)GetMarkedObjectByIndex(a); + BreakSingle3DObj(pObj); + } + DeleteMarked(); + EndUndo(); + } +} + +void E3dView::BreakSingle3DObj(E3dObject* pObj) +{ + if(pObj->ISA(E3dScene)) + { + SdrObjList* pSubList = pObj->GetSubList(); + SdrObjListIter aIter(*pSubList, IM_FLAT); + + while(aIter.IsMore()) + { + E3dObject* pSubObj = (E3dObject*)aIter.Next(); + BreakSingle3DObj(pSubObj); + } + } + else + { + SdrAttrObj* pNewObj = pObj->GetBreakObj(); + if(pNewObj) + { + InsertObjectAtView(pNewObj, *GetSdrPageView(), SDRINSERT_DONTMARK); + pNewObj->SetChanged(); + pNewObj->BroadcastObjectChange(); + } + } +} + +/************************************************************************* +|* +|* Szenen mischen +|* +\************************************************************************/ + +void E3dView::MergeScenes () +{ + ULONG nCount = GetMarkedObjectCount(); + + if (nCount > 0) + { + ULONG nObj = 0; + SdrObject *pObj = GetMarkedObjectByIndex(nObj); + E3dScene *pScene = new E3dPolyScene(Get3DDefaultAttributes()); + basegfx::B3DRange aBoundVol; + Rectangle aAllBoundRect (GetMarkedObjBoundRect ()); + Point aCenter (aAllBoundRect.Center()); + + while (pObj) + { + if (pObj->ISA(E3dScene)) + { + /********************************************************** + * Es ist eine 3D-Scene oder 3D-PolyScene + **********************************************************/ + SdrObjList* pSubList = ((E3dObject*) pObj)->GetSubList(); + + SdrObjListIter aIter(*pSubList, IM_FLAT); + + while (aIter.IsMore()) + { + /****************************************************** + * LatheObjekte suchen + ******************************************************/ + SdrObject* pSubObj = aIter.Next(); + + E3dObject *pNewObj = 0; + + switch (pSubObj->GetObjIdentifier()) + { + case E3D_CUBEOBJ_ID : + pNewObj = new E3dCubeObj; + *(E3dCubeObj*)pNewObj = *(E3dCubeObj*)pSubObj; + break; + + case E3D_SPHEREOBJ_ID: + pNewObj = new E3dSphereObj; + *(E3dSphereObj*)pNewObj = *(E3dSphereObj*)pSubObj; + break; + + case E3D_EXTRUDEOBJ_ID: + pNewObj = new E3dExtrudeObj; + *(E3dExtrudeObj*)pNewObj = *(E3dExtrudeObj*)pSubObj; + break; + + case E3D_LATHEOBJ_ID: + pNewObj = new E3dLatheObj; + *(E3dLatheObj*)pNewObj = *(E3dLatheObj*)pSubObj; + break; + + case E3D_COMPOUNDOBJ_ID: + pNewObj = new E3dCompoundObject; + *(E3dCompoundObject*)pNewObj = *(E3dCompoundObject*)pSubObj; + break; + } + + Rectangle aBoundRect = pSubObj->GetCurrentBoundRect(); + + basegfx::B3DHomMatrix aMatrix; + aMatrix.translate(aBoundRect.Left() - aCenter.getX(), aCenter.getY(), 0.0); + pNewObj->SetTransform(aMatrix * pNewObj->GetTransform()); // #112587# + + if (pNewObj) aBoundVol.expand(pNewObj->GetBoundVolume()); + pScene->Insert3DObj (pNewObj); + } + } + + nObj++; + + if (nObj < nCount) + { + pObj = GetMarkedObjectByIndex(nObj); + } + else + { + pObj = NULL; + } + } + + double fW = aAllBoundRect.GetWidth(); + double fH = aAllBoundRect.GetHeight(); + Rectangle aRect(0,0, (long) fW, (long) fH); + + InitScene(pScene, fW, fH, aBoundVol.getMaxZ() + + ((fW + fH) / 4.0)); + pScene->NbcSetSnapRect(aRect); + + Camera3D &aCamera = (Camera3D&) pScene->GetCamera (); + basegfx::B3DPoint aMinVec(aBoundVol.getMinimum()); + basegfx::B3DPoint aMaxVec(aBoundVol.getMaximum()); + double fDeepth(fabs(aMaxVec.getZ() - aMinVec.getZ())); + + aCamera.SetPRP(basegfx::B3DPoint(0.0, 0.0, 1000.0)); + double fDefaultCamPosZ(GetDefaultCamPosZ()); + aCamera.SetPosition(basegfx::B3DPoint(0.0, 0.0, fDefaultCamPosZ + fDeepth / 2.0)); + aCamera.SetFocalLength(GetDefaultCamFocal()); + pScene->SetCamera (aCamera); + + // SnapRects der Objekte ungueltig + pScene->SetRectsDirty(); + + InsertObjectAtView(pScene, *(GetSdrPageViewOfMarkedByIndex(0))); + + // SnapRects der Objekte ungueltig + pScene->SetRectsDirty(); + } +} + +/************************************************************************* +|* +|* Possibilities, hauptsaechlich gruppieren/ungruppieren +|* +\************************************************************************/ +void E3dView::CheckPossibilities() +{ + // call parent + SdrView::CheckPossibilities(); + + // Weitere Flags bewerten + if(bGroupPossible || bUnGroupPossible || bGrpEnterPossible) + { + INT32 nMarkCnt = GetMarkedObjectCount(); + BOOL bCoumpound = FALSE; + BOOL b3DObject = FALSE; + for(INT32 nObjs = 0L; (nObjs < nMarkCnt) && !bCoumpound; nObjs++) + { + SdrObject *pObj = GetMarkedObjectByIndex(nObjs); + if(pObj && pObj->ISA(E3dCompoundObject)) + bCoumpound = TRUE; + if(pObj && pObj->ISA(E3dObject)) + b3DObject = TRUE; + } + + // Bisher: Es sind ZWEI oder mehr beliebiger Objekte selektiert. + // Nachsehen, ob CompoundObjects beteiligt sind. Falls ja, + // das Gruppieren verbieten. + if(bGroupPossible && bCoumpound) + bGroupPossible = FALSE; + + if(bUnGroupPossible && b3DObject) + bUnGroupPossible = FALSE; + + if(bGrpEnterPossible && bCoumpound) + bGrpEnterPossible = FALSE; + } +} + +// eof diff --git a/svx/source/engine3d/view3d1.cxx b/svx/source/engine3d/view3d1.cxx new file mode 100644 index 000000000000..dce003fe90ae --- /dev/null +++ b/svx/source/engine3d/view3d1.cxx @@ -0,0 +1,230 @@ +/************************************************************************* + * + * 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_svx.hxx" + +#include <tools/shl.hxx> +#include "svditer.hxx" +#include <svx/svdpool.hxx> +#include <svx/svdmodel.hxx> +#include <svx/svxids.hrc> +#include <svx/xtable.hxx> +#include <svx/fmview.hxx> +#include <svx/dialogs.hrc> +#include <svx/dialmgr.hxx> +#include "globl3d.hxx" +#include <svx/obj3d.hxx> +#include <svx/polysc3d.hxx> +#include <svx/e3ditem.hxx> +#include <editeng/colritem.hxx> +#include <svx/lathe3d.hxx> +#include <svx/sphere3d.hxx> +#include <svx/extrud3d.hxx> +#include <svx/e3dundo.hxx> +#include <svx/view3d.hxx> +#include <svx/cube3d.hxx> +#include <svx/xflclit.hxx> +#include <svx/svdogrp.hxx> +#include <svx/e3dsceneupdater.hxx> + +/************************************************************************* +|* +|* Konvertierung in Polygone +|* +\************************************************************************/ + +void E3dView::ConvertMarkedToPolyObj(BOOL bLineToArea) +{ + SdrObject* pNewObj = NULL; + + if (GetMarkedObjectCount() == 1) + { + SdrObject* pObj = GetMarkedObjectByIndex(0); + + if (pObj && pObj->ISA(E3dPolyScene)) + { + BOOL bBezier = FALSE; + pNewObj = ((E3dPolyScene*) pObj)->ConvertToPolyObj(bBezier, bLineToArea); + + if (pNewObj) + { + BegUndo(SVX_RESSTR(RID_SVX_3D_UNDO_EXTRUDE)); + ReplaceObjectAtView(pObj, *GetSdrPageView(), pNewObj); + EndUndo(); + } + } + } + + if (!pNewObj) + { + SdrView::ConvertMarkedToPolyObj(bLineToArea); + } +} + +/************************************************************************* +|* +|* Get3DAttributes +|* +\************************************************************************/ + +void Imp_E3dView_InorderRun3DObjects(const SdrObject* pObj, sal_uInt32& rMask) +{ + if(pObj->ISA(E3dLatheObj)) + { + rMask |= 0x0001; + } + else if(pObj->ISA(E3dExtrudeObj)) + { + rMask |= 0x0002; + } + else if(pObj->ISA(E3dSphereObj)) + { + rMask |= 0x0004; + } + else if(pObj->ISA(E3dCubeObj)) + { + rMask |= 0x0008; + } + else if(pObj->IsGroupObject()) + { + SdrObjList* pList = pObj->GetSubList(); + for(sal_uInt32 a(0); a < pList->GetObjCount(); a++) + Imp_E3dView_InorderRun3DObjects(pList->GetObj(a), rMask); + } +} + +SfxItemSet E3dView::Get3DAttributes(E3dScene* pInScene, BOOL /*bOnly3DAttr*/) const +{ + // ItemSet mit entspr. Bereich anlegen + SfxItemSet aSet( + pMod->GetItemPool(), + SDRATTR_START, SDRATTR_END, + SID_ATTR_3D_INTERN, SID_ATTR_3D_INTERN, + 0, 0); + + sal_uInt32 nSelectedItems(0L); + + if(pInScene) + { + // special scene + aSet.Put(pInScene->GetMergedItemSet()); + } + else + { + // get attributes from all selected objects + MergeAttrFromMarked(aSet, FALSE); + + // calc flags for SID_ATTR_3D_INTERN + const SdrMarkList& rMarkList = GetMarkedObjectList(); + sal_uInt32 nMarkCnt(rMarkList.GetMarkCount()); + + for(sal_uInt32 a(0); a < nMarkCnt; a++) + { + SdrObject* pObj = GetMarkedObjectByIndex(a); + Imp_E3dView_InorderRun3DObjects(pObj, nSelectedItems); + } + } + + // setze SID_ATTR_3D_INTERN auf den Status der selektierten Objekte + aSet.Put(SfxUInt32Item(SID_ATTR_3D_INTERN, nSelectedItems)); + + // DefaultValues pflegen + if(!nSelectedItems && !pInScene) + { + // Defaults holen und hinzufuegen + SfxItemSet aDefaultSet(pMod->GetItemPool(), SDRATTR_3D_FIRST, SDRATTR_3D_LAST); + GetAttributes(aDefaultSet); + aSet.Put(aDefaultSet); + + // ... aber keine Linien fuer 3D + aSet.Put(XLineStyleItem (XLINE_NONE)); + + // #84061# new defaults for distance and focal length + aSet.Put(Svx3DDistanceItem(100)); + aSet.Put(Svx3DFocalLengthItem(10000)); + } + + // ItemSet zurueckgeben + return(aSet); +} + +/************************************************************************* +|* +|* Set3DAttributes: +|* +\************************************************************************/ + +void E3dView::Set3DAttributes( const SfxItemSet& rAttr, E3dScene* pInScene, BOOL bReplaceAll) +{ + sal_uInt32 nSelectedItems(0L); + + if(pInScene) + { + //pInScene->SetItemSetAndBroadcast(rAttr, bReplaceAll); + pInScene->SetMergedItemSetAndBroadcast(rAttr, bReplaceAll); + } + else + { + // #i94832# removed usage of E3DModifySceneSnapRectUpdater here. + // They are not needed here, they are already handled in SetAttrToMarked + + // set at selected objects + SetAttrToMarked(rAttr, bReplaceAll); + + // old run + const SdrMarkList& rMarkList = GetMarkedObjectList(); + const sal_uInt32 nMarkCnt(rMarkList.GetMarkCount()); + + for(sal_uInt32 a(0); a < nMarkCnt; a++) + { + SdrObject* pObj = GetMarkedObjectByIndex(a); + Imp_E3dView_InorderRun3DObjects(pObj, nSelectedItems); + } + } + + // DefaultValues pflegen + if(!nSelectedItems && !pInScene) + { + // Defaults setzen + SfxItemSet aDefaultSet(pMod->GetItemPool(), SDRATTR_3D_FIRST, SDRATTR_3D_LAST); + aDefaultSet.Put(rAttr); + SetAttributes(aDefaultSet); + + } +} + +double E3dView::GetDefaultCamPosZ() +{ + return (double)((const SfxUInt32Item&)pMod->GetItemPool().GetDefaultItem(SDRATTR_3DSCENE_DISTANCE)).GetValue(); +} + +double E3dView::GetDefaultCamFocal() +{ + return (double)((const SfxUInt32Item&)pMod->GetItemPool().GetDefaultItem(SDRATTR_3DSCENE_FOCAL_LENGTH)).GetValue(); +} + diff --git a/svx/source/engine3d/viewpt3d.cxx b/svx/source/engine3d/viewpt3d.cxx new file mode 100644 index 000000000000..ef9750781a2e --- /dev/null +++ b/svx/source/engine3d/viewpt3d.cxx @@ -0,0 +1,32 @@ +/************************************************************************* + * + * 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_svx.hxx" +#include <svx/viewpt3d.hxx> + +// eof diff --git a/svx/source/engine3d/viewpt3d2.cxx b/svx/source/engine3d/viewpt3d2.cxx new file mode 100644 index 000000000000..ce5ffd7ba90e --- /dev/null +++ b/svx/source/engine3d/viewpt3d2.cxx @@ -0,0 +1,394 @@ +/************************************************************************* + * + * 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_svx.hxx" +#include <svx/viewpt3d.hxx> +#include <svx/volume3d.hxx> + +/************************************************************************* +|* +|* Konstruktor +|* +\************************************************************************/ + +Viewport3D::Viewport3D() : + aVRP(0, 0, 5), + aVPN(0, 0, 1), + aVUV(0, 1, 1), + aPRP(0, 0, 2), + fVPD(-3), + fNearClipDist (0.0), + fFarClipDist (0.0), + eProjection(PR_PERSPECTIVE), + eAspectMapping(AS_NO_MAPPING), + aDeviceRect(Point(0,0), Size(-1,-1)), + aViewPoint (0, 0, 5000), + bTfValid(0), + fWRatio (1.0), + fHRatio (1.0) +{ + aViewWin.X = -1; aViewWin.Y = -1; + aViewWin.W = 2; aViewWin.H = 2; +} + +/************************************************************************* +|* +|* ViewWindow (in View-Koordinaten) setzen +|* +\************************************************************************/ + +void Viewport3D::SetViewWindow(double fX, double fY, double fW, double fH) +{ + aViewWin.X = fX; + aViewWin.Y = fY; + if ( fW > 0 ) aViewWin.W = fW; + else aViewWin.W = 1.0; + if ( fH > 0 ) aViewWin.H = fH; + else aViewWin.H = 1.0; + + fWRatio = aDeviceRect.GetWidth() / aViewWin.W; + fHRatio = aDeviceRect.GetHeight() / aViewWin.H; +} + +/************************************************************************* +|* +|* ViewWindow zurueckgeben +|* +\************************************************************************/ + +void Viewport3D::GetViewWindow(double& rX, double& rY, + double& rW, double& rH) const +{ + rX = aViewWin.X; + rY = aViewWin.Y; + rW = aViewWin.W; + rH = aViewWin.H; +} + +/************************************************************************* +|* +|* Beobachterposition (PRP) in Weltkoordinaten zurueckgeben +|* +\************************************************************************/ + +const basegfx::B3DPoint& Viewport3D::GetViewPoint() +{ + MakeTransform(); + + return aViewPoint; +} + +/************************************************************************* +|* +|* Transformationsmatrix zurueckgeben +|* +\************************************************************************/ + +const basegfx::B3DHomMatrix& Viewport3D::GetViewTransform() +{ + MakeTransform(); + + return aViewTf; +} + + + + + + + +/************************************************************************* +|* +|* View-Transformationsmatrix berechnen +|* +\************************************************************************/ + +void Viewport3D::MakeTransform(void) +{ + if ( !bTfValid ) + { + double fV, fXupVp, fYupVp; + aViewPoint = aVRP + aVPN * aPRP.getZ(); + + // auf Einheitsmatrix zuruecksetzen + aViewTf.identity(); + + // in den Ursprung verschieben + aViewTf.translate(-aVRP.getX(), -aVRP.getY(), -aVRP.getZ()); + + // fV = Laenge der Projektion von aVPN auf die yz-Ebene: + fV = aVPN.getYZLength(); + + if ( fV != 0 ) + { + basegfx::B3DHomMatrix aTemp; + const double fSin(aVPN.getY() / fV); + const double fCos(aVPN.getZ() / fV); + aTemp.set(2, 2, fCos); + aTemp.set(1, 1, fCos); + aTemp.set(2, 1, fSin); + aTemp.set(1, 2, -fSin); + aViewTf *= aTemp; + } + + { + basegfx::B3DHomMatrix aTemp; + const double fSin(-aVPN.getX()); + const double fCos(fV); + aTemp.set(2, 2, fCos); + aTemp.set(0, 0, fCos); + aTemp.set(0, 2, fSin); + aTemp.set(2, 0, -fSin); + aViewTf *= aTemp; + } + + // X- und Y-Koordinaten des View Up Vektors in das (vorlaeufige) + // View-Koordinatensytem umrechnen + fXupVp = aViewTf.get(0, 0) * aVUV.getX() + aViewTf.get(0, 1) * aVUV.getY() + aViewTf.get(0, 2) * aVUV.getZ(); + fYupVp = aViewTf.get(1, 0) * aVUV.getX() + aViewTf.get(1, 1) * aVUV.getY() + aViewTf.get(1, 2) * aVUV.getZ(); + fV = sqrt(fXupVp * fXupVp + fYupVp * fYupVp); + + if ( fV != 0 ) + { + basegfx::B3DHomMatrix aTemp; + const double fSin(fXupVp / fV); + const double fCos(fYupVp / fV); + aTemp.set(1, 1, fCos); + aTemp.set(0, 0, fCos); + aTemp.set(1, 0, fSin); + aTemp.set(0, 1, -fSin); + aViewTf *= aTemp; + } + + bTfValid = TRUE; + } +} + +/************************************************************************* +|* +|* DeviceWindow des Ausgabegeraetes setzen +|* +\************************************************************************/ + +void Viewport3D::SetDeviceWindow(const Rectangle& rRect) +{ + long nNewW = rRect.GetWidth(); + long nNewH = rRect.GetHeight(); + long nOldW = aDeviceRect.GetWidth(); + long nOldH = aDeviceRect.GetHeight(); + + switch ( eAspectMapping ) + { + double fRatio, fTmp; + + // Mapping, ohne die reale Groesse der Objekte im Device-Window + // zu aendern + case AS_HOLD_SIZE: + // Wenn Device ungueltig (w, h = -1), zunaechst + // View mit AsHoldX anpassen + if ( nOldW > 0 && nOldH > 0 ) + { + fRatio = (double) nNewW / nOldW; + aViewWin.X *= fRatio; + aViewWin.W *= fRatio; + fRatio = (double) nNewH / nOldH; + aViewWin.Y *= fRatio; + aViewWin.H *= fRatio; + break; + } + case AS_HOLD_X: + // View-Hoehe an -Breite anpassen + fRatio = (double) nNewH / nNewW; + fTmp = aViewWin.H; + aViewWin.H = aViewWin.W * fRatio; + aViewWin.Y = aViewWin.Y * aViewWin.H / fTmp; + break; + + case AS_HOLD_Y: + // View-Breite an -Hoehe anpassen + fRatio = (double) nNewW / nNewH; + fTmp = aViewWin.W; + aViewWin.W = aViewWin.H * fRatio; + aViewWin.X = aViewWin.X * aViewWin.W / fTmp; + break; + default: break; + } + fWRatio = nNewW / aViewWin.W; + fHRatio = nNewH / aViewWin.H; + + aDeviceRect = rRect; +} + + + + + + + + + + +/************************************************************************* +|* +|* 3D-Punkt auf Viewplane projizieren +|* +\************************************************************************/ + +basegfx::B3DPoint Viewport3D::DoProjection(const basegfx::B3DPoint& rVec) const +{ + basegfx::B3DPoint aVec(rVec); + + if ( eProjection == PR_PERSPECTIVE ) + { + double fPrDist = fVPD - aPRP.getZ(); + + if ( aPRP.getZ() == rVec.getZ() ) + { + aVec.setX(0.0); + aVec.setY(0.0); + } + else + { + // Das ist die Version fuer beliebigen PRP, wird aber + // aus Performancegruenden nicht verwendet + fPrDist /= aVec.getZ() - aPRP.getZ(); + aVec.setX(aVec.getX() * fPrDist); + aVec.setY(aVec.getY() * fPrDist); + } + } + + return aVec; +} + +/************************************************************************* +|* +|* 3D-Punkt auf Geraetekoordinaten mappen +|* +\************************************************************************/ + +basegfx::B3DPoint Viewport3D::MapToDevice(const basegfx::B3DPoint& rVec) const +{ + basegfx::B3DPoint aRetval; + + // Y-Koordinate subtrahieren, da die Device-Y-Achse von oben + // nach unten verlaeuft + aRetval.setX((double)aDeviceRect.Left() + ((rVec.getX() - aViewWin.X) * fWRatio)); + aRetval.setY((double)aDeviceRect.Bottom() - ((rVec.getY() - aViewWin.Y) * fHRatio)); + aRetval.setZ(rVec.getZ()); + + return aRetval; +} + +/************************************************************************* +|* +|* View Reference Point setzen +|* +\************************************************************************/ + +void Viewport3D::SetVRP(const basegfx::B3DPoint& rNewVRP) +{ + aVRP = rNewVRP; + bTfValid = FALSE; +} + +/************************************************************************* +|* +|* View Plane Normal setzen +|* +\************************************************************************/ + +void Viewport3D::SetVPN(const basegfx::B3DVector& rNewVPN) +{ + aVPN = rNewVPN; + aVPN.normalize(); + bTfValid = FALSE; +} + +/************************************************************************* +|* +|* View Up Vector setzen +|* +\************************************************************************/ + +void Viewport3D::SetVUV(const basegfx::B3DVector& rNewVUV) +{ + aVUV = rNewVUV; + bTfValid = FALSE; +} + +/************************************************************************* +|* +|* Center Of Projection setzen +|* +\************************************************************************/ + +void Viewport3D::SetPRP(const basegfx::B3DPoint& rNewPRP) +{ + aPRP = rNewPRP; + aPRP.setX(0.0); + aPRP.setY(0.0); + bTfValid = FALSE; +} + +/************************************************************************* +|* +|* View Plane Distance setzen +|* +\************************************************************************/ + +void Viewport3D::SetVPD(double fNewVPD) +{ + fVPD = fNewVPD; + bTfValid = FALSE; +} + +/************************************************************************* +|* +|* Abstand der vorderen Clippingebene setzen +|* +\************************************************************************/ + +void Viewport3D::SetNearClipDist(double fNewNCD) +{ + fNearClipDist = fNewNCD; + bTfValid = FALSE; +} + +/************************************************************************* +|* +|* Abstand der hinteren Clippingebene setzen +|* +\************************************************************************/ + +void Viewport3D::SetFarClipDist(double fNewFCD) +{ + fFarClipDist = fNewFCD; + bTfValid = FALSE; +} + +// eof diff --git a/svx/source/engine3d/volume3d.cxx b/svx/source/engine3d/volume3d.cxx new file mode 100644 index 000000000000..04a94b1705f5 --- /dev/null +++ b/svx/source/engine3d/volume3d.cxx @@ -0,0 +1,32 @@ +/************************************************************************* + * + * 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_svx.hxx" +#include <svx/volume3d.hxx> + +// eof |