1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: fucon3d.cxx,v $
10 * $Revision: 1.23.8.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sd.hxx"
34 #include "fucon3d.hxx"
35 #include <vcl/waitobj.hxx>
37 #include <svx/svxids.hrc>
38 #include <svtools/aeitem.hxx>
39 #include <sfx2/app.hxx>
40 #include <sfx2/dispatch.hxx>
41 #include <sfx2/viewfrm.hxx>
42 #include <tools/poly.hxx>
45 #include <svx/globl3d.hxx>
46 #include <svx/scene3d.hxx>
47 #include <svx/sphere3d.hxx>
48 #include <svx/cube3d.hxx>
49 #include <svx/lathe3d.hxx>
50 #include <svx/camera3d.hxx>
53 #include "res_bmp.hrc"
56 #include "ViewShell.hxx"
57 #include "drawdoc.hxx"
58 #include "ViewShellBase.hxx"
59 #include "ToolBarManager.hxx"
60 #include <svx/svx3ditems.hxx>
63 #include <svx/polysc3d.hxx>
64 #include <basegfx/polygon/b2dpolygontools.hxx>
68 TYPEINIT1( FuConstruct3dObject
, FuConstruct
);
70 /*************************************************************************
74 \************************************************************************/
76 FuConstruct3dObject::FuConstruct3dObject (
82 : FuConstruct(pViewSh
, pWin
, pView
, pDoc
, rReq
)
86 FunctionReference
FuConstruct3dObject::Create( ViewShell
* pViewSh
, ::sd::Window
* pWin
, ::sd::View
* pView
, SdDrawDocument
* pDoc
, SfxRequest
& rReq
, bool bPermanent
)
88 FuConstruct3dObject
* pFunc
;
89 FunctionReference
xFunc( pFunc
= new FuConstruct3dObject( pViewSh
, pWin
, pView
, pDoc
, rReq
) );
90 xFunc
->DoExecute(rReq
);
91 pFunc
->SetPermanent(bPermanent
);
95 void FuConstruct3dObject::DoExecute( SfxRequest
& rReq
)
97 FuConstruct::DoExecute( rReq
);
98 mpViewShell
->GetViewShellBase().GetToolBarManager()->SetToolBar(
99 ToolBarManager::TBG_FUNCTION
,
100 ToolBarManager::msDrawingObjectToolBar
);
103 /*************************************************************************
105 |* MouseButtonDown-event
107 \************************************************************************/
110 E3dCompoundObject
* FuConstruct3dObject::ImpCreateBasic3DShape()
112 E3dCompoundObject
* p3DObj
= NULL
;
119 p3DObj
= new E3dCubeObj(
120 mpView
->Get3DDefaultAttributes(),
121 ::basegfx::B3DPoint(-2500, -2500, -2500),
122 ::basegfx::B3DVector(5000, 5000, 5000));
128 p3DObj
= new E3dSphereObj(
129 mpView
->Get3DDefaultAttributes(),
130 ::basegfx::B3DPoint(0, 0, 0),
131 ::basegfx::B3DVector(5000, 5000, 5000));
137 XPolygon
aXPoly(Point (0, 1250), 2500, 2500, 0, 900, FALSE
);
138 aXPoly
.Scale(5.0, 5.0);
140 ::basegfx::B2DPolygon
aB2DPolygon(aXPoly
.getB2DPolygon());
141 if(aB2DPolygon
.areControlPointsUsed())
143 aB2DPolygon
= ::basegfx::tools::adaptiveSubdivideByAngle(aB2DPolygon
);
145 p3DObj
= new E3dLatheObj(mpView
->Get3DDefaultAttributes(), ::basegfx::B2DPolyPolygon(aB2DPolygon
));
147 // Dies ist ein offenes Objekt, muss daher defaultmaessig
148 // doppelseitig behandelt werden
149 p3DObj
->SetMergedItem(Svx3DDoubleSidedItem(TRUE
));
153 case SID_3D_HALF_SPHERE
:
155 XPolygon
aXPoly(Point (0, 1250), 2500, 2500, 0, 900, FALSE
);
156 aXPoly
.Scale(5.0, 5.0);
158 aXPoly
.Insert(0, Point (2400*5, 1250*5), XPOLY_NORMAL
);
159 aXPoly
.Insert(0, Point (2000*5, 1250*5), XPOLY_NORMAL
);
160 aXPoly
.Insert(0, Point (1500*5, 1250*5), XPOLY_NORMAL
);
161 aXPoly
.Insert(0, Point (1000*5, 1250*5), XPOLY_NORMAL
);
162 aXPoly
.Insert(0, Point (500*5, 1250*5), XPOLY_NORMAL
);
163 aXPoly
.Insert(0, Point (250*5, 1250*5), XPOLY_NORMAL
);
164 aXPoly
.Insert(0, Point (50*5, 1250*5), XPOLY_NORMAL
);
165 aXPoly
.Insert(0, Point (0*5, 1250*5), XPOLY_NORMAL
);
167 ::basegfx::B2DPolygon
aB2DPolygon(aXPoly
.getB2DPolygon());
168 if(aB2DPolygon
.areControlPointsUsed())
170 aB2DPolygon
= ::basegfx::tools::adaptiveSubdivideByAngle(aB2DPolygon
);
172 p3DObj
= new E3dLatheObj(mpView
->Get3DDefaultAttributes(), ::basegfx::B2DPolyPolygon(aB2DPolygon
));
178 ::basegfx::B2DPolygon
aB2DPolygon(::basegfx::tools::createPolygonFromCircle(::basegfx::B2DPoint(1000.0, 0.0), 500.0));
179 if(aB2DPolygon
.areControlPointsUsed())
181 aB2DPolygon
= ::basegfx::tools::adaptiveSubdivideByAngle(aB2DPolygon
);
183 p3DObj
= new E3dLatheObj(mpView
->Get3DDefaultAttributes(), ::basegfx::B2DPolyPolygon(aB2DPolygon
));
187 case SID_3D_CYLINDER
:
189 ::basegfx::B2DPolygon aInnerPoly
;
191 aInnerPoly
.append(::basegfx::B2DPoint(0, 1000*5));
192 aInnerPoly
.append(::basegfx::B2DPoint(50*5, 1000*5));
193 aInnerPoly
.append(::basegfx::B2DPoint(100*5, 1000*5));
194 aInnerPoly
.append(::basegfx::B2DPoint(200*5, 1000*5));
195 aInnerPoly
.append(::basegfx::B2DPoint(300*5, 1000*5));
196 aInnerPoly
.append(::basegfx::B2DPoint(400*5, 1000*5));
197 aInnerPoly
.append(::basegfx::B2DPoint(450*5, 1000*5));
198 aInnerPoly
.append(::basegfx::B2DPoint(500*5, 1000*5));
199 aInnerPoly
.append(::basegfx::B2DPoint(500*5, -1000*5));
200 aInnerPoly
.append(::basegfx::B2DPoint(450*5, -1000*5));
201 aInnerPoly
.append(::basegfx::B2DPoint(400*5, -1000*5));
202 aInnerPoly
.append(::basegfx::B2DPoint(300*5, -1000*5));
203 aInnerPoly
.append(::basegfx::B2DPoint(200*5, -1000*5));
204 aInnerPoly
.append(::basegfx::B2DPoint(100*5, -1000*5));
205 aInnerPoly
.append(::basegfx::B2DPoint(50*5, -1000*5));
206 aInnerPoly
.append(::basegfx::B2DPoint(0*5, -1000*5));
207 aInnerPoly
.setClosed(true);
209 p3DObj
= new E3dLatheObj(mpView
->Get3DDefaultAttributes(), ::basegfx::B2DPolyPolygon(aInnerPoly
));
215 ::basegfx::B2DPolygon aInnerPoly
;
217 aInnerPoly
.append(::basegfx::B2DPoint(0, -1000*5));
218 aInnerPoly
.append(::basegfx::B2DPoint(25*5, -900*5));
219 aInnerPoly
.append(::basegfx::B2DPoint(50*5, -800*5));
220 aInnerPoly
.append(::basegfx::B2DPoint(100*5, -600*5));
221 aInnerPoly
.append(::basegfx::B2DPoint(200*5, -200*5));
222 aInnerPoly
.append(::basegfx::B2DPoint(300*5, 200*5));
223 aInnerPoly
.append(::basegfx::B2DPoint(400*5, 600*5));
224 aInnerPoly
.append(::basegfx::B2DPoint(500*5, 1000*5));
225 aInnerPoly
.append(::basegfx::B2DPoint(400*5, 1000*5));
226 aInnerPoly
.append(::basegfx::B2DPoint(300*5, 1000*5));
227 aInnerPoly
.append(::basegfx::B2DPoint(200*5, 1000*5));
228 aInnerPoly
.append(::basegfx::B2DPoint(100*5, 1000*5));
229 aInnerPoly
.append(::basegfx::B2DPoint(50*5, 1000*5));
230 aInnerPoly
.append(::basegfx::B2DPoint(0*5, 1000*5));
231 aInnerPoly
.setClosed(true);
233 p3DObj
= new E3dLatheObj(mpView
->Get3DDefaultAttributes(), ::basegfx::B2DPolyPolygon(aInnerPoly
));
239 ::basegfx::B2DPolygon aInnerPoly
;
241 aInnerPoly
.append(::basegfx::B2DPoint(0, -1000*5));
242 aInnerPoly
.append(::basegfx::B2DPoint(25*5, -900*5));
243 aInnerPoly
.append(::basegfx::B2DPoint(50*5, -800*5));
244 aInnerPoly
.append(::basegfx::B2DPoint(100*5, -600*5));
245 aInnerPoly
.append(::basegfx::B2DPoint(200*5, -200*5));
246 aInnerPoly
.append(::basegfx::B2DPoint(300*5, 200*5));
247 aInnerPoly
.append(::basegfx::B2DPoint(400*5, 600*5));
248 aInnerPoly
.append(::basegfx::B2DPoint(500*5, 1000*5));
249 aInnerPoly
.append(::basegfx::B2DPoint(400*5, 1000*5));
250 aInnerPoly
.append(::basegfx::B2DPoint(300*5, 1000*5));
251 aInnerPoly
.append(::basegfx::B2DPoint(200*5, 1000*5));
252 aInnerPoly
.append(::basegfx::B2DPoint(100*5, 1000*5));
253 aInnerPoly
.append(::basegfx::B2DPoint(50*5, 1000*5));
254 aInnerPoly
.append(::basegfx::B2DPoint(0, 1000*5));
255 aInnerPoly
.setClosed(true);
257 p3DObj
= new E3dLatheObj(mpView
->Get3DDefaultAttributes(), ::basegfx::B2DPolyPolygon(aInnerPoly
));
258 p3DObj
->SetMergedItem(Svx3DHorizontalSegmentsItem(4));
267 void FuConstruct3dObject::ImpPrepareBasic3DShape(E3dCompoundObject
* p3DObj
, E3dScene
*pScene
)
269 Camera3D
&aCamera
= (Camera3D
&) pScene
->GetCamera ();
271 // get transformed BoundVolume of the new object
272 basegfx::B3DRange aBoundVol
;
273 basegfx::B3DRange
aObjVol(p3DObj
->GetBoundVolume());
274 aObjVol
.transform(p3DObj
->GetTransform());
275 aBoundVol
.expand(aObjVol
);
276 double fDeepth(aBoundVol
.getDepth());
278 aCamera
.SetPRP(::basegfx::B3DPoint(0.0, 0.0, 1000.0));
279 aCamera
.SetPosition(::basegfx::B3DPoint(0.0, 0.0, mpView
->GetDefaultCamPosZ() + fDeepth
/ 2));
280 aCamera
.SetFocalLength(mpView
->GetDefaultCamFocal());
281 pScene
->SetCamera(aCamera
);
282 basegfx::B3DHomMatrix aTransformation
;
288 aTransformation
.rotate(DEG2RAD(20), 0.0, 0.0);
294 // pScene->RotateX(DEG2RAD(60));
299 case SID_3D_HALF_SPHERE
:
301 aTransformation
.rotate(DEG2RAD(200), 0.0, 0.0);
305 case SID_3D_CYLINDER
:
309 // pScene->RotateX(DEG2RAD(25));
315 // pScene->RotateX(DEG2RAD(15));
316 aTransformation
.rotate(DEG2RAD(90), 0.0, 0.0);
326 pScene
->SetTransform(aTransformation
* pScene
->GetTransform());
328 SfxItemSet
aAttr (mpViewShell
->GetPool());
329 pScene
->SetMergedItemSetAndBroadcast(aAttr
);
332 BOOL
FuConstruct3dObject::MouseButtonDown(const MouseEvent
& rMEvt
)
334 BOOL bReturn
= FuConstruct::MouseButtonDown(rMEvt
);
336 if ( rMEvt
.IsLeft() && !mpView
->IsAction() )
338 Point
aPnt( mpWindow
->PixelToLogic( rMEvt
.GetPosPixel() ) );
340 mpWindow
->CaptureMouse();
341 USHORT nDrgLog
= USHORT ( mpWindow
->PixelToLogic(Size(DRGPIX
,0)).Width() );
343 E3dCompoundObject
* p3DObj
= NULL
;
345 WaitObject
aWait( (Window
*)mpViewShell
->GetActiveWindow() );
348 p3DObj
= ImpCreateBasic3DShape();
349 E3dScene
* pScene
= mpView
->SetCurrent3DObj(p3DObj
);
352 ImpPrepareBasic3DShape(p3DObj
, pScene
);
353 bReturn
= mpView
->BegCreatePreparedObject(aPnt
, nDrgLog
, pScene
);
355 SdrObject
* pObj
= mpView
->GetCreateObj();
359 SfxItemSet
aAttr(mpDoc
->GetPool());
360 SetStyleSheet(aAttr
, pObj
);
362 // LineStyle rausnehmen
363 aAttr
.Put(XLineStyleItem (XLINE_NONE
));
365 pObj
->SetMergedItemSet(aAttr
);
372 /*************************************************************************
376 \************************************************************************/
378 BOOL
FuConstruct3dObject::MouseMove(const MouseEvent
& rMEvt
)
380 return FuConstruct::MouseMove(rMEvt
);
383 /*************************************************************************
385 |* MouseButtonUp-event
387 \************************************************************************/
389 BOOL
FuConstruct3dObject::MouseButtonUp(const MouseEvent
& rMEvt
)
391 BOOL bReturn
= FALSE
;
393 if ( mpView
->IsCreateObj() && rMEvt
.IsLeft() )
395 Point
aPnt( mpWindow
->PixelToLogic( rMEvt
.GetPosPixel() ) );
396 mpView
->EndCreateObj(SDRCREATE_FORCEEND
);
400 bReturn
= FuConstruct::MouseButtonUp(rMEvt
) || bReturn
;
403 mpViewShell
->GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT
, SFX_CALLMODE_ASYNCHRON
);
408 /*************************************************************************
410 |* Tastaturereignisse bearbeiten
412 |* Wird ein KeyEvent bearbeitet, so ist der Return-Wert TRUE, andernfalls
415 \************************************************************************/
417 BOOL
FuConstruct3dObject::KeyInput(const KeyEvent
& rKEvt
)
419 return( FuConstruct::KeyInput(rKEvt
) );
422 /*************************************************************************
424 |* Function aktivieren
426 \************************************************************************/
428 void FuConstruct3dObject::Activate()
430 mpView
->SetCurrentObj(OBJ_NONE
);
432 FuConstruct::Activate();
435 /*************************************************************************
437 |* Function deaktivieren
439 \************************************************************************/
441 void FuConstruct3dObject::Deactivate()
443 FuConstruct::Deactivate();
447 SdrObject
* FuConstruct3dObject::CreateDefaultObject(const sal_uInt16 nID
, const Rectangle
& rRectangle
)
450 // case SID_3D_SHELL:
451 // case SID_3D_SPHERE:
452 // case SID_3D_TORUS:
453 // case SID_3D_HALF_SPHERE:
454 // case SID_3D_CYLINDER:
456 // case SID_3D_PYRAMID:
458 E3dCompoundObject
* p3DObj
= ImpCreateBasic3DShape();
460 // E3dView::SetCurrent3DObj part
461 // get transformed BoundVolume of the object
462 basegfx::B3DRange
aObjVol(p3DObj
->GetBoundVolume());
463 aObjVol
.transform(p3DObj
->GetTransform());
464 basegfx::B3DRange
aVolume(aObjVol
);
465 double fW(aVolume
.getWidth());
466 double fH(aVolume
.getHeight());
467 Rectangle
a3DRect(0, 0, (long)fW
, (long)fH
);
468 E3dScene
* pScene
= new E3dPolyScene(mpView
->Get3DDefaultAttributes());
470 // mpView->InitScene(pScene, fW, fH, aVolume.MaxVec().Z() + ((fW + fH) / 4.0));
471 // copied code from E3dView::InitScene
472 double fCamZ(aVolume
.getMaxZ() + ((fW
+ fH
) / 4.0));
473 Camera3D
aCam(pScene
->GetCamera());
474 aCam
.SetAutoAdjustProjection(FALSE
);
475 aCam
.SetViewWindow(- fW
/ 2, - fH
/ 2, fW
, fH
);
476 ::basegfx::B3DPoint aLookAt
;
477 double fDefaultCamPosZ
= mpView
->GetDefaultCamPosZ();
478 ::basegfx::B3DPoint
aCamPos(0.0, 0.0, fCamZ
< fDefaultCamPosZ
? fDefaultCamPosZ
: fCamZ
);
479 aCam
.SetPosAndLookAt(aCamPos
, aLookAt
);
480 aCam
.SetFocalLength(mpView
->GetDefaultCamFocal());
481 aCam
.SetDefaults(::basegfx::B3DPoint(0.0, 0.0, fDefaultCamPosZ
), aLookAt
, mpView
->GetDefaultCamFocal());
482 pScene
->SetCamera(aCam
);
484 pScene
->Insert3DObj(p3DObj
);
485 pScene
->NbcSetSnapRect(a3DRect
);
486 pScene
->SetModel(mpDoc
);
488 ImpPrepareBasic3DShape(p3DObj
, pScene
);
490 SfxItemSet
aAttr(mpDoc
->GetPool());
491 SetStyleSheet(aAttr
, p3DObj
);
492 aAttr
.Put(XLineStyleItem (XLINE_NONE
));
493 p3DObj
->SetMergedItemSet(aAttr
);
495 // make object interactive at once
496 pScene
->SetRectsDirty();
498 // Take care of restrictions for the rectangle
499 Rectangle
aRect(rRectangle
);
508 ImpForceQuadratic(aRect
);
513 case SID_3D_HALF_SPHERE
:
515 // force horizontal layout
519 case SID_3D_CYLINDER
:
523 // force vertical layout
528 // #97016#, #98245# use changed rectangle, not original one
529 pScene
->SetLogicRect(aRect
);
534 } // end of namespace sd