xref: /AOO41X/main/xmloff/source/draw/ximp3dscene.cxx (revision 63bba73cc51e0afb45f8a8d578158724bb5afee8)
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_xmloff.hxx"
26 #include "ximp3dscene.hxx"
27 #include <xmloff/xmluconv.hxx>
28 #include "xexptran.hxx"
29 #include <xmloff/xmltoken.hxx>
30 #include "xmloff/xmlnmspe.hxx"
31 #include <com/sun/star/drawing/Direction3D.hpp>
32 #include <com/sun/star/drawing/CameraGeometry.hpp>
33 #include "eventimp.hxx"
34 #include "descriptionimp.hxx"
35 
36 using ::rtl::OUString;
37 using ::rtl::OUStringBuffer;
38 
39 using namespace ::com::sun::star;
40 using namespace ::xmloff::token;
41 
42 //////////////////////////////////////////////////////////////////////////////
43 // dr3d:3dlight context
44 
SdXML3DLightContext(SvXMLImport & rImport,sal_uInt16 nPrfx,const rtl::OUString & rLName,const com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList> & xAttrList)45 SdXML3DLightContext::SdXML3DLightContext(
46     SvXMLImport& rImport,
47     sal_uInt16 nPrfx,
48     const rtl::OUString& rLName,
49     const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttrList)
50 :   SvXMLImportContext( rImport, nPrfx, rLName),
51     maDiffuseColor(0x00000000),
52     maDirection(0.0, 0.0, 1.0),
53     mbEnabled(sal_False),
54     mbSpecular(sal_False)
55 {
56     // read attributes for the 3DScene
57     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
58     for(sal_Int16 i=0; i < nAttrCount; i++)
59     {
60         OUString sAttrName = xAttrList->getNameByIndex( i );
61         OUString aLocalName;
62         sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
63         OUString sValue = xAttrList->getValueByIndex( i );
64         const SvXMLTokenMap& rAttrTokenMap = GetImport().GetShapeImport()->Get3DLightAttrTokenMap();
65 
66         switch(rAttrTokenMap.Get(nPrefix, aLocalName))
67         {
68             case XML_TOK_3DLIGHT_DIFFUSE_COLOR:
69             {
70                 GetImport().GetMM100UnitConverter().convertColor(maDiffuseColor, sValue);
71                 break;
72             }
73             case XML_TOK_3DLIGHT_DIRECTION:
74             {
75                 GetImport().GetMM100UnitConverter().convertB3DVector(maDirection, sValue);
76                 break;
77             }
78             case XML_TOK_3DLIGHT_ENABLED:
79             {
80                 GetImport().GetMM100UnitConverter().convertBool(mbEnabled, sValue);
81                 break;
82             }
83             case XML_TOK_3DLIGHT_SPECULAR:
84             {
85                 GetImport().GetMM100UnitConverter().convertBool(mbSpecular, sValue);
86                 break;
87             }
88         }
89     }
90 }
91 
~SdXML3DLightContext()92 SdXML3DLightContext::~SdXML3DLightContext()
93 {
94 }
95 
96 //////////////////////////////////////////////////////////////////////////////
97 
98 TYPEINIT1( SdXML3DSceneShapeContext, SdXMLShapeContext );
99 
SdXML3DSceneShapeContext(SvXMLImport & rImport,sal_uInt16 nPrfx,const OUString & rLocalName,const com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList> & xAttrList,uno::Reference<drawing::XShapes> & rShapes,sal_Bool bTemporaryShapes)100 SdXML3DSceneShapeContext::SdXML3DSceneShapeContext(
101     SvXMLImport& rImport,
102     sal_uInt16 nPrfx,
103     const OUString& rLocalName,
104     const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList,
105     uno::Reference< drawing::XShapes >& rShapes,
106     sal_Bool bTemporaryShapes)
107 :   SdXMLShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShapes ), SdXML3DSceneAttributesHelper( rImport )
108 {
109 }
110 
111 //////////////////////////////////////////////////////////////////////////////
112 
~SdXML3DSceneShapeContext()113 SdXML3DSceneShapeContext::~SdXML3DSceneShapeContext()
114 {
115 }
116 
117 //////////////////////////////////////////////////////////////////////////////
118 
StartElement(const uno::Reference<xml::sax::XAttributeList> & xAttrList)119 void SdXML3DSceneShapeContext::StartElement(const uno::Reference< xml::sax::XAttributeList>& xAttrList)
120 {
121     // create new 3DScene shape and add it to rShapes, use it
122     // as base for the new 3DScene import
123     AddShape( "com.sun.star.drawing.Shape3DSceneObject" );
124     if( mxShape.is() )
125     {
126         SetStyle();
127 
128         mxChilds = uno::Reference< drawing::XShapes >::query( mxShape );
129         if( mxChilds.is() )
130             GetImport().GetShapeImport()->pushGroupForSorting( mxChilds );
131 
132         SetLayer();
133 
134         // set pos, size, shear and rotate
135         SetTransformation();
136     }
137 
138     // read attributes for the 3DScene
139     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
140     for(sal_Int16 i=0; i < nAttrCount; i++)
141     {
142         OUString sAttrName = xAttrList->getNameByIndex( i );
143         OUString aLocalName;
144         sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
145         OUString sValue = xAttrList->getValueByIndex( i );
146         processSceneAttribute( nPrefix, aLocalName, sValue );
147     }
148 
149     // #91047# call parent function is missing here, added it
150     if(mxShape.is())
151     {
152         // call parent
153         SdXMLShapeContext::StartElement(xAttrList);
154     }
155 }
156 
157 //////////////////////////////////////////////////////////////////////////////
158 
EndElement()159 void SdXML3DSceneShapeContext::EndElement()
160 {
161     if(mxShape.is())
162     {
163         uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
164         if(xPropSet.is())
165         {
166             setSceneAttributes( xPropSet );
167         }
168 
169         if( mxChilds.is() )
170             GetImport().GetShapeImport()->popGroupAndSort();
171 
172         // call parent
173         SdXMLShapeContext::EndElement();
174     }
175 }
176 
177 //////////////////////////////////////////////////////////////////////////////
178 
CreateChildContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> & xAttrList)179 SvXMLImportContext* SdXML3DSceneShapeContext::CreateChildContext( sal_uInt16 nPrefix,
180     const OUString& rLocalName,
181     const uno::Reference< xml::sax::XAttributeList>& xAttrList )
182 {
183     SvXMLImportContext* pContext = 0L;
184 
185     // #i68101#
186     if( nPrefix == XML_NAMESPACE_SVG &&
187         (IsXMLToken( rLocalName, XML_TITLE ) || IsXMLToken( rLocalName, XML_DESC ) ) )
188     {
189         pContext = new SdXMLDescriptionContext( GetImport(), nPrefix, rLocalName, xAttrList, mxShape );
190     }
191     else if( nPrefix == XML_NAMESPACE_OFFICE && IsXMLToken( rLocalName, XML_EVENT_LISTENERS ) )
192     {
193         pContext = new SdXMLEventsContext( GetImport(), nPrefix, rLocalName, xAttrList, mxShape );
194     }
195     // look for local light context first
196     else if(nPrefix == XML_NAMESPACE_DR3D && IsXMLToken( rLocalName, XML_LIGHT ) )
197     {
198         // dr3d:light inside dr3d:scene context
199         pContext = create3DLightContext( nPrefix, rLocalName, xAttrList );
200     }
201 
202     // call GroupChildContext function at common ShapeImport
203     if(!pContext)
204     {
205         pContext = GetImport().GetShapeImport()->Create3DSceneChildContext(
206             GetImport(), nPrefix, rLocalName, xAttrList, mxChilds);
207         }
208 
209     // call parent when no own context was created
210     if(!pContext)
211     {
212         pContext = SvXMLImportContext::CreateChildContext(
213         nPrefix, rLocalName, xAttrList);
214     }
215 
216     return pContext;
217 }
218 
219 //////////////////////////////////////////////////////////////////////////////
220 
SdXML3DSceneAttributesHelper(SvXMLImport & rImporter)221 SdXML3DSceneAttributesHelper::SdXML3DSceneAttributesHelper( SvXMLImport& rImporter )
222 :   mrImport( rImporter ),
223     mbSetTransform( sal_False ),
224     mxPrjMode(drawing::ProjectionMode_PERSPECTIVE),
225     mnDistance(1000),
226     mnFocalLength(1000),
227     mnShadowSlant(0),
228     mxShadeMode(drawing::ShadeMode_SMOOTH),
229     maAmbientColor(0x00666666),
230     mbLightingMode(sal_False),
231     maVRP(0.0, 0.0, 1.0),
232     maVPN(0.0, 0.0, 1.0),
233     maVUP(0.0, 1.0, 0.0),
234     mbVRPUsed(sal_False),
235     mbVPNUsed(sal_False),
236     mbVUPUsed(sal_False)
237 {
238 }
239 
~SdXML3DSceneAttributesHelper()240 SdXML3DSceneAttributesHelper::~SdXML3DSceneAttributesHelper()
241 {
242     // release remembered light contexts, they are no longer needed
243     while(maList.Count())
244         maList.Remove(maList.Count() - 1)->ReleaseRef();
245 }
246 
247 /** creates a 3d ligth context and adds it to the internal list for later processing */
create3DLightContext(sal_uInt16 nPrfx,const rtl::OUString & rLName,const com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList> & xAttrList)248 SvXMLImportContext * SdXML3DSceneAttributesHelper::create3DLightContext( sal_uInt16 nPrfx, const rtl::OUString& rLName, const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttrList)
249 {
250     SvXMLImportContext* pContext = new SdXML3DLightContext(mrImport, nPrfx, rLName, xAttrList);
251 
252     // remember SdXML3DLightContext for later evaluation
253     if(pContext)
254     {
255         pContext->AddRef();
256         maList.Insert((SdXML3DLightContext*)pContext, LIST_APPEND);
257     }
258 
259     return pContext;
260 }
261 
262 /** this should be called for each scene attribute */
processSceneAttribute(sal_uInt16 nPrefix,const::rtl::OUString & rLocalName,const::rtl::OUString & rValue)263 void SdXML3DSceneAttributesHelper::processSceneAttribute( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, const ::rtl::OUString& rValue )
264 {
265     if( XML_NAMESPACE_DR3D == nPrefix )
266     {
267         if( IsXMLToken( rLocalName, XML_TRANSFORM ) )
268         {
269             SdXMLImExTransform3D aTransform(rValue, mrImport.GetMM100UnitConverter());
270             if(aTransform.NeedsAction())
271                 mbSetTransform = aTransform.GetFullHomogenTransform(mxHomMat);
272             return;
273         }
274         else if( IsXMLToken( rLocalName, XML_VRP ) )
275         {
276             ::basegfx::B3DVector aNewVec;
277             mrImport.GetMM100UnitConverter().convertB3DVector(aNewVec, rValue);
278 
279             if(aNewVec != maVRP)
280             {
281                 maVRP = aNewVec;
282                 mbVRPUsed = sal_True;
283             }
284             return;
285         }
286         else if( IsXMLToken( rLocalName, XML_VPN ) )
287         {
288             ::basegfx::B3DVector aNewVec;
289             mrImport.GetMM100UnitConverter().convertB3DVector(aNewVec, rValue);
290 
291             if(aNewVec != maVPN)
292             {
293                 maVPN = aNewVec;
294                 mbVPNUsed = sal_True;
295             }
296             return;
297         }
298         else if( IsXMLToken( rLocalName, XML_VUP ) )
299         {
300             ::basegfx::B3DVector aNewVec;
301             mrImport.GetMM100UnitConverter().convertB3DVector(aNewVec, rValue);
302 
303             if(aNewVec != maVUP)
304             {
305                 maVUP = aNewVec;
306                 mbVUPUsed = sal_True;
307             }
308             return;
309         }
310         else if( IsXMLToken( rLocalName, XML_PROJECTION ) )
311         {
312             if( IsXMLToken( rValue, XML_PARALLEL ) )
313                 mxPrjMode = drawing::ProjectionMode_PARALLEL;
314             else
315                 mxPrjMode = drawing::ProjectionMode_PERSPECTIVE;
316             return;
317         }
318         else if( IsXMLToken( rLocalName, XML_DISTANCE ) )
319         {
320             mrImport.GetMM100UnitConverter().convertMeasure(mnDistance, rValue);
321             return;
322         }
323         else if( IsXMLToken( rLocalName, XML_FOCAL_LENGTH ) )
324         {
325             mrImport.GetMM100UnitConverter().convertMeasure(mnFocalLength, rValue);
326             return;
327         }
328         else if( IsXMLToken( rLocalName, XML_SHADOW_SLANT ) )
329         {
330             mrImport.GetMM100UnitConverter().convertNumber(mnShadowSlant, rValue);
331             return;
332         }
333         else if( IsXMLToken( rLocalName, XML_SHADE_MODE ) )
334         {
335             if( IsXMLToken( rValue, XML_FLAT ) )
336                 mxShadeMode = drawing::ShadeMode_FLAT;
337             else if( IsXMLToken( rValue, XML_PHONG ) )
338                 mxShadeMode = drawing::ShadeMode_PHONG;
339             else if( IsXMLToken( rValue, XML_GOURAUD ) )
340                 mxShadeMode = drawing::ShadeMode_SMOOTH;
341             else
342                 mxShadeMode = drawing::ShadeMode_DRAFT;
343             return;
344         }
345         else if( IsXMLToken( rLocalName, XML_AMBIENT_COLOR ) )
346         {
347             mrImport.GetMM100UnitConverter().convertColor(maAmbientColor, rValue);
348             return;
349         }
350         else if( IsXMLToken( rLocalName, XML_LIGHTING_MODE ) )
351         {
352             mrImport.GetMM100UnitConverter().convertBool(mbLightingMode, rValue);
353             return;
354         }
355     }
356 }
357 
358 /** this sets the scene attributes at this propertyset */
setSceneAttributes(const com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet> & xPropSet)359 void SdXML3DSceneAttributesHelper::setSceneAttributes( const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xPropSet )
360 {
361     uno::Any aAny;
362 
363     // world transformation
364     if(mbSetTransform)
365     {
366         aAny <<= mxHomMat;
367         xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DTransformMatrix")), aAny);
368     }
369 
370     // distance
371     aAny <<= mnDistance;
372     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneDistance")), aAny);
373 
374     // focalLength
375     aAny <<= mnFocalLength;
376     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneFocalLength")), aAny);
377 
378     // shadowSlant
379     aAny <<= (sal_Int16)mnShadowSlant;
380     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneShadowSlant")), aAny);
381 
382     // shadeMode
383     aAny <<= mxShadeMode;
384     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneShadeMode")), aAny);
385 
386     // ambientColor
387     aAny <<= maAmbientColor.GetColor();
388     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneAmbientColor")), aAny);
389 
390     // lightingMode
391     aAny <<= mbLightingMode;
392     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneTwoSidedLighting")), aAny);
393 
394     if(maList.Count())
395     {
396         uno::Any aAny2;
397         uno::Any aAny3;
398 
399         // set lights
400         for(sal_uInt32 a(0L); a < maList.Count(); a++)
401         {
402             SdXML3DLightContext* pCtx = (SdXML3DLightContext*)maList.GetObject(a);
403 
404             // set anys
405             aAny <<= pCtx->GetDiffuseColor().GetColor();
406             drawing::Direction3D xLightDir;
407             xLightDir.DirectionX = pCtx->GetDirection().getX();
408             xLightDir.DirectionY = pCtx->GetDirection().getY();
409             xLightDir.DirectionZ = pCtx->GetDirection().getZ();
410             aAny2 <<= xLightDir;
411             aAny3 <<= pCtx->GetEnabled();
412 
413             switch(a)
414             {
415                 case 0:
416                 {
417                     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor1")), aAny);
418                     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection1")), aAny2);
419                     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn1")), aAny3);
420                     break;
421                 }
422                 case 1:
423                 {
424                     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor2")), aAny);
425                     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection2")), aAny2);
426                     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn2")), aAny3);
427                     break;
428                 }
429                 case 2:
430                 {
431                     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor3")), aAny);
432                     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection3")), aAny2);
433                     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn3")), aAny3);
434                     break;
435                 }
436                 case 3:
437                 {
438                     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor4")), aAny);
439                     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection4")), aAny2);
440                     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn4")), aAny3);
441                     break;
442                 }
443                 case 4:
444                 {
445                     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor5")), aAny);
446                     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection5")), aAny2);
447                     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn5")), aAny3);
448                     break;
449                 }
450                 case 5:
451                 {
452                     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor6")), aAny);
453                     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection6")), aAny2);
454                     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn6")), aAny3);
455                     break;
456                 }
457                 case 6:
458                 {
459                     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor7")), aAny);
460                     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection7")), aAny2);
461                     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn7")), aAny3);
462                     break;
463                 }
464                 case 7:
465                 {
466                     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor8")), aAny);
467                     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection8")), aAny2);
468                     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn8")), aAny3);
469                     break;
470                 }
471             }
472         }
473     }
474 
475     // CameraGeometry and camera settings
476     drawing::CameraGeometry aCamGeo;
477     aCamGeo.vrp.PositionX = maVRP.getX();
478     aCamGeo.vrp.PositionY = maVRP.getY();
479     aCamGeo.vrp.PositionZ = maVRP.getZ();
480     aCamGeo.vpn.DirectionX = maVPN.getX();
481     aCamGeo.vpn.DirectionY = maVPN.getY();
482     aCamGeo.vpn.DirectionZ = maVPN.getZ();
483     aCamGeo.vup.DirectionX = maVUP.getX();
484     aCamGeo.vup.DirectionY = maVUP.getY();
485     aCamGeo.vup.DirectionZ = maVUP.getZ();
486     aAny <<= aCamGeo;
487     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DCameraGeometry")), aAny);
488 
489     // #91047# set drawing::ProjectionMode AFTER camera geometry is set
490     // projection "D3DScenePerspective" drawing::ProjectionMode
491     aAny <<= mxPrjMode;
492     xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DScenePerspective")), aAny);
493 }
494