/**************************************************************
 * 
 * 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();
}
