bump product version to 7.2.5.1
[LibreOffice.git] / svx / source / unodraw / unoshap3.cxx
blobad8286f1e97a195c9ede403fd51bb7a1d7bd2eae
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 .
20 #include <sal/config.h>
22 #include <initializer_list>
23 #include <string_view>
25 #include <com/sun/star/drawing/HomogenMatrix.hpp>
26 #include <com/sun/star/drawing/Position3D.hpp>
27 #include <com/sun/star/drawing/Direction3D.hpp>
28 #include <com/sun/star/drawing/DoubleSequence.hpp>
29 #include <com/sun/star/drawing/CameraGeometry.hpp>
30 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
31 #include <o3tl/safeint.hxx>
32 #include <vcl/svapp.hxx>
33 #include <comphelper/sequence.hxx>
34 #include <sal/log.hxx>
36 #include <svx/svdpool.hxx>
37 #include <svx/svditer.hxx>
38 #include <svx/unoshape.hxx>
39 #include <svx/unopage.hxx>
40 #include <svx/cube3d.hxx>
41 #include <svx/sphere3d.hxx>
42 #include <svx/lathe3d.hxx>
43 #include <extrud3d.hxx>
44 #include <polygn3d.hxx>
45 #include <svx/unoshprp.hxx>
46 #include <svx/svdmodel.hxx>
47 #include <svx/scene3d.hxx>
48 #include <basegfx/polygon/b3dpolygon.hxx>
49 #include <basegfx/polygon/b3dpolygontools.hxx>
50 #include <com/sun/star/drawing/PolyPolygonShape3D.hpp>
51 #include <basegfx/polygon/b2dpolypolygontools.hxx>
52 #include <basegfx/matrix/b3dhommatrixtools.hxx>
53 #include "shapeimpl.hxx"
55 using namespace ::cppu;
56 using namespace ::com::sun::star;
57 using namespace ::com::sun::star::uno;
58 using namespace ::com::sun::star::lang;
59 using namespace ::com::sun::star::container;
61 #define QUERYINT( xint ) \
62 if( rType == cppu::UnoType<xint>::get() ) \
63 aAny <<= Reference< xint >(this)
65 Svx3DSceneObject::Svx3DSceneObject(SdrObject* pObj, SvxDrawPage* pDrawPage)
66 : SvxShape( pObj, getSvxMapProvider().GetMap(SVXMAP_3DSCENEOBJECT), getSvxMapProvider().GetPropertySet(SVXMAP_3DSCENEOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
67 , mxPage( pDrawPage )
72 Svx3DSceneObject::~Svx3DSceneObject() noexcept
77 void Svx3DSceneObject::Create( SdrObject* pNewObj, SvxDrawPage* pNewPage )
79 SvxShape::Create( pNewObj, pNewPage );
80 mxPage = pNewPage;
84 uno::Any SAL_CALL Svx3DSceneObject::queryAggregation( const uno::Type & rType )
86 uno::Any aAny;
88 QUERYINT( drawing::XShapes );
89 else QUERYINT( container::XIndexAccess );
90 else QUERYINT( container::XElementAccess );
91 else
92 return SvxShape::queryAggregation( rType );
94 return aAny;
97 uno::Any SAL_CALL Svx3DSceneObject::queryInterface( const uno::Type & rType )
99 return SvxShape::queryInterface( rType );
102 // XTypeProvider
104 uno::Sequence< sal_Int8 > SAL_CALL Svx3DSceneObject::getImplementationId()
106 return css::uno::Sequence<sal_Int8>();
110 void SAL_CALL Svx3DSceneObject::add( const Reference< drawing::XShape >& xShape )
112 SolarMutexGuard aGuard;
114 SvxShape* pShape = comphelper::getUnoTunnelImplementation<SvxShape>( xShape );
116 if(!HasSdrObject() || !mxPage.is() || pShape == nullptr || nullptr != pShape->GetSdrObject() )
117 throw uno::RuntimeException();
119 SdrObject* pSdrShape = mxPage->CreateSdrObject_( xShape );
120 if( dynamic_cast<const E3dObject* >(pSdrShape) != nullptr )
122 GetSdrObject()->GetSubList()->NbcInsertObject( pSdrShape );
123 pShape->Create(pSdrShape, mxPage.get());
125 else
127 SdrObject::Free( pSdrShape );
128 throw uno::RuntimeException();
131 GetSdrObject()->getSdrModelFromSdrObject().SetChanged();
135 void SAL_CALL Svx3DSceneObject::remove( const Reference< drawing::XShape >& xShape )
137 SolarMutexGuard aGuard;
139 SdrObject* pSdrShape = SdrObject::getSdrObjectFromXShape( xShape );
141 if(!HasSdrObject() || !pSdrShape ||
142 pSdrShape->getParentSdrObjectFromSdrObject() != GetSdrObject())
143 throw uno::RuntimeException();
145 SdrObjList& rList = *pSdrShape->getParentSdrObjListFromSdrObject();
147 const size_t nObjCount = rList.GetObjCount();
148 size_t nObjNum = 0;
149 while( nObjNum < nObjCount )
151 if(rList.GetObj( nObjNum ) == pSdrShape )
152 break;
153 nObjNum++;
156 if( nObjNum < nObjCount )
158 SdrObject* pObject = rList.NbcRemoveObject( nObjNum );
159 SdrObject::Free( pObject );
161 else
163 SAL_WARN( "svx", "Fatality! SdrObject is not belonging to its SdrObjList! [CL]" );
168 sal_Int32 SAL_CALL Svx3DSceneObject::getCount()
170 SolarMutexGuard aGuard;
172 sal_Int32 nRetval = 0;
174 if(HasSdrObject() && dynamic_cast<const E3dScene* >(GetSdrObject()) != nullptr && GetSdrObject()->GetSubList())
175 nRetval = GetSdrObject()->GetSubList()->GetObjCount();
176 return nRetval;
180 uno::Any SAL_CALL Svx3DSceneObject::getByIndex( sal_Int32 Index )
182 SolarMutexGuard aGuard;
184 if( !HasSdrObject() || GetSdrObject()->GetSubList() == nullptr )
185 throw uno::RuntimeException();
187 if( Index<0 || GetSdrObject()->GetSubList()->GetObjCount() <= o3tl::make_unsigned(Index) )
188 throw lang::IndexOutOfBoundsException();
190 SdrObject* pDestObj = GetSdrObject()->GetSubList()->GetObj( Index );
191 if(pDestObj == nullptr)
192 throw lang::IndexOutOfBoundsException();
194 Reference< drawing::XShape > xShape( pDestObj->getUnoShape(), uno::UNO_QUERY );
195 return uno::Any(xShape);
199 // css::container::XElementAccess
201 uno::Type SAL_CALL Svx3DSceneObject::getElementType()
203 return cppu::UnoType<drawing::XShape>::get();
207 sal_Bool SAL_CALL Svx3DSceneObject::hasElements()
209 SolarMutexGuard aGuard;
211 return HasSdrObject() && GetSdrObject()->GetSubList() && (GetSdrObject()->GetSubList()->GetObjCount() > 0);
215 static bool ConvertHomogenMatrixToObject( E3dObject* pObject, const Any& rValue )
217 drawing::HomogenMatrix aMat;
218 if( rValue >>= aMat )
220 pObject->SetTransform(basegfx::utils::UnoHomogenMatrixToB3DHomMatrix(aMat));
221 return true;
223 return false;
226 static void ConvertObjectToHomogenMatric( E3dObject const * pObject, Any& rValue )
228 drawing::HomogenMatrix aHomMat;
229 const basegfx::B3DHomMatrix& rMat = pObject->GetTransform();
230 basegfx::utils::B3DHomMatrixToUnoHomogenMatrix(rMat, aHomMat);
231 rValue <<= aHomMat;
234 namespace {
236 struct ImpRememberTransAndRect
238 basegfx::B3DHomMatrix maMat;
239 tools::Rectangle maRect;
244 bool Svx3DSceneObject::setPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue )
246 switch( pProperty->nWID )
248 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
250 // patch transformation matrix to the object
251 if( ConvertHomogenMatrixToObject( static_cast< E3dObject* >( GetSdrObject() ), rValue ) )
252 return true;
253 break;
255 case OWN_ATTR_3D_VALUE_CAMERA_GEOMETRY:
257 // set CameraGeometry at scene
258 E3dScene* pScene = static_cast< E3dScene* >( GetSdrObject() );
259 drawing::CameraGeometry aCamGeo;
261 if(rValue >>= aCamGeo)
263 basegfx::B3DPoint aVRP(aCamGeo.vrp.PositionX, aCamGeo.vrp.PositionY, aCamGeo.vrp.PositionZ);
264 basegfx::B3DVector aVPN(aCamGeo.vpn.DirectionX, aCamGeo.vpn.DirectionY, aCamGeo.vpn.DirectionZ);
265 basegfx::B3DVector aVUP(aCamGeo.vup.DirectionX, aCamGeo.vup.DirectionY, aCamGeo.vup.DirectionZ);
267 // rescue scene transformation
268 ImpRememberTransAndRect aSceneTAR;
269 aSceneTAR.maMat = pScene->GetTransform();
270 aSceneTAR.maRect = pScene->GetSnapRect();
272 // rescue object transformations
273 SdrObjListIter aIter(pScene->GetSubList(), SdrIterMode::DeepWithGroups);
274 std::vector<basegfx::B3DHomMatrix*> aObjTrans;
275 while(aIter.IsMore())
277 E3dObject* p3DObj = static_cast<E3dObject*>(aIter.Next());
278 basegfx::B3DHomMatrix* pNew = new basegfx::B3DHomMatrix;
279 *pNew = p3DObj->GetTransform();
280 aObjTrans.push_back(pNew);
283 // reset object transformations
284 aIter.Reset();
285 while(aIter.IsMore())
287 E3dObject* p3DObj = static_cast<E3dObject*>(aIter.Next());
288 p3DObj->NbcSetTransform(basegfx::B3DHomMatrix());
291 // reset scene transformation and make a complete recalc
292 pScene->NbcSetTransform(basegfx::B3DHomMatrix());
294 // fill old camera from new parameters
295 Camera3D aCam(pScene->GetCamera());
296 const basegfx::B3DRange& rVolume = pScene->GetBoundVolume();
297 double fW = rVolume.getWidth();
298 double fH = rVolume.getHeight();
300 const SfxItemSet& rSceneSet = pScene->GetMergedItemSet();
301 double fCamPosZ =
302 static_cast<double>(rSceneSet.Get(SDRATTR_3DSCENE_DISTANCE).GetValue());
303 double fCamFocal =
304 static_cast<double>(rSceneSet.Get(SDRATTR_3DSCENE_FOCAL_LENGTH).GetValue());
306 aCam.SetAutoAdjustProjection(false);
307 aCam.SetViewWindow(- fW / 2, - fH / 2, fW, fH);
308 basegfx::B3DPoint aLookAt;
309 basegfx::B3DPoint aCamPos(0.0, 0.0, fCamPosZ);
310 aCam.SetPosAndLookAt(aCamPos, aLookAt);
311 aCam.SetFocalLength(fCamFocal / 100.0);
312 aCam.SetDeviceWindow(tools::Rectangle(0, 0, static_cast<tools::Long>(fW), static_cast<tools::Long>(fH)));
314 // set at scene
315 pScene->SetCamera(aCam);
317 // #91047# use imported VRP, VPN and VUP (if used)
318 bool bVRPUsed(!aVRP.equal(basegfx::B3DPoint(0.0, 0.0, 1.0)));
319 bool bVPNUsed(!aVPN.equal(basegfx::B3DVector(0.0, 0.0, 1.0)));
320 bool bVUPUsed(!aVUP.equal(basegfx::B3DVector(0.0, 1.0, 0.0)));
322 if(bVRPUsed || bVPNUsed || bVUPUsed)
324 pScene->GetCameraSet().SetViewportValues(aVRP, aVPN, aVUP);
327 // set object transformations again at objects
328 aIter.Reset();
329 sal_uInt32 nIndex(0);
330 while(aIter.IsMore())
332 E3dObject* p3DObj = static_cast<E3dObject*>(aIter.Next());
333 basegfx::B3DHomMatrix* pMat = aObjTrans[nIndex++];
334 p3DObj->NbcSetTransform(*pMat);
335 delete pMat;
338 // set scene transformation again at scene
339 pScene->NbcSetTransform(aSceneTAR.maMat);
340 pScene->NbcSetSnapRect(aSceneTAR.maRect);
342 return true;
344 break;
346 default:
347 return SvxShape::setPropertyValueImpl(rName, pProperty, rValue);
350 throw IllegalArgumentException();
354 bool Svx3DSceneObject::getPropertyValueImpl(const OUString& rName, const SfxItemPropertyMapEntry* pProperty,
355 css::uno::Any& rValue)
357 switch( pProperty->nWID )
359 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
361 // patch object to a homogeneous 4x4 matrix
362 ConvertObjectToHomogenMatric( static_cast< E3dObject* >( GetSdrObject() ), rValue );
363 break;
365 case OWN_ATTR_3D_VALUE_CAMERA_GEOMETRY:
367 // get CameraGeometry from scene
368 E3dScene* pScene = static_cast< E3dScene* >( GetSdrObject() );
369 drawing::CameraGeometry aCamGeo;
371 // fill Vectors from scene camera
372 B3dCamera& aCameraSet = pScene->GetCameraSet();
373 basegfx::B3DPoint aVRP(aCameraSet.GetVRP());
374 basegfx::B3DVector aVPN(aCameraSet.GetVPN());
375 basegfx::B3DVector aVUP(aCameraSet.GetVUV());
377 // transfer to structure
378 aCamGeo.vrp.PositionX = aVRP.getX();
379 aCamGeo.vrp.PositionY = aVRP.getY();
380 aCamGeo.vrp.PositionZ = aVRP.getZ();
381 aCamGeo.vpn.DirectionX = aVPN.getX();
382 aCamGeo.vpn.DirectionY = aVPN.getY();
383 aCamGeo.vpn.DirectionZ = aVPN.getZ();
384 aCamGeo.vup.DirectionX = aVUP.getX();
385 aCamGeo.vup.DirectionY = aVUP.getY();
386 aCamGeo.vup.DirectionZ = aVUP.getZ();
388 rValue <<= aCamGeo;
389 break;
391 default:
392 return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
395 return true;
398 // css::lang::XServiceInfo
399 uno::Sequence< OUString > SAL_CALL Svx3DSceneObject::getSupportedServiceNames()
401 return comphelper::concatSequences(
402 SvxShape::getSupportedServiceNames(),
403 std::initializer_list<std::u16string_view>{ u"com.sun.star.drawing.Shape3DScene" });
406 Svx3DCubeObject::Svx3DCubeObject(SdrObject* pObj)
407 : SvxShape( pObj, getSvxMapProvider().GetMap(SVXMAP_3DCUBEOBJECT), getSvxMapProvider().GetPropertySet(SVXMAP_3DCUBEOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
411 Svx3DCubeObject::~Svx3DCubeObject() noexcept
415 bool Svx3DCubeObject::setPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue )
417 SolarMutexGuard aGuard;
419 switch( pProperty->nWID )
421 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
423 // pack transformationmatrix to the object
424 if( ConvertHomogenMatrixToObject( static_cast< E3dObject* >( GetSdrObject() ), rValue ) )
425 return true;
426 break;
428 case OWN_ATTR_3D_VALUE_POSITION:
430 // pack position to the object
431 drawing::Position3D aUnoPos;
432 if( rValue >>= aUnoPos )
434 basegfx::B3DPoint aPos(aUnoPos.PositionX, aUnoPos.PositionY, aUnoPos.PositionZ);
435 static_cast< E3dCubeObj* >( GetSdrObject() )->SetCubePos(aPos);
436 return true;
438 break;
440 case OWN_ATTR_3D_VALUE_SIZE:
442 // pack size to the object
443 drawing::Direction3D aDirection;
444 if( rValue >>= aDirection )
446 basegfx::B3DVector aSize(aDirection.DirectionX, aDirection.DirectionY, aDirection.DirectionZ);
447 static_cast< E3dCubeObj* >( GetSdrObject() )->SetCubeSize(aSize);
448 return true;
450 break;
452 case OWN_ATTR_3D_VALUE_POS_IS_CENTER:
454 bool bNew = false;
455 // pack sal_Bool bPosIsCenter to the object
456 if( rValue >>= bNew )
458 static_cast< E3dCubeObj* >( GetSdrObject() )->SetPosIsCenter(bNew);
459 return true;
461 break;
463 default:
464 return SvxShape::setPropertyValueImpl( rName, pProperty, rValue );
467 throw IllegalArgumentException();
470 bool Svx3DCubeObject::getPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, css::uno::Any& rValue )
472 switch( pProperty->nWID )
474 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
476 // pack transformation to a homogeneous matrix
477 ConvertObjectToHomogenMatric( static_cast< E3dObject* >( GetSdrObject() ), rValue );
478 break;
480 case OWN_ATTR_3D_VALUE_POSITION:
482 // pack position
483 const basegfx::B3DPoint& rPos = static_cast<E3dCubeObj*>(GetSdrObject())->GetCubePos();
484 drawing::Position3D aPos;
486 aPos.PositionX = rPos.getX();
487 aPos.PositionY = rPos.getY();
488 aPos.PositionZ = rPos.getZ();
490 rValue <<= aPos;
491 break;
493 case OWN_ATTR_3D_VALUE_SIZE:
495 // pack size
496 const basegfx::B3DVector& rSize = static_cast<E3dCubeObj*>(GetSdrObject())->GetCubeSize();
497 drawing::Direction3D aDir;
499 aDir.DirectionX = rSize.getX();
500 aDir.DirectionY = rSize.getY();
501 aDir.DirectionZ = rSize.getZ();
503 rValue <<= aDir;
504 break;
506 case OWN_ATTR_3D_VALUE_POS_IS_CENTER:
508 rValue <<= static_cast<E3dCubeObj*>(GetSdrObject())->GetPosIsCenter();
509 break;
511 default:
512 return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
515 return true;
518 // css::lang::XServiceInfo
519 uno::Sequence< OUString > SAL_CALL Svx3DCubeObject::getSupportedServiceNames()
521 return comphelper::concatSequences(
522 SvxShape::getSupportedServiceNames(),
523 std::initializer_list<std::u16string_view>{ u"com.sun.star.drawing.Shape3D",
524 u"com.sun.star.drawing.Shape3DCube" });
527 Svx3DSphereObject::Svx3DSphereObject(SdrObject* pObj)
528 : SvxShape( pObj, getSvxMapProvider().GetMap(SVXMAP_3DSPHEREOBJECT), getSvxMapProvider().GetPropertySet(SVXMAP_3DSPHEREOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
532 Svx3DSphereObject::~Svx3DSphereObject() noexcept
536 bool Svx3DSphereObject::setPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue )
538 switch( pProperty->nWID )
540 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
542 // pack transformation matrix to the object
543 if( ConvertHomogenMatrixToObject( static_cast< E3dObject* >( GetSdrObject() ), rValue ) )
544 return true;
545 break;
548 case OWN_ATTR_3D_VALUE_POSITION:
550 // pack position to the object
551 drawing::Position3D aUnoPos;
552 if( rValue >>= aUnoPos )
554 basegfx::B3DPoint aPos(aUnoPos.PositionX, aUnoPos.PositionY, aUnoPos.PositionZ);
555 static_cast<E3dSphereObj*>(GetSdrObject())->SetCenter(aPos);
556 return true;
558 break;
561 case OWN_ATTR_3D_VALUE_SIZE:
563 // pack size to the object
564 drawing::Direction3D aDir;
565 if( rValue >>= aDir )
567 basegfx::B3DVector aPos(aDir.DirectionX, aDir.DirectionY, aDir.DirectionZ);
568 static_cast<E3dSphereObj*>(GetSdrObject())->SetSize(aPos);
569 return true;
571 break;
573 default:
574 return SvxShape::setPropertyValueImpl( rName, pProperty, rValue );
577 throw IllegalArgumentException();
580 bool Svx3DSphereObject::getPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, css::uno::Any& rValue )
582 switch( pProperty->nWID )
584 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
586 // pack transformation to a homogeneous matrix
587 ConvertObjectToHomogenMatric( static_cast< E3dObject* >( GetSdrObject() ), rValue );
588 break;
590 case OWN_ATTR_3D_VALUE_POSITION:
592 // pack position
593 const basegfx::B3DPoint& rPos = static_cast<E3dSphereObj*>(GetSdrObject())->Center();
594 drawing::Position3D aPos;
596 aPos.PositionX = rPos.getX();
597 aPos.PositionY = rPos.getY();
598 aPos.PositionZ = rPos.getZ();
600 rValue <<= aPos;
601 break;
603 case OWN_ATTR_3D_VALUE_SIZE:
605 // pack size
606 const basegfx::B3DVector& rSize = static_cast<E3dSphereObj*>(GetSdrObject())->Size();
607 drawing::Direction3D aDir;
609 aDir.DirectionX = rSize.getX();
610 aDir.DirectionY = rSize.getY();
611 aDir.DirectionZ = rSize.getZ();
613 rValue <<= aDir;
614 break;
616 default:
617 return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
620 return true;
623 // css::lang::XServiceInfo
624 uno::Sequence< OUString > SAL_CALL Svx3DSphereObject::getSupportedServiceNames()
626 return comphelper::concatSequences(
627 SvxShape::getSupportedServiceNames(),
628 std::initializer_list<std::u16string_view>{ u"com.sun.star.drawing.Shape3D",
629 u"com.sun.star.drawing.Shape3DSphere" });
632 Svx3DLatheObject::Svx3DLatheObject(SdrObject* pObj)
633 : SvxShape( pObj, getSvxMapProvider().GetMap(SVXMAP_3DLATHEOBJECT), getSvxMapProvider().GetPropertySet(SVXMAP_3DLATHEOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
637 Svx3DLatheObject::~Svx3DLatheObject() noexcept
641 static bool PolyPolygonShape3D_to_B3dPolyPolygon(
642 const Any& rValue,
643 basegfx::B3DPolyPolygon& rResultPolygon,
644 bool bCorrectPolygon)
646 drawing::PolyPolygonShape3D aSourcePolyPolygon;
647 if( !(rValue >>= aSourcePolyPolygon) )
648 return false;
650 sal_Int32 nOuterSequenceCount = aSourcePolyPolygon.SequenceX.getLength();
651 if(nOuterSequenceCount != aSourcePolyPolygon.SequenceY.getLength() || nOuterSequenceCount != aSourcePolyPolygon.SequenceZ.getLength())
652 return false;
654 drawing::DoubleSequence* pInnerSequenceX = aSourcePolyPolygon.SequenceX.getArray();
655 drawing::DoubleSequence* pInnerSequenceY = aSourcePolyPolygon.SequenceY.getArray();
656 drawing::DoubleSequence* pInnerSequenceZ = aSourcePolyPolygon.SequenceZ.getArray();
657 for(sal_Int32 a(0);a<nOuterSequenceCount;a++)
659 sal_Int32 nInnerSequenceCount = pInnerSequenceX->getLength();
660 if(nInnerSequenceCount != pInnerSequenceY->getLength() || nInnerSequenceCount != pInnerSequenceZ->getLength())
662 return false;
664 basegfx::B3DPolygon aNewPolygon;
665 double* pArrayX = pInnerSequenceX->getArray();
666 double* pArrayY = pInnerSequenceY->getArray();
667 double* pArrayZ = pInnerSequenceZ->getArray();
668 for(sal_Int32 b(0);b<nInnerSequenceCount;b++)
670 aNewPolygon.append(basegfx::B3DPoint(*pArrayX++,*pArrayY++,*pArrayZ++));
672 pInnerSequenceX++;
673 pInnerSequenceY++;
674 pInnerSequenceZ++;
676 // #i101520# correction is needed for imported polygons of old format,
677 // see callers
678 if(bCorrectPolygon)
680 basegfx::utils::checkClosed(aNewPolygon);
683 rResultPolygon.append(aNewPolygon);
685 return true;
688 static void B3dPolyPolygon_to_PolyPolygonShape3D( const basegfx::B3DPolyPolygon& rSourcePolyPolygon, Any& rValue )
690 drawing::PolyPolygonShape3D aRetval;
691 aRetval.SequenceX.realloc(rSourcePolyPolygon.count());
692 aRetval.SequenceY.realloc(rSourcePolyPolygon.count());
693 aRetval.SequenceZ.realloc(rSourcePolyPolygon.count());
694 drawing::DoubleSequence* pOuterSequenceX = aRetval.SequenceX.getArray();
695 drawing::DoubleSequence* pOuterSequenceY = aRetval.SequenceY.getArray();
696 drawing::DoubleSequence* pOuterSequenceZ = aRetval.SequenceZ.getArray();
697 for(sal_uInt32 a(0);a<rSourcePolyPolygon.count();a++)
699 const basegfx::B3DPolygon& aPoly(rSourcePolyPolygon.getB3DPolygon(a));
700 sal_Int32 nPointCount(aPoly.count());
701 if(aPoly.isClosed()) nPointCount++;
702 pOuterSequenceX->realloc(nPointCount);
703 pOuterSequenceY->realloc(nPointCount);
704 pOuterSequenceZ->realloc(nPointCount);
705 double* pInnerSequenceX = pOuterSequenceX->getArray();
706 double* pInnerSequenceY = pOuterSequenceY->getArray();
707 double* pInnerSequenceZ = pOuterSequenceZ->getArray();
708 for(sal_uInt32 b(0);b<aPoly.count();b++)
710 const basegfx::B3DPoint aPoint(aPoly.getB3DPoint(b));
711 *pInnerSequenceX++ = aPoint.getX();
712 *pInnerSequenceY++ = aPoint.getY();
713 *pInnerSequenceZ++ = aPoint.getZ();
715 if(aPoly.isClosed())
717 const basegfx::B3DPoint aPoint(aPoly.getB3DPoint(0));
718 *pInnerSequenceX++ = aPoint.getX();
719 *pInnerSequenceY++ = aPoint.getY();
720 *pInnerSequenceZ++ = aPoint.getZ();
722 pOuterSequenceX++;
723 pOuterSequenceY++;
724 pOuterSequenceZ++;
726 rValue <<= aRetval;
729 bool Svx3DLatheObject::setPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue )
731 switch( pProperty->nWID )
733 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
735 // pack transformation matrix to the object
736 if( ConvertHomogenMatrixToObject( static_cast< E3dObject* >( GetSdrObject() ), rValue ) )
737 return true;
738 break;
740 case OWN_ATTR_3D_VALUE_POLYPOLYGON3D:
742 // pack polygon definition to the object
743 basegfx::B3DPolyPolygon aNewB3DPolyPolygon;
745 // #i101520# Probably imported
746 if( PolyPolygonShape3D_to_B3dPolyPolygon( rValue, aNewB3DPolyPolygon, true ) )
748 // #105127# SetPolyPoly3D sets the Svx3DVerticalSegmentsItem to the number
749 // of points of the polygon. Thus, value gets lost. To avoid this, rescue
750 // item here and re-set after setting the polygon.
751 const sal_uInt32 nPrevVerticalSegs(static_cast<E3dLatheObj*>(GetSdrObject())->GetVerticalSegments());
753 // set polygon
754 const basegfx::B3DHomMatrix aIdentity;
755 const basegfx::B2DPolyPolygon aB2DPolyPolygon(basegfx::utils::createB2DPolyPolygonFromB3DPolyPolygon(aNewB3DPolyPolygon, aIdentity));
756 static_cast<E3dLatheObj*>(GetSdrObject())->SetPolyPoly2D(aB2DPolyPolygon);
757 const sal_uInt32 nPostVerticalSegs(static_cast<E3dLatheObj*>(GetSdrObject())->GetVerticalSegments());
759 if(nPrevVerticalSegs != nPostVerticalSegs)
761 // restore the vertical segment count
762 static_cast<E3dLatheObj*>(GetSdrObject())->SetMergedItem(makeSvx3DVerticalSegmentsItem(nPrevVerticalSegs));
764 return true;
766 break;
768 default:
769 return SvxShape::setPropertyValueImpl( rName, pProperty, rValue );
772 throw IllegalArgumentException();
775 bool Svx3DLatheObject::getPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, css::uno::Any& rValue )
777 switch( pProperty->nWID )
779 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
781 // pack transformation to a homogeneous matrix
782 drawing::HomogenMatrix aHomMat;
783 basegfx::B3DHomMatrix aMat = static_cast<E3dObject*>(GetSdrObject())->GetTransform();
784 basegfx::utils::B3DHomMatrixToUnoHomogenMatrix(aMat, aHomMat);
785 rValue <<= aHomMat;
786 break;
788 case OWN_ATTR_3D_VALUE_POLYPOLYGON3D:
790 const basegfx::B2DPolyPolygon& rPolyPoly = static_cast<E3dLatheObj*>(GetSdrObject())->GetPolyPoly2D();
791 const basegfx::B3DPolyPolygon aB3DPolyPolygon(basegfx::utils::createB3DPolyPolygonFromB2DPolyPolygon(rPolyPoly));
793 B3dPolyPolygon_to_PolyPolygonShape3D(aB3DPolyPolygon, rValue);
794 break;
796 default:
797 return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
800 return true;
803 // css::lang::XServiceInfo
804 uno::Sequence< OUString > SAL_CALL Svx3DLatheObject::getSupportedServiceNames()
806 return comphelper::concatSequences(
807 SvxShape::getSupportedServiceNames(),
808 std::initializer_list<std::u16string_view>{ u"com.sun.star.drawing.Shape3D",
809 u"com.sun.star.drawing.Shape3DLathe" });
812 Svx3DExtrudeObject::Svx3DExtrudeObject(SdrObject* pObj)
813 : SvxShape( pObj, getSvxMapProvider().GetMap(SVXMAP_3DEXTRUDEOBJECT), getSvxMapProvider().GetPropertySet(SVXMAP_3DEXTRUDEOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
817 Svx3DExtrudeObject::~Svx3DExtrudeObject() noexcept
821 bool Svx3DExtrudeObject::setPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue )
823 switch( pProperty->nWID )
825 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
827 // pack transformation matrix to the object
828 if( ConvertHomogenMatrixToObject( static_cast< E3dObject* >( GetSdrObject() ), rValue ) )
829 return true;
830 break;
833 case OWN_ATTR_3D_VALUE_POLYPOLYGON3D:
835 // pack polygon definition to the object
836 basegfx::B3DPolyPolygon aNewB3DPolyPolygon;
838 // #i101520# Probably imported
839 if( PolyPolygonShape3D_to_B3dPolyPolygon( rValue, aNewB3DPolyPolygon, true ) )
841 // set polygon
842 const basegfx::B3DHomMatrix aIdentity;
843 const basegfx::B2DPolyPolygon aB2DPolyPolygon(basegfx::utils::createB2DPolyPolygonFromB3DPolyPolygon(aNewB3DPolyPolygon, aIdentity));
844 static_cast<E3dExtrudeObj*>(GetSdrObject())->SetExtrudePolygon(aB2DPolyPolygon);
845 return true;
847 break;
849 default:
850 return SvxShape::setPropertyValueImpl( rName, pProperty, rValue );
853 throw IllegalArgumentException();
856 bool Svx3DExtrudeObject::getPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, css::uno::Any& rValue )
858 switch( pProperty->nWID )
860 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
862 // pack transformation to a homogeneous matrix
863 drawing::HomogenMatrix aHomMat;
864 basegfx::B3DHomMatrix aMat = static_cast<E3dObject*>(GetSdrObject())->GetTransform();
865 basegfx::utils::B3DHomMatrixToUnoHomogenMatrix(aMat, aHomMat);
866 rValue <<= aHomMat;
867 break;
870 case OWN_ATTR_3D_VALUE_POLYPOLYGON3D:
872 // pack polygon definition
873 const basegfx::B2DPolyPolygon& rPolyPoly = static_cast<E3dExtrudeObj*>(GetSdrObject())->GetExtrudePolygon();
874 const basegfx::B3DPolyPolygon aB3DPolyPolygon(basegfx::utils::createB3DPolyPolygonFromB2DPolyPolygon(rPolyPoly));
876 B3dPolyPolygon_to_PolyPolygonShape3D(aB3DPolyPolygon, rValue);
877 break;
879 default:
880 return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
883 return true;
886 // css::lang::XServiceInfo
887 uno::Sequence< OUString > SAL_CALL Svx3DExtrudeObject::getSupportedServiceNames()
889 return comphelper::concatSequences(
890 SvxShape::getSupportedServiceNames(),
891 std::initializer_list<std::u16string_view>{ u"com.sun.star.drawing.Shape3D",
892 u"com.sun.star.drawing.Shape3DExtrude" });
895 Svx3DPolygonObject::Svx3DPolygonObject(SdrObject* pObj)
896 : SvxShape( pObj, getSvxMapProvider().GetMap(SVXMAP_3DPOLYGONOBJECT), getSvxMapProvider().GetPropertySet(SVXMAP_3DPOLYGONOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
900 Svx3DPolygonObject::~Svx3DPolygonObject() noexcept
904 bool Svx3DPolygonObject::setPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue )
906 switch( pProperty->nWID )
908 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
910 // pack transformation matrix to the object
911 if( ConvertHomogenMatrixToObject( static_cast< E3dObject* >( GetSdrObject() ), rValue ) )
912 return true;
913 break;
916 case OWN_ATTR_3D_VALUE_POLYPOLYGON3D:
918 // pack polygon definition to the object
919 basegfx::B3DPolyPolygon aNewB3DPolyPolygon;
921 // #i101520# Direct API data (e.g. from chart)
922 if( PolyPolygonShape3D_to_B3dPolyPolygon( rValue, aNewB3DPolyPolygon, false ) )
924 // set polygon
925 static_cast<E3dPolygonObj*>(GetSdrObject())->SetPolyPolygon3D(aNewB3DPolyPolygon);
926 return true;
928 break;
930 case OWN_ATTR_3D_VALUE_NORMALSPOLYGON3D:
932 // pack perpendicular definition to the object
933 basegfx::B3DPolyPolygon aNewB3DPolyPolygon;
935 // #i101520# Direct API data (e.g. from chart)
936 if( PolyPolygonShape3D_to_B3dPolyPolygon( rValue, aNewB3DPolyPolygon, false ) )
938 // set polygon
939 static_cast<E3dPolygonObj*>(GetSdrObject())->SetPolyNormals3D(aNewB3DPolyPolygon);
940 return true;
942 break;
944 case OWN_ATTR_3D_VALUE_TEXTUREPOLYGON3D:
946 // pack texture definition to the object
947 basegfx::B3DPolyPolygon aNewB3DPolyPolygon;
949 // #i101520# Direct API data (e.g. from chart)
950 if( PolyPolygonShape3D_to_B3dPolyPolygon( rValue, aNewB3DPolyPolygon, false ) )
952 // set polygon
953 const basegfx::B3DHomMatrix aIdentity;
954 const basegfx::B2DPolyPolygon aB2DPolyPolygon(basegfx::utils::createB2DPolyPolygonFromB3DPolyPolygon(aNewB3DPolyPolygon, aIdentity));
955 static_cast<E3dPolygonObj*>(GetSdrObject())->SetPolyTexture2D(aB2DPolyPolygon);
956 return true;
958 break;
960 case OWN_ATTR_3D_VALUE_LINEONLY:
962 bool bNew = false;
963 if( rValue >>= bNew )
965 static_cast<E3dPolygonObj*>(GetSdrObject())->SetLineOnly(bNew);
966 return true;
968 break;
970 default:
971 return SvxShape::setPropertyValueImpl( rName, pProperty, rValue );
974 throw IllegalArgumentException();
977 bool Svx3DPolygonObject::getPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, css::uno::Any& rValue )
979 switch( pProperty->nWID )
981 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
983 ConvertObjectToHomogenMatric( static_cast< E3dObject* >( GetSdrObject() ), rValue );
984 break;
987 case OWN_ATTR_3D_VALUE_POLYPOLYGON3D:
989 B3dPolyPolygon_to_PolyPolygonShape3D(static_cast<E3dPolygonObj*>(GetSdrObject())->GetPolyPolygon3D(),rValue);
990 break;
993 case OWN_ATTR_3D_VALUE_NORMALSPOLYGON3D:
995 B3dPolyPolygon_to_PolyPolygonShape3D(static_cast<E3dPolygonObj*>(GetSdrObject())->GetPolyNormals3D(),rValue);
996 break;
999 case OWN_ATTR_3D_VALUE_TEXTUREPOLYGON3D:
1001 // pack texture definition
1002 const basegfx::B2DPolyPolygon& rPolyPoly = static_cast<E3dPolygonObj*>(GetSdrObject())->GetPolyTexture2D();
1003 const basegfx::B3DPolyPolygon aB3DPolyPolygon(basegfx::utils::createB3DPolyPolygonFromB2DPolyPolygon(rPolyPoly));
1005 B3dPolyPolygon_to_PolyPolygonShape3D(aB3DPolyPolygon,rValue);
1006 break;
1009 case OWN_ATTR_3D_VALUE_LINEONLY:
1011 rValue <<= static_cast<E3dPolygonObj*>(GetSdrObject())->GetLineOnly();
1012 break;
1015 default:
1016 return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
1019 return true;
1022 // css::lang::XServiceInfo
1023 uno::Sequence< OUString > SAL_CALL Svx3DPolygonObject::getSupportedServiceNames()
1025 return comphelper::concatSequences(
1026 SvxShape::getSupportedServiceNames(),
1027 std::initializer_list<std::u16string_view>{ u"com.sun.star.drawing.Shape3D",
1028 u"com.sun.star.drawing.Shape3DPolygon" });
1031 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */