summaryrefslogtreecommitdiffstats
path: root/svx/source/unodraw/unoshap3.cxx
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
commit267c6f2ac71f92999e969232431ba04678e7437e (patch)
tree358c9467650e1d0a1d7227a21dac2e3d08b622b2 /svx/source/unodraw/unoshap3.cxx
parentInitial commit. (diff)
downloadlibreoffice-267c6f2ac71f92999e969232431ba04678e7437e.tar.xz
libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.zip
Adding upstream version 4:24.2.0.upstream/4%24.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'svx/source/unodraw/unoshap3.cxx')
-rw-r--r--svx/source/unodraw/unoshap3.cxx1051
1 files changed, 1051 insertions, 0 deletions
diff --git a/svx/source/unodraw/unoshap3.cxx b/svx/source/unodraw/unoshap3.cxx
new file mode 100644
index 0000000000..ea4e90ee46
--- /dev/null
+++ b/svx/source/unodraw/unoshap3.cxx
@@ -0,0 +1,1051 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#include <sal/config.h>
+
+#include <initializer_list>
+#include <string_view>
+
+#include <com/sun/star/drawing/HomogenMatrix.hpp>
+#include <com/sun/star/drawing/Position3D.hpp>
+#include <com/sun/star/drawing/Direction3D.hpp>
+#include <com/sun/star/drawing/DoubleSequence.hpp>
+#include <com/sun/star/drawing/CameraGeometry.hpp>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+#include <o3tl/safeint.hxx>
+#include <vcl/svapp.hxx>
+#include <comphelper/sequence.hxx>
+#include <sal/log.hxx>
+
+#include <svx/svdpool.hxx>
+#include <svx/svditer.hxx>
+#include <svx/unoshape.hxx>
+#include <svx/unopage.hxx>
+#include <svx/cube3d.hxx>
+#include <svx/sphere3d.hxx>
+#include <svx/lathe3d.hxx>
+#include <extrud3d.hxx>
+#include <polygn3d.hxx>
+#include <svx/unoshprp.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/scene3d.hxx>
+#include <basegfx/polygon/b3dpolygon.hxx>
+#include <basegfx/polygon/b3dpolygontools.hxx>
+#include <com/sun/star/drawing/PolyPolygonShape3D.hpp>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <basegfx/matrix/b3dhommatrixtools.hxx>
+#include "shapeimpl.hxx"
+
+using namespace ::cppu;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+
+#define QUERYINT( xint ) \
+ if( rType == cppu::UnoType<xint>::get() ) \
+ aAny <<= Reference< xint >(this)
+
+Svx3DSceneObject::Svx3DSceneObject(SdrObject* pObj, SvxDrawPage* pDrawPage)
+: SvxShapeGroupAnyD( pObj, getSvxMapProvider().GetMap(SVXMAP_3DSCENEOBJECT), getSvxMapProvider().GetPropertySet(SVXMAP_3DSCENEOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
+, mxPage( pDrawPage )
+{
+}
+
+
+Svx3DSceneObject::~Svx3DSceneObject() noexcept
+{
+}
+
+
+void Svx3DSceneObject::Create( SdrObject* pNewObj, SvxDrawPage* pNewPage )
+{
+ SvxShape::Create( pNewObj, pNewPage );
+ mxPage = pNewPage;
+}
+
+
+uno::Any SAL_CALL Svx3DSceneObject::queryAggregation( const uno::Type & rType )
+{
+ uno::Any aAny;
+
+ QUERYINT( drawing::XShapes );
+ else QUERYINT( container::XIndexAccess );
+ else QUERYINT( container::XElementAccess );
+ else
+ return SvxShape::queryAggregation( rType );
+
+ return aAny;
+}
+
+uno::Any SAL_CALL Svx3DSceneObject::queryInterface( const uno::Type & rType )
+{
+ return SvxShape::queryInterface( rType );
+}
+
+// XTypeProvider
+
+uno::Sequence< sal_Int8 > SAL_CALL Svx3DSceneObject::getImplementationId()
+{
+ return css::uno::Sequence<sal_Int8>();
+}
+
+
+void SAL_CALL Svx3DSceneObject::add( const Reference< drawing::XShape >& xShape )
+{
+ SolarMutexGuard aGuard;
+
+ SvxShape* pShape = comphelper::getFromUnoTunnel<SvxShape>( xShape );
+
+ if(!HasSdrObject() || !mxPage.is() || pShape == nullptr || nullptr != pShape->GetSdrObject() )
+ throw uno::RuntimeException();
+
+ rtl::Reference<SdrObject> pSdrShape = mxPage->CreateSdrObject_( xShape );
+ if( DynCastE3dObject(pSdrShape.get()) )
+ {
+ GetSdrObject()->GetSubList()->NbcInsertObject( pSdrShape.get() );
+ pShape->Create(pSdrShape.get(), mxPage.get());
+ }
+ else
+ {
+ pSdrShape.clear();
+ throw uno::RuntimeException();
+ }
+
+ GetSdrObject()->getSdrModelFromSdrObject().SetChanged();
+}
+
+void Svx3DSceneObject::addShape( SvxShape& rShape )
+{
+ SolarMutexGuard aGuard;
+
+ if(!HasSdrObject() || !mxPage.is() || nullptr != rShape.GetSdrObject() )
+ throw uno::RuntimeException();
+
+ rtl::Reference<SdrObject> pSdrShape = mxPage->CreateSdrObject_( &rShape );
+ if( DynCastE3dObject(pSdrShape.get()) )
+ {
+ GetSdrObject()->GetSubList()->NbcInsertObject( pSdrShape.get() );
+ rShape.Create(pSdrShape.get(), mxPage.get());
+ }
+ else
+ {
+ pSdrShape.clear();
+ throw uno::RuntimeException();
+ }
+
+ GetSdrObject()->getSdrModelFromSdrObject().SetChanged();
+}
+
+void SAL_CALL Svx3DSceneObject::remove( const Reference< drawing::XShape >& xShape )
+{
+ SolarMutexGuard aGuard;
+
+ SdrObject* pSdrShape = SdrObject::getSdrObjectFromXShape( xShape );
+
+ if(!HasSdrObject() || !pSdrShape ||
+ pSdrShape->getParentSdrObjectFromSdrObject() != GetSdrObject())
+ throw uno::RuntimeException();
+
+ SdrObjList& rList = *pSdrShape->getParentSdrObjListFromSdrObject();
+
+ const size_t nObjCount = rList.GetObjCount();
+ size_t nObjNum = 0;
+ while( nObjNum < nObjCount )
+ {
+ if(rList.GetObj( nObjNum ) == pSdrShape )
+ break;
+ nObjNum++;
+ }
+
+ if( nObjNum < nObjCount )
+ {
+ rList.NbcRemoveObject( nObjNum );
+ }
+ else
+ {
+ SAL_WARN( "svx", "Fatality! SdrObject is not belonging to its SdrObjList! [CL]" );
+ }
+}
+
+
+sal_Int32 SAL_CALL Svx3DSceneObject::getCount()
+{
+ SolarMutexGuard aGuard;
+
+ sal_Int32 nRetval = 0;
+
+ if(HasSdrObject() && DynCastE3dScene(GetSdrObject()) && GetSdrObject()->GetSubList())
+ nRetval = GetSdrObject()->GetSubList()->GetObjCount();
+ return nRetval;
+}
+
+
+uno::Any SAL_CALL Svx3DSceneObject::getByIndex( sal_Int32 Index )
+{
+ SolarMutexGuard aGuard;
+
+ if( !HasSdrObject() || GetSdrObject()->GetSubList() == nullptr )
+ throw uno::RuntimeException();
+
+ if( Index<0 || GetSdrObject()->GetSubList()->GetObjCount() <= o3tl::make_unsigned(Index) )
+ throw lang::IndexOutOfBoundsException();
+
+ SdrObject* pDestObj = GetSdrObject()->GetSubList()->GetObj( Index );
+ if(pDestObj == nullptr)
+ throw lang::IndexOutOfBoundsException();
+
+ Reference< drawing::XShape > xShape( pDestObj->getUnoShape(), uno::UNO_QUERY );
+ return uno::Any(xShape);
+}
+
+
+// css::container::XElementAccess
+
+uno::Type SAL_CALL Svx3DSceneObject::getElementType()
+{
+ return cppu::UnoType<drawing::XShape>::get();
+}
+
+
+sal_Bool SAL_CALL Svx3DSceneObject::hasElements()
+{
+ SolarMutexGuard aGuard;
+
+ return HasSdrObject() && GetSdrObject()->GetSubList() && (GetSdrObject()->GetSubList()->GetObjCount() > 0);
+}
+
+
+static bool ConvertHomogenMatrixToObject( E3dObject* pObject, const Any& rValue )
+{
+ drawing::HomogenMatrix aMat;
+ if( rValue >>= aMat )
+ {
+ pObject->SetTransform(basegfx::utils::UnoHomogenMatrixToB3DHomMatrix(aMat));
+ return true;
+ }
+ return false;
+}
+
+static void ConvertObjectToHomogenMatric( E3dObject const * pObject, Any& rValue )
+{
+ drawing::HomogenMatrix aHomMat;
+ const basegfx::B3DHomMatrix& rMat = pObject->GetTransform();
+ basegfx::utils::B3DHomMatrixToUnoHomogenMatrix(rMat, aHomMat);
+ rValue <<= aHomMat;
+}
+
+namespace {
+
+struct ImpRememberTransAndRect
+{
+ basegfx::B3DHomMatrix maMat;
+ tools::Rectangle maRect;
+};
+
+}
+
+bool Svx3DSceneObject::setPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue )
+{
+ switch( pProperty->nWID )
+ {
+ case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
+ {
+ // patch transformation matrix to the object
+ if( ConvertHomogenMatrixToObject( static_cast< E3dObject* >( GetSdrObject() ), rValue ) )
+ return true;
+ break;
+ }
+ case OWN_ATTR_3D_VALUE_CAMERA_GEOMETRY:
+ {
+ // set CameraGeometry at scene
+ E3dScene* pScene = static_cast< E3dScene* >( GetSdrObject() );
+ drawing::CameraGeometry aCamGeo;
+
+ if(rValue >>= aCamGeo)
+ {
+ basegfx::B3DPoint aVRP(aCamGeo.vrp.PositionX, aCamGeo.vrp.PositionY, aCamGeo.vrp.PositionZ);
+ basegfx::B3DVector aVPN(aCamGeo.vpn.DirectionX, aCamGeo.vpn.DirectionY, aCamGeo.vpn.DirectionZ);
+ basegfx::B3DVector aVUP(aCamGeo.vup.DirectionX, aCamGeo.vup.DirectionY, aCamGeo.vup.DirectionZ);
+
+ // rescue scene transformation
+ ImpRememberTransAndRect aSceneTAR;
+ aSceneTAR.maMat = pScene->GetTransform();
+ aSceneTAR.maRect = pScene->GetSnapRect();
+
+ // rescue object transformations
+ SdrObjListIter aIter(pScene->GetSubList(), SdrIterMode::DeepWithGroups);
+ std::vector<basegfx::B3DHomMatrix*> aObjTrans;
+ while(aIter.IsMore())
+ {
+ E3dObject* p3DObj = static_cast<E3dObject*>(aIter.Next());
+ basegfx::B3DHomMatrix* pNew = new basegfx::B3DHomMatrix;
+ *pNew = p3DObj->GetTransform();
+ aObjTrans.push_back(pNew);
+ }
+
+ // reset object transformations
+ aIter.Reset();
+ while(aIter.IsMore())
+ {
+ E3dObject* p3DObj = static_cast<E3dObject*>(aIter.Next());
+ p3DObj->NbcSetTransform(basegfx::B3DHomMatrix());
+ }
+
+ // reset scene transformation and make a complete recalc
+ pScene->NbcSetTransform(basegfx::B3DHomMatrix());
+
+ // fill old camera from new parameters
+ Camera3D aCam(pScene->GetCamera());
+ const basegfx::B3DRange& rVolume = pScene->GetBoundVolume();
+ double fW = rVolume.getWidth();
+ double fH = rVolume.getHeight();
+
+ const SfxItemSet& rSceneSet = pScene->GetMergedItemSet();
+ double fCamPosZ =
+ static_cast<double>(rSceneSet.Get(SDRATTR_3DSCENE_DISTANCE).GetValue());
+ double fCamFocal =
+ static_cast<double>(rSceneSet.Get(SDRATTR_3DSCENE_FOCAL_LENGTH).GetValue());
+
+ aCam.SetAutoAdjustProjection(false);
+ aCam.SetViewWindow(- fW / 2, - fH / 2, fW, fH);
+ basegfx::B3DPoint aLookAt;
+ basegfx::B3DPoint aCamPos(0.0, 0.0, fCamPosZ);
+ aCam.SetPosAndLookAt(aCamPos, aLookAt);
+ aCam.SetFocalLength(fCamFocal / 100.0);
+ aCam.SetDeviceWindow(tools::Rectangle(0, 0, static_cast<tools::Long>(fW), static_cast<tools::Long>(fH)));
+
+ // set at scene
+ pScene->SetCamera(aCam);
+
+ // #91047# use imported VRP, VPN and VUP (if used)
+ bool bVRPUsed(!aVRP.equal(basegfx::B3DPoint(0.0, 0.0, 1.0)));
+ bool bVPNUsed(!aVPN.equal(basegfx::B3DVector(0.0, 0.0, 1.0)));
+ bool bVUPUsed(!aVUP.equal(basegfx::B3DVector(0.0, 1.0, 0.0)));
+
+ if(bVRPUsed || bVPNUsed || bVUPUsed)
+ {
+ pScene->GetCameraSet().SetViewportValues(aVRP, aVPN, aVUP);
+ }
+
+ // set object transformations again at objects
+ aIter.Reset();
+ sal_uInt32 nIndex(0);
+ while(aIter.IsMore())
+ {
+ E3dObject* p3DObj = static_cast<E3dObject*>(aIter.Next());
+ basegfx::B3DHomMatrix* pMat = aObjTrans[nIndex++];
+ p3DObj->NbcSetTransform(*pMat);
+ delete pMat;
+ }
+
+ // set scene transformation again at scene
+ pScene->NbcSetTransform(aSceneTAR.maMat);
+ pScene->NbcSetSnapRect(aSceneTAR.maRect);
+
+ return true;
+ }
+ break;
+ }
+ default:
+ return SvxShape::setPropertyValueImpl(rName, pProperty, rValue);
+ }
+
+ throw IllegalArgumentException();
+}
+
+
+bool Svx3DSceneObject::getPropertyValueImpl(const OUString& rName, const SfxItemPropertyMapEntry* pProperty,
+ css::uno::Any& rValue)
+{
+ switch( pProperty->nWID )
+ {
+ case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
+ {
+ // patch object to a homogeneous 4x4 matrix
+ ConvertObjectToHomogenMatric( static_cast< E3dObject* >( GetSdrObject() ), rValue );
+ break;
+ }
+ case OWN_ATTR_3D_VALUE_CAMERA_GEOMETRY:
+ {
+ // get CameraGeometry from scene
+ E3dScene* pScene = static_cast< E3dScene* >( GetSdrObject() );
+ drawing::CameraGeometry aCamGeo;
+
+ // fill Vectors from scene camera
+ B3dCamera& aCameraSet = pScene->GetCameraSet();
+ basegfx::B3DPoint aVRP(aCameraSet.GetVRP());
+ basegfx::B3DVector aVPN(aCameraSet.GetVPN());
+ basegfx::B3DVector aVUP(aCameraSet.GetVUV());
+
+ // transfer to structure
+ aCamGeo.vrp.PositionX = aVRP.getX();
+ aCamGeo.vrp.PositionY = aVRP.getY();
+ aCamGeo.vrp.PositionZ = aVRP.getZ();
+ aCamGeo.vpn.DirectionX = aVPN.getX();
+ aCamGeo.vpn.DirectionY = aVPN.getY();
+ aCamGeo.vpn.DirectionZ = aVPN.getZ();
+ aCamGeo.vup.DirectionX = aVUP.getX();
+ aCamGeo.vup.DirectionY = aVUP.getY();
+ aCamGeo.vup.DirectionZ = aVUP.getZ();
+
+ rValue <<= aCamGeo;
+ break;
+ }
+ default:
+ return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
+ }
+
+ return true;
+}
+
+// css::lang::XServiceInfo
+uno::Sequence< OUString > SAL_CALL Svx3DSceneObject::getSupportedServiceNames()
+{
+ return comphelper::concatSequences(
+ SvxShape::getSupportedServiceNames(),
+ std::initializer_list<std::u16string_view>{ u"com.sun.star.drawing.Shape3DScene" });
+}
+
+Svx3DCubeObject::Svx3DCubeObject(SdrObject* pObj)
+: SvxShape( pObj, getSvxMapProvider().GetMap(SVXMAP_3DCUBEOBJECT), getSvxMapProvider().GetPropertySet(SVXMAP_3DCUBEOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
+{
+}
+
+Svx3DCubeObject::~Svx3DCubeObject() noexcept
+{
+}
+
+bool Svx3DCubeObject::setPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue )
+{
+ SolarMutexGuard aGuard;
+
+ switch( pProperty->nWID )
+ {
+ case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
+ {
+ // pack transformationmatrix to the object
+ if( ConvertHomogenMatrixToObject( static_cast< E3dObject* >( GetSdrObject() ), rValue ) )
+ return true;
+ break;
+ }
+ case OWN_ATTR_3D_VALUE_POSITION:
+ {
+ // pack position to the object
+ drawing::Position3D aUnoPos;
+ if( rValue >>= aUnoPos )
+ {
+ basegfx::B3DPoint aPos(aUnoPos.PositionX, aUnoPos.PositionY, aUnoPos.PositionZ);
+ static_cast< E3dCubeObj* >( GetSdrObject() )->SetCubePos(aPos);
+ return true;
+ }
+ break;
+ }
+ case OWN_ATTR_3D_VALUE_SIZE:
+ {
+ // pack size to the object
+ drawing::Direction3D aDirection;
+ if( rValue >>= aDirection )
+ {
+ basegfx::B3DVector aSize(aDirection.DirectionX, aDirection.DirectionY, aDirection.DirectionZ);
+ static_cast< E3dCubeObj* >( GetSdrObject() )->SetCubeSize(aSize);
+ return true;
+ }
+ break;
+ }
+ case OWN_ATTR_3D_VALUE_POS_IS_CENTER:
+ {
+ bool bNew = false;
+ // pack sal_Bool bPosIsCenter to the object
+ if( rValue >>= bNew )
+ {
+ static_cast< E3dCubeObj* >( GetSdrObject() )->SetPosIsCenter(bNew);
+ return true;
+ }
+ break;
+ }
+ default:
+ return SvxShape::setPropertyValueImpl( rName, pProperty, rValue );
+ }
+
+ throw IllegalArgumentException();
+}
+
+bool Svx3DCubeObject::getPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, css::uno::Any& rValue )
+{
+ switch( pProperty->nWID )
+ {
+ case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
+ {
+ // pack transformation to a homogeneous matrix
+ ConvertObjectToHomogenMatric( static_cast< E3dObject* >( GetSdrObject() ), rValue );
+ break;
+ }
+ case OWN_ATTR_3D_VALUE_POSITION:
+ {
+ // pack position
+ const basegfx::B3DPoint& rPos = static_cast<E3dCubeObj*>(GetSdrObject())->GetCubePos();
+ drawing::Position3D aPos;
+
+ aPos.PositionX = rPos.getX();
+ aPos.PositionY = rPos.getY();
+ aPos.PositionZ = rPos.getZ();
+
+ rValue <<= aPos;
+ break;
+ }
+ case OWN_ATTR_3D_VALUE_SIZE:
+ {
+ // pack size
+ const basegfx::B3DVector& rSize = static_cast<E3dCubeObj*>(GetSdrObject())->GetCubeSize();
+ drawing::Direction3D aDir;
+
+ aDir.DirectionX = rSize.getX();
+ aDir.DirectionY = rSize.getY();
+ aDir.DirectionZ = rSize.getZ();
+
+ rValue <<= aDir;
+ break;
+ }
+ case OWN_ATTR_3D_VALUE_POS_IS_CENTER:
+ {
+ rValue <<= static_cast<E3dCubeObj*>(GetSdrObject())->GetPosIsCenter();
+ break;
+ }
+ default:
+ return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
+ }
+
+ return true;
+}
+
+// css::lang::XServiceInfo
+uno::Sequence< OUString > SAL_CALL Svx3DCubeObject::getSupportedServiceNames()
+{
+ return comphelper::concatSequences(
+ SvxShape::getSupportedServiceNames(),
+ std::initializer_list<std::u16string_view>{ u"com.sun.star.drawing.Shape3D",
+ u"com.sun.star.drawing.Shape3DCube" });
+}
+
+Svx3DSphereObject::Svx3DSphereObject(SdrObject* pObj)
+ : SvxShape( pObj, getSvxMapProvider().GetMap(SVXMAP_3DSPHEREOBJECT), getSvxMapProvider().GetPropertySet(SVXMAP_3DSPHEREOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
+{
+}
+
+Svx3DSphereObject::~Svx3DSphereObject() noexcept
+{
+}
+
+bool Svx3DSphereObject::setPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue )
+{
+ switch( pProperty->nWID )
+ {
+ case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
+ {
+ // pack transformation matrix to the object
+ if( ConvertHomogenMatrixToObject( static_cast< E3dObject* >( GetSdrObject() ), rValue ) )
+ return true;
+ break;
+ }
+
+ case OWN_ATTR_3D_VALUE_POSITION:
+ {
+ // pack position to the object
+ drawing::Position3D aUnoPos;
+ if( rValue >>= aUnoPos )
+ {
+ basegfx::B3DPoint aPos(aUnoPos.PositionX, aUnoPos.PositionY, aUnoPos.PositionZ);
+ static_cast<E3dSphereObj*>(GetSdrObject())->SetCenter(aPos);
+ return true;
+ }
+ break;
+ }
+
+ case OWN_ATTR_3D_VALUE_SIZE:
+ {
+ // pack size to the object
+ drawing::Direction3D aDir;
+ if( rValue >>= aDir )
+ {
+ basegfx::B3DVector aPos(aDir.DirectionX, aDir.DirectionY, aDir.DirectionZ);
+ static_cast<E3dSphereObj*>(GetSdrObject())->SetSize(aPos);
+ return true;
+ }
+ break;
+ }
+ default:
+ return SvxShape::setPropertyValueImpl( rName, pProperty, rValue );
+ }
+
+ throw IllegalArgumentException();
+}
+
+bool Svx3DSphereObject::getPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, css::uno::Any& rValue )
+{
+ switch( pProperty->nWID )
+ {
+ case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
+ {
+ // pack transformation to a homogeneous matrix
+ ConvertObjectToHomogenMatric( static_cast< E3dObject* >( GetSdrObject() ), rValue );
+ break;
+ }
+ case OWN_ATTR_3D_VALUE_POSITION:
+ {
+ // pack position
+ const basegfx::B3DPoint& rPos = static_cast<E3dSphereObj*>(GetSdrObject())->Center();
+ drawing::Position3D aPos;
+
+ aPos.PositionX = rPos.getX();
+ aPos.PositionY = rPos.getY();
+ aPos.PositionZ = rPos.getZ();
+
+ rValue <<= aPos;
+ break;
+ }
+ case OWN_ATTR_3D_VALUE_SIZE:
+ {
+ // pack size
+ const basegfx::B3DVector& rSize = static_cast<E3dSphereObj*>(GetSdrObject())->Size();
+ drawing::Direction3D aDir;
+
+ aDir.DirectionX = rSize.getX();
+ aDir.DirectionY = rSize.getY();
+ aDir.DirectionZ = rSize.getZ();
+
+ rValue <<= aDir;
+ break;
+ }
+ default:
+ return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
+ }
+
+ return true;
+}
+
+// css::lang::XServiceInfo
+uno::Sequence< OUString > SAL_CALL Svx3DSphereObject::getSupportedServiceNames()
+{
+ return comphelper::concatSequences(
+ SvxShape::getSupportedServiceNames(),
+ std::initializer_list<std::u16string_view>{ u"com.sun.star.drawing.Shape3D",
+ u"com.sun.star.drawing.Shape3DSphere" });
+}
+
+Svx3DLatheObject::Svx3DLatheObject(SdrObject* pObj)
+: SvxShape( pObj, getSvxMapProvider().GetMap(SVXMAP_3DLATHEOBJECT), getSvxMapProvider().GetPropertySet(SVXMAP_3DLATHEOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
+{
+}
+
+Svx3DLatheObject::~Svx3DLatheObject() noexcept
+{
+}
+
+static bool PolyPolygonShape3D_to_B3dPolyPolygon(
+ const Any& rValue,
+ basegfx::B3DPolyPolygon& rResultPolygon,
+ bool bCorrectPolygon)
+{
+ drawing::PolyPolygonShape3D aSourcePolyPolygon;
+ if( !(rValue >>= aSourcePolyPolygon) )
+ return false;
+
+ sal_Int32 nOuterSequenceCount = aSourcePolyPolygon.SequenceX.getLength();
+ if(nOuterSequenceCount != aSourcePolyPolygon.SequenceY.getLength() || nOuterSequenceCount != aSourcePolyPolygon.SequenceZ.getLength())
+ return false;
+
+ const drawing::DoubleSequence* pInnerSequenceX = aSourcePolyPolygon.SequenceX.getConstArray();
+ const drawing::DoubleSequence* pInnerSequenceY = aSourcePolyPolygon.SequenceY.getConstArray();
+ const drawing::DoubleSequence* pInnerSequenceZ = aSourcePolyPolygon.SequenceZ.getConstArray();
+ for(sal_Int32 a(0);a<nOuterSequenceCount;a++)
+ {
+ sal_Int32 nInnerSequenceCount = pInnerSequenceX->getLength();
+ if(nInnerSequenceCount != pInnerSequenceY->getLength() || nInnerSequenceCount != pInnerSequenceZ->getLength())
+ {
+ return false;
+ }
+ basegfx::B3DPolygon aNewPolygon;
+ const double* pArrayX = pInnerSequenceX->getConstArray();
+ const double* pArrayY = pInnerSequenceY->getConstArray();
+ const double* pArrayZ = pInnerSequenceZ->getConstArray();
+ for(sal_Int32 b(0);b<nInnerSequenceCount;b++)
+ {
+ aNewPolygon.append(basegfx::B3DPoint(*pArrayX++,*pArrayY++,*pArrayZ++));
+ }
+ pInnerSequenceX++;
+ pInnerSequenceY++;
+ pInnerSequenceZ++;
+
+ // #i101520# correction is needed for imported polygons of old format,
+ // see callers
+ if(bCorrectPolygon)
+ {
+ basegfx::utils::checkClosed(aNewPolygon);
+ }
+
+ rResultPolygon.append(aNewPolygon);
+ }
+ return true;
+}
+
+static void B3dPolyPolygon_to_PolyPolygonShape3D( const basegfx::B3DPolyPolygon& rSourcePolyPolygon, Any& rValue )
+{
+ drawing::PolyPolygonShape3D aRetval;
+ aRetval.SequenceX.realloc(rSourcePolyPolygon.count());
+ aRetval.SequenceY.realloc(rSourcePolyPolygon.count());
+ aRetval.SequenceZ.realloc(rSourcePolyPolygon.count());
+ drawing::DoubleSequence* pOuterSequenceX = aRetval.SequenceX.getArray();
+ drawing::DoubleSequence* pOuterSequenceY = aRetval.SequenceY.getArray();
+ drawing::DoubleSequence* pOuterSequenceZ = aRetval.SequenceZ.getArray();
+ for(sal_uInt32 a(0);a<rSourcePolyPolygon.count();a++)
+ {
+ const basegfx::B3DPolygon& aPoly(rSourcePolyPolygon.getB3DPolygon(a));
+ sal_Int32 nPointCount(aPoly.count());
+ if(aPoly.isClosed()) nPointCount++;
+ pOuterSequenceX->realloc(nPointCount);
+ pOuterSequenceY->realloc(nPointCount);
+ pOuterSequenceZ->realloc(nPointCount);
+ double* pInnerSequenceX = pOuterSequenceX->getArray();
+ double* pInnerSequenceY = pOuterSequenceY->getArray();
+ double* pInnerSequenceZ = pOuterSequenceZ->getArray();
+ for(sal_uInt32 b(0);b<aPoly.count();b++)
+ {
+ const basegfx::B3DPoint aPoint(aPoly.getB3DPoint(b));
+ *pInnerSequenceX++ = aPoint.getX();
+ *pInnerSequenceY++ = aPoint.getY();
+ *pInnerSequenceZ++ = aPoint.getZ();
+ }
+ if(aPoly.isClosed())
+ {
+ const basegfx::B3DPoint aPoint(aPoly.getB3DPoint(0));
+ *pInnerSequenceX++ = aPoint.getX();
+ *pInnerSequenceY++ = aPoint.getY();
+ *pInnerSequenceZ++ = aPoint.getZ();
+ }
+ pOuterSequenceX++;
+ pOuterSequenceY++;
+ pOuterSequenceZ++;
+ }
+ rValue <<= aRetval;
+}
+
+bool Svx3DLatheObject::setPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue )
+{
+ switch( pProperty->nWID )
+ {
+ case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
+ {
+ // pack transformation matrix to the object
+ if( ConvertHomogenMatrixToObject( static_cast< E3dObject* >( GetSdrObject() ), rValue ) )
+ return true;
+ break;
+ }
+ case OWN_ATTR_3D_VALUE_POLYPOLYGON3D:
+ {
+ // pack polygon definition to the object
+ basegfx::B3DPolyPolygon aNewB3DPolyPolygon;
+
+ // #i101520# Probably imported
+ if( PolyPolygonShape3D_to_B3dPolyPolygon( rValue, aNewB3DPolyPolygon, true ) )
+ {
+ // #105127# SetPolyPoly3D sets the Svx3DVerticalSegmentsItem to the number
+ // of points of the polygon. Thus, value gets lost. To avoid this, rescue
+ // item here and re-set after setting the polygon.
+ const sal_uInt32 nPrevVerticalSegs(static_cast<E3dLatheObj*>(GetSdrObject())->GetVerticalSegments());
+
+ // set polygon
+ const basegfx::B3DHomMatrix aIdentity;
+ const basegfx::B2DPolyPolygon aB2DPolyPolygon(basegfx::utils::createB2DPolyPolygonFromB3DPolyPolygon(aNewB3DPolyPolygon, aIdentity));
+ static_cast<E3dLatheObj*>(GetSdrObject())->SetPolyPoly2D(aB2DPolyPolygon);
+ const sal_uInt32 nPostVerticalSegs(static_cast<E3dLatheObj*>(GetSdrObject())->GetVerticalSegments());
+
+ if(nPrevVerticalSegs != nPostVerticalSegs)
+ {
+ // restore the vertical segment count
+ static_cast<E3dLatheObj*>(GetSdrObject())->SetMergedItem(makeSvx3DVerticalSegmentsItem(nPrevVerticalSegs));
+ }
+ return true;
+ }
+ break;
+ }
+ default:
+ return SvxShape::setPropertyValueImpl( rName, pProperty, rValue );
+ }
+
+ throw IllegalArgumentException();
+}
+
+bool Svx3DLatheObject::getPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, css::uno::Any& rValue )
+{
+ switch( pProperty->nWID )
+ {
+ case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
+ {
+ // pack transformation to a homogeneous matrix
+ drawing::HomogenMatrix aHomMat;
+ basegfx::B3DHomMatrix aMat = static_cast<E3dObject*>(GetSdrObject())->GetTransform();
+ basegfx::utils::B3DHomMatrixToUnoHomogenMatrix(aMat, aHomMat);
+ rValue <<= aHomMat;
+ break;
+ }
+ case OWN_ATTR_3D_VALUE_POLYPOLYGON3D:
+ {
+ const basegfx::B2DPolyPolygon& rPolyPoly = static_cast<E3dLatheObj*>(GetSdrObject())->GetPolyPoly2D();
+ const basegfx::B3DPolyPolygon aB3DPolyPolygon(basegfx::utils::createB3DPolyPolygonFromB2DPolyPolygon(rPolyPoly));
+
+ B3dPolyPolygon_to_PolyPolygonShape3D(aB3DPolyPolygon, rValue);
+ break;
+ }
+ default:
+ return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
+ }
+
+ return true;
+}
+
+// css::lang::XServiceInfo
+uno::Sequence< OUString > SAL_CALL Svx3DLatheObject::getSupportedServiceNames()
+{
+ return comphelper::concatSequences(
+ SvxShape::getSupportedServiceNames(),
+ std::initializer_list<std::u16string_view>{ u"com.sun.star.drawing.Shape3D",
+ u"com.sun.star.drawing.Shape3DLathe" });
+}
+
+Svx3DExtrudeObject::Svx3DExtrudeObject(SdrObject* pObj)
+: SvxShape( pObj, getSvxMapProvider().GetMap(SVXMAP_3DEXTRUDEOBJECT), getSvxMapProvider().GetPropertySet(SVXMAP_3DEXTRUDEOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
+{
+}
+
+Svx3DExtrudeObject::~Svx3DExtrudeObject() noexcept
+{
+}
+
+bool Svx3DExtrudeObject::setPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue )
+{
+ switch( pProperty->nWID )
+ {
+ case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
+ {
+ // pack transformation matrix to the object
+ if( ConvertHomogenMatrixToObject( static_cast< E3dObject* >( GetSdrObject() ), rValue ) )
+ return true;
+ break;
+ }
+
+ case OWN_ATTR_3D_VALUE_POLYPOLYGON3D:
+ {
+ // pack polygon definition to the object
+ basegfx::B3DPolyPolygon aNewB3DPolyPolygon;
+
+ // #i101520# Probably imported
+ if( PolyPolygonShape3D_to_B3dPolyPolygon( rValue, aNewB3DPolyPolygon, true ) )
+ {
+ // set polygon
+ const basegfx::B3DHomMatrix aIdentity;
+ const basegfx::B2DPolyPolygon aB2DPolyPolygon(basegfx::utils::createB2DPolyPolygonFromB3DPolyPolygon(aNewB3DPolyPolygon, aIdentity));
+ static_cast<E3dExtrudeObj*>(GetSdrObject())->SetExtrudePolygon(aB2DPolyPolygon);
+ return true;
+ }
+ break;
+ }
+ default:
+ return SvxShape::setPropertyValueImpl( rName, pProperty, rValue );
+ }
+
+ throw IllegalArgumentException();
+}
+
+bool Svx3DExtrudeObject::getPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, css::uno::Any& rValue )
+{
+ switch( pProperty->nWID )
+ {
+ case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
+ {
+ // pack transformation to a homogeneous matrix
+ drawing::HomogenMatrix aHomMat;
+ basegfx::B3DHomMatrix aMat = static_cast<E3dObject*>(GetSdrObject())->GetTransform();
+ basegfx::utils::B3DHomMatrixToUnoHomogenMatrix(aMat, aHomMat);
+ rValue <<= aHomMat;
+ break;
+ }
+
+ case OWN_ATTR_3D_VALUE_POLYPOLYGON3D:
+ {
+ // pack polygon definition
+ const basegfx::B2DPolyPolygon& rPolyPoly = static_cast<E3dExtrudeObj*>(GetSdrObject())->GetExtrudePolygon();
+ const basegfx::B3DPolyPolygon aB3DPolyPolygon(basegfx::utils::createB3DPolyPolygonFromB2DPolyPolygon(rPolyPoly));
+
+ B3dPolyPolygon_to_PolyPolygonShape3D(aB3DPolyPolygon, rValue);
+ break;
+ }
+ default:
+ return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
+ }
+
+ return true;
+}
+
+// css::lang::XServiceInfo
+uno::Sequence< OUString > SAL_CALL Svx3DExtrudeObject::getSupportedServiceNames()
+{
+ return comphelper::concatSequences(
+ SvxShape::getSupportedServiceNames(),
+ std::initializer_list<std::u16string_view>{ u"com.sun.star.drawing.Shape3D",
+ u"com.sun.star.drawing.Shape3DExtrude" });
+}
+
+Svx3DPolygonObject::Svx3DPolygonObject(SdrObject* pObj)
+: SvxShape( pObj, getSvxMapProvider().GetMap(SVXMAP_3DPOLYGONOBJECT), getSvxMapProvider().GetPropertySet(SVXMAP_3DPOLYGONOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
+{
+}
+
+Svx3DPolygonObject::~Svx3DPolygonObject() noexcept
+{
+}
+
+bool Svx3DPolygonObject::setPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue )
+{
+ switch( pProperty->nWID )
+ {
+ case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
+ {
+ // pack transformation matrix to the object
+ if( ConvertHomogenMatrixToObject( static_cast< E3dObject* >( GetSdrObject() ), rValue ) )
+ return true;
+ break;
+ }
+
+ case OWN_ATTR_3D_VALUE_POLYPOLYGON3D:
+ {
+ // pack polygon definition to the object
+ basegfx::B3DPolyPolygon aNewB3DPolyPolygon;
+
+ // #i101520# Direct API data (e.g. from chart)
+ if( PolyPolygonShape3D_to_B3dPolyPolygon( rValue, aNewB3DPolyPolygon, false ) )
+ {
+ // set polygon
+ static_cast<E3dPolygonObj*>(GetSdrObject())->SetPolyPolygon3D(aNewB3DPolyPolygon);
+ return true;
+ }
+ break;
+ }
+ case OWN_ATTR_3D_VALUE_NORMALSPOLYGON3D:
+ {
+ // pack perpendicular definition to the object
+ basegfx::B3DPolyPolygon aNewB3DPolyPolygon;
+
+ // #i101520# Direct API data (e.g. from chart)
+ if( PolyPolygonShape3D_to_B3dPolyPolygon( rValue, aNewB3DPolyPolygon, false ) )
+ {
+ // set polygon
+ static_cast<E3dPolygonObj*>(GetSdrObject())->SetPolyNormals3D(aNewB3DPolyPolygon);
+ return true;
+ }
+ break;
+ }
+ case OWN_ATTR_3D_VALUE_TEXTUREPOLYGON3D:
+ {
+ // pack texture definition to the object
+ basegfx::B3DPolyPolygon aNewB3DPolyPolygon;
+
+ // #i101520# Direct API data (e.g. from chart)
+ if( PolyPolygonShape3D_to_B3dPolyPolygon( rValue, aNewB3DPolyPolygon, false ) )
+ {
+ // set polygon
+ const basegfx::B3DHomMatrix aIdentity;
+ const basegfx::B2DPolyPolygon aB2DPolyPolygon(basegfx::utils::createB2DPolyPolygonFromB3DPolyPolygon(aNewB3DPolyPolygon, aIdentity));
+ static_cast<E3dPolygonObj*>(GetSdrObject())->SetPolyTexture2D(aB2DPolyPolygon);
+ return true;
+ }
+ break;
+ }
+ case OWN_ATTR_3D_VALUE_LINEONLY:
+ {
+ bool bNew = false;
+ if( rValue >>= bNew )
+ {
+ static_cast<E3dPolygonObj*>(GetSdrObject())->SetLineOnly(bNew);
+ return true;
+ }
+ break;
+ }
+ default:
+ return SvxShape::setPropertyValueImpl( rName, pProperty, rValue );
+ }
+
+ throw IllegalArgumentException();
+}
+
+bool Svx3DPolygonObject::getPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, css::uno::Any& rValue )
+{
+ switch( pProperty->nWID )
+ {
+ case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
+ {
+ ConvertObjectToHomogenMatric( static_cast< E3dObject* >( GetSdrObject() ), rValue );
+ break;
+ }
+
+ case OWN_ATTR_3D_VALUE_POLYPOLYGON3D:
+ {
+ B3dPolyPolygon_to_PolyPolygonShape3D(static_cast<E3dPolygonObj*>(GetSdrObject())->GetPolyPolygon3D(),rValue);
+ break;
+ }
+
+ case OWN_ATTR_3D_VALUE_NORMALSPOLYGON3D:
+ {
+ B3dPolyPolygon_to_PolyPolygonShape3D(static_cast<E3dPolygonObj*>(GetSdrObject())->GetPolyNormals3D(),rValue);
+ break;
+ }
+
+ case OWN_ATTR_3D_VALUE_TEXTUREPOLYGON3D:
+ {
+ // pack texture definition
+ const basegfx::B2DPolyPolygon& rPolyPoly = static_cast<E3dPolygonObj*>(GetSdrObject())->GetPolyTexture2D();
+ const basegfx::B3DPolyPolygon aB3DPolyPolygon(basegfx::utils::createB3DPolyPolygonFromB2DPolyPolygon(rPolyPoly));
+
+ B3dPolyPolygon_to_PolyPolygonShape3D(aB3DPolyPolygon,rValue);
+ break;
+ }
+
+ case OWN_ATTR_3D_VALUE_LINEONLY:
+ {
+ rValue <<= static_cast<E3dPolygonObj*>(GetSdrObject())->GetLineOnly();
+ break;
+ }
+
+ default:
+ return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
+ }
+
+ return true;
+}
+
+// css::lang::XServiceInfo
+uno::Sequence< OUString > SAL_CALL Svx3DPolygonObject::getSupportedServiceNames()
+{
+ return comphelper::concatSequences(
+ SvxShape::getSupportedServiceNames(),
+ std::initializer_list<std::u16string_view>{ u"com.sun.star.drawing.Shape3D",
+ u"com.sun.star.drawing.Shape3DPolygon" });
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */