LibreOffice Module xmloff (master) 1
ximp3dscene.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
21#include <rtl/math.hxx>
22#include <sal/log.hxx>
23
24#include "ximp3dscene.hxx"
25#include <xmloff/xmluconv.hxx>
26#include <xexptran.hxx>
27#include <xmloff/xmltoken.hxx>
29#include <com/sun/star/beans/XPropertySet.hpp>
30#include <com/sun/star/drawing/Direction3D.hpp>
31#include <com/sun/star/drawing/CameraGeometry.hpp>
32#include "eventimp.hxx"
33#include "descriptionimp.hxx"
34
35using namespace ::com::sun::star;
36using namespace ::xmloff::token;
37
38// dr3d:3dlight context
39
41 SvXMLImport& rImport,
42 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
43: SvXMLImportContext( rImport ),
44 maDiffuseColor(0x00000000),
45 maDirection(0.0, 0.0, 1.0),
46 mbEnabled(false),
47 mbSpecular(false)
48{
49 // read attributes for the 3DScene
50 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
51 {
52 switch(aIter.getToken())
53 {
55 {
57 break;
58 }
59 case XML_ELEMENT(DR3D, XML_DIRECTION):
60 {
62 SvXMLUnitConverter::convertB3DVector(aVal, aIter.toView());
63 if (!std::isnan(aVal.getX()) && !std::isnan(aVal.getY()) && !std::isnan(aVal.getZ()))
64 {
65 maDirection = aVal;
66 }
67 else
68 {
69 SAL_WARN("xmloff", "NaNs found in light direction: " << aIter.toString());
70 }
71 break;
72 }
73 case XML_ELEMENT(DR3D, XML_ENABLED):
74 {
75 (void)::sax::Converter::convertBool(mbEnabled, aIter.toView());
76 break;
77 }
78 case XML_ELEMENT(DR3D, XML_SPECULAR):
79 {
80 (void)::sax::Converter::convertBool(mbSpecular, aIter.toView());
81 break;
82 }
83 default:
84 XMLOFF_WARN_UNKNOWN("xmloff", aIter);
85 }
86 }
87}
88
90{
91}
92
93
95 SvXMLImport& rImport,
96 const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
97 uno::Reference< drawing::XShapes > const & rShapes,
98 bool bTemporaryShapes)
99: SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShapes ), SdXML3DSceneAttributesHelper( rImport )
100{
101}
102
104{
105}
106
108 sal_Int32 nElement,
109 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
110{
111 // create new 3DScene shape and add it to rShapes, use it
112 // as base for the new 3DScene import
113 AddShape( "com.sun.star.drawing.Shape3DSceneObject" );
114 if( mxShape.is() )
115 {
116 SetStyle();
117
118 mxChildren.set( mxShape, uno::UNO_QUERY );
119 if( mxChildren.is() )
120 GetImport().GetShapeImport()->pushGroupForPostProcessing( mxChildren );
121
122 SetLayer();
123
124 // set pos, size, shear and rotate
126 }
127
128 // read attributes for the 3DScene
129 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
130 processSceneAttribute( aIter );
131
132 // #91047# call parent function is missing here, added it
133 if(mxShape.is())
134 {
135 // call parent
136 SdXMLShapeContext::startFastElement(nElement, xAttrList);
137 }
138}
139
141{
142 if(!mxShape.is())
143 return;
144
145 uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
146 if(xPropSet.is())
147 {
148 setSceneAttributes( xPropSet );
149 }
150
151 if( mxChildren.is() )
152 GetImport().GetShapeImport()->popGroupAndPostProcess();
153
154 // call parent
156}
157
158css::uno::Reference< css::xml::sax::XFastContextHandler > SdXML3DSceneShapeContext::createFastChildContext(
159 sal_Int32 nElement,
160 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
161{
162 SvXMLImportContextRef xContext;
163 switch (nElement)
164 {
165 // #i68101#
167 case XML_ELEMENT(SVG_COMPAT, XML_TITLE):
168 case XML_ELEMENT(SVG, XML_DESC):
169 case XML_ELEMENT(SVG_COMPAT, XML_DESC):
170 xContext = new SdXMLDescriptionContext( GetImport(), nElement, mxShape );
171 break;
173 xContext = new SdXMLEventsContext( GetImport(), mxShape );
174 break;
175 // look for local light context first
176 case XML_ELEMENT(DR3D, XML_LIGHT):
177 // dr3d:light inside dr3d:scene context
178 xContext = create3DLightContext( xAttrList );
179 break;
180 default:
181 // call GroupChildContext function at common ShapeImport
183 GetImport(), nElement, xAttrList, mxChildren);
184 }
185 return xContext;
186}
187
189: mrImport( rImporter ),
190 mbSetTransform( false ),
191 mxPrjMode(drawing::ProjectionMode_PERSPECTIVE),
192 mnDistance(1000),
193 mnFocalLength(1000),
194 mnShadowSlant(0),
195 mxShadeMode(drawing::ShadeMode_SMOOTH),
196 maAmbientColor(0x00666666),
197 mbLightingMode(false),
198 maVRP(0.0, 0.0, 1.0),
199 maVPN(0.0, 0.0, 1.0),
200 maVUP(0.0, 1.0, 0.0),
201 mbVRPUsed(false)
202{
203}
204
206SvXMLImportContext * SdXML3DSceneAttributesHelper::create3DLightContext( const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
207{
209
210 // remember SdXML3DLightContext for later evaluation
211 maList.push_back(xContext);
212
213 return xContext.get();
214}
215
218{
219 auto nAttributeToken = aIter.getToken();
220 if( !IsTokenInNamespace(nAttributeToken, XML_NAMESPACE_DR3D) )
221 return;
222
223 switch(nAttributeToken & TOKEN_MASK)
224 {
225 case XML_TRANSFORM:
226 {
227 SdXMLImExTransform3D aTransform(aIter.toString(), mrImport.GetMM100UnitConverter());
228 if(aTransform.NeedsAction())
230 return;
231 }
232 case XML_VRP:
233 {
234 ::basegfx::B3DVector aNewVec;
236
237 if(aNewVec != maVRP)
238 {
239 maVRP = aNewVec;
240 mbVRPUsed = true;
241 }
242 return;
243 }
244 case XML_VPN:
245 {
246 ::basegfx::B3DVector aNewVec;
248
249 if(aNewVec != maVPN)
250 {
251 maVPN = aNewVec;
252 }
253 return;
254 }
255 case XML_VUP:
256 {
257 ::basegfx::B3DVector aNewVec;
259
260 if(aNewVec != maVUP)
261 {
262 maVUP = aNewVec;
263 }
264 return;
265 }
266 case XML_PROJECTION:
267 {
268 if( IsXMLToken( aIter, XML_PARALLEL ) )
269 mxPrjMode = drawing::ProjectionMode_PARALLEL;
270 else
271 mxPrjMode = drawing::ProjectionMode_PERSPECTIVE;
272 return;
273 }
274 case XML_DISTANCE:
275 {
276 mrImport.GetMM100UnitConverter().convertMeasureToCore(mnDistance,
277 aIter.toView());
278 return;
279 }
280 case XML_FOCAL_LENGTH:
281 {
282 mrImport.GetMM100UnitConverter().convertMeasureToCore(mnFocalLength,
283 aIter.toView());
284 return;
285 }
286 case XML_SHADOW_SLANT:
287 {
289 return;
290 }
291 case XML_SHADE_MODE:
292 {
293 if( IsXMLToken( aIter, XML_FLAT ) )
294 mxShadeMode = drawing::ShadeMode_FLAT;
295 else if( IsXMLToken( aIter, XML_PHONG ) )
296 mxShadeMode = drawing::ShadeMode_PHONG;
297 else if( IsXMLToken( aIter, XML_GOURAUD ) )
298 mxShadeMode = drawing::ShadeMode_SMOOTH;
299 else
300 mxShadeMode = drawing::ShadeMode_DRAFT;
301 return;
302 }
304 {
306 return;
307 }
309 {
311 return;
312 }
313 default:
314 XMLOFF_WARN_UNKNOWN("xmloff", aIter);
315 }
316}
317
319void SdXML3DSceneAttributesHelper::setSceneAttributes( const css::uno::Reference< css::beans::XPropertySet >& xPropSet )
320{
321 uno::Any aAny;
322
323 // world transformation
325 {
326 xPropSet->setPropertyValue("D3DTransformMatrix", uno::Any(mxHomMat));
327 }
328
329 // distance
330 xPropSet->setPropertyValue("D3DSceneDistance", uno::Any(mnDistance));
331 // focalLength
332 xPropSet->setPropertyValue("D3DSceneFocalLength", uno::Any(mnFocalLength));
333 // shadowSlant
334 xPropSet->setPropertyValue("D3DSceneShadowSlant", uno::Any(static_cast<sal_Int16>(mnShadowSlant)));
335 // shadeMode
336 xPropSet->setPropertyValue("D3DSceneShadeMode", uno::Any(mxShadeMode));
337 // ambientColor
338 xPropSet->setPropertyValue("D3DSceneAmbientColor", uno::Any(maAmbientColor));
339 // lightingMode
340 xPropSet->setPropertyValue("D3DSceneTwoSidedLighting", uno::Any(mbLightingMode));
341
342 if( !maList.empty() )
343 {
344 uno::Any aAny2;
345 uno::Any aAny3;
346
347 // set lights
348 for( size_t a = 0; a < maList.size(); a++)
349 {
350 SdXML3DLightContext* pCtx = maList[ a ].get();
351
352 // set anys
353 aAny <<= pCtx->GetDiffuseColor();
354 drawing::Direction3D aLightDir;
355 aLightDir.DirectionX = pCtx->GetDirection().getX();
356 aLightDir.DirectionY = pCtx->GetDirection().getY();
357 aLightDir.DirectionZ = pCtx->GetDirection().getZ();
358 aAny2 <<= aLightDir;
359 aAny3 <<= pCtx->GetEnabled();
360
361 switch(a)
362 {
363 case 0:
364 {
365 xPropSet->setPropertyValue("D3DSceneLightColor1", aAny);
366 xPropSet->setPropertyValue("D3DSceneLightDirection1", aAny2);
367 xPropSet->setPropertyValue("D3DSceneLightOn1", aAny3);
368 break;
369 }
370 case 1:
371 {
372 xPropSet->setPropertyValue("D3DSceneLightColor2", aAny);
373 xPropSet->setPropertyValue("D3DSceneLightDirection2", aAny2);
374 xPropSet->setPropertyValue("D3DSceneLightOn2", aAny3);
375 break;
376 }
377 case 2:
378 {
379 xPropSet->setPropertyValue("D3DSceneLightColor3", aAny);
380 xPropSet->setPropertyValue("D3DSceneLightDirection3", aAny2);
381 xPropSet->setPropertyValue("D3DSceneLightOn3", aAny3);
382 break;
383 }
384 case 3:
385 {
386 xPropSet->setPropertyValue("D3DSceneLightColor4", aAny);
387 xPropSet->setPropertyValue("D3DSceneLightDirection4", aAny2);
388 xPropSet->setPropertyValue("D3DSceneLightOn4", aAny3);
389 break;
390 }
391 case 4:
392 {
393 xPropSet->setPropertyValue("D3DSceneLightColor5", aAny);
394 xPropSet->setPropertyValue("D3DSceneLightDirection5", aAny2);
395 xPropSet->setPropertyValue("D3DSceneLightOn5", aAny3);
396 break;
397 }
398 case 5:
399 {
400 xPropSet->setPropertyValue("D3DSceneLightColor6", aAny);
401 xPropSet->setPropertyValue("D3DSceneLightDirection6", aAny2);
402 xPropSet->setPropertyValue("D3DSceneLightOn6", aAny3);
403 break;
404 }
405 case 6:
406 {
407 xPropSet->setPropertyValue("D3DSceneLightColor7", aAny);
408 xPropSet->setPropertyValue("D3DSceneLightDirection7", aAny2);
409 xPropSet->setPropertyValue("D3DSceneLightOn7", aAny3);
410 break;
411 }
412 case 7:
413 {
414 xPropSet->setPropertyValue("D3DSceneLightColor8", aAny);
415 xPropSet->setPropertyValue("D3DSceneLightDirection8", aAny2);
416 xPropSet->setPropertyValue("D3DSceneLightOn8", aAny3);
417 break;
418 }
419 }
420 }
421 }
422
423 // CameraGeometry and camera settings
424 drawing::CameraGeometry aCamGeo;
425 aCamGeo.vrp.PositionX = maVRP.getX();
426 aCamGeo.vrp.PositionY = maVRP.getY();
427 aCamGeo.vrp.PositionZ = maVRP.getZ();
428 aCamGeo.vpn.DirectionX = maVPN.getX();
429 aCamGeo.vpn.DirectionY = maVPN.getY();
430 aCamGeo.vpn.DirectionZ = maVPN.getZ();
431 aCamGeo.vup.DirectionX = maVUP.getX();
432 aCamGeo.vup.DirectionY = maVUP.getY();
433 aCamGeo.vup.DirectionZ = maVUP.getZ();
434 xPropSet->setPropertyValue("D3DCameraGeometry", uno::Any(aCamGeo));
435
436 // #91047# set drawing::ProjectionMode AFTER camera geometry is set
437 // projection "D3DScenePerspective" drawing::ProjectionMode
438 xPropSet->setPropertyValue("D3DScenePerspective", uno::Any(mxPrjMode));
439}
440
441/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SdXML3DLightContext(SvXMLImport &rImport, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
Definition: ximp3dscene.cxx:40
sal_Int32 maDiffuseColor
Definition: shapeimport.hxx:54
::basegfx::B3DVector maDirection
Definition: shapeimport.hxx:55
virtual ~SdXML3DLightContext() override
Definition: ximp3dscene.cxx:89
const ::basegfx::B3DVector & GetDirection() const
Definition: shapeimport.hxx:66
sal_Int32 GetDiffuseColor() const
Definition: shapeimport.hxx:65
bool GetEnabled() const
Definition: shapeimport.hxx:67
void processSceneAttribute(const sax_fastparser::FastAttributeList::FastAttributeIter &aIter)
this should be called for each scene attribute
void setSceneAttributes(const css::uno::Reference< css::beans::XPropertySet > &xPropSet)
this sets the scene attributes at this propertyset
css::drawing::ShadeMode mxShadeMode
Definition: shapeimport.hxx:88
SdXML3DSceneAttributesHelper(SvXMLImport &rImporter)
::basegfx::B3DVector maVRP
Definition: shapeimport.hxx:92
css::drawing::ProjectionMode mxPrjMode
Definition: shapeimport.hxx:84
SvXMLImportContext * create3DLightContext(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
creates a 3d light context and adds it to the internal list for later processing
css::drawing::HomogenMatrix mxHomMat
Definition: shapeimport.hxx:81
::std::vector< rtl::Reference< SdXML3DLightContext > > maList
Definition: shapeimport.hxx:78
::basegfx::B3DVector maVUP
Definition: shapeimport.hxx:94
::basegfx::B3DVector maVPN
Definition: shapeimport.hxx:93
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override
endFastElement is called before a context will be destructed, but after an elements context has been ...
virtual ~SdXML3DSceneShapeContext() override
SdXML3DSceneShapeContext(SvXMLImport &rImport, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList, css::uno::Reference< css::drawing::XShapes > const &rShapes, bool bTemporaryShape)
Definition: ximp3dscene.cxx:94
css::uno::Reference< css::drawing::XShapes > mxChildren
Definition: ximp3dscene.hxx:32
virtual void SAL_CALL startFastElement(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList) override
virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &AttrList) override
bool GetFullHomogenTransform(css::drawing::HomogenMatrix &xHomMat)
Definition: xexptran.cxx:920
bool NeedsAction() const
Definition: xexptran.hxx:75
virtual void SAL_CALL startFastElement(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList) override
Definition: ximpshap.cxx:323
void AddShape(css::uno::Reference< css::drawing::XShape > &xShape)
void SetTransformation()
Definition: ximpshap.cxx:522
SvXMLImport & GetImport()
Definition: xmlictxt.hxx:60
void SetStyle(bool bSupportsStyle=true)
if bSupportsStyle is false, auto styles will be set but not a style
Definition: ximpshap.cxx:600
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override
endFastElement is called before a context will be destructed, but after an elements context has been ...
Definition: ximpshap.cxx:329
This class deliberately does not support XWeak, to improve performance when loading large documents.
Definition: xmlictxt.hxx:48
css::uno::Reference< css::drawing::XShape > mxShape
static bool convertB3DVector(::basegfx::B3DVector &rVector, std::string_view rValue)
convert string to basegfx::B3DVector
Definition: xmluconv.cxx:588
static SvXMLShapeContext * Create3DSceneChildContext(SvXMLImport &rImport, sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList, css::uno::Reference< css::drawing::XShapes > const &rShapes)
TYPE getX() const
TYPE getZ() const
TYPE getY() const
static bool convertColor(sal_Int32 &rColor, std::u16string_view rValue)
static bool convertNumber(sal_Int32 &rValue, std::u16string_view aString, sal_Int32 nMin=SAL_MIN_INT32, sal_Int32 nMax=SAL_MAX_INT32)
static bool convertBool(bool &rBool, std::u16string_view rString)
uno_Any a
#define SAL_WARN(area, stream)
FastAttributeList & castToFastAttributeList(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
Handling of tokens in XML:
bool IsXMLToken(std::u16string_view rString, enum XMLTokenEnum eToken)
compare eToken to the string
Definition: xmltoken.cxx:3597
#define XMLOFF_WARN_UNKNOWN(area, rIter)
Definition: xmlictxt.hxx:114
#define XML_ELEMENT(prefix, name)
Definition: xmlimp.hxx:97
constexpr bool IsTokenInNamespace(sal_Int32 nToken, sal_uInt16 nNamespacePrefix)
Definition: xmlimp.hxx:104
constexpr sal_Int32 TOKEN_MASK
Definition: xmlimp.hxx:94
constexpr sal_uInt16 XML_NAMESPACE_DR3D