Files
libreoffice/svx/source/engine3d/obj3d.cxx

981 lines
29 KiB
C++
Raw Normal View History

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
re-base on ALv2 code. Includes: Patch contributed by Christian Lippka impress212: #i113063# patch: dubios self assign in svx/source/dialog/framelink.cxx http://svn.apache.org/viewvc?view=revision&revision=1167619 Patches contributed by Mathias Bauer gnumake4 work variously http://svn.apache.org/viewvc?view=revision&revision=1394707 http://svn.apache.org/viewvc?view=revision&revision=1394326 cws mba34issues01: #i117712#: fix several resource errors introduced by IAccessible2 implementation http://svn.apache.org/viewvc?view=revision&revision=1172343 cws mba34issues01: #i117719#: use correct resource ID http://svn.apache.org/viewvc?view=revision&revision=1172351 Patch contributed by Andre Fischer Do not add targets for junit tests when junit is disabled. http://svn.apache.org/viewvc?view=revision&revision=1241508 Patches contributed by Armin Le-Grand #118804# corrected GraphicExporter behaviour on shortcut when pixel graphic is requested http://svn.apache.org/viewvc?view=revision&revision=1240195 fix for #118525#: Using primitives for chart sub-geometry visualisation http://svn.apache.org/viewvc?view=revision&revision=1226879 #118485# - Styles for OLEs are not saved. http://svn.apache.org/viewvc?view=revision&revision=1182166 #118524: apply patch, followup fixes to 118485 http://svn.apache.org/viewvc?view=revision&revision=1186077 13f79535-47bb-0310-9956-ffa450edef68 Patch contributed by Regina Henschel linecap: Reintegrating finished LineCap feature http://svn.apache.org/viewvc?view=revision&revision=1232507 Patch contributed by Wang Lei (leiw) #i118760# split the first table cell vertically, then undo&redo, the Presentation app will crash http://svn.apache.org/viewvc?view=revision&revision=1301361 cleanup globlmn hacks, undo dependent fixmes.
2012-11-21 22:06:52 +00:00
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
2000-09-18 16:07:07 +00:00
#include <o3tl/numeric.hxx>
#include "svx/svdstr.hrc"
#include "svdglob.hxx"
#include <svx/svdview.hxx>
#include <svx/svdattr.hxx>
#include <svx/svdpage.hxx>
#include <svx/svdmodel.hxx>
#include "svx/svditer.hxx"
#include "svx/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/xfillit.hxx>
#include <svx/xlnwtit.hxx>
2000-09-18 16:07:07 +00:00
#include <vcl/virdev.hxx>
#include <tools/poly.hxx>
2009-12-15 21:55:40 +01:00
#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>
2000-09-18 16:07:07 +00:00
#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 <sdr/properties/e3dproperties.hxx>
#include <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>
2008-10-17 08:40:10 +00:00
#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 <svx/e3dsceneupdater.hxx>
2008-10-17 08:40:10 +00:00
using namespace com::sun::star;
2011-04-07 15:47:21 +03:00
// List for 3D-Objects
2000-09-18 16:07:07 +00:00
TYPEINIT1(E3dObjList, SdrObjList);
E3dObjList::E3dObjList(SdrModel* pNewModel, SdrPage* pNewPage, E3dObjList* pNewUpList)
: SdrObjList(pNewModel, pNewPage, pNewUpList)
{
}
E3dObjList::E3dObjList(const E3dObjList&)
: SdrObjList()
2000-09-18 16:07:07 +00:00
{
}
E3dObjList* E3dObjList::Clone() const
{
E3dObjList* const pObjList = new E3dObjList(*this);
pObjList->lateInit(*this);
return pObjList;
}
2000-09-18 16:07:07 +00:00
E3dObjList::~E3dObjList()
{
}
void E3dObjList::NbcInsertObject(SdrObject* pObj, size_t nPos, const SdrInsertReason* pReason)
2000-09-18 16:07:07 +00:00
{
2011-04-07 15:47:21 +03:00
// Get owner
DBG_ASSERT(GetOwnerObj()->ISA(E3dObject), "Insert 3D object in parent != 3DObject");
2000-09-18 16:07:07 +00:00
2011-04-07 15:47:21 +03:00
// Is it even a 3D object?
2000-09-18 16:07:07 +00:00
if(pObj && pObj->ISA(E3dObject))
{
2011-04-07 15:47:21 +03:00
// Normal 3D object, insert means
2000-09-18 16:07:07 +00:00
// call parent
SdrObjList::NbcInsertObject(pObj, nPos, pReason);
}
else
{
2011-04-07 15:47:21 +03:00
// No 3D object, inserted a page in place in a scene ...
2000-09-18 16:07:07 +00:00
GetOwnerObj()->GetPage()->InsertObject(pObj, nPos);
}
}
void E3dObjList::InsertObject(SdrObject* pObj, size_t nPos, const SdrInsertReason* pReason)
2008-10-17 08:40:10 +00:00
{
2011-04-07 15:47:21 +03:00
OSL_ENSURE(GetOwnerObj()->ISA(E3dObject), "Insert 3D object in non-3D Parent");
2008-10-17 08:40:10 +00:00
// call parent
SdrObjList::InsertObject(pObj, nPos, pReason);
E3dScene* pScene = static_cast<E3dObject*>(GetOwnerObj())->GetScene();
2008-10-17 08:40:10 +00:00
if(pScene)
{
pScene->Cleanup3DDepthMapper();
}
}
SdrObject* E3dObjList::NbcRemoveObject(size_t nObjNum)
2000-09-18 16:07:07 +00:00
{
2011-04-07 15:47:21 +03:00
DBG_ASSERT(GetOwnerObj()->ISA(E3dObject), "Remove 3D object from Parent != 3DObject");
2000-09-18 16:07:07 +00:00
// call parent
SdrObject* pRetval = SdrObjList::NbcRemoveObject(nObjNum);
E3dScene* pScene = static_cast<E3dObject*>(GetOwnerObj())->GetScene();
2008-10-17 08:40:10 +00:00
if(pScene)
{
pScene->Cleanup3DDepthMapper();
}
2000-09-18 16:07:07 +00:00
return pRetval;
}
SdrObject* E3dObjList::RemoveObject(size_t nObjNum)
2000-09-18 16:07:07 +00:00
{
2011-04-07 15:47:21 +03:00
OSL_ENSURE(GetOwnerObj()->ISA(E3dObject), "3D object is removed from non-3D Parent");
2000-09-18 16:07:07 +00:00
// call parent
SdrObject* pRetval = SdrObjList::RemoveObject(nObjNum);
E3dScene* pScene = static_cast<E3dObject*>(GetOwnerObj())->GetScene();
2008-10-17 08:40:10 +00:00
if(pScene)
{
pScene->Cleanup3DDepthMapper();
}
2000-09-18 16:07:07 +00:00
return pRetval;
}
sdr::properties::BaseProperties* E3dObject::CreateObjectSpecificProperties()
{
return new sdr::properties::E3dProperties(*this);
}
2000-09-18 16:07:07 +00:00
TYPEINIT1(E3dObject, SdrAttrObj);
2008-10-17 08:40:10 +00:00
E3dObject::E3dObject()
: maSubList(),
maLocalBoundVol(),
maTransformation(),
maFullTransform(),
mbTfHasChanged(true),
mbIsSelected(false)
2000-09-18 16:07:07 +00:00
{
2008-10-17 08:40:10 +00:00
bIs3DObj = true;
maSubList.SetOwnerObj(this);
maSubList.SetListKind(SDROBJLIST_GROUPOBJ);
bClosedObj = true;
2000-09-18 16:07:07 +00:00
}
E3dObject::~E3dObject()
{
}
2008-10-17 08:40:10 +00:00
void E3dObject::SetSelected(bool bNew)
2000-09-18 16:07:07 +00:00
{
2008-10-17 08:40:10 +00:00
if((bool)mbIsSelected != bNew)
{
mbIsSelected = bNew;
}
2000-09-18 16:07:07 +00:00
for(size_t a = 0; a < maSubList.GetObjCount(); ++a)
2000-09-18 16:07:07 +00:00
{
2008-10-17 08:40:10 +00:00
E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a));
if(pCandidate)
{
pCandidate->SetSelected(bNew);
}
2000-09-18 16:07:07 +00:00
}
}
2011-04-07 15:47:21 +03:00
// Break, default implementations
2000-09-18 16:07:07 +00:00
bool E3dObject::IsBreakObjPossible()
2000-09-18 16:07:07 +00:00
{
return false;
2000-09-18 16:07:07 +00:00
}
SdrAttrObj* E3dObject::GetBreakObj()
{
return 0L;
}
2011-04-07 15:47:21 +03:00
// SetRectsDirty must be done through the local SdrSubList
2000-09-18 16:07:07 +00:00
void E3dObject::SetRectsDirty(bool bNotMyself)
2000-09-18 16:07:07 +00:00
{
// call parent
SdrAttrObj::SetRectsDirty(bNotMyself);
for(size_t a = 0; a < maSubList.GetObjCount(); ++a)
2000-09-18 16:07:07 +00:00
{
2008-10-17 08:40:10 +00:00
E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a));
if(pCandidate)
2000-09-18 16:07:07 +00:00
{
2008-10-17 08:40:10 +00:00
pCandidate->SetRectsDirty(bNotMyself);
2000-09-18 16:07:07 +00:00
}
}
}
sal_uInt32 E3dObject::GetObjInventor() const
2000-09-18 16:07:07 +00:00
{
return E3dInventor;
}
sal_uInt16 E3dObject::GetObjIdentifier() const
2000-09-18 16:07:07 +00:00
{
return E3D_OBJECT_ID;
}
2011-04-07 15:47:21 +03:00
// Determine the capabilities of the object
2000-09-18 16:07:07 +00:00
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;
2000-09-18 16:07:07 +00:00
// no transparence for 3d objects
rInfo.bTransparenceAllowed = false;
2000-09-18 16:07:07 +00:00
// gradient depends on fillstyle
// BM *** check if SetItem is NULL ***
drawing::FillStyle eFillStyle = static_cast<const XFillStyleItem&>(GetMergedItem(XATTR_FILLSTYLE)).GetValue();
rInfo.bGradientAllowed = (eFillStyle == drawing::FillStyle_GRADIENT);
2000-09-18 16:07:07 +00:00
2011-04-07 15:47:21 +03:00
// Convert 3D objects in a group of polygons:
// At first not only possible, because the creation of a group of
// 2D polygons would be required which need to be sorted by depth,
// ie at intersections be cut relative to each other. Also the texture
// coorinates were an unsolved problem.
rInfo.bCanConvToPoly = false;
rInfo.bCanConvToContour = false;
rInfo.bCanConvToPathLineToArea = false;
rInfo.bCanConvToPolyLineToArea = false;
2000-09-18 16:07:07 +00:00
}
void E3dObject::NbcSetLayer(SdrLayerID nLayer)
{
SdrAttrObj::NbcSetLayer(nLayer);
for(size_t a = 0; a < maSubList.GetObjCount(); ++a)
2008-10-17 08:40:10 +00:00
{
E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a));
if(pCandidate)
{
pCandidate->NbcSetLayer(nLayer);
}
}
2000-09-18 16:07:07 +00:00
}
2011-04-07 15:47:21 +03:00
// Set ObjList also on SubList
2000-09-18 16:07:07 +00:00
void E3dObject::SetObjList(SdrObjList* pNewObjList)
{
SdrObject::SetObjList(pNewObjList);
2008-10-17 08:40:10 +00:00
maSubList.SetUpList(pNewObjList);
2000-09-18 16:07:07 +00:00
}
void E3dObject::SetPage(SdrPage* pNewPage)
{
SdrAttrObj::SetPage(pNewPage);
2008-10-17 08:40:10 +00:00
maSubList.SetPage(pNewPage);
2000-09-18 16:07:07 +00:00
}
void E3dObject::SetModel(SdrModel* pNewModel)
{
SdrAttrObj::SetModel(pNewModel);
2008-10-17 08:40:10 +00:00
maSubList.SetModel(pNewModel);
2000-09-18 16:07:07 +00:00
}
2011-04-07 15:47:21 +03:00
// 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)
2000-09-18 16:07:07 +00:00
{
2011-04-07 15:47:21 +03:00
// Movement in X, Y in the eye coordinate system
2000-09-18 16:07:07 +00:00
E3dScene* pScene = GetScene();
if(pScene)
{
2008-10-17 08:40:10 +00:00
// 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;
2000-09-18 16:07:07 +00:00
2011-04-07 15:47:21 +03:00
// Get scale factors
double fScaleX(xFact);
double fScaleY(yFact);
2000-09-18 16:07:07 +00:00
// build transform
2008-10-17 08:40:10 +00:00
basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation());
aInverseOrientation.invert();
basegfx::B3DHomMatrix mFullTransform(GetFullTransform());
basegfx::B3DHomMatrix mTrans(mFullTransform);
2000-09-18 16:07:07 +00:00
2008-10-17 08:40:10 +00:00
mTrans *= aViewInfo3D.getOrientation();
mTrans.translate(-aScaleCenter3D.getX(), -aScaleCenter3D.getY(), -aScaleCenter3D.getZ());
mTrans.scale(fScaleX, fScaleY, 1.0);
2008-10-17 08:40:10 +00:00
mTrans.translate(aScaleCenter3D.getX(), aScaleCenter3D.getY(), aScaleCenter3D.getZ());
mTrans *= aInverseOrientation;
mFullTransform.invert();
2000-09-18 16:07:07 +00:00
mTrans *= mFullTransform;
2011-04-07 15:47:21 +03:00
// Apply
basegfx::B3DHomMatrix mObjTrans(GetTransform());
2000-09-18 16:07:07 +00:00
mObjTrans *= mTrans;
E3DModifySceneSnapRectUpdater aUpdater(this);
2008-10-17 08:40:10 +00:00
SetTransform(mObjTrans);
2000-09-18 16:07:07 +00:00
}
}
2011-04-07 15:47:21 +03:00
// Move object in 2D is needed when using cursor keys
2000-09-18 16:07:07 +00:00
void E3dObject::NbcMove(const Size& rSize)
{
2011-04-07 15:47:21 +03:00
// Movement in X, Y in the eye coordinate system
2000-09-18 16:07:07 +00:00
E3dScene* pScene = GetScene();
if(pScene)
{
2011-04-07 15:47:21 +03:00
//Dimensions of the scene in 3D and 2D for comparison
2000-09-18 16:07:07 +00:00
Rectangle aRect = pScene->GetSnapRect();
basegfx::B3DHomMatrix mInvDispTransform;
2000-09-18 16:07:07 +00:00
if(GetParentObj())
{
mInvDispTransform = GetParentObj()->GetFullTransform();
mInvDispTransform.invert();
2000-09-18 16:07:07 +00:00
}
2008-10-17 08:40:10 +00:00
// 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());
2000-09-18 16:07:07 +00:00
if ((aRect.GetWidth() == 0) || (aRect.GetHeight() == 0))
throw o3tl::divide_by_zero();
2008-10-17 08:40:10 +00:00
// 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(),
2000-09-18 16:07:07 +00:00
0.0);
2008-10-17 08:40:10 +00:00
basegfx::B3DPoint aPos(0.0, 0.0, 0.0);
2000-09-18 16:07:07 +00:00
2011-04-07 15:47:21 +03:00
// movement vector to local coordinates of objects' parent
2008-10-17 08:40:10 +00:00
basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation());
aInverseOrientation.invert();
basegfx::B3DHomMatrix aCompleteTrans(mInvDispTransform * aInverseOrientation);
2000-09-18 16:07:07 +00:00
2008-10-17 08:40:10 +00:00
aMove = aCompleteTrans * aMove;
aPos = aCompleteTrans * aPos;
2000-09-18 16:07:07 +00:00
2008-10-17 08:40:10 +00:00
// build transformation and apply
basegfx::B3DHomMatrix aTranslate;
aTranslate.translate(aMove.getX() - aPos.getX(), aMove.getY() - aPos.getY(), aMove.getZ() - aPos.getZ());
E3DModifySceneSnapRectUpdater aUpdater(pScene);
2008-10-17 08:40:10 +00:00
SetTransform(aTranslate * GetTransform());
2000-09-18 16:07:07 +00:00
}
}
2011-04-07 15:47:21 +03:00
// Return the sublist, but only if it contains objects!
2000-09-18 16:07:07 +00:00
SdrObjList* E3dObject::GetSubList() const
{
2008-10-17 08:40:10 +00:00
return &(const_cast< E3dObjList& >(maSubList));
2000-09-18 16:07:07 +00:00
}
void E3dObject::RecalcSnapRect()
{
maSnapRect = Rectangle();
2008-10-17 08:40:10 +00:00
for(size_t a = 0; a < maSubList.GetObjCount(); ++a)
2000-09-18 16:07:07 +00:00
{
2008-10-17 08:40:10 +00:00
E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a));
if(pCandidate)
2000-09-18 16:07:07 +00:00
{
2008-10-17 08:40:10 +00:00
maSnapRect.Union(pCandidate->GetSnapRect());
2000-09-18 16:07:07 +00:00
}
}
}
2011-04-07 15:47:21 +03:00
// Inform the parent about insertion of a 3D object, so that the parent is able
// treat the particualar objects in a special way (eg Light / Label in E3dScene)
2000-09-18 16:07:07 +00:00
void E3dObject::NewObjectInserted(const E3dObject* p3DObj)
{
if(GetParentObj())
GetParentObj()->NewObjectInserted(p3DObj);
}
2011-04-07 15:47:21 +03:00
// Inform parent of changes in the structure (eg by transformation), in this
// process the object in which the change has occurred is returned.
2000-09-18 16:07:07 +00:00
2008-10-17 08:40:10 +00:00
void E3dObject::StructureChanged()
2000-09-18 16:07:07 +00:00
{
if ( GetParentObj() )
{
2008-10-17 08:40:10 +00:00
GetParentObj()->InvalidateBoundVolume();
GetParentObj()->StructureChanged();
2000-09-18 16:07:07 +00:00
}
}
void E3dObject::Insert3DObj(E3dObject* p3DObj)
{
2011-04-07 15:47:21 +03:00
DBG_ASSERT(p3DObj, "Insert3DObj with NULL-pointer!");
2000-09-18 16:07:07 +00:00
SdrPage* pPg = pPage;
2008-10-17 08:40:10 +00:00
maSubList.InsertObject(p3DObj);
2000-09-18 16:07:07 +00:00
pPage = pPg;
2008-10-17 08:40:10 +00:00
InvalidateBoundVolume();
2000-09-18 16:07:07 +00:00
NewObjectInserted(p3DObj);
2008-10-17 08:40:10 +00:00
StructureChanged();
2000-09-18 16:07:07 +00:00
}
void E3dObject::Remove3DObj(E3dObject* p3DObj)
{
2011-04-07 15:47:21 +03:00
DBG_ASSERT(p3DObj, "Remove3DObj with NULL-pointer!");
2000-09-18 16:07:07 +00:00
if(p3DObj->GetParentObj() == this)
{
SdrPage* pPg = pPage;
2008-10-17 08:40:10 +00:00
maSubList.RemoveObject(p3DObj->GetOrdNum());
2000-09-18 16:07:07 +00:00
pPage = pPg;
2008-10-17 08:40:10 +00:00
InvalidateBoundVolume();
StructureChanged();
2000-09-18 16:07:07 +00:00
}
}
E3dObject* E3dObject::GetParentObj() const
{
E3dObject* pRetval = NULL;
if(GetObjList()
&& GetObjList()->GetOwnerObj()
&& GetObjList()->GetOwnerObj()->ISA(E3dObject))
pRetval = static_cast<E3dObject*>(GetObjList()->GetOwnerObj());
2000-09-18 16:07:07 +00:00
return pRetval;
}
2011-04-07 15:47:21 +03:00
// Determine the top-level scene object
2000-09-18 16:07:07 +00:00
E3dScene* E3dObject::GetScene() const
{
if(GetParentObj())
return GetParentObj()->GetScene();
return NULL;
}
2011-04-07 15:47:21 +03:00
// Calculate enclosed volume, including all child objects
2000-09-18 16:07:07 +00:00
2008-10-17 08:40:10 +00:00
basegfx::B3DRange E3dObject::RecalcBoundVolume() const
2000-09-18 16:07:07 +00:00
{
2008-10-17 08:40:10 +00:00
basegfx::B3DRange aRetval;
const size_t nObjCnt(maSubList.GetObjCount());
2000-09-18 16:07:07 +00:00
if(nObjCnt)
{
for(size_t a = 0; a < nObjCnt; ++a)
2000-09-18 16:07:07 +00:00
{
2008-10-17 08:40:10 +00:00
const E3dObject* p3DObject = dynamic_cast< const E3dObject* >(maSubList.GetObj(a));
2000-09-18 16:07:07 +00:00
2008-10-17 08:40:10 +00:00
if(p3DObject)
{
basegfx::B3DRange aLocalRange(p3DObject->GetBoundVolume());
aLocalRange.transform(p3DObject->GetTransform());
aRetval.expand(aLocalRange);
}
}
2000-09-18 16:07:07 +00:00
}
else
{
2008-10-17 08:40:10 +00:00
// single 3D object
const sdr::contact::ViewContactOfE3d* pVCOfE3D = dynamic_cast< const sdr::contact::ViewContactOfE3d* >(&GetViewContact());
2008-10-17 08:40:10 +00:00
if(pVCOfE3D)
{
2008-10-17 08:40:10 +00:00
// BoundVolume is without 3D object transformation, use correct sequence
const drawinglayer::primitive3d::Primitive3DSequence xLocalSequence(pVCOfE3D->getVIP3DSWithoutObjectTransform());
2008-10-17 08:40:10 +00:00
if(xLocalSequence.hasElements())
{
2008-10-17 08:40:10 +00:00
const uno::Sequence< beans::PropertyValue > aEmptyParameters;
const drawinglayer::geometry::ViewInformation3D aLocalViewInformation3D(aEmptyParameters);
aRetval = drawinglayer::primitive3d::getB3DRangeFromPrimitive3DSequence(
xLocalSequence, aLocalViewInformation3D);
}
}
2000-09-18 16:07:07 +00:00
}
2008-10-17 08:40:10 +00:00
return aRetval;
2000-09-18 16:07:07 +00:00
}
2011-04-07 15:47:21 +03:00
// Get enclosed volume and possibly recalculate it
2000-09-18 16:07:07 +00:00
2008-10-17 08:40:10 +00:00
const basegfx::B3DRange& E3dObject::GetBoundVolume() const
2000-09-18 16:07:07 +00:00
{
2008-10-17 08:40:10 +00:00
if(maLocalBoundVol.isEmpty())
{
2008-10-17 08:40:10 +00:00
const_cast< E3dObject* >(this)->maLocalBoundVol = RecalcBoundVolume();
}
2000-09-18 16:07:07 +00:00
2008-10-17 08:40:10 +00:00
return maLocalBoundVol;
2000-09-18 16:07:07 +00:00
}
2008-10-17 08:40:10 +00:00
void E3dObject::InvalidateBoundVolume()
2000-09-18 16:07:07 +00:00
{
2008-10-17 08:40:10 +00:00
maLocalBoundVol.reset();
2000-09-18 16:07:07 +00:00
}
2011-04-07 15:47:21 +03:00
// Pass on the changes of the BoundVolumes to all child objects
2000-09-18 16:07:07 +00:00
void E3dObject::SetBoundVolInvalid()
{
2008-10-17 08:40:10 +00:00
InvalidateBoundVolume();
2000-09-18 16:07:07 +00:00
for(size_t a = 0; a < maSubList.GetObjCount(); ++a)
2000-09-18 16:07:07 +00:00
{
2008-10-17 08:40:10 +00:00
E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a));
2000-09-18 16:07:07 +00:00
2008-10-17 08:40:10 +00:00
if(pCandidate)
{
pCandidate->SetBoundVolInvalid();
}
2000-09-18 16:07:07 +00:00
}
}
2011-04-07 15:47:21 +03:00
// Pass on the changes in transformation to all child objects
2000-09-18 16:07:07 +00:00
void E3dObject::SetTransformChanged()
{
2008-10-17 08:40:10 +00:00
InvalidateBoundVolume();
mbTfHasChanged = true;
2000-09-18 16:07:07 +00:00
for(size_t a = 0; a < maSubList.GetObjCount(); ++a)
2000-09-18 16:07:07 +00:00
{
2008-10-17 08:40:10 +00:00
E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a));
2000-09-18 16:07:07 +00:00
2008-10-17 08:40:10 +00:00
if(pCandidate)
{
pCandidate->SetTransformChanged();
}
2000-09-18 16:07:07 +00:00
}
}
2011-04-07 15:47:21 +03:00
// Define the hierarchical transformation over all Parents, store in
// maFullTransform and return them
2000-09-18 16:07:07 +00:00
const basegfx::B3DHomMatrix& E3dObject::GetFullTransform() const
2000-09-18 16:07:07 +00:00
{
2008-10-17 08:40:10 +00:00
if(mbTfHasChanged)
2000-09-18 16:07:07 +00:00
{
2008-10-17 08:40:10 +00:00
basegfx::B3DHomMatrix aNewFullTransformation(maTransformation);
2000-09-18 16:07:07 +00:00
if ( GetParentObj() )
2008-10-17 08:40:10 +00:00
{
aNewFullTransformation = GetParentObj()->GetFullTransform() * aNewFullTransformation;
}
const_cast< E3dObject* >(this)->maFullTransform = aNewFullTransformation;
const_cast< E3dObject* >(this)->mbTfHasChanged = false;
2000-09-18 16:07:07 +00:00
}
2008-10-17 08:40:10 +00:00
return maFullTransform;
2000-09-18 16:07:07 +00:00
}
void E3dObject::NbcSetTransform(const basegfx::B3DHomMatrix& rMatrix)
2000-09-18 16:07:07 +00:00
{
2008-10-17 08:40:10 +00:00
if(maTransformation != rMatrix)
{
maTransformation = rMatrix;
SetTransformChanged();
StructureChanged();
}
2000-09-18 16:07:07 +00:00
}
2011-04-07 15:47:21 +03:00
// Set transformation matrix with repaint broadcast
2000-09-18 16:07:07 +00:00
void E3dObject::SetTransform(const basegfx::B3DHomMatrix& rMatrix)
2000-09-18 16:07:07 +00:00
{
2008-10-17 08:40:10 +00:00
if(rMatrix != maTransformation)
{
NbcSetTransform(rMatrix);
SetChanged();
BroadcastObjectChange();
if (pUserCall != NULL) pUserCall->Changed(*this, SDRUSERCALL_RESIZE, Rectangle());
}
2000-09-18 16:07:07 +00:00
}
2008-10-17 08:40:10 +00:00
basegfx::B3DPolyPolygon E3dObject::CreateWireframe() const
2000-09-18 16:07:07 +00:00
{
2008-10-17 08:40:10 +00:00
const basegfx::B3DRange aBoundVolume(GetBoundVolume());
return basegfx::tools::createCubePolyPolygonFromB3DRange(aBoundVolume);
2000-09-18 16:07:07 +00:00
}
2011-04-07 15:47:21 +03:00
// Get the name of the object (singular)
2000-09-18 16:07:07 +00:00
OUString E3dObject::TakeObjNameSingul() const
2000-09-18 16:07:07 +00:00
{
OUStringBuffer sName(ImpGetResStr(STR_ObjNameSingulObj3d));
2008-10-17 08:40:10 +00:00
OUString aName(GetName());
if (!aName.isEmpty())
2008-10-17 08:40:10 +00:00
{
sName.append(' ');
sName.append('\'');
sName.append(aName);
sName.append('\'');
2008-10-17 08:40:10 +00:00
}
return sName.makeStringAndClear();
2000-09-18 16:07:07 +00:00
}
2008-10-17 08:40:10 +00:00
2011-04-07 15:47:21 +03:00
// Get the name of the object (plural)
2000-09-18 16:07:07 +00:00
OUString E3dObject::TakeObjNamePlural() const
2000-09-18 16:07:07 +00:00
{
return ImpGetResStr(STR_ObjNamePluralObj3d);
2000-09-18 16:07:07 +00:00
}
E3dObject* E3dObject::Clone() const
{
return CloneHelper< E3dObject >();
}
E3dObject& E3dObject::operator=(const E3dObject& rObj)
2000-09-18 16:07:07 +00:00
{
if( this == &rObj )
return *this;
2008-10-17 08:40:10 +00:00
SdrObject::operator=(rObj);
2000-09-18 16:07:07 +00:00
2008-10-17 08:40:10 +00:00
const E3dObject& r3DObj = (const E3dObject&) rObj;
if (r3DObj.GetSubList())
{
maSubList.CopyObjects(*r3DObj.GetSubList());
}
2000-09-18 16:07:07 +00:00
2011-04-07 15:47:21 +03:00
// BoundVol can be copied since also the children are copied
2008-10-17 08:40:10 +00:00
maLocalBoundVol = r3DObj.maLocalBoundVol;
maTransformation = r3DObj.maTransformation;
2000-09-18 16:07:07 +00:00
2011-04-07 15:47:21 +03:00
// Because the parent may have changed, definitely redefine the total
// transformation next time
2000-09-18 16:07:07 +00:00
SetTransformChanged();
2011-04-07 15:47:21 +03:00
// Copy selection status
2008-10-17 08:40:10 +00:00
mbIsSelected = r3DObj.mbIsSelected;
return *this;
2000-09-18 16:07:07 +00:00
}
2008-10-17 08:40:10 +00:00
SdrObjGeoData *E3dObject::NewGeoData() const
2000-09-18 16:07:07 +00:00
{
2008-10-17 08:40:10 +00:00
return new E3DObjGeoData;
2000-09-18 16:07:07 +00:00
}
2008-10-17 08:40:10 +00:00
void E3dObject::SaveGeoData(SdrObjGeoData& rGeo) const
2000-09-18 16:07:07 +00:00
{
2008-10-17 08:40:10 +00:00
SdrAttrObj::SaveGeoData (rGeo);
2000-09-18 16:07:07 +00:00
static_cast<E3DObjGeoData &>(rGeo).maLocalBoundVol = maLocalBoundVol;
static_cast<E3DObjGeoData &>(rGeo).maTransformation = maTransformation;
2000-09-18 16:07:07 +00:00
}
2008-10-17 08:40:10 +00:00
void E3dObject::RestGeoData(const SdrObjGeoData& rGeo)
2000-09-18 16:07:07 +00:00
{
maLocalBoundVol = static_cast<const E3DObjGeoData &>(rGeo).maLocalBoundVol;
E3DModifySceneSnapRectUpdater aUpdater(this);
NbcSetTransform(static_cast<const E3DObjGeoData &>(rGeo).maTransformation);
2008-10-17 08:40:10 +00:00
SdrAttrObj::RestGeoData (rGeo);
2000-09-18 16:07:07 +00:00
}
2011-04-07 15:47:21 +03:00
// 2D-rotation of a 3D-body, normally this is done by the scene itself.
// This is however a correct implementation, because everything that has
// happened is a rotation around the axis perpendicular to the screen and that
// is regardless of how the scene has been rotated up until now.
2000-09-18 16:07:07 +00:00
void E3dObject::NbcRotate(const Point& rRef, long nAngle, double sn, double cs)
2000-09-18 16:07:07 +00:00
{
2011-04-07 15:47:21 +03:00
// So currently the glue points are defined relative to the scene aOutRect.
// Before turning the glue points are defined relative to the page. They
// take no part in the rotation of the scene. To ensure this, there is the
// SetGlueReallyAbsolute(sal_True);
2000-09-18 16:07:07 +00:00
double fWinkelInRad = nAngle/100.0 * F_PI180;
2000-09-18 16:07:07 +00:00
2008-10-17 08:40:10 +00:00
basegfx::B3DHomMatrix aRotateZ;
aRotateZ.rotate(0.0, 0.0, fWinkelInRad);
NbcSetTransform(aRotateZ * GetTransform());
2011-04-07 15:47:21 +03:00
SetRectsDirty(); // This forces a recalculation of all BoundRects
NbcRotateGluePoints(rRef,nAngle,sn,cs); // Rotate the glue points (who still
2011-04-07 15:47:21 +03:00
// have coordinates relative to the
// original page)
SetGlueReallyAbsolute(false); // from now they are again relative to BoundRect (that is defined as aOutRect)
2000-09-18 16:07:07 +00:00
}
2008-10-17 08:40:10 +00:00
sdr::properties::BaseProperties* E3dCompoundObject::CreateObjectSpecificProperties()
2000-09-18 16:07:07 +00:00
{
2008-10-17 08:40:10 +00:00
return new sdr::properties::E3dCompoundProperties(*this);
2000-09-18 16:07:07 +00:00
}
2008-10-17 08:40:10 +00:00
TYPEINIT1(E3dCompoundObject, E3dObject);
E3dCompoundObject::E3dCompoundObject()
: E3dObject(),
aMaterialAmbientColor(),
bCreateNormals(false),
bCreateTexture(false)
2000-09-18 16:07:07 +00:00
{
2011-04-07 15:47:21 +03:00
// Set defaults
2008-10-17 08:40:10 +00:00
E3dDefaultAttributes aDefault;
SetDefaultAttributes(aDefault);
2000-09-18 16:07:07 +00:00
}
2008-10-17 08:40:10 +00:00
E3dCompoundObject::E3dCompoundObject(E3dDefaultAttributes& rDefault)
: E3dObject(),
aMaterialAmbientColor(),
bCreateNormals(false),
bCreateTexture(false)
2000-09-18 16:07:07 +00:00
{
2011-04-07 15:47:21 +03:00
// Set defaults
2008-10-17 08:40:10 +00:00
SetDefaultAttributes(rDefault);
2000-09-18 16:07:07 +00:00
}
2008-10-17 08:40:10 +00:00
void E3dCompoundObject::SetDefaultAttributes(E3dDefaultAttributes& rDefault)
2000-09-18 16:07:07 +00:00
{
2011-04-07 15:47:21 +03:00
// Set defaults
2008-10-17 08:40:10 +00:00
aMaterialAmbientColor = rDefault.GetDefaultAmbientColor();
bCreateNormals = rDefault.GetDefaultCreateNormals();
bCreateTexture = rDefault.GetDefaultCreateTexture();
2000-09-18 16:07:07 +00:00
}
2008-10-17 08:40:10 +00:00
E3dCompoundObject::~E3dCompoundObject ()
{
2000-09-18 16:07:07 +00:00
}
2008-10-17 08:40:10 +00:00
basegfx::B2DPolyPolygon E3dCompoundObject::TakeXorPoly() const
2000-09-18 16:07:07 +00:00
{
2008-10-17 08:40:10 +00:00
basegfx::B2DPolyPolygon aRetval;
const uno::Sequence< beans::PropertyValue > aEmptyParameters;
drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters);
E3dScene* pRootScene = fillViewInformation3DForCompoundObject(aViewInfo3D, *this);
2002-06-07 11:08:48 +00:00
2008-10-17 08:40:10 +00:00
if(pRootScene)
2002-06-07 11:08:48 +00:00
{
2008-10-17 08:40:10 +00:00
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());
2002-06-07 11:08:48 +00:00
}
2008-10-17 08:40:10 +00:00
return aRetval;
2000-09-18 16:07:07 +00:00
}
2008-10-17 08:40:10 +00:00
sal_uInt32 E3dCompoundObject::GetHdlCount() const
2000-09-18 16:07:07 +00:00
{
2011-04-07 15:47:21 +03:00
// 8 corners + 1 E3dVolumeMarker (= Wireframe representation)
2008-10-17 08:40:10 +00:00
return 9L;
2000-09-18 16:07:07 +00:00
}
2008-10-17 08:40:10 +00:00
void E3dCompoundObject::AddToHdlList(SdrHdlList& rHdlList) const
2000-09-18 16:07:07 +00:00
{
2008-10-17 08:40:10 +00:00
const uno::Sequence< beans::PropertyValue > aEmptyParameters;
drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters);
E3dScene* pRootScene = fillViewInformation3DForCompoundObject(aViewInfo3D, *this);
2000-09-18 16:07:07 +00:00
2008-10-17 08:40:10 +00:00
if(pRootScene)
2000-09-18 16:07:07 +00:00
{
2008-10-17 08:40:10 +00:00
const basegfx::B3DRange aBoundVolume(GetBoundVolume());
2000-09-18 16:07:07 +00:00
2008-10-17 08:40:10 +00:00
if(!aBoundVolume.isEmpty())
2000-09-18 16:07:07 +00:00
{
2008-10-17 08:40:10 +00:00
const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pRootScene->GetViewContact());
2000-09-18 16:07:07 +00:00
2008-10-17 08:40:10 +00:00
for(sal_uInt32 a(0); a < 8; a++)
{
2008-10-17 08:40:10 +00:00
basegfx::B3DPoint aPos3D;
2008-10-17 08:40:10 +00:00
switch(a)
{
2008-10-17 08:40:10 +00:00
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;
}
2000-09-18 16:07:07 +00:00
2008-10-17 08:40:10 +00:00
// to 3d view coor
aPos3D *= aViewInfo3D.getObjectToView() * GetTransform();
2000-09-18 16:07:07 +00:00
2008-10-17 08:40:10 +00:00
// create 2d relative scene
basegfx::B2DPoint aPos2D(aPos3D.getX(), aPos3D.getY());
2000-09-18 16:07:07 +00:00
2008-10-17 08:40:10 +00:00
// to 2d world coor
aPos2D *= rVCScene.getObjectTransformation();
2000-09-18 16:07:07 +00:00
2008-10-17 08:40:10 +00:00
rHdlList.AddHdl(new SdrHdl(Point(basegfx::fround(aPos2D.getX()), basegfx::fround(aPos2D.getY())), HDL_BWGT));
2000-09-18 16:07:07 +00:00
}
}
}
2008-10-17 08:40:10 +00:00
const basegfx::B2DPolyPolygon aPolyPolygon(TakeXorPoly());
if(aPolyPolygon.count())
{
E3dVolumeMarker* pVolMarker = new E3dVolumeMarker(aPolyPolygon);
rHdlList.AddHdl(pVolMarker);
}
2000-09-18 16:07:07 +00:00
}
sal_uInt16 E3dCompoundObject::GetObjIdentifier() const
{
2008-10-17 08:40:10 +00:00
return E3D_COMPOUNDOBJ_ID;
}
2000-09-18 16:07:07 +00:00
2008-10-17 08:40:10 +00:00
void E3dCompoundObject::RecalcSnapRect()
2000-09-18 16:07:07 +00:00
{
2008-10-17 08:40:10 +00:00
const uno::Sequence< beans::PropertyValue > aEmptyParameters;
drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters);
E3dScene* pRootScene = fillViewInformation3DForCompoundObject(aViewInfo3D, *this);
maSnapRect = Rectangle();
2000-09-18 16:07:07 +00:00
2008-10-17 08:40:10 +00:00
if(pRootScene)
2000-09-18 16:07:07 +00:00
{
2008-10-17 08:40:10 +00:00
// get VC of 3D candidate
const sdr::contact::ViewContactOfE3d* pVCOfE3D = dynamic_cast< const sdr::contact::ViewContactOfE3d* >(&GetViewContact());
2008-10-17 08:40:10 +00:00
if(pVCOfE3D)
{
2008-10-17 08:40:10 +00:00
// get 3D primitive sequence
const drawinglayer::primitive3d::Primitive3DSequence xLocalSequence(pVCOfE3D->getViewIndependentPrimitive3DSequence());
if(xLocalSequence.hasElements())
2000-09-18 16:07:07 +00:00
{
2008-10-17 08:40:10 +00:00
// 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 coordinates
2008-10-17 08:40:10 +00:00
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())));
2000-09-18 16:07:07 +00:00
}
}
}
}
E3dCompoundObject* E3dCompoundObject::Clone() const
{
return CloneHelper< E3dCompoundObject >();
}
2011-04-07 15:47:21 +03:00
// convert given basegfx::B3DPolyPolygon to screen coor
2000-09-18 16:07:07 +00:00
basegfx::B2DPolyPolygon E3dCompoundObject::TransformToScreenCoor(const basegfx::B3DPolyPolygon& rCandidate)
2000-09-18 16:07:07 +00:00
{
2008-10-17 08:40:10 +00:00
const uno::Sequence< beans::PropertyValue > aEmptyParameters;
drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters);
E3dScene* pRootScene = fillViewInformation3DForCompoundObject(aViewInfo3D, *this);
basegfx::B2DPolyPolygon aRetval;
2000-09-18 16:07:07 +00:00
2008-10-17 08:40:10 +00:00
if(pRootScene)
2000-09-18 16:07:07 +00:00
{
2008-10-17 08:40:10 +00:00
aRetval = basegfx::tools::createB2DPolyPolygonFromB3DPolyPolygon(rCandidate,
aViewInfo3D.getObjectToView() * GetTransform());
const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pRootScene->GetViewContact());
aRetval.transform(rVCScene.getObjectTransformation());
2000-09-18 16:07:07 +00:00
}
return aRetval;
2000-09-18 16:07:07 +00:00
}
bool E3dCompoundObject::IsAOrdNumRemapCandidate(E3dScene*& prScene) const
{
if(GetObjList()
&& GetObjList()->GetOwnerObj()
&& GetObjList()->GetOwnerObj()->ISA(E3dScene))
{
prScene = static_cast<E3dScene*>(GetObjList()->GetOwnerObj());
return true;
}
return false;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */