Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/svx/source/unodraw/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 34 kB image not shown  

Quelle  unoshap3.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */


#include <sal/config.h>

#include <initializer_list>
#include <string_view>

#include <com/sun/star/drawing/HomogenMatrix.hpp>
#include <com/sun/star/drawing/Position3D.hpp>
#include <com/sun/star/drawing/Direction3D.hpp>
#include <com/sun/star/drawing/DoubleSequence.hpp>
#include <com/sun/star/drawing/CameraGeometry.hpp>
#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
#include <o3tl/safeint.hxx>
#include <vcl/svapp.hxx>
#include <comphelper/sequence.hxx>
#include <sal/log.hxx>

#include <svx/svdpool.hxx>
#include <svx/svditer.hxx>
#include <svx/unoshape.hxx>
#include <svx/unopage.hxx>
#include <svx/cube3d.hxx>
#include <svx/sphere3d.hxx>
#include <svx/lathe3d.hxx>
#include <extrud3d.hxx>
#include <polygn3d.hxx>
#include <svx/unoshprp.hxx>
#include <svx/svdmodel.hxx>
#include <svx/scene3d.hxx>
#include <basegfx/polygon/b3dpolygon.hxx>
#include <basegfx/polygon/b3dpolygontools.hxx>
#include <com/sun/star/drawing/PolyPolygonShape3D.hpp>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <basegfx/matrix/b3dhommatrixtools.hxx>
#include "shapeimpl.hxx"

using namespace ::cppu;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::container;

#define QUERYINT( xint ) \
    if( rType == cppu::UnoType<xint>::get() ) \
        aAny <<= Reference< xint >(this)

Svx3DSceneObject::Svx3DSceneObject(SdrObject* pObj, SvxDrawPage* pDrawPage)
:   SvxShapeGroupAnyD( pObj, getSvxMapProvider().GetMap(SVXMAP_3DSCENEOBJECT), getSvxMapProvider().GetPropertySet(SVXMAP_3DSCENEOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
,   mxPage( pDrawPage )
{
}


Svx3DSceneObject::~Svx3DSceneObject() noexcept
{
}


void Svx3DSceneObject::Create( SdrObject* pNewObj, SvxDrawPage* pNewPage )
{
    SvxShape::Create( pNewObj, pNewPage );
    mxPage = pNewPage;
}


uno::Any SAL_CALL Svx3DSceneObject::queryAggregation( const uno::Type & rType )
{
    uno::Any aAny;

    QUERYINT( drawing::XShapes );
    else QUERYINT( container::XIndexAccess );
    else QUERYINT( container::XElementAccess );
    else
        return SvxShape::queryAggregation( rType );

    return aAny;
}

uno::Any SAL_CALL Svx3DSceneObject::queryInterface( const uno::Type & rType )
{
    return SvxShape::queryInterface( rType );
}

// XTypeProvider

uno::Sequence< sal_Int8 > SAL_CALL Svx3DSceneObject::getImplementationId()
{
    return css::uno::Sequence<sal_Int8>();
}


void SAL_CALL Svx3DSceneObject::add( const Reference< drawing::XShape >& xShape )
{
    SolarMutexGuard aGuard;

    SvxShape* pShape = comphelper::getFromUnoTunnel<SvxShape>( xShape );

    if(!HasSdrObject() || !mxPage.is() || pShape == nullptr || nullptr != pShape->GetSdrObject() )
        throw uno::RuntimeException();

    rtl::Reference<SdrObject> pSdrShape = mxPage->CreateSdrObject_( xShape );
    if( DynCastE3dObject(pSdrShape.get()) )
    {
        GetSdrObject()->GetSubList()->NbcInsertObject( pSdrShape.get() );
        pShape->Create(pSdrShape.get(), mxPage.get());
    }
    else
    {
        pSdrShape.clear();
        throw uno::RuntimeException();
    }

    GetSdrObject()->getSdrModelFromSdrObject().SetChanged();
}

void Svx3DSceneObject::addShape( SvxShape& rShape )
{
    SolarMutexGuard aGuard;

    if(!HasSdrObject() || !mxPage.is() || nullptr != rShape.GetSdrObject() )
        throw uno::RuntimeException();

    rtl::Reference<SdrObject> pSdrShape = mxPage->CreateSdrObject_( &rShape );
    if( DynCastE3dObject(pSdrShape.get()) )
    {
        GetSdrObject()->GetSubList()->NbcInsertObject( pSdrShape.get() );
        rShape.Create(pSdrShape.get(), mxPage.get());
    }
    else
    {
        pSdrShape.clear();
        throw uno::RuntimeException();
    }

    GetSdrObject()->getSdrModelFromSdrObject().SetChanged();
}

void SAL_CALL Svx3DSceneObject::remove( const Reference< drawing::XShape >& xShape )
{
    SolarMutexGuard aGuard;

    SdrObject* pSdrShape = SdrObject::getSdrObjectFromXShape( xShape );

    if(!HasSdrObject() || !pSdrShape ||
        pSdrShape->getParentSdrObjectFromSdrObject() != GetSdrObject())
        throw uno::RuntimeException();

    SdrObjList& rList = *pSdrShape->getParentSdrObjListFromSdrObject();

    const size_t nObjCount = rList.GetObjCount();
    size_t nObjNum = 0;
    while( nObjNum < nObjCount )
    {
        if(rList.GetObj( nObjNum ) == pSdrShape )
            break;
        nObjNum++;
    }

    if( nObjNum < nObjCount )
    {
        rList.NbcRemoveObject( nObjNum );
    }
    else
    {
        SAL_WARN( "svx""Fatality! SdrObject is not belonging to its SdrObjList! [CL]" );
    }
}


sal_Int32 SAL_CALL Svx3DSceneObject::getCount()
{
    SolarMutexGuard aGuard;

    sal_Int32 nRetval = 0;

    if(HasSdrObject() && DynCastE3dScene(GetSdrObject()) && GetSdrObject()->GetSubList())
        nRetval = GetSdrObject()->GetSubList()->GetObjCount();
    return nRetval;
}


uno::Any SAL_CALL Svx3DSceneObject::getByIndex( sal_Int32 Index )
{
    SolarMutexGuard aGuard;

    if( !HasSdrObject() || GetSdrObject()->GetSubList() == nullptr )
        throw uno::RuntimeException();

    if( Index<0 || GetSdrObject()->GetSubList()->GetObjCount() <= o3tl::make_unsigned(Index) )
        throw lang::IndexOutOfBoundsException();

    SdrObject* pDestObj = GetSdrObject()->GetSubList()->GetObj( Index );
    if(pDestObj == nullptr)
        throw lang::IndexOutOfBoundsException();

    Reference< drawing::XShape > xShape( pDestObj->getUnoShape(), uno::UNO_QUERY );
    return uno::Any(xShape);
}


// css::container::XElementAccess

uno::Type SAL_CALL Svx3DSceneObject::getElementType()
{
    return cppu::UnoType<drawing::XShape>::get();
}


sal_Bool SAL_CALL Svx3DSceneObject::hasElements()
{
    SolarMutexGuard aGuard;

    return HasSdrObject() && GetSdrObject()->GetSubList() && (GetSdrObject()->GetSubList()->GetObjCount() > 0);
}


static bool ConvertHomogenMatrixToObject( E3dObject* pObject, const Any& rValue )
{
    drawing::HomogenMatrix aMat;
    if( rValue >>= aMat )
    {
        pObject->SetTransform(basegfx::utils::UnoHomogenMatrixToB3DHomMatrix(aMat));
        return true;
    }
    return false;
}

static void ConvertObjectToHomogenMatric( E3dObject const * pObject, Any& rValue )
{
    drawing::HomogenMatrix aHomMat;
    const basegfx::B3DHomMatrix& rMat = pObject->GetTransform();
    basegfx::utils::B3DHomMatrixToUnoHomogenMatrix(rMat, aHomMat);
    rValue <<= aHomMat;
}

namespace {

struct ImpRememberTransAndRect
{
    basegfx::B3DHomMatrix                   maMat;
    tools::Rectangle                   maRect;
};

}

bool Svx3DSceneObject::setPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue )
{
    switch( pProperty->nWID )
    {
    case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
    {
        // patch transformation matrix to the object
        if( ConvertHomogenMatrixToObject( static_cast< E3dObject* >( GetSdrObject() ), rValue ) )
            return true;
        break;
    }
    case OWN_ATTR_3D_VALUE_CAMERA_GEOMETRY:
    {
        // set CameraGeometry at scene
        E3dScene* pScene = static_cast< E3dScene* >( GetSdrObject() );
        drawing::CameraGeometry aCamGeo;

        if(rValue >>= aCamGeo)
        {
            basegfx::B3DPoint aVRP(aCamGeo.vrp.PositionX, aCamGeo.vrp.PositionY, aCamGeo.vrp.PositionZ);
            basegfx::B3DVector aVPN(aCamGeo.vpn.DirectionX, aCamGeo.vpn.DirectionY, aCamGeo.vpn.DirectionZ);
            basegfx::B3DVector aVUP(aCamGeo.vup.DirectionX, aCamGeo.vup.DirectionY, aCamGeo.vup.DirectionZ);

            // rescue scene transformation
            ImpRememberTransAndRect aSceneTAR;
            aSceneTAR.maMat = pScene->GetTransform();
            aSceneTAR.maRect = pScene->GetSnapRect();

            // rescue object transformations
            SdrObjListIter aIter(pScene->GetSubList(), SdrIterMode::DeepWithGroups);
            std::vector<basegfx::B3DHomMatrix*> aObjTrans;
            while(aIter.IsMore())
            {
                E3dObject* p3DObj = static_cast<E3dObject*>(aIter.Next());
                basegfx::B3DHomMatrix* pNew = new basegfx::B3DHomMatrix;
                *pNew = p3DObj->GetTransform();
                aObjTrans.push_back(pNew);
            }

            // reset object transformations
            aIter.Reset();
            while(aIter.IsMore())
            {
                E3dObject* p3DObj = static_cast<E3dObject*>(aIter.Next());
                p3DObj->NbcSetTransform(basegfx::B3DHomMatrix());
            }

            // reset scene transformation and make a complete recalc
            pScene->NbcSetTransform(basegfx::B3DHomMatrix());

            // fill old camera from new parameters
            Camera3D aCam(pScene->GetCamera());
            const basegfx::B3DRange& rVolume = pScene->GetBoundVolume();
            double fW = rVolume.getWidth();
            double fH = rVolume.getHeight();

            const SfxItemSet& rSceneSet = pScene->GetMergedItemSet();
            double fCamPosZ =
                static_cast<double>(rSceneSet.Get(SDRATTR_3DSCENE_DISTANCE).GetValue());
            double fCamFocal =
                static_cast<double>(rSceneSet.Get(SDRATTR_3DSCENE_FOCAL_LENGTH).GetValue());

            aCam.SetAutoAdjustProjection(false);
            aCam.SetViewWindow(- fW / 2, - fH / 2, fW, fH);
            basegfx::B3DPoint aLookAt;
            basegfx::B3DPoint aCamPos(0.0, 0.0, fCamPosZ);
            aCam.SetPosAndLookAt(aCamPos, aLookAt);
            aCam.SetFocalLength(fCamFocal / 100.0);
            aCam.SetDeviceWindow(tools::Rectangle(0, 0, static_cast<tools::Long>(fW), static_cast<tools::Long>(fH)));

            // set at scene
            pScene->SetCamera(aCam);

            // #91047# use imported VRP, VPN and VUP (if used)
            bool bVRPUsed(!aVRP.equal(basegfx::B3DPoint(0.0, 0.0, 1.0)));
            bool bVPNUsed(!aVPN.equal(basegfx::B3DVector(0.0, 0.0, 1.0)));
            bool bVUPUsed(!aVUP.equal(basegfx::B3DVector(0.0, 1.0, 0.0)));

            if(bVRPUsed || bVPNUsed || bVUPUsed)
            {
                pScene->GetCameraSet().SetViewportValues(aVRP, aVPN, aVUP);
            }

            // set object transformations again at objects
            aIter.Reset();
            sal_uInt32 nIndex(0);
            while(aIter.IsMore())
            {
                E3dObject* p3DObj = static_cast<E3dObject*>(aIter.Next());
                basegfx::B3DHomMatrix* pMat = aObjTrans[nIndex++];
                p3DObj->NbcSetTransform(*pMat);
                delete pMat;
            }

            // set scene transformation again at scene
            pScene->NbcSetTransform(aSceneTAR.maMat);
            pScene->NbcSetSnapRect(aSceneTAR.maRect);

            return true;
        }
        break;
    }
    default:
        return SvxShape::setPropertyValueImpl(rName, pProperty, rValue);
    }

    throw IllegalArgumentException();
}


bool Svx3DSceneObject::getPropertyValueImpl(const OUString& rName, const SfxItemPropertyMapEntry* pProperty,
    css::uno::Any& rValue)
{
    switch( pProperty->nWID )
    {
    case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
    {
        // patch object to a homogeneous 4x4 matrix
        ConvertObjectToHomogenMatric( static_cast< E3dObject* >( GetSdrObject() ), rValue );
        break;
    }
    case OWN_ATTR_3D_VALUE_CAMERA_GEOMETRY:
    {
        // get CameraGeometry from scene
        E3dScene* pScene = static_cast< E3dScene* >( GetSdrObject() );
        drawing::CameraGeometry aCamGeo;

        // fill Vectors from scene camera
        B3dCamera& aCameraSet = pScene->GetCameraSet();
        basegfx::B3DPoint aVRP(aCameraSet.GetVRP());
        basegfx::B3DVector aVPN(aCameraSet.GetVPN());
        basegfx::B3DVector aVUP(aCameraSet.GetVUV());

        // transfer to structure
        aCamGeo.vrp.PositionX = aVRP.getX();
        aCamGeo.vrp.PositionY = aVRP.getY();
        aCamGeo.vrp.PositionZ = aVRP.getZ();
        aCamGeo.vpn.DirectionX = aVPN.getX();
        aCamGeo.vpn.DirectionY = aVPN.getY();
        aCamGeo.vpn.DirectionZ = aVPN.getZ();
        aCamGeo.vup.DirectionX = aVUP.getX();
        aCamGeo.vup.DirectionY = aVUP.getY();
        aCamGeo.vup.DirectionZ = aVUP.getZ();

        rValue <<= aCamGeo;
        break;
    }
    default:
        return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
    }

    return true;
}

// css::lang::XServiceInfo
uno::Sequence< OUString > SAL_CALL Svx3DSceneObject::getSupportedServiceNames()
{
    return comphelper::concatSequences(
        SvxShape::getSupportedServiceNames(),
        std::initializer_list<OUString>{ u"com.sun.star.drawing.Shape3DScene"_ustr });
}

Svx3DCubeObject::Svx3DCubeObject(SdrObject* pObj)
:   SvxShape( pObj, getSvxMapProvider().GetMap(SVXMAP_3DCUBEOBJECT), getSvxMapProvider().GetPropertySet(SVXMAP_3DCUBEOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
{
}

Svx3DCubeObject::~Svx3DCubeObject() noexcept
{
}

bool Svx3DCubeObject::setPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue )
{
    SolarMutexGuard aGuard;

    switch( pProperty->nWID )
    {
    case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
    {
        // pack transformationmatrix to the object
        if( ConvertHomogenMatrixToObject( static_cast< E3dObject* >( GetSdrObject() ), rValue ) )
            return true;
        break;
    }
    case OWN_ATTR_3D_VALUE_POSITION:
    {
        // pack position to the object
        drawing::Position3D aUnoPos;
        if( rValue >>= aUnoPos )
        {
            basegfx::B3DPoint aPos(aUnoPos.PositionX, aUnoPos.PositionY, aUnoPos.PositionZ);
            static_cast< E3dCubeObj* >( GetSdrObject() )->SetCubePos(aPos);
            return true;
        }
        break;
    }
    case OWN_ATTR_3D_VALUE_SIZE:
    {
        // pack size to the object
        drawing::Direction3D aDirection;
        if( rValue >>= aDirection )
        {
            basegfx::B3DVector aSize(aDirection.DirectionX, aDirection.DirectionY, aDirection.DirectionZ);
            static_cast< E3dCubeObj* >( GetSdrObject() )->SetCubeSize(aSize);
            return true;
        }
        break;
    }
    case OWN_ATTR_3D_VALUE_POS_IS_CENTER:
    {
        bool bNew = false;
        // pack sal_Bool bPosIsCenter to the object
        if( rValue >>= bNew )
        {
            static_cast< E3dCubeObj* >( GetSdrObject() )->SetPosIsCenter(bNew);
            return true;
        }
        break;
    }
    default:
        return SvxShape::setPropertyValueImpl( rName, pProperty, rValue );
    }

    throw IllegalArgumentException();
}

bool Svx3DCubeObject::getPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, css::uno::Any& rValue )
{
    switch( pProperty->nWID )
    {
    case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
    {
        // pack transformation to a homogeneous matrix
        ConvertObjectToHomogenMatric( static_cast< E3dObject* >( GetSdrObject() ), rValue );
        break;
    }
    case OWN_ATTR_3D_VALUE_POSITION:
    {
        // pack position
        const basegfx::B3DPoint& rPos = static_cast<E3dCubeObj*>(GetSdrObject())->GetCubePos();
        drawing::Position3D aPos;

        aPos.PositionX = rPos.getX();
        aPos.PositionY = rPos.getY();
        aPos.PositionZ = rPos.getZ();

        rValue <<= aPos;
        break;
    }
    case OWN_ATTR_3D_VALUE_SIZE:
    {
        // pack size
        const basegfx::B3DVector& rSize = static_cast<E3dCubeObj*>(GetSdrObject())->GetCubeSize();
        drawing::Direction3D aDir;

        aDir.DirectionX = rSize.getX();
        aDir.DirectionY = rSize.getY();
        aDir.DirectionZ = rSize.getZ();

        rValue <<= aDir;
        break;
    }
    case OWN_ATTR_3D_VALUE_POS_IS_CENTER:
    {
        rValue <<= static_cast<E3dCubeObj*>(GetSdrObject())->GetPosIsCenter();
        break;
    }
    default:
        return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
    }

    return true;
}

// css::lang::XServiceInfo
uno::Sequence< OUString > SAL_CALL Svx3DCubeObject::getSupportedServiceNames()
{
    return comphelper::concatSequences(
        SvxShape::getSupportedServiceNames(),
        std::initializer_list<OUString>{ u"com.sun.star.drawing.Shape3D"_ustr,
                                         u"com.sun.star.drawing.Shape3DCube"_ustr });
}

Svx3DSphereObject::Svx3DSphereObject(SdrObject* pObj)
    : SvxShape( pObj, getSvxMapProvider().GetMap(SVXMAP_3DSPHEREOBJECT), getSvxMapProvider().GetPropertySet(SVXMAP_3DSPHEREOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
{
}

Svx3DSphereObject::~Svx3DSphereObject() noexcept
{
}

bool Svx3DSphereObject::setPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue )
{
    switch( pProperty->nWID )
    {
    case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
    {
        // pack transformation matrix to the object
        if( ConvertHomogenMatrixToObject( static_cast< E3dObject* >( GetSdrObject() ), rValue ) )
            return true;
        break;
    }

    case OWN_ATTR_3D_VALUE_POSITION:
    {
        // pack position to the object
        drawing::Position3D aUnoPos;
        if( rValue >>= aUnoPos )
        {
            basegfx::B3DPoint aPos(aUnoPos.PositionX, aUnoPos.PositionY, aUnoPos.PositionZ);
            static_cast<E3dSphereObj*>(GetSdrObject())->SetCenter(aPos);
            return true;
        }
        break;
    }

    case OWN_ATTR_3D_VALUE_SIZE:
    {
        // pack size to the object
        drawing::Direction3D aDir;
        if( rValue >>= aDir )
        {
            basegfx::B3DVector aPos(aDir.DirectionX, aDir.DirectionY, aDir.DirectionZ);
            static_cast<E3dSphereObj*>(GetSdrObject())->SetSize(aPos);
            return true;
        }
        break;
    }
    default:
        return SvxShape::setPropertyValueImpl( rName, pProperty, rValue );
    }

    throw IllegalArgumentException();
}

bool Svx3DSphereObject::getPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, css::uno::Any& rValue )
{
    switch( pProperty->nWID )
    {
    case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
    {
        // pack transformation to a homogeneous matrix
        ConvertObjectToHomogenMatric( static_cast< E3dObject* >( GetSdrObject() ), rValue );
        break;
    }
    case OWN_ATTR_3D_VALUE_POSITION:
    {
        // pack position
        const basegfx::B3DPoint& rPos = static_cast<E3dSphereObj*>(GetSdrObject())->Center();
        drawing::Position3D aPos;

        aPos.PositionX = rPos.getX();
        aPos.PositionY = rPos.getY();
        aPos.PositionZ = rPos.getZ();

        rValue <<= aPos;
        break;
    }
    case OWN_ATTR_3D_VALUE_SIZE:
    {
        // pack size
        const basegfx::B3DVector& rSize = static_cast<E3dSphereObj*>(GetSdrObject())->Size();
        drawing::Direction3D aDir;

        aDir.DirectionX = rSize.getX();
        aDir.DirectionY = rSize.getY();
        aDir.DirectionZ = rSize.getZ();

        rValue <<= aDir;
        break;
    }
    default:
        return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
    }

    return true;
}

// css::lang::XServiceInfo
uno::Sequence< OUString > SAL_CALL Svx3DSphereObject::getSupportedServiceNames()
{
    return comphelper::concatSequences(
        SvxShape::getSupportedServiceNames(),
        std::initializer_list<OUString>{ u"com.sun.star.drawing.Shape3D"_ustr,
                                         u"com.sun.star.drawing.Shape3DSphere"_ustr });
}

Svx3DLatheObject::Svx3DLatheObject(SdrObject* pObj)
:   SvxShape( pObj, getSvxMapProvider().GetMap(SVXMAP_3DLATHEOBJECT), getSvxMapProvider().GetPropertySet(SVXMAP_3DLATHEOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
{
}

Svx3DLatheObject::~Svx3DLatheObject() noexcept
{
}

static bool PolyPolygonShape3D_to_B3dPolyPolygon(
    const Any& rValue,
    basegfx::B3DPolyPolygon& rResultPolygon,
    bool bCorrectPolygon)
{
    drawing::PolyPolygonShape3D aSourcePolyPolygon;
    if( !(rValue >>= aSourcePolyPolygon) )
        return false;

    sal_Int32 nOuterSequenceCount = aSourcePolyPolygon.SequenceX.getLength();
    if(nOuterSequenceCount != aSourcePolyPolygon.SequenceY.getLength() || nOuterSequenceCount != aSourcePolyPolygon.SequenceZ.getLength())
        return false;

    const drawing::DoubleSequence* pInnerSequenceX = aSourcePolyPolygon.SequenceX.getConstArray();
    const drawing::DoubleSequence* pInnerSequenceY = aSourcePolyPolygon.SequenceY.getConstArray();
    const drawing::DoubleSequence* pInnerSequenceZ = aSourcePolyPolygon.SequenceZ.getConstArray();
    for(sal_Int32 a(0);a<nOuterSequenceCount;a++)
    {
        sal_Int32 nInnerSequenceCount = pInnerSequenceX->getLength();
        if(nInnerSequenceCount != pInnerSequenceY->getLength() || nInnerSequenceCount != pInnerSequenceZ->getLength())
        {
            return false;
        }
        basegfx::B3DPolygon aNewPolygon;
        const double* pArrayX = pInnerSequenceX->getConstArray();
        const double* pArrayY = pInnerSequenceY->getConstArray();
        const double* pArrayZ = pInnerSequenceZ->getConstArray();
        for(sal_Int32 b(0);b<nInnerSequenceCount;b++)
        {
            aNewPolygon.append(basegfx::B3DPoint(*pArrayX++,*pArrayY++,*pArrayZ++));
        }
        pInnerSequenceX++;
        pInnerSequenceY++;
        pInnerSequenceZ++;

        // #i101520# correction is needed for imported polygons of old format,
        // see callers
        if(bCorrectPolygon)
        {
            basegfx::utils::checkClosed(aNewPolygon);
        }

        rResultPolygon.append(aNewPolygon);
    }
    return true;
}

static void B3dPolyPolygon_to_PolyPolygonShape3D( const basegfx::B3DPolyPolygon& rSourcePolyPolygon, Any& rValue )
{
    drawing::PolyPolygonShape3D aRetval;
    aRetval.SequenceX.realloc(rSourcePolyPolygon.count());
    aRetval.SequenceY.realloc(rSourcePolyPolygon.count());
    aRetval.SequenceZ.realloc(rSourcePolyPolygon.count());
    drawing::DoubleSequence* pOuterSequenceX = aRetval.SequenceX.getArray();
    drawing::DoubleSequence* pOuterSequenceY = aRetval.SequenceY.getArray();
    drawing::DoubleSequence* pOuterSequenceZ = aRetval.SequenceZ.getArray();
    for(sal_uInt32 a(0);a<rSourcePolyPolygon.count();a++)
    {
        const basegfx::B3DPolygon& aPoly(rSourcePolyPolygon.getB3DPolygon(a));
        sal_Int32 nPointCount(aPoly.count());
        if(aPoly.isClosed()) nPointCount++;
        pOuterSequenceX->realloc(nPointCount);
        pOuterSequenceY->realloc(nPointCount);
        pOuterSequenceZ->realloc(nPointCount);
        double* pInnerSequenceX = pOuterSequenceX->getArray();
        double* pInnerSequenceY = pOuterSequenceY->getArray();
        double* pInnerSequenceZ = pOuterSequenceZ->getArray();
        for(sal_uInt32 b(0);b<aPoly.count();b++)
        {
            const basegfx::B3DPoint aPoint(aPoly.getB3DPoint(b));
            *pInnerSequenceX++ = aPoint.getX();
            *pInnerSequenceY++ = aPoint.getY();
            *pInnerSequenceZ++ = aPoint.getZ();
        }
        if(aPoly.isClosed())
        {
            const basegfx::B3DPoint aPoint(aPoly.getB3DPoint(0));
            *pInnerSequenceX++ = aPoint.getX();
            *pInnerSequenceY++ = aPoint.getY();
            *pInnerSequenceZ++ = aPoint.getZ();
        }
        pOuterSequenceX++;
        pOuterSequenceY++;
        pOuterSequenceZ++;
    }
    rValue <<= aRetval;
}

bool Svx3DLatheObject::setPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue )
{
    switch( pProperty->nWID )
    {
    case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
    {
        // pack transformation matrix to the object
        if( ConvertHomogenMatrixToObject( static_cast< E3dObject* >( GetSdrObject() ), rValue ) )
            return true;
        break;
    }
    case OWN_ATTR_3D_VALUE_POLYPOLYGON3D:
    {
        // pack polygon definition to the object
        basegfx::B3DPolyPolygon aNewB3DPolyPolygon;

        // #i101520# Probably imported
        if( PolyPolygonShape3D_to_B3dPolyPolygon( rValue, aNewB3DPolyPolygon, true ) )
        {
            // #105127# SetPolyPoly3D sets the Svx3DVerticalSegmentsItem to the number
            // of points of the polygon. Thus, value gets lost. To avoid this, rescue
            // item here and re-set after setting the polygon.
            const sal_uInt32 nPrevVerticalSegs(static_cast<E3dLatheObj*>(GetSdrObject())->GetVerticalSegments());

            // set polygon
            const basegfx::B3DHomMatrix aIdentity;
            const basegfx::B2DPolyPolygon aB2DPolyPolygon(basegfx::utils::createB2DPolyPolygonFromB3DPolyPolygon(aNewB3DPolyPolygon, aIdentity));
            static_cast<E3dLatheObj*>(GetSdrObject())->SetPolyPoly2D(aB2DPolyPolygon);
            const sal_uInt32 nPostVerticalSegs(static_cast<E3dLatheObj*>(GetSdrObject())->GetVerticalSegments());

            if(nPrevVerticalSegs != nPostVerticalSegs)
            {
                // restore the vertical segment count
                static_cast<E3dLatheObj*>(GetSdrObject())->SetMergedItem(makeSvx3DVerticalSegmentsItem(nPrevVerticalSegs));
            }
            return true;
        }
        break;
    }
    default:
        return SvxShape::setPropertyValueImpl( rName, pProperty, rValue );
    }

    throw IllegalArgumentException();
}

bool Svx3DLatheObject::getPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, css::uno::Any& rValue )
{
    switch( pProperty->nWID )
    {
    case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
    {
        // pack transformation to a homogeneous matrix
        drawing::HomogenMatrix aHomMat;
        basegfx::B3DHomMatrix aMat = static_cast<E3dObject*>(GetSdrObject())->GetTransform();
        basegfx::utils::B3DHomMatrixToUnoHomogenMatrix(aMat, aHomMat);
        rValue <<= aHomMat;
        break;
    }
    case OWN_ATTR_3D_VALUE_POLYPOLYGON3D:
    {
        const basegfx::B2DPolyPolygon& rPolyPoly = static_cast<E3dLatheObj*>(GetSdrObject())->GetPolyPoly2D();
        const basegfx::B3DPolyPolygon aB3DPolyPolygon(basegfx::utils::createB3DPolyPolygonFromB2DPolyPolygon(rPolyPoly));

        B3dPolyPolygon_to_PolyPolygonShape3D(aB3DPolyPolygon, rValue);
        break;
    }
    default:
        return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
    }

    return true;
}

// css::lang::XServiceInfo
uno::Sequence< OUString > SAL_CALL Svx3DLatheObject::getSupportedServiceNames()
{
    return comphelper::concatSequences(
        SvxShape::getSupportedServiceNames(),
        std::initializer_list<OUString>{ u"com.sun.star.drawing.Shape3D"_ustr,
                                         u"com.sun.star.drawing.Shape3DLathe"_ustr });
}

Svx3DExtrudeObject::Svx3DExtrudeObject(SdrObject* pObj)
:   SvxShape( pObj, getSvxMapProvider().GetMap(SVXMAP_3DEXTRUDEOBJECT), getSvxMapProvider().GetPropertySet(SVXMAP_3DEXTRUDEOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
{
}

Svx3DExtrudeObject::~Svx3DExtrudeObject() noexcept
{
}

bool Svx3DExtrudeObject::setPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue )
{
    switch( pProperty->nWID )
    {
    case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
    {
        // pack transformation matrix to the object
        if( ConvertHomogenMatrixToObject( static_cast< E3dObject* >( GetSdrObject() ), rValue ) )
            return true;
        break;
    }

    case OWN_ATTR_3D_VALUE_POLYPOLYGON3D:
    {
        // pack polygon definition to the object
        basegfx::B3DPolyPolygon aNewB3DPolyPolygon;

        // #i101520# Probably imported
        if( PolyPolygonShape3D_to_B3dPolyPolygon( rValue, aNewB3DPolyPolygon, true ) )
        {
            // set polygon
            const basegfx::B3DHomMatrix aIdentity;
            const basegfx::B2DPolyPolygon aB2DPolyPolygon(basegfx::utils::createB2DPolyPolygonFromB3DPolyPolygon(aNewB3DPolyPolygon, aIdentity));
            static_cast<E3dExtrudeObj*>(GetSdrObject())->SetExtrudePolygon(aB2DPolyPolygon);
            return true;
        }
        break;
    }
    default:
        return SvxShape::setPropertyValueImpl( rName, pProperty, rValue );
    }

    throw IllegalArgumentException();
}

bool Svx3DExtrudeObject::getPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, css::uno::Any& rValue )
{
    switch( pProperty->nWID )
    {
    case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
    {
        // pack transformation to a homogeneous matrix
        drawing::HomogenMatrix aHomMat;
        basegfx::B3DHomMatrix aMat = static_cast<E3dObject*>(GetSdrObject())->GetTransform();
        basegfx::utils::B3DHomMatrixToUnoHomogenMatrix(aMat, aHomMat);
        rValue <<= aHomMat;
        break;
    }

    case OWN_ATTR_3D_VALUE_POLYPOLYGON3D:
    {
        // pack polygon definition
        const basegfx::B2DPolyPolygon& rPolyPoly = static_cast<E3dExtrudeObj*>(GetSdrObject())->GetExtrudePolygon();
        const basegfx::B3DPolyPolygon aB3DPolyPolygon(basegfx::utils::createB3DPolyPolygonFromB2DPolyPolygon(rPolyPoly));

        B3dPolyPolygon_to_PolyPolygonShape3D(aB3DPolyPolygon, rValue);
        break;
    }
    default:
        return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
    }

    return true;
}

// css::lang::XServiceInfo
uno::Sequence< OUString > SAL_CALL Svx3DExtrudeObject::getSupportedServiceNames()
{
    return comphelper::concatSequences(
        SvxShape::getSupportedServiceNames(),
        std::initializer_list<OUString>{ u"com.sun.star.drawing.Shape3D"_ustr,
                                         u"com.sun.star.drawing.Shape3DExtrude"_ustr });
}

Svx3DPolygonObject::Svx3DPolygonObject(SdrObject* pObj)
:   SvxShape( pObj, getSvxMapProvider().GetMap(SVXMAP_3DPOLYGONOBJECT), getSvxMapProvider().GetPropertySet(SVXMAP_3DPOLYGONOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
{
}

Svx3DPolygonObject::~Svx3DPolygonObject() noexcept
{
}

bool Svx3DPolygonObject::setPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue )
{
    switch( pProperty->nWID )
    {
    case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
    {
        // pack transformation matrix to the object
        if( ConvertHomogenMatrixToObject( static_cast< E3dObject* >( GetSdrObject() ), rValue ) )
            return true;
        break;
    }

    case OWN_ATTR_3D_VALUE_POLYPOLYGON3D:
    {
        // pack polygon definition to the object
        basegfx::B3DPolyPolygon aNewB3DPolyPolygon;

        // #i101520# Direct API data (e.g. from chart)
        if( PolyPolygonShape3D_to_B3dPolyPolygon( rValue, aNewB3DPolyPolygon, false ) )
        {
            // set polygon
            static_cast<E3dPolygonObj*>(GetSdrObject())->SetPolyPolygon3D(aNewB3DPolyPolygon);
            return true;
        }
        break;
    }
    case OWN_ATTR_3D_VALUE_NORMALSPOLYGON3D:
    {
        // pack perpendicular definition to the object
        basegfx::B3DPolyPolygon aNewB3DPolyPolygon;

        // #i101520# Direct API data (e.g. from chart)
        if( PolyPolygonShape3D_to_B3dPolyPolygon( rValue, aNewB3DPolyPolygon, false ) )
        {
            // set polygon
            static_cast<E3dPolygonObj*>(GetSdrObject())->SetPolyNormals3D(aNewB3DPolyPolygon);
            return true;
        }
        break;
    }
    case OWN_ATTR_3D_VALUE_TEXTUREPOLYGON3D:
    {
        // pack texture definition to the object
        basegfx::B3DPolyPolygon aNewB3DPolyPolygon;

        // #i101520# Direct API data (e.g. from chart)
        if( PolyPolygonShape3D_to_B3dPolyPolygon( rValue, aNewB3DPolyPolygon, false ) )
        {
            // set polygon
            const basegfx::B3DHomMatrix aIdentity;
            const basegfx::B2DPolyPolygon aB2DPolyPolygon(basegfx::utils::createB2DPolyPolygonFromB3DPolyPolygon(aNewB3DPolyPolygon, aIdentity));
            static_cast<E3dPolygonObj*>(GetSdrObject())->SetPolyTexture2D(aB2DPolyPolygon);
            return true;
        }
        break;
    }
    case OWN_ATTR_3D_VALUE_LINEONLY:
    {
        bool bNew = false;
        if( rValue >>= bNew )
        {
            static_cast<E3dPolygonObj*>(GetSdrObject())->SetLineOnly(bNew);
            return true;
        }
        break;
    }
    default:
        return SvxShape::setPropertyValueImpl( rName, pProperty, rValue );
    }

    throw IllegalArgumentException();
}

bool Svx3DPolygonObject::getPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, css::uno::Any& rValue )
{
    switch( pProperty->nWID )
    {
    case OWN_ATTR_3D_VALUE_TRANSFORM_MATRIX:
    {
        ConvertObjectToHomogenMatric( static_cast< E3dObject* >( GetSdrObject() ), rValue );
        break;
    }

    case OWN_ATTR_3D_VALUE_POLYPOLYGON3D:
    {
        B3dPolyPolygon_to_PolyPolygonShape3D(static_cast<E3dPolygonObj*>(GetSdrObject())->GetPolyPolygon3D(),rValue);
        break;
    }

    case OWN_ATTR_3D_VALUE_NORMALSPOLYGON3D:
    {
        B3dPolyPolygon_to_PolyPolygonShape3D(static_cast<E3dPolygonObj*>(GetSdrObject())->GetPolyNormals3D(),rValue);
        break;
    }

    case OWN_ATTR_3D_VALUE_TEXTUREPOLYGON3D:
    {
        // pack texture definition
        const basegfx::B2DPolyPolygon& rPolyPoly = static_cast<E3dPolygonObj*>(GetSdrObject())->GetPolyTexture2D();
        const basegfx::B3DPolyPolygon aB3DPolyPolygon(basegfx::utils::createB3DPolyPolygonFromB2DPolyPolygon(rPolyPoly));

        B3dPolyPolygon_to_PolyPolygonShape3D(aB3DPolyPolygon,rValue);
        break;
    }

    case OWN_ATTR_3D_VALUE_LINEONLY:
    {
        rValue <<= static_cast<E3dPolygonObj*>(GetSdrObject())->GetLineOnly();
        break;
    }

    default:
        return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
    }

    return true;
}

// css::lang::XServiceInfo
uno::Sequence< OUString > SAL_CALL Svx3DPolygonObject::getSupportedServiceNames()
{
    return comphelper::concatSequences(
        SvxShape::getSupportedServiceNames(),
        std::initializer_list<OUString>{ u"com.sun.star.drawing.Shape3D"_ustr,
                                         u"com.sun.star.drawing.Shape3DPolygon"_ustr });
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=93 H=99 G=95

¤ Dauer der Verarbeitung: 0.15 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.