diff options
Diffstat (limited to 'sd/source/ui/func/fucon3d.cxx')
-rw-r--r-- | sd/source/ui/func/fucon3d.cxx | 531 |
1 files changed, 531 insertions, 0 deletions
diff --git a/sd/source/ui/func/fucon3d.cxx b/sd/source/ui/func/fucon3d.cxx new file mode 100644 index 000000000000..ef0827cc6efc --- /dev/null +++ b/sd/source/ui/func/fucon3d.cxx @@ -0,0 +1,531 @@ +/************************************************************************* + * + * 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_sd.hxx" + +#include "fucon3d.hxx" +#include <vcl/waitobj.hxx> + +#include <svx/svxids.hrc> +#include <svl/aeitem.hxx> +#include <sfx2/app.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/viewfrm.hxx> +#include <tools/poly.hxx> + +#include <math.h> +#include <svx/globl3d.hxx> +#include <svx/scene3d.hxx> +#include <svx/sphere3d.hxx> +#include <svx/cube3d.hxx> +#include <svx/lathe3d.hxx> +#include <svx/camera3d.hxx> + +#include "app.hrc" +#include "res_bmp.hrc" +#include "View.hxx" +#include "Window.hxx" +#include "ViewShell.hxx" +#include "drawdoc.hxx" +#include "ViewShellBase.hxx" +#include "ToolBarManager.hxx" +#include <svx/svx3ditems.hxx> + +// #97016# +#include <svx/polysc3d.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> + +namespace sd { + +TYPEINIT1( FuConstruct3dObject, FuConstruct ); + +/************************************************************************* +|* +|* Konstruktor +|* +\************************************************************************/ + +FuConstruct3dObject::FuConstruct3dObject ( + ViewShell* pViewSh, + ::sd::Window* pWin, + ::sd::View* pView, + SdDrawDocument* pDoc, + SfxRequest& rReq) + : FuConstruct(pViewSh, pWin, pView, pDoc, rReq) +{ +} + +FunctionReference FuConstruct3dObject::Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq, bool bPermanent ) +{ + FuConstruct3dObject* pFunc; + FunctionReference xFunc( pFunc = new FuConstruct3dObject( pViewSh, pWin, pView, pDoc, rReq ) ); + xFunc->DoExecute(rReq); + pFunc->SetPermanent(bPermanent); + return xFunc; +} + +void FuConstruct3dObject::DoExecute( SfxRequest& rReq ) +{ + FuConstruct::DoExecute( rReq ); + mpViewShell->GetViewShellBase().GetToolBarManager()->SetToolBar( + ToolBarManager::TBG_FUNCTION, + ToolBarManager::msDrawingObjectToolBar); +} + +/************************************************************************* +|* +|* MouseButtonDown-event +|* +\************************************************************************/ + +// #97016# +E3dCompoundObject* FuConstruct3dObject::ImpCreateBasic3DShape() +{ + E3dCompoundObject* p3DObj = NULL; + + switch (nSlotId) + { + default: + case SID_3D_CUBE: + { + p3DObj = new E3dCubeObj( + mpView->Get3DDefaultAttributes(), + ::basegfx::B3DPoint(-2500, -2500, -2500), + ::basegfx::B3DVector(5000, 5000, 5000)); + break; + } + + case SID_3D_SPHERE: + { + p3DObj = new E3dSphereObj( + mpView->Get3DDefaultAttributes(), + ::basegfx::B3DPoint(0, 0, 0), + ::basegfx::B3DVector(5000, 5000, 5000)); + break; + } + + case SID_3D_SHELL: + { + XPolygon aXPoly(Point (0, 1250), 2500, 2500, 0, 900, FALSE); + aXPoly.Scale(5.0, 5.0); + + ::basegfx::B2DPolygon aB2DPolygon(aXPoly.getB2DPolygon()); + if(aB2DPolygon.areControlPointsUsed()) + { + aB2DPolygon = ::basegfx::tools::adaptiveSubdivideByAngle(aB2DPolygon); + } + p3DObj = new E3dLatheObj(mpView->Get3DDefaultAttributes(), ::basegfx::B2DPolyPolygon(aB2DPolygon)); + + // Dies ist ein offenes Objekt, muss daher defaultmaessig + // doppelseitig behandelt werden + p3DObj->SetMergedItem(Svx3DDoubleSidedItem(TRUE)); + break; + } + + case SID_3D_HALF_SPHERE: + { + XPolygon aXPoly(Point (0, 1250), 2500, 2500, 0, 900, FALSE); + aXPoly.Scale(5.0, 5.0); + + aXPoly.Insert(0, Point (2400*5, 1250*5), XPOLY_NORMAL); + aXPoly.Insert(0, Point (2000*5, 1250*5), XPOLY_NORMAL); + aXPoly.Insert(0, Point (1500*5, 1250*5), XPOLY_NORMAL); + aXPoly.Insert(0, Point (1000*5, 1250*5), XPOLY_NORMAL); + aXPoly.Insert(0, Point (500*5, 1250*5), XPOLY_NORMAL); + aXPoly.Insert(0, Point (250*5, 1250*5), XPOLY_NORMAL); + aXPoly.Insert(0, Point (50*5, 1250*5), XPOLY_NORMAL); + aXPoly.Insert(0, Point (0*5, 1250*5), XPOLY_NORMAL); + + ::basegfx::B2DPolygon aB2DPolygon(aXPoly.getB2DPolygon()); + if(aB2DPolygon.areControlPointsUsed()) + { + aB2DPolygon = ::basegfx::tools::adaptiveSubdivideByAngle(aB2DPolygon); + } + p3DObj = new E3dLatheObj(mpView->Get3DDefaultAttributes(), ::basegfx::B2DPolyPolygon(aB2DPolygon)); + break; + } + + case SID_3D_TORUS: + { + ::basegfx::B2DPolygon aB2DPolygon(::basegfx::tools::createPolygonFromCircle(::basegfx::B2DPoint(1000.0, 0.0), 500.0)); + if(aB2DPolygon.areControlPointsUsed()) + { + aB2DPolygon = ::basegfx::tools::adaptiveSubdivideByAngle(aB2DPolygon); + } + p3DObj = new E3dLatheObj(mpView->Get3DDefaultAttributes(), ::basegfx::B2DPolyPolygon(aB2DPolygon)); + break; + } + + case SID_3D_CYLINDER: + { + ::basegfx::B2DPolygon aInnerPoly; + + aInnerPoly.append(::basegfx::B2DPoint(0, 1000*5)); + aInnerPoly.append(::basegfx::B2DPoint(50*5, 1000*5)); + aInnerPoly.append(::basegfx::B2DPoint(100*5, 1000*5)); + aInnerPoly.append(::basegfx::B2DPoint(200*5, 1000*5)); + aInnerPoly.append(::basegfx::B2DPoint(300*5, 1000*5)); + aInnerPoly.append(::basegfx::B2DPoint(400*5, 1000*5)); + aInnerPoly.append(::basegfx::B2DPoint(450*5, 1000*5)); + aInnerPoly.append(::basegfx::B2DPoint(500*5, 1000*5)); + aInnerPoly.append(::basegfx::B2DPoint(500*5, -1000*5)); + aInnerPoly.append(::basegfx::B2DPoint(450*5, -1000*5)); + aInnerPoly.append(::basegfx::B2DPoint(400*5, -1000*5)); + aInnerPoly.append(::basegfx::B2DPoint(300*5, -1000*5)); + aInnerPoly.append(::basegfx::B2DPoint(200*5, -1000*5)); + aInnerPoly.append(::basegfx::B2DPoint(100*5, -1000*5)); + aInnerPoly.append(::basegfx::B2DPoint(50*5, -1000*5)); + aInnerPoly.append(::basegfx::B2DPoint(0*5, -1000*5)); + aInnerPoly.setClosed(true); + + p3DObj = new E3dLatheObj(mpView->Get3DDefaultAttributes(), ::basegfx::B2DPolyPolygon(aInnerPoly)); + break; + } + + case SID_3D_CONE: + { + ::basegfx::B2DPolygon aInnerPoly; + + aInnerPoly.append(::basegfx::B2DPoint(0, -1000*5)); + aInnerPoly.append(::basegfx::B2DPoint(25*5, -900*5)); + aInnerPoly.append(::basegfx::B2DPoint(50*5, -800*5)); + aInnerPoly.append(::basegfx::B2DPoint(100*5, -600*5)); + aInnerPoly.append(::basegfx::B2DPoint(200*5, -200*5)); + aInnerPoly.append(::basegfx::B2DPoint(300*5, 200*5)); + aInnerPoly.append(::basegfx::B2DPoint(400*5, 600*5)); + aInnerPoly.append(::basegfx::B2DPoint(500*5, 1000*5)); + aInnerPoly.append(::basegfx::B2DPoint(400*5, 1000*5)); + aInnerPoly.append(::basegfx::B2DPoint(300*5, 1000*5)); + aInnerPoly.append(::basegfx::B2DPoint(200*5, 1000*5)); + aInnerPoly.append(::basegfx::B2DPoint(100*5, 1000*5)); + aInnerPoly.append(::basegfx::B2DPoint(50*5, 1000*5)); + aInnerPoly.append(::basegfx::B2DPoint(0*5, 1000*5)); + aInnerPoly.setClosed(true); + + p3DObj = new E3dLatheObj(mpView->Get3DDefaultAttributes(), ::basegfx::B2DPolyPolygon(aInnerPoly)); + break; + } + + case SID_3D_PYRAMID: + { + ::basegfx::B2DPolygon aInnerPoly; + + aInnerPoly.append(::basegfx::B2DPoint(0, -1000*5)); + aInnerPoly.append(::basegfx::B2DPoint(25*5, -900*5)); + aInnerPoly.append(::basegfx::B2DPoint(50*5, -800*5)); + aInnerPoly.append(::basegfx::B2DPoint(100*5, -600*5)); + aInnerPoly.append(::basegfx::B2DPoint(200*5, -200*5)); + aInnerPoly.append(::basegfx::B2DPoint(300*5, 200*5)); + aInnerPoly.append(::basegfx::B2DPoint(400*5, 600*5)); + aInnerPoly.append(::basegfx::B2DPoint(500*5, 1000*5)); + aInnerPoly.append(::basegfx::B2DPoint(400*5, 1000*5)); + aInnerPoly.append(::basegfx::B2DPoint(300*5, 1000*5)); + aInnerPoly.append(::basegfx::B2DPoint(200*5, 1000*5)); + aInnerPoly.append(::basegfx::B2DPoint(100*5, 1000*5)); + aInnerPoly.append(::basegfx::B2DPoint(50*5, 1000*5)); + aInnerPoly.append(::basegfx::B2DPoint(0, 1000*5)); + aInnerPoly.setClosed(true); + + p3DObj = new E3dLatheObj(mpView->Get3DDefaultAttributes(), ::basegfx::B2DPolyPolygon(aInnerPoly)); + p3DObj->SetMergedItem(Svx3DHorizontalSegmentsItem(4)); + break; + } + } + + return p3DObj; +} + +// #97016# +void FuConstruct3dObject::ImpPrepareBasic3DShape(E3dCompoundObject* p3DObj, E3dScene *pScene) +{ + Camera3D &aCamera = (Camera3D&) pScene->GetCamera (); + + // get transformed BoundVolume of the new object + basegfx::B3DRange aBoundVol; + basegfx::B3DRange aObjVol(p3DObj->GetBoundVolume()); + aObjVol.transform(p3DObj->GetTransform()); + aBoundVol.expand(aObjVol); + double fDeepth(aBoundVol.getDepth()); + + aCamera.SetPRP(::basegfx::B3DPoint(0.0, 0.0, 1000.0)); + aCamera.SetPosition(::basegfx::B3DPoint(0.0, 0.0, mpView->GetDefaultCamPosZ() + fDeepth / 2)); + aCamera.SetFocalLength(mpView->GetDefaultCamFocal()); + pScene->SetCamera(aCamera); + basegfx::B3DHomMatrix aTransformation; + + switch (nSlotId) + { + case SID_3D_CUBE: + { + aTransformation.rotate(DEG2RAD(20), 0.0, 0.0); + } + break; + + case SID_3D_SPHERE: + { +// pScene->RotateX(DEG2RAD(60)); + } + break; + + case SID_3D_SHELL: + case SID_3D_HALF_SPHERE: + { + aTransformation.rotate(DEG2RAD(200), 0.0, 0.0); + } + break; + + case SID_3D_CYLINDER: + case SID_3D_CONE: + case SID_3D_PYRAMID: + { +// pScene->RotateX(DEG2RAD(25)); + } + break; + + case SID_3D_TORUS: + { +// pScene->RotateX(DEG2RAD(15)); + aTransformation.rotate(DEG2RAD(90), 0.0, 0.0); + } + break; + + default: + { + } + break; + } + + pScene->SetTransform(aTransformation * pScene->GetTransform()); + + SfxItemSet aAttr (mpViewShell->GetPool()); + pScene->SetMergedItemSetAndBroadcast(aAttr); +} + +BOOL FuConstruct3dObject::MouseButtonDown(const MouseEvent& rMEvt) +{ + BOOL bReturn = FuConstruct::MouseButtonDown(rMEvt); + + if ( rMEvt.IsLeft() && !mpView->IsAction() ) + { + Point aPnt( mpWindow->PixelToLogic( rMEvt.GetPosPixel() ) ); + + mpWindow->CaptureMouse(); + USHORT nDrgLog = USHORT ( mpWindow->PixelToLogic(Size(DRGPIX,0)).Width() ); + + E3dCompoundObject* p3DObj = NULL; + + WaitObject aWait( (Window*)mpViewShell->GetActiveWindow() ); + + // #97016# + p3DObj = ImpCreateBasic3DShape(); + E3dScene* pScene = mpView->SetCurrent3DObj(p3DObj); + + // #97016# + ImpPrepareBasic3DShape(p3DObj, pScene); + bReturn = mpView->BegCreatePreparedObject(aPnt, nDrgLog, pScene); + + SdrObject* pObj = mpView->GetCreateObj(); + + if (pObj) + { + SfxItemSet aAttr(mpDoc->GetPool()); + SetStyleSheet(aAttr, pObj); + + // LineStyle rausnehmen + aAttr.Put(XLineStyleItem (XLINE_NONE)); + + pObj->SetMergedItemSet(aAttr); + } + } + + return bReturn; +} + +/************************************************************************* +|* +|* MouseMove-event +|* +\************************************************************************/ + +BOOL FuConstruct3dObject::MouseMove(const MouseEvent& rMEvt) +{ + return FuConstruct::MouseMove(rMEvt); +} + +/************************************************************************* +|* +|* MouseButtonUp-event +|* +\************************************************************************/ + +BOOL FuConstruct3dObject::MouseButtonUp(const MouseEvent& rMEvt) +{ + BOOL bReturn = FALSE; + + if ( mpView->IsCreateObj() && rMEvt.IsLeft() ) + { + Point aPnt( mpWindow->PixelToLogic( rMEvt.GetPosPixel() ) ); + mpView->EndCreateObj(SDRCREATE_FORCEEND); + bReturn = TRUE; + } + + bReturn = FuConstruct::MouseButtonUp(rMEvt) || bReturn; + + if (!bPermanent) + mpViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SFX_CALLMODE_ASYNCHRON); + + return bReturn; +} + +/************************************************************************* +|* +|* Tastaturereignisse bearbeiten +|* +|* Wird ein KeyEvent bearbeitet, so ist der Return-Wert TRUE, andernfalls +|* FALSE. +|* +\************************************************************************/ + +BOOL FuConstruct3dObject::KeyInput(const KeyEvent& rKEvt) +{ + return( FuConstruct::KeyInput(rKEvt) ); +} + +/************************************************************************* +|* +|* Function aktivieren +|* +\************************************************************************/ + +void FuConstruct3dObject::Activate() +{ + mpView->SetCurrentObj(OBJ_NONE); + + FuConstruct::Activate(); +} + +/************************************************************************* +|* +|* Function deaktivieren +|* +\************************************************************************/ + +void FuConstruct3dObject::Deactivate() +{ + FuConstruct::Deactivate(); +} + +// #97016# +SdrObject* FuConstruct3dObject::CreateDefaultObject(const sal_uInt16 nID, const Rectangle& rRectangle) +{ + // case SID_3D_CUBE: + // case SID_3D_SHELL: + // case SID_3D_SPHERE: + // case SID_3D_TORUS: + // case SID_3D_HALF_SPHERE: + // case SID_3D_CYLINDER: + // case SID_3D_CONE: + // case SID_3D_PYRAMID: + + E3dCompoundObject* p3DObj = ImpCreateBasic3DShape(); + + // E3dView::SetCurrent3DObj part + // get transformed BoundVolume of the object + basegfx::B3DRange aObjVol(p3DObj->GetBoundVolume()); + aObjVol.transform(p3DObj->GetTransform()); + basegfx::B3DRange aVolume(aObjVol); + double fW(aVolume.getWidth()); + double fH(aVolume.getHeight()); + Rectangle a3DRect(0, 0, (long)fW, (long)fH); + E3dScene* pScene = new E3dPolyScene(mpView->Get3DDefaultAttributes()); + + // mpView->InitScene(pScene, fW, fH, aVolume.MaxVec().Z() + ((fW + fH) / 4.0)); + // copied code from E3dView::InitScene + double fCamZ(aVolume.getMaxZ() + ((fW + fH) / 4.0)); + Camera3D aCam(pScene->GetCamera()); + aCam.SetAutoAdjustProjection(FALSE); + aCam.SetViewWindow(- fW / 2, - fH / 2, fW, fH); + ::basegfx::B3DPoint aLookAt; + double fDefaultCamPosZ = mpView->GetDefaultCamPosZ(); + ::basegfx::B3DPoint aCamPos(0.0, 0.0, fCamZ < fDefaultCamPosZ ? fDefaultCamPosZ : fCamZ); + aCam.SetPosAndLookAt(aCamPos, aLookAt); + aCam.SetFocalLength(mpView->GetDefaultCamFocal()); + aCam.SetDefaults(::basegfx::B3DPoint(0.0, 0.0, fDefaultCamPosZ), aLookAt, mpView->GetDefaultCamFocal()); + pScene->SetCamera(aCam); + + pScene->Insert3DObj(p3DObj); + pScene->NbcSetSnapRect(a3DRect); + pScene->SetModel(mpDoc); + + ImpPrepareBasic3DShape(p3DObj, pScene); + + SfxItemSet aAttr(mpDoc->GetPool()); + SetStyleSheet(aAttr, p3DObj); + aAttr.Put(XLineStyleItem (XLINE_NONE)); + p3DObj->SetMergedItemSet(aAttr); + + // make object interactive at once + pScene->SetRectsDirty(); + + // Take care of restrictions for the rectangle + Rectangle aRect(rRectangle); + + switch(nID) + { + case SID_3D_CUBE: + case SID_3D_SPHERE: + case SID_3D_TORUS: + { + // force quadratic + ImpForceQuadratic(aRect); + break; + } + + case SID_3D_SHELL: + case SID_3D_HALF_SPHERE: + { + // force horizontal layout + break; + } + + case SID_3D_CYLINDER: + case SID_3D_CONE: + case SID_3D_PYRAMID: + { + // force vertical layout + break; + } + } + + // #97016#, #98245# use changed rectangle, not original one + pScene->SetLogicRect(aRect); + + return pScene; +} + +} // end of namespace sd |