1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_svx.hxx" 26 #include "EnhancedCustomShape3d.hxx" 27 #include <svx/svdetc.hxx> 28 #include <svx/svdmodel.hxx> 29 #include <tools/poly.hxx> 30 #include <svx/svditer.hxx> 31 #include <svx/svdobj.hxx> 32 #include <svx/svdoashp.hxx> 33 #include <svl/poolitem.hxx> 34 #include <svl/itemset.hxx> 35 #include <svx/xfillit0.hxx> 36 #include <svx/xsflclit.hxx> 37 #include <svx/xit.hxx> 38 #include <svx/xbtmpit.hxx> 39 #include <svx/xflclit.hxx> 40 #include <svx/svdopath.hxx> 41 #include <svx/svdogrp.hxx> 42 #include <svx/svdpage.hxx> 43 #include <svx/polysc3d.hxx> 44 #include <svx/svddef.hxx> 45 #include <svx/svx3ditems.hxx> 46 #include <svx/extrud3d.hxx> 47 #include <svx/xflbmtit.hxx> 48 #include <vcl/svapp.hxx> 49 #include <svx/xlnclit.hxx> 50 #include <svx/sdasitm.hxx> 51 #include <com/sun/star/awt/Point.hpp> 52 #include <com/sun/star/drawing/Position3D.hpp> 53 #include <com/sun/star/drawing/Direction3D.hpp> 54 #include <com/sun/star/drawing/ShadeMode.hpp> 55 #include <svx/sdr/properties/properties.hxx> 56 #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp> 57 #include <basegfx/polygon/b2dpolypolygontools.hxx> 58 #include <basegfx/range/b2drange.hxx> 59 60 #define ITEMVALUE(ItemSet,Id,Cast) ((const Cast&)(ItemSet).Get(Id)).GetValue() 61 using namespace com::sun::star; 62 using namespace com::sun::star::uno; 63 64 const rtl::OUString sExtrusion( RTL_CONSTASCII_USTRINGPARAM ( "Extrusion" ) ); 65 66 void GetOrigin( SdrCustomShapeGeometryItem& rItem, double& rOriginX, double& rOriginY ) 67 { 68 ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aOriginParaPair; 69 const rtl::OUString sOrigin( RTL_CONSTASCII_USTRINGPARAM ( "Origin" ) ); 70 Any* pAny = rItem.GetPropertyValueByName( sExtrusion, sOrigin ); 71 if ( ! ( pAny && ( *pAny >>= aOriginParaPair ) && ( aOriginParaPair.First.Value >>= rOriginX ) && ( aOriginParaPair.Second.Value >>= rOriginY ) ) ) 72 { 73 rOriginX = 0.50; 74 rOriginY =-0.50; 75 } 76 } 77 78 void GetRotateAngle( SdrCustomShapeGeometryItem& rItem, double& rAngleX, double& rAngleY ) 79 { 80 ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aRotateAngleParaPair; 81 const rtl::OUString sRotateAngle( RTL_CONSTASCII_USTRINGPARAM ( "RotateAngle" ) ); 82 Any* pAny = rItem.GetPropertyValueByName( sExtrusion, sRotateAngle ); 83 if ( ! ( pAny && ( *pAny >>= aRotateAngleParaPair ) && ( aRotateAngleParaPair.First.Value >>= rAngleX ) && ( aRotateAngleParaPair.Second.Value >>= rAngleY ) ) ) 84 { 85 rAngleX = 0.0; 86 rAngleY = 0.0; 87 } 88 rAngleX *= F_PI180; 89 rAngleY *= F_PI180; 90 } 91 92 void GetSkew( SdrCustomShapeGeometryItem& rItem, double& rSkewAmount, double& rSkewAngle ) 93 { 94 ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aSkewParaPair; 95 const rtl::OUString sSkew( RTL_CONSTASCII_USTRINGPARAM ( "Skew" ) ); 96 Any* pAny = rItem.GetPropertyValueByName( sExtrusion, sSkew ); 97 if ( ! ( pAny && ( *pAny >>= aSkewParaPair ) && ( aSkewParaPair.First.Value >>= rSkewAmount ) && ( aSkewParaPair.Second.Value >>= rSkewAngle ) ) ) 98 { 99 rSkewAmount = 50; 100 rSkewAngle = -135; 101 } 102 rSkewAngle *= F_PI180; 103 } 104 105 void GetExtrusionDepth( SdrCustomShapeGeometryItem& rItem, const double* pMap, double& rBackwardDepth, double& rForwardDepth ) 106 { 107 ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aDepthParaPair; 108 double fDepth = 0, fFraction = 0; 109 const rtl::OUString sDepth( RTL_CONSTASCII_USTRINGPARAM ( "Depth" ) ); 110 Any* pAny = rItem.GetPropertyValueByName( sExtrusion, sDepth ); 111 if ( pAny && ( *pAny >>= aDepthParaPair ) && ( aDepthParaPair.First.Value >>= fDepth ) && ( aDepthParaPair.Second.Value >>= fFraction ) ) 112 { 113 rForwardDepth = fDepth * fFraction; 114 rBackwardDepth = fDepth - rForwardDepth; 115 } 116 else 117 { 118 rBackwardDepth = 1270; 119 rForwardDepth = 0; 120 } 121 if ( pMap ) 122 { 123 double fMap = *pMap; 124 rBackwardDepth *= fMap; 125 rForwardDepth *= fMap; 126 } 127 } 128 129 double GetDouble( SdrCustomShapeGeometryItem& rItem, const rtl::OUString& rPropertyName, double fDefault, const double* pMap ) 130 { 131 double fRetValue = fDefault; 132 Any* pAny = rItem.GetPropertyValueByName( sExtrusion, rPropertyName ); 133 if ( pAny ) 134 *pAny >>= fRetValue; 135 if ( pMap ) 136 fRetValue *= *pMap; 137 return fRetValue; 138 } 139 140 drawing::ShadeMode GetShadeMode( SdrCustomShapeGeometryItem& rItem, const drawing::ShadeMode eDefault ) 141 { 142 drawing::ShadeMode eRet( eDefault ); 143 const rtl::OUString sShadeMode( RTL_CONSTASCII_USTRINGPARAM ( "ShadeMode" ) ); 144 Any* pAny = rItem.GetPropertyValueByName( sExtrusion, sShadeMode ); 145 if ( pAny ) 146 *pAny >>= eRet; 147 return eRet; 148 } 149 150 sal_Int32 GetInt32( SdrCustomShapeGeometryItem& rItem, const rtl::OUString& rPropertyName, const sal_Int32 nDefault ) 151 { 152 sal_Int32 nRetValue = nDefault; 153 Any* pAny = rItem.GetPropertyValueByName( sExtrusion, rPropertyName ); 154 if ( pAny ) 155 *pAny >>= nRetValue; 156 return nRetValue; 157 } 158 159 sal_Bool GetBool( SdrCustomShapeGeometryItem& rItem, const rtl::OUString& rPropertyName, const sal_Bool bDefault ) 160 { 161 sal_Bool bRetValue = bDefault; 162 const Any* pAny = rItem.GetPropertyValueByName( sExtrusion, rPropertyName ); 163 if ( pAny ) 164 *pAny >>= bRetValue; 165 return bRetValue; 166 } 167 168 awt::Point GetPoint( SdrCustomShapeGeometryItem& rItem, const rtl::OUString& rPropertyName, const awt::Point& rDefault ) 169 { 170 awt::Point aRetValue( rDefault ); 171 const Any* pAny = rItem.GetPropertyValueByName( sExtrusion, rPropertyName ); 172 if ( pAny ) 173 *pAny >>= aRetValue; 174 return aRetValue; 175 } 176 177 drawing::Position3D GetPosition3D( SdrCustomShapeGeometryItem& rItem, const rtl::OUString& rPropertyName, 178 const drawing::Position3D& rDefault, const double* pMap ) 179 { 180 drawing::Position3D aRetValue( rDefault ); 181 const Any* pAny = rItem.GetPropertyValueByName( sExtrusion, rPropertyName ); 182 if ( pAny ) 183 *pAny >>= aRetValue; 184 if ( pMap ) 185 { 186 aRetValue.PositionX *= *pMap; 187 aRetValue.PositionY *= *pMap; 188 aRetValue.PositionZ *= *pMap; 189 } 190 return aRetValue; 191 } 192 193 drawing::Direction3D GetDirection3D( SdrCustomShapeGeometryItem& rItem, const rtl::OUString& rPropertyName, const drawing::Direction3D& rDefault ) 194 { 195 drawing::Direction3D aRetValue( rDefault ); 196 const Any* pAny = rItem.GetPropertyValueByName( sExtrusion, rPropertyName ); 197 if ( pAny ) 198 *pAny >>= aRetValue; 199 return aRetValue; 200 } 201 202 EnhancedCustomShape3d::Transformation2D::Transformation2D( const SdrObject* pCustomShape, const Rectangle& /*rBoundRect*/, const double *pM ) 203 : aCenter( pCustomShape->GetSnapRect().Center() ) 204 , eProjectionMode( drawing::ProjectionMode_PARALLEL ) 205 , pMap( pM ) 206 { 207 SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)pCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ); 208 const rtl::OUString sProjectionMode( RTL_CONSTASCII_USTRINGPARAM ( "ProjectionMode" ) ); 209 Any* pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, sProjectionMode ); 210 if ( pAny ) 211 *pAny >>= eProjectionMode; 212 213 if ( eProjectionMode == drawing::ProjectionMode_PARALLEL ) 214 GetSkew( rGeometryItem, fSkew, fSkewAngle ); 215 else 216 { 217 fZScreen = 0.0; 218 GetOrigin( rGeometryItem, fOriginX, fOriginY ); 219 fOriginX = fOriginX * pCustomShape->GetLogicRect().GetWidth(); 220 fOriginY = fOriginY * pCustomShape->GetLogicRect().GetHeight(); 221 222 const rtl::OUString sViewPoint( RTL_CONSTASCII_USTRINGPARAM ( "ViewPoint" ) ); 223 drawing::Position3D aViewPointDefault( 3472, -3472, 25000 ); 224 drawing::Position3D aViewPoint( GetPosition3D( rGeometryItem, sViewPoint, aViewPointDefault, pMap ) ); 225 fViewPoint.setX(aViewPoint.PositionX); 226 fViewPoint.setY(aViewPoint.PositionY); 227 fViewPoint.setZ(-aViewPoint.PositionZ); 228 } 229 } 230 231 basegfx::B3DPolygon EnhancedCustomShape3d::Transformation2D::ApplySkewSettings( const basegfx::B3DPolygon& rPoly3D ) const 232 { 233 basegfx::B3DPolygon aRetval; 234 235 sal_uInt32 j; 236 for ( j = 0L; j < rPoly3D.count(); j++ ) 237 { 238 const basegfx::B3DPoint aPoint(rPoly3D.getB3DPoint(j)); 239 double fDepth(-( aPoint.getZ() * fSkew ) / 100.0); 240 aRetval.append(basegfx::B3DPoint( 241 aPoint.getX() + (fDepth * cos( fSkewAngle )), 242 aPoint.getY() - (fDepth * sin( fSkewAngle )), 243 aPoint.getZ())); 244 } 245 246 return aRetval; 247 } 248 249 Point EnhancedCustomShape3d::Transformation2D::Transform2D( const basegfx::B3DPoint& rPoint3D ) const 250 { 251 Point aPoint2D; 252 if ( eProjectionMode == drawing::ProjectionMode_PARALLEL ) 253 { 254 aPoint2D.X() = (sal_Int32)rPoint3D.getX(); 255 aPoint2D.Y() = (sal_Int32)rPoint3D.getY(); 256 } 257 else 258 { 259 double fX = rPoint3D.getX() - fOriginX; 260 double fY = rPoint3D.getY() - fOriginY; 261 double f = ( fZScreen - fViewPoint.getZ() ) / ( rPoint3D.getZ() - fViewPoint.getZ() ); 262 aPoint2D.X() = (sal_Int32)(( fX - fViewPoint.getX() ) * f + fViewPoint.getX() + fOriginX ); 263 aPoint2D.Y() = (sal_Int32)(( fY - fViewPoint.getY() ) * f + fViewPoint.getY() + fOriginY ); 264 } 265 aPoint2D.Move( aCenter.X(), aCenter.Y() ); 266 return aPoint2D; 267 } 268 269 sal_Bool EnhancedCustomShape3d::Transformation2D::IsParallel() const 270 { 271 return eProjectionMode == com::sun::star::drawing::ProjectionMode_PARALLEL; 272 } 273 274 SdrObject* EnhancedCustomShape3d::Create3DObject( const SdrObject* pShape2d, const SdrObject* pCustomShape ) 275 { 276 SdrObject* pRet = NULL; 277 SdrModel* pModel = pCustomShape->GetModel(); 278 SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)pCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ); 279 280 double fMap, *pMap = NULL; 281 if ( pModel ) 282 { 283 fMap = 1.0; 284 Fraction aFraction( pModel->GetScaleFraction() ); 285 if ( ( aFraction.GetNumerator() ) != 1 || ( aFraction.GetDenominator() != 1 ) ) 286 { 287 fMap *= aFraction.GetNumerator(); 288 fMap /= aFraction.GetDenominator(); 289 pMap = &fMap; 290 } 291 if ( pModel->GetScaleUnit() != MAP_100TH_MM ) 292 { 293 DBG_ASSERT( pModel->GetScaleUnit() == MAP_TWIP, "EnhancedCustomShape3d::Current MapMode is Unsupported" ); 294 fMap *= 1440.0 / 2540.0; 295 pMap = &fMap; 296 } 297 } 298 if ( GetBool( rGeometryItem, sExtrusion, sal_False ) ) 299 { 300 sal_Bool bIsMirroredX = ((SdrObjCustomShape*)pCustomShape)->IsMirroredX(); 301 sal_Bool bIsMirroredY = ((SdrObjCustomShape*)pCustomShape)->IsMirroredY(); 302 Rectangle aSnapRect( pCustomShape->GetLogicRect() ); 303 long nObjectRotation = pCustomShape->GetRotateAngle(); 304 if ( nObjectRotation ) 305 { 306 double a = ( 36000 - nObjectRotation ) * nPi180; 307 long dx = aSnapRect.Right() - aSnapRect.Left(); 308 long dy = aSnapRect.Bottom()- aSnapRect.Top(); 309 Point aP( aSnapRect.TopLeft() ); 310 RotatePoint( aP, pCustomShape->GetSnapRect().Center(), sin( a ), cos( a ) ); 311 aSnapRect.Left() = aP.X(); 312 aSnapRect.Top() = aP.Y(); 313 aSnapRect.Right() = aSnapRect.Left() + dx; 314 aSnapRect.Bottom() = aSnapRect.Top() + dy; 315 } 316 Point aCenter( aSnapRect.Center() ); 317 318 SfxItemSet aSet( pCustomShape->GetMergedItemSet() ); 319 320 //SJ: vertical writing is not required, by removing this item no outliner is created 321 aSet.ClearItem( SDRATTR_TEXTDIRECTION ); 322 323 // #i105323# For 3D AutoShapes, the shadow attribute has to be applied to each 324 // created visualisation helper model shape individually. The shadow itself 325 // will then be rendered from the 3D renderer correctly for the whole 3D scene 326 // (and thus behind all objects of which the visualisation may be built). So, 327 // dio NOT remove it from the ItemSet here. 328 // aSet.ClearItem(SDRATTR_SHADOW); 329 330 std::vector< E3dCompoundObject* > aPlaceholderObjectList; 331 332 double fExtrusionBackward, fExtrusionForward; 333 GetExtrusionDepth( rGeometryItem, pMap, fExtrusionBackward, fExtrusionForward ); 334 double fDepth = fExtrusionBackward - fExtrusionForward; 335 if ( fDepth < 1.0 ) 336 fDepth = 1.0; 337 338 drawing::ProjectionMode eProjectionMode( drawing::ProjectionMode_PARALLEL ); 339 const rtl::OUString sProjectionMode( RTL_CONSTASCII_USTRINGPARAM ( "ProjectionMode" ) ); 340 Any* pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, sProjectionMode ); 341 if ( pAny ) 342 *pAny >>= eProjectionMode; 343 ProjectionType eProjectionType( eProjectionMode == drawing::ProjectionMode_PARALLEL ? PR_PARALLEL : PR_PERSPECTIVE ); 344 345 // pShape2d Umwandeln in Szene mit 3D Objekt 346 E3dDefaultAttributes a3DDefaultAttr; 347 a3DDefaultAttr.SetDefaultLatheCharacterMode( sal_True ); 348 a3DDefaultAttr.SetDefaultExtrudeCharacterMode( sal_True ); 349 350 E3dScene* pScene = new E3dPolyScene( a3DDefaultAttr ); 351 352 sal_Bool bSceneHasObjects ( sal_False ); 353 sal_Bool bUseTwoFillStyles( sal_False ); 354 355 drawing::ShadeMode eShadeMode( GetShadeMode( rGeometryItem, drawing::ShadeMode_FLAT ) ); 356 const rtl::OUString sExtrusionColor( RTL_CONSTASCII_USTRINGPARAM ( "Color" ) ); 357 sal_Bool bUseExtrusionColor = GetBool( rGeometryItem, sExtrusionColor, sal_False ); 358 359 XFillStyle eFillStyle( ITEMVALUE( aSet, XATTR_FILLSTYLE, XFillStyleItem ) ); 360 pScene->GetProperties().SetObjectItem( Svx3DShadeModeItem( 0 ) ); 361 aSet.Put( Svx3DPercentDiagonalItem( 0 ) ); 362 aSet.Put( Svx3DTextureModeItem( 1 ) ); 363 aSet.Put( Svx3DNormalsKindItem( 1 ) ); 364 365 if ( eShadeMode == drawing::ShadeMode_DRAFT ) 366 { 367 aSet.Put( XLineStyleItem( XLINE_SOLID ) ); 368 aSet.Put( XFillStyleItem ( XFILL_NONE ) ); 369 aSet.Put( Svx3DDoubleSidedItem( sal_True ) ); 370 } 371 else 372 { 373 aSet.Put( XLineStyleItem( XLINE_NONE ) ); 374 if ( eFillStyle == XFILL_NONE ) 375 aSet.Put( XFillStyleItem( XFILL_SOLID ) ); 376 else if ( ( eFillStyle == XFILL_BITMAP ) || ( eFillStyle == XFILL_GRADIENT ) || bUseExtrusionColor ) 377 bUseTwoFillStyles = sal_True; 378 379 // #116336# 380 // If shapes are mirrored once (mirroring two times correct geometry again) 381 // double-sided at the object and two-sided-lighting at the scene need to be set. 382 if((bIsMirroredX && !bIsMirroredY) || (!bIsMirroredX && bIsMirroredY)) 383 { 384 aSet.Put( Svx3DDoubleSidedItem( sal_True ) ); 385 pScene->GetProperties().SetObjectItem( Svx3DTwoSidedLightingItem( sal_True ) ); 386 } 387 } 388 389 Rectangle aBoundRect2d; 390 SdrObjListIter aIter( *pShape2d, IM_DEEPWITHGROUPS ); 391 while( aIter.IsMore() ) 392 { 393 const SdrObject* pNext = aIter.Next(); 394 sal_Bool bIsPlaceholderObject = (((XFillStyleItem&)pNext->GetMergedItem( XATTR_FILLSTYLE )).GetValue() == XFILL_NONE ) 395 && (((XLineStyleItem&)pNext->GetMergedItem( XATTR_LINESTYLE )).GetValue() == XLINE_NONE ); 396 basegfx::B2DPolyPolygon aPolyPoly; 397 398 if ( pNext->ISA( SdrPathObj ) ) 399 { 400 aPolyPoly = ((SdrPathObj*)pNext)->GetPathPoly(); 401 402 if(aPolyPoly.areControlPointsUsed()) 403 { 404 aPolyPoly = basegfx::tools::adaptiveSubdivideByAngle(aPolyPoly); 405 } 406 } 407 else 408 { 409 SdrObject* pNewObj = pNext->ConvertToPolyObj( sal_False, sal_False ); 410 SdrPathObj* pPath = PTR_CAST( SdrPathObj, pNewObj ); 411 if ( pPath ) 412 aPolyPoly = pPath->GetPathPoly(); 413 SdrObject::Free( pNewObj ); 414 } 415 416 if( aPolyPoly.count() ) 417 { 418 const basegfx::B2DRange aTempRange(basegfx::tools::getRange(aPolyPoly)); 419 const Rectangle aBoundRect(basegfx::fround(aTempRange.getMinX()), basegfx::fround(aTempRange.getMinY()), basegfx::fround(aTempRange.getMaxX()), basegfx::fround(aTempRange.getMaxY())); 420 aBoundRect2d.Union( aBoundRect ); 421 422 E3dCompoundObject* p3DObj = new E3dExtrudeObj( a3DDefaultAttr, aPolyPoly, bUseTwoFillStyles ? 10 : fDepth ); 423 p3DObj->NbcSetLayer( pShape2d->GetLayer() ); 424 p3DObj->SetMergedItemSet( aSet ); 425 if ( bIsPlaceholderObject ) 426 aPlaceholderObjectList.push_back( p3DObj ); 427 else if ( bUseTwoFillStyles ) 428 { 429 Bitmap aFillBmp; 430 sal_Bool bFillBmpTile = ((XFillBmpTileItem&)p3DObj->GetMergedItem( XATTR_FILLBMP_TILE )).GetValue(); 431 if ( bFillBmpTile ) 432 { 433 const XFillBitmapItem& rBmpItm = (XFillBitmapItem&)p3DObj->GetMergedItem( XATTR_FILLBITMAP ); 434 const XOBitmap& rXOBmp = rBmpItm.GetBitmapValue(); 435 aFillBmp = rXOBmp.GetBitmap(); 436 Size aLogicalSize = aFillBmp.GetPrefSize(); 437 if ( aFillBmp.GetPrefMapMode() == MAP_PIXEL ) 438 aLogicalSize = Application::GetDefaultDevice()->PixelToLogic( aLogicalSize, MAP_100TH_MM ); 439 else 440 aLogicalSize = OutputDevice::LogicToLogic( aLogicalSize, aFillBmp.GetPrefMapMode(), MAP_100TH_MM ); 441 aLogicalSize.Width() *= 5; ;// :-( nice scaling, look at engine3d/obj3d.cxx 442 aLogicalSize.Height() *= 5; 443 aFillBmp.SetPrefSize( aLogicalSize ); 444 aFillBmp.SetPrefMapMode( MAP_100TH_MM ); 445 p3DObj->SetMergedItem( XFillBitmapItem( String(), aFillBmp ) ); 446 } 447 else 448 { 449 if ( aSnapRect != aBoundRect ) 450 { 451 const XFillBitmapItem& rBmpItm = (XFillBitmapItem&)p3DObj->GetMergedItem( XATTR_FILLBITMAP ); 452 const XOBitmap& rXOBmp = rBmpItm.GetBitmapValue(); 453 aFillBmp = rXOBmp.GetBitmap(); 454 Size aBmpSize( aFillBmp.GetSizePixel() ); 455 double fXScale = (double)aBoundRect.GetWidth() / (double)aSnapRect.GetWidth(); 456 double fYScale = (double)aBoundRect.GetHeight() / (double)aSnapRect.GetHeight(); 457 458 Point aPt( (sal_Int32)( (double)( aBoundRect.Left() - aSnapRect.Left() )* (double)aBmpSize.Width() / (double)aSnapRect.GetWidth() ), 459 (sal_Int32)( (double)( aBoundRect.Top() - aSnapRect.Top() ) * (double)aBmpSize.Height() / (double)aSnapRect.GetHeight() ) ); 460 Size aSize( (sal_Int32)( aBmpSize.Width() * fXScale ), 461 (sal_Int32)( aBmpSize.Height() * fYScale ) ); 462 Rectangle aCropRect( aPt, aSize ); 463 aFillBmp.Crop( aCropRect ); 464 p3DObj->SetMergedItem( XFillBitmapItem( String(), aFillBmp ) ); 465 } 466 } 467 pScene->Insert3DObj( p3DObj ); 468 p3DObj = new E3dExtrudeObj( a3DDefaultAttr, aPolyPoly, fDepth ); 469 p3DObj->NbcSetLayer( pShape2d->GetLayer() ); 470 p3DObj->SetMergedItemSet( aSet ); 471 if ( bUseExtrusionColor ) 472 p3DObj->SetMergedItem( XFillColorItem( String(), ((XSecondaryFillColorItem&)pCustomShape->GetMergedItem( XATTR_SECONDARYFILLCOLOR )).GetColorValue() ) ); 473 p3DObj->SetMergedItem( XFillStyleItem( XFILL_SOLID ) ); 474 p3DObj->SetMergedItem( Svx3DCloseFrontItem( sal_False ) ); 475 p3DObj->SetMergedItem( Svx3DCloseBackItem( sal_False ) ); 476 pScene->Insert3DObj( p3DObj ); 477 p3DObj = new E3dExtrudeObj( a3DDefaultAttr, aPolyPoly, 10 ); 478 p3DObj->NbcSetLayer( pShape2d->GetLayer() ); 479 p3DObj->SetMergedItemSet( aSet ); 480 481 basegfx::B3DHomMatrix aFrontTransform( p3DObj->GetTransform() ); 482 aFrontTransform.translate( 0.0, 0.0, fDepth ); 483 p3DObj->NbcSetTransform( aFrontTransform ); 484 485 if ( ( eFillStyle == XFILL_BITMAP ) && !aFillBmp.IsEmpty() ) 486 p3DObj->SetMergedItem( XFillBitmapItem( String(), aFillBmp ) ); 487 } 488 else if ( eFillStyle == XFILL_NONE ) 489 { 490 XLineColorItem& rLineColor = (XLineColorItem&)p3DObj->GetMergedItem( XATTR_LINECOLOR ); 491 p3DObj->SetMergedItem( XFillColorItem( String(), rLineColor.GetColorValue() ) ); 492 p3DObj->SetMergedItem( Svx3DDoubleSidedItem( sal_True ) ); 493 p3DObj->SetMergedItem( Svx3DCloseFrontItem( sal_False ) ); 494 p3DObj->SetMergedItem( Svx3DCloseBackItem( sal_False ) ); 495 } 496 pScene->Insert3DObj( p3DObj ); 497 bSceneHasObjects = sal_True; 498 } 499 } 500 501 if ( bSceneHasObjects ) // is the SdrObject properly converted 502 { 503 // then we can change the return value 504 pRet = pScene; 505 506 // Kameraeinstellungen, Perspektive ... 507 Camera3D& rCamera = (Camera3D&)pScene->GetCamera(); 508 const basegfx::B3DRange& rVolume = pScene->GetBoundVolume(); 509 pScene->NbcSetSnapRect( aSnapRect ); 510 511 // InitScene replacement 512 double fW = rVolume.getWidth(); 513 double fH = rVolume.getHeight(); 514 515 rCamera.SetAutoAdjustProjection( sal_False ); 516 rCamera.SetViewWindow( -fW / 2, - fH / 2, fW, fH); 517 basegfx::B3DPoint aLookAt( 0.0, 0.0, 0.0 ); 518 basegfx::B3DPoint aCamPos( 0.0, 0.0, 100.0 ); 519 rCamera.SetDefaults( basegfx::B3DPoint( 0.0, 0.0, 100.0 ), aLookAt, 100.0 ); 520 rCamera.SetPosAndLookAt( aCamPos, aLookAt ); 521 rCamera.SetFocalLength( 1.0 ); 522 rCamera.SetProjection( eProjectionType ); 523 pScene->SetCamera( rCamera ); 524 pScene->SetRectsDirty(); 525 526 double fOriginX, fOriginY; 527 GetOrigin( rGeometryItem, fOriginX, fOriginY ); 528 fOriginX = fOriginX * aSnapRect.GetWidth(); 529 fOriginY = fOriginY * aSnapRect.GetHeight(); 530 531 basegfx::B3DHomMatrix aNewTransform( pScene->GetTransform() ); 532 aNewTransform.translate( -aCenter.X(), aCenter.Y(), -pScene->GetBoundVolume().getDepth() ); 533 534 double fXRotate, fYRotate; 535 GetRotateAngle( rGeometryItem, fXRotate, fYRotate ); 536 double fZRotate = ((SdrObjCustomShape*)pCustomShape)->GetObjectRotation() * F_PI180; 537 if ( fZRotate != 0.0 ) 538 aNewTransform.rotate( 0.0, 0.0, fZRotate ); 539 if ( bIsMirroredX ) 540 aNewTransform.scale( -1.0, 1, 1 ); 541 if ( bIsMirroredY ) 542 aNewTransform.scale( 1, -1.0, 1 ); 543 if( fYRotate != 0.0 ) 544 aNewTransform.rotate( 0.0, -fYRotate, 0.0 ); 545 if( fXRotate != 0.0 ) 546 aNewTransform.rotate( -fXRotate, 0.0, 0.0 ); 547 if ( eProjectionType == PR_PARALLEL ) 548 { 549 double fSkew, fAlpha; 550 GetSkew( rGeometryItem, fSkew, fAlpha ); 551 if ( fSkew != 0.0 ) 552 { 553 double fInvTanBeta( fSkew / 100.0 ); 554 if(fInvTanBeta) 555 { 556 aNewTransform.shearXY( 557 fInvTanBeta * cos(fAlpha), 558 fInvTanBeta * sin(fAlpha)); 559 } 560 } 561 basegfx::B3DPoint _aLookAt( 0.0, 0.0, 0.0 ); 562 basegfx::B3DPoint _aNewCamPos( 0.0, 0.0, 25000.0 ); 563 rCamera.SetPosAndLookAt( _aNewCamPos, _aLookAt ); 564 pScene->SetCamera( rCamera ); 565 } 566 else 567 { 568 aNewTransform.translate( -fOriginX, fOriginY, 0.0 ); 569 // now set correct camera position 570 const rtl::OUString sViewPoint( RTL_CONSTASCII_USTRINGPARAM ( "ViewPoint" ) ); 571 drawing::Position3D aViewPointDefault( 3472, -3472, 25000 ); 572 drawing::Position3D aViewPoint( GetPosition3D( rGeometryItem, sViewPoint, aViewPointDefault, pMap ) ); 573 double fViewPointX = aViewPoint.PositionX; 574 double fViewPointY = aViewPoint.PositionY; 575 double fViewPointZ = aViewPoint.PositionZ; 576 basegfx::B3DPoint _aLookAt( fViewPointX, -fViewPointY, 0.0 ); 577 basegfx::B3DPoint aNewCamPos( fViewPointX, -fViewPointY, fViewPointZ ); 578 rCamera.SetPosAndLookAt( aNewCamPos, _aLookAt ); 579 pScene->SetCamera( rCamera ); 580 } 581 582 pScene->NbcSetTransform( aNewTransform ); 583 584 /////////// 585 // light // 586 /////////// 587 588 const rtl::OUString sBrightness( RTL_CONSTASCII_USTRINGPARAM ( "Brightness" ) ); 589 double fAmbientIntensity = GetDouble( rGeometryItem, sBrightness, 22178.0 / 655.36, NULL ) / 100.0; 590 591 592 const rtl::OUString sFirstLightDirection( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightDirection" ) ); 593 drawing::Direction3D aFirstLightDirectionDefault( 50000, 0, 10000 ); 594 drawing::Direction3D aFirstLightDirection( GetDirection3D( rGeometryItem, sFirstLightDirection, aFirstLightDirectionDefault ) ); 595 if ( aFirstLightDirection.DirectionZ == 0.0 ) 596 aFirstLightDirection.DirectionZ = 1.0; 597 598 const rtl::OUString sFirstLightLevel( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightLevel" ) ); 599 double fLightIntensity = GetDouble( rGeometryItem, sFirstLightLevel, 43712.0 / 655.36, NULL ) / 100.0; 600 601 const rtl::OUString sFirstLightHarsh( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightHarsh" ) ); 602 /* sal_Bool bFirstLightHarsh = */ GetBool( rGeometryItem, sFirstLightHarsh, sal_False ); 603 604 const rtl::OUString sSecondLightDirection( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightDirection" ) ); 605 drawing::Direction3D aSecondLightDirectionDefault( -50000, 0, 10000 ); 606 drawing::Direction3D aSecondLightDirection( GetDirection3D( rGeometryItem, sSecondLightDirection, aSecondLightDirectionDefault ) ); 607 if ( aSecondLightDirection.DirectionZ == 0.0 ) 608 aSecondLightDirection.DirectionZ = -1; 609 610 const rtl::OUString sSecondLightLevel( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightLevel" ) ); 611 double fLight2Intensity = GetDouble( rGeometryItem, sSecondLightLevel, 43712.0 / 655.36, NULL ) / 100.0; 612 613 const rtl::OUString sSecondLightHarsh( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightHarsh" ) ); 614 const rtl::OUString sLightFace( RTL_CONSTASCII_USTRINGPARAM ( "LightFace" ) ); 615 /* sal_Bool bLight2Harsh = */ GetBool( rGeometryItem, sSecondLightHarsh, sal_False ); 616 /* sal_Bool bLightFace = */ GetBool( rGeometryItem, sLightFace, sal_False ); 617 618 sal_uInt16 nAmbientColor = (sal_uInt16)( fAmbientIntensity * 255.0 ); 619 if ( nAmbientColor > 255 ) 620 nAmbientColor = 255; 621 Color aGlobalAmbientColor( (sal_uInt8)nAmbientColor, (sal_uInt8)nAmbientColor, (sal_uInt8)nAmbientColor ); 622 pScene->GetProperties().SetObjectItem( Svx3DAmbientcolorItem( aGlobalAmbientColor ) ); 623 624 sal_uInt8 nSpotLight1 = (sal_uInt8)( fLightIntensity * 255.0 ); 625 basegfx::B3DVector aSpotLight1( aFirstLightDirection.DirectionX, - ( aFirstLightDirection.DirectionY ), -( aFirstLightDirection.DirectionZ ) ); 626 aSpotLight1.normalize(); 627 pScene->GetProperties().SetObjectItem( Svx3DLightOnOff1Item( sal_True ) ); 628 Color aAmbientSpot1Color( nSpotLight1, nSpotLight1, nSpotLight1 ); 629 pScene->GetProperties().SetObjectItem( Svx3DLightcolor1Item( aAmbientSpot1Color ) ); 630 pScene->GetProperties().SetObjectItem( Svx3DLightDirection1Item( aSpotLight1 ) ); 631 632 sal_uInt8 nSpotLight2 = (sal_uInt8)( fLight2Intensity * 255.0 ); 633 basegfx::B3DVector aSpotLight2( aSecondLightDirection.DirectionX, -aSecondLightDirection.DirectionY, -aSecondLightDirection.DirectionZ ); 634 aSpotLight2.normalize(); 635 pScene->GetProperties().SetObjectItem( Svx3DLightOnOff2Item( sal_True ) ); 636 Color aAmbientSpot2Color( nSpotLight2, nSpotLight2, nSpotLight2 ); 637 pScene->GetProperties().SetObjectItem( Svx3DLightcolor2Item( aAmbientSpot2Color ) ); 638 pScene->GetProperties().SetObjectItem( Svx3DLightDirection2Item( aSpotLight2 ) ); 639 640 sal_uInt8 nSpotLight3 = 70; 641 basegfx::B3DVector aSpotLight3( 0.0, 0.0, 1.0 ); 642 pScene->GetProperties().SetObjectItem( Svx3DLightOnOff3Item( sal_True ) ); 643 Color aAmbientSpot3Color( nSpotLight3, nSpotLight3, nSpotLight3 ); 644 pScene->GetProperties().SetObjectItem( Svx3DLightcolor3Item( aAmbientSpot3Color ) ); 645 pScene->GetProperties().SetObjectItem( Svx3DLightDirection3Item( aSpotLight3 ) ); 646 647 const rtl::OUString sSpecularity( RTL_CONSTASCII_USTRINGPARAM ( "Specularity" ) ); 648 const rtl::OUString sDiffusion( RTL_CONSTASCII_USTRINGPARAM ( "Diffusion" ) ); 649 const rtl::OUString sShininess( RTL_CONSTASCII_USTRINGPARAM ( "Shininess" ) ); 650 const rtl::OUString sMetal( RTL_CONSTASCII_USTRINGPARAM ( "Metal" ) ); 651 double fSpecular = GetDouble( rGeometryItem, sSpecularity, 0, NULL ) / 100; 652 sal_Bool bMetal = GetBool( rGeometryItem, sMetal, sal_False ); 653 654 Color aSpecularCol( 225,225,225 ); 655 if ( bMetal ) 656 { 657 aSpecularCol = Color( 200, 200, 200 ); 658 fSpecular += 0.15; 659 } 660 sal_Int32 nIntensity = (sal_Int32)fSpecular * 100; 661 if ( nIntensity > 100 ) 662 nIntensity = 100; 663 else if ( nIntensity < 0 ) 664 nIntensity = 0; 665 nIntensity = 100 - nIntensity; 666 pScene->GetProperties().SetObjectItem( Svx3DMaterialSpecularItem( aSpecularCol ) ); 667 pScene->GetProperties().SetObjectItem( Svx3DMaterialSpecularIntensityItem( (sal_uInt16)nIntensity ) ); 668 669 pScene->SetLogicRect( CalculateNewSnapRect( pCustomShape, aSnapRect, aBoundRect2d, pMap ) ); 670 671 // removing placeholder objects 672 std::vector< E3dCompoundObject* >::iterator aObjectListIter( aPlaceholderObjectList.begin() ); 673 while ( aObjectListIter != aPlaceholderObjectList.end() ) 674 { 675 pScene->Remove3DObj( *aObjectListIter ); 676 delete *aObjectListIter++; 677 } 678 } 679 else 680 delete pScene; 681 } 682 return pRet; 683 } 684 685 Rectangle EnhancedCustomShape3d::CalculateNewSnapRect( const SdrObject* pCustomShape, const Rectangle& rSnapRect, const Rectangle& rBoundRect, const double* pMap ) 686 { 687 SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)pCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ); 688 const Point aCenter( rSnapRect.Center() ); 689 double fExtrusionBackward, fExtrusionForward; 690 GetExtrusionDepth( rGeometryItem, pMap, fExtrusionBackward, fExtrusionForward ); 691 sal_uInt32 i; 692 693 // creating initial bound volume ( without rotation. skewing.and camera ) 694 basegfx::B3DPolygon aBoundVolume; 695 const Polygon aPolygon( rBoundRect ); 696 697 for ( i = 0L; i < 4L; i++ ) 698 { 699 aBoundVolume.append(basegfx::B3DPoint(aPolygon[ (sal_uInt16)i ].X() - aCenter.X(), aPolygon[ (sal_uInt16)i ].Y() - aCenter.Y(), fExtrusionForward)); 700 } 701 702 for ( i = 0L; i < 4L; i++ ) 703 { 704 aBoundVolume.append(basegfx::B3DPoint(aPolygon[ (sal_uInt16)i ].X() - aCenter.X(), aPolygon[ (sal_uInt16)i ].Y() - aCenter.Y(), fExtrusionBackward)); 705 } 706 707 const rtl::OUString sRotationCenter( RTL_CONSTASCII_USTRINGPARAM ( "RotationCenter" ) ); 708 drawing::Direction3D aRotationCenterDefault( 0, 0, 0 ); // default seems to be wrong, a fractional size of shape has to be used!! 709 drawing::Direction3D aRotationCenter( GetDirection3D( rGeometryItem, sRotationCenter, aRotationCenterDefault ) ); 710 711 // double XCenterInGUnits = rPropSet.GetPropertyValue( DFF_Prop_c3DRotationCenterX, 0 ); 712 // double YCenterInGUnits = rPropSet.GetPropertyValue( DFF_Prop_c3DRotationCenterY, 0 ); 713 714 // sal_Int32 nRotationXAxisInProz = rPropSet.GetPropertyValue( DFF_Prop_c3DRotationAxisX, 100 ); 715 // sal_Int32 nRotationYAxisInProz = rPropSet.GetPropertyValue( DFF_Prop_c3DRotationAxisY, 0 ); 716 // sal_Int32 nRotationZAxisInProz = rPropSet.GetPropertyValue( DFF_Prop_c3DRotationAxisZ, 0 ); 717 718 719 double fXRotate, fYRotate; 720 GetRotateAngle( rGeometryItem, fXRotate, fYRotate ); 721 double fZRotate = - ((SdrObjCustomShape*)pCustomShape)->GetObjectRotation() * F_PI180; 722 723 // rotating bound volume 724 basegfx::B3DHomMatrix aMatrix; 725 aMatrix.translate(-aRotationCenter.DirectionX, -aRotationCenter.DirectionY, -aRotationCenter.DirectionZ); 726 if ( fZRotate != 0.0 ) 727 aMatrix.rotate( 0.0, 0.0, fZRotate ); 728 if ( ((SdrObjCustomShape*)pCustomShape)->IsMirroredX() ) 729 aMatrix.scale( -1.0, 1, 1 ); 730 if ( ((SdrObjCustomShape*)pCustomShape)->IsMirroredY() ) 731 aMatrix.scale( 1, -1.0, 1 ); 732 if( fYRotate != 0.0 ) 733 aMatrix.rotate( 0.0, fYRotate, 0.0 ); 734 if( fXRotate != 0.0 ) 735 aMatrix.rotate( -fXRotate, 0.0, 0.0 ); 736 aMatrix.translate(aRotationCenter.DirectionX, aRotationCenter.DirectionY, aRotationCenter.DirectionZ); 737 aBoundVolume.transform(aMatrix); 738 739 Transformation2D aTransformation2D( pCustomShape, rSnapRect, pMap ); 740 if ( aTransformation2D.IsParallel() ) 741 aBoundVolume = aTransformation2D.ApplySkewSettings( aBoundVolume ); 742 743 Polygon aTransformed( 8 ); 744 for ( i = 0L; i < 8L; i++ ) 745 aTransformed[ (sal_uInt16)i ] = aTransformation2D.Transform2D( aBoundVolume.getB3DPoint( i ) ); 746 747 return aTransformed.GetBoundRect(); 748 } 749