1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: EnhancedCustomShape3d.cxx,v $
10 * $Revision: 1.19.18.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
33 #include "EnhancedCustomShape3d.hxx"
34 #include <svx/svdetc.hxx>
35 #include <svx/svdmodel.hxx>
36 #include <tools/poly.hxx>
37 #include <svditer.hxx>
38 #include <svx/svdobj.hxx>
39 #include <svx/svdoashp.hxx>
40 #include <svtools/poolitem.hxx>
41 #include <svtools/itemset.hxx>
42 #include <svx/xfillit0.hxx>
43 #include <svx/xsflclit.hxx>
44 #include <svx/xit.hxx>
45 #include <svx/xbtmpit.hxx>
46 #include <svx/xflclit.hxx>
47 #include <svx/svdopath.hxx>
48 #include <svx/svdogrp.hxx>
49 #include <svx/svdpage.hxx>
50 #include <svx/polysc3d.hxx>
51 #include <svx/svddef.hxx>
52 #include <svx/svx3ditems.hxx>
53 #include <svx/extrud3d.hxx>
54 #include <svx/xflbmtit.hxx>
55 #include <vcl/svapp.hxx>
56 #include <svx/xlnclit.hxx>
57 #include <svx/sdasitm.hxx>
58 #include <com/sun/star/awt/Point.hpp>
59 #include <com/sun/star/drawing/Position3D.hpp>
60 #include <com/sun/star/drawing/Direction3D.hpp>
61 #include <com/sun/star/drawing/ShadeMode.hpp>
62 #include <svx/sdr/properties/properties.hxx>
63 #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
64 #include <basegfx/polygon/b2dpolypolygontools.hxx>
65 #include <basegfx/range/b2drange.hxx>
67 #define ITEMVALUE(ItemSet,Id,Cast) ((const Cast&)(ItemSet).Get(Id)).GetValue()
68 using namespace com::sun::star
;
69 using namespace com::sun::star::uno
;
71 const rtl::OUString
sExtrusion( RTL_CONSTASCII_USTRINGPARAM ( "Extrusion" ) );
73 void GetOrigin( SdrCustomShapeGeometryItem
& rItem
, double& rOriginX
, double& rOriginY
)
75 ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aOriginParaPair
;
76 const rtl::OUString
sOrigin( RTL_CONSTASCII_USTRINGPARAM ( "Origin" ) );
77 Any
* pAny
= rItem
.GetPropertyValueByName( sExtrusion
, sOrigin
);
78 if ( ! ( pAny
&& ( *pAny
>>= aOriginParaPair
) && ( aOriginParaPair
.First
.Value
>>= rOriginX
) && ( aOriginParaPair
.Second
.Value
>>= rOriginY
) ) )
85 void GetRotateAngle( SdrCustomShapeGeometryItem
& rItem
, double& rAngleX
, double& rAngleY
)
87 ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aRotateAngleParaPair
;
88 const rtl::OUString
sRotateAngle( RTL_CONSTASCII_USTRINGPARAM ( "RotateAngle" ) );
89 Any
* pAny
= rItem
.GetPropertyValueByName( sExtrusion
, sRotateAngle
);
90 if ( ! ( pAny
&& ( *pAny
>>= aRotateAngleParaPair
) && ( aRotateAngleParaPair
.First
.Value
>>= rAngleX
) && ( aRotateAngleParaPair
.Second
.Value
>>= rAngleY
) ) )
99 void GetSkew( SdrCustomShapeGeometryItem
& rItem
, double& rSkewAmount
, double& rSkewAngle
)
101 ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aSkewParaPair
;
102 const rtl::OUString
sSkew( RTL_CONSTASCII_USTRINGPARAM ( "Skew" ) );
103 Any
* pAny
= rItem
.GetPropertyValueByName( sExtrusion
, sSkew
);
104 if ( ! ( pAny
&& ( *pAny
>>= aSkewParaPair
) && ( aSkewParaPair
.First
.Value
>>= rSkewAmount
) && ( aSkewParaPair
.Second
.Value
>>= rSkewAngle
) ) )
109 rSkewAngle
*= F_PI180
;
112 void GetExtrusionDepth( SdrCustomShapeGeometryItem
& rItem
, const double* pMap
, double& rBackwardDepth
, double& rForwardDepth
)
114 ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aDepthParaPair
;
115 double fDepth
= 0, fFraction
= 0;
116 const rtl::OUString
sDepth( RTL_CONSTASCII_USTRINGPARAM ( "Depth" ) );
117 Any
* pAny
= rItem
.GetPropertyValueByName( sExtrusion
, sDepth
);
118 if ( pAny
&& ( *pAny
>>= aDepthParaPair
) && ( aDepthParaPair
.First
.Value
>>= fDepth
) && ( aDepthParaPair
.Second
.Value
>>= fFraction
) )
120 rForwardDepth
= fDepth
* fFraction
;
121 rBackwardDepth
= fDepth
- rForwardDepth
;
125 rBackwardDepth
= 1270;
131 rBackwardDepth
*= fMap
;
132 rForwardDepth
*= fMap
;
136 double GetDouble( SdrCustomShapeGeometryItem
& rItem
, const rtl::OUString
& rPropertyName
, double fDefault
, const double* pMap
)
138 double fRetValue
= fDefault
;
139 Any
* pAny
= rItem
.GetPropertyValueByName( sExtrusion
, rPropertyName
);
147 drawing::ShadeMode
GetShadeMode( SdrCustomShapeGeometryItem
& rItem
, const drawing::ShadeMode eDefault
)
149 drawing::ShadeMode
eRet( eDefault
);
150 const rtl::OUString
sShadeMode( RTL_CONSTASCII_USTRINGPARAM ( "ShadeMode" ) );
151 Any
* pAny
= rItem
.GetPropertyValueByName( sExtrusion
, sShadeMode
);
157 sal_Int32
GetInt32( SdrCustomShapeGeometryItem
& rItem
, const rtl::OUString
& rPropertyName
, const sal_Int32 nDefault
)
159 sal_Int32 nRetValue
= nDefault
;
160 Any
* pAny
= rItem
.GetPropertyValueByName( sExtrusion
, rPropertyName
);
166 sal_Bool
GetBool( SdrCustomShapeGeometryItem
& rItem
, const rtl::OUString
& rPropertyName
, const sal_Bool bDefault
)
168 sal_Bool bRetValue
= bDefault
;
169 const Any
* pAny
= rItem
.GetPropertyValueByName( sExtrusion
, rPropertyName
);
175 awt::Point
GetPoint( SdrCustomShapeGeometryItem
& rItem
, const rtl::OUString
& rPropertyName
, const awt::Point
& rDefault
)
177 awt::Point
aRetValue( rDefault
);
178 const Any
* pAny
= rItem
.GetPropertyValueByName( sExtrusion
, rPropertyName
);
184 drawing::Position3D
GetPosition3D( SdrCustomShapeGeometryItem
& rItem
, const rtl::OUString
& rPropertyName
,
185 const drawing::Position3D
& rDefault
, const double* pMap
)
187 drawing::Position3D
aRetValue( rDefault
);
188 const Any
* pAny
= rItem
.GetPropertyValueByName( sExtrusion
, rPropertyName
);
193 aRetValue
.PositionX
*= *pMap
;
194 aRetValue
.PositionY
*= *pMap
;
195 aRetValue
.PositionZ
*= *pMap
;
200 drawing::Direction3D
GetDirection3D( SdrCustomShapeGeometryItem
& rItem
, const rtl::OUString
& rPropertyName
, const drawing::Direction3D
& rDefault
)
202 drawing::Direction3D
aRetValue( rDefault
);
203 const Any
* pAny
= rItem
.GetPropertyValueByName( sExtrusion
, rPropertyName
);
209 EnhancedCustomShape3d::Transformation2D::Transformation2D( const SdrObject
* pCustomShape
, const Rectangle
& /*rBoundRect*/, const double *pM
)
210 : aCenter( pCustomShape
->GetSnapRect().Center() )
211 , eProjectionMode( drawing::ProjectionMode_PARALLEL
)
214 SdrCustomShapeGeometryItem
& rGeometryItem
= (SdrCustomShapeGeometryItem
&)pCustomShape
->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY
);
215 const rtl::OUString
sProjectionMode( RTL_CONSTASCII_USTRINGPARAM ( "ProjectionMode" ) );
216 Any
* pAny
= rGeometryItem
.GetPropertyValueByName( sExtrusion
, sProjectionMode
);
218 *pAny
>>= eProjectionMode
;
220 if ( eProjectionMode
== drawing::ProjectionMode_PARALLEL
)
221 GetSkew( rGeometryItem
, fSkew
, fSkewAngle
);
225 GetOrigin( rGeometryItem
, fOriginX
, fOriginY
);
226 fOriginX
= fOriginX
* pCustomShape
->GetLogicRect().GetWidth();
227 fOriginY
= fOriginY
* pCustomShape
->GetLogicRect().GetHeight();
229 const rtl::OUString
sViewPoint( RTL_CONSTASCII_USTRINGPARAM ( "ViewPoint" ) );
230 drawing::Position3D
aViewPointDefault( 3472, -3472, 25000 );
231 drawing::Position3D
aViewPoint( GetPosition3D( rGeometryItem
, sViewPoint
, aViewPointDefault
, pMap
) );
232 fViewPoint
.setX(aViewPoint
.PositionX
);
233 fViewPoint
.setY(aViewPoint
.PositionY
);
234 fViewPoint
.setZ(-aViewPoint
.PositionZ
);
238 basegfx::B3DPolygon
EnhancedCustomShape3d::Transformation2D::ApplySkewSettings( const basegfx::B3DPolygon
& rPoly3D
) const
240 basegfx::B3DPolygon aRetval
;
243 for ( j
= 0L; j
< rPoly3D
.count(); j
++ )
245 const basegfx::B3DPoint
aPoint(rPoly3D
.getB3DPoint(j
));
246 double fDepth(-( aPoint
.getZ() * fSkew
) / 100.0);
247 aRetval
.append(basegfx::B3DPoint(
248 aPoint
.getX() + (fDepth
* cos( fSkewAngle
)),
249 aPoint
.getY() - (fDepth
* sin( fSkewAngle
)),
256 Point
EnhancedCustomShape3d::Transformation2D::Transform2D( const basegfx::B3DPoint
& rPoint3D
) const
259 if ( eProjectionMode
== drawing::ProjectionMode_PARALLEL
)
261 aPoint2D
.X() = (sal_Int32
)rPoint3D
.getX();
262 aPoint2D
.Y() = (sal_Int32
)rPoint3D
.getY();
266 double fX
= rPoint3D
.getX() - fOriginX
;
267 double fY
= rPoint3D
.getY() - fOriginY
;
268 double f
= ( fZScreen
- fViewPoint
.getZ() ) / ( rPoint3D
.getZ() - fViewPoint
.getZ() );
269 aPoint2D
.X() = (sal_Int32
)(( fX
- fViewPoint
.getX() ) * f
+ fViewPoint
.getX() + fOriginX
);
270 aPoint2D
.Y() = (sal_Int32
)(( fY
- fViewPoint
.getY() ) * f
+ fViewPoint
.getY() + fOriginY
);
272 aPoint2D
.Move( aCenter
.X(), aCenter
.Y() );
276 sal_Bool
EnhancedCustomShape3d::Transformation2D::IsParallel() const
278 return eProjectionMode
== com::sun::star::drawing::ProjectionMode_PARALLEL
;
281 SdrObject
* EnhancedCustomShape3d::Create3DObject( const SdrObject
* pShape2d
, const SdrObject
* pCustomShape
)
283 SdrObject
* pRet
= NULL
;
284 SdrModel
* pModel
= pCustomShape
->GetModel();
285 SdrCustomShapeGeometryItem
& rGeometryItem
= (SdrCustomShapeGeometryItem
&)pCustomShape
->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY
);
287 double fMap
, *pMap
= NULL
;
291 Fraction
aFraction( pModel
->GetScaleFraction() );
292 if ( ( aFraction
.GetNumerator() ) != 1 || ( aFraction
.GetDenominator() != 1 ) )
294 fMap
*= aFraction
.GetNumerator();
295 fMap
/= aFraction
.GetDenominator();
298 if ( pModel
->GetScaleUnit() != MAP_100TH_MM
)
300 DBG_ASSERT( pModel
->GetScaleUnit() == MAP_TWIP
, "EnhancedCustomShape3d::Current MapMode is Unsupported" );
301 fMap
*= 1440.0 / 2540.0;
305 if ( GetBool( rGeometryItem
, sExtrusion
, sal_False
) )
307 sal_Bool bIsMirroredX
= ((SdrObjCustomShape
*)pCustomShape
)->IsMirroredX();
308 sal_Bool bIsMirroredY
= ((SdrObjCustomShape
*)pCustomShape
)->IsMirroredY();
309 Rectangle
aSnapRect( pCustomShape
->GetLogicRect() );
310 long nObjectRotation
= pCustomShape
->GetRotateAngle();
311 if ( nObjectRotation
)
313 double a
= ( 36000 - nObjectRotation
) * nPi180
;
314 long dx
= aSnapRect
.Right() - aSnapRect
.Left();
315 long dy
= aSnapRect
.Bottom()- aSnapRect
.Top();
316 Point
aP( aSnapRect
.TopLeft() );
317 RotatePoint( aP
, pCustomShape
->GetSnapRect().Center(), sin( a
), cos( a
) );
318 aSnapRect
.Left() = aP
.X();
319 aSnapRect
.Top() = aP
.Y();
320 aSnapRect
.Right() = aSnapRect
.Left() + dx
;
321 aSnapRect
.Bottom() = aSnapRect
.Top() + dy
;
323 Point
aCenter( aSnapRect
.Center() );
325 SfxItemSet
aSet( pCustomShape
->GetMergedItemSet() );
326 aSet
.ClearItem( SDRATTR_TEXTDIRECTION
); //SJ: vertical writing is not required, by removing this item no outliner is created
327 std::vector
< E3dCompoundObject
* > aPlaceholderObjectList
;
329 double fExtrusionBackward
, fExtrusionForward
;
330 GetExtrusionDepth( rGeometryItem
, pMap
, fExtrusionBackward
, fExtrusionForward
);
331 double fDepth
= fExtrusionBackward
- fExtrusionForward
;
335 drawing::ProjectionMode
eProjectionMode( drawing::ProjectionMode_PARALLEL
);
336 const rtl::OUString
sProjectionMode( RTL_CONSTASCII_USTRINGPARAM ( "ProjectionMode" ) );
337 Any
* pAny
= rGeometryItem
.GetPropertyValueByName( sExtrusion
, sProjectionMode
);
339 *pAny
>>= eProjectionMode
;
340 ProjectionType
eProjectionType( eProjectionMode
== drawing::ProjectionMode_PARALLEL
? PR_PARALLEL
: PR_PERSPECTIVE
);
342 // pShape2d Umwandeln in Szene mit 3D Objekt
343 E3dDefaultAttributes a3DDefaultAttr
;
344 a3DDefaultAttr
.SetDefaultLatheCharacterMode( TRUE
);
345 a3DDefaultAttr
.SetDefaultExtrudeCharacterMode( TRUE
);
347 E3dScene
* pScene
= new E3dPolyScene( a3DDefaultAttr
);
349 sal_Bool
bSceneHasObjects ( sal_False
);
350 sal_Bool
bUseTwoFillStyles( sal_False
);
352 drawing::ShadeMode
eShadeMode( GetShadeMode( rGeometryItem
, drawing::ShadeMode_FLAT
) );
353 const rtl::OUString
sExtrusionColor( RTL_CONSTASCII_USTRINGPARAM ( "Color" ) );
354 sal_Bool bUseExtrusionColor
= GetBool( rGeometryItem
, sExtrusionColor
, sal_False
);
356 XFillStyle
eFillStyle( ITEMVALUE( aSet
, XATTR_FILLSTYLE
, XFillStyleItem
) );
357 pScene
->GetProperties().SetObjectItem( Svx3DShadeModeItem( 0 ) );
358 aSet
.Put( Svx3DPercentDiagonalItem( 0 ) );
359 aSet
.Put( Svx3DTextureModeItem( 1 ) );
360 aSet
.Put( Svx3DNormalsKindItem( 1 ) );
362 if ( eShadeMode
== drawing::ShadeMode_DRAFT
)
364 aSet
.Put( XLineStyleItem( XLINE_SOLID
) );
365 aSet
.Put( XFillStyleItem ( XFILL_NONE
) );
366 aSet
.Put( Svx3DDoubleSidedItem( TRUE
) );
370 aSet
.Put( XLineStyleItem( XLINE_NONE
) );
371 if ( eFillStyle
== XFILL_NONE
)
372 aSet
.Put( XFillStyleItem( XFILL_SOLID
) );
373 else if ( ( eFillStyle
== XFILL_BITMAP
) || ( eFillStyle
== XFILL_GRADIENT
) || bUseExtrusionColor
)
374 bUseTwoFillStyles
= sal_True
;
377 // If shapes are mirrored once (mirroring two times correct geometry again)
378 // double-sided at the object and two-sided-lighting at the scene need to be set.
379 if((bIsMirroredX
&& !bIsMirroredY
) || (!bIsMirroredX
&& bIsMirroredY
))
381 aSet
.Put( Svx3DDoubleSidedItem( sal_True
) );
382 pScene
->GetProperties().SetObjectItem( Svx3DTwoSidedLightingItem( sal_True
) );
386 Rectangle aBoundRect2d
;
387 SdrObjListIter
aIter( *pShape2d
, IM_DEEPWITHGROUPS
);
388 while( aIter
.IsMore() )
390 const SdrObject
* pNext
= aIter
.Next();
391 sal_Bool bIsPlaceholderObject
= (((XFillStyleItem
&)pNext
->GetMergedItem( XATTR_FILLSTYLE
)).GetValue() == XFILL_NONE
)
392 && (((XLineStyleItem
&)pNext
->GetMergedItem( XATTR_LINESTYLE
)).GetValue() == XLINE_NONE
);
393 basegfx::B2DPolyPolygon aPolyPoly
;
395 if ( pNext
->ISA( SdrPathObj
) )
397 aPolyPoly
= ((SdrPathObj
*)pNext
)->GetPathPoly();
399 if(aPolyPoly
.areControlPointsUsed())
401 aPolyPoly
= basegfx::tools::adaptiveSubdivideByAngle(aPolyPoly
);
406 SdrObject
* pNewObj
= pNext
->ConvertToPolyObj( FALSE
, FALSE
);
407 SdrPathObj
* pPath
= PTR_CAST( SdrPathObj
, pNewObj
);
409 aPolyPoly
= pPath
->GetPathPoly();
410 SdrObject::Free( pNewObj
);
413 if( aPolyPoly
.count() )
415 const basegfx::B2DRange
aTempRange(basegfx::tools::getRange(aPolyPoly
));
416 const Rectangle
aBoundRect(basegfx::fround(aTempRange
.getMinX()), basegfx::fround(aTempRange
.getMinY()), basegfx::fround(aTempRange
.getMaxX()), basegfx::fround(aTempRange
.getMaxY()));
417 aBoundRect2d
.Union( aBoundRect
);
419 E3dCompoundObject
* p3DObj
= new E3dExtrudeObj( a3DDefaultAttr
, aPolyPoly
, bUseTwoFillStyles
? 10 : fDepth
);
420 p3DObj
->NbcSetLayer( pShape2d
->GetLayer() );
421 p3DObj
->SetMergedItemSet( aSet
);
422 if ( bIsPlaceholderObject
)
423 aPlaceholderObjectList
.push_back( p3DObj
);
424 else if ( bUseTwoFillStyles
)
427 sal_Bool bFillBmpTile
= ((XFillBmpTileItem
&)p3DObj
->GetMergedItem( XATTR_FILLBMP_TILE
)).GetValue();
430 const XFillBitmapItem
& rBmpItm
= (XFillBitmapItem
&)p3DObj
->GetMergedItem( XATTR_FILLBITMAP
);
431 const XOBitmap
& rXOBmp
= rBmpItm
.GetBitmapValue();
432 aFillBmp
= rXOBmp
.GetBitmap();
433 Size aLogicalSize
= aFillBmp
.GetPrefSize();
434 if ( aFillBmp
.GetPrefMapMode() == MAP_PIXEL
)
435 aLogicalSize
= Application::GetDefaultDevice()->PixelToLogic( aLogicalSize
, MAP_100TH_MM
);
437 aLogicalSize
= OutputDevice::LogicToLogic( aLogicalSize
, aFillBmp
.GetPrefMapMode(), MAP_100TH_MM
);
438 aLogicalSize
.Width() *= 5; ;// :-( nice scaling, look at engine3d/obj3d.cxx
439 aLogicalSize
.Height() *= 5;
440 aFillBmp
.SetPrefSize( aLogicalSize
);
441 aFillBmp
.SetPrefMapMode( MAP_100TH_MM
);
442 p3DObj
->SetMergedItem( XFillBitmapItem( String(), aFillBmp
) );
446 if ( aSnapRect
!= aBoundRect
)
448 const XFillBitmapItem
& rBmpItm
= (XFillBitmapItem
&)p3DObj
->GetMergedItem( XATTR_FILLBITMAP
);
449 const XOBitmap
& rXOBmp
= rBmpItm
.GetBitmapValue();
450 aFillBmp
= rXOBmp
.GetBitmap();
451 Size
aBmpSize( aFillBmp
.GetSizePixel() );
452 double fXScale
= (double)aBoundRect
.GetWidth() / (double)aSnapRect
.GetWidth();
453 double fYScale
= (double)aBoundRect
.GetHeight() / (double)aSnapRect
.GetHeight();
455 Point
aPt( (sal_Int32
)( (double)( aBoundRect
.Left() - aSnapRect
.Left() )* (double)aBmpSize
.Width() / (double)aSnapRect
.GetWidth() ),
456 (sal_Int32
)( (double)( aBoundRect
.Top() - aSnapRect
.Top() ) * (double)aBmpSize
.Height() / (double)aSnapRect
.GetHeight() ) );
457 Size
aSize( (sal_Int32
)( aBmpSize
.Width() * fXScale
),
458 (sal_Int32
)( aBmpSize
.Height() * fYScale
) );
459 Rectangle
aCropRect( aPt
, aSize
);
460 aFillBmp
.Crop( aCropRect
);
461 p3DObj
->SetMergedItem( XFillBitmapItem( String(), aFillBmp
) );
464 pScene
->Insert3DObj( p3DObj
);
465 p3DObj
= new E3dExtrudeObj( a3DDefaultAttr
, aPolyPoly
, fDepth
);
466 p3DObj
->NbcSetLayer( pShape2d
->GetLayer() );
467 p3DObj
->SetMergedItemSet( aSet
);
468 if ( bUseExtrusionColor
)
469 p3DObj
->SetMergedItem( XFillColorItem( String(), ((XSecondaryFillColorItem
&)pCustomShape
->GetMergedItem( XATTR_SECONDARYFILLCOLOR
)).GetColorValue() ) );
470 p3DObj
->SetMergedItem( XFillStyleItem( XFILL_SOLID
) );
471 p3DObj
->SetMergedItem( Svx3DCloseFrontItem( sal_False
) );
472 p3DObj
->SetMergedItem( Svx3DCloseBackItem( sal_False
) );
473 pScene
->Insert3DObj( p3DObj
);
474 p3DObj
= new E3dExtrudeObj( a3DDefaultAttr
, aPolyPoly
, 10 );
475 p3DObj
->NbcSetLayer( pShape2d
->GetLayer() );
476 p3DObj
->SetMergedItemSet( aSet
);
478 basegfx::B3DHomMatrix
aFrontTransform( p3DObj
->GetTransform() );
479 aFrontTransform
.translate( 0.0, 0.0, fDepth
);
480 p3DObj
->NbcSetTransform( aFrontTransform
);
482 if ( ( eFillStyle
== XFILL_BITMAP
) && !aFillBmp
.IsEmpty() )
483 p3DObj
->SetMergedItem( XFillBitmapItem( String(), aFillBmp
) );
485 else if ( eFillStyle
== XFILL_NONE
)
487 XLineColorItem
& rLineColor
= (XLineColorItem
&)p3DObj
->GetMergedItem( XATTR_LINECOLOR
);
488 p3DObj
->SetMergedItem( XFillColorItem( String(), rLineColor
.GetColorValue() ) );
489 p3DObj
->SetMergedItem( Svx3DDoubleSidedItem( sal_True
) );
490 p3DObj
->SetMergedItem( Svx3DCloseFrontItem( sal_False
) );
491 p3DObj
->SetMergedItem( Svx3DCloseBackItem( sal_False
) );
493 pScene
->Insert3DObj( p3DObj
);
494 bSceneHasObjects
= sal_True
;
498 if ( bSceneHasObjects
) // is the SdrObject properly converted
500 // then we can change the return value
503 // Kameraeinstellungen, Perspektive ...
504 Camera3D
& rCamera
= (Camera3D
&)pScene
->GetCamera();
505 const basegfx::B3DRange
& rVolume
= pScene
->GetBoundVolume();
506 pScene
->NbcSetSnapRect( aSnapRect
);
508 // InitScene replacement
509 double fW
= rVolume
.getWidth();
510 double fH
= rVolume
.getHeight();
512 rCamera
.SetAutoAdjustProjection( FALSE
);
513 rCamera
.SetViewWindow( -fW
/ 2, - fH
/ 2, fW
, fH
);
514 basegfx::B3DPoint
aLookAt( 0.0, 0.0, 0.0 );
515 basegfx::B3DPoint
aCamPos( 0.0, 0.0, 100.0 );
516 rCamera
.SetDefaults( basegfx::B3DPoint( 0.0, 0.0, 100.0 ), aLookAt
, 100.0 );
517 rCamera
.SetPosAndLookAt( aCamPos
, aLookAt
);
518 rCamera
.SetFocalLength( 1.0 );
519 rCamera
.SetProjection( eProjectionType
);
520 pScene
->SetCamera( rCamera
);
521 pScene
->SetRectsDirty();
523 double fOriginX
, fOriginY
;
524 GetOrigin( rGeometryItem
, fOriginX
, fOriginY
);
525 fOriginX
= fOriginX
* aSnapRect
.GetWidth();
526 fOriginY
= fOriginY
* aSnapRect
.GetHeight();
528 basegfx::B3DHomMatrix
aNewTransform( pScene
->GetTransform() );
529 aNewTransform
.translate( -aCenter
.X(), aCenter
.Y(), -pScene
->GetBoundVolume().getDepth() );
531 double fXRotate
, fYRotate
;
532 GetRotateAngle( rGeometryItem
, fXRotate
, fYRotate
);
533 double fZRotate
= ((SdrObjCustomShape
*)pCustomShape
)->GetObjectRotation() * F_PI180
;
534 if ( fZRotate
!= 0.0 )
535 aNewTransform
.rotate( 0.0, 0.0, fZRotate
);
537 aNewTransform
.scale( -1.0, 1, 1 );
539 aNewTransform
.scale( 1, -1.0, 1 );
540 if( fYRotate
!= 0.0 )
541 aNewTransform
.rotate( 0.0, -fYRotate
, 0.0 );
542 if( fXRotate
!= 0.0 )
543 aNewTransform
.rotate( -fXRotate
, 0.0, 0.0 );
544 if ( eProjectionType
== PR_PARALLEL
)
546 double fSkew
, fAlpha
;
547 GetSkew( rGeometryItem
, fSkew
, fAlpha
);
550 double fInvTanBeta( fSkew
/ 100.0 );
553 aNewTransform
.shearXY(
554 fInvTanBeta
* cos(fAlpha
),
555 fInvTanBeta
* sin(fAlpha
));
558 basegfx::B3DPoint
_aLookAt( 0.0, 0.0, 0.0 );
559 basegfx::B3DPoint
_aNewCamPos( 0.0, 0.0, 25000.0 );
560 rCamera
.SetPosAndLookAt( _aNewCamPos
, _aLookAt
);
561 pScene
->SetCamera( rCamera
);
565 aNewTransform
.translate( -fOriginX
, fOriginY
, 0.0 );
566 // now set correct camera position
567 const rtl::OUString
sViewPoint( RTL_CONSTASCII_USTRINGPARAM ( "ViewPoint" ) );
568 drawing::Position3D
aViewPointDefault( 3472, -3472, 25000 );
569 drawing::Position3D
aViewPoint( GetPosition3D( rGeometryItem
, sViewPoint
, aViewPointDefault
, pMap
) );
570 double fViewPointX
= aViewPoint
.PositionX
;
571 double fViewPointY
= aViewPoint
.PositionY
;
572 double fViewPointZ
= aViewPoint
.PositionZ
;
573 basegfx::B3DPoint
_aLookAt( fViewPointX
, -fViewPointY
, 0.0 );
574 basegfx::B3DPoint
aNewCamPos( fViewPointX
, -fViewPointY
, fViewPointZ
);
575 rCamera
.SetPosAndLookAt( aNewCamPos
, _aLookAt
);
576 pScene
->SetCamera( rCamera
);
579 pScene
->NbcSetTransform( aNewTransform
);
585 const rtl::OUString
sBrightness( RTL_CONSTASCII_USTRINGPARAM ( "Brightness" ) );
586 double fAmbientIntensity
= GetDouble( rGeometryItem
, sBrightness
, 22178.0 / 655.36, NULL
) / 100.0;
589 const rtl::OUString
sFirstLightDirection( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightDirection" ) );
590 drawing::Direction3D
aFirstLightDirectionDefault( 50000, 0, 10000 );
591 drawing::Direction3D
aFirstLightDirection( GetDirection3D( rGeometryItem
, sFirstLightDirection
, aFirstLightDirectionDefault
) );
592 if ( aFirstLightDirection
.DirectionZ
== 0.0 )
593 aFirstLightDirection
.DirectionZ
= 1.0;
595 const rtl::OUString
sFirstLightLevel( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightLevel" ) );
596 double fLightIntensity
= GetDouble( rGeometryItem
, sFirstLightLevel
, 43712.0 / 655.36, NULL
) / 100.0;
598 const rtl::OUString
sFirstLightHarsh( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightHarsh" ) );
599 /* sal_Bool bFirstLightHarsh = */ GetBool( rGeometryItem
, sFirstLightHarsh
, sal_False
);
601 const rtl::OUString
sSecondLightDirection( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightDirection" ) );
602 drawing::Direction3D
aSecondLightDirectionDefault( -50000, 0, 10000 );
603 drawing::Direction3D
aSecondLightDirection( GetDirection3D( rGeometryItem
, sSecondLightDirection
, aSecondLightDirectionDefault
) );
604 if ( aSecondLightDirection
.DirectionZ
== 0.0 )
605 aSecondLightDirection
.DirectionZ
= -1;
607 const rtl::OUString
sSecondLightLevel( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightLevel" ) );
608 double fLight2Intensity
= GetDouble( rGeometryItem
, sSecondLightLevel
, 43712.0 / 655.36, NULL
) / 100.0;
610 const rtl::OUString
sSecondLightHarsh( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightHarsh" ) );
611 const rtl::OUString
sLightFace( RTL_CONSTASCII_USTRINGPARAM ( "LightFace" ) );
612 /* sal_Bool bLight2Harsh = */ GetBool( rGeometryItem
, sSecondLightHarsh
, sal_False
);
613 /* sal_Bool bLightFace = */ GetBool( rGeometryItem
, sLightFace
, sal_False
);
615 sal_uInt16 nAmbientColor
= (sal_uInt16
)( fAmbientIntensity
* 255.0 );
616 if ( nAmbientColor
> 255 )
618 Color
aGlobalAmbientColor( (sal_uInt8
)nAmbientColor
, (sal_uInt8
)nAmbientColor
, (sal_uInt8
)nAmbientColor
);
619 pScene
->GetProperties().SetObjectItem( Svx3DAmbientcolorItem( aGlobalAmbientColor
) );
621 sal_uInt8 nSpotLight1
= (sal_uInt8
)( fLightIntensity
* 255.0 );
622 basegfx::B3DVector
aSpotLight1( aFirstLightDirection
.DirectionX
, - ( aFirstLightDirection
.DirectionY
), -( aFirstLightDirection
.DirectionZ
) );
623 aSpotLight1
.normalize();
624 pScene
->GetProperties().SetObjectItem( Svx3DLightOnOff1Item( sal_True
) );
625 Color
aAmbientSpot1Color( nSpotLight1
, nSpotLight1
, nSpotLight1
);
626 pScene
->GetProperties().SetObjectItem( Svx3DLightcolor1Item( aAmbientSpot1Color
) );
627 pScene
->GetProperties().SetObjectItem( Svx3DLightDirection1Item( aSpotLight1
) );
629 sal_uInt8 nSpotLight2
= (sal_uInt8
)( fLight2Intensity
* 255.0 );
630 basegfx::B3DVector
aSpotLight2( aSecondLightDirection
.DirectionX
, -aSecondLightDirection
.DirectionY
, -aSecondLightDirection
.DirectionZ
);
631 aSpotLight2
.normalize();
632 pScene
->GetProperties().SetObjectItem( Svx3DLightOnOff2Item( sal_True
) );
633 Color
aAmbientSpot2Color( nSpotLight2
, nSpotLight2
, nSpotLight2
);
634 pScene
->GetProperties().SetObjectItem( Svx3DLightcolor2Item( aAmbientSpot2Color
) );
635 pScene
->GetProperties().SetObjectItem( Svx3DLightDirection2Item( aSpotLight2
) );
637 sal_uInt8 nSpotLight3
= 70;
638 basegfx::B3DVector
aSpotLight3( 0.0, 0.0, 1.0 );
639 pScene
->GetProperties().SetObjectItem( Svx3DLightOnOff3Item( sal_True
) );
640 Color
aAmbientSpot3Color( nSpotLight3
, nSpotLight3
, nSpotLight3
);
641 pScene
->GetProperties().SetObjectItem( Svx3DLightcolor3Item( aAmbientSpot3Color
) );
642 pScene
->GetProperties().SetObjectItem( Svx3DLightDirection3Item( aSpotLight3
) );
644 const rtl::OUString
sSpecularity( RTL_CONSTASCII_USTRINGPARAM ( "Specularity" ) );
645 const rtl::OUString
sDiffusion( RTL_CONSTASCII_USTRINGPARAM ( "Diffusion" ) );
646 const rtl::OUString
sShininess( RTL_CONSTASCII_USTRINGPARAM ( "Shininess" ) );
647 const rtl::OUString
sMetal( RTL_CONSTASCII_USTRINGPARAM ( "Metal" ) );
648 double fSpecular
= GetDouble( rGeometryItem
, sSpecularity
, 0, NULL
) / 100;
649 sal_Bool bMetal
= GetBool( rGeometryItem
, sMetal
, sal_False
);
651 Color
aSpecularCol( 225,225,225 );
654 aSpecularCol
= Color( 200, 200, 200 );
657 sal_Int32 nIntensity
= (sal_Int32
)fSpecular
* 100;
658 if ( nIntensity
> 100 )
660 else if ( nIntensity
< 0 )
662 nIntensity
= 100 - nIntensity
;
663 pScene
->GetProperties().SetObjectItem( Svx3DMaterialSpecularItem( aSpecularCol
) );
664 pScene
->GetProperties().SetObjectItem( Svx3DMaterialSpecularIntensityItem( (sal_uInt16
)nIntensity
) );
666 pScene
->SetLogicRect( CalculateNewSnapRect( pCustomShape
, aSnapRect
, aBoundRect2d
, pMap
) );
668 // removing placeholder objects
669 std::vector
< E3dCompoundObject
* >::iterator
aObjectListIter( aPlaceholderObjectList
.begin() );
670 while ( aObjectListIter
!= aPlaceholderObjectList
.end() )
672 pScene
->Remove3DObj( *aObjectListIter
);
673 delete *aObjectListIter
++;
682 Rectangle
EnhancedCustomShape3d::CalculateNewSnapRect( const SdrObject
* pCustomShape
, const Rectangle
& rSnapRect
, const Rectangle
& rBoundRect
, const double* pMap
)
684 SdrCustomShapeGeometryItem
& rGeometryItem
= (SdrCustomShapeGeometryItem
&)pCustomShape
->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY
);
685 const Point
aCenter( rSnapRect
.Center() );
686 double fExtrusionBackward
, fExtrusionForward
;
687 GetExtrusionDepth( rGeometryItem
, pMap
, fExtrusionBackward
, fExtrusionForward
);
690 // creating initial bound volume ( without rotation. skewing.and camera )
691 basegfx::B3DPolygon aBoundVolume
;
692 const Polygon
aPolygon( rBoundRect
);
694 for ( i
= 0L; i
< 4L; i
++ )
696 aBoundVolume
.append(basegfx::B3DPoint(aPolygon
[ (sal_uInt16
)i
].X() - aCenter
.X(), aPolygon
[ (sal_uInt16
)i
].Y() - aCenter
.Y(), fExtrusionForward
));
699 for ( i
= 0L; i
< 4L; i
++ )
701 aBoundVolume
.append(basegfx::B3DPoint(aPolygon
[ (sal_uInt16
)i
].X() - aCenter
.X(), aPolygon
[ (sal_uInt16
)i
].Y() - aCenter
.Y(), fExtrusionBackward
));
704 const rtl::OUString
sRotationCenter( RTL_CONSTASCII_USTRINGPARAM ( "RotationCenter" ) );
705 drawing::Direction3D
aRotationCenterDefault( 0, 0, 0 ); // default seems to be wrong, a fractional size of shape has to be used!!
706 drawing::Direction3D
aRotationCenter( GetDirection3D( rGeometryItem
, sRotationCenter
, aRotationCenterDefault
) );
708 // double XCenterInGUnits = rPropSet.GetPropertyValue( DFF_Prop_c3DRotationCenterX, 0 );
709 // double YCenterInGUnits = rPropSet.GetPropertyValue( DFF_Prop_c3DRotationCenterY, 0 );
711 // sal_Int32 nRotationXAxisInProz = rPropSet.GetPropertyValue( DFF_Prop_c3DRotationAxisX, 100 );
712 // sal_Int32 nRotationYAxisInProz = rPropSet.GetPropertyValue( DFF_Prop_c3DRotationAxisY, 0 );
713 // sal_Int32 nRotationZAxisInProz = rPropSet.GetPropertyValue( DFF_Prop_c3DRotationAxisZ, 0 );
716 double fXRotate
, fYRotate
;
717 GetRotateAngle( rGeometryItem
, fXRotate
, fYRotate
);
718 double fZRotate
= - ((SdrObjCustomShape
*)pCustomShape
)->GetObjectRotation() * F_PI180
;
720 // rotating bound volume
721 basegfx::B3DHomMatrix aMatrix
;
722 aMatrix
.translate(-aRotationCenter
.DirectionX
, -aRotationCenter
.DirectionY
, -aRotationCenter
.DirectionZ
);
723 if ( fZRotate
!= 0.0 )
724 aMatrix
.rotate( 0.0, 0.0, fZRotate
);
725 if ( ((SdrObjCustomShape
*)pCustomShape
)->IsMirroredX() )
726 aMatrix
.scale( -1.0, 1, 1 );
727 if ( ((SdrObjCustomShape
*)pCustomShape
)->IsMirroredY() )
728 aMatrix
.scale( 1, -1.0, 1 );
729 if( fYRotate
!= 0.0 )
730 aMatrix
.rotate( 0.0, fYRotate
, 0.0 );
731 if( fXRotate
!= 0.0 )
732 aMatrix
.rotate( -fXRotate
, 0.0, 0.0 );
733 aMatrix
.translate(aRotationCenter
.DirectionX
, aRotationCenter
.DirectionY
, aRotationCenter
.DirectionZ
);
734 aBoundVolume
.transform(aMatrix
);
736 Transformation2D
aTransformation2D( pCustomShape
, rSnapRect
, pMap
);
737 if ( aTransformation2D
.IsParallel() )
738 aBoundVolume
= aTransformation2D
.ApplySkewSettings( aBoundVolume
);
740 Polygon
aTransformed( 8 );
741 for ( i
= 0L; i
< 8L; i
++ )
742 aTransformed
[ (sal_uInt16
)i
] = aTransformation2D
.Transform2D( aBoundVolume
.getB3DPoint( i
) );
744 return aTransformed
.GetBoundRect();