1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 : SvxShapeGroupAnyD( pObj
, getSvxMapProvider().GetMap(SVXMAP_3DSCENEOBJECT
), getSvxMapProvider().GetPropertySet(SVXMAP_3DSCENEOBJECT
, SdrObject::GetGlobalDrawObjectItemPool()) )
72 Svx3DSceneObject::~Svx3DSceneObject() noexcept
77 void Svx3DSceneObject::Create( SdrObject
* pNewObj
, SvxDrawPage
* pNewPage
)
79 SvxShape::Create( pNewObj
, pNewPage
);
84 uno::Any SAL_CALL
Svx3DSceneObject::queryAggregation( const uno::Type
& rType
)
88 QUERYINT( drawing::XShapes
);
89 else QUERYINT( container::XIndexAccess
);
90 else QUERYINT( container::XElementAccess
);
92 return SvxShape::queryAggregation( rType
);
97 uno::Any SAL_CALL
Svx3DSceneObject::queryInterface( const uno::Type
& rType
)
99 return SvxShape::queryInterface( rType
);
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::getFromUnoTunnel
<SvxShape
>( xShape
);
116 if(!HasSdrObject() || !mxPage
.is() || pShape
== nullptr || nullptr != pShape
->GetSdrObject() )
117 throw uno::RuntimeException();
119 rtl::Reference
<SdrObject
> pSdrShape
= mxPage
->CreateSdrObject_( xShape
);
120 if( DynCastE3dObject(pSdrShape
.get()) )
122 GetSdrObject()->GetSubList()->NbcInsertObject( pSdrShape
.get() );
123 pShape
->Create(pSdrShape
.get(), mxPage
.get());
128 throw uno::RuntimeException();
131 GetSdrObject()->getSdrModelFromSdrObject().SetChanged();
134 void Svx3DSceneObject::addShape( SvxShape
& rShape
)
136 SolarMutexGuard aGuard
;
138 if(!HasSdrObject() || !mxPage
.is() || nullptr != rShape
.GetSdrObject() )
139 throw uno::RuntimeException();
141 rtl::Reference
<SdrObject
> pSdrShape
= mxPage
->CreateSdrObject_( &rShape
);
142 if( DynCastE3dObject(pSdrShape
.get()) )
144 GetSdrObject()->GetSubList()->NbcInsertObject( pSdrShape
.get() );
145 rShape
.Create(pSdrShape
.get(), mxPage
.get());
150 throw uno::RuntimeException();
153 GetSdrObject()->getSdrModelFromSdrObject().SetChanged();
156 void SAL_CALL
Svx3DSceneObject::remove( const Reference
< drawing::XShape
>& xShape
)
158 SolarMutexGuard aGuard
;
160 SdrObject
* pSdrShape
= SdrObject::getSdrObjectFromXShape( xShape
);
162 if(!HasSdrObject() || !pSdrShape
||
163 pSdrShape
->getParentSdrObjectFromSdrObject() != GetSdrObject())
164 throw uno::RuntimeException();
166 SdrObjList
& rList
= *pSdrShape
->getParentSdrObjListFromSdrObject();
168 const size_t nObjCount
= rList
.GetObjCount();
170 while( nObjNum
< nObjCount
)
172 if(rList
.GetObj( nObjNum
) == pSdrShape
)
177 if( nObjNum
< nObjCount
)
179 rList
.NbcRemoveObject( nObjNum
);
183 SAL_WARN( "svx", "Fatality! SdrObject is not belonging to its SdrObjList! [CL]" );
188 sal_Int32 SAL_CALL
Svx3DSceneObject::getCount()
190 SolarMutexGuard aGuard
;
192 sal_Int32 nRetval
= 0;
194 if(HasSdrObject() && DynCastE3dScene(GetSdrObject()) && GetSdrObject()->GetSubList())
195 nRetval
= GetSdrObject()->GetSubList()->GetObjCount();
200 uno::Any SAL_CALL
Svx3DSceneObject::getByIndex( sal_Int32 Index
)
202 SolarMutexGuard aGuard
;
204 if( !HasSdrObject() || GetSdrObject()->GetSubList() == nullptr )
205 throw uno::RuntimeException();
207 if( Index
<0 || GetSdrObject()->GetSubList()->GetObjCount() <= o3tl::make_unsigned(Index
) )
208 throw lang::IndexOutOfBoundsException();
210 SdrObject
* pDestObj
= GetSdrObject()->GetSubList()->GetObj( Index
);
211 if(pDestObj
== nullptr)
212 throw lang::IndexOutOfBoundsException();
214 Reference
< drawing::XShape
> xShape( pDestObj
->getUnoShape(), uno::UNO_QUERY
);
215 return uno::Any(xShape
);
219 // css::container::XElementAccess
221 uno::Type SAL_CALL
Svx3DSceneObject::getElementType()
223 return cppu::UnoType
<drawing::XShape
>::get();
227 sal_Bool SAL_CALL
Svx3DSceneObject::hasElements()
229 SolarMutexGuard aGuard
;
231 return HasSdrObject() && GetSdrObject()->GetSubList() && (GetSdrObject()->GetSubList()->GetObjCount() > 0);
235 static bool ConvertHomogenMatrixToObject( E3dObject
* pObject
, const Any
& rValue
)
237 drawing::HomogenMatrix aMat
;
238 if( rValue
>>= aMat
)
240 pObject
->SetTransform(basegfx::utils::UnoHomogenMatrixToB3DHomMatrix(aMat
));
246 static void ConvertObjectToHomogenMatric( E3dObject
const * pObject
, Any
& rValue
)
248 drawing::HomogenMatrix aHomMat
;
249 const basegfx::B3DHomMatrix
& rMat
= pObject
->GetTransform();
250 basegfx::utils::B3DHomMatrixToUnoHomogenMatrix(rMat
, aHomMat
);
256 struct ImpRememberTransAndRect
258 basegfx::B3DHomMatrix maMat
;
259 tools::Rectangle maRect
;
264 bool Svx3DSceneObject::setPropertyValueImpl( const OUString
& rName
, const SfxItemPropertyMapEntry
* pProperty
, const css::uno::Any
& rValue
)
266 switch( pProperty
->nWID
)
268 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX
:
270 // patch transformation matrix to the object
271 if( ConvertHomogenMatrixToObject( static_cast< E3dObject
* >( GetSdrObject() ), rValue
) )
275 case OWN_ATTR_3D_VALUE_CAMERA_GEOMETRY
:
277 // set CameraGeometry at scene
278 E3dScene
* pScene
= static_cast< E3dScene
* >( GetSdrObject() );
279 drawing::CameraGeometry aCamGeo
;
281 if(rValue
>>= aCamGeo
)
283 basegfx::B3DPoint
aVRP(aCamGeo
.vrp
.PositionX
, aCamGeo
.vrp
.PositionY
, aCamGeo
.vrp
.PositionZ
);
284 basegfx::B3DVector
aVPN(aCamGeo
.vpn
.DirectionX
, aCamGeo
.vpn
.DirectionY
, aCamGeo
.vpn
.DirectionZ
);
285 basegfx::B3DVector
aVUP(aCamGeo
.vup
.DirectionX
, aCamGeo
.vup
.DirectionY
, aCamGeo
.vup
.DirectionZ
);
287 // rescue scene transformation
288 ImpRememberTransAndRect aSceneTAR
;
289 aSceneTAR
.maMat
= pScene
->GetTransform();
290 aSceneTAR
.maRect
= pScene
->GetSnapRect();
292 // rescue object transformations
293 SdrObjListIter
aIter(pScene
->GetSubList(), SdrIterMode::DeepWithGroups
);
294 std::vector
<basegfx::B3DHomMatrix
*> aObjTrans
;
295 while(aIter
.IsMore())
297 E3dObject
* p3DObj
= static_cast<E3dObject
*>(aIter
.Next());
298 basegfx::B3DHomMatrix
* pNew
= new basegfx::B3DHomMatrix
;
299 *pNew
= p3DObj
->GetTransform();
300 aObjTrans
.push_back(pNew
);
303 // reset object transformations
305 while(aIter
.IsMore())
307 E3dObject
* p3DObj
= static_cast<E3dObject
*>(aIter
.Next());
308 p3DObj
->NbcSetTransform(basegfx::B3DHomMatrix());
311 // reset scene transformation and make a complete recalc
312 pScene
->NbcSetTransform(basegfx::B3DHomMatrix());
314 // fill old camera from new parameters
315 Camera3D
aCam(pScene
->GetCamera());
316 const basegfx::B3DRange
& rVolume
= pScene
->GetBoundVolume();
317 double fW
= rVolume
.getWidth();
318 double fH
= rVolume
.getHeight();
320 const SfxItemSet
& rSceneSet
= pScene
->GetMergedItemSet();
322 static_cast<double>(rSceneSet
.Get(SDRATTR_3DSCENE_DISTANCE
).GetValue());
324 static_cast<double>(rSceneSet
.Get(SDRATTR_3DSCENE_FOCAL_LENGTH
).GetValue());
326 aCam
.SetAutoAdjustProjection(false);
327 aCam
.SetViewWindow(- fW
/ 2, - fH
/ 2, fW
, fH
);
328 basegfx::B3DPoint aLookAt
;
329 basegfx::B3DPoint
aCamPos(0.0, 0.0, fCamPosZ
);
330 aCam
.SetPosAndLookAt(aCamPos
, aLookAt
);
331 aCam
.SetFocalLength(fCamFocal
/ 100.0);
332 aCam
.SetDeviceWindow(tools::Rectangle(0, 0, static_cast<tools::Long
>(fW
), static_cast<tools::Long
>(fH
)));
335 pScene
->SetCamera(aCam
);
337 // #91047# use imported VRP, VPN and VUP (if used)
338 bool bVRPUsed(!aVRP
.equal(basegfx::B3DPoint(0.0, 0.0, 1.0)));
339 bool bVPNUsed(!aVPN
.equal(basegfx::B3DVector(0.0, 0.0, 1.0)));
340 bool bVUPUsed(!aVUP
.equal(basegfx::B3DVector(0.0, 1.0, 0.0)));
342 if(bVRPUsed
|| bVPNUsed
|| bVUPUsed
)
344 pScene
->GetCameraSet().SetViewportValues(aVRP
, aVPN
, aVUP
);
347 // set object transformations again at objects
349 sal_uInt32
nIndex(0);
350 while(aIter
.IsMore())
352 E3dObject
* p3DObj
= static_cast<E3dObject
*>(aIter
.Next());
353 basegfx::B3DHomMatrix
* pMat
= aObjTrans
[nIndex
++];
354 p3DObj
->NbcSetTransform(*pMat
);
358 // set scene transformation again at scene
359 pScene
->NbcSetTransform(aSceneTAR
.maMat
);
360 pScene
->NbcSetSnapRect(aSceneTAR
.maRect
);
367 return SvxShape::setPropertyValueImpl(rName
, pProperty
, rValue
);
370 throw IllegalArgumentException();
374 bool Svx3DSceneObject::getPropertyValueImpl(const OUString
& rName
, const SfxItemPropertyMapEntry
* pProperty
,
375 css::uno::Any
& rValue
)
377 switch( pProperty
->nWID
)
379 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX
:
381 // patch object to a homogeneous 4x4 matrix
382 ConvertObjectToHomogenMatric( static_cast< E3dObject
* >( GetSdrObject() ), rValue
);
385 case OWN_ATTR_3D_VALUE_CAMERA_GEOMETRY
:
387 // get CameraGeometry from scene
388 E3dScene
* pScene
= static_cast< E3dScene
* >( GetSdrObject() );
389 drawing::CameraGeometry aCamGeo
;
391 // fill Vectors from scene camera
392 B3dCamera
& aCameraSet
= pScene
->GetCameraSet();
393 basegfx::B3DPoint
aVRP(aCameraSet
.GetVRP());
394 basegfx::B3DVector
aVPN(aCameraSet
.GetVPN());
395 basegfx::B3DVector
aVUP(aCameraSet
.GetVUV());
397 // transfer to structure
398 aCamGeo
.vrp
.PositionX
= aVRP
.getX();
399 aCamGeo
.vrp
.PositionY
= aVRP
.getY();
400 aCamGeo
.vrp
.PositionZ
= aVRP
.getZ();
401 aCamGeo
.vpn
.DirectionX
= aVPN
.getX();
402 aCamGeo
.vpn
.DirectionY
= aVPN
.getY();
403 aCamGeo
.vpn
.DirectionZ
= aVPN
.getZ();
404 aCamGeo
.vup
.DirectionX
= aVUP
.getX();
405 aCamGeo
.vup
.DirectionY
= aVUP
.getY();
406 aCamGeo
.vup
.DirectionZ
= aVUP
.getZ();
412 return SvxShape::getPropertyValueImpl( rName
, pProperty
, rValue
);
418 // css::lang::XServiceInfo
419 uno::Sequence
< OUString
> SAL_CALL
Svx3DSceneObject::getSupportedServiceNames()
421 return comphelper::concatSequences(
422 SvxShape::getSupportedServiceNames(),
423 std::initializer_list
<OUString
>{ u
"com.sun.star.drawing.Shape3DScene"_ustr
});
426 Svx3DCubeObject::Svx3DCubeObject(SdrObject
* pObj
)
427 : SvxShape( pObj
, getSvxMapProvider().GetMap(SVXMAP_3DCUBEOBJECT
), getSvxMapProvider().GetPropertySet(SVXMAP_3DCUBEOBJECT
, SdrObject::GetGlobalDrawObjectItemPool()) )
431 Svx3DCubeObject::~Svx3DCubeObject() noexcept
435 bool Svx3DCubeObject::setPropertyValueImpl( const OUString
& rName
, const SfxItemPropertyMapEntry
* pProperty
, const css::uno::Any
& rValue
)
437 SolarMutexGuard aGuard
;
439 switch( pProperty
->nWID
)
441 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX
:
443 // pack transformationmatrix to the object
444 if( ConvertHomogenMatrixToObject( static_cast< E3dObject
* >( GetSdrObject() ), rValue
) )
448 case OWN_ATTR_3D_VALUE_POSITION
:
450 // pack position to the object
451 drawing::Position3D aUnoPos
;
452 if( rValue
>>= aUnoPos
)
454 basegfx::B3DPoint
aPos(aUnoPos
.PositionX
, aUnoPos
.PositionY
, aUnoPos
.PositionZ
);
455 static_cast< E3dCubeObj
* >( GetSdrObject() )->SetCubePos(aPos
);
460 case OWN_ATTR_3D_VALUE_SIZE
:
462 // pack size to the object
463 drawing::Direction3D aDirection
;
464 if( rValue
>>= aDirection
)
466 basegfx::B3DVector
aSize(aDirection
.DirectionX
, aDirection
.DirectionY
, aDirection
.DirectionZ
);
467 static_cast< E3dCubeObj
* >( GetSdrObject() )->SetCubeSize(aSize
);
472 case OWN_ATTR_3D_VALUE_POS_IS_CENTER
:
475 // pack sal_Bool bPosIsCenter to the object
476 if( rValue
>>= bNew
)
478 static_cast< E3dCubeObj
* >( GetSdrObject() )->SetPosIsCenter(bNew
);
484 return SvxShape::setPropertyValueImpl( rName
, pProperty
, rValue
);
487 throw IllegalArgumentException();
490 bool Svx3DCubeObject::getPropertyValueImpl( const OUString
& rName
, const SfxItemPropertyMapEntry
* pProperty
, css::uno::Any
& rValue
)
492 switch( pProperty
->nWID
)
494 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX
:
496 // pack transformation to a homogeneous matrix
497 ConvertObjectToHomogenMatric( static_cast< E3dObject
* >( GetSdrObject() ), rValue
);
500 case OWN_ATTR_3D_VALUE_POSITION
:
503 const basegfx::B3DPoint
& rPos
= static_cast<E3dCubeObj
*>(GetSdrObject())->GetCubePos();
504 drawing::Position3D aPos
;
506 aPos
.PositionX
= rPos
.getX();
507 aPos
.PositionY
= rPos
.getY();
508 aPos
.PositionZ
= rPos
.getZ();
513 case OWN_ATTR_3D_VALUE_SIZE
:
516 const basegfx::B3DVector
& rSize
= static_cast<E3dCubeObj
*>(GetSdrObject())->GetCubeSize();
517 drawing::Direction3D aDir
;
519 aDir
.DirectionX
= rSize
.getX();
520 aDir
.DirectionY
= rSize
.getY();
521 aDir
.DirectionZ
= rSize
.getZ();
526 case OWN_ATTR_3D_VALUE_POS_IS_CENTER
:
528 rValue
<<= static_cast<E3dCubeObj
*>(GetSdrObject())->GetPosIsCenter();
532 return SvxShape::getPropertyValueImpl( rName
, pProperty
, rValue
);
538 // css::lang::XServiceInfo
539 uno::Sequence
< OUString
> SAL_CALL
Svx3DCubeObject::getSupportedServiceNames()
541 return comphelper::concatSequences(
542 SvxShape::getSupportedServiceNames(),
543 std::initializer_list
<OUString
>{ u
"com.sun.star.drawing.Shape3D"_ustr
,
544 u
"com.sun.star.drawing.Shape3DCube"_ustr
});
547 Svx3DSphereObject::Svx3DSphereObject(SdrObject
* pObj
)
548 : SvxShape( pObj
, getSvxMapProvider().GetMap(SVXMAP_3DSPHEREOBJECT
), getSvxMapProvider().GetPropertySet(SVXMAP_3DSPHEREOBJECT
, SdrObject::GetGlobalDrawObjectItemPool()) )
552 Svx3DSphereObject::~Svx3DSphereObject() noexcept
556 bool Svx3DSphereObject::setPropertyValueImpl( const OUString
& rName
, const SfxItemPropertyMapEntry
* pProperty
, const css::uno::Any
& rValue
)
558 switch( pProperty
->nWID
)
560 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX
:
562 // pack transformation matrix to the object
563 if( ConvertHomogenMatrixToObject( static_cast< E3dObject
* >( GetSdrObject() ), rValue
) )
568 case OWN_ATTR_3D_VALUE_POSITION
:
570 // pack position to the object
571 drawing::Position3D aUnoPos
;
572 if( rValue
>>= aUnoPos
)
574 basegfx::B3DPoint
aPos(aUnoPos
.PositionX
, aUnoPos
.PositionY
, aUnoPos
.PositionZ
);
575 static_cast<E3dSphereObj
*>(GetSdrObject())->SetCenter(aPos
);
581 case OWN_ATTR_3D_VALUE_SIZE
:
583 // pack size to the object
584 drawing::Direction3D aDir
;
585 if( rValue
>>= aDir
)
587 basegfx::B3DVector
aPos(aDir
.DirectionX
, aDir
.DirectionY
, aDir
.DirectionZ
);
588 static_cast<E3dSphereObj
*>(GetSdrObject())->SetSize(aPos
);
594 return SvxShape::setPropertyValueImpl( rName
, pProperty
, rValue
);
597 throw IllegalArgumentException();
600 bool Svx3DSphereObject::getPropertyValueImpl( const OUString
& rName
, const SfxItemPropertyMapEntry
* pProperty
, css::uno::Any
& rValue
)
602 switch( pProperty
->nWID
)
604 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX
:
606 // pack transformation to a homogeneous matrix
607 ConvertObjectToHomogenMatric( static_cast< E3dObject
* >( GetSdrObject() ), rValue
);
610 case OWN_ATTR_3D_VALUE_POSITION
:
613 const basegfx::B3DPoint
& rPos
= static_cast<E3dSphereObj
*>(GetSdrObject())->Center();
614 drawing::Position3D aPos
;
616 aPos
.PositionX
= rPos
.getX();
617 aPos
.PositionY
= rPos
.getY();
618 aPos
.PositionZ
= rPos
.getZ();
623 case OWN_ATTR_3D_VALUE_SIZE
:
626 const basegfx::B3DVector
& rSize
= static_cast<E3dSphereObj
*>(GetSdrObject())->Size();
627 drawing::Direction3D aDir
;
629 aDir
.DirectionX
= rSize
.getX();
630 aDir
.DirectionY
= rSize
.getY();
631 aDir
.DirectionZ
= rSize
.getZ();
637 return SvxShape::getPropertyValueImpl( rName
, pProperty
, rValue
);
643 // css::lang::XServiceInfo
644 uno::Sequence
< OUString
> SAL_CALL
Svx3DSphereObject::getSupportedServiceNames()
646 return comphelper::concatSequences(
647 SvxShape::getSupportedServiceNames(),
648 std::initializer_list
<OUString
>{ u
"com.sun.star.drawing.Shape3D"_ustr
,
649 u
"com.sun.star.drawing.Shape3DSphere"_ustr
});
652 Svx3DLatheObject::Svx3DLatheObject(SdrObject
* pObj
)
653 : SvxShape( pObj
, getSvxMapProvider().GetMap(SVXMAP_3DLATHEOBJECT
), getSvxMapProvider().GetPropertySet(SVXMAP_3DLATHEOBJECT
, SdrObject::GetGlobalDrawObjectItemPool()) )
657 Svx3DLatheObject::~Svx3DLatheObject() noexcept
661 static bool PolyPolygonShape3D_to_B3dPolyPolygon(
663 basegfx::B3DPolyPolygon
& rResultPolygon
,
664 bool bCorrectPolygon
)
666 drawing::PolyPolygonShape3D aSourcePolyPolygon
;
667 if( !(rValue
>>= aSourcePolyPolygon
) )
670 sal_Int32 nOuterSequenceCount
= aSourcePolyPolygon
.SequenceX
.getLength();
671 if(nOuterSequenceCount
!= aSourcePolyPolygon
.SequenceY
.getLength() || nOuterSequenceCount
!= aSourcePolyPolygon
.SequenceZ
.getLength())
674 const drawing::DoubleSequence
* pInnerSequenceX
= aSourcePolyPolygon
.SequenceX
.getConstArray();
675 const drawing::DoubleSequence
* pInnerSequenceY
= aSourcePolyPolygon
.SequenceY
.getConstArray();
676 const drawing::DoubleSequence
* pInnerSequenceZ
= aSourcePolyPolygon
.SequenceZ
.getConstArray();
677 for(sal_Int32
a(0);a
<nOuterSequenceCount
;a
++)
679 sal_Int32 nInnerSequenceCount
= pInnerSequenceX
->getLength();
680 if(nInnerSequenceCount
!= pInnerSequenceY
->getLength() || nInnerSequenceCount
!= pInnerSequenceZ
->getLength())
684 basegfx::B3DPolygon aNewPolygon
;
685 const double* pArrayX
= pInnerSequenceX
->getConstArray();
686 const double* pArrayY
= pInnerSequenceY
->getConstArray();
687 const double* pArrayZ
= pInnerSequenceZ
->getConstArray();
688 for(sal_Int32
b(0);b
<nInnerSequenceCount
;b
++)
690 aNewPolygon
.append(basegfx::B3DPoint(*pArrayX
++,*pArrayY
++,*pArrayZ
++));
696 // #i101520# correction is needed for imported polygons of old format,
700 basegfx::utils::checkClosed(aNewPolygon
);
703 rResultPolygon
.append(aNewPolygon
);
708 static void B3dPolyPolygon_to_PolyPolygonShape3D( const basegfx::B3DPolyPolygon
& rSourcePolyPolygon
, Any
& rValue
)
710 drawing::PolyPolygonShape3D aRetval
;
711 aRetval
.SequenceX
.realloc(rSourcePolyPolygon
.count());
712 aRetval
.SequenceY
.realloc(rSourcePolyPolygon
.count());
713 aRetval
.SequenceZ
.realloc(rSourcePolyPolygon
.count());
714 drawing::DoubleSequence
* pOuterSequenceX
= aRetval
.SequenceX
.getArray();
715 drawing::DoubleSequence
* pOuterSequenceY
= aRetval
.SequenceY
.getArray();
716 drawing::DoubleSequence
* pOuterSequenceZ
= aRetval
.SequenceZ
.getArray();
717 for(sal_uInt32
a(0);a
<rSourcePolyPolygon
.count();a
++)
719 const basegfx::B3DPolygon
& aPoly(rSourcePolyPolygon
.getB3DPolygon(a
));
720 sal_Int32
nPointCount(aPoly
.count());
721 if(aPoly
.isClosed()) nPointCount
++;
722 pOuterSequenceX
->realloc(nPointCount
);
723 pOuterSequenceY
->realloc(nPointCount
);
724 pOuterSequenceZ
->realloc(nPointCount
);
725 double* pInnerSequenceX
= pOuterSequenceX
->getArray();
726 double* pInnerSequenceY
= pOuterSequenceY
->getArray();
727 double* pInnerSequenceZ
= pOuterSequenceZ
->getArray();
728 for(sal_uInt32
b(0);b
<aPoly
.count();b
++)
730 const basegfx::B3DPoint
aPoint(aPoly
.getB3DPoint(b
));
731 *pInnerSequenceX
++ = aPoint
.getX();
732 *pInnerSequenceY
++ = aPoint
.getY();
733 *pInnerSequenceZ
++ = aPoint
.getZ();
737 const basegfx::B3DPoint
aPoint(aPoly
.getB3DPoint(0));
738 *pInnerSequenceX
++ = aPoint
.getX();
739 *pInnerSequenceY
++ = aPoint
.getY();
740 *pInnerSequenceZ
++ = aPoint
.getZ();
749 bool Svx3DLatheObject::setPropertyValueImpl( const OUString
& rName
, const SfxItemPropertyMapEntry
* pProperty
, const css::uno::Any
& rValue
)
751 switch( pProperty
->nWID
)
753 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX
:
755 // pack transformation matrix to the object
756 if( ConvertHomogenMatrixToObject( static_cast< E3dObject
* >( GetSdrObject() ), rValue
) )
760 case OWN_ATTR_3D_VALUE_POLYPOLYGON3D
:
762 // pack polygon definition to the object
763 basegfx::B3DPolyPolygon aNewB3DPolyPolygon
;
765 // #i101520# Probably imported
766 if( PolyPolygonShape3D_to_B3dPolyPolygon( rValue
, aNewB3DPolyPolygon
, true ) )
768 // #105127# SetPolyPoly3D sets the Svx3DVerticalSegmentsItem to the number
769 // of points of the polygon. Thus, value gets lost. To avoid this, rescue
770 // item here and re-set after setting the polygon.
771 const sal_uInt32
nPrevVerticalSegs(static_cast<E3dLatheObj
*>(GetSdrObject())->GetVerticalSegments());
774 const basegfx::B3DHomMatrix aIdentity
;
775 const basegfx::B2DPolyPolygon
aB2DPolyPolygon(basegfx::utils::createB2DPolyPolygonFromB3DPolyPolygon(aNewB3DPolyPolygon
, aIdentity
));
776 static_cast<E3dLatheObj
*>(GetSdrObject())->SetPolyPoly2D(aB2DPolyPolygon
);
777 const sal_uInt32
nPostVerticalSegs(static_cast<E3dLatheObj
*>(GetSdrObject())->GetVerticalSegments());
779 if(nPrevVerticalSegs
!= nPostVerticalSegs
)
781 // restore the vertical segment count
782 static_cast<E3dLatheObj
*>(GetSdrObject())->SetMergedItem(makeSvx3DVerticalSegmentsItem(nPrevVerticalSegs
));
789 return SvxShape::setPropertyValueImpl( rName
, pProperty
, rValue
);
792 throw IllegalArgumentException();
795 bool Svx3DLatheObject::getPropertyValueImpl( const OUString
& rName
, const SfxItemPropertyMapEntry
* pProperty
, css::uno::Any
& rValue
)
797 switch( pProperty
->nWID
)
799 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX
:
801 // pack transformation to a homogeneous matrix
802 drawing::HomogenMatrix aHomMat
;
803 basegfx::B3DHomMatrix aMat
= static_cast<E3dObject
*>(GetSdrObject())->GetTransform();
804 basegfx::utils::B3DHomMatrixToUnoHomogenMatrix(aMat
, aHomMat
);
808 case OWN_ATTR_3D_VALUE_POLYPOLYGON3D
:
810 const basegfx::B2DPolyPolygon
& rPolyPoly
= static_cast<E3dLatheObj
*>(GetSdrObject())->GetPolyPoly2D();
811 const basegfx::B3DPolyPolygon
aB3DPolyPolygon(basegfx::utils::createB3DPolyPolygonFromB2DPolyPolygon(rPolyPoly
));
813 B3dPolyPolygon_to_PolyPolygonShape3D(aB3DPolyPolygon
, rValue
);
817 return SvxShape::getPropertyValueImpl( rName
, pProperty
, rValue
);
823 // css::lang::XServiceInfo
824 uno::Sequence
< OUString
> SAL_CALL
Svx3DLatheObject::getSupportedServiceNames()
826 return comphelper::concatSequences(
827 SvxShape::getSupportedServiceNames(),
828 std::initializer_list
<OUString
>{ u
"com.sun.star.drawing.Shape3D"_ustr
,
829 u
"com.sun.star.drawing.Shape3DLathe"_ustr
});
832 Svx3DExtrudeObject::Svx3DExtrudeObject(SdrObject
* pObj
)
833 : SvxShape( pObj
, getSvxMapProvider().GetMap(SVXMAP_3DEXTRUDEOBJECT
), getSvxMapProvider().GetPropertySet(SVXMAP_3DEXTRUDEOBJECT
, SdrObject::GetGlobalDrawObjectItemPool()) )
837 Svx3DExtrudeObject::~Svx3DExtrudeObject() noexcept
841 bool Svx3DExtrudeObject::setPropertyValueImpl( const OUString
& rName
, const SfxItemPropertyMapEntry
* pProperty
, const css::uno::Any
& rValue
)
843 switch( pProperty
->nWID
)
845 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX
:
847 // pack transformation matrix to the object
848 if( ConvertHomogenMatrixToObject( static_cast< E3dObject
* >( GetSdrObject() ), rValue
) )
853 case OWN_ATTR_3D_VALUE_POLYPOLYGON3D
:
855 // pack polygon definition to the object
856 basegfx::B3DPolyPolygon aNewB3DPolyPolygon
;
858 // #i101520# Probably imported
859 if( PolyPolygonShape3D_to_B3dPolyPolygon( rValue
, aNewB3DPolyPolygon
, true ) )
862 const basegfx::B3DHomMatrix aIdentity
;
863 const basegfx::B2DPolyPolygon
aB2DPolyPolygon(basegfx::utils::createB2DPolyPolygonFromB3DPolyPolygon(aNewB3DPolyPolygon
, aIdentity
));
864 static_cast<E3dExtrudeObj
*>(GetSdrObject())->SetExtrudePolygon(aB2DPolyPolygon
);
870 return SvxShape::setPropertyValueImpl( rName
, pProperty
, rValue
);
873 throw IllegalArgumentException();
876 bool Svx3DExtrudeObject::getPropertyValueImpl( const OUString
& rName
, const SfxItemPropertyMapEntry
* pProperty
, css::uno::Any
& rValue
)
878 switch( pProperty
->nWID
)
880 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX
:
882 // pack transformation to a homogeneous matrix
883 drawing::HomogenMatrix aHomMat
;
884 basegfx::B3DHomMatrix aMat
= static_cast<E3dObject
*>(GetSdrObject())->GetTransform();
885 basegfx::utils::B3DHomMatrixToUnoHomogenMatrix(aMat
, aHomMat
);
890 case OWN_ATTR_3D_VALUE_POLYPOLYGON3D
:
892 // pack polygon definition
893 const basegfx::B2DPolyPolygon
& rPolyPoly
= static_cast<E3dExtrudeObj
*>(GetSdrObject())->GetExtrudePolygon();
894 const basegfx::B3DPolyPolygon
aB3DPolyPolygon(basegfx::utils::createB3DPolyPolygonFromB2DPolyPolygon(rPolyPoly
));
896 B3dPolyPolygon_to_PolyPolygonShape3D(aB3DPolyPolygon
, rValue
);
900 return SvxShape::getPropertyValueImpl( rName
, pProperty
, rValue
);
906 // css::lang::XServiceInfo
907 uno::Sequence
< OUString
> SAL_CALL
Svx3DExtrudeObject::getSupportedServiceNames()
909 return comphelper::concatSequences(
910 SvxShape::getSupportedServiceNames(),
911 std::initializer_list
<OUString
>{ u
"com.sun.star.drawing.Shape3D"_ustr
,
912 u
"com.sun.star.drawing.Shape3DExtrude"_ustr
});
915 Svx3DPolygonObject::Svx3DPolygonObject(SdrObject
* pObj
)
916 : SvxShape( pObj
, getSvxMapProvider().GetMap(SVXMAP_3DPOLYGONOBJECT
), getSvxMapProvider().GetPropertySet(SVXMAP_3DPOLYGONOBJECT
, SdrObject::GetGlobalDrawObjectItemPool()) )
920 Svx3DPolygonObject::~Svx3DPolygonObject() noexcept
924 bool Svx3DPolygonObject::setPropertyValueImpl( const OUString
& rName
, const SfxItemPropertyMapEntry
* pProperty
, const css::uno::Any
& rValue
)
926 switch( pProperty
->nWID
)
928 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX
:
930 // pack transformation matrix to the object
931 if( ConvertHomogenMatrixToObject( static_cast< E3dObject
* >( GetSdrObject() ), rValue
) )
936 case OWN_ATTR_3D_VALUE_POLYPOLYGON3D
:
938 // pack polygon definition to the object
939 basegfx::B3DPolyPolygon aNewB3DPolyPolygon
;
941 // #i101520# Direct API data (e.g. from chart)
942 if( PolyPolygonShape3D_to_B3dPolyPolygon( rValue
, aNewB3DPolyPolygon
, false ) )
945 static_cast<E3dPolygonObj
*>(GetSdrObject())->SetPolyPolygon3D(aNewB3DPolyPolygon
);
950 case OWN_ATTR_3D_VALUE_NORMALSPOLYGON3D
:
952 // pack perpendicular definition to the object
953 basegfx::B3DPolyPolygon aNewB3DPolyPolygon
;
955 // #i101520# Direct API data (e.g. from chart)
956 if( PolyPolygonShape3D_to_B3dPolyPolygon( rValue
, aNewB3DPolyPolygon
, false ) )
959 static_cast<E3dPolygonObj
*>(GetSdrObject())->SetPolyNormals3D(aNewB3DPolyPolygon
);
964 case OWN_ATTR_3D_VALUE_TEXTUREPOLYGON3D
:
966 // pack texture definition to the object
967 basegfx::B3DPolyPolygon aNewB3DPolyPolygon
;
969 // #i101520# Direct API data (e.g. from chart)
970 if( PolyPolygonShape3D_to_B3dPolyPolygon( rValue
, aNewB3DPolyPolygon
, false ) )
973 const basegfx::B3DHomMatrix aIdentity
;
974 const basegfx::B2DPolyPolygon
aB2DPolyPolygon(basegfx::utils::createB2DPolyPolygonFromB3DPolyPolygon(aNewB3DPolyPolygon
, aIdentity
));
975 static_cast<E3dPolygonObj
*>(GetSdrObject())->SetPolyTexture2D(aB2DPolyPolygon
);
980 case OWN_ATTR_3D_VALUE_LINEONLY
:
983 if( rValue
>>= bNew
)
985 static_cast<E3dPolygonObj
*>(GetSdrObject())->SetLineOnly(bNew
);
991 return SvxShape::setPropertyValueImpl( rName
, pProperty
, rValue
);
994 throw IllegalArgumentException();
997 bool Svx3DPolygonObject::getPropertyValueImpl( const OUString
& rName
, const SfxItemPropertyMapEntry
* pProperty
, css::uno::Any
& rValue
)
999 switch( pProperty
->nWID
)
1001 case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX
:
1003 ConvertObjectToHomogenMatric( static_cast< E3dObject
* >( GetSdrObject() ), rValue
);
1007 case OWN_ATTR_3D_VALUE_POLYPOLYGON3D
:
1009 B3dPolyPolygon_to_PolyPolygonShape3D(static_cast<E3dPolygonObj
*>(GetSdrObject())->GetPolyPolygon3D(),rValue
);
1013 case OWN_ATTR_3D_VALUE_NORMALSPOLYGON3D
:
1015 B3dPolyPolygon_to_PolyPolygonShape3D(static_cast<E3dPolygonObj
*>(GetSdrObject())->GetPolyNormals3D(),rValue
);
1019 case OWN_ATTR_3D_VALUE_TEXTUREPOLYGON3D
:
1021 // pack texture definition
1022 const basegfx::B2DPolyPolygon
& rPolyPoly
= static_cast<E3dPolygonObj
*>(GetSdrObject())->GetPolyTexture2D();
1023 const basegfx::B3DPolyPolygon
aB3DPolyPolygon(basegfx::utils::createB3DPolyPolygonFromB2DPolyPolygon(rPolyPoly
));
1025 B3dPolyPolygon_to_PolyPolygonShape3D(aB3DPolyPolygon
,rValue
);
1029 case OWN_ATTR_3D_VALUE_LINEONLY
:
1031 rValue
<<= static_cast<E3dPolygonObj
*>(GetSdrObject())->GetLineOnly();
1036 return SvxShape::getPropertyValueImpl( rName
, pProperty
, rValue
);
1042 // css::lang::XServiceInfo
1043 uno::Sequence
< OUString
> SAL_CALL
Svx3DPolygonObject::getSupportedServiceNames()
1045 return comphelper::concatSequences(
1046 SvxShape::getSupportedServiceNames(),
1047 std::initializer_list
<OUString
>{ u
"com.sun.star.drawing.Shape3D"_ustr
,
1048 u
"com.sun.star.drawing.Shape3DPolygon"_ustr
});
1051 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */