/**************************************************************
 *
 * 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
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"
#include "EnhancedCustomShape3d.hxx"
#include <svx/svdetc.hxx>
#include <svx/svdmodel.hxx>
#include <tools/poly.hxx>
#include <svx/svditer.hxx>
#include <svx/svdobj.hxx>
#include <svx/svdoashp.hxx>
#include <svl/poolitem.hxx>
#include <svl/itemset.hxx>
#include <svx/xfillit0.hxx>
#include <svx/xsflclit.hxx>
#include <svx/xit.hxx>
#include <svx/xbtmpit.hxx>
#include <svx/xflclit.hxx>
#include <svx/svdopath.hxx>
#include <svx/svdogrp.hxx>
#include <svx/svdpage.hxx>
#include <svx/polysc3d.hxx>
#include <svx/svddef.hxx>
#include <svx/svx3ditems.hxx>
#include <svx/extrud3d.hxx>
#include <svx/xflbmtit.hxx>
#include <vcl/svapp.hxx>
#include <svx/xlnclit.hxx>
#include <svx/sdasitm.hxx>
#include <com/sun/star/awt/Point.hpp>
#include <com/sun/star/drawing/Position3D.hpp>
#include <com/sun/star/drawing/Direction3D.hpp>
#include <com/sun/star/drawing/ShadeMode.hpp>
#include <svx/sdr/properties/properties.hxx>
#include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <basegfx/range/b2drange.hxx>
#include <svx/sdr/primitive2d/sdrattributecreator.hxx>
#include <drawinglayer/attribute/sdrlineattribute.hxx>
#include <drawinglayer/attribute/sdrlinestartendattribute.hxx>
#include <svx/xlnwtit.hxx>
#include <svx/xlntrit.hxx>
#include <svx/xfltrit.hxx>

#define ITEMVALUE(ItemSet,Id,Cast)  ((const Cast&)(ItemSet).Get(Id)).GetValue()
using namespace com::sun::star;
using namespace com::sun::star::uno;

const rtl::OUString	sExtrusion( RTL_CONSTASCII_USTRINGPARAM ( "Extrusion" ) );

void GetOrigin( SdrCustomShapeGeometryItem& rItem, double& rOriginX, double& rOriginY )
{
	::com::sun::star::drawing::EnhancedCustomShapeParameterPair aOriginParaPair;
 	const rtl::OUString	sOrigin( RTL_CONSTASCII_USTRINGPARAM ( "Origin" ) );
	Any* pAny = rItem.GetPropertyValueByName( sExtrusion, sOrigin );
	if ( ! ( pAny && ( *pAny >>= aOriginParaPair ) && ( aOriginParaPair.First.Value >>= rOriginX ) && ( aOriginParaPair.Second.Value >>= rOriginY ) ) )
	{
		rOriginX = 0.50;
		rOriginY =-0.50;
	}
}

void GetRotateAngle( SdrCustomShapeGeometryItem& rItem, double& rAngleX, double& rAngleY )
{
	::com::sun::star::drawing::EnhancedCustomShapeParameterPair aRotateAngleParaPair;
 	const rtl::OUString	sRotateAngle( RTL_CONSTASCII_USTRINGPARAM ( "RotateAngle" ) );
	Any* pAny = rItem.GetPropertyValueByName( sExtrusion, sRotateAngle );
	if ( ! ( pAny && ( *pAny >>= aRotateAngleParaPair ) && ( aRotateAngleParaPair.First.Value >>= rAngleX ) && ( aRotateAngleParaPair.Second.Value >>= rAngleY ) ) )
	{
		rAngleX = 0.0;
		rAngleY = 0.0;
	}
	rAngleX *= F_PI180;
	rAngleY *= F_PI180;
}

void GetSkew( SdrCustomShapeGeometryItem& rItem, double& rSkewAmount, double& rSkewAngle )
{
	::com::sun::star::drawing::EnhancedCustomShapeParameterPair aSkewParaPair;
 	const rtl::OUString	sSkew( RTL_CONSTASCII_USTRINGPARAM ( "Skew" ) );
	Any* pAny = rItem.GetPropertyValueByName( sExtrusion, sSkew );
	if ( ! ( pAny && ( *pAny >>= aSkewParaPair ) && ( aSkewParaPair.First.Value >>= rSkewAmount ) && ( aSkewParaPair.Second.Value >>= rSkewAngle ) ) )
	{
		rSkewAmount = 50;
		rSkewAngle = -135;
	}
	rSkewAngle *= F_PI180;
}

void GetExtrusionDepth( SdrCustomShapeGeometryItem& rItem, const double* pMap, double& rBackwardDepth, double& rForwardDepth )
{
	::com::sun::star::drawing::EnhancedCustomShapeParameterPair aDepthParaPair;
	double fDepth = 0, fFraction = 0;
	const rtl::OUString	sDepth( RTL_CONSTASCII_USTRINGPARAM ( "Depth" ) );
	Any* pAny = rItem.GetPropertyValueByName( sExtrusion, sDepth );
	if ( pAny && ( *pAny >>= aDepthParaPair ) && ( aDepthParaPair.First.Value >>= fDepth ) && ( aDepthParaPair.Second.Value >>= fFraction ) )
	{
		rForwardDepth = fDepth * fFraction;
		rBackwardDepth = fDepth - rForwardDepth;
	}
	else
	{
		rBackwardDepth = 1270;
		rForwardDepth = 0;
	}
	if ( pMap )
	{
		double fMap = *pMap;
		rBackwardDepth *= fMap;
		rForwardDepth *= fMap;
	}
}

double GetDouble( SdrCustomShapeGeometryItem& rItem, const rtl::OUString& rPropertyName, double fDefault, const double* pMap )
{
	double fRetValue = fDefault;
	Any* pAny = rItem.GetPropertyValueByName( sExtrusion, rPropertyName );
	if ( pAny )
		*pAny >>= fRetValue;
	if ( pMap )
		fRetValue *= *pMap;
	return fRetValue;
}

drawing::ShadeMode GetShadeMode( SdrCustomShapeGeometryItem& rItem, const drawing::ShadeMode eDefault )
{
	drawing::ShadeMode eRet( eDefault );
	const rtl::OUString	sShadeMode( RTL_CONSTASCII_USTRINGPARAM ( "ShadeMode" ) );
	Any* pAny = rItem.GetPropertyValueByName( sExtrusion, sShadeMode );
	if ( pAny )
		*pAny >>= eRet;
	return eRet;
}

sal_Int32 GetInt32( SdrCustomShapeGeometryItem& rItem, const rtl::OUString& rPropertyName, const sal_Int32 nDefault )
{
	sal_Int32 nRetValue = nDefault;
	Any* pAny = rItem.GetPropertyValueByName( sExtrusion, rPropertyName );
	if ( pAny )
		*pAny >>= nRetValue;
	return nRetValue;
}

sal_Bool GetBool( SdrCustomShapeGeometryItem& rItem, const rtl::OUString& rPropertyName, const sal_Bool bDefault )
{
	sal_Bool bRetValue = bDefault;
	const Any* pAny = rItem.GetPropertyValueByName( sExtrusion, rPropertyName );
	if ( pAny )
		*pAny >>= bRetValue;
	return bRetValue;
}

awt::Point GetPoint( SdrCustomShapeGeometryItem& rItem, const rtl::OUString& rPropertyName, const awt::Point& rDefault )
{
	awt::Point aRetValue( rDefault );
	const Any* pAny = rItem.GetPropertyValueByName( sExtrusion, rPropertyName );
	if ( pAny )
		*pAny >>= aRetValue;
	return aRetValue;
}

drawing::Position3D GetPosition3D( SdrCustomShapeGeometryItem& rItem, const rtl::OUString& rPropertyName,
									const drawing::Position3D& rDefault, const double* pMap )
{
	drawing::Position3D aRetValue( rDefault );
	const Any* pAny = rItem.GetPropertyValueByName( sExtrusion, rPropertyName );
	if ( pAny )
		*pAny >>= aRetValue;
	if ( pMap )
	{
		aRetValue.PositionX *= *pMap;
		aRetValue.PositionY *= *pMap;
		aRetValue.PositionZ *= *pMap;
	}
	return aRetValue;
}

drawing::Direction3D GetDirection3D( SdrCustomShapeGeometryItem& rItem, const rtl::OUString& rPropertyName, const drawing::Direction3D& rDefault )
{
	drawing::Direction3D aRetValue( rDefault );
	const Any* pAny = rItem.GetPropertyValueByName( sExtrusion, rPropertyName );
	if ( pAny )
		*pAny >>= aRetValue;
	return aRetValue;
}

EnhancedCustomShape3d::Transformation2D::Transformation2D( const SdrObject* pCustomShape, const Rectangle& /*rBoundRect*/, const double *pM )
:	aCenter( pCustomShape->GetSnapRect().Center() )
,	eProjectionMode( drawing::ProjectionMode_PARALLEL )
,	pMap( pM )
{
	SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)pCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
	const rtl::OUString	sProjectionMode( RTL_CONSTASCII_USTRINGPARAM ( "ProjectionMode" ) );
	Any* pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, sProjectionMode );
	if ( pAny )
		*pAny >>= eProjectionMode;

	if ( eProjectionMode == drawing::ProjectionMode_PARALLEL )
		GetSkew( rGeometryItem, fSkew, fSkewAngle );
	else
	{
		fZScreen = 0.0;
		GetOrigin( rGeometryItem, fOriginX, fOriginY );
		fOriginX = fOriginX * pCustomShape->GetLogicRect().GetWidth();
		fOriginY = fOriginY * pCustomShape->GetLogicRect().GetHeight();

		const rtl::OUString	sViewPoint( RTL_CONSTASCII_USTRINGPARAM ( "ViewPoint" ) );
		drawing::Position3D aViewPointDefault( 3472, -3472, 25000 );
		drawing::Position3D aViewPoint( GetPosition3D( rGeometryItem, sViewPoint, aViewPointDefault, pMap ) );
		fViewPoint.setX(aViewPoint.PositionX);
		fViewPoint.setY(aViewPoint.PositionY);
		fViewPoint.setZ(-aViewPoint.PositionZ);
	}
}

basegfx::B3DPolygon EnhancedCustomShape3d::Transformation2D::ApplySkewSettings( const basegfx::B3DPolygon& rPoly3D ) const
{
	basegfx::B3DPolygon aRetval;

	sal_uInt32 j;
	for ( j = 0L; j < rPoly3D.count(); j++ )
	{
		const basegfx::B3DPoint aPoint(rPoly3D.getB3DPoint(j));
		double fDepth(-( aPoint.getZ() * fSkew ) / 100.0);
		aRetval.append(basegfx::B3DPoint(
			aPoint.getX() + (fDepth * cos( fSkewAngle )),
			aPoint.getY() - (fDepth * sin( fSkewAngle )),
			aPoint.getZ()));
	}

	return aRetval;
}

Point EnhancedCustomShape3d::Transformation2D::Transform2D( const basegfx::B3DPoint& rPoint3D ) const
{
	Point aPoint2D;
	if ( eProjectionMode == drawing::ProjectionMode_PARALLEL )
	{
		aPoint2D.X() = (sal_Int32)rPoint3D.getX();
		aPoint2D.Y() = (sal_Int32)rPoint3D.getY();
	}
	else
	{
		double fX = rPoint3D.getX() - fOriginX;
		double fY = rPoint3D.getY() - fOriginY;
		double f = ( fZScreen - fViewPoint.getZ() ) / ( rPoint3D.getZ() - fViewPoint.getZ() );
		aPoint2D.X() = (sal_Int32)(( fX - fViewPoint.getX() ) * f + fViewPoint.getX() + fOriginX );
		aPoint2D.Y() = (sal_Int32)(( fY - fViewPoint.getY() ) * f + fViewPoint.getY() + fOriginY );
	}
	aPoint2D.Move( aCenter.X(), aCenter.Y() );
	return aPoint2D;
}

sal_Bool EnhancedCustomShape3d::Transformation2D::IsParallel() const
{
	return eProjectionMode == com::sun::star::drawing::ProjectionMode_PARALLEL;
}

SdrObject* EnhancedCustomShape3d::Create3DObject( const SdrObject* pShape2d, const SdrObject* pCustomShape )
{
	SdrObject*	pRet = NULL;
	SdrModel*	pModel = pCustomShape->GetModel();
	SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)pCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );

	double		fMap, *pMap = NULL;
	if ( pModel )
	{
		fMap = 1.0;
		Fraction aFraction( pModel->GetScaleFraction() );
		if ( ( aFraction.GetNumerator() ) != 1 || ( aFraction.GetDenominator() != 1 ) )
		{
			fMap *= aFraction.GetNumerator();
			fMap /= aFraction.GetDenominator();
			pMap = &fMap;
		}
		if ( pModel->GetScaleUnit() != MAP_100TH_MM )
		{
			DBG_ASSERT( pModel->GetScaleUnit() == MAP_TWIP, "EnhancedCustomShape3d::Current MapMode is Unsupported" );
			fMap *= 1440.0 / 2540.0;
			pMap = &fMap;
		}
	}
	if ( GetBool( rGeometryItem, sExtrusion, sal_False ) )
	{
		sal_Bool bIsMirroredX = ((SdrObjCustomShape*)pCustomShape)->IsMirroredX();
		sal_Bool bIsMirroredY = ((SdrObjCustomShape*)pCustomShape)->IsMirroredY();
		Rectangle aSnapRect( pCustomShape->GetLogicRect() );
		long nObjectRotation = pCustomShape->GetRotateAngle();
		if ( nObjectRotation )
		{
			double a = ( 36000 - nObjectRotation ) * nPi180;
			long dx = aSnapRect.Right() - aSnapRect.Left();
			long dy = aSnapRect.Bottom()- aSnapRect.Top();
			Point aP( aSnapRect.TopLeft() );
			RotatePoint( aP, pCustomShape->GetSnapRect().Center(), sin( a ), cos( a ) );
			aSnapRect.Left() = aP.X();
			aSnapRect.Top() = aP.Y();
			aSnapRect.Right() = aSnapRect.Left() + dx;
			aSnapRect.Bottom() = aSnapRect.Top() + dy;
		}
		Point aCenter( aSnapRect.Center() );

		SfxItemSet aSet( pCustomShape->GetMergedItemSet() );

        //SJ: vertical writing is not required, by removing this item no outliner is created
        aSet.ClearItem( SDRATTR_TEXTDIRECTION );

        // #i105323# For 3D AutoShapes, the shadow attribute has to be applied to each
		// created visualisation helper model shape individually. The shadow itself
		// will then be rendered from the 3D renderer correctly for the whole 3D scene
		// (and thus behind all objects of which the visualisation may be built). So,
		// dio NOT remove it from the ItemSet here.
	    // aSet.ClearItem(SDRATTR_SHADOW);

        std::vector< E3dCompoundObject* > aPlaceholderObjectList;

		double fExtrusionBackward, fExtrusionForward;
		GetExtrusionDepth( rGeometryItem, pMap, fExtrusionBackward, fExtrusionForward );
		double fDepth = fExtrusionBackward + fExtrusionForward;
		if ( fDepth < 1.0 )
			fDepth = 1.0;

		drawing::ProjectionMode eProjectionMode( drawing::ProjectionMode_PARALLEL );
		const rtl::OUString	sProjectionMode( RTL_CONSTASCII_USTRINGPARAM ( "ProjectionMode" ) );
		Any* pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, sProjectionMode );
		if ( pAny )
			*pAny >>= eProjectionMode;
		ProjectionType eProjectionType( eProjectionMode == drawing::ProjectionMode_PARALLEL ? PR_PARALLEL : PR_PERSPECTIVE );

		// pShape2d Umwandeln in Szene mit 3D Objekt
		E3dDefaultAttributes a3DDefaultAttr;
		a3DDefaultAttr.SetDefaultLatheCharacterMode( sal_True );
		a3DDefaultAttr.SetDefaultExtrudeCharacterMode( sal_True );

		E3dScene* pScene = new E3dPolyScene( a3DDefaultAttr );

		sal_Bool bSceneHasObjects ( sal_False );
		sal_Bool bUseTwoFillStyles( sal_False );

		drawing::ShadeMode eShadeMode( GetShadeMode( rGeometryItem, drawing::ShadeMode_FLAT ) );
		const rtl::OUString	sExtrusionColor( RTL_CONSTASCII_USTRINGPARAM ( "Color" ) );
		sal_Bool bUseExtrusionColor = GetBool( rGeometryItem, sExtrusionColor, sal_False );

		XFillStyle eFillStyle( ITEMVALUE( aSet, XATTR_FILLSTYLE, XFillStyleItem ) );
		pScene->GetProperties().SetObjectItem( Svx3DShadeModeItem( 0 ) );
		aSet.Put( Svx3DPercentDiagonalItem( 0 ) );
		aSet.Put( Svx3DTextureModeItem( 1 ) );
		aSet.Put( Svx3DNormalsKindItem( 1 ) );

		if ( eShadeMode == drawing::ShadeMode_DRAFT )
		{
			aSet.Put( XLineStyleItem( XLINE_SOLID ) );
			aSet.Put( XFillStyleItem ( XFILL_NONE ) );
			aSet.Put( Svx3DDoubleSidedItem( sal_True ) );
		}
		else
		{
			aSet.Put( XLineStyleItem( XLINE_NONE ) );
			if ( eFillStyle == XFILL_NONE )
				aSet.Put( XFillStyleItem( XFILL_SOLID ) );
			else if ( ( eFillStyle == XFILL_BITMAP ) || ( eFillStyle == XFILL_GRADIENT ) || bUseExtrusionColor )
				bUseTwoFillStyles = sal_True;

			// #116336#
			// If shapes are mirrored once (mirroring two times correct geometry again)
			// double-sided at the object and two-sided-lighting at the scene need to be set.
            //
            // #122777# Also use double sided for two fill styles since there several 3d objects get
            // created with a depth of 0; one of them is the backside which needs double-sided to
            // get visible
			if(bUseTwoFillStyles || (bIsMirroredX && !bIsMirroredY) || (!bIsMirroredX && bIsMirroredY))
			{
				aSet.Put( Svx3DDoubleSidedItem( sal_True ) );
				pScene->GetProperties().SetObjectItem( Svx3DTwoSidedLightingItem( sal_True ) );
			}
		}

		Rectangle aBoundRect2d;
		SdrObjListIter aIter( *pShape2d, IM_DEEPNOGROUPS );
        const bool bMultipleSubObjects(aIter.Count() > 1);

		while( aIter.IsMore() )
		{
			const SdrObject* pNext = aIter.Next();
			sal_Bool bIsPlaceholderObject = (((XFillStyleItem&)pNext->GetMergedItem( XATTR_FILLSTYLE )).GetValue() == XFILL_NONE )
										&& (((XLineStyleItem&)pNext->GetMergedItem( XATTR_LINESTYLE )).GetValue() == XLINE_NONE );
			basegfx::B2DPolyPolygon aPolyPoly;
    		SfxItemSet aLocalSet(aSet);
            XFillStyle aLocalFillStyle(eFillStyle);

			if ( pNext->ISA( SdrPathObj ) )
			{
                const SfxItemSet& rSet = pNext->GetMergedItemSet();
                bool bNeedToConvertToContour(false);

                // do conversion only for single line objects; for all others a fill and a
                // line object get created. When we have fill, we want no line. That line has
                // always been there, but since it was never converted to contour, it kept
                // invisible (all this 'hidden' logic should be migrated to primitives).
                if(!bMultipleSubObjects)
                {
                    const XFillStyle eStyle(((XFillStyleItem&)(rSet.Get(XATTR_FILLSTYLE))).GetValue());

                    if(XFILL_NONE == eStyle)
                    {
                        const drawinglayer::attribute::SdrLineAttribute aLine(
                            drawinglayer::primitive2d::createNewSdrLineAttribute(rSet));

                        bNeedToConvertToContour = (0.0 < aLine.getWidth() || 0.0 != aLine.getFullDotDashLen());

                        if(!bNeedToConvertToContour && !aLine.isDefault())
                        {
                            const drawinglayer::attribute::SdrLineStartEndAttribute aLineStartEnd(
                                drawinglayer::primitive2d::createNewSdrLineStartEndAttribute(rSet, aLine.getWidth()));

                            if((aLineStartEnd.getStartWidth() && aLineStartEnd.isStartActive())
                                || (aLineStartEnd.getEndWidth() && aLineStartEnd.isEndActive()))
                            {
                                bNeedToConvertToContour = true;
                            }
                        }
                    }
                }

                if(bNeedToConvertToContour)
                {
                	SdrObject* pNewObj = pNext->ConvertToContourObj(const_cast< SdrObject* >(pNext));
                    SdrPathObj* pNewPathObj = dynamic_cast< SdrPathObj* >(pNewObj);

                    if(pNewPathObj)
                    {
                        aPolyPoly = pNewPathObj->GetPathPoly();

                        if(aPolyPoly.isClosed())
                        {
                            // correct item properties from line to fill style
                            if(eShadeMode == drawing::ShadeMode_DRAFT)
                            {
                                // for draft, create wireframe with fixed line width
                                aLocalSet.Put(XLineStyleItem(XLINE_SOLID));
                                aLocalSet.Put(XLineWidthItem(40));
                                aLocalFillStyle = XFILL_NONE;
                            }
                            else
                            {
                                // switch from line to fill, copy line attr to fill attr (color, transparence)
				                aLocalSet.Put(XLineWidthItem(0));
				                aLocalSet.Put(XLineStyleItem(XLINE_NONE));
				                aLocalSet.Put(XFillColorItem(XubString(), ((const XLineColorItem&)(aLocalSet.Get(XATTR_LINECOLOR))).GetColorValue()));
				                aLocalSet.Put(XFillStyleItem(XFILL_SOLID));
				                aLocalSet.Put(XFillTransparenceItem(((const XLineTransparenceItem&)(aLocalSet.Get(XATTR_LINETRANSPARENCE))).GetValue()));
                                aLocalFillStyle = XFILL_SOLID;
                            }
                        }
                        else
                        {
                            // correct item properties to hairlines
				            aLocalSet.Put(XLineWidthItem(0));
				            aLocalSet.Put(XLineStyleItem(XLINE_SOLID));
                        }
                    }

                    SdrObject::Free(pNewObj);
                }
                else
                {
                    aPolyPoly = ((SdrPathObj*)pNext)->GetPathPoly();
                }
			}
			else
			{
				SdrObject* pNewObj = pNext->ConvertToPolyObj( sal_False, sal_False );
				SdrPathObj* pPath = PTR_CAST( SdrPathObj, pNewObj );
				if ( pPath )
					aPolyPoly = pPath->GetPathPoly();
                SdrObject::Free( pNewObj );
			}

			if( aPolyPoly.count() )
			{
			    if(aPolyPoly.areControlPointsUsed())
			    {
				    aPolyPoly = basegfx::tools::adaptiveSubdivideByAngle(aPolyPoly);
			    }

                const basegfx::B2DRange aTempRange(basegfx::tools::getRange(aPolyPoly));
                const Rectangle aBoundRect(basegfx::fround(aTempRange.getMinX()), basegfx::fround(aTempRange.getMinY()), basegfx::fround(aTempRange.getMaxX()), basegfx::fround(aTempRange.getMaxY()));
				aBoundRect2d.Union( aBoundRect );

                // #122777# depth 0 is okay for planes when using double-sided
				E3dCompoundObject* p3DObj = new E3dExtrudeObj( a3DDefaultAttr, aPolyPoly, bUseTwoFillStyles ? 0 : fDepth );

				p3DObj->NbcSetLayer( pShape2d->GetLayer() );
				p3DObj->SetMergedItemSet( aLocalSet );
				if ( bIsPlaceholderObject )
					aPlaceholderObjectList.push_back( p3DObj );
				else if ( bUseTwoFillStyles )
				{
					BitmapEx aFillBmp;
					sal_Bool bFillBmpTile = ((XFillBmpTileItem&)p3DObj->GetMergedItem( XATTR_FILLBMP_TILE )).GetValue();
					if ( bFillBmpTile )
					{
						const XFillBitmapItem& rBmpItm = (XFillBitmapItem&)p3DObj->GetMergedItem(XATTR_FILLBITMAP);
						aFillBmp = rBmpItm.GetGraphicObject().GetGraphic().GetBitmapEx();

                        // #122777# old adaption of FillStyle bitmap size to 5-times the original size; this is not needed
                        // anymore and was used in old times to male the fill look better when converting to 3D. Removed
                        // from regular 3D objects for some time, also needs to be removed from CustomShapes
                        //
						//Size aLogicalSize = aFillBmp.GetPrefSize();
						//if ( aFillBmp.GetPrefMapMode() == MAP_PIXEL )
						//	aLogicalSize = Application::GetDefaultDevice()->PixelToLogic( aLogicalSize, MAP_100TH_MM );
						//else
						//	aLogicalSize = OutputDevice::LogicToLogic( aLogicalSize, aFillBmp.GetPrefMapMode(), MAP_100TH_MM );
						//aLogicalSize.Width()  *= 5;			;//				:-(		nice scaling, look at engine3d/obj3d.cxx
						//aLogicalSize.Height() *= 5;
						//aFillBmp.SetPrefSize( aLogicalSize );
						//aFillBmp.SetPrefMapMode( MAP_100TH_MM );
						//p3DObj->SetMergedItem(XFillBitmapItem(String(), Graphic(aFillBmp)));
					}
					else
					{
						if ( aSnapRect != aBoundRect )
						{
							const XFillBitmapItem& rBmpItm = (XFillBitmapItem&)p3DObj->GetMergedItem(XATTR_FILLBITMAP);
							aFillBmp = rBmpItm.GetGraphicObject().GetGraphic().GetBitmapEx();
							Size aBmpSize( aFillBmp.GetSizePixel() );
							double fXScale = (double)aBoundRect.GetWidth() / (double)aSnapRect.GetWidth();
							double fYScale = (double)aBoundRect.GetHeight() / (double)aSnapRect.GetHeight();

							Point aPt( (sal_Int32)( (double)( aBoundRect.Left() - aSnapRect.Left() )* (double)aBmpSize.Width() / (double)aSnapRect.GetWidth() ),
												(sal_Int32)( (double)( aBoundRect.Top() - aSnapRect.Top() ) * (double)aBmpSize.Height() / (double)aSnapRect.GetHeight() ) );
							Size aSize( (sal_Int32)( aBmpSize.Width() * fXScale ),
													(sal_Int32)( aBmpSize.Height() * fYScale ) );
							Rectangle aCropRect( aPt, aSize );
 							aFillBmp.Crop( aCropRect );
							p3DObj->SetMergedItem(XFillBitmapItem(String(), Graphic(aFillBmp)));
						}
					}
					pScene->Insert3DObj( p3DObj );
					p3DObj = new E3dExtrudeObj( a3DDefaultAttr, aPolyPoly, fDepth );
					p3DObj->NbcSetLayer( pShape2d->GetLayer() );
					p3DObj->SetMergedItemSet( aLocalSet );
					if ( bUseExtrusionColor )
						p3DObj->SetMergedItem( XFillColorItem( String(), ((XSecondaryFillColorItem&)pCustomShape->GetMergedItem( XATTR_SECONDARYFILLCOLOR )).GetColorValue() ) );
					p3DObj->SetMergedItem( XFillStyleItem( XFILL_SOLID ) );
					p3DObj->SetMergedItem( Svx3DCloseFrontItem( sal_False ) );
					p3DObj->SetMergedItem( Svx3DCloseBackItem( sal_False ) );
					pScene->Insert3DObj( p3DObj );

                    // #122777# depth 0 is okay for planes when using double-sided
					p3DObj = new E3dExtrudeObj( a3DDefaultAttr, aPolyPoly, 0 );

					p3DObj->NbcSetLayer( pShape2d->GetLayer() );
					p3DObj->SetMergedItemSet( aLocalSet );

					basegfx::B3DHomMatrix aFrontTransform( p3DObj->GetTransform() );
					aFrontTransform.translate( 0.0, 0.0, fDepth );
					p3DObj->NbcSetTransform( aFrontTransform );

					if ( ( aLocalFillStyle == XFILL_BITMAP ) && !aFillBmp.IsEmpty() )
                    {
						p3DObj->SetMergedItem(XFillBitmapItem(String(), Graphic(aFillBmp)));
                    }
				}
				else if ( aLocalFillStyle == XFILL_NONE )
				{
					XLineColorItem& rLineColor = (XLineColorItem&)p3DObj->GetMergedItem( XATTR_LINECOLOR );
					p3DObj->SetMergedItem( XFillColorItem( String(), rLineColor.GetColorValue() ) );
					p3DObj->SetMergedItem( Svx3DDoubleSidedItem( sal_True ) );
					p3DObj->SetMergedItem( Svx3DCloseFrontItem( sal_False ) );
					p3DObj->SetMergedItem( Svx3DCloseBackItem( sal_False ) );
				}
				pScene->Insert3DObj( p3DObj );
				bSceneHasObjects = sal_True;
			}
		}

		if ( bSceneHasObjects )	// is the SdrObject properly converted
		{
			// then we can change the return value
			pRet = pScene;

			// Kameraeinstellungen, Perspektive ...
			Camera3D& rCamera = (Camera3D&)pScene->GetCamera();
			const basegfx::B3DRange& rVolume = pScene->GetBoundVolume();
			pScene->NbcSetSnapRect( aSnapRect );

			// InitScene replacement
			double fW = rVolume.getWidth();
			double fH = rVolume.getHeight();

			rCamera.SetAutoAdjustProjection( sal_False );
			rCamera.SetViewWindow( -fW / 2, - fH / 2, fW, fH);
			basegfx::B3DPoint aLookAt( 0.0, 0.0, 0.0 );
			basegfx::B3DPoint aCamPos( 0.0, 0.0, 100.0 );
			rCamera.SetDefaults( basegfx::B3DPoint( 0.0, 0.0, 100.0 ), aLookAt, 100.0 );
			rCamera.SetPosAndLookAt( aCamPos, aLookAt );
			rCamera.SetFocalLength( 1.0 );
			rCamera.SetProjection( eProjectionType );
			pScene->SetCamera( rCamera );
			pScene->SetRectsDirty();

			double fOriginX, fOriginY;
			GetOrigin( rGeometryItem, fOriginX, fOriginY );
			fOriginX = fOriginX * aSnapRect.GetWidth();
			fOriginY = fOriginY * aSnapRect.GetHeight();

			basegfx::B3DHomMatrix aNewTransform( pScene->GetTransform() );
			aNewTransform.translate( -aCenter.X(), aCenter.Y(), -pScene->GetBoundVolume().getDepth() );

			double fXRotate, fYRotate;
			GetRotateAngle( rGeometryItem, fXRotate, fYRotate );
			double fZRotate = ((SdrObjCustomShape*)pCustomShape)->GetObjectRotation() * F_PI180;
			if ( fZRotate != 0.0 )
				aNewTransform.rotate( 0.0, 0.0, fZRotate );
			if ( bIsMirroredX )
				aNewTransform.scale( -1.0, 1, 1 );
			if ( bIsMirroredY )
				aNewTransform.scale( 1, -1.0, 1 );
			if( fYRotate != 0.0 )
				aNewTransform.rotate( 0.0, -fYRotate, 0.0 );
			if( fXRotate != 0.0 )
				aNewTransform.rotate( -fXRotate, 0.0, 0.0 );
			if ( eProjectionType == PR_PARALLEL )
			{
				double fSkew, fAlpha;
				GetSkew( rGeometryItem, fSkew, fAlpha );
				if ( fSkew != 0.0 )
				{
					double fInvTanBeta( fSkew / 100.0 );
					if(fInvTanBeta)
					{
						aNewTransform.shearXY(
							fInvTanBeta * cos(fAlpha),
							fInvTanBeta * sin(fAlpha));
					}
				}
				basegfx::B3DPoint _aLookAt( 0.0, 0.0, 0.0 );
				basegfx::B3DPoint _aNewCamPos( 0.0, 0.0, 25000.0 );
				rCamera.SetPosAndLookAt( _aNewCamPos, _aLookAt );
				pScene->SetCamera( rCamera );
			}
			else
			{
				aNewTransform.translate( -fOriginX, fOriginY, 0.0 );
				// now set correct camera position
				const rtl::OUString	sViewPoint( RTL_CONSTASCII_USTRINGPARAM ( "ViewPoint" ) );
				drawing::Position3D aViewPointDefault( 3472, -3472, 25000 );
				drawing::Position3D aViewPoint( GetPosition3D( rGeometryItem, sViewPoint, aViewPointDefault, pMap ) );
				double fViewPointX = aViewPoint.PositionX;
				double fViewPointY = aViewPoint.PositionY;
				double fViewPointZ = aViewPoint.PositionZ;
				basegfx::B3DPoint _aLookAt( fViewPointX, -fViewPointY, 0.0 );
				basegfx::B3DPoint aNewCamPos( fViewPointX, -fViewPointY, fViewPointZ );
				rCamera.SetPosAndLookAt( aNewCamPos, _aLookAt );
				pScene->SetCamera( rCamera );
			}

			pScene->NbcSetTransform( aNewTransform );

			///////////
			// light //
			///////////

			const rtl::OUString	sBrightness( RTL_CONSTASCII_USTRINGPARAM ( "Brightness" ) );
			double fAmbientIntensity = GetDouble( rGeometryItem, sBrightness, 22178.0 / 655.36, NULL ) / 100.0;


			const rtl::OUString	sFirstLightDirection( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightDirection" ) );
			drawing::Direction3D aFirstLightDirectionDefault( 50000, 0, 10000 );
			drawing::Direction3D aFirstLightDirection( GetDirection3D( rGeometryItem, sFirstLightDirection, aFirstLightDirectionDefault ) );
			if ( aFirstLightDirection.DirectionZ == 0.0 )
				aFirstLightDirection.DirectionZ = 1.0;

			const rtl::OUString	sFirstLightLevel( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightLevel" ) );
			double fLightIntensity = GetDouble( rGeometryItem, sFirstLightLevel, 43712.0 / 655.36, NULL ) / 100.0;

			const rtl::OUString	sFirstLightHarsh( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightHarsh" ) );
			/* sal_Bool bFirstLightHarsh = */ GetBool( rGeometryItem, sFirstLightHarsh, sal_False );

			const rtl::OUString	sSecondLightDirection( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightDirection" ) );
			drawing::Direction3D aSecondLightDirectionDefault( -50000, 0, 10000 );
			drawing::Direction3D aSecondLightDirection( GetDirection3D( rGeometryItem, sSecondLightDirection, aSecondLightDirectionDefault ) );
			if ( aSecondLightDirection.DirectionZ == 0.0 )
				aSecondLightDirection.DirectionZ = -1;

			const rtl::OUString	sSecondLightLevel( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightLevel" ) );
			double fLight2Intensity = GetDouble( rGeometryItem, sSecondLightLevel, 43712.0 / 655.36, NULL ) / 100.0;

			const rtl::OUString	sSecondLightHarsh( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightHarsh" ) );
			const rtl::OUString	sLightFace( RTL_CONSTASCII_USTRINGPARAM ( "LightFace" ) );
			/* sal_Bool bLight2Harsh = */ GetBool( rGeometryItem, sSecondLightHarsh, sal_False );
			/* sal_Bool bLightFace = */ GetBool( rGeometryItem, sLightFace, sal_False );

			sal_uInt16 nAmbientColor = (sal_uInt16)( fAmbientIntensity * 255.0 );
			if ( nAmbientColor > 255 )
				nAmbientColor = 255;
			Color aGlobalAmbientColor( (sal_uInt8)nAmbientColor, (sal_uInt8)nAmbientColor, (sal_uInt8)nAmbientColor );
			pScene->GetProperties().SetObjectItem( Svx3DAmbientcolorItem( aGlobalAmbientColor ) );

			sal_uInt8 nSpotLight1 = (sal_uInt8)( fLightIntensity * 255.0 );
			basegfx::B3DVector aSpotLight1( aFirstLightDirection.DirectionX, - ( aFirstLightDirection.DirectionY ), -( aFirstLightDirection.DirectionZ ) );
			aSpotLight1.normalize();
			pScene->GetProperties().SetObjectItem( Svx3DLightOnOff1Item( sal_True ) );
			Color aAmbientSpot1Color( nSpotLight1, nSpotLight1, nSpotLight1 );
			pScene->GetProperties().SetObjectItem( Svx3DLightcolor1Item( aAmbientSpot1Color ) );
			pScene->GetProperties().SetObjectItem( Svx3DLightDirection1Item( aSpotLight1 ) );

			sal_uInt8 nSpotLight2 = (sal_uInt8)( fLight2Intensity * 255.0 );
			basegfx::B3DVector aSpotLight2( aSecondLightDirection.DirectionX, -aSecondLightDirection.DirectionY, -aSecondLightDirection.DirectionZ );
			aSpotLight2.normalize();
			pScene->GetProperties().SetObjectItem( Svx3DLightOnOff2Item( sal_True ) );
			Color aAmbientSpot2Color( nSpotLight2, nSpotLight2, nSpotLight2 );
			pScene->GetProperties().SetObjectItem( Svx3DLightcolor2Item( aAmbientSpot2Color ) );
			pScene->GetProperties().SetObjectItem( Svx3DLightDirection2Item( aSpotLight2 ) );

				sal_uInt8 nSpotLight3 = 70;
				basegfx::B3DVector aSpotLight3( 0.0, 0.0, 1.0 );
				pScene->GetProperties().SetObjectItem( Svx3DLightOnOff3Item( sal_True ) );
				Color aAmbientSpot3Color( nSpotLight3, nSpotLight3, nSpotLight3 );
				pScene->GetProperties().SetObjectItem( Svx3DLightcolor3Item( aAmbientSpot3Color ) );
				pScene->GetProperties().SetObjectItem( Svx3DLightDirection3Item( aSpotLight3 ) );

			const rtl::OUString	sSpecularity( RTL_CONSTASCII_USTRINGPARAM ( "Specularity" ) );
			const rtl::OUString	sDiffusion( RTL_CONSTASCII_USTRINGPARAM ( "Diffusion" ) );
			const rtl::OUString	sShininess( RTL_CONSTASCII_USTRINGPARAM ( "Shininess" ) );
			const rtl::OUString	sMetal( RTL_CONSTASCII_USTRINGPARAM ( "Metal" ) );
			double fSpecular = GetDouble( rGeometryItem, sSpecularity, 0, NULL ) / 100;
			sal_Bool bMetal = GetBool( rGeometryItem, sMetal, sal_False );

			Color aSpecularCol( 225,225,225 );
			if ( bMetal )
			{
				aSpecularCol = Color( 200, 200, 200 );
				fSpecular += 0.15;
			}
			sal_Int32 nIntensity = (sal_Int32)fSpecular * 100;
			if ( nIntensity > 100 )
				nIntensity = 100;
			else if ( nIntensity < 0 )
				nIntensity = 0;
			nIntensity = 100 - nIntensity;
			pScene->GetProperties().SetObjectItem( Svx3DMaterialSpecularItem( aSpecularCol ) );
			pScene->GetProperties().SetObjectItem( Svx3DMaterialSpecularIntensityItem( (sal_uInt16)nIntensity ) );

			pScene->SetLogicRect( CalculateNewSnapRect( pCustomShape, aSnapRect, aBoundRect2d, pMap ) );

			// removing placeholder objects
			std::vector< E3dCompoundObject* >::iterator aObjectListIter( aPlaceholderObjectList.begin() );
			while ( aObjectListIter != aPlaceholderObjectList.end() )
			{
				pScene->Remove3DObj( *aObjectListIter );
				delete *aObjectListIter++;
			}
		}
		else
			delete pScene;
	}
	return pRet;
}

Rectangle EnhancedCustomShape3d::CalculateNewSnapRect( const SdrObject* pCustomShape, const Rectangle& rSnapRect, const Rectangle& rBoundRect, const double* pMap )
{
	SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)pCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
	const Point aCenter( rSnapRect.Center() );
	double fExtrusionBackward, fExtrusionForward;
	GetExtrusionDepth( rGeometryItem, pMap, fExtrusionBackward, fExtrusionForward );
	sal_uInt32 i;

	// creating initial bound volume ( without rotation. skewing.and camera )
	basegfx::B3DPolygon aBoundVolume;
	const Polygon aPolygon( rBoundRect );

	for ( i = 0L; i < 4L; i++ )
	{
		aBoundVolume.append(basegfx::B3DPoint(aPolygon[ (sal_uInt16)i ].X() - aCenter.X(), aPolygon[ (sal_uInt16)i ].Y() - aCenter.Y(), -fExtrusionForward));
	}

	for ( i = 0L; i < 4L; i++ )
	{
		aBoundVolume.append(basegfx::B3DPoint(aPolygon[ (sal_uInt16)i ].X() - aCenter.X(), aPolygon[ (sal_uInt16)i ].Y() - aCenter.Y(), fExtrusionBackward));
	}

	const rtl::OUString	sRotationCenter( RTL_CONSTASCII_USTRINGPARAM ( "RotationCenter" ) );
	drawing::Direction3D aRotationCenterDefault( 0, 0, 0 );	// default seems to be wrong, a fractional size of shape has to be used!!
	drawing::Direction3D aRotationCenter( GetDirection3D( rGeometryItem, sRotationCenter, aRotationCenterDefault ) );

	// double XCenterInGUnits = rPropSet.GetPropertyValue( DFF_Prop_c3DRotationCenterX, 0 );
	// double YCenterInGUnits = rPropSet.GetPropertyValue( DFF_Prop_c3DRotationCenterY, 0 );

	// sal_Int32 nRotationXAxisInProz = rPropSet.GetPropertyValue( DFF_Prop_c3DRotationAxisX, 100 );
	// sal_Int32 nRotationYAxisInProz = rPropSet.GetPropertyValue( DFF_Prop_c3DRotationAxisY, 0 );
	// sal_Int32 nRotationZAxisInProz = rPropSet.GetPropertyValue( DFF_Prop_c3DRotationAxisZ, 0 );


	double fXRotate, fYRotate;
	GetRotateAngle( rGeometryItem, fXRotate, fYRotate );
	double fZRotate = - ((SdrObjCustomShape*)pCustomShape)->GetObjectRotation() * F_PI180;

	// rotating bound volume
	basegfx::B3DHomMatrix aMatrix;
	aMatrix.translate(-aRotationCenter.DirectionX, -aRotationCenter.DirectionY, -aRotationCenter.DirectionZ);
	if ( fZRotate != 0.0 )
		aMatrix.rotate( 0.0, 0.0, fZRotate );
	if ( ((SdrObjCustomShape*)pCustomShape)->IsMirroredX() )
		aMatrix.scale( -1.0, 1, 1 );
	if ( ((SdrObjCustomShape*)pCustomShape)->IsMirroredY() )
		aMatrix.scale( 1, -1.0, 1 );
	if( fYRotate != 0.0 )
		aMatrix.rotate( 0.0, fYRotate, 0.0 );
	if( fXRotate != 0.0 )
		aMatrix.rotate( -fXRotate, 0.0, 0.0 );
	aMatrix.translate(aRotationCenter.DirectionX, aRotationCenter.DirectionY, aRotationCenter.DirectionZ);
	aBoundVolume.transform(aMatrix);

	Transformation2D aTransformation2D( pCustomShape, rSnapRect, pMap );
	if ( aTransformation2D.IsParallel() )
		aBoundVolume = aTransformation2D.ApplySkewSettings( aBoundVolume );

	Polygon aTransformed( 8 );
	for ( i = 0L; i < 8L; i++ )
		aTransformed[ (sal_uInt16)i ] = aTransformation2D.Transform2D( aBoundVolume.getB3DPoint( i ) );

	return aTransformed.GetBoundRect();
}
