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

				E3dCompoundObject* p3DObj = new E3dExtrudeObj( a3DDefaultAttr, aPolyPoly, bUseTwoFillStyles ? 10 : 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();
						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 );
					p3DObj = new E3dExtrudeObj( a3DDefaultAttr, aPolyPoly, 10 );
					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();
}
