1f6e50924SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3f6e50924SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4f6e50924SAndrew Rist * or more contributor license agreements. See the NOTICE file 5f6e50924SAndrew Rist * distributed with this work for additional information 6f6e50924SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7f6e50924SAndrew Rist * to you under the Apache License, Version 2.0 (the 8f6e50924SAndrew Rist * "License"); you may not use this file except in compliance 9f6e50924SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11f6e50924SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13f6e50924SAndrew Rist * Unless required by applicable law or agreed to in writing, 14f6e50924SAndrew Rist * software distributed under the License is distributed on an 15f6e50924SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16f6e50924SAndrew Rist * KIND, either express or implied. See the License for the 17f6e50924SAndrew Rist * specific language governing permissions and limitations 18f6e50924SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20f6e50924SAndrew Rist *************************************************************/ 21f6e50924SAndrew Rist 22f6e50924SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_svx.hxx" 26cdf0e10cSrcweir #include "EnhancedCustomShape3d.hxx" 27cdf0e10cSrcweir #include <svx/svdetc.hxx> 28cdf0e10cSrcweir #include <svx/svdmodel.hxx> 29cdf0e10cSrcweir #include <tools/poly.hxx> 30cdf0e10cSrcweir #include <svx/svditer.hxx> 31cdf0e10cSrcweir #include <svx/svdobj.hxx> 32cdf0e10cSrcweir #include <svx/svdoashp.hxx> 33cdf0e10cSrcweir #include <svl/poolitem.hxx> 34cdf0e10cSrcweir #include <svl/itemset.hxx> 35cdf0e10cSrcweir #include <svx/xfillit0.hxx> 36cdf0e10cSrcweir #include <svx/xsflclit.hxx> 37cdf0e10cSrcweir #include <svx/xit.hxx> 38cdf0e10cSrcweir #include <svx/xbtmpit.hxx> 39cdf0e10cSrcweir #include <svx/xflclit.hxx> 40cdf0e10cSrcweir #include <svx/svdopath.hxx> 41cdf0e10cSrcweir #include <svx/svdogrp.hxx> 42cdf0e10cSrcweir #include <svx/svdpage.hxx> 43cdf0e10cSrcweir #include <svx/polysc3d.hxx> 44cdf0e10cSrcweir #include <svx/svddef.hxx> 45cdf0e10cSrcweir #include <svx/svx3ditems.hxx> 46cdf0e10cSrcweir #include <svx/extrud3d.hxx> 47cdf0e10cSrcweir #include <svx/xflbmtit.hxx> 48cdf0e10cSrcweir #include <vcl/svapp.hxx> 49cdf0e10cSrcweir #include <svx/xlnclit.hxx> 50cdf0e10cSrcweir #include <svx/sdasitm.hxx> 51cdf0e10cSrcweir #include <com/sun/star/awt/Point.hpp> 52cdf0e10cSrcweir #include <com/sun/star/drawing/Position3D.hpp> 53cdf0e10cSrcweir #include <com/sun/star/drawing/Direction3D.hpp> 54cdf0e10cSrcweir #include <com/sun/star/drawing/ShadeMode.hpp> 55cdf0e10cSrcweir #include <svx/sdr/properties/properties.hxx> 56cdf0e10cSrcweir #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp> 57cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygontools.hxx> 58cdf0e10cSrcweir #include <basegfx/range/b2drange.hxx> 598899a091SArmin Le Grand #include <svx/sdr/primitive2d/sdrattributecreator.hxx> 608899a091SArmin Le Grand #include <drawinglayer/attribute/sdrlineattribute.hxx> 618899a091SArmin Le Grand #include <drawinglayer/attribute/sdrlinestartendattribute.hxx> 628899a091SArmin Le Grand #include <svx/xlnwtit.hxx> 638899a091SArmin Le Grand #include <svx/xlntrit.hxx> 648899a091SArmin Le Grand #include <svx/xfltrit.hxx> 65cdf0e10cSrcweir 66cdf0e10cSrcweir #define ITEMVALUE(ItemSet,Id,Cast) ((const Cast&)(ItemSet).Get(Id)).GetValue() 67cdf0e10cSrcweir using namespace com::sun::star; 68cdf0e10cSrcweir using namespace com::sun::star::uno; 69cdf0e10cSrcweir 70cdf0e10cSrcweir const rtl::OUString sExtrusion( RTL_CONSTASCII_USTRINGPARAM ( "Extrusion" ) ); 71cdf0e10cSrcweir 72cdf0e10cSrcweir void GetOrigin( SdrCustomShapeGeometryItem& rItem, double& rOriginX, double& rOriginY ) 73cdf0e10cSrcweir { 74cdf0e10cSrcweir ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aOriginParaPair; 75cdf0e10cSrcweir const rtl::OUString sOrigin( RTL_CONSTASCII_USTRINGPARAM ( "Origin" ) ); 76cdf0e10cSrcweir Any* pAny = rItem.GetPropertyValueByName( sExtrusion, sOrigin ); 77cdf0e10cSrcweir if ( ! ( pAny && ( *pAny >>= aOriginParaPair ) && ( aOriginParaPair.First.Value >>= rOriginX ) && ( aOriginParaPair.Second.Value >>= rOriginY ) ) ) 78cdf0e10cSrcweir { 79cdf0e10cSrcweir rOriginX = 0.50; 80cdf0e10cSrcweir rOriginY =-0.50; 81cdf0e10cSrcweir } 82cdf0e10cSrcweir } 83cdf0e10cSrcweir 84cdf0e10cSrcweir void GetRotateAngle( SdrCustomShapeGeometryItem& rItem, double& rAngleX, double& rAngleY ) 85cdf0e10cSrcweir { 86cdf0e10cSrcweir ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aRotateAngleParaPair; 87cdf0e10cSrcweir const rtl::OUString sRotateAngle( RTL_CONSTASCII_USTRINGPARAM ( "RotateAngle" ) ); 88cdf0e10cSrcweir Any* pAny = rItem.GetPropertyValueByName( sExtrusion, sRotateAngle ); 89cdf0e10cSrcweir if ( ! ( pAny && ( *pAny >>= aRotateAngleParaPair ) && ( aRotateAngleParaPair.First.Value >>= rAngleX ) && ( aRotateAngleParaPair.Second.Value >>= rAngleY ) ) ) 90cdf0e10cSrcweir { 91cdf0e10cSrcweir rAngleX = 0.0; 92cdf0e10cSrcweir rAngleY = 0.0; 93cdf0e10cSrcweir } 94cdf0e10cSrcweir rAngleX *= F_PI180; 95cdf0e10cSrcweir rAngleY *= F_PI180; 96cdf0e10cSrcweir } 97cdf0e10cSrcweir 98cdf0e10cSrcweir void GetSkew( SdrCustomShapeGeometryItem& rItem, double& rSkewAmount, double& rSkewAngle ) 99cdf0e10cSrcweir { 100cdf0e10cSrcweir ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aSkewParaPair; 101cdf0e10cSrcweir const rtl::OUString sSkew( RTL_CONSTASCII_USTRINGPARAM ( "Skew" ) ); 102cdf0e10cSrcweir Any* pAny = rItem.GetPropertyValueByName( sExtrusion, sSkew ); 103cdf0e10cSrcweir if ( ! ( pAny && ( *pAny >>= aSkewParaPair ) && ( aSkewParaPair.First.Value >>= rSkewAmount ) && ( aSkewParaPair.Second.Value >>= rSkewAngle ) ) ) 104cdf0e10cSrcweir { 105cdf0e10cSrcweir rSkewAmount = 50; 106cdf0e10cSrcweir rSkewAngle = -135; 107cdf0e10cSrcweir } 108cdf0e10cSrcweir rSkewAngle *= F_PI180; 109cdf0e10cSrcweir } 110cdf0e10cSrcweir 111cdf0e10cSrcweir void GetExtrusionDepth( SdrCustomShapeGeometryItem& rItem, const double* pMap, double& rBackwardDepth, double& rForwardDepth ) 112cdf0e10cSrcweir { 113cdf0e10cSrcweir ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aDepthParaPair; 114cdf0e10cSrcweir double fDepth = 0, fFraction = 0; 115cdf0e10cSrcweir const rtl::OUString sDepth( RTL_CONSTASCII_USTRINGPARAM ( "Depth" ) ); 116cdf0e10cSrcweir Any* pAny = rItem.GetPropertyValueByName( sExtrusion, sDepth ); 117cdf0e10cSrcweir if ( pAny && ( *pAny >>= aDepthParaPair ) && ( aDepthParaPair.First.Value >>= fDepth ) && ( aDepthParaPair.Second.Value >>= fFraction ) ) 118cdf0e10cSrcweir { 119cdf0e10cSrcweir rForwardDepth = fDepth * fFraction; 120cdf0e10cSrcweir rBackwardDepth = fDepth - rForwardDepth; 121cdf0e10cSrcweir } 122cdf0e10cSrcweir else 123cdf0e10cSrcweir { 124cdf0e10cSrcweir rBackwardDepth = 1270; 125cdf0e10cSrcweir rForwardDepth = 0; 126cdf0e10cSrcweir } 127cdf0e10cSrcweir if ( pMap ) 128cdf0e10cSrcweir { 129cdf0e10cSrcweir double fMap = *pMap; 130cdf0e10cSrcweir rBackwardDepth *= fMap; 131cdf0e10cSrcweir rForwardDepth *= fMap; 132cdf0e10cSrcweir } 133cdf0e10cSrcweir } 134cdf0e10cSrcweir 135cdf0e10cSrcweir double GetDouble( SdrCustomShapeGeometryItem& rItem, const rtl::OUString& rPropertyName, double fDefault, const double* pMap ) 136cdf0e10cSrcweir { 137cdf0e10cSrcweir double fRetValue = fDefault; 138cdf0e10cSrcweir Any* pAny = rItem.GetPropertyValueByName( sExtrusion, rPropertyName ); 139cdf0e10cSrcweir if ( pAny ) 140cdf0e10cSrcweir *pAny >>= fRetValue; 141cdf0e10cSrcweir if ( pMap ) 142cdf0e10cSrcweir fRetValue *= *pMap; 143cdf0e10cSrcweir return fRetValue; 144cdf0e10cSrcweir } 145cdf0e10cSrcweir 146cdf0e10cSrcweir drawing::ShadeMode GetShadeMode( SdrCustomShapeGeometryItem& rItem, const drawing::ShadeMode eDefault ) 147cdf0e10cSrcweir { 148cdf0e10cSrcweir drawing::ShadeMode eRet( eDefault ); 149cdf0e10cSrcweir const rtl::OUString sShadeMode( RTL_CONSTASCII_USTRINGPARAM ( "ShadeMode" ) ); 150cdf0e10cSrcweir Any* pAny = rItem.GetPropertyValueByName( sExtrusion, sShadeMode ); 151cdf0e10cSrcweir if ( pAny ) 152cdf0e10cSrcweir *pAny >>= eRet; 153cdf0e10cSrcweir return eRet; 154cdf0e10cSrcweir } 155cdf0e10cSrcweir 156cdf0e10cSrcweir sal_Int32 GetInt32( SdrCustomShapeGeometryItem& rItem, const rtl::OUString& rPropertyName, const sal_Int32 nDefault ) 157cdf0e10cSrcweir { 158cdf0e10cSrcweir sal_Int32 nRetValue = nDefault; 159cdf0e10cSrcweir Any* pAny = rItem.GetPropertyValueByName( sExtrusion, rPropertyName ); 160cdf0e10cSrcweir if ( pAny ) 161cdf0e10cSrcweir *pAny >>= nRetValue; 162cdf0e10cSrcweir return nRetValue; 163cdf0e10cSrcweir } 164cdf0e10cSrcweir 165cdf0e10cSrcweir sal_Bool GetBool( SdrCustomShapeGeometryItem& rItem, const rtl::OUString& rPropertyName, const sal_Bool bDefault ) 166cdf0e10cSrcweir { 167cdf0e10cSrcweir sal_Bool bRetValue = bDefault; 168cdf0e10cSrcweir const Any* pAny = rItem.GetPropertyValueByName( sExtrusion, rPropertyName ); 169cdf0e10cSrcweir if ( pAny ) 170cdf0e10cSrcweir *pAny >>= bRetValue; 171cdf0e10cSrcweir return bRetValue; 172cdf0e10cSrcweir } 173cdf0e10cSrcweir 174cdf0e10cSrcweir awt::Point GetPoint( SdrCustomShapeGeometryItem& rItem, const rtl::OUString& rPropertyName, const awt::Point& rDefault ) 175cdf0e10cSrcweir { 176cdf0e10cSrcweir awt::Point aRetValue( rDefault ); 177cdf0e10cSrcweir const Any* pAny = rItem.GetPropertyValueByName( sExtrusion, rPropertyName ); 178cdf0e10cSrcweir if ( pAny ) 179cdf0e10cSrcweir *pAny >>= aRetValue; 180cdf0e10cSrcweir return aRetValue; 181cdf0e10cSrcweir } 182cdf0e10cSrcweir 183cdf0e10cSrcweir drawing::Position3D GetPosition3D( SdrCustomShapeGeometryItem& rItem, const rtl::OUString& rPropertyName, 184cdf0e10cSrcweir const drawing::Position3D& rDefault, const double* pMap ) 185cdf0e10cSrcweir { 186cdf0e10cSrcweir drawing::Position3D aRetValue( rDefault ); 187cdf0e10cSrcweir const Any* pAny = rItem.GetPropertyValueByName( sExtrusion, rPropertyName ); 188cdf0e10cSrcweir if ( pAny ) 189cdf0e10cSrcweir *pAny >>= aRetValue; 190cdf0e10cSrcweir if ( pMap ) 191cdf0e10cSrcweir { 192cdf0e10cSrcweir aRetValue.PositionX *= *pMap; 193cdf0e10cSrcweir aRetValue.PositionY *= *pMap; 194cdf0e10cSrcweir aRetValue.PositionZ *= *pMap; 195cdf0e10cSrcweir } 196cdf0e10cSrcweir return aRetValue; 197cdf0e10cSrcweir } 198cdf0e10cSrcweir 199cdf0e10cSrcweir drawing::Direction3D GetDirection3D( SdrCustomShapeGeometryItem& rItem, const rtl::OUString& rPropertyName, const drawing::Direction3D& rDefault ) 200cdf0e10cSrcweir { 201cdf0e10cSrcweir drawing::Direction3D aRetValue( rDefault ); 202cdf0e10cSrcweir const Any* pAny = rItem.GetPropertyValueByName( sExtrusion, rPropertyName ); 203cdf0e10cSrcweir if ( pAny ) 204cdf0e10cSrcweir *pAny >>= aRetValue; 205cdf0e10cSrcweir return aRetValue; 206cdf0e10cSrcweir } 207cdf0e10cSrcweir 208cdf0e10cSrcweir EnhancedCustomShape3d::Transformation2D::Transformation2D( const SdrObject* pCustomShape, const Rectangle& /*rBoundRect*/, const double *pM ) 209cdf0e10cSrcweir : aCenter( pCustomShape->GetSnapRect().Center() ) 210cdf0e10cSrcweir , eProjectionMode( drawing::ProjectionMode_PARALLEL ) 211cdf0e10cSrcweir , pMap( pM ) 212cdf0e10cSrcweir { 213cdf0e10cSrcweir SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)pCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ); 214cdf0e10cSrcweir const rtl::OUString sProjectionMode( RTL_CONSTASCII_USTRINGPARAM ( "ProjectionMode" ) ); 215cdf0e10cSrcweir Any* pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, sProjectionMode ); 216cdf0e10cSrcweir if ( pAny ) 217cdf0e10cSrcweir *pAny >>= eProjectionMode; 218cdf0e10cSrcweir 219cdf0e10cSrcweir if ( eProjectionMode == drawing::ProjectionMode_PARALLEL ) 220cdf0e10cSrcweir GetSkew( rGeometryItem, fSkew, fSkewAngle ); 221cdf0e10cSrcweir else 222cdf0e10cSrcweir { 223cdf0e10cSrcweir fZScreen = 0.0; 224cdf0e10cSrcweir GetOrigin( rGeometryItem, fOriginX, fOriginY ); 225cdf0e10cSrcweir fOriginX = fOriginX * pCustomShape->GetLogicRect().GetWidth(); 226cdf0e10cSrcweir fOriginY = fOriginY * pCustomShape->GetLogicRect().GetHeight(); 227cdf0e10cSrcweir 228cdf0e10cSrcweir const rtl::OUString sViewPoint( RTL_CONSTASCII_USTRINGPARAM ( "ViewPoint" ) ); 229cdf0e10cSrcweir drawing::Position3D aViewPointDefault( 3472, -3472, 25000 ); 230cdf0e10cSrcweir drawing::Position3D aViewPoint( GetPosition3D( rGeometryItem, sViewPoint, aViewPointDefault, pMap ) ); 231cdf0e10cSrcweir fViewPoint.setX(aViewPoint.PositionX); 232cdf0e10cSrcweir fViewPoint.setY(aViewPoint.PositionY); 233cdf0e10cSrcweir fViewPoint.setZ(-aViewPoint.PositionZ); 234cdf0e10cSrcweir } 235cdf0e10cSrcweir } 236cdf0e10cSrcweir 237cdf0e10cSrcweir basegfx::B3DPolygon EnhancedCustomShape3d::Transformation2D::ApplySkewSettings( const basegfx::B3DPolygon& rPoly3D ) const 238cdf0e10cSrcweir { 239cdf0e10cSrcweir basegfx::B3DPolygon aRetval; 240cdf0e10cSrcweir 241cdf0e10cSrcweir sal_uInt32 j; 242cdf0e10cSrcweir for ( j = 0L; j < rPoly3D.count(); j++ ) 243cdf0e10cSrcweir { 244cdf0e10cSrcweir const basegfx::B3DPoint aPoint(rPoly3D.getB3DPoint(j)); 245cdf0e10cSrcweir double fDepth(-( aPoint.getZ() * fSkew ) / 100.0); 246cdf0e10cSrcweir aRetval.append(basegfx::B3DPoint( 247cdf0e10cSrcweir aPoint.getX() + (fDepth * cos( fSkewAngle )), 248cdf0e10cSrcweir aPoint.getY() - (fDepth * sin( fSkewAngle )), 249cdf0e10cSrcweir aPoint.getZ())); 250cdf0e10cSrcweir } 251cdf0e10cSrcweir 252cdf0e10cSrcweir return aRetval; 253cdf0e10cSrcweir } 254cdf0e10cSrcweir 255cdf0e10cSrcweir Point EnhancedCustomShape3d::Transformation2D::Transform2D( const basegfx::B3DPoint& rPoint3D ) const 256cdf0e10cSrcweir { 257cdf0e10cSrcweir Point aPoint2D; 258cdf0e10cSrcweir if ( eProjectionMode == drawing::ProjectionMode_PARALLEL ) 259cdf0e10cSrcweir { 260cdf0e10cSrcweir aPoint2D.X() = (sal_Int32)rPoint3D.getX(); 261cdf0e10cSrcweir aPoint2D.Y() = (sal_Int32)rPoint3D.getY(); 262cdf0e10cSrcweir } 263cdf0e10cSrcweir else 264cdf0e10cSrcweir { 265cdf0e10cSrcweir double fX = rPoint3D.getX() - fOriginX; 266cdf0e10cSrcweir double fY = rPoint3D.getY() - fOriginY; 267cdf0e10cSrcweir double f = ( fZScreen - fViewPoint.getZ() ) / ( rPoint3D.getZ() - fViewPoint.getZ() ); 268cdf0e10cSrcweir aPoint2D.X() = (sal_Int32)(( fX - fViewPoint.getX() ) * f + fViewPoint.getX() + fOriginX ); 269cdf0e10cSrcweir aPoint2D.Y() = (sal_Int32)(( fY - fViewPoint.getY() ) * f + fViewPoint.getY() + fOriginY ); 270cdf0e10cSrcweir } 271cdf0e10cSrcweir aPoint2D.Move( aCenter.X(), aCenter.Y() ); 272cdf0e10cSrcweir return aPoint2D; 273cdf0e10cSrcweir } 274cdf0e10cSrcweir 275cdf0e10cSrcweir sal_Bool EnhancedCustomShape3d::Transformation2D::IsParallel() const 276cdf0e10cSrcweir { 277cdf0e10cSrcweir return eProjectionMode == com::sun::star::drawing::ProjectionMode_PARALLEL; 278cdf0e10cSrcweir } 279cdf0e10cSrcweir 280cdf0e10cSrcweir SdrObject* EnhancedCustomShape3d::Create3DObject( const SdrObject* pShape2d, const SdrObject* pCustomShape ) 281cdf0e10cSrcweir { 282cdf0e10cSrcweir SdrObject* pRet = NULL; 283cdf0e10cSrcweir SdrModel* pModel = pCustomShape->GetModel(); 284cdf0e10cSrcweir SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)pCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ); 285cdf0e10cSrcweir 286cdf0e10cSrcweir double fMap, *pMap = NULL; 287cdf0e10cSrcweir if ( pModel ) 288cdf0e10cSrcweir { 289cdf0e10cSrcweir fMap = 1.0; 290cdf0e10cSrcweir Fraction aFraction( pModel->GetScaleFraction() ); 291cdf0e10cSrcweir if ( ( aFraction.GetNumerator() ) != 1 || ( aFraction.GetDenominator() != 1 ) ) 292cdf0e10cSrcweir { 293cdf0e10cSrcweir fMap *= aFraction.GetNumerator(); 294cdf0e10cSrcweir fMap /= aFraction.GetDenominator(); 295cdf0e10cSrcweir pMap = &fMap; 296cdf0e10cSrcweir } 297cdf0e10cSrcweir if ( pModel->GetScaleUnit() != MAP_100TH_MM ) 298cdf0e10cSrcweir { 299cdf0e10cSrcweir DBG_ASSERT( pModel->GetScaleUnit() == MAP_TWIP, "EnhancedCustomShape3d::Current MapMode is Unsupported" ); 300cdf0e10cSrcweir fMap *= 1440.0 / 2540.0; 301cdf0e10cSrcweir pMap = &fMap; 302cdf0e10cSrcweir } 303cdf0e10cSrcweir } 304cdf0e10cSrcweir if ( GetBool( rGeometryItem, sExtrusion, sal_False ) ) 305cdf0e10cSrcweir { 306cdf0e10cSrcweir sal_Bool bIsMirroredX = ((SdrObjCustomShape*)pCustomShape)->IsMirroredX(); 307cdf0e10cSrcweir sal_Bool bIsMirroredY = ((SdrObjCustomShape*)pCustomShape)->IsMirroredY(); 308cdf0e10cSrcweir Rectangle aSnapRect( pCustomShape->GetLogicRect() ); 309cdf0e10cSrcweir long nObjectRotation = pCustomShape->GetRotateAngle(); 310cdf0e10cSrcweir if ( nObjectRotation ) 311cdf0e10cSrcweir { 312cdf0e10cSrcweir double a = ( 36000 - nObjectRotation ) * nPi180; 313cdf0e10cSrcweir long dx = aSnapRect.Right() - aSnapRect.Left(); 314cdf0e10cSrcweir long dy = aSnapRect.Bottom()- aSnapRect.Top(); 315cdf0e10cSrcweir Point aP( aSnapRect.TopLeft() ); 316cdf0e10cSrcweir RotatePoint( aP, pCustomShape->GetSnapRect().Center(), sin( a ), cos( a ) ); 317cdf0e10cSrcweir aSnapRect.Left() = aP.X(); 318cdf0e10cSrcweir aSnapRect.Top() = aP.Y(); 319cdf0e10cSrcweir aSnapRect.Right() = aSnapRect.Left() + dx; 320cdf0e10cSrcweir aSnapRect.Bottom() = aSnapRect.Top() + dy; 321cdf0e10cSrcweir } 322cdf0e10cSrcweir Point aCenter( aSnapRect.Center() ); 323cdf0e10cSrcweir 324cdf0e10cSrcweir SfxItemSet aSet( pCustomShape->GetMergedItemSet() ); 325cdf0e10cSrcweir 326cdf0e10cSrcweir //SJ: vertical writing is not required, by removing this item no outliner is created 327cdf0e10cSrcweir aSet.ClearItem( SDRATTR_TEXTDIRECTION ); 328cdf0e10cSrcweir 329cdf0e10cSrcweir // #i105323# For 3D AutoShapes, the shadow attribute has to be applied to each 330cdf0e10cSrcweir // created visualisation helper model shape individually. The shadow itself 331cdf0e10cSrcweir // will then be rendered from the 3D renderer correctly for the whole 3D scene 332cdf0e10cSrcweir // (and thus behind all objects of which the visualisation may be built). So, 333cdf0e10cSrcweir // dio NOT remove it from the ItemSet here. 334cdf0e10cSrcweir // aSet.ClearItem(SDRATTR_SHADOW); 335cdf0e10cSrcweir 336cdf0e10cSrcweir std::vector< E3dCompoundObject* > aPlaceholderObjectList; 337cdf0e10cSrcweir 338cdf0e10cSrcweir double fExtrusionBackward, fExtrusionForward; 339cdf0e10cSrcweir GetExtrusionDepth( rGeometryItem, pMap, fExtrusionBackward, fExtrusionForward ); 340*1c05acecSMatthias Seidel double fDepth = fExtrusionBackward + fExtrusionForward; 341cdf0e10cSrcweir if ( fDepth < 1.0 ) 342cdf0e10cSrcweir fDepth = 1.0; 343cdf0e10cSrcweir 344cdf0e10cSrcweir drawing::ProjectionMode eProjectionMode( drawing::ProjectionMode_PARALLEL ); 345cdf0e10cSrcweir const rtl::OUString sProjectionMode( RTL_CONSTASCII_USTRINGPARAM ( "ProjectionMode" ) ); 346cdf0e10cSrcweir Any* pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, sProjectionMode ); 347cdf0e10cSrcweir if ( pAny ) 348cdf0e10cSrcweir *pAny >>= eProjectionMode; 349cdf0e10cSrcweir ProjectionType eProjectionType( eProjectionMode == drawing::ProjectionMode_PARALLEL ? PR_PARALLEL : PR_PERSPECTIVE ); 350cdf0e10cSrcweir 351cdf0e10cSrcweir // pShape2d Umwandeln in Szene mit 3D Objekt 352cdf0e10cSrcweir E3dDefaultAttributes a3DDefaultAttr; 353cdf0e10cSrcweir a3DDefaultAttr.SetDefaultLatheCharacterMode( sal_True ); 354cdf0e10cSrcweir a3DDefaultAttr.SetDefaultExtrudeCharacterMode( sal_True ); 355cdf0e10cSrcweir 356cdf0e10cSrcweir E3dScene* pScene = new E3dPolyScene( a3DDefaultAttr ); 357cdf0e10cSrcweir 358cdf0e10cSrcweir sal_Bool bSceneHasObjects ( sal_False ); 359cdf0e10cSrcweir sal_Bool bUseTwoFillStyles( sal_False ); 360cdf0e10cSrcweir 361cdf0e10cSrcweir drawing::ShadeMode eShadeMode( GetShadeMode( rGeometryItem, drawing::ShadeMode_FLAT ) ); 362cdf0e10cSrcweir const rtl::OUString sExtrusionColor( RTL_CONSTASCII_USTRINGPARAM ( "Color" ) ); 363cdf0e10cSrcweir sal_Bool bUseExtrusionColor = GetBool( rGeometryItem, sExtrusionColor, sal_False ); 364cdf0e10cSrcweir 365cdf0e10cSrcweir XFillStyle eFillStyle( ITEMVALUE( aSet, XATTR_FILLSTYLE, XFillStyleItem ) ); 366cdf0e10cSrcweir pScene->GetProperties().SetObjectItem( Svx3DShadeModeItem( 0 ) ); 367cdf0e10cSrcweir aSet.Put( Svx3DPercentDiagonalItem( 0 ) ); 368cdf0e10cSrcweir aSet.Put( Svx3DTextureModeItem( 1 ) ); 369cdf0e10cSrcweir aSet.Put( Svx3DNormalsKindItem( 1 ) ); 370cdf0e10cSrcweir 371cdf0e10cSrcweir if ( eShadeMode == drawing::ShadeMode_DRAFT ) 372cdf0e10cSrcweir { 373cdf0e10cSrcweir aSet.Put( XLineStyleItem( XLINE_SOLID ) ); 374cdf0e10cSrcweir aSet.Put( XFillStyleItem ( XFILL_NONE ) ); 375cdf0e10cSrcweir aSet.Put( Svx3DDoubleSidedItem( sal_True ) ); 376cdf0e10cSrcweir } 377cdf0e10cSrcweir else 378cdf0e10cSrcweir { 379cdf0e10cSrcweir aSet.Put( XLineStyleItem( XLINE_NONE ) ); 380cdf0e10cSrcweir if ( eFillStyle == XFILL_NONE ) 381cdf0e10cSrcweir aSet.Put( XFillStyleItem( XFILL_SOLID ) ); 382cdf0e10cSrcweir else if ( ( eFillStyle == XFILL_BITMAP ) || ( eFillStyle == XFILL_GRADIENT ) || bUseExtrusionColor ) 383cdf0e10cSrcweir bUseTwoFillStyles = sal_True; 384cdf0e10cSrcweir 385cdf0e10cSrcweir // #116336# 386cdf0e10cSrcweir // If shapes are mirrored once (mirroring two times correct geometry again) 387cdf0e10cSrcweir // double-sided at the object and two-sided-lighting at the scene need to be set. 388ae7bc73aSArmin Le Grand // 389ae7bc73aSArmin Le Grand // #122777# Also use double sided for two fill styles since there several 3d objects get 390ae7bc73aSArmin Le Grand // created with a depth of 0; one of them is the backside which needs double-sided to 391ae7bc73aSArmin Le Grand // get visible 392ae7bc73aSArmin Le Grand if(bUseTwoFillStyles || (bIsMirroredX && !bIsMirroredY) || (!bIsMirroredX && bIsMirroredY)) 393cdf0e10cSrcweir { 394cdf0e10cSrcweir aSet.Put( Svx3DDoubleSidedItem( sal_True ) ); 395cdf0e10cSrcweir pScene->GetProperties().SetObjectItem( Svx3DTwoSidedLightingItem( sal_True ) ); 396cdf0e10cSrcweir } 397cdf0e10cSrcweir } 398cdf0e10cSrcweir 399cdf0e10cSrcweir Rectangle aBoundRect2d; 400d1d225beSArmin Le Grand SdrObjListIter aIter( *pShape2d, IM_DEEPNOGROUPS ); 401d1d225beSArmin Le Grand const bool bMultipleSubObjects(aIter.Count() > 1); 402d1d225beSArmin Le Grand 403cdf0e10cSrcweir while( aIter.IsMore() ) 404cdf0e10cSrcweir { 405cdf0e10cSrcweir const SdrObject* pNext = aIter.Next(); 406cdf0e10cSrcweir sal_Bool bIsPlaceholderObject = (((XFillStyleItem&)pNext->GetMergedItem( XATTR_FILLSTYLE )).GetValue() == XFILL_NONE ) 407cdf0e10cSrcweir && (((XLineStyleItem&)pNext->GetMergedItem( XATTR_LINESTYLE )).GetValue() == XLINE_NONE ); 408cdf0e10cSrcweir basegfx::B2DPolyPolygon aPolyPoly; 4098899a091SArmin Le Grand SfxItemSet aLocalSet(aSet); 4108899a091SArmin Le Grand XFillStyle aLocalFillStyle(eFillStyle); 411cdf0e10cSrcweir 412cdf0e10cSrcweir if ( pNext->ISA( SdrPathObj ) ) 413cdf0e10cSrcweir { 4148899a091SArmin Le Grand const SfxItemSet& rSet = pNext->GetMergedItemSet(); 415d1d225beSArmin Le Grand bool bNeedToConvertToContour(false); 416d1d225beSArmin Le Grand 417d1d225beSArmin Le Grand // do conversion only for single line objects; for all others a fill and a 418d1d225beSArmin Le Grand // line object get created. When we have fill, we want no line. That line has 419d1d225beSArmin Le Grand // always been there, but since it was never converted to contour, it kept 420d1d225beSArmin Le Grand // invisible (all this 'hidden' logic should be migrated to primitives). 421d1d225beSArmin Le Grand if(!bMultipleSubObjects) 422d1d225beSArmin Le Grand { 423d1d225beSArmin Le Grand const XFillStyle eStyle(((XFillStyleItem&)(rSet.Get(XATTR_FILLSTYLE))).GetValue()); 424d1d225beSArmin Le Grand 425d1d225beSArmin Le Grand if(XFILL_NONE == eStyle) 426d1d225beSArmin Le Grand { 4278899a091SArmin Le Grand const drawinglayer::attribute::SdrLineAttribute aLine( 4288899a091SArmin Le Grand drawinglayer::primitive2d::createNewSdrLineAttribute(rSet)); 429d1d225beSArmin Le Grand 430d1d225beSArmin Le Grand bNeedToConvertToContour = (0.0 < aLine.getWidth() || 0.0 != aLine.getFullDotDashLen()); 431cdf0e10cSrcweir 4328899a091SArmin Le Grand if(!bNeedToConvertToContour && !aLine.isDefault()) 433cdf0e10cSrcweir { 4348899a091SArmin Le Grand const drawinglayer::attribute::SdrLineStartEndAttribute aLineStartEnd( 4358899a091SArmin Le Grand drawinglayer::primitive2d::createNewSdrLineStartEndAttribute(rSet, aLine.getWidth())); 4368899a091SArmin Le Grand 4378899a091SArmin Le Grand if((aLineStartEnd.getStartWidth() && aLineStartEnd.isStartActive()) 4388899a091SArmin Le Grand || (aLineStartEnd.getEndWidth() && aLineStartEnd.isEndActive())) 4398899a091SArmin Le Grand { 4408899a091SArmin Le Grand bNeedToConvertToContour = true; 4418899a091SArmin Le Grand } 4428899a091SArmin Le Grand } 443d1d225beSArmin Le Grand } 444d1d225beSArmin Le Grand } 4458899a091SArmin Le Grand 4468899a091SArmin Le Grand if(bNeedToConvertToContour) 4478899a091SArmin Le Grand { 4488899a091SArmin Le Grand SdrObject* pNewObj = pNext->ConvertToContourObj(const_cast< SdrObject* >(pNext)); 4498899a091SArmin Le Grand SdrPathObj* pNewPathObj = dynamic_cast< SdrPathObj* >(pNewObj); 4508899a091SArmin Le Grand 4518899a091SArmin Le Grand if(pNewPathObj) 4528899a091SArmin Le Grand { 4538899a091SArmin Le Grand aPolyPoly = pNewPathObj->GetPathPoly(); 4548899a091SArmin Le Grand 4558899a091SArmin Le Grand if(aPolyPoly.isClosed()) 4568899a091SArmin Le Grand { 4578899a091SArmin Le Grand // correct item properties from line to fill style 458d1d225beSArmin Le Grand if(eShadeMode == drawing::ShadeMode_DRAFT) 459d1d225beSArmin Le Grand { 460d1d225beSArmin Le Grand // for draft, create wireframe with fixed line width 461d1d225beSArmin Le Grand aLocalSet.Put(XLineStyleItem(XLINE_SOLID)); 462d1d225beSArmin Le Grand aLocalSet.Put(XLineWidthItem(40)); 463d1d225beSArmin Le Grand aLocalFillStyle = XFILL_NONE; 464d1d225beSArmin Le Grand } 465d1d225beSArmin Le Grand else 466d1d225beSArmin Le Grand { 467d1d225beSArmin Le Grand // switch from line to fill, copy line attr to fill attr (color, transparence) 4688899a091SArmin Le Grand aLocalSet.Put(XLineWidthItem(0)); 4698899a091SArmin Le Grand aLocalSet.Put(XLineStyleItem(XLINE_NONE)); 4708899a091SArmin Le Grand aLocalSet.Put(XFillColorItem(XubString(), ((const XLineColorItem&)(aLocalSet.Get(XATTR_LINECOLOR))).GetColorValue())); 4718899a091SArmin Le Grand aLocalSet.Put(XFillStyleItem(XFILL_SOLID)); 4728899a091SArmin Le Grand aLocalSet.Put(XFillTransparenceItem(((const XLineTransparenceItem&)(aLocalSet.Get(XATTR_LINETRANSPARENCE))).GetValue())); 4738899a091SArmin Le Grand aLocalFillStyle = XFILL_SOLID; 4748899a091SArmin Le Grand } 475d1d225beSArmin Le Grand } 4768899a091SArmin Le Grand else 4778899a091SArmin Le Grand { 4788899a091SArmin Le Grand // correct item properties to hairlines 4798899a091SArmin Le Grand aLocalSet.Put(XLineWidthItem(0)); 4808899a091SArmin Le Grand aLocalSet.Put(XLineStyleItem(XLINE_SOLID)); 4818899a091SArmin Le Grand } 4828899a091SArmin Le Grand } 4838899a091SArmin Le Grand 4848899a091SArmin Le Grand SdrObject::Free(pNewObj); 4858899a091SArmin Le Grand } 4868899a091SArmin Le Grand else 4878899a091SArmin Le Grand { 4888899a091SArmin Le Grand aPolyPoly = ((SdrPathObj*)pNext)->GetPathPoly(); 489cdf0e10cSrcweir } 490cdf0e10cSrcweir } 491cdf0e10cSrcweir else 492cdf0e10cSrcweir { 493cdf0e10cSrcweir SdrObject* pNewObj = pNext->ConvertToPolyObj( sal_False, sal_False ); 494cdf0e10cSrcweir SdrPathObj* pPath = PTR_CAST( SdrPathObj, pNewObj ); 495cdf0e10cSrcweir if ( pPath ) 496cdf0e10cSrcweir aPolyPoly = pPath->GetPathPoly(); 497cdf0e10cSrcweir SdrObject::Free( pNewObj ); 498cdf0e10cSrcweir } 499cdf0e10cSrcweir 500cdf0e10cSrcweir if( aPolyPoly.count() ) 501cdf0e10cSrcweir { 5028899a091SArmin Le Grand if(aPolyPoly.areControlPointsUsed()) 5038899a091SArmin Le Grand { 5048899a091SArmin Le Grand aPolyPoly = basegfx::tools::adaptiveSubdivideByAngle(aPolyPoly); 5058899a091SArmin Le Grand } 5068899a091SArmin Le Grand 507cdf0e10cSrcweir const basegfx::B2DRange aTempRange(basegfx::tools::getRange(aPolyPoly)); 508cdf0e10cSrcweir const Rectangle aBoundRect(basegfx::fround(aTempRange.getMinX()), basegfx::fround(aTempRange.getMinY()), basegfx::fround(aTempRange.getMaxX()), basegfx::fround(aTempRange.getMaxY())); 509cdf0e10cSrcweir aBoundRect2d.Union( aBoundRect ); 510cdf0e10cSrcweir 511ae7bc73aSArmin Le Grand // #122777# depth 0 is okay for planes when using double-sided 512ae7bc73aSArmin Le Grand E3dCompoundObject* p3DObj = new E3dExtrudeObj( a3DDefaultAttr, aPolyPoly, bUseTwoFillStyles ? 0 : fDepth ); 513ae7bc73aSArmin Le Grand 514cdf0e10cSrcweir p3DObj->NbcSetLayer( pShape2d->GetLayer() ); 5158899a091SArmin Le Grand p3DObj->SetMergedItemSet( aLocalSet ); 516cdf0e10cSrcweir if ( bIsPlaceholderObject ) 517cdf0e10cSrcweir aPlaceholderObjectList.push_back( p3DObj ); 518cdf0e10cSrcweir else if ( bUseTwoFillStyles ) 519cdf0e10cSrcweir { 52070d3707aSArmin Le Grand BitmapEx aFillBmp; 521cdf0e10cSrcweir sal_Bool bFillBmpTile = ((XFillBmpTileItem&)p3DObj->GetMergedItem( XATTR_FILLBMP_TILE )).GetValue(); 522cdf0e10cSrcweir if ( bFillBmpTile ) 523cdf0e10cSrcweir { 524cdf0e10cSrcweir const XFillBitmapItem& rBmpItm = (XFillBitmapItem&)p3DObj->GetMergedItem(XATTR_FILLBITMAP); 52570d3707aSArmin Le Grand aFillBmp = rBmpItm.GetGraphicObject().GetGraphic().GetBitmapEx(); 526ae7bc73aSArmin Le Grand 527ae7bc73aSArmin Le Grand // #122777# old adaption of FillStyle bitmap size to 5-times the original size; this is not needed 528ae7bc73aSArmin Le Grand // anymore and was used in old times to male the fill look better when converting to 3D. Removed 529ae7bc73aSArmin Le Grand // from regular 3D objects for some time, also needs to be removed from CustomShapes 530ae7bc73aSArmin Le Grand // 531ae7bc73aSArmin Le Grand //Size aLogicalSize = aFillBmp.GetPrefSize(); 532ae7bc73aSArmin Le Grand //if ( aFillBmp.GetPrefMapMode() == MAP_PIXEL ) 533ae7bc73aSArmin Le Grand // aLogicalSize = Application::GetDefaultDevice()->PixelToLogic( aLogicalSize, MAP_100TH_MM ); 534ae7bc73aSArmin Le Grand //else 535ae7bc73aSArmin Le Grand // aLogicalSize = OutputDevice::LogicToLogic( aLogicalSize, aFillBmp.GetPrefMapMode(), MAP_100TH_MM ); 536ae7bc73aSArmin Le Grand //aLogicalSize.Width() *= 5; ;// :-( nice scaling, look at engine3d/obj3d.cxx 537ae7bc73aSArmin Le Grand //aLogicalSize.Height() *= 5; 538ae7bc73aSArmin Le Grand //aFillBmp.SetPrefSize( aLogicalSize ); 539ae7bc73aSArmin Le Grand //aFillBmp.SetPrefMapMode( MAP_100TH_MM ); 540ae7bc73aSArmin Le Grand //p3DObj->SetMergedItem(XFillBitmapItem(String(), Graphic(aFillBmp))); 541cdf0e10cSrcweir } 542cdf0e10cSrcweir else 543cdf0e10cSrcweir { 544cdf0e10cSrcweir if ( aSnapRect != aBoundRect ) 545cdf0e10cSrcweir { 546cdf0e10cSrcweir const XFillBitmapItem& rBmpItm = (XFillBitmapItem&)p3DObj->GetMergedItem(XATTR_FILLBITMAP); 54770d3707aSArmin Le Grand aFillBmp = rBmpItm.GetGraphicObject().GetGraphic().GetBitmapEx(); 548cdf0e10cSrcweir Size aBmpSize( aFillBmp.GetSizePixel() ); 549cdf0e10cSrcweir double fXScale = (double)aBoundRect.GetWidth() / (double)aSnapRect.GetWidth(); 550cdf0e10cSrcweir double fYScale = (double)aBoundRect.GetHeight() / (double)aSnapRect.GetHeight(); 551cdf0e10cSrcweir 552cdf0e10cSrcweir Point aPt( (sal_Int32)( (double)( aBoundRect.Left() - aSnapRect.Left() )* (double)aBmpSize.Width() / (double)aSnapRect.GetWidth() ), 553cdf0e10cSrcweir (sal_Int32)( (double)( aBoundRect.Top() - aSnapRect.Top() ) * (double)aBmpSize.Height() / (double)aSnapRect.GetHeight() ) ); 554cdf0e10cSrcweir Size aSize( (sal_Int32)( aBmpSize.Width() * fXScale ), 555cdf0e10cSrcweir (sal_Int32)( aBmpSize.Height() * fYScale ) ); 556cdf0e10cSrcweir Rectangle aCropRect( aPt, aSize ); 557cdf0e10cSrcweir aFillBmp.Crop( aCropRect ); 55870d3707aSArmin Le Grand p3DObj->SetMergedItem(XFillBitmapItem(String(), Graphic(aFillBmp))); 559cdf0e10cSrcweir } 560cdf0e10cSrcweir } 561cdf0e10cSrcweir pScene->Insert3DObj( p3DObj ); 562cdf0e10cSrcweir p3DObj = new E3dExtrudeObj( a3DDefaultAttr, aPolyPoly, fDepth ); 563cdf0e10cSrcweir p3DObj->NbcSetLayer( pShape2d->GetLayer() ); 5648899a091SArmin Le Grand p3DObj->SetMergedItemSet( aLocalSet ); 565cdf0e10cSrcweir if ( bUseExtrusionColor ) 566cdf0e10cSrcweir p3DObj->SetMergedItem( XFillColorItem( String(), ((XSecondaryFillColorItem&)pCustomShape->GetMergedItem( XATTR_SECONDARYFILLCOLOR )).GetColorValue() ) ); 567cdf0e10cSrcweir p3DObj->SetMergedItem( XFillStyleItem( XFILL_SOLID ) ); 568cdf0e10cSrcweir p3DObj->SetMergedItem( Svx3DCloseFrontItem( sal_False ) ); 569cdf0e10cSrcweir p3DObj->SetMergedItem( Svx3DCloseBackItem( sal_False ) ); 570cdf0e10cSrcweir pScene->Insert3DObj( p3DObj ); 571ae7bc73aSArmin Le Grand 572ae7bc73aSArmin Le Grand // #122777# depth 0 is okay for planes when using double-sided 573ae7bc73aSArmin Le Grand p3DObj = new E3dExtrudeObj( a3DDefaultAttr, aPolyPoly, 0 ); 574ae7bc73aSArmin Le Grand 575cdf0e10cSrcweir p3DObj->NbcSetLayer( pShape2d->GetLayer() ); 5768899a091SArmin Le Grand p3DObj->SetMergedItemSet( aLocalSet ); 577cdf0e10cSrcweir 578cdf0e10cSrcweir basegfx::B3DHomMatrix aFrontTransform( p3DObj->GetTransform() ); 579cdf0e10cSrcweir aFrontTransform.translate( 0.0, 0.0, fDepth ); 580cdf0e10cSrcweir p3DObj->NbcSetTransform( aFrontTransform ); 581cdf0e10cSrcweir 5828899a091SArmin Le Grand if ( ( aLocalFillStyle == XFILL_BITMAP ) && !aFillBmp.IsEmpty() ) 58370d3707aSArmin Le Grand { 58470d3707aSArmin Le Grand p3DObj->SetMergedItem(XFillBitmapItem(String(), Graphic(aFillBmp))); 58570d3707aSArmin Le Grand } 586cdf0e10cSrcweir } 5878899a091SArmin Le Grand else if ( aLocalFillStyle == XFILL_NONE ) 588cdf0e10cSrcweir { 589cdf0e10cSrcweir XLineColorItem& rLineColor = (XLineColorItem&)p3DObj->GetMergedItem( XATTR_LINECOLOR ); 590cdf0e10cSrcweir p3DObj->SetMergedItem( XFillColorItem( String(), rLineColor.GetColorValue() ) ); 591cdf0e10cSrcweir p3DObj->SetMergedItem( Svx3DDoubleSidedItem( sal_True ) ); 592cdf0e10cSrcweir p3DObj->SetMergedItem( Svx3DCloseFrontItem( sal_False ) ); 593cdf0e10cSrcweir p3DObj->SetMergedItem( Svx3DCloseBackItem( sal_False ) ); 594cdf0e10cSrcweir } 595cdf0e10cSrcweir pScene->Insert3DObj( p3DObj ); 596cdf0e10cSrcweir bSceneHasObjects = sal_True; 597cdf0e10cSrcweir } 598cdf0e10cSrcweir } 599cdf0e10cSrcweir 600cdf0e10cSrcweir if ( bSceneHasObjects ) // is the SdrObject properly converted 601cdf0e10cSrcweir { 602cdf0e10cSrcweir // then we can change the return value 603cdf0e10cSrcweir pRet = pScene; 604cdf0e10cSrcweir 605cdf0e10cSrcweir // Kameraeinstellungen, Perspektive ... 606cdf0e10cSrcweir Camera3D& rCamera = (Camera3D&)pScene->GetCamera(); 607cdf0e10cSrcweir const basegfx::B3DRange& rVolume = pScene->GetBoundVolume(); 608cdf0e10cSrcweir pScene->NbcSetSnapRect( aSnapRect ); 609cdf0e10cSrcweir 610cdf0e10cSrcweir // InitScene replacement 611cdf0e10cSrcweir double fW = rVolume.getWidth(); 612cdf0e10cSrcweir double fH = rVolume.getHeight(); 613cdf0e10cSrcweir 614cdf0e10cSrcweir rCamera.SetAutoAdjustProjection( sal_False ); 615cdf0e10cSrcweir rCamera.SetViewWindow( -fW / 2, - fH / 2, fW, fH); 616cdf0e10cSrcweir basegfx::B3DPoint aLookAt( 0.0, 0.0, 0.0 ); 617cdf0e10cSrcweir basegfx::B3DPoint aCamPos( 0.0, 0.0, 100.0 ); 618cdf0e10cSrcweir rCamera.SetDefaults( basegfx::B3DPoint( 0.0, 0.0, 100.0 ), aLookAt, 100.0 ); 619cdf0e10cSrcweir rCamera.SetPosAndLookAt( aCamPos, aLookAt ); 620cdf0e10cSrcweir rCamera.SetFocalLength( 1.0 ); 621cdf0e10cSrcweir rCamera.SetProjection( eProjectionType ); 622cdf0e10cSrcweir pScene->SetCamera( rCamera ); 623cdf0e10cSrcweir pScene->SetRectsDirty(); 624cdf0e10cSrcweir 625cdf0e10cSrcweir double fOriginX, fOriginY; 626cdf0e10cSrcweir GetOrigin( rGeometryItem, fOriginX, fOriginY ); 627cdf0e10cSrcweir fOriginX = fOriginX * aSnapRect.GetWidth(); 628cdf0e10cSrcweir fOriginY = fOriginY * aSnapRect.GetHeight(); 629cdf0e10cSrcweir 630cdf0e10cSrcweir basegfx::B3DHomMatrix aNewTransform( pScene->GetTransform() ); 631cdf0e10cSrcweir aNewTransform.translate( -aCenter.X(), aCenter.Y(), -pScene->GetBoundVolume().getDepth() ); 632cdf0e10cSrcweir 633cdf0e10cSrcweir double fXRotate, fYRotate; 634cdf0e10cSrcweir GetRotateAngle( rGeometryItem, fXRotate, fYRotate ); 635cdf0e10cSrcweir double fZRotate = ((SdrObjCustomShape*)pCustomShape)->GetObjectRotation() * F_PI180; 636cdf0e10cSrcweir if ( fZRotate != 0.0 ) 637cdf0e10cSrcweir aNewTransform.rotate( 0.0, 0.0, fZRotate ); 638cdf0e10cSrcweir if ( bIsMirroredX ) 639cdf0e10cSrcweir aNewTransform.scale( -1.0, 1, 1 ); 640cdf0e10cSrcweir if ( bIsMirroredY ) 641cdf0e10cSrcweir aNewTransform.scale( 1, -1.0, 1 ); 642cdf0e10cSrcweir if( fYRotate != 0.0 ) 643cdf0e10cSrcweir aNewTransform.rotate( 0.0, -fYRotate, 0.0 ); 644cdf0e10cSrcweir if( fXRotate != 0.0 ) 645cdf0e10cSrcweir aNewTransform.rotate( -fXRotate, 0.0, 0.0 ); 646cdf0e10cSrcweir if ( eProjectionType == PR_PARALLEL ) 647cdf0e10cSrcweir { 648cdf0e10cSrcweir double fSkew, fAlpha; 649cdf0e10cSrcweir GetSkew( rGeometryItem, fSkew, fAlpha ); 650cdf0e10cSrcweir if ( fSkew != 0.0 ) 651cdf0e10cSrcweir { 652cdf0e10cSrcweir double fInvTanBeta( fSkew / 100.0 ); 653cdf0e10cSrcweir if(fInvTanBeta) 654cdf0e10cSrcweir { 655cdf0e10cSrcweir aNewTransform.shearXY( 656cdf0e10cSrcweir fInvTanBeta * cos(fAlpha), 657cdf0e10cSrcweir fInvTanBeta * sin(fAlpha)); 658cdf0e10cSrcweir } 659cdf0e10cSrcweir } 660cdf0e10cSrcweir basegfx::B3DPoint _aLookAt( 0.0, 0.0, 0.0 ); 661cdf0e10cSrcweir basegfx::B3DPoint _aNewCamPos( 0.0, 0.0, 25000.0 ); 662cdf0e10cSrcweir rCamera.SetPosAndLookAt( _aNewCamPos, _aLookAt ); 663cdf0e10cSrcweir pScene->SetCamera( rCamera ); 664cdf0e10cSrcweir } 665cdf0e10cSrcweir else 666cdf0e10cSrcweir { 667cdf0e10cSrcweir aNewTransform.translate( -fOriginX, fOriginY, 0.0 ); 668cdf0e10cSrcweir // now set correct camera position 669cdf0e10cSrcweir const rtl::OUString sViewPoint( RTL_CONSTASCII_USTRINGPARAM ( "ViewPoint" ) ); 670cdf0e10cSrcweir drawing::Position3D aViewPointDefault( 3472, -3472, 25000 ); 671cdf0e10cSrcweir drawing::Position3D aViewPoint( GetPosition3D( rGeometryItem, sViewPoint, aViewPointDefault, pMap ) ); 672cdf0e10cSrcweir double fViewPointX = aViewPoint.PositionX; 673cdf0e10cSrcweir double fViewPointY = aViewPoint.PositionY; 674cdf0e10cSrcweir double fViewPointZ = aViewPoint.PositionZ; 675cdf0e10cSrcweir basegfx::B3DPoint _aLookAt( fViewPointX, -fViewPointY, 0.0 ); 676cdf0e10cSrcweir basegfx::B3DPoint aNewCamPos( fViewPointX, -fViewPointY, fViewPointZ ); 677cdf0e10cSrcweir rCamera.SetPosAndLookAt( aNewCamPos, _aLookAt ); 678cdf0e10cSrcweir pScene->SetCamera( rCamera ); 679cdf0e10cSrcweir } 680cdf0e10cSrcweir 681cdf0e10cSrcweir pScene->NbcSetTransform( aNewTransform ); 682cdf0e10cSrcweir 683cdf0e10cSrcweir /////////// 684cdf0e10cSrcweir // light // 685cdf0e10cSrcweir /////////// 686cdf0e10cSrcweir 687cdf0e10cSrcweir const rtl::OUString sBrightness( RTL_CONSTASCII_USTRINGPARAM ( "Brightness" ) ); 688cdf0e10cSrcweir double fAmbientIntensity = GetDouble( rGeometryItem, sBrightness, 22178.0 / 655.36, NULL ) / 100.0; 689cdf0e10cSrcweir 690cdf0e10cSrcweir 691cdf0e10cSrcweir const rtl::OUString sFirstLightDirection( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightDirection" ) ); 692cdf0e10cSrcweir drawing::Direction3D aFirstLightDirectionDefault( 50000, 0, 10000 ); 693cdf0e10cSrcweir drawing::Direction3D aFirstLightDirection( GetDirection3D( rGeometryItem, sFirstLightDirection, aFirstLightDirectionDefault ) ); 694cdf0e10cSrcweir if ( aFirstLightDirection.DirectionZ == 0.0 ) 695cdf0e10cSrcweir aFirstLightDirection.DirectionZ = 1.0; 696cdf0e10cSrcweir 697cdf0e10cSrcweir const rtl::OUString sFirstLightLevel( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightLevel" ) ); 698cdf0e10cSrcweir double fLightIntensity = GetDouble( rGeometryItem, sFirstLightLevel, 43712.0 / 655.36, NULL ) / 100.0; 699cdf0e10cSrcweir 700cdf0e10cSrcweir const rtl::OUString sFirstLightHarsh( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightHarsh" ) ); 701cdf0e10cSrcweir /* sal_Bool bFirstLightHarsh = */ GetBool( rGeometryItem, sFirstLightHarsh, sal_False ); 702cdf0e10cSrcweir 703cdf0e10cSrcweir const rtl::OUString sSecondLightDirection( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightDirection" ) ); 704cdf0e10cSrcweir drawing::Direction3D aSecondLightDirectionDefault( -50000, 0, 10000 ); 705cdf0e10cSrcweir drawing::Direction3D aSecondLightDirection( GetDirection3D( rGeometryItem, sSecondLightDirection, aSecondLightDirectionDefault ) ); 706cdf0e10cSrcweir if ( aSecondLightDirection.DirectionZ == 0.0 ) 707cdf0e10cSrcweir aSecondLightDirection.DirectionZ = -1; 708cdf0e10cSrcweir 709cdf0e10cSrcweir const rtl::OUString sSecondLightLevel( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightLevel" ) ); 710cdf0e10cSrcweir double fLight2Intensity = GetDouble( rGeometryItem, sSecondLightLevel, 43712.0 / 655.36, NULL ) / 100.0; 711cdf0e10cSrcweir 712cdf0e10cSrcweir const rtl::OUString sSecondLightHarsh( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightHarsh" ) ); 713cdf0e10cSrcweir const rtl::OUString sLightFace( RTL_CONSTASCII_USTRINGPARAM ( "LightFace" ) ); 714cdf0e10cSrcweir /* sal_Bool bLight2Harsh = */ GetBool( rGeometryItem, sSecondLightHarsh, sal_False ); 715cdf0e10cSrcweir /* sal_Bool bLightFace = */ GetBool( rGeometryItem, sLightFace, sal_False ); 716cdf0e10cSrcweir 717cdf0e10cSrcweir sal_uInt16 nAmbientColor = (sal_uInt16)( fAmbientIntensity * 255.0 ); 718cdf0e10cSrcweir if ( nAmbientColor > 255 ) 719cdf0e10cSrcweir nAmbientColor = 255; 720cdf0e10cSrcweir Color aGlobalAmbientColor( (sal_uInt8)nAmbientColor, (sal_uInt8)nAmbientColor, (sal_uInt8)nAmbientColor ); 721cdf0e10cSrcweir pScene->GetProperties().SetObjectItem( Svx3DAmbientcolorItem( aGlobalAmbientColor ) ); 722cdf0e10cSrcweir 723cdf0e10cSrcweir sal_uInt8 nSpotLight1 = (sal_uInt8)( fLightIntensity * 255.0 ); 724cdf0e10cSrcweir basegfx::B3DVector aSpotLight1( aFirstLightDirection.DirectionX, - ( aFirstLightDirection.DirectionY ), -( aFirstLightDirection.DirectionZ ) ); 725cdf0e10cSrcweir aSpotLight1.normalize(); 726cdf0e10cSrcweir pScene->GetProperties().SetObjectItem( Svx3DLightOnOff1Item( sal_True ) ); 727cdf0e10cSrcweir Color aAmbientSpot1Color( nSpotLight1, nSpotLight1, nSpotLight1 ); 728cdf0e10cSrcweir pScene->GetProperties().SetObjectItem( Svx3DLightcolor1Item( aAmbientSpot1Color ) ); 729cdf0e10cSrcweir pScene->GetProperties().SetObjectItem( Svx3DLightDirection1Item( aSpotLight1 ) ); 730cdf0e10cSrcweir 731cdf0e10cSrcweir sal_uInt8 nSpotLight2 = (sal_uInt8)( fLight2Intensity * 255.0 ); 732cdf0e10cSrcweir basegfx::B3DVector aSpotLight2( aSecondLightDirection.DirectionX, -aSecondLightDirection.DirectionY, -aSecondLightDirection.DirectionZ ); 733cdf0e10cSrcweir aSpotLight2.normalize(); 734cdf0e10cSrcweir pScene->GetProperties().SetObjectItem( Svx3DLightOnOff2Item( sal_True ) ); 735cdf0e10cSrcweir Color aAmbientSpot2Color( nSpotLight2, nSpotLight2, nSpotLight2 ); 736cdf0e10cSrcweir pScene->GetProperties().SetObjectItem( Svx3DLightcolor2Item( aAmbientSpot2Color ) ); 737cdf0e10cSrcweir pScene->GetProperties().SetObjectItem( Svx3DLightDirection2Item( aSpotLight2 ) ); 738cdf0e10cSrcweir 739cdf0e10cSrcweir sal_uInt8 nSpotLight3 = 70; 740cdf0e10cSrcweir basegfx::B3DVector aSpotLight3( 0.0, 0.0, 1.0 ); 741cdf0e10cSrcweir pScene->GetProperties().SetObjectItem( Svx3DLightOnOff3Item( sal_True ) ); 742cdf0e10cSrcweir Color aAmbientSpot3Color( nSpotLight3, nSpotLight3, nSpotLight3 ); 743cdf0e10cSrcweir pScene->GetProperties().SetObjectItem( Svx3DLightcolor3Item( aAmbientSpot3Color ) ); 744cdf0e10cSrcweir pScene->GetProperties().SetObjectItem( Svx3DLightDirection3Item( aSpotLight3 ) ); 745cdf0e10cSrcweir 746cdf0e10cSrcweir const rtl::OUString sSpecularity( RTL_CONSTASCII_USTRINGPARAM ( "Specularity" ) ); 747cdf0e10cSrcweir const rtl::OUString sDiffusion( RTL_CONSTASCII_USTRINGPARAM ( "Diffusion" ) ); 748cdf0e10cSrcweir const rtl::OUString sShininess( RTL_CONSTASCII_USTRINGPARAM ( "Shininess" ) ); 749cdf0e10cSrcweir const rtl::OUString sMetal( RTL_CONSTASCII_USTRINGPARAM ( "Metal" ) ); 750cdf0e10cSrcweir double fSpecular = GetDouble( rGeometryItem, sSpecularity, 0, NULL ) / 100; 751cdf0e10cSrcweir sal_Bool bMetal = GetBool( rGeometryItem, sMetal, sal_False ); 752cdf0e10cSrcweir 753cdf0e10cSrcweir Color aSpecularCol( 225,225,225 ); 754cdf0e10cSrcweir if ( bMetal ) 755cdf0e10cSrcweir { 756cdf0e10cSrcweir aSpecularCol = Color( 200, 200, 200 ); 757cdf0e10cSrcweir fSpecular += 0.15; 758cdf0e10cSrcweir } 759cdf0e10cSrcweir sal_Int32 nIntensity = (sal_Int32)fSpecular * 100; 760cdf0e10cSrcweir if ( nIntensity > 100 ) 761cdf0e10cSrcweir nIntensity = 100; 762cdf0e10cSrcweir else if ( nIntensity < 0 ) 763cdf0e10cSrcweir nIntensity = 0; 764cdf0e10cSrcweir nIntensity = 100 - nIntensity; 765cdf0e10cSrcweir pScene->GetProperties().SetObjectItem( Svx3DMaterialSpecularItem( aSpecularCol ) ); 766cdf0e10cSrcweir pScene->GetProperties().SetObjectItem( Svx3DMaterialSpecularIntensityItem( (sal_uInt16)nIntensity ) ); 767cdf0e10cSrcweir 768cdf0e10cSrcweir pScene->SetLogicRect( CalculateNewSnapRect( pCustomShape, aSnapRect, aBoundRect2d, pMap ) ); 769cdf0e10cSrcweir 770cdf0e10cSrcweir // removing placeholder objects 771cdf0e10cSrcweir std::vector< E3dCompoundObject* >::iterator aObjectListIter( aPlaceholderObjectList.begin() ); 772cdf0e10cSrcweir while ( aObjectListIter != aPlaceholderObjectList.end() ) 773cdf0e10cSrcweir { 774cdf0e10cSrcweir pScene->Remove3DObj( *aObjectListIter ); 775cdf0e10cSrcweir delete *aObjectListIter++; 776cdf0e10cSrcweir } 777cdf0e10cSrcweir } 778cdf0e10cSrcweir else 779cdf0e10cSrcweir delete pScene; 780cdf0e10cSrcweir } 781cdf0e10cSrcweir return pRet; 782cdf0e10cSrcweir } 783cdf0e10cSrcweir 784cdf0e10cSrcweir Rectangle EnhancedCustomShape3d::CalculateNewSnapRect( const SdrObject* pCustomShape, const Rectangle& rSnapRect, const Rectangle& rBoundRect, const double* pMap ) 785cdf0e10cSrcweir { 786cdf0e10cSrcweir SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)pCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ); 787cdf0e10cSrcweir const Point aCenter( rSnapRect.Center() ); 788cdf0e10cSrcweir double fExtrusionBackward, fExtrusionForward; 789cdf0e10cSrcweir GetExtrusionDepth( rGeometryItem, pMap, fExtrusionBackward, fExtrusionForward ); 790cdf0e10cSrcweir sal_uInt32 i; 791cdf0e10cSrcweir 792cdf0e10cSrcweir // creating initial bound volume ( without rotation. skewing.and camera ) 793cdf0e10cSrcweir basegfx::B3DPolygon aBoundVolume; 794cdf0e10cSrcweir const Polygon aPolygon( rBoundRect ); 795cdf0e10cSrcweir 796cdf0e10cSrcweir for ( i = 0L; i < 4L; i++ ) 797cdf0e10cSrcweir { 798*1c05acecSMatthias Seidel aBoundVolume.append(basegfx::B3DPoint(aPolygon[ (sal_uInt16)i ].X() - aCenter.X(), aPolygon[ (sal_uInt16)i ].Y() - aCenter.Y(), -fExtrusionForward)); 799cdf0e10cSrcweir } 800cdf0e10cSrcweir 801cdf0e10cSrcweir for ( i = 0L; i < 4L; i++ ) 802cdf0e10cSrcweir { 803cdf0e10cSrcweir aBoundVolume.append(basegfx::B3DPoint(aPolygon[ (sal_uInt16)i ].X() - aCenter.X(), aPolygon[ (sal_uInt16)i ].Y() - aCenter.Y(), fExtrusionBackward)); 804cdf0e10cSrcweir } 805cdf0e10cSrcweir 806cdf0e10cSrcweir const rtl::OUString sRotationCenter( RTL_CONSTASCII_USTRINGPARAM ( "RotationCenter" ) ); 807cdf0e10cSrcweir drawing::Direction3D aRotationCenterDefault( 0, 0, 0 ); // default seems to be wrong, a fractional size of shape has to be used!! 808cdf0e10cSrcweir drawing::Direction3D aRotationCenter( GetDirection3D( rGeometryItem, sRotationCenter, aRotationCenterDefault ) ); 809cdf0e10cSrcweir 810cdf0e10cSrcweir // double XCenterInGUnits = rPropSet.GetPropertyValue( DFF_Prop_c3DRotationCenterX, 0 ); 811cdf0e10cSrcweir // double YCenterInGUnits = rPropSet.GetPropertyValue( DFF_Prop_c3DRotationCenterY, 0 ); 812cdf0e10cSrcweir 813cdf0e10cSrcweir // sal_Int32 nRotationXAxisInProz = rPropSet.GetPropertyValue( DFF_Prop_c3DRotationAxisX, 100 ); 814cdf0e10cSrcweir // sal_Int32 nRotationYAxisInProz = rPropSet.GetPropertyValue( DFF_Prop_c3DRotationAxisY, 0 ); 815cdf0e10cSrcweir // sal_Int32 nRotationZAxisInProz = rPropSet.GetPropertyValue( DFF_Prop_c3DRotationAxisZ, 0 ); 816cdf0e10cSrcweir 817cdf0e10cSrcweir 818cdf0e10cSrcweir double fXRotate, fYRotate; 819cdf0e10cSrcweir GetRotateAngle( rGeometryItem, fXRotate, fYRotate ); 820cdf0e10cSrcweir double fZRotate = - ((SdrObjCustomShape*)pCustomShape)->GetObjectRotation() * F_PI180; 821cdf0e10cSrcweir 822cdf0e10cSrcweir // rotating bound volume 823cdf0e10cSrcweir basegfx::B3DHomMatrix aMatrix; 824cdf0e10cSrcweir aMatrix.translate(-aRotationCenter.DirectionX, -aRotationCenter.DirectionY, -aRotationCenter.DirectionZ); 825cdf0e10cSrcweir if ( fZRotate != 0.0 ) 826cdf0e10cSrcweir aMatrix.rotate( 0.0, 0.0, fZRotate ); 827cdf0e10cSrcweir if ( ((SdrObjCustomShape*)pCustomShape)->IsMirroredX() ) 828cdf0e10cSrcweir aMatrix.scale( -1.0, 1, 1 ); 829cdf0e10cSrcweir if ( ((SdrObjCustomShape*)pCustomShape)->IsMirroredY() ) 830cdf0e10cSrcweir aMatrix.scale( 1, -1.0, 1 ); 831cdf0e10cSrcweir if( fYRotate != 0.0 ) 832cdf0e10cSrcweir aMatrix.rotate( 0.0, fYRotate, 0.0 ); 833cdf0e10cSrcweir if( fXRotate != 0.0 ) 834cdf0e10cSrcweir aMatrix.rotate( -fXRotate, 0.0, 0.0 ); 835cdf0e10cSrcweir aMatrix.translate(aRotationCenter.DirectionX, aRotationCenter.DirectionY, aRotationCenter.DirectionZ); 836cdf0e10cSrcweir aBoundVolume.transform(aMatrix); 837cdf0e10cSrcweir 838cdf0e10cSrcweir Transformation2D aTransformation2D( pCustomShape, rSnapRect, pMap ); 839cdf0e10cSrcweir if ( aTransformation2D.IsParallel() ) 840cdf0e10cSrcweir aBoundVolume = aTransformation2D.ApplySkewSettings( aBoundVolume ); 841cdf0e10cSrcweir 842cdf0e10cSrcweir Polygon aTransformed( 8 ); 843cdf0e10cSrcweir for ( i = 0L; i < 8L; i++ ) 844cdf0e10cSrcweir aTransformed[ (sal_uInt16)i ] = aTransformation2D.Transform2D( aBoundVolume.getB3DPoint( i ) ); 845cdf0e10cSrcweir 846cdf0e10cSrcweir return aTransformed.GetBoundRect(); 847cdf0e10cSrcweir } 848