1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20 #include <sal/config.h>
21
22 #include <initializer_list>
23 #include <string_view>
24
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>
35
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"
54
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;
60
61 #define QUERYINT( xint ) \
62 if( rType == cppu::UnoType<xint>::get() ) \
63 aAny <<= Reference< xint >(this)
64
Svx3DSceneObject(SdrObject * pObj,SvxDrawPage * pDrawPage)65 Svx3DSceneObject::Svx3DSceneObject(SdrObject* pObj, SvxDrawPage* pDrawPage)
66 : SvxShape( pObj, getSvxMapProvider().GetMap(SVXMAP_3DSCENEOBJECT), getSvxMapProvider().GetPropertySet(SVXMAP_3DSCENEOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
67 , mxPage( pDrawPage )
68 {
69 }
70
71
~Svx3DSceneObject()72 Svx3DSceneObject::~Svx3DSceneObject() noexcept
73 {
74 }
75
76
Create(SdrObject * pNewObj,SvxDrawPage * pNewPage)77 void Svx3DSceneObject::Create( SdrObject* pNewObj, SvxDrawPage* pNewPage )
78 {
79 SvxShape::Create( pNewObj, pNewPage );
80 mxPage = pNewPage;
81 }
82
83
queryAggregation(const uno::Type & rType)84 uno::Any SAL_CALL Svx3DSceneObject::queryAggregation( const uno::Type & rType )
85 {
86 uno::Any aAny;
87
88 QUERYINT( drawing::XShapes );
89 else QUERYINT( container::XIndexAccess );
90 else QUERYINT( container::XElementAccess );
91 else
92 return SvxShape::queryAggregation( rType );
93
94 return aAny;
95 }
96
queryInterface(const uno::Type & rType)97 uno::Any SAL_CALL Svx3DSceneObject::queryInterface( const uno::Type & rType )
98 {
99 return SvxShape::queryInterface( rType );
100 }
101
102 // XTypeProvider
103
getImplementationId()104 uno::Sequence< sal_Int8 > SAL_CALL Svx3DSceneObject::getImplementationId()
105 {
106 return css::uno::Sequence<sal_Int8>();
107 }
108
109
add(const Reference<drawing::XShape> & xShape)110 void SAL_CALL Svx3DSceneObject::add( const Reference< drawing::XShape >& xShape )
111 {
112 SolarMutexGuard aGuard;
113
114 SvxShape* pShape = comphelper::getUnoTunnelImplementation<SvxShape>( xShape );
115
116 if(!HasSdrObject() || !mxPage.is() || pShape == nullptr || nullptr != pShape->GetSdrObject() )
117 throw uno::RuntimeException();
118
119 SdrObject* pSdrShape = mxPage->CreateSdrObject_( xShape );
120 if( dynamic_cast<const E3dObject* >(pSdrShape) != nullptr )
121 {
122 GetSdrObject()->GetSubList()->NbcInsertObject( pSdrShape );
123 pShape->Create(pSdrShape, mxPage.get());
124 }
125 else
126 {
127 SdrObject::Free( pSdrShape );
128 throw uno::RuntimeException();
129 }
130
131 GetSdrObject()->getSdrModelFromSdrObject().SetChanged();
132 }
133
134
remove(const Reference<drawing::XShape> & xShape)135 void SAL_CALL Svx3DSceneObject::remove( const Reference< drawing::XShape >& xShape )
136 {
137 SolarMutexGuard aGuard;
138
139 SdrObject* pSdrShape = SdrObject::getSdrObjectFromXShape( xShape );
140
141 if(!HasSdrObject() || !pSdrShape ||
142 pSdrShape->getParentSdrObjectFromSdrObject() != GetSdrObject())
143 throw uno::RuntimeException();
144
145 SdrObjList& rList = *pSdrShape->getParentSdrObjListFromSdrObject();
146
147 const size_t nObjCount = rList.GetObjCount();
148 size_t nObjNum = 0;
149 while( nObjNum < nObjCount )
150 {
151 if(rList.GetObj( nObjNum ) == pSdrShape )
152 break;
153 nObjNum++;
154 }
155
156 if( nObjNum < nObjCount )
157 {
158 SdrObject* pObject = rList.NbcRemoveObject( nObjNum );
159 SdrObject::Free( pObject );
160 }
161 else
162 {
163 SAL_WARN( "svx", "Fatality! SdrObject is not belonging to its SdrObjList! [CL]" );
164 }
165 }
166
167
getCount()168 sal_Int32 SAL_CALL Svx3DSceneObject::getCount()
169 {
170 SolarMutexGuard aGuard;
171
172 sal_Int32 nRetval = 0;
173
174 if(HasSdrObject() && dynamic_cast<const E3dScene* >(GetSdrObject()) != nullptr && GetSdrObject()->GetSubList())
175 nRetval = GetSdrObject()->GetSubList()->GetObjCount();
176 return nRetval;
177 }
178
179
getByIndex(sal_Int32 Index)180 uno::Any SAL_CALL Svx3DSceneObject::getByIndex( sal_Int32 Index )
181 {
182 SolarMutexGuard aGuard;
183
184 if( !HasSdrObject() || GetSdrObject()->GetSubList() == nullptr )
185 throw uno::RuntimeException();
186
187 if( Index<0 || GetSdrObject()->GetSubList()->GetObjCount() <= o3tl::make_unsigned(Index) )
188 throw lang::IndexOutOfBoundsException();
189
190 SdrObject* pDestObj = GetSdrObject()->GetSubList()->GetObj( Index );
191 if(pDestObj == nullptr)
192 throw lang::IndexOutOfBoundsException();
193
194 Reference< drawing::XShape > xShape( pDestObj->getUnoShape(), uno::UNO_QUERY );
195 return uno::Any(xShape);
196 }
197
198
199 // css::container::XElementAccess
200
getElementType()201 uno::Type SAL_CALL Svx3DSceneObject::getElementType()
202 {
203 return cppu::UnoType<drawing::XShape>::get();
204 }
205
206
hasElements()207 sal_Bool SAL_CALL Svx3DSceneObject::hasElements()
208 {
209 SolarMutexGuard aGuard;
210
211 return HasSdrObject() && GetSdrObject()->GetSubList() && (GetSdrObject()->GetSubList()->GetObjCount() > 0);
212 }
213
214
ConvertHomogenMatrixToObject(E3dObject * pObject,const Any & rValue)215 static bool ConvertHomogenMatrixToObject( E3dObject* pObject, const Any& rValue )
216 {
217 drawing::HomogenMatrix aMat;
218 if( rValue >>= aMat )
219 {
220 pObject->SetTransform(basegfx::utils::UnoHomogenMatrixToB3DHomMatrix(aMat));
221 return true;
222 }
223 return false;
224 }
225
ConvertObjectToHomogenMatric(E3dObject const * pObject,Any & rValue)226 static void ConvertObjectToHomogenMatric( E3dObject const * pObject, Any& rValue )
227 {
228 drawing::HomogenMatrix aHomMat;
229 const basegfx::B3DHomMatrix& rMat = pObject->GetTransform();
230 basegfx::utils::B3DHomMatrixToUnoHomogenMatrix(rMat, aHomMat);
231 rValue <<= aHomMat;
232 }
233
234 namespace {
235
236 struct ImpRememberTransAndRect
237 {
238 basegfx::B3DHomMatrix maMat;
239 tools::Rectangle maRect;
240 };
241
242 }
243
setPropertyValueImpl(const OUString & rName,const SfxItemPropertyMapEntry * pProperty,const css::uno::Any & rValue)244 bool Svx3DSceneObject::setPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue )
245 {
246 switch( pProperty->nWID )
247 {
248 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
249 {
250 // patch transformation matrix to the object
251 if( ConvertHomogenMatrixToObject( static_cast< E3dObject* >( GetSdrObject() ), rValue ) )
252 return true;
253 break;
254 }
255 case OWN_ATTR_3D_VALUE_CAMERA_GEOMETRY:
256 {
257 // set CameraGeometry at scene
258 E3dScene* pScene = static_cast< E3dScene* >( GetSdrObject() );
259 drawing::CameraGeometry aCamGeo;
260
261 if(rValue >>= aCamGeo)
262 {
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);
266
267 // rescue scene transformation
268 ImpRememberTransAndRect aSceneTAR;
269 aSceneTAR.maMat = pScene->GetTransform();
270 aSceneTAR.maRect = pScene->GetSnapRect();
271
272 // rescue object transformations
273 SdrObjListIter aIter(pScene->GetSubList(), SdrIterMode::DeepWithGroups);
274 std::vector<basegfx::B3DHomMatrix*> aObjTrans;
275 while(aIter.IsMore())
276 {
277 E3dObject* p3DObj = static_cast<E3dObject*>(aIter.Next());
278 basegfx::B3DHomMatrix* pNew = new basegfx::B3DHomMatrix;
279 *pNew = p3DObj->GetTransform();
280 aObjTrans.push_back(pNew);
281 }
282
283 // reset object transformations
284 aIter.Reset();
285 while(aIter.IsMore())
286 {
287 E3dObject* p3DObj = static_cast<E3dObject*>(aIter.Next());
288 p3DObj->NbcSetTransform(basegfx::B3DHomMatrix());
289 }
290
291 // reset scene transformation and make a complete recalc
292 pScene->NbcSetTransform(basegfx::B3DHomMatrix());
293
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();
299
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());
305
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)));
313
314 // set at scene
315 pScene->SetCamera(aCam);
316
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)));
321
322 if(bVRPUsed || bVPNUsed || bVUPUsed)
323 {
324 pScene->GetCameraSet().SetViewportValues(aVRP, aVPN, aVUP);
325 }
326
327 // set object transformations again at objects
328 aIter.Reset();
329 sal_uInt32 nIndex(0);
330 while(aIter.IsMore())
331 {
332 E3dObject* p3DObj = static_cast<E3dObject*>(aIter.Next());
333 basegfx::B3DHomMatrix* pMat = aObjTrans[nIndex++];
334 p3DObj->NbcSetTransform(*pMat);
335 delete pMat;
336 }
337
338 // set scene transformation again at scene
339 pScene->NbcSetTransform(aSceneTAR.maMat);
340 pScene->NbcSetSnapRect(aSceneTAR.maRect);
341
342 return true;
343 }
344 break;
345 }
346 default:
347 return SvxShape::setPropertyValueImpl(rName, pProperty, rValue);
348 }
349
350 throw IllegalArgumentException();
351 }
352
353
getPropertyValueImpl(const OUString & rName,const SfxItemPropertyMapEntry * pProperty,css::uno::Any & rValue)354 bool Svx3DSceneObject::getPropertyValueImpl(const OUString& rName, const SfxItemPropertyMapEntry* pProperty,
355 css::uno::Any& rValue)
356 {
357 switch( pProperty->nWID )
358 {
359 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
360 {
361 // patch object to a homogeneous 4x4 matrix
362 ConvertObjectToHomogenMatric( static_cast< E3dObject* >( GetSdrObject() ), rValue );
363 break;
364 }
365 case OWN_ATTR_3D_VALUE_CAMERA_GEOMETRY:
366 {
367 // get CameraGeometry from scene
368 E3dScene* pScene = static_cast< E3dScene* >( GetSdrObject() );
369 drawing::CameraGeometry aCamGeo;
370
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());
376
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();
387
388 rValue <<= aCamGeo;
389 break;
390 }
391 default:
392 return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
393 }
394
395 return true;
396 }
397
398 // css::lang::XServiceInfo
getSupportedServiceNames()399 uno::Sequence< OUString > SAL_CALL Svx3DSceneObject::getSupportedServiceNames()
400 {
401 return comphelper::concatSequences(
402 SvxShape::getSupportedServiceNames(),
403 std::initializer_list<std::u16string_view>{ u"com.sun.star.drawing.Shape3DScene" });
404 }
405
Svx3DCubeObject(SdrObject * pObj)406 Svx3DCubeObject::Svx3DCubeObject(SdrObject* pObj)
407 : SvxShape( pObj, getSvxMapProvider().GetMap(SVXMAP_3DCUBEOBJECT), getSvxMapProvider().GetPropertySet(SVXMAP_3DCUBEOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
408 {
409 }
410
~Svx3DCubeObject()411 Svx3DCubeObject::~Svx3DCubeObject() noexcept
412 {
413 }
414
setPropertyValueImpl(const OUString & rName,const SfxItemPropertyMapEntry * pProperty,const css::uno::Any & rValue)415 bool Svx3DCubeObject::setPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue )
416 {
417 SolarMutexGuard aGuard;
418
419 switch( pProperty->nWID )
420 {
421 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
422 {
423 // pack transformationmatrix to the object
424 if( ConvertHomogenMatrixToObject( static_cast< E3dObject* >( GetSdrObject() ), rValue ) )
425 return true;
426 break;
427 }
428 case OWN_ATTR_3D_VALUE_POSITION:
429 {
430 // pack position to the object
431 drawing::Position3D aUnoPos;
432 if( rValue >>= aUnoPos )
433 {
434 basegfx::B3DPoint aPos(aUnoPos.PositionX, aUnoPos.PositionY, aUnoPos.PositionZ);
435 static_cast< E3dCubeObj* >( GetSdrObject() )->SetCubePos(aPos);
436 return true;
437 }
438 break;
439 }
440 case OWN_ATTR_3D_VALUE_SIZE:
441 {
442 // pack size to the object
443 drawing::Direction3D aDirection;
444 if( rValue >>= aDirection )
445 {
446 basegfx::B3DVector aSize(aDirection.DirectionX, aDirection.DirectionY, aDirection.DirectionZ);
447 static_cast< E3dCubeObj* >( GetSdrObject() )->SetCubeSize(aSize);
448 return true;
449 }
450 break;
451 }
452 case OWN_ATTR_3D_VALUE_POS_IS_CENTER:
453 {
454 bool bNew = false;
455 // pack sal_Bool bPosIsCenter to the object
456 if( rValue >>= bNew )
457 {
458 static_cast< E3dCubeObj* >( GetSdrObject() )->SetPosIsCenter(bNew);
459 return true;
460 }
461 break;
462 }
463 default:
464 return SvxShape::setPropertyValueImpl( rName, pProperty, rValue );
465 }
466
467 throw IllegalArgumentException();
468 }
469
getPropertyValueImpl(const OUString & rName,const SfxItemPropertyMapEntry * pProperty,css::uno::Any & rValue)470 bool Svx3DCubeObject::getPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, css::uno::Any& rValue )
471 {
472 switch( pProperty->nWID )
473 {
474 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
475 {
476 // pack transformation to a homogeneous matrix
477 ConvertObjectToHomogenMatric( static_cast< E3dObject* >( GetSdrObject() ), rValue );
478 break;
479 }
480 case OWN_ATTR_3D_VALUE_POSITION:
481 {
482 // pack position
483 const basegfx::B3DPoint& rPos = static_cast<E3dCubeObj*>(GetSdrObject())->GetCubePos();
484 drawing::Position3D aPos;
485
486 aPos.PositionX = rPos.getX();
487 aPos.PositionY = rPos.getY();
488 aPos.PositionZ = rPos.getZ();
489
490 rValue <<= aPos;
491 break;
492 }
493 case OWN_ATTR_3D_VALUE_SIZE:
494 {
495 // pack size
496 const basegfx::B3DVector& rSize = static_cast<E3dCubeObj*>(GetSdrObject())->GetCubeSize();
497 drawing::Direction3D aDir;
498
499 aDir.DirectionX = rSize.getX();
500 aDir.DirectionY = rSize.getY();
501 aDir.DirectionZ = rSize.getZ();
502
503 rValue <<= aDir;
504 break;
505 }
506 case OWN_ATTR_3D_VALUE_POS_IS_CENTER:
507 {
508 rValue <<= static_cast<E3dCubeObj*>(GetSdrObject())->GetPosIsCenter();
509 break;
510 }
511 default:
512 return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
513 }
514
515 return true;
516 }
517
518 // css::lang::XServiceInfo
getSupportedServiceNames()519 uno::Sequence< OUString > SAL_CALL Svx3DCubeObject::getSupportedServiceNames()
520 {
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" });
525 }
526
Svx3DSphereObject(SdrObject * pObj)527 Svx3DSphereObject::Svx3DSphereObject(SdrObject* pObj)
528 : SvxShape( pObj, getSvxMapProvider().GetMap(SVXMAP_3DSPHEREOBJECT), getSvxMapProvider().GetPropertySet(SVXMAP_3DSPHEREOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
529 {
530 }
531
~Svx3DSphereObject()532 Svx3DSphereObject::~Svx3DSphereObject() noexcept
533 {
534 }
535
setPropertyValueImpl(const OUString & rName,const SfxItemPropertyMapEntry * pProperty,const css::uno::Any & rValue)536 bool Svx3DSphereObject::setPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue )
537 {
538 switch( pProperty->nWID )
539 {
540 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
541 {
542 // pack transformation matrix to the object
543 if( ConvertHomogenMatrixToObject( static_cast< E3dObject* >( GetSdrObject() ), rValue ) )
544 return true;
545 break;
546 }
547
548 case OWN_ATTR_3D_VALUE_POSITION:
549 {
550 // pack position to the object
551 drawing::Position3D aUnoPos;
552 if( rValue >>= aUnoPos )
553 {
554 basegfx::B3DPoint aPos(aUnoPos.PositionX, aUnoPos.PositionY, aUnoPos.PositionZ);
555 static_cast<E3dSphereObj*>(GetSdrObject())->SetCenter(aPos);
556 return true;
557 }
558 break;
559 }
560
561 case OWN_ATTR_3D_VALUE_SIZE:
562 {
563 // pack size to the object
564 drawing::Direction3D aDir;
565 if( rValue >>= aDir )
566 {
567 basegfx::B3DVector aPos(aDir.DirectionX, aDir.DirectionY, aDir.DirectionZ);
568 static_cast<E3dSphereObj*>(GetSdrObject())->SetSize(aPos);
569 return true;
570 }
571 break;
572 }
573 default:
574 return SvxShape::setPropertyValueImpl( rName, pProperty, rValue );
575 }
576
577 throw IllegalArgumentException();
578 }
579
getPropertyValueImpl(const OUString & rName,const SfxItemPropertyMapEntry * pProperty,css::uno::Any & rValue)580 bool Svx3DSphereObject::getPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, css::uno::Any& rValue )
581 {
582 switch( pProperty->nWID )
583 {
584 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
585 {
586 // pack transformation to a homogeneous matrix
587 ConvertObjectToHomogenMatric( static_cast< E3dObject* >( GetSdrObject() ), rValue );
588 break;
589 }
590 case OWN_ATTR_3D_VALUE_POSITION:
591 {
592 // pack position
593 const basegfx::B3DPoint& rPos = static_cast<E3dSphereObj*>(GetSdrObject())->Center();
594 drawing::Position3D aPos;
595
596 aPos.PositionX = rPos.getX();
597 aPos.PositionY = rPos.getY();
598 aPos.PositionZ = rPos.getZ();
599
600 rValue <<= aPos;
601 break;
602 }
603 case OWN_ATTR_3D_VALUE_SIZE:
604 {
605 // pack size
606 const basegfx::B3DVector& rSize = static_cast<E3dSphereObj*>(GetSdrObject())->Size();
607 drawing::Direction3D aDir;
608
609 aDir.DirectionX = rSize.getX();
610 aDir.DirectionY = rSize.getY();
611 aDir.DirectionZ = rSize.getZ();
612
613 rValue <<= aDir;
614 break;
615 }
616 default:
617 return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
618 }
619
620 return true;
621 }
622
623 // css::lang::XServiceInfo
getSupportedServiceNames()624 uno::Sequence< OUString > SAL_CALL Svx3DSphereObject::getSupportedServiceNames()
625 {
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" });
630 }
631
Svx3DLatheObject(SdrObject * pObj)632 Svx3DLatheObject::Svx3DLatheObject(SdrObject* pObj)
633 : SvxShape( pObj, getSvxMapProvider().GetMap(SVXMAP_3DLATHEOBJECT), getSvxMapProvider().GetPropertySet(SVXMAP_3DLATHEOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
634 {
635 }
636
~Svx3DLatheObject()637 Svx3DLatheObject::~Svx3DLatheObject() noexcept
638 {
639 }
640
PolyPolygonShape3D_to_B3dPolyPolygon(const Any & rValue,basegfx::B3DPolyPolygon & rResultPolygon,bool bCorrectPolygon)641 static bool PolyPolygonShape3D_to_B3dPolyPolygon(
642 const Any& rValue,
643 basegfx::B3DPolyPolygon& rResultPolygon,
644 bool bCorrectPolygon)
645 {
646 drawing::PolyPolygonShape3D aSourcePolyPolygon;
647 if( !(rValue >>= aSourcePolyPolygon) )
648 return false;
649
650 sal_Int32 nOuterSequenceCount = aSourcePolyPolygon.SequenceX.getLength();
651 if(nOuterSequenceCount != aSourcePolyPolygon.SequenceY.getLength() || nOuterSequenceCount != aSourcePolyPolygon.SequenceZ.getLength())
652 return false;
653
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++)
658 {
659 sal_Int32 nInnerSequenceCount = pInnerSequenceX->getLength();
660 if(nInnerSequenceCount != pInnerSequenceY->getLength() || nInnerSequenceCount != pInnerSequenceZ->getLength())
661 {
662 return false;
663 }
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++)
669 {
670 aNewPolygon.append(basegfx::B3DPoint(*pArrayX++,*pArrayY++,*pArrayZ++));
671 }
672 pInnerSequenceX++;
673 pInnerSequenceY++;
674 pInnerSequenceZ++;
675
676 // #i101520# correction is needed for imported polygons of old format,
677 // see callers
678 if(bCorrectPolygon)
679 {
680 basegfx::utils::checkClosed(aNewPolygon);
681 }
682
683 rResultPolygon.append(aNewPolygon);
684 }
685 return true;
686 }
687
B3dPolyPolygon_to_PolyPolygonShape3D(const basegfx::B3DPolyPolygon & rSourcePolyPolygon,Any & rValue)688 static void B3dPolyPolygon_to_PolyPolygonShape3D( const basegfx::B3DPolyPolygon& rSourcePolyPolygon, Any& rValue )
689 {
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++)
698 {
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++)
709 {
710 const basegfx::B3DPoint aPoint(aPoly.getB3DPoint(b));
711 *pInnerSequenceX++ = aPoint.getX();
712 *pInnerSequenceY++ = aPoint.getY();
713 *pInnerSequenceZ++ = aPoint.getZ();
714 }
715 if(aPoly.isClosed())
716 {
717 const basegfx::B3DPoint aPoint(aPoly.getB3DPoint(0));
718 *pInnerSequenceX++ = aPoint.getX();
719 *pInnerSequenceY++ = aPoint.getY();
720 *pInnerSequenceZ++ = aPoint.getZ();
721 }
722 pOuterSequenceX++;
723 pOuterSequenceY++;
724 pOuterSequenceZ++;
725 }
726 rValue <<= aRetval;
727 }
728
setPropertyValueImpl(const OUString & rName,const SfxItemPropertyMapEntry * pProperty,const css::uno::Any & rValue)729 bool Svx3DLatheObject::setPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue )
730 {
731 switch( pProperty->nWID )
732 {
733 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
734 {
735 // pack transformation matrix to the object
736 if( ConvertHomogenMatrixToObject( static_cast< E3dObject* >( GetSdrObject() ), rValue ) )
737 return true;
738 break;
739 }
740 case OWN_ATTR_3D_VALUE_POLYPOLYGON3D:
741 {
742 // pack polygon definition to the object
743 basegfx::B3DPolyPolygon aNewB3DPolyPolygon;
744
745 // #i101520# Probably imported
746 if( PolyPolygonShape3D_to_B3dPolyPolygon( rValue, aNewB3DPolyPolygon, true ) )
747 {
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());
752
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());
758
759 if(nPrevVerticalSegs != nPostVerticalSegs)
760 {
761 // restore the vertical segment count
762 static_cast<E3dLatheObj*>(GetSdrObject())->SetMergedItem(makeSvx3DVerticalSegmentsItem(nPrevVerticalSegs));
763 }
764 return true;
765 }
766 break;
767 }
768 default:
769 return SvxShape::setPropertyValueImpl( rName, pProperty, rValue );
770 }
771
772 throw IllegalArgumentException();
773 }
774
getPropertyValueImpl(const OUString & rName,const SfxItemPropertyMapEntry * pProperty,css::uno::Any & rValue)775 bool Svx3DLatheObject::getPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, css::uno::Any& rValue )
776 {
777 switch( pProperty->nWID )
778 {
779 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
780 {
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;
787 }
788 case OWN_ATTR_3D_VALUE_POLYPOLYGON3D:
789 {
790 const basegfx::B2DPolyPolygon& rPolyPoly = static_cast<E3dLatheObj*>(GetSdrObject())->GetPolyPoly2D();
791 const basegfx::B3DPolyPolygon aB3DPolyPolygon(basegfx::utils::createB3DPolyPolygonFromB2DPolyPolygon(rPolyPoly));
792
793 B3dPolyPolygon_to_PolyPolygonShape3D(aB3DPolyPolygon, rValue);
794 break;
795 }
796 default:
797 return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
798 }
799
800 return true;
801 }
802
803 // css::lang::XServiceInfo
getSupportedServiceNames()804 uno::Sequence< OUString > SAL_CALL Svx3DLatheObject::getSupportedServiceNames()
805 {
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" });
810 }
811
Svx3DExtrudeObject(SdrObject * pObj)812 Svx3DExtrudeObject::Svx3DExtrudeObject(SdrObject* pObj)
813 : SvxShape( pObj, getSvxMapProvider().GetMap(SVXMAP_3DEXTRUDEOBJECT), getSvxMapProvider().GetPropertySet(SVXMAP_3DEXTRUDEOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
814 {
815 }
816
~Svx3DExtrudeObject()817 Svx3DExtrudeObject::~Svx3DExtrudeObject() noexcept
818 {
819 }
820
setPropertyValueImpl(const OUString & rName,const SfxItemPropertyMapEntry * pProperty,const css::uno::Any & rValue)821 bool Svx3DExtrudeObject::setPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue )
822 {
823 switch( pProperty->nWID )
824 {
825 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
826 {
827 // pack transformation matrix to the object
828 if( ConvertHomogenMatrixToObject( static_cast< E3dObject* >( GetSdrObject() ), rValue ) )
829 return true;
830 break;
831 }
832
833 case OWN_ATTR_3D_VALUE_POLYPOLYGON3D:
834 {
835 // pack polygon definition to the object
836 basegfx::B3DPolyPolygon aNewB3DPolyPolygon;
837
838 // #i101520# Probably imported
839 if( PolyPolygonShape3D_to_B3dPolyPolygon( rValue, aNewB3DPolyPolygon, true ) )
840 {
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;
846 }
847 break;
848 }
849 default:
850 return SvxShape::setPropertyValueImpl( rName, pProperty, rValue );
851 }
852
853 throw IllegalArgumentException();
854 }
855
getPropertyValueImpl(const OUString & rName,const SfxItemPropertyMapEntry * pProperty,css::uno::Any & rValue)856 bool Svx3DExtrudeObject::getPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, css::uno::Any& rValue )
857 {
858 switch( pProperty->nWID )
859 {
860 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
861 {
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;
868 }
869
870 case OWN_ATTR_3D_VALUE_POLYPOLYGON3D:
871 {
872 // pack polygon definition
873 const basegfx::B2DPolyPolygon& rPolyPoly = static_cast<E3dExtrudeObj*>(GetSdrObject())->GetExtrudePolygon();
874 const basegfx::B3DPolyPolygon aB3DPolyPolygon(basegfx::utils::createB3DPolyPolygonFromB2DPolyPolygon(rPolyPoly));
875
876 B3dPolyPolygon_to_PolyPolygonShape3D(aB3DPolyPolygon, rValue);
877 break;
878 }
879 default:
880 return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
881 }
882
883 return true;
884 }
885
886 // css::lang::XServiceInfo
getSupportedServiceNames()887 uno::Sequence< OUString > SAL_CALL Svx3DExtrudeObject::getSupportedServiceNames()
888 {
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" });
893 }
894
Svx3DPolygonObject(SdrObject * pObj)895 Svx3DPolygonObject::Svx3DPolygonObject(SdrObject* pObj)
896 : SvxShape( pObj, getSvxMapProvider().GetMap(SVXMAP_3DPOLYGONOBJECT), getSvxMapProvider().GetPropertySet(SVXMAP_3DPOLYGONOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
897 {
898 }
899
~Svx3DPolygonObject()900 Svx3DPolygonObject::~Svx3DPolygonObject() noexcept
901 {
902 }
903
setPropertyValueImpl(const OUString & rName,const SfxItemPropertyMapEntry * pProperty,const css::uno::Any & rValue)904 bool Svx3DPolygonObject::setPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue )
905 {
906 switch( pProperty->nWID )
907 {
908 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
909 {
910 // pack transformation matrix to the object
911 if( ConvertHomogenMatrixToObject( static_cast< E3dObject* >( GetSdrObject() ), rValue ) )
912 return true;
913 break;
914 }
915
916 case OWN_ATTR_3D_VALUE_POLYPOLYGON3D:
917 {
918 // pack polygon definition to the object
919 basegfx::B3DPolyPolygon aNewB3DPolyPolygon;
920
921 // #i101520# Direct API data (e.g. from chart)
922 if( PolyPolygonShape3D_to_B3dPolyPolygon( rValue, aNewB3DPolyPolygon, false ) )
923 {
924 // set polygon
925 static_cast<E3dPolygonObj*>(GetSdrObject())->SetPolyPolygon3D(aNewB3DPolyPolygon);
926 return true;
927 }
928 break;
929 }
930 case OWN_ATTR_3D_VALUE_NORMALSPOLYGON3D:
931 {
932 // pack perpendicular definition to the object
933 basegfx::B3DPolyPolygon aNewB3DPolyPolygon;
934
935 // #i101520# Direct API data (e.g. from chart)
936 if( PolyPolygonShape3D_to_B3dPolyPolygon( rValue, aNewB3DPolyPolygon, false ) )
937 {
938 // set polygon
939 static_cast<E3dPolygonObj*>(GetSdrObject())->SetPolyNormals3D(aNewB3DPolyPolygon);
940 return true;
941 }
942 break;
943 }
944 case OWN_ATTR_3D_VALUE_TEXTUREPOLYGON3D:
945 {
946 // pack texture definition to the object
947 basegfx::B3DPolyPolygon aNewB3DPolyPolygon;
948
949 // #i101520# Direct API data (e.g. from chart)
950 if( PolyPolygonShape3D_to_B3dPolyPolygon( rValue, aNewB3DPolyPolygon, false ) )
951 {
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;
957 }
958 break;
959 }
960 case OWN_ATTR_3D_VALUE_LINEONLY:
961 {
962 bool bNew = false;
963 if( rValue >>= bNew )
964 {
965 static_cast<E3dPolygonObj*>(GetSdrObject())->SetLineOnly(bNew);
966 return true;
967 }
968 break;
969 }
970 default:
971 return SvxShape::setPropertyValueImpl( rName, pProperty, rValue );
972 }
973
974 throw IllegalArgumentException();
975 }
976
getPropertyValueImpl(const OUString & rName,const SfxItemPropertyMapEntry * pProperty,css::uno::Any & rValue)977 bool Svx3DPolygonObject::getPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, css::uno::Any& rValue )
978 {
979 switch( pProperty->nWID )
980 {
981 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
982 {
983 ConvertObjectToHomogenMatric( static_cast< E3dObject* >( GetSdrObject() ), rValue );
984 break;
985 }
986
987 case OWN_ATTR_3D_VALUE_POLYPOLYGON3D:
988 {
989 B3dPolyPolygon_to_PolyPolygonShape3D(static_cast<E3dPolygonObj*>(GetSdrObject())->GetPolyPolygon3D(),rValue);
990 break;
991 }
992
993 case OWN_ATTR_3D_VALUE_NORMALSPOLYGON3D:
994 {
995 B3dPolyPolygon_to_PolyPolygonShape3D(static_cast<E3dPolygonObj*>(GetSdrObject())->GetPolyNormals3D(),rValue);
996 break;
997 }
998
999 case OWN_ATTR_3D_VALUE_TEXTUREPOLYGON3D:
1000 {
1001 // pack texture definition
1002 const basegfx::B2DPolyPolygon& rPolyPoly = static_cast<E3dPolygonObj*>(GetSdrObject())->GetPolyTexture2D();
1003 const basegfx::B3DPolyPolygon aB3DPolyPolygon(basegfx::utils::createB3DPolyPolygonFromB2DPolyPolygon(rPolyPoly));
1004
1005 B3dPolyPolygon_to_PolyPolygonShape3D(aB3DPolyPolygon,rValue);
1006 break;
1007 }
1008
1009 case OWN_ATTR_3D_VALUE_LINEONLY:
1010 {
1011 rValue <<= static_cast<E3dPolygonObj*>(GetSdrObject())->GetLineOnly();
1012 break;
1013 }
1014
1015 default:
1016 return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
1017 }
1018
1019 return true;
1020 }
1021
1022 // css::lang::XServiceInfo
getSupportedServiceNames()1023 uno::Sequence< OUString > SAL_CALL Svx3DPolygonObject::getSupportedServiceNames()
1024 {
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" });
1029 }
1030
1031 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1032