fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / svx / source / engine3d / obj3d.cxx
blob06835cefa6ea8eb6cfb81eb76af73a55d878eeda
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "svx/svdstr.hrc"
22 #include "svx/svdglob.hxx"
23 #include <svx/svdview.hxx>
24 #include <svx/svdattr.hxx>
25 #include <svx/svdpage.hxx>
26 #include <svx/svdmodel.hxx>
27 #include "svx/svditer.hxx"
28 #include "svx/globl3d.hxx"
29 #include <svx/camera3d.hxx>
30 #include <svx/scene3d.hxx>
31 #include <svx/polysc3d.hxx>
32 #include <svx/cube3d.hxx>
33 #include <svx/lathe3d.hxx>
34 #include <svx/sphere3d.hxx>
35 #include <svx/extrud3d.hxx>
36 #include <svx/obj3d.hxx>
37 #include <svx/xtable.hxx>
38 #include <svx/xflclit.hxx>
39 #include <vcl/svapp.hxx>
40 #include <vcl/settings.hxx>
41 #include <svx/xlnclit.hxx>
42 #include <svl/metitem.hxx>
43 #include <svx/xfillit.hxx>
44 #include <svx/xlnwtit.hxx>
45 #include <vcl/virdev.hxx>
46 #include <tools/poly.hxx>
47 #include <tools/b3dtrans.hxx>
48 #include <svx/svxids.hrc>
49 #include <editeng/colritem.hxx>
50 #include <svx/e3ditem.hxx>
51 #include <svx/xlntrit.hxx>
52 #include <svx/xfltrit.hxx>
53 #include <svx/svdpagv.hxx>
54 #include <vcl/gradient.hxx>
55 #include <vcl/metaact.hxx>
56 #include <svx/svx3ditems.hxx>
57 #include <svl/whiter.hxx>
58 #include <svtools/colorcfg.hxx>
59 #include <editeng/eeitem.hxx>
60 #include <svx/xgrscit.hxx>
61 #include <svx/sdr/properties/e3dproperties.hxx>
62 #include <svx/sdr/properties/e3dcompoundproperties.hxx>
63 #include <basegfx/polygon/b3dpolypolygontools.hxx>
64 #include <basegfx/point/b3dpoint.hxx>
65 #include <basegfx/vector/b3dvector.hxx>
66 #include <svx/xlndsit.hxx>
67 #include <basegfx/matrix/b3dhommatrix.hxx>
68 #include <basegfx/polygon/b3dpolygon.hxx>
69 #include <basegfx/matrix/b2dhommatrix.hxx>
70 #include <basegfx/polygon/b2dpolypolygontools.hxx>
71 #include <basegfx/polygon/b3dpolygontools.hxx>
72 #include <svx/helperhittest3d.hxx>
73 #include <svx/sdr/contact/viewcontactofe3d.hxx>
74 #include <drawinglayer/geometry/viewinformation3d.hxx>
75 #include <com/sun/star/uno/Sequence.h>
76 #include <svx/sdr/contact/viewcontactofe3dscene.hxx>
77 #include <svx/e3dsceneupdater.hxx>
79 //////////////////////////////////////////////////////////////////////////////
81 using namespace com::sun::star;
84 // List for 3D-Objects
86 TYPEINIT1(E3dObjList, SdrObjList);
88 E3dObjList::E3dObjList(SdrModel* pNewModel, SdrPage* pNewPage, E3dObjList* pNewUpList)
89 : SdrObjList(pNewModel, pNewPage, pNewUpList)
93 E3dObjList::E3dObjList(const E3dObjList& rSrcList)
94 : SdrObjList(rSrcList)
98 E3dObjList::~E3dObjList()
102 void E3dObjList::NbcInsertObject(SdrObject* pObj, sal_uIntPtr nPos, const SdrInsertReason* pReason)
104 // Get owner
105 DBG_ASSERT(GetOwnerObj()->ISA(E3dObject), "Insert 3D object in parent != 3DObject");
107 // Is it even a 3D object?
108 if(pObj && pObj->ISA(E3dObject))
110 // Normal 3D object, insert means
111 // call parent
112 SdrObjList::NbcInsertObject(pObj, nPos, pReason);
114 else
116 // No 3D object, inserted a page in place in a scene ...
117 GetOwnerObj()->GetPage()->InsertObject(pObj, nPos);
121 void E3dObjList::InsertObject(SdrObject* pObj, sal_uIntPtr nPos, const SdrInsertReason* pReason)
123 OSL_ENSURE(GetOwnerObj()->ISA(E3dObject), "Insert 3D object in non-3D Parent");
125 // call parent
126 SdrObjList::InsertObject(pObj, nPos, pReason);
128 E3dScene* pScene = ((E3dObject*)GetOwnerObj())->GetScene();
129 if(pScene)
131 pScene->Cleanup3DDepthMapper();
135 SdrObject* E3dObjList::NbcRemoveObject(sal_uIntPtr nObjNum)
137 DBG_ASSERT(GetOwnerObj()->ISA(E3dObject), "Remove 3D object from Parent != 3DObject");
139 // call parent
140 SdrObject* pRetval = SdrObjList::NbcRemoveObject(nObjNum);
142 E3dScene* pScene = ((E3dObject*)GetOwnerObj())->GetScene();
143 if(pScene)
145 pScene->Cleanup3DDepthMapper();
148 return pRetval;
151 SdrObject* E3dObjList::RemoveObject(sal_uIntPtr nObjNum)
153 OSL_ENSURE(GetOwnerObj()->ISA(E3dObject), "3D object is removed from non-3D Parent");
155 // call parent
156 SdrObject* pRetval = SdrObjList::RemoveObject(nObjNum);
158 E3dScene* pScene = ((E3dObject*)GetOwnerObj())->GetScene();
159 if(pScene)
161 pScene->Cleanup3DDepthMapper();
164 return pRetval;
167 //////////////////////////////////////////////////////////////////////////////
169 sdr::properties::BaseProperties* E3dObject::CreateObjectSpecificProperties()
171 return new sdr::properties::E3dProperties(*this);
174 //////////////////////////////////////////////////////////////////////////////
176 TYPEINIT1(E3dObject, SdrAttrObj);
178 E3dObject::E3dObject()
179 : maSubList(),
180 maLocalBoundVol(),
181 maTransformation(),
182 maFullTransform(),
183 mbTfHasChanged(true),
184 mbIsSelected(false)
186 bIs3DObj = true;
187 maSubList.SetOwnerObj(this);
188 maSubList.SetListKind(SDROBJLIST_GROUPOBJ);
189 bClosedObj = true;
192 E3dObject::~E3dObject()
196 void E3dObject::SetSelected(bool bNew)
198 if((bool)mbIsSelected != bNew)
200 mbIsSelected = bNew;
203 for(sal_uInt32 a(0); a < maSubList.GetObjCount(); a++)
205 E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a));
207 if(pCandidate)
209 pCandidate->SetSelected(bNew);
214 // Break, default implementations
216 bool E3dObject::IsBreakObjPossible()
218 return false;
221 SdrAttrObj* E3dObject::GetBreakObj()
223 return 0L;
226 // SetRectsDirty must be done through the local SdrSubList
228 void E3dObject::SetRectsDirty(sal_Bool bNotMyself)
230 // call parent
231 SdrAttrObj::SetRectsDirty(bNotMyself);
233 for(sal_uInt32 a(0); a < maSubList.GetObjCount(); a++)
235 E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a));
237 if(pCandidate)
239 pCandidate->SetRectsDirty(bNotMyself);
244 sal_uInt32 E3dObject::GetObjInventor() const
246 return E3dInventor;
249 sal_uInt16 E3dObject::GetObjIdentifier() const
251 return E3D_OBJECT_ID;
254 // Determine the capabilities of the object
256 void E3dObject::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
258 rInfo.bResizeFreeAllowed = sal_True;
259 rInfo.bResizePropAllowed = sal_True;
260 rInfo.bRotateFreeAllowed = sal_True;
261 rInfo.bRotate90Allowed = sal_True;
262 rInfo.bMirrorFreeAllowed = sal_False;
263 rInfo.bMirror45Allowed = sal_False;
264 rInfo.bMirror90Allowed = sal_False;
265 rInfo.bShearAllowed = sal_False;
266 rInfo.bEdgeRadiusAllowed = sal_False;
267 rInfo.bCanConvToPath = sal_False;
269 // no transparence for 3d objects
270 rInfo.bTransparenceAllowed = sal_False;
272 // gradient depends on fillstyle
273 // BM *** check if SetItem is NULL ***
274 XFillStyle eFillStyle = ((XFillStyleItem&)(GetMergedItem(XATTR_FILLSTYLE))).GetValue();
275 rInfo.bGradientAllowed = (eFillStyle == XFILL_GRADIENT);
277 // Convert 3D objects in a group of polygons:
278 // At first not only possible, because the creation of a group of
279 // 2D polygons would be required which need to be sorted by depth,
280 // ie at intersections be cut relative to each other. Also the texture
281 // coorinates were an unsolved problem.
282 rInfo.bCanConvToPoly = sal_False;
283 rInfo.bCanConvToContour = sal_False;
284 rInfo.bCanConvToPathLineToArea = sal_False;
285 rInfo.bCanConvToPolyLineToArea = sal_False;
288 void E3dObject::NbcSetLayer(SdrLayerID nLayer)
290 SdrAttrObj::NbcSetLayer(nLayer);
292 for(sal_uInt32 a(0); a < maSubList.GetObjCount(); a++)
294 E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a));
296 if(pCandidate)
298 pCandidate->NbcSetLayer(nLayer);
303 // Set ObjList also on SubList
305 void E3dObject::SetObjList(SdrObjList* pNewObjList)
307 SdrObject::SetObjList(pNewObjList);
308 maSubList.SetUpList(pNewObjList);
311 void E3dObject::SetPage(SdrPage* pNewPage)
313 SdrAttrObj::SetPage(pNewPage);
314 maSubList.SetPage(pNewPage);
317 void E3dObject::SetModel(SdrModel* pNewModel)
319 SdrAttrObj::SetModel(pNewModel);
320 maSubList.SetModel(pNewModel);
323 // resize object, used from old 2d interfaces, e.g. in Move/Scale dialog (F4)
325 void E3dObject::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
327 // Movement in X, Y in the eye coordinate system
328 E3dScene* pScene = GetScene();
330 if(pScene)
332 // transform pos from 2D world to 3D eye
333 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pScene->GetViewContact());
334 const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D());
335 basegfx::B2DPoint aScaleCenter2D((double)rRef.X(), (double)rRef.Y());
336 basegfx::B2DHomMatrix aInverseSceneTransform(rVCScene.getObjectTransformation());
338 aInverseSceneTransform.invert();
339 aScaleCenter2D = aInverseSceneTransform * aScaleCenter2D;
341 basegfx::B3DPoint aScaleCenter3D(aScaleCenter2D.getX(), aScaleCenter2D.getY(), 0.5);
342 basegfx::B3DHomMatrix aInverseViewToEye(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection());
344 aInverseViewToEye.invert();
345 aScaleCenter3D = aInverseViewToEye * aScaleCenter3D;
347 // Get scale factors
348 double fScaleX(xFact);
349 double fScaleY(yFact);
351 // build transform
352 basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation());
353 aInverseOrientation.invert();
354 basegfx::B3DHomMatrix mFullTransform(GetFullTransform());
355 basegfx::B3DHomMatrix mTrans(mFullTransform);
357 mTrans *= aViewInfo3D.getOrientation();
358 mTrans.translate(-aScaleCenter3D.getX(), -aScaleCenter3D.getY(), -aScaleCenter3D.getZ());
359 mTrans.scale(fScaleX, fScaleY, 1.0);
360 mTrans.translate(aScaleCenter3D.getX(), aScaleCenter3D.getY(), aScaleCenter3D.getZ());
361 mTrans *= aInverseOrientation;
362 mFullTransform.invert();
363 mTrans *= mFullTransform;
365 // Apply
366 basegfx::B3DHomMatrix mObjTrans(GetTransform());
367 mObjTrans *= mTrans;
369 E3DModifySceneSnapRectUpdater aUpdater(this);
370 SetTransform(mObjTrans);
375 // Move object in 2D is needed when using cursor keys
377 void E3dObject::NbcMove(const Size& rSize)
379 // Movement in X, Y in the eye coordinate system
380 E3dScene* pScene = GetScene();
382 if(pScene)
384 //Dimensions of the scene in 3D and 2D for comparison
385 Rectangle aRect = pScene->GetSnapRect();
387 basegfx::B3DHomMatrix mInvDispTransform;
388 if(GetParentObj())
390 mInvDispTransform = GetParentObj()->GetFullTransform();
391 mInvDispTransform.invert();
394 // BoundVolume from 3d world to 3d eye
395 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pScene->GetViewContact());
396 const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D());
397 basegfx::B3DRange aEyeVol(pScene->GetBoundVolume());
398 aEyeVol.transform(aViewInfo3D.getOrientation());
400 // build relative movement vector in eye coordinates
401 basegfx::B3DPoint aMove(
402 (double)rSize.Width() * aEyeVol.getWidth() / (double)aRect.GetWidth(),
403 (double)-rSize.Height() * aEyeVol.getHeight() / (double)aRect.GetHeight(),
404 0.0);
405 basegfx::B3DPoint aPos(0.0, 0.0, 0.0);
407 // movement vector to local coordinates of objects' parent
408 basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation());
409 aInverseOrientation.invert();
410 basegfx::B3DHomMatrix aCompleteTrans(mInvDispTransform * aInverseOrientation);
412 aMove = aCompleteTrans * aMove;
413 aPos = aCompleteTrans * aPos;
415 // build transformation and apply
416 basegfx::B3DHomMatrix aTranslate;
417 aTranslate.translate(aMove.getX() - aPos.getX(), aMove.getY() - aPos.getY(), aMove.getZ() - aPos.getZ());
419 E3DModifySceneSnapRectUpdater aUpdater(pScene);
420 SetTransform(aTranslate * GetTransform());
424 // Return the sublist, but only if it contains objects!
426 SdrObjList* E3dObject::GetSubList() const
428 return &(const_cast< E3dObjList& >(maSubList));
431 void E3dObject::RecalcSnapRect()
433 maSnapRect = Rectangle();
435 for(sal_uInt32 a(0); a < maSubList.GetObjCount(); a++)
437 E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a));
439 if(pCandidate)
441 maSnapRect.Union(pCandidate->GetSnapRect());
446 // Inform the parent about insertion of a 3D object, so that the parent is able
447 // treat the particualar objects in a special way (eg Light / Label in E3dScene)
449 void E3dObject::NewObjectInserted(const E3dObject* p3DObj)
451 if(GetParentObj())
452 GetParentObj()->NewObjectInserted(p3DObj);
455 // Inform parent of changes in the structure (eg by transformation), in this
456 // process the object in which the change has occurred is returned.
458 void E3dObject::StructureChanged()
460 if ( GetParentObj() )
462 GetParentObj()->InvalidateBoundVolume();
463 GetParentObj()->StructureChanged();
467 void E3dObject::Insert3DObj(E3dObject* p3DObj)
469 DBG_ASSERT(p3DObj, "Insert3DObj with NULL-pointer!");
470 SdrPage* pPg = pPage;
471 maSubList.InsertObject(p3DObj);
472 pPage = pPg;
473 InvalidateBoundVolume();
474 NewObjectInserted(p3DObj);
475 StructureChanged();
478 void E3dObject::Remove3DObj(E3dObject* p3DObj)
480 DBG_ASSERT(p3DObj, "Remove3DObj with NULL-pointer!");
482 if(p3DObj->GetParentObj() == this)
484 SdrPage* pPg = pPage;
485 maSubList.RemoveObject(p3DObj->GetOrdNum());
486 pPage = pPg;
488 InvalidateBoundVolume();
489 StructureChanged();
493 E3dObject* E3dObject::GetParentObj() const
495 E3dObject* pRetval = NULL;
497 if(GetObjList()
498 && GetObjList()->GetOwnerObj()
499 && GetObjList()->GetOwnerObj()->ISA(E3dObject))
500 pRetval = ((E3dObject*)GetObjList()->GetOwnerObj());
501 return pRetval;
504 // Determine the top-level scene object
506 E3dScene* E3dObject::GetScene() const
508 if(GetParentObj())
509 return GetParentObj()->GetScene();
510 return NULL;
513 // Calculate enclosed volume, including all child objects
515 basegfx::B3DRange E3dObject::RecalcBoundVolume() const
517 basegfx::B3DRange aRetval;
518 const sal_uInt32 nObjCnt(maSubList.GetObjCount());
520 if(nObjCnt)
522 for(sal_uInt32 a(0); a < nObjCnt; a++)
524 const E3dObject* p3DObject = dynamic_cast< const E3dObject* >(maSubList.GetObj(a));
526 if(p3DObject)
528 basegfx::B3DRange aLocalRange(p3DObject->GetBoundVolume());
529 aLocalRange.transform(p3DObject->GetTransform());
530 aRetval.expand(aLocalRange);
534 else
536 // single 3D object
537 const sdr::contact::ViewContactOfE3d* pVCOfE3D = dynamic_cast< const sdr::contact::ViewContactOfE3d* >(&GetViewContact());
539 if(pVCOfE3D)
541 // BoundVolume is without 3D object transformation, use correct sequence
542 const drawinglayer::primitive3d::Primitive3DSequence xLocalSequence(pVCOfE3D->getVIP3DSWithoutObjectTransform());
544 if(xLocalSequence.hasElements())
546 const uno::Sequence< beans::PropertyValue > aEmptyParameters;
547 const drawinglayer::geometry::ViewInformation3D aLocalViewInformation3D(aEmptyParameters);
549 aRetval = drawinglayer::primitive3d::getB3DRangeFromPrimitive3DSequence(
550 xLocalSequence, aLocalViewInformation3D);
555 return aRetval;
558 // Get enclosed volume and possibly recalculate it
560 const basegfx::B3DRange& E3dObject::GetBoundVolume() const
562 if(maLocalBoundVol.isEmpty())
564 const_cast< E3dObject* >(this)->maLocalBoundVol = RecalcBoundVolume();
567 return maLocalBoundVol;
570 void E3dObject::InvalidateBoundVolume()
572 maLocalBoundVol.reset();
575 // Pass on the changes of the BoundVolumes to all child objects
577 void E3dObject::SetBoundVolInvalid()
579 InvalidateBoundVolume();
581 for(sal_uInt32 a(0); a < maSubList.GetObjCount(); a++)
583 E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a));
585 if(pCandidate)
587 pCandidate->SetBoundVolInvalid();
592 // Pass on the changes in transformation to all child objects
594 void E3dObject::SetTransformChanged()
596 InvalidateBoundVolume();
597 mbTfHasChanged = true;
599 for(sal_uInt32 a(0); a < maSubList.GetObjCount(); a++)
601 E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a));
603 if(pCandidate)
605 pCandidate->SetTransformChanged();
610 // Define the hierarchical transformation over all Parents, store in
611 // maFullTransform and return them
613 const basegfx::B3DHomMatrix& E3dObject::GetFullTransform() const
615 if(mbTfHasChanged)
617 basegfx::B3DHomMatrix aNewFullTransformation(maTransformation);
619 if ( GetParentObj() )
621 aNewFullTransformation = GetParentObj()->GetFullTransform() * aNewFullTransformation;
624 const_cast< E3dObject* >(this)->maFullTransform = aNewFullTransformation;
625 const_cast< E3dObject* >(this)->mbTfHasChanged = false;
628 return maFullTransform;
631 const basegfx::B3DHomMatrix& E3dObject::GetTransform() const
633 return maTransformation;
636 void E3dObject::NbcSetTransform(const basegfx::B3DHomMatrix& rMatrix)
638 if(maTransformation != rMatrix)
640 maTransformation = rMatrix;
641 SetTransformChanged();
642 StructureChanged();
646 // Set transformation matrix with repaint broadcast
648 void E3dObject::SetTransform(const basegfx::B3DHomMatrix& rMatrix)
650 if(rMatrix != maTransformation)
652 NbcSetTransform(rMatrix);
653 SetChanged();
654 BroadcastObjectChange();
655 if (pUserCall != NULL) pUserCall->Changed(*this, SDRUSERCALL_RESIZE, Rectangle());
659 basegfx::B3DPolyPolygon E3dObject::CreateWireframe() const
661 const basegfx::B3DRange aBoundVolume(GetBoundVolume());
662 return basegfx::tools::createCubePolyPolygonFromB3DRange(aBoundVolume);
665 // Get the name of the object (singular)
667 void E3dObject::TakeObjNameSingul(XubString& rName) const
669 rName=ImpGetResStr(STR_ObjNameSingulObj3d);
671 String aName( GetName() );
672 if(aName.Len())
674 rName += sal_Unicode(' ');
675 rName += sal_Unicode('\'');
676 rName += aName;
677 rName += sal_Unicode('\'');
681 // Get the name of the object (plural)
683 void E3dObject::TakeObjNamePlural(XubString& rName) const
685 rName=ImpGetResStr(STR_ObjNamePluralObj3d);
688 E3dObject* E3dObject::Clone() const
690 return CloneHelper< E3dObject >();
693 E3dObject& E3dObject::operator=(const E3dObject& rObj)
695 if( this == &rObj )
696 return *this;
697 SdrObject::operator=(rObj);
699 const E3dObject& r3DObj = (const E3dObject&) rObj;
700 if (r3DObj.GetSubList())
702 maSubList.CopyObjects(*r3DObj.GetSubList());
705 // BoundVol can be copied since also the children are copied
706 maLocalBoundVol = r3DObj.maLocalBoundVol;
707 maTransformation = r3DObj.maTransformation;
709 // Because the parent may have changed, definitely redefine the total
710 // transformation next time
711 SetTransformChanged();
713 // Copy selection status
714 mbIsSelected = r3DObj.mbIsSelected;
715 return *this;
718 SdrObjGeoData *E3dObject::NewGeoData() const
720 return new E3DObjGeoData;
723 void E3dObject::SaveGeoData(SdrObjGeoData& rGeo) const
725 SdrAttrObj::SaveGeoData (rGeo);
727 ((E3DObjGeoData &) rGeo).maLocalBoundVol = maLocalBoundVol;
728 ((E3DObjGeoData &) rGeo).maTransformation = maTransformation;
731 void E3dObject::RestGeoData(const SdrObjGeoData& rGeo)
733 maLocalBoundVol = ((E3DObjGeoData &) rGeo).maLocalBoundVol;
734 E3DModifySceneSnapRectUpdater aUpdater(this);
735 NbcSetTransform(((E3DObjGeoData &) rGeo).maTransformation);
736 SdrAttrObj::RestGeoData (rGeo);
739 // 2D-rotation of a 3D-body, normally this is done by the scene itself.
740 // This is however a correct implementation, because everything that has
741 // happened is a rotation around the axis perpendicular to the screen and that
742 // is regardless of how the scene has been rotated up until now.
744 void E3dObject::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
746 // So currently the glue points are defined relative to the scene aOutRect.
747 // Before turning the glue points are defined relative to the page. They
748 // take no part in the rotation of the scene. To ensure this, there is the
749 // SetGlueReallyAbsolute(sal_True);
751 double fWinkelInRad = nWink/100 * F_PI180;
753 basegfx::B3DHomMatrix aRotateZ;
754 aRotateZ.rotate(0.0, 0.0, fWinkelInRad);
755 NbcSetTransform(aRotateZ * GetTransform());
757 SetRectsDirty(); // This forces a recalculation of all BoundRects
758 NbcRotateGluePoints(rRef,nWink,sn,cs); // Rotate the glue points (who still
759 // have coordinates relative to the
760 // original page)
761 SetGlueReallyAbsolute(sal_False); // from now they are again relative to BoundRect (that is defined as aOutRect)
764 /*************************************************************************/
766 //////////////////////////////////////////////////////////////////////////////
768 sdr::properties::BaseProperties* E3dCompoundObject::CreateObjectSpecificProperties()
770 return new sdr::properties::E3dCompoundProperties(*this);
773 //////////////////////////////////////////////////////////////////////////////
775 TYPEINIT1(E3dCompoundObject, E3dObject);
777 E3dCompoundObject::E3dCompoundObject()
778 : E3dObject(),
779 aMaterialAmbientColor(),
780 bCreateNormals(false),
781 bCreateTexture(false)
783 // Set defaults
784 E3dDefaultAttributes aDefault;
785 SetDefaultAttributes(aDefault);
788 E3dCompoundObject::E3dCompoundObject(E3dDefaultAttributes& rDefault)
789 : E3dObject(),
790 aMaterialAmbientColor(),
791 bCreateNormals(false),
792 bCreateTexture(false)
794 // Set defaults
795 SetDefaultAttributes(rDefault);
798 void E3dCompoundObject::SetDefaultAttributes(E3dDefaultAttributes& rDefault)
800 // Set defaults
801 aMaterialAmbientColor = rDefault.GetDefaultAmbientColor();
803 bCreateNormals = rDefault.GetDefaultCreateNormals();
804 bCreateTexture = rDefault.GetDefaultCreateTexture();
807 E3dCompoundObject::~E3dCompoundObject ()
811 basegfx::B2DPolyPolygon E3dCompoundObject::TakeXorPoly() const
813 basegfx::B2DPolyPolygon aRetval;
814 const uno::Sequence< beans::PropertyValue > aEmptyParameters;
815 drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters);
816 E3dScene* pRootScene = fillViewInformation3DForCompoundObject(aViewInfo3D, *this);
818 if(pRootScene)
820 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pRootScene->GetViewContact());
821 const basegfx::B3DPolyPolygon aCubePolyPolygon(CreateWireframe());
822 aRetval = basegfx::tools::createB2DPolyPolygonFromB3DPolyPolygon(aCubePolyPolygon,
823 aViewInfo3D.getObjectToView() * GetTransform());
824 aRetval.transform(rVCScene.getObjectTransformation());
827 return aRetval;
830 sal_uInt32 E3dCompoundObject::GetHdlCount() const
832 // 8 corners + 1 E3dVolumeMarker (= Wireframe representation)
833 return 9L;
836 void E3dCompoundObject::AddToHdlList(SdrHdlList& rHdlList) const
838 const uno::Sequence< beans::PropertyValue > aEmptyParameters;
839 drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters);
840 E3dScene* pRootScene = fillViewInformation3DForCompoundObject(aViewInfo3D, *this);
842 if(pRootScene)
844 const basegfx::B3DRange aBoundVolume(GetBoundVolume());
846 if(!aBoundVolume.isEmpty())
848 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pRootScene->GetViewContact());
850 for(sal_uInt32 a(0); a < 8; a++)
852 basegfx::B3DPoint aPos3D;
854 switch(a)
856 case 0 : aPos3D.setX(aBoundVolume.getMinX()); aPos3D.setY(aBoundVolume.getMinY()); aPos3D.setZ(aBoundVolume.getMinZ()); break;
857 case 1 : aPos3D.setX(aBoundVolume.getMinX()); aPos3D.setY(aBoundVolume.getMinY()); aPos3D.setZ(aBoundVolume.getMaxZ()); break;
858 case 2 : aPos3D.setX(aBoundVolume.getMinX()); aPos3D.setY(aBoundVolume.getMaxY()); aPos3D.setZ(aBoundVolume.getMinZ()); break;
859 case 3 : aPos3D.setX(aBoundVolume.getMinX()); aPos3D.setY(aBoundVolume.getMaxY()); aPos3D.setZ(aBoundVolume.getMaxZ()); break;
860 case 4 : aPos3D.setX(aBoundVolume.getMaxX()); aPos3D.setY(aBoundVolume.getMinY()); aPos3D.setZ(aBoundVolume.getMinZ()); break;
861 case 5 : aPos3D.setX(aBoundVolume.getMaxX()); aPos3D.setY(aBoundVolume.getMinY()); aPos3D.setZ(aBoundVolume.getMaxZ()); break;
862 case 6 : aPos3D.setX(aBoundVolume.getMaxX()); aPos3D.setY(aBoundVolume.getMaxY()); aPos3D.setZ(aBoundVolume.getMinZ()); break;
863 case 7 : aPos3D.setX(aBoundVolume.getMaxX()); aPos3D.setY(aBoundVolume.getMaxY()); aPos3D.setZ(aBoundVolume.getMaxZ()); break;
866 // to 3d view coor
867 aPos3D *= aViewInfo3D.getObjectToView() * GetTransform();
869 // create 2d relative scene
870 basegfx::B2DPoint aPos2D(aPos3D.getX(), aPos3D.getY());
872 // to 2d world coor
873 aPos2D *= rVCScene.getObjectTransformation();
875 rHdlList.AddHdl(new SdrHdl(Point(basegfx::fround(aPos2D.getX()), basegfx::fround(aPos2D.getY())), HDL_BWGT));
880 const basegfx::B2DPolyPolygon aPolyPolygon(TakeXorPoly());
882 if(aPolyPolygon.count())
884 E3dVolumeMarker* pVolMarker = new E3dVolumeMarker(aPolyPolygon);
885 rHdlList.AddHdl(pVolMarker);
889 sal_uInt16 E3dCompoundObject::GetObjIdentifier() const
891 return E3D_COMPOUNDOBJ_ID;
894 void E3dCompoundObject::RecalcSnapRect()
896 const uno::Sequence< beans::PropertyValue > aEmptyParameters;
897 drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters);
898 E3dScene* pRootScene = fillViewInformation3DForCompoundObject(aViewInfo3D, *this);
899 maSnapRect = Rectangle();
901 if(pRootScene)
903 // get VC of 3D candidate
904 const sdr::contact::ViewContactOfE3d* pVCOfE3D = dynamic_cast< const sdr::contact::ViewContactOfE3d* >(&GetViewContact());
906 if(pVCOfE3D)
908 // get 3D primitive sequence
909 const drawinglayer::primitive3d::Primitive3DSequence xLocalSequence(pVCOfE3D->getViewIndependentPrimitive3DSequence());
911 if(xLocalSequence.hasElements())
913 // get BoundVolume
914 basegfx::B3DRange aBoundVolume(drawinglayer::primitive3d::getB3DRangeFromPrimitive3DSequence(
915 xLocalSequence, aViewInfo3D));
917 // transform bound volume to relative scene coordinates
918 aBoundVolume.transform(aViewInfo3D.getObjectToView());
920 // build 2d relative scene range
921 basegfx::B2DRange aSnapRange(
922 aBoundVolume.getMinX(), aBoundVolume.getMinY(),
923 aBoundVolume.getMaxX(), aBoundVolume.getMaxY());
925 // transform to 2D world coordiantes
926 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pRootScene->GetViewContact());
927 aSnapRange.transform(rVCScene.getObjectTransformation());
929 // snap to integer
930 maSnapRect = Rectangle(
931 sal_Int32(floor(aSnapRange.getMinX())), sal_Int32(floor(aSnapRange.getMinY())),
932 sal_Int32(ceil(aSnapRange.getMaxX())), sal_Int32(ceil(aSnapRange.getMaxY())));
938 E3dCompoundObject* E3dCompoundObject::Clone() const
940 return CloneHelper< E3dCompoundObject >();
943 // convert given basegfx::B3DPolyPolygon to screen coor
945 basegfx::B2DPolyPolygon E3dCompoundObject::TransformToScreenCoor(const basegfx::B3DPolyPolygon& rCandidate)
947 const uno::Sequence< beans::PropertyValue > aEmptyParameters;
948 drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters);
949 E3dScene* pRootScene = fillViewInformation3DForCompoundObject(aViewInfo3D, *this);
950 basegfx::B2DPolyPolygon aRetval;
952 if(pRootScene)
954 aRetval = basegfx::tools::createB2DPolyPolygonFromB3DPolyPolygon(rCandidate,
955 aViewInfo3D.getObjectToView() * GetTransform());
956 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pRootScene->GetViewContact());
957 aRetval.transform(rVCScene.getObjectTransformation());
960 return aRetval;
963 bool E3dCompoundObject::IsAOrdNumRemapCandidate(E3dScene*& prScene) const
965 if(GetObjList()
966 && GetObjList()->GetOwnerObj()
967 && GetObjList()->GetOwnerObj()->ISA(E3dScene))
969 prScene = (E3dScene*)GetObjList()->GetOwnerObj();
970 return true;
973 return false;
976 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */