Adjust includes
[LibreOffice.git] / svx / source / unodraw / unoshap3.cxx
blobdb8fbdd03dd4d553dd01f1a792e994b96ccf5ef3
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 <com/sun/star/drawing/HomogenMatrix.hpp>
21 #include <com/sun/star/drawing/Position3D.hpp>
22 #include <com/sun/star/drawing/Direction3D.hpp>
23 #include <com/sun/star/drawing/DoubleSequence.hpp>
24 #include <com/sun/star/drawing/CameraGeometry.hpp>
25 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
26 #include <vcl/svapp.hxx>
27 #include <comphelper/servicehelper.hxx>
28 #include <comphelper/serviceinfohelper.hxx>
30 #include <svx/svdpool.hxx>
31 #include <svx/svditer.hxx>
32 #include <svx/unoshape.hxx>
33 #include <svx/unopage.hxx>
34 #include <editeng/unoprnms.hxx>
35 #include <svx/globl3d.hxx>
36 #include <svx/cube3d.hxx>
37 #include <svx/sphere3d.hxx>
38 #include <svx/lathe3d.hxx>
39 #include <svx/extrud3d.hxx>
40 #include <svx/polygn3d.hxx>
41 #include <svx/unoshprp.hxx>
42 #include <svx/svdmodel.hxx>
43 #include <svx/scene3d.hxx>
44 #include <basegfx/polygon/b3dpolygon.hxx>
45 #include <basegfx/polygon/b3dpolygontools.hxx>
46 #include <com/sun/star/drawing/PolyPolygonShape3D.hpp>
47 #include <basegfx/polygon/b2dpolypolygontools.hxx>
48 #include "shapeimpl.hxx"
50 using namespace ::cppu;
51 using namespace ::com::sun::star;
52 using namespace ::com::sun::star::uno;
53 using namespace ::com::sun::star::lang;
54 using namespace ::com::sun::star::container;
56 #define QUERYINT( xint ) \
57 if( rType == cppu::UnoType<xint>::get() ) \
58 aAny <<= Reference< xint >(this)
60 Svx3DSceneObject::Svx3DSceneObject( SdrObject* pObj, SvxDrawPage* pDrawPage ) throw()
61 : SvxShape( pObj, getSvxMapProvider().GetMap(SVXMAP_3DSCENEOBJECT), getSvxMapProvider().GetPropertySet(SVXMAP_3DSCENEOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
62 , mxPage( pDrawPage )
67 Svx3DSceneObject::~Svx3DSceneObject() throw()
72 void Svx3DSceneObject::Create( SdrObject* pNewObj, SvxDrawPage* pNewPage )
74 SvxShape::Create( pNewObj, pNewPage );
75 mxPage = pNewPage;
79 uno::Any SAL_CALL Svx3DSceneObject::queryAggregation( const uno::Type & rType )
81 uno::Any aAny;
83 QUERYINT( drawing::XShapes );
84 else QUERYINT( container::XIndexAccess );
85 else QUERYINT( container::XElementAccess );
86 else
87 return SvxShape::queryAggregation( rType );
89 return aAny;
92 uno::Any SAL_CALL Svx3DSceneObject::queryInterface( const uno::Type & rType )
94 return SvxShape::queryInterface( rType );
97 void SAL_CALL Svx3DSceneObject::acquire() throw ( )
99 SvxShape::acquire();
102 void SAL_CALL Svx3DSceneObject::release() throw ( )
104 SvxShape::release();
107 // XTypeProvider
109 uno::Sequence< sal_Int8 > SAL_CALL Svx3DSceneObject::getImplementationId()
111 return css::uno::Sequence<sal_Int8>();
115 void SAL_CALL Svx3DSceneObject::add( const Reference< drawing::XShape >& xShape )
117 SolarMutexGuard aGuard;
119 SvxShape* pShape = SvxShape::getImplementation( xShape );
121 if(!mpObj.is() || !mxPage.is() || pShape == nullptr || nullptr != pShape->GetSdrObject() )
122 throw uno::RuntimeException();
124 SdrObject* pSdrShape = mxPage->CreateSdrObject_( xShape );
125 if( dynamic_cast<const E3dObject* >(pSdrShape) != nullptr )
127 mpObj->GetSubList()->NbcInsertObject( pSdrShape );
129 if(pShape)
130 pShape->Create( pSdrShape, mxPage.get() );
132 else
134 SdrObject::Free( pSdrShape );
135 throw uno::RuntimeException();
138 if( mpModel )
139 mpModel->SetChanged();
143 void SAL_CALL Svx3DSceneObject::remove( const Reference< drawing::XShape >& xShape )
145 SolarMutexGuard aGuard;
147 SvxShape* pShape = SvxShape::getImplementation( xShape );
149 if(!mpObj.is() || pShape == nullptr)
150 throw uno::RuntimeException();
152 SdrObject* pSdrShape = pShape->GetSdrObject();
153 if(pSdrShape == nullptr || pSdrShape->GetObjList()->GetOwnerObj() != mpObj.get())
155 throw uno::RuntimeException();
158 SdrObjList& rList = *pSdrShape->GetObjList();
160 const size_t nObjCount = rList.GetObjCount();
161 size_t nObjNum = 0;
162 while( nObjNum < nObjCount )
164 if(rList.GetObj( nObjNum ) == pSdrShape )
165 break;
166 nObjNum++;
169 if( nObjNum < nObjCount )
171 SdrObject* pObject = rList.NbcRemoveObject( nObjNum );
172 SdrObject::Free( pObject );
174 else
176 SAL_WARN( "svx", "Fatality! SdrObject is not belonging to its SdrObjList! [CL]" );
181 sal_Int32 SAL_CALL Svx3DSceneObject::getCount()
183 SolarMutexGuard aGuard;
185 sal_Int32 nRetval = 0;
187 if(mpObj.is() && dynamic_cast<const E3dScene* >(mpObj.get()) != nullptr && mpObj->GetSubList())
188 nRetval = mpObj->GetSubList()->GetObjCount();
189 return nRetval;
193 uno::Any SAL_CALL Svx3DSceneObject::getByIndex( sal_Int32 Index )
195 SolarMutexGuard aGuard;
197 if( !mpObj.is() || mpObj->GetSubList() == nullptr )
198 throw uno::RuntimeException();
200 if( Index<0 || mpObj->GetSubList()->GetObjCount() <= static_cast<size_t>(Index) )
201 throw lang::IndexOutOfBoundsException();
203 SdrObject* pDestObj = mpObj->GetSubList()->GetObj( Index );
204 if(pDestObj == nullptr)
205 throw lang::IndexOutOfBoundsException();
207 Reference< drawing::XShape > xShape( pDestObj->getUnoShape(), uno::UNO_QUERY );
208 return uno::Any(xShape);
212 // css::container::XElementAccess
214 uno::Type SAL_CALL Svx3DSceneObject::getElementType()
216 return cppu::UnoType<drawing::XShape>::get();
220 sal_Bool SAL_CALL Svx3DSceneObject::hasElements()
222 SolarMutexGuard aGuard;
224 return mpObj.is() && mpObj->GetSubList() && (mpObj->GetSubList()->GetObjCount() > 0);
228 static bool ConvertHomogenMatrixToObject( E3dObject* pObject, const Any& rValue )
230 drawing::HomogenMatrix m;
231 if( rValue >>= m )
233 basegfx::B3DHomMatrix aMat;
234 aMat.set(0, 0, m.Line1.Column1);
235 aMat.set(0, 1, m.Line1.Column2);
236 aMat.set(0, 2, m.Line1.Column3);
237 aMat.set(0, 3, m.Line1.Column4);
238 aMat.set(1, 0, m.Line2.Column1);
239 aMat.set(1, 1, m.Line2.Column2);
240 aMat.set(1, 2, m.Line2.Column3);
241 aMat.set(1, 3, m.Line2.Column4);
242 aMat.set(2, 0, m.Line3.Column1);
243 aMat.set(2, 1, m.Line3.Column2);
244 aMat.set(2, 2, m.Line3.Column3);
245 aMat.set(2, 3, m.Line3.Column4);
246 aMat.set(3, 0, m.Line4.Column1);
247 aMat.set(3, 1, m.Line4.Column2);
248 aMat.set(3, 2, m.Line4.Column3);
249 aMat.set(3, 3, m.Line4.Column4);
250 pObject->SetTransform(aMat);
251 return true;
253 return false;
256 static void ConvertObjectToHomogenMatric( E3dObject const * pObject, Any& rValue )
258 drawing::HomogenMatrix aHomMat;
259 const basegfx::B3DHomMatrix& rMat = pObject->GetTransform();
260 aHomMat.Line1.Column1 = rMat.get(0, 0);
261 aHomMat.Line1.Column2 = rMat.get(0, 1);
262 aHomMat.Line1.Column3 = rMat.get(0, 2);
263 aHomMat.Line1.Column4 = rMat.get(0, 3);
264 aHomMat.Line2.Column1 = rMat.get(1, 0);
265 aHomMat.Line2.Column2 = rMat.get(1, 1);
266 aHomMat.Line2.Column3 = rMat.get(1, 2);
267 aHomMat.Line2.Column4 = rMat.get(1, 3);
268 aHomMat.Line3.Column1 = rMat.get(2, 0);
269 aHomMat.Line3.Column2 = rMat.get(2, 1);
270 aHomMat.Line3.Column3 = rMat.get(2, 2);
271 aHomMat.Line3.Column4 = rMat.get(2, 3);
272 aHomMat.Line4.Column1 = rMat.get(3, 0);
273 aHomMat.Line4.Column2 = rMat.get(3, 1);
274 aHomMat.Line4.Column3 = rMat.get(3, 2);
275 aHomMat.Line4.Column4 = rMat.get(3, 3);
276 rValue <<= aHomMat;
280 struct ImpRememberTransAndRect
282 basegfx::B3DHomMatrix maMat;
283 tools::Rectangle maRect;
286 bool Svx3DSceneObject::setPropertyValueImpl( const OUString& rName, const SfxItemPropertySimpleEntry* pProperty, const css::uno::Any& rValue )
288 switch( pProperty->nWID )
290 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
292 // pach transformation matrix to the object
293 if( ConvertHomogenMatrixToObject( static_cast< E3dObject* >( mpObj.get() ), rValue ) )
294 return true;
295 break;
297 case OWN_ATTR_3D_VALUE_CAMERA_GEOMETRY:
299 // set CameraGeometry at scene
300 E3dScene* pScene = static_cast< E3dScene* >( mpObj.get() );
301 drawing::CameraGeometry aCamGeo;
303 if(rValue >>= aCamGeo)
305 basegfx::B3DPoint aVRP(aCamGeo.vrp.PositionX, aCamGeo.vrp.PositionY, aCamGeo.vrp.PositionZ);
306 basegfx::B3DVector aVPN(aCamGeo.vpn.DirectionX, aCamGeo.vpn.DirectionY, aCamGeo.vpn.DirectionZ);
307 basegfx::B3DVector aVUP(aCamGeo.vup.DirectionX, aCamGeo.vup.DirectionY, aCamGeo.vup.DirectionZ);
309 // rescue scene transformation
310 ImpRememberTransAndRect aSceneTAR;
311 aSceneTAR.maMat = pScene->GetTransform();
312 aSceneTAR.maRect = pScene->GetSnapRect();
314 // rescue object transformations
315 SdrObjListIter aIter(*pScene->GetSubList(), SdrIterMode::DeepWithGroups);
316 std::vector<basegfx::B3DHomMatrix*> aObjTrans;
317 while(aIter.IsMore())
319 E3dObject* p3DObj = static_cast<E3dObject*>(aIter.Next());
320 basegfx::B3DHomMatrix* pNew = new basegfx::B3DHomMatrix;
321 *pNew = p3DObj->GetTransform();
322 aObjTrans.push_back(pNew);
325 // reset object transformations
326 aIter.Reset();
327 while(aIter.IsMore())
329 E3dObject* p3DObj = static_cast<E3dObject*>(aIter.Next());
330 p3DObj->NbcSetTransform(basegfx::B3DHomMatrix());
333 // reset scene transformation and make a complete recalc
334 pScene->NbcSetTransform(basegfx::B3DHomMatrix());
336 // fill old camera from new parameters
337 Camera3D aCam(pScene->GetCamera());
338 const basegfx::B3DRange& rVolume = pScene->GetBoundVolume();
339 double fW = rVolume.getWidth();
340 double fH = rVolume.getHeight();
342 const SfxItemSet& rSceneSet = pScene->GetMergedItemSet();
343 double fCamPosZ =
344 (double)rSceneSet.Get(SDRATTR_3DSCENE_DISTANCE).GetValue();
345 double fCamFocal =
346 (double)rSceneSet.Get(SDRATTR_3DSCENE_FOCAL_LENGTH).GetValue();
348 aCam.SetAutoAdjustProjection(false);
349 aCam.SetViewWindow(- fW / 2, - fH / 2, fW, fH);
350 basegfx::B3DPoint aLookAt;
351 basegfx::B3DPoint aCamPos(0.0, 0.0, fCamPosZ);
352 aCam.SetPosAndLookAt(aCamPos, aLookAt);
353 aCam.SetFocalLength(fCamFocal / 100.0);
354 aCam.SetDefaults(basegfx::B3DPoint(0.0, 0.0, fCamPosZ), aLookAt);
355 aCam.SetDeviceWindow(tools::Rectangle(0, 0, (long)fW, (long)fH));
357 // set at scene
358 pScene->SetCamera(aCam);
360 // #91047# use imported VRP, VPN and VUP (if used)
361 bool bVRPUsed(!aVRP.equal(basegfx::B3DPoint(0.0, 0.0, 1.0)));
362 bool bVPNUsed(!aVPN.equal(basegfx::B3DVector(0.0, 0.0, 1.0)));
363 bool bVUPUsed(!aVUP.equal(basegfx::B3DVector(0.0, 1.0, 0.0)));
365 if(bVRPUsed || bVPNUsed || bVUPUsed)
367 pScene->GetCameraSet().SetViewportValues(aVRP, aVPN, aVUP);
370 // set object transformations again at objects
371 aIter.Reset();
372 sal_uInt32 nIndex(0);
373 while(aIter.IsMore())
375 E3dObject* p3DObj = static_cast<E3dObject*>(aIter.Next());
376 basegfx::B3DHomMatrix* pMat = aObjTrans[nIndex++];
377 p3DObj->NbcSetTransform(*pMat);
378 delete pMat;
381 // set scene transformation again at scene
382 pScene->NbcSetTransform(aSceneTAR.maMat);
383 pScene->NbcSetSnapRect(aSceneTAR.maRect);
385 return true;
387 break;
389 default:
390 return SvxShape::setPropertyValueImpl(rName, pProperty, rValue);
393 throw IllegalArgumentException();
397 bool Svx3DSceneObject::getPropertyValueImpl(const OUString& rName, const SfxItemPropertySimpleEntry* pProperty,
398 css::uno::Any& rValue)
400 switch( pProperty->nWID )
402 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
404 // pach object to a homogeneous 4x4 matrix
405 ConvertObjectToHomogenMatric( static_cast< E3dObject* >( mpObj.get() ), rValue );
406 break;
408 case OWN_ATTR_3D_VALUE_CAMERA_GEOMETRY:
410 // get CameraGeometry from scene
411 E3dScene* pScene = static_cast< E3dScene* >( mpObj.get() );
412 drawing::CameraGeometry aCamGeo;
414 // fill Vectors from scene camera
415 B3dCamera& aCameraSet = pScene->GetCameraSet();
416 basegfx::B3DPoint aVRP(aCameraSet.GetVRP());
417 basegfx::B3DVector aVPN(aCameraSet.GetVPN());
418 basegfx::B3DVector aVUP(aCameraSet.GetVUV());
420 // transfer to structure
421 aCamGeo.vrp.PositionX = aVRP.getX();
422 aCamGeo.vrp.PositionY = aVRP.getY();
423 aCamGeo.vrp.PositionZ = aVRP.getZ();
424 aCamGeo.vpn.DirectionX = aVPN.getX();
425 aCamGeo.vpn.DirectionY = aVPN.getY();
426 aCamGeo.vpn.DirectionZ = aVPN.getZ();
427 aCamGeo.vup.DirectionX = aVUP.getX();
428 aCamGeo.vup.DirectionY = aVUP.getY();
429 aCamGeo.vup.DirectionZ = aVUP.getZ();
431 rValue <<= aCamGeo;
432 break;
434 default:
435 return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
438 return true;
441 // css::lang::XServiceInfo
442 uno::Sequence< OUString > SAL_CALL Svx3DSceneObject::getSupportedServiceNames()
444 uno::Sequence< OUString > aSeq( SvxShape::getSupportedServiceNames() );
445 comphelper::ServiceInfoHelper::addToSequence( aSeq, {"com.sun.star.drawing.Shape3DScene"} );
446 return aSeq;
449 Svx3DCubeObject::Svx3DCubeObject( SdrObject* pObj ) throw()
450 : SvxShape( pObj, getSvxMapProvider().GetMap(SVXMAP_3DCUBEOBJECT), getSvxMapProvider().GetPropertySet(SVXMAP_3DCUBEOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
454 Svx3DCubeObject::~Svx3DCubeObject() throw()
458 bool Svx3DCubeObject::setPropertyValueImpl( const OUString& rName, const SfxItemPropertySimpleEntry* pProperty, const css::uno::Any& rValue )
460 SolarMutexGuard aGuard;
462 switch( pProperty->nWID )
464 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
466 // pack transformationmatrix to the object
467 if( ConvertHomogenMatrixToObject( static_cast< E3dObject* >( mpObj.get() ), rValue ) )
468 return true;
469 break;
471 case OWN_ATTR_3D_VALUE_POSITION:
473 // pack position to the object
474 drawing::Position3D aUnoPos;
475 if( rValue >>= aUnoPos )
477 basegfx::B3DPoint aPos(aUnoPos.PositionX, aUnoPos.PositionY, aUnoPos.PositionZ);
478 static_cast< E3dCubeObj* >( mpObj.get() )->SetCubePos(aPos);
479 return true;
481 break;
483 case OWN_ATTR_3D_VALUE_SIZE:
485 // pack size to the object
486 drawing::Direction3D aDirection;
487 if( rValue >>= aDirection )
489 basegfx::B3DVector aSize(aDirection.DirectionX, aDirection.DirectionY, aDirection.DirectionZ);
490 static_cast< E3dCubeObj* >( mpObj.get() )->SetCubeSize(aSize);
491 return true;
493 break;
495 case OWN_ATTR_3D_VALUE_POS_IS_CENTER:
497 bool bNew = false;
498 // pack sal_Bool bPosIsCenter to the object
499 if( rValue >>= bNew )
501 static_cast< E3dCubeObj* >( mpObj.get() )->SetPosIsCenter(bNew);
502 return true;
504 break;
506 default:
507 return SvxShape::setPropertyValueImpl( rName, pProperty, rValue );
510 throw IllegalArgumentException();
513 bool Svx3DCubeObject::getPropertyValueImpl( const OUString& rName, const SfxItemPropertySimpleEntry* pProperty, css::uno::Any& rValue )
515 switch( pProperty->nWID )
517 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
519 // pack transformation to a homogeneous matrix
520 ConvertObjectToHomogenMatric( static_cast< E3dObject* >( mpObj.get() ), rValue );
521 break;
523 case OWN_ATTR_3D_VALUE_POSITION:
525 // pack position
526 const basegfx::B3DPoint& rPos = static_cast<E3dCubeObj*>(mpObj.get())->GetCubePos();
527 drawing::Position3D aPos;
529 aPos.PositionX = rPos.getX();
530 aPos.PositionY = rPos.getY();
531 aPos.PositionZ = rPos.getZ();
533 rValue <<= aPos;
534 break;
536 case OWN_ATTR_3D_VALUE_SIZE:
538 // pack size
539 const basegfx::B3DVector& rSize = static_cast<E3dCubeObj*>(mpObj.get())->GetCubeSize();
540 drawing::Direction3D aDir;
542 aDir.DirectionX = rSize.getX();
543 aDir.DirectionY = rSize.getY();
544 aDir.DirectionZ = rSize.getZ();
546 rValue <<= aDir;
547 break;
549 case OWN_ATTR_3D_VALUE_POS_IS_CENTER:
551 rValue <<= static_cast<E3dCubeObj*>(mpObj.get())->GetPosIsCenter();
552 break;
554 default:
555 return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
558 return true;
561 // css::lang::XServiceInfo
562 uno::Sequence< OUString > SAL_CALL Svx3DCubeObject::getSupportedServiceNames()
564 uno::Sequence< OUString > aSeq( SvxShape::getSupportedServiceNames() );
565 comphelper::ServiceInfoHelper::addToSequence( aSeq, {"com.sun.star.drawing.Shape3D",
566 "com.sun.star.drawing.Shape3DCube"});
567 return aSeq;
570 Svx3DSphereObject::Svx3DSphereObject( SdrObject* pObj ) throw()
571 : SvxShape( pObj, getSvxMapProvider().GetMap(SVXMAP_3DSPHEREOBJECT), getSvxMapProvider().GetPropertySet(SVXMAP_3DSPHEREOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
575 Svx3DSphereObject::~Svx3DSphereObject() throw()
579 bool Svx3DSphereObject::setPropertyValueImpl( const OUString& rName, const SfxItemPropertySimpleEntry* pProperty, const css::uno::Any& rValue )
581 switch( pProperty->nWID )
583 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
585 // pack transformation matrix to the object
586 if( ConvertHomogenMatrixToObject( static_cast< E3dObject* >( mpObj.get() ), rValue ) )
587 return true;
588 break;
591 case OWN_ATTR_3D_VALUE_POSITION:
593 // pack position to the object
594 drawing::Position3D aUnoPos;
595 if( rValue >>= aUnoPos )
597 basegfx::B3DPoint aPos(aUnoPos.PositionX, aUnoPos.PositionY, aUnoPos.PositionZ);
598 static_cast<E3dSphereObj*>(mpObj.get())->SetCenter(aPos);
599 return true;
601 break;
604 case OWN_ATTR_3D_VALUE_SIZE:
606 // pack size to the object
607 drawing::Direction3D aDir;
608 if( rValue >>= aDir )
610 basegfx::B3DVector aPos(aDir.DirectionX, aDir.DirectionY, aDir.DirectionZ);
611 static_cast<E3dSphereObj*>(mpObj.get())->SetSize(aPos);
612 return true;
614 break;
616 default:
617 return SvxShape::setPropertyValueImpl( rName, pProperty, rValue );
620 throw IllegalArgumentException();
623 bool Svx3DSphereObject::getPropertyValueImpl( const OUString& rName, const SfxItemPropertySimpleEntry* pProperty, css::uno::Any& rValue )
625 switch( pProperty->nWID )
627 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
629 // pack transformation to a homogeneous matrix
630 ConvertObjectToHomogenMatric( static_cast< E3dObject* >( mpObj.get() ), rValue );
631 break;
633 case OWN_ATTR_3D_VALUE_POSITION:
635 // pack position
636 const basegfx::B3DPoint& rPos = static_cast<E3dSphereObj*>(mpObj.get())->Center();
637 drawing::Position3D aPos;
639 aPos.PositionX = rPos.getX();
640 aPos.PositionY = rPos.getY();
641 aPos.PositionZ = rPos.getZ();
643 rValue <<= aPos;
644 break;
646 case OWN_ATTR_3D_VALUE_SIZE:
648 // pack size
649 const basegfx::B3DVector& rSize = static_cast<E3dSphereObj*>(mpObj.get())->Size();
650 drawing::Direction3D aDir;
652 aDir.DirectionX = rSize.getX();
653 aDir.DirectionY = rSize.getY();
654 aDir.DirectionZ = rSize.getZ();
656 rValue <<= aDir;
657 break;
659 default:
660 return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
663 return true;
666 // css::lang::XServiceInfo
667 uno::Sequence< OUString > SAL_CALL Svx3DSphereObject::getSupportedServiceNames()
669 uno::Sequence< OUString > aSeq( SvxShape::getSupportedServiceNames() );
670 comphelper::ServiceInfoHelper::addToSequence( aSeq, {"com.sun.star.drawing.Shape3D",
671 "com.sun.star.drawing.Shape3DSphere"});
672 return aSeq;
674 Svx3DLatheObject::Svx3DLatheObject( SdrObject* pObj ) throw()
675 : SvxShape( pObj, getSvxMapProvider().GetMap(SVXMAP_3DLATHEOBJECT), getSvxMapProvider().GetPropertySet(SVXMAP_3DLATHEOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
680 Svx3DLatheObject::~Svx3DLatheObject() throw()
684 bool PolyPolygonShape3D_to_B3dPolyPolygon(
685 const Any& rValue,
686 basegfx::B3DPolyPolygon& rResultPolygon,
687 bool bCorrectPolygon)
689 drawing::PolyPolygonShape3D aSourcePolyPolygon;
690 if( !(rValue >>= aSourcePolyPolygon) )
691 return false;
693 sal_Int32 nOuterSequenceCount = aSourcePolyPolygon.SequenceX.getLength();
694 if(nOuterSequenceCount != aSourcePolyPolygon.SequenceY.getLength() || nOuterSequenceCount != aSourcePolyPolygon.SequenceZ.getLength())
695 return false;
697 drawing::DoubleSequence* pInnerSequenceX = aSourcePolyPolygon.SequenceX.getArray();
698 drawing::DoubleSequence* pInnerSequenceY = aSourcePolyPolygon.SequenceY.getArray();
699 drawing::DoubleSequence* pInnerSequenceZ = aSourcePolyPolygon.SequenceZ.getArray();
700 for(sal_Int32 a(0);a<nOuterSequenceCount;a++)
702 sal_Int32 nInnerSequenceCount = pInnerSequenceX->getLength();
703 if(nInnerSequenceCount != pInnerSequenceY->getLength() || nInnerSequenceCount != pInnerSequenceZ->getLength())
705 return false;
707 basegfx::B3DPolygon aNewPolygon;
708 double* pArrayX = pInnerSequenceX->getArray();
709 double* pArrayY = pInnerSequenceY->getArray();
710 double* pArrayZ = pInnerSequenceZ->getArray();
711 for(sal_Int32 b(0);b<nInnerSequenceCount;b++)
713 aNewPolygon.append(basegfx::B3DPoint(*pArrayX++,*pArrayY++,*pArrayZ++));
715 pInnerSequenceX++;
716 pInnerSequenceY++;
717 pInnerSequenceZ++;
719 // #i101520# correction is needed for imported polygons of old format,
720 // see callers
721 if(bCorrectPolygon)
723 basegfx::utils::checkClosed(aNewPolygon);
726 rResultPolygon.append(aNewPolygon);
728 return true;
731 static void B3dPolyPolygon_to_PolyPolygonShape3D( const basegfx::B3DPolyPolygon& rSourcePolyPolygon, Any& rValue )
733 drawing::PolyPolygonShape3D aRetval;
734 aRetval.SequenceX.realloc(rSourcePolyPolygon.count());
735 aRetval.SequenceY.realloc(rSourcePolyPolygon.count());
736 aRetval.SequenceZ.realloc(rSourcePolyPolygon.count());
737 drawing::DoubleSequence* pOuterSequenceX = aRetval.SequenceX.getArray();
738 drawing::DoubleSequence* pOuterSequenceY = aRetval.SequenceY.getArray();
739 drawing::DoubleSequence* pOuterSequenceZ = aRetval.SequenceZ.getArray();
740 for(sal_uInt32 a(0);a<rSourcePolyPolygon.count();a++)
742 const basegfx::B3DPolygon aPoly(rSourcePolyPolygon.getB3DPolygon(a));
743 sal_Int32 nPointCount(aPoly.count());
744 if(aPoly.isClosed()) nPointCount++;
745 pOuterSequenceX->realloc(nPointCount);
746 pOuterSequenceY->realloc(nPointCount);
747 pOuterSequenceZ->realloc(nPointCount);
748 double* pInnerSequenceX = pOuterSequenceX->getArray();
749 double* pInnerSequenceY = pOuterSequenceY->getArray();
750 double* pInnerSequenceZ = pOuterSequenceZ->getArray();
751 for(sal_uInt32 b(0);b<aPoly.count();b++)
753 const basegfx::B3DPoint aPoint(aPoly.getB3DPoint(b));
754 *pInnerSequenceX++ = aPoint.getX();
755 *pInnerSequenceY++ = aPoint.getY();
756 *pInnerSequenceZ++ = aPoint.getZ();
758 if(aPoly.isClosed())
760 const basegfx::B3DPoint aPoint(aPoly.getB3DPoint(0));
761 *pInnerSequenceX++ = aPoint.getX();
762 *pInnerSequenceY++ = aPoint.getY();
763 *pInnerSequenceZ++ = aPoint.getZ();
765 pOuterSequenceX++;
766 pOuterSequenceY++;
767 pOuterSequenceZ++;
769 rValue <<= aRetval;
772 bool Svx3DLatheObject::setPropertyValueImpl( const OUString& rName, const SfxItemPropertySimpleEntry* pProperty, const css::uno::Any& rValue )
774 switch( pProperty->nWID )
776 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
778 // pack transformation matrix to the object
779 if( ConvertHomogenMatrixToObject( static_cast< E3dObject* >( mpObj.get() ), rValue ) )
780 return true;
781 break;
783 case OWN_ATTR_3D_VALUE_POLYPOLYGON3D:
785 // pack polygon definition to the object
786 basegfx::B3DPolyPolygon aNewB3DPolyPolygon;
788 // #i101520# Probably imported
789 if( PolyPolygonShape3D_to_B3dPolyPolygon( rValue, aNewB3DPolyPolygon, true ) )
791 // #105127# SetPolyPoly3D sets the Svx3DVerticalSegmentsItem to the number
792 // of points of the polygon. Thus, value gets lost. To avoid this, rescue
793 // item here and re-set after setting the polygon.
794 const sal_uInt32 nPrevVerticalSegs(static_cast<E3dLatheObj*>(mpObj.get())->GetVerticalSegments());
796 // set polygon
797 const basegfx::B3DHomMatrix aIdentity;
798 const basegfx::B2DPolyPolygon aB2DPolyPolygon(basegfx::utils::createB2DPolyPolygonFromB3DPolyPolygon(aNewB3DPolyPolygon, aIdentity));
799 static_cast<E3dLatheObj*>(mpObj.get())->SetPolyPoly2D(aB2DPolyPolygon);
800 const sal_uInt32 nPostVerticalSegs(static_cast<E3dLatheObj*>(mpObj.get())->GetVerticalSegments());
802 if(nPrevVerticalSegs != nPostVerticalSegs)
804 // restore the vertical segment count
805 static_cast<E3dLatheObj*>(mpObj.get())->SetMergedItem(makeSvx3DVerticalSegmentsItem(nPrevVerticalSegs));
807 return true;
809 break;
811 default:
812 return SvxShape::setPropertyValueImpl( rName, pProperty, rValue );
815 throw IllegalArgumentException();
818 bool Svx3DLatheObject::getPropertyValueImpl( const OUString& rName, const SfxItemPropertySimpleEntry* pProperty, css::uno::Any& rValue )
820 switch( pProperty->nWID )
822 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
824 // pack transformation to a homogeneous matrix
825 drawing::HomogenMatrix aHomMat;
826 basegfx::B3DHomMatrix aMat = static_cast<E3dObject*>(mpObj.get())->GetTransform();
828 // pack evtl. transformed matrix to output
829 aHomMat.Line1.Column1 = aMat.get(0, 0);
830 aHomMat.Line1.Column2 = aMat.get(0, 1);
831 aHomMat.Line1.Column3 = aMat.get(0, 2);
832 aHomMat.Line1.Column4 = aMat.get(0, 3);
833 aHomMat.Line2.Column1 = aMat.get(1, 0);
834 aHomMat.Line2.Column2 = aMat.get(1, 1);
835 aHomMat.Line2.Column3 = aMat.get(1, 2);
836 aHomMat.Line2.Column4 = aMat.get(1, 3);
837 aHomMat.Line3.Column1 = aMat.get(2, 0);
838 aHomMat.Line3.Column2 = aMat.get(2, 1);
839 aHomMat.Line3.Column3 = aMat.get(2, 2);
840 aHomMat.Line3.Column4 = aMat.get(2, 3);
841 aHomMat.Line4.Column1 = aMat.get(3, 0);
842 aHomMat.Line4.Column2 = aMat.get(3, 1);
843 aHomMat.Line4.Column3 = aMat.get(3, 2);
844 aHomMat.Line4.Column4 = aMat.get(3, 3);
846 rValue <<= aHomMat;
847 break;
849 case OWN_ATTR_3D_VALUE_POLYPOLYGON3D:
851 const basegfx::B2DPolyPolygon& rPolyPoly = static_cast<E3dLatheObj*>(mpObj.get())->GetPolyPoly2D();
852 const basegfx::B3DPolyPolygon aB3DPolyPolygon(basegfx::utils::createB3DPolyPolygonFromB2DPolyPolygon(rPolyPoly));
854 B3dPolyPolygon_to_PolyPolygonShape3D(aB3DPolyPolygon, rValue);
855 break;
857 default:
858 return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
861 return true;
864 // css::lang::XServiceInfo
865 uno::Sequence< OUString > SAL_CALL Svx3DLatheObject::getSupportedServiceNames()
867 uno::Sequence< OUString > aSeq( SvxShape::getSupportedServiceNames() );
868 comphelper::ServiceInfoHelper::addToSequence( aSeq, {"com.sun.star.drawing.Shape3D",
869 "com.sun.star.drawing.Shape3DLathe"});
870 return aSeq;
873 Svx3DExtrudeObject::Svx3DExtrudeObject( SdrObject* pObj ) throw()
874 : SvxShape( pObj, getSvxMapProvider().GetMap(SVXMAP_3DEXTRUDEOBJECT), getSvxMapProvider().GetPropertySet(SVXMAP_3DEXTRUDEOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
878 Svx3DExtrudeObject::~Svx3DExtrudeObject() throw()
882 bool Svx3DExtrudeObject::setPropertyValueImpl( const OUString& rName, const SfxItemPropertySimpleEntry* pProperty, const css::uno::Any& rValue )
884 switch( pProperty->nWID )
886 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
888 // pack transformation matrix to the object
889 if( ConvertHomogenMatrixToObject( static_cast< E3dObject* >( mpObj.get() ), rValue ) )
890 return true;
891 break;
894 case OWN_ATTR_3D_VALUE_POLYPOLYGON3D:
896 // pack polygon definition to the object
897 basegfx::B3DPolyPolygon aNewB3DPolyPolygon;
899 // #i101520# Probably imported
900 if( PolyPolygonShape3D_to_B3dPolyPolygon( rValue, aNewB3DPolyPolygon, true ) )
902 // set polygon
903 const basegfx::B3DHomMatrix aIdentity;
904 const basegfx::B2DPolyPolygon aB2DPolyPolygon(basegfx::utils::createB2DPolyPolygonFromB3DPolyPolygon(aNewB3DPolyPolygon, aIdentity));
905 static_cast<E3dExtrudeObj*>(mpObj.get())->SetExtrudePolygon(aB2DPolyPolygon);
906 return true;
908 break;
910 default:
911 return SvxShape::setPropertyValueImpl( rName, pProperty, rValue );
914 throw IllegalArgumentException();
917 bool Svx3DExtrudeObject::getPropertyValueImpl( const OUString& rName, const SfxItemPropertySimpleEntry* pProperty, css::uno::Any& rValue )
919 switch( pProperty->nWID )
921 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
923 // pack transformation to a homogeneous matrix
924 drawing::HomogenMatrix aHomMat;
925 basegfx::B3DHomMatrix aMat = static_cast<E3dObject*>(mpObj.get())->GetTransform();
927 // pack evtl. transformed matrix to output
928 aHomMat.Line1.Column1 = aMat.get(0, 0);
929 aHomMat.Line1.Column2 = aMat.get(0, 1);
930 aHomMat.Line1.Column3 = aMat.get(0, 2);
931 aHomMat.Line1.Column4 = aMat.get(0, 3);
932 aHomMat.Line2.Column1 = aMat.get(1, 0);
933 aHomMat.Line2.Column2 = aMat.get(1, 1);
934 aHomMat.Line2.Column3 = aMat.get(1, 2);
935 aHomMat.Line2.Column4 = aMat.get(1, 3);
936 aHomMat.Line3.Column1 = aMat.get(2, 0);
937 aHomMat.Line3.Column2 = aMat.get(2, 1);
938 aHomMat.Line3.Column3 = aMat.get(2, 2);
939 aHomMat.Line3.Column4 = aMat.get(2, 3);
940 aHomMat.Line4.Column1 = aMat.get(3, 0);
941 aHomMat.Line4.Column2 = aMat.get(3, 1);
942 aHomMat.Line4.Column3 = aMat.get(3, 2);
943 aHomMat.Line4.Column4 = aMat.get(3, 3);
945 rValue <<= aHomMat;
946 break;
949 case OWN_ATTR_3D_VALUE_POLYPOLYGON3D:
951 // pack polygon definition
952 const basegfx::B2DPolyPolygon& rPolyPoly = static_cast<E3dExtrudeObj*>(mpObj.get())->GetExtrudePolygon();
953 const basegfx::B3DPolyPolygon aB3DPolyPolygon(basegfx::utils::createB3DPolyPolygonFromB2DPolyPolygon(rPolyPoly));
955 B3dPolyPolygon_to_PolyPolygonShape3D(aB3DPolyPolygon, rValue);
956 break;
958 default:
959 return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
962 return true;
965 // css::lang::XServiceInfo
966 uno::Sequence< OUString > SAL_CALL Svx3DExtrudeObject::getSupportedServiceNames()
968 uno::Sequence< OUString > aSeq( SvxShape::getSupportedServiceNames() );
969 comphelper::ServiceInfoHelper::addToSequence( aSeq, {"com.sun.star.drawing.Shape3D",
970 "com.sun.star.drawing.Shape3DExtrude"});
971 return aSeq;
974 Svx3DPolygonObject::Svx3DPolygonObject( SdrObject* pObj ) throw()
975 : SvxShape( pObj, getSvxMapProvider().GetMap(SVXMAP_3DPOLYGONOBJECT), getSvxMapProvider().GetPropertySet(SVXMAP_3DPOLYGONOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
979 Svx3DPolygonObject::~Svx3DPolygonObject() throw()
983 bool Svx3DPolygonObject::setPropertyValueImpl( const OUString& rName, const SfxItemPropertySimpleEntry* pProperty, const css::uno::Any& rValue )
985 switch( pProperty->nWID )
987 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
989 // pack transformation matrix to the object
990 if( ConvertHomogenMatrixToObject( static_cast< E3dObject* >( mpObj.get() ), rValue ) )
991 return true;
992 break;
995 case OWN_ATTR_3D_VALUE_POLYPOLYGON3D:
997 // pack polygon definition to the object
998 basegfx::B3DPolyPolygon aNewB3DPolyPolygon;
1000 // #i101520# Direct API data (e.g. from chart)
1001 if( PolyPolygonShape3D_to_B3dPolyPolygon( rValue, aNewB3DPolyPolygon, false ) )
1003 // set polygon
1004 static_cast<E3dPolygonObj*>(mpObj.get())->SetPolyPolygon3D(aNewB3DPolyPolygon);
1005 return true;
1007 break;
1009 case OWN_ATTR_3D_VALUE_NORMALSPOLYGON3D:
1011 // pack perpendicular definition to the object
1012 basegfx::B3DPolyPolygon aNewB3DPolyPolygon;
1014 // #i101520# Direct API data (e.g. from chart)
1015 if( PolyPolygonShape3D_to_B3dPolyPolygon( rValue, aNewB3DPolyPolygon, false ) )
1017 // set polygon
1018 static_cast<E3dPolygonObj*>(mpObj.get())->SetPolyNormals3D(aNewB3DPolyPolygon);
1019 return true;
1021 break;
1023 case OWN_ATTR_3D_VALUE_TEXTUREPOLYGON3D:
1025 // pack texture definition to the object
1026 basegfx::B3DPolyPolygon aNewB3DPolyPolygon;
1028 // #i101520# Direct API data (e.g. from chart)
1029 if( PolyPolygonShape3D_to_B3dPolyPolygon( rValue, aNewB3DPolyPolygon, false ) )
1031 // set polygon
1032 const basegfx::B3DHomMatrix aIdentity;
1033 const basegfx::B2DPolyPolygon aB2DPolyPolygon(basegfx::utils::createB2DPolyPolygonFromB3DPolyPolygon(aNewB3DPolyPolygon, aIdentity));
1034 static_cast<E3dPolygonObj*>(mpObj.get())->SetPolyTexture2D(aB2DPolyPolygon);
1035 return true;
1037 break;
1039 case OWN_ATTR_3D_VALUE_LINEONLY:
1041 bool bNew = false;
1042 if( rValue >>= bNew )
1044 static_cast<E3dPolygonObj*>(mpObj.get())->SetLineOnly(bNew);
1045 return true;
1047 break;
1049 default:
1050 return SvxShape::setPropertyValueImpl( rName, pProperty, rValue );
1053 throw IllegalArgumentException();
1056 bool Svx3DPolygonObject::getPropertyValueImpl( const OUString& rName, const SfxItemPropertySimpleEntry* pProperty, css::uno::Any& rValue )
1058 switch( pProperty->nWID )
1060 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
1062 ConvertObjectToHomogenMatric( static_cast< E3dObject* >( mpObj.get() ), rValue );
1063 break;
1066 case OWN_ATTR_3D_VALUE_POLYPOLYGON3D:
1068 B3dPolyPolygon_to_PolyPolygonShape3D(static_cast<E3dPolygonObj*>(mpObj.get())->GetPolyPolygon3D(),rValue);
1069 break;
1072 case OWN_ATTR_3D_VALUE_NORMALSPOLYGON3D:
1074 B3dPolyPolygon_to_PolyPolygonShape3D(static_cast<E3dPolygonObj*>(mpObj.get())->GetPolyNormals3D(),rValue);
1075 break;
1078 case OWN_ATTR_3D_VALUE_TEXTUREPOLYGON3D:
1080 // pack texture definition
1081 const basegfx::B2DPolyPolygon& rPolyPoly = static_cast<E3dPolygonObj*>(mpObj.get())->GetPolyTexture2D();
1082 const basegfx::B3DPolyPolygon aB3DPolyPolygon(basegfx::utils::createB3DPolyPolygonFromB2DPolyPolygon(rPolyPoly));
1084 B3dPolyPolygon_to_PolyPolygonShape3D(aB3DPolyPolygon,rValue);
1085 break;
1088 case OWN_ATTR_3D_VALUE_LINEONLY:
1090 rValue <<= static_cast<E3dPolygonObj*>(mpObj.get())->GetLineOnly();
1091 break;
1094 default:
1095 return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
1098 return true;
1101 // css::lang::XServiceInfo
1102 uno::Sequence< OUString > SAL_CALL Svx3DPolygonObject::getSupportedServiceNames()
1104 Sequence< OUString > aSeq( SvxShape::getSupportedServiceNames() );
1105 comphelper::ServiceInfoHelper::addToSequence( aSeq, {"com.sun.star.drawing.Shape3D",
1106 "com.sun.star.drawing.Shape3DPolygon"});
1107 return aSeq;
1110 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */