xref: /trunk/main/drawinglayer/source/processor3d/defaultprocessor3d.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
1464702f4SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3464702f4SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4464702f4SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5464702f4SAndrew Rist  * distributed with this work for additional information
6464702f4SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7464702f4SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8464702f4SAndrew Rist  * "License"); you may not use this file except in compliance
9464702f4SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11464702f4SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13464702f4SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14464702f4SAndrew Rist  * software distributed under the License is distributed on an
15464702f4SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16464702f4SAndrew Rist  * KIND, either express or implied.  See the License for the
17464702f4SAndrew Rist  * specific language governing permissions and limitations
18464702f4SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20464702f4SAndrew Rist  *************************************************************/
21464702f4SAndrew Rist 
22464702f4SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_drawinglayer.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <drawinglayer/processor3d/defaultprocessor3d.hxx>
28cdf0e10cSrcweir #include <drawinglayer/primitive3d/textureprimitive3d.hxx>
29cdf0e10cSrcweir #include <drawinglayer/texture/texture.hxx>
30cdf0e10cSrcweir #include <drawinglayer/texture/texture3d.hxx>
31cdf0e10cSrcweir #include <drawinglayer/primitive3d/hatchtextureprimitive3d.hxx>
32cdf0e10cSrcweir #include <drawinglayer/primitive3d/modifiedcolorprimitive3d.hxx>
33cdf0e10cSrcweir #include <drawinglayer/primitive3d/polygonprimitive3d.hxx>
34cdf0e10cSrcweir #include <basegfx/polygon/b3dpolygontools.hxx>
35cdf0e10cSrcweir #include <drawinglayer/attribute/materialattribute3d.hxx>
36cdf0e10cSrcweir #include <drawinglayer/primitive3d/polypolygonprimitive3d.hxx>
37cdf0e10cSrcweir #include <basegfx/polygon/b3dpolypolygontools.hxx>
38cdf0e10cSrcweir #include <com/sun/star/drawing/ShadeMode.hpp>
39cdf0e10cSrcweir #include <drawinglayer/primitive3d/transformprimitive3d.hxx>
40cdf0e10cSrcweir #include <drawinglayer/primitive3d/drawinglayer_primitivetypes3d.hxx>
41cdf0e10cSrcweir #include <vcl/bitmapex.hxx>
42cdf0e10cSrcweir #include <drawinglayer/attribute/sdrsceneattribute3d.hxx>
43cdf0e10cSrcweir #include <drawinglayer/attribute/sdrlightingattribute3d.hxx>
44035a2f44SArmin Le Grand #include <vcl/graph.hxx>
45035a2f44SArmin Le Grand #include <basegfx/matrix/b2dhommatrixtools.hxx>
46cdf0e10cSrcweir 
47cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
48cdf0e10cSrcweir 
49cdf0e10cSrcweir using namespace com::sun::star;
50cdf0e10cSrcweir 
51cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
52cdf0e10cSrcweir 
53cdf0e10cSrcweir namespace drawinglayer
54cdf0e10cSrcweir {
55cdf0e10cSrcweir     namespace processor3d
56cdf0e10cSrcweir     {
impRenderGradientTexturePrimitive3D(const primitive3d::GradientTexturePrimitive3D & rPrimitive,bool bTransparence)57cdf0e10cSrcweir         void DefaultProcessor3D::impRenderGradientTexturePrimitive3D(const primitive3d::GradientTexturePrimitive3D& rPrimitive, bool bTransparence)
58cdf0e10cSrcweir         {
59cdf0e10cSrcweir             const primitive3d::Primitive3DSequence& rSubSequence = rPrimitive.getChildren();
60cdf0e10cSrcweir 
61cdf0e10cSrcweir             if(rSubSequence.hasElements())
62cdf0e10cSrcweir             {
63cdf0e10cSrcweir                 // rescue values
64cdf0e10cSrcweir                 const bool bOldModulate(getModulate()); mbModulate = rPrimitive.getModulate();
65cdf0e10cSrcweir                 const bool bOldFilter(getFilter()); mbFilter = rPrimitive.getFilter();
66cdf0e10cSrcweir                 const bool bOldSimpleTextureActive(getSimpleTextureActive());
67cdf0e10cSrcweir                 boost::shared_ptr< texture::GeoTexSvx > pOldTex = (bTransparence) ? mpTransparenceGeoTexSvx : mpGeoTexSvx;
68cdf0e10cSrcweir 
69cdf0e10cSrcweir                 // create texture
70cdf0e10cSrcweir                 const attribute::FillGradientAttribute& rFillGradient = rPrimitive.getGradient();
71cdf0e10cSrcweir                 const basegfx::B2DRange aOutlineRange(0.0, 0.0, rPrimitive.getTextureSize().getX(), rPrimitive.getTextureSize().getY());
72cdf0e10cSrcweir                 const attribute::GradientStyle aGradientStyle(rFillGradient.getStyle());
73cdf0e10cSrcweir                 sal_uInt32 nSteps(rFillGradient.getSteps());
74cdf0e10cSrcweir                 const basegfx::BColor aStart(rFillGradient.getStartColor());
75cdf0e10cSrcweir                 const basegfx::BColor aEnd(rFillGradient.getEndColor());
76cdf0e10cSrcweir                 const sal_uInt32 nMaxSteps(sal_uInt32((aStart.getMaximumDistance(aEnd) * 127.5) + 0.5));
77cdf0e10cSrcweir                 boost::shared_ptr< texture::GeoTexSvx > pNewTex;
78cdf0e10cSrcweir 
79cdf0e10cSrcweir                 if(nMaxSteps)
80cdf0e10cSrcweir                 {
81cdf0e10cSrcweir                     // there IS a color distance
82cdf0e10cSrcweir                     if(nSteps == 0L)
83cdf0e10cSrcweir                     {
84cdf0e10cSrcweir                         nSteps = nMaxSteps;
85cdf0e10cSrcweir                     }
86cdf0e10cSrcweir 
87cdf0e10cSrcweir                     if(nSteps < 2L)
88cdf0e10cSrcweir                     {
89cdf0e10cSrcweir                         nSteps = 2L;
90cdf0e10cSrcweir                     }
91cdf0e10cSrcweir 
92cdf0e10cSrcweir                     if(nSteps > nMaxSteps)
93cdf0e10cSrcweir                     {
94cdf0e10cSrcweir                         nSteps = nMaxSteps;
95cdf0e10cSrcweir                     }
96cdf0e10cSrcweir 
97cdf0e10cSrcweir                     switch(aGradientStyle)
98cdf0e10cSrcweir                     {
99cdf0e10cSrcweir                         case attribute::GRADIENTSTYLE_LINEAR:
100cdf0e10cSrcweir                         {
101*64b14621SArmin Le Grand                             pNewTex.reset(
102*64b14621SArmin Le Grand                                 new texture::GeoTexSvxGradientLinear(
103*64b14621SArmin Le Grand                                     aOutlineRange,
104*64b14621SArmin Le Grand                                     aOutlineRange,
105*64b14621SArmin Le Grand                                     aStart,
106*64b14621SArmin Le Grand                                     aEnd,
107*64b14621SArmin Le Grand                                     nSteps,
108*64b14621SArmin Le Grand                                     rFillGradient.getBorder(),
109*64b14621SArmin Le Grand                                     rFillGradient.getAngle()));
110cdf0e10cSrcweir                             break;
111cdf0e10cSrcweir                         }
112cdf0e10cSrcweir                         case attribute::GRADIENTSTYLE_AXIAL:
113cdf0e10cSrcweir                         {
114*64b14621SArmin Le Grand                             pNewTex.reset(
115*64b14621SArmin Le Grand                                 new texture::GeoTexSvxGradientAxial(
116*64b14621SArmin Le Grand                                     aOutlineRange,
117*64b14621SArmin Le Grand                                     aOutlineRange,
118*64b14621SArmin Le Grand                                     aStart,
119*64b14621SArmin Le Grand                                     aEnd,
120*64b14621SArmin Le Grand                                     nSteps,
121*64b14621SArmin Le Grand                                     rFillGradient.getBorder(),
122*64b14621SArmin Le Grand                                     rFillGradient.getAngle()));
123cdf0e10cSrcweir                             break;
124cdf0e10cSrcweir                         }
125cdf0e10cSrcweir                         case attribute::GRADIENTSTYLE_RADIAL:
126cdf0e10cSrcweir                         {
127*64b14621SArmin Le Grand                             pNewTex.reset(
128*64b14621SArmin Le Grand                                 new texture::GeoTexSvxGradientRadial(
129*64b14621SArmin Le Grand                                     aOutlineRange,
130*64b14621SArmin Le Grand                                     aStart,
131*64b14621SArmin Le Grand                                     aEnd,
132*64b14621SArmin Le Grand                                     nSteps,
133*64b14621SArmin Le Grand                                     rFillGradient.getBorder(),
134*64b14621SArmin Le Grand                                     rFillGradient.getOffsetX(),
135*64b14621SArmin Le Grand                                     rFillGradient.getOffsetY()));
136cdf0e10cSrcweir                             break;
137cdf0e10cSrcweir                         }
138cdf0e10cSrcweir                         case attribute::GRADIENTSTYLE_ELLIPTICAL:
139cdf0e10cSrcweir                         {
140*64b14621SArmin Le Grand                             pNewTex.reset(
141*64b14621SArmin Le Grand                                 new texture::GeoTexSvxGradientElliptical(
142*64b14621SArmin Le Grand                                     aOutlineRange,
143*64b14621SArmin Le Grand                                     aStart,
144*64b14621SArmin Le Grand                                     aEnd,
145*64b14621SArmin Le Grand                                     nSteps,
146*64b14621SArmin Le Grand                                     rFillGradient.getBorder(),
147*64b14621SArmin Le Grand                                     rFillGradient.getOffsetX(),
148*64b14621SArmin Le Grand                                     rFillGradient.getOffsetY(),
149*64b14621SArmin Le Grand                                     rFillGradient.getAngle()));
150cdf0e10cSrcweir                             break;
151cdf0e10cSrcweir                         }
152cdf0e10cSrcweir                         case attribute::GRADIENTSTYLE_SQUARE:
153cdf0e10cSrcweir                         {
154*64b14621SArmin Le Grand                             pNewTex.reset(
155*64b14621SArmin Le Grand                                 new texture::GeoTexSvxGradientSquare(
156*64b14621SArmin Le Grand                                     aOutlineRange,
157*64b14621SArmin Le Grand                                     aStart,
158*64b14621SArmin Le Grand                                     aEnd,
159*64b14621SArmin Le Grand                                     nSteps,
160*64b14621SArmin Le Grand                                     rFillGradient.getBorder(),
161*64b14621SArmin Le Grand                                     rFillGradient.getOffsetX(),
162*64b14621SArmin Le Grand                                     rFillGradient.getOffsetY(),
163*64b14621SArmin Le Grand                                     rFillGradient.getAngle()));
164cdf0e10cSrcweir                             break;
165cdf0e10cSrcweir                         }
166cdf0e10cSrcweir                         case attribute::GRADIENTSTYLE_RECT:
167cdf0e10cSrcweir                         {
168*64b14621SArmin Le Grand                             pNewTex.reset(
169*64b14621SArmin Le Grand                                 new texture::GeoTexSvxGradientRect(
170*64b14621SArmin Le Grand                                     aOutlineRange,
171*64b14621SArmin Le Grand                                     aStart,
172*64b14621SArmin Le Grand                                     aEnd,
173*64b14621SArmin Le Grand                                     nSteps,
174*64b14621SArmin Le Grand                                     rFillGradient.getBorder(),
175*64b14621SArmin Le Grand                                     rFillGradient.getOffsetX(),
176*64b14621SArmin Le Grand                                     rFillGradient.getOffsetY(),
177*64b14621SArmin Le Grand                                     rFillGradient.getAngle()));
178cdf0e10cSrcweir                             break;
179cdf0e10cSrcweir                         }
180cdf0e10cSrcweir                     }
181cdf0e10cSrcweir 
182cdf0e10cSrcweir                     mbSimpleTextureActive = false;
183cdf0e10cSrcweir                 }
184cdf0e10cSrcweir                 else
185cdf0e10cSrcweir                 {
186cdf0e10cSrcweir                     // no color distance -> same color, use simple texture
187cdf0e10cSrcweir                     pNewTex.reset(new texture::GeoTexSvxMono(aStart, 1.0 - aStart.luminance()));
188cdf0e10cSrcweir                     mbSimpleTextureActive = true;
189cdf0e10cSrcweir                 }
190cdf0e10cSrcweir 
191cdf0e10cSrcweir                 // set created texture
192cdf0e10cSrcweir                 if(bTransparence)
193cdf0e10cSrcweir                 {
194cdf0e10cSrcweir                     mpTransparenceGeoTexSvx = pNewTex;
195cdf0e10cSrcweir                 }
196cdf0e10cSrcweir                 else
197cdf0e10cSrcweir                 {
198cdf0e10cSrcweir                     mpGeoTexSvx = pNewTex;
199cdf0e10cSrcweir                 }
200cdf0e10cSrcweir 
201cdf0e10cSrcweir                 // process sub-list
202cdf0e10cSrcweir                 process(rSubSequence);
203cdf0e10cSrcweir 
204cdf0e10cSrcweir                 // restore values
205cdf0e10cSrcweir                 mbModulate = bOldModulate;
206cdf0e10cSrcweir                 mbFilter = bOldFilter;
207cdf0e10cSrcweir                 mbSimpleTextureActive = bOldSimpleTextureActive;
208cdf0e10cSrcweir 
209cdf0e10cSrcweir                 if(bTransparence)
210cdf0e10cSrcweir                 {
211cdf0e10cSrcweir                     mpTransparenceGeoTexSvx = pOldTex;
212cdf0e10cSrcweir                 }
213cdf0e10cSrcweir                 else
214cdf0e10cSrcweir                 {
215cdf0e10cSrcweir                     mpGeoTexSvx = pOldTex;
216cdf0e10cSrcweir                 }
217cdf0e10cSrcweir             }
218cdf0e10cSrcweir         }
219cdf0e10cSrcweir 
impRenderHatchTexturePrimitive3D(const primitive3d::HatchTexturePrimitive3D & rPrimitive)220cdf0e10cSrcweir         void DefaultProcessor3D::impRenderHatchTexturePrimitive3D(const primitive3d::HatchTexturePrimitive3D& rPrimitive)
221cdf0e10cSrcweir         {
222cdf0e10cSrcweir             const primitive3d::Primitive3DSequence& rSubSequence = rPrimitive.getChildren();
223cdf0e10cSrcweir 
224cdf0e10cSrcweir             if(rSubSequence.hasElements())
225cdf0e10cSrcweir             {
226cdf0e10cSrcweir                 // rescue values
227cdf0e10cSrcweir                 const bool bOldModulate(getModulate()); mbModulate = rPrimitive.getModulate();
228cdf0e10cSrcweir                 const bool bOldFilter(getFilter()); mbFilter = rPrimitive.getFilter();
229cdf0e10cSrcweir                 boost::shared_ptr< texture::GeoTexSvx > pOldTex = mpGeoTexSvx;
230cdf0e10cSrcweir 
231cdf0e10cSrcweir                 // calculate logic pixel size in object coordinates. Create transformation view
232cdf0e10cSrcweir                 // to object by inverting ObjectToView
233cdf0e10cSrcweir                 basegfx::B3DHomMatrix aInvObjectToView(getViewInformation3D().getObjectToView());
234cdf0e10cSrcweir                 aInvObjectToView.invert();
235cdf0e10cSrcweir 
236cdf0e10cSrcweir                 // back-project discrete coordinates to object coordinates and extract
237cdf0e10cSrcweir                 // maximum distance
238cdf0e10cSrcweir                 const basegfx::B3DPoint aZero(aInvObjectToView * basegfx::B3DPoint(0.0, 0.0, 0.0));
239cdf0e10cSrcweir                 const basegfx::B3DPoint aOne(aInvObjectToView * basegfx::B3DPoint(1.0, 1.0, 1.0));
240cdf0e10cSrcweir                 const basegfx::B3DVector aLogicPixel(aOne - aZero);
241cdf0e10cSrcweir                 double fLogicPixelSizeWorld(::std::max(::std::max(fabs(aLogicPixel.getX()), fabs(aLogicPixel.getY())), fabs(aLogicPixel.getZ())));
242cdf0e10cSrcweir 
243cdf0e10cSrcweir                 // calculate logic pixel size in texture coordinates
244cdf0e10cSrcweir                 const double fLogicTexSizeX(fLogicPixelSizeWorld / rPrimitive.getTextureSize().getX());
245cdf0e10cSrcweir                 const double fLogicTexSizeY(fLogicPixelSizeWorld / rPrimitive.getTextureSize().getY());
246cdf0e10cSrcweir                 const double fLogicTexSize(fLogicTexSizeX > fLogicTexSizeY ? fLogicTexSizeX : fLogicTexSizeY);
247cdf0e10cSrcweir 
248cdf0e10cSrcweir                 // create texture and set
249cdf0e10cSrcweir                 mpGeoTexSvx.reset(new texture::GeoTexSvxMultiHatch(rPrimitive, fLogicTexSize));
250cdf0e10cSrcweir 
251cdf0e10cSrcweir                 // process sub-list
252cdf0e10cSrcweir                 process(rSubSequence);
253cdf0e10cSrcweir 
254cdf0e10cSrcweir                 // restore values
255cdf0e10cSrcweir                 mbModulate = bOldModulate;
256cdf0e10cSrcweir                 mbFilter = bOldFilter;
257cdf0e10cSrcweir                 mpGeoTexSvx = pOldTex;
258cdf0e10cSrcweir             }
259cdf0e10cSrcweir         }
260cdf0e10cSrcweir 
impRenderBitmapTexturePrimitive3D(const primitive3d::BitmapTexturePrimitive3D & rPrimitive)261cdf0e10cSrcweir         void DefaultProcessor3D::impRenderBitmapTexturePrimitive3D(const primitive3d::BitmapTexturePrimitive3D& rPrimitive)
262cdf0e10cSrcweir         {
263cdf0e10cSrcweir             const primitive3d::Primitive3DSequence& rSubSequence = rPrimitive.getChildren();
264cdf0e10cSrcweir 
265cdf0e10cSrcweir             if(rSubSequence.hasElements())
266cdf0e10cSrcweir             {
267cdf0e10cSrcweir                 // rescue values
268cdf0e10cSrcweir                 const bool bOldModulate(getModulate()); mbModulate = rPrimitive.getModulate();
269cdf0e10cSrcweir                 const bool bOldFilter(getFilter()); mbFilter = rPrimitive.getFilter();
270cdf0e10cSrcweir                 boost::shared_ptr< texture::GeoTexSvx > pOldTex = mpGeoTexSvx;
271cdf0e10cSrcweir 
272cdf0e10cSrcweir                 // create texture
273035a2f44SArmin Le Grand                 const attribute::FillGraphicAttribute& rFillGraphicAttribute = rPrimitive.getFillGraphicAttribute();
274cdf0e10cSrcweir 
275035a2f44SArmin Le Grand                 // #121194# For 3D texture we will use the BitmapRex representation
276035a2f44SArmin Le Grand                 const BitmapEx aBitmapEx(rFillGraphicAttribute.getGraphic().GetBitmapEx());
277035a2f44SArmin Le Grand 
278035a2f44SArmin Le Grand                 // create range scaled by texture size
279035a2f44SArmin Le Grand                 basegfx::B2DRange aGraphicRange(rFillGraphicAttribute.getGraphicRange());
280035a2f44SArmin Le Grand 
281035a2f44SArmin Le Grand                 aGraphicRange.transform(
282035a2f44SArmin Le Grand                     basegfx::tools::createScaleB2DHomMatrix(
283035a2f44SArmin Le Grand                         rPrimitive.getTextureSize()));
284035a2f44SArmin Le Grand 
285035a2f44SArmin Le Grand                 if(rFillGraphicAttribute.getTiling())
286cdf0e10cSrcweir                 {
287035a2f44SArmin Le Grand                     mpGeoTexSvx.reset(
288035a2f44SArmin Le Grand                         new texture::GeoTexSvxBitmapExTiled(
289035a2f44SArmin Le Grand                             aBitmapEx,
290035a2f44SArmin Le Grand                             aGraphicRange,
291035a2f44SArmin Le Grand                             rFillGraphicAttribute.getOffsetX(),
292035a2f44SArmin Le Grand                             rFillGraphicAttribute.getOffsetY()));
293cdf0e10cSrcweir                 }
294cdf0e10cSrcweir                 else
295cdf0e10cSrcweir                 {
296035a2f44SArmin Le Grand                     mpGeoTexSvx.reset(
297035a2f44SArmin Le Grand                         new texture::GeoTexSvxBitmapEx(
298035a2f44SArmin Le Grand                             aBitmapEx,
299035a2f44SArmin Le Grand                             aGraphicRange));
300cdf0e10cSrcweir                 }
301cdf0e10cSrcweir 
302cdf0e10cSrcweir                 // process sub-list
303cdf0e10cSrcweir                 process(rSubSequence);
304cdf0e10cSrcweir 
305cdf0e10cSrcweir                 // restore values
306cdf0e10cSrcweir                 mbModulate = bOldModulate;
307cdf0e10cSrcweir                 mbFilter = bOldFilter;
308cdf0e10cSrcweir                 mpGeoTexSvx = pOldTex;
309cdf0e10cSrcweir             }
310cdf0e10cSrcweir         }
311cdf0e10cSrcweir 
impRenderModifiedColorPrimitive3D(const primitive3d::ModifiedColorPrimitive3D & rModifiedCandidate)312cdf0e10cSrcweir         void DefaultProcessor3D::impRenderModifiedColorPrimitive3D(const primitive3d::ModifiedColorPrimitive3D& rModifiedCandidate)
313cdf0e10cSrcweir         {
314cdf0e10cSrcweir             const primitive3d::Primitive3DSequence& rSubSequence = rModifiedCandidate.getChildren();
315cdf0e10cSrcweir 
316cdf0e10cSrcweir             if(rSubSequence.hasElements())
317cdf0e10cSrcweir             {
318cdf0e10cSrcweir                 // put modifier on stack
319cdf0e10cSrcweir                 maBColorModifierStack.push(rModifiedCandidate.getColorModifier());
320cdf0e10cSrcweir 
321cdf0e10cSrcweir                 // process sub-list
322cdf0e10cSrcweir                 process(rModifiedCandidate.getChildren());
323cdf0e10cSrcweir 
324cdf0e10cSrcweir                 // remove modifier from stack
325cdf0e10cSrcweir                 maBColorModifierStack.pop();
326cdf0e10cSrcweir             }
327cdf0e10cSrcweir         }
328cdf0e10cSrcweir 
impRenderPolygonHairlinePrimitive3D(const primitive3d::PolygonHairlinePrimitive3D & rPrimitive)329cdf0e10cSrcweir         void DefaultProcessor3D::impRenderPolygonHairlinePrimitive3D(const primitive3d::PolygonHairlinePrimitive3D& rPrimitive)
330cdf0e10cSrcweir         {
331cdf0e10cSrcweir             basegfx::B3DPolygon aHairline(rPrimitive.getB3DPolygon());
332cdf0e10cSrcweir 
333cdf0e10cSrcweir             if(aHairline.count())
334cdf0e10cSrcweir             {
335cdf0e10cSrcweir                 // hairlines need no extra data, clear it
336cdf0e10cSrcweir                 aHairline.clearTextureCoordinates();
337cdf0e10cSrcweir                 aHairline.clearNormals();
338cdf0e10cSrcweir                 aHairline.clearBColors();
339cdf0e10cSrcweir 
340cdf0e10cSrcweir                 // transform to device coordinates (-1.0 .. 1.0) and check for visibility
341cdf0e10cSrcweir                 aHairline.transform(getViewInformation3D().getObjectToView());
342cdf0e10cSrcweir                 const basegfx::B3DRange a3DRange(basegfx::tools::getRange(aHairline));
343cdf0e10cSrcweir                 const basegfx::B2DRange a2DRange(a3DRange.getMinX(), a3DRange.getMinY(), a3DRange.getMaxX(), a3DRange.getMaxY());
344cdf0e10cSrcweir 
345cdf0e10cSrcweir                 if(a2DRange.overlaps(maRasterRange))
346cdf0e10cSrcweir                 {
347cdf0e10cSrcweir                     const attribute::MaterialAttribute3D aMaterial(maBColorModifierStack.getModifiedColor(rPrimitive.getBColor()));
348cdf0e10cSrcweir 
349cdf0e10cSrcweir                     rasterconvertB3DPolygon(aMaterial, aHairline);
350cdf0e10cSrcweir                 }
351cdf0e10cSrcweir             }
352cdf0e10cSrcweir         }
353cdf0e10cSrcweir 
impRenderPolyPolygonMaterialPrimitive3D(const primitive3d::PolyPolygonMaterialPrimitive3D & rPrimitive)354cdf0e10cSrcweir         void DefaultProcessor3D::impRenderPolyPolygonMaterialPrimitive3D(const primitive3d::PolyPolygonMaterialPrimitive3D& rPrimitive)
355cdf0e10cSrcweir         {
356cdf0e10cSrcweir             basegfx::B3DPolyPolygon aFill(rPrimitive.getB3DPolyPolygon());
357cdf0e10cSrcweir             basegfx::BColor aObjectColor(rPrimitive.getMaterial().getColor());
358cdf0e10cSrcweir             bool bPaintIt(aFill.count());
359cdf0e10cSrcweir 
360cdf0e10cSrcweir             // #i98295# get ShadeMode. Correct early when only flat is possible due to missing normals
361cdf0e10cSrcweir             const ::com::sun::star::drawing::ShadeMode aShadeMode(
362cdf0e10cSrcweir                 aFill.areNormalsUsed() ?
363cdf0e10cSrcweir                     getSdrSceneAttribute().getShadeMode() : ::com::sun::star::drawing::ShadeMode_FLAT);
364cdf0e10cSrcweir 
365cdf0e10cSrcweir             if(bPaintIt)
366cdf0e10cSrcweir             {
367cdf0e10cSrcweir                 // get rid of texture coordinates if there is no texture
368cdf0e10cSrcweir                 if(aFill.areTextureCoordinatesUsed() && !getGeoTexSvx().get() && !getTransparenceGeoTexSvx().get())
369cdf0e10cSrcweir                 {
370cdf0e10cSrcweir                     aFill.clearTextureCoordinates();
371cdf0e10cSrcweir                 }
372cdf0e10cSrcweir 
373cdf0e10cSrcweir                 // #i98295# get rid of normals and color early when not needed
374cdf0e10cSrcweir                 if(::com::sun::star::drawing::ShadeMode_FLAT == aShadeMode)
375cdf0e10cSrcweir                 {
376cdf0e10cSrcweir                     aFill.clearNormals();
377cdf0e10cSrcweir                     aFill.clearBColors();
378cdf0e10cSrcweir                 }
379cdf0e10cSrcweir 
380cdf0e10cSrcweir                 // transform to device coordinates (-1.0 .. 1.0) and check for visibility
381cdf0e10cSrcweir                 aFill.transform(getViewInformation3D().getObjectToView());
382cdf0e10cSrcweir                 const basegfx::B3DRange a3DRange(basegfx::tools::getRange(aFill));
383cdf0e10cSrcweir                 const basegfx::B2DRange a2DRange(a3DRange.getMinX(), a3DRange.getMinY(), a3DRange.getMaxX(), a3DRange.getMaxY());
384cdf0e10cSrcweir 
385cdf0e10cSrcweir                 bPaintIt = a2DRange.overlaps(maRasterRange);
386cdf0e10cSrcweir             }
387cdf0e10cSrcweir 
388cdf0e10cSrcweir             // check if it shall be painted regarding hiding of normals (backface culling)
389cdf0e10cSrcweir             if(bPaintIt && !rPrimitive.getDoubleSided())
390cdf0e10cSrcweir             {
391cdf0e10cSrcweir                 // get plane normal of polygon in view coordinates (with ZBuffer values),
392cdf0e10cSrcweir                 // left-handed coordinate system
393cdf0e10cSrcweir                 const basegfx::B3DVector aPlaneNormal(aFill.getB3DPolygon(0L).getNormal());
394cdf0e10cSrcweir 
395cdf0e10cSrcweir                 if(aPlaneNormal.getZ() > 0.0)
396cdf0e10cSrcweir                 {
397cdf0e10cSrcweir                     bPaintIt = false;
398cdf0e10cSrcweir                 }
399cdf0e10cSrcweir             }
400cdf0e10cSrcweir 
401cdf0e10cSrcweir             if(bPaintIt)
402cdf0e10cSrcweir             {
403cdf0e10cSrcweir                 // prepare ObjectToEye in NormalTransform
404cdf0e10cSrcweir                 basegfx::B3DHomMatrix aNormalTransform(getViewInformation3D().getOrientation() * getViewInformation3D().getObjectTransformation());
405cdf0e10cSrcweir 
406cdf0e10cSrcweir                 if(getSdrSceneAttribute().getTwoSidedLighting())
407cdf0e10cSrcweir                 {
408cdf0e10cSrcweir                     // get plane normal of polygon in view coordinates (with ZBuffer values),
409cdf0e10cSrcweir                     // left-handed coordinate system
410cdf0e10cSrcweir                     const basegfx::B3DVector aPlaneNormal(aFill.getB3DPolygon(0L).getNormal());
411cdf0e10cSrcweir 
412cdf0e10cSrcweir                     if(aPlaneNormal.getZ() > 0.0)
413cdf0e10cSrcweir                     {
414cdf0e10cSrcweir                         // mirror normals
415cdf0e10cSrcweir                         aNormalTransform.scale(-1.0, -1.0, -1.0);
416cdf0e10cSrcweir                     }
417cdf0e10cSrcweir                 }
418cdf0e10cSrcweir 
419cdf0e10cSrcweir                 switch(aShadeMode)
420cdf0e10cSrcweir                 {
421cdf0e10cSrcweir                     case ::com::sun::star::drawing::ShadeMode_PHONG:
422cdf0e10cSrcweir                     {
423cdf0e10cSrcweir                         // phong shading. Transform normals to eye coor
424cdf0e10cSrcweir                         aFill.transformNormals(aNormalTransform);
425cdf0e10cSrcweir                         break;
426cdf0e10cSrcweir                     }
427cdf0e10cSrcweir                     case ::com::sun::star::drawing::ShadeMode_SMOOTH:
428cdf0e10cSrcweir                     {
429cdf0e10cSrcweir                         // gouraud shading. Transform normals to eye coor
430cdf0e10cSrcweir                         aFill.transformNormals(aNormalTransform);
431cdf0e10cSrcweir 
432cdf0e10cSrcweir                         // prepare color model parameters, evtl. use blend color
433cdf0e10cSrcweir                         const basegfx::BColor aColor(getModulate() ? basegfx::BColor(1.0, 1.0, 1.0) : rPrimitive.getMaterial().getColor());
434cdf0e10cSrcweir                         const basegfx::BColor& rSpecular(rPrimitive.getMaterial().getSpecular());
435cdf0e10cSrcweir                         const basegfx::BColor& rEmission(rPrimitive.getMaterial().getEmission());
436cdf0e10cSrcweir                         const sal_uInt16 nSpecularIntensity(rPrimitive.getMaterial().getSpecularIntensity());
437cdf0e10cSrcweir 
438cdf0e10cSrcweir                         // solve color model for each normal vector, set colors at points. Clear normals.
439cdf0e10cSrcweir                         for(sal_uInt32 a(0L); a < aFill.count(); a++)
440cdf0e10cSrcweir                         {
441cdf0e10cSrcweir                             basegfx::B3DPolygon aPartFill(aFill.getB3DPolygon(a));
442cdf0e10cSrcweir 
443cdf0e10cSrcweir                             for(sal_uInt32 b(0L); b < aPartFill.count(); b++)
444cdf0e10cSrcweir                             {
445cdf0e10cSrcweir                                 // solve color model. Transform normal to eye coor
446cdf0e10cSrcweir                                 const basegfx::B3DVector aNormal(aPartFill.getNormal(b));
447cdf0e10cSrcweir                                 const basegfx::BColor aSolvedColor(getSdrLightingAttribute().solveColorModel(aNormal, aColor, rSpecular, rEmission, nSpecularIntensity));
448cdf0e10cSrcweir                                 aPartFill.setBColor(b, aSolvedColor);
449cdf0e10cSrcweir                             }
450cdf0e10cSrcweir 
451cdf0e10cSrcweir                             // clear normals on this part polygon and write it back
452cdf0e10cSrcweir                             aPartFill.clearNormals();
453cdf0e10cSrcweir                             aFill.setB3DPolygon(a, aPartFill);
454cdf0e10cSrcweir                         }
455cdf0e10cSrcweir                         break;
456cdf0e10cSrcweir                     }
457cdf0e10cSrcweir                     case ::com::sun::star::drawing::ShadeMode_FLAT:
458cdf0e10cSrcweir                     {
459cdf0e10cSrcweir                         // flat shading. Get plane vector in eye coordinates
460cdf0e10cSrcweir                         const basegfx::B3DVector aPlaneEyeNormal(aNormalTransform * rPrimitive.getB3DPolyPolygon().getB3DPolygon(0L).getNormal());
461cdf0e10cSrcweir 
462cdf0e10cSrcweir                         // prepare color model parameters, evtl. use blend color
463cdf0e10cSrcweir                         const basegfx::BColor aColor(getModulate() ? basegfx::BColor(1.0, 1.0, 1.0) : rPrimitive.getMaterial().getColor());
464cdf0e10cSrcweir                         const basegfx::BColor& rSpecular(rPrimitive.getMaterial().getSpecular());
465cdf0e10cSrcweir                         const basegfx::BColor& rEmission(rPrimitive.getMaterial().getEmission());
466cdf0e10cSrcweir                         const sal_uInt16 nSpecularIntensity(rPrimitive.getMaterial().getSpecularIntensity());
467cdf0e10cSrcweir 
468cdf0e10cSrcweir                         // solve color model for plane vector and use that color for whole plane
469cdf0e10cSrcweir                         aObjectColor = getSdrLightingAttribute().solveColorModel(aPlaneEyeNormal, aColor, rSpecular, rEmission, nSpecularIntensity);
470cdf0e10cSrcweir                         break;
471cdf0e10cSrcweir                     }
472cdf0e10cSrcweir                     default: // case ::com::sun::star::drawing::ShadeMode_DRAFT:
473cdf0e10cSrcweir                     {
474cdf0e10cSrcweir                         // draft, just use object color which is already set. Delete all other infos
475cdf0e10cSrcweir                         aFill.clearNormals();
476cdf0e10cSrcweir                         aFill.clearBColors();
477cdf0e10cSrcweir                         break;
478cdf0e10cSrcweir                     }
479cdf0e10cSrcweir                 }
480cdf0e10cSrcweir 
481cdf0e10cSrcweir                 // draw it to ZBuffer
482cdf0e10cSrcweir                 const attribute::MaterialAttribute3D aMaterial(
483cdf0e10cSrcweir                     maBColorModifierStack.getModifiedColor(aObjectColor),
484cdf0e10cSrcweir                     rPrimitive.getMaterial().getSpecular(),
485cdf0e10cSrcweir                     rPrimitive.getMaterial().getEmission(),
486cdf0e10cSrcweir                     rPrimitive.getMaterial().getSpecularIntensity());
487cdf0e10cSrcweir 
488cdf0e10cSrcweir                 rasterconvertB3DPolyPolygon(aMaterial, aFill);
489cdf0e10cSrcweir             }
490cdf0e10cSrcweir         }
491cdf0e10cSrcweir 
impRenderTransformPrimitive3D(const primitive3d::TransformPrimitive3D & rTransformCandidate)492cdf0e10cSrcweir         void DefaultProcessor3D::impRenderTransformPrimitive3D(const primitive3d::TransformPrimitive3D& rTransformCandidate)
493cdf0e10cSrcweir         {
494cdf0e10cSrcweir             // transform group. Remember current transformations
495cdf0e10cSrcweir             const geometry::ViewInformation3D aLastViewInformation3D(getViewInformation3D());
496cdf0e10cSrcweir 
497cdf0e10cSrcweir             // create new transformation; add new object transform from right side
498cdf0e10cSrcweir             const geometry::ViewInformation3D aNewViewInformation3D(
499cdf0e10cSrcweir                 aLastViewInformation3D.getObjectTransformation() * rTransformCandidate.getTransformation(),
500cdf0e10cSrcweir                 aLastViewInformation3D.getOrientation(),
501cdf0e10cSrcweir                 aLastViewInformation3D.getProjection(),
502cdf0e10cSrcweir                 aLastViewInformation3D.getDeviceToView(),
503cdf0e10cSrcweir                 aLastViewInformation3D.getViewTime(),
504cdf0e10cSrcweir                 aLastViewInformation3D.getExtendedInformationSequence());
505cdf0e10cSrcweir             updateViewInformation(aNewViewInformation3D);
506cdf0e10cSrcweir 
507cdf0e10cSrcweir             // let break down recursively
508cdf0e10cSrcweir             process(rTransformCandidate.getChildren());
509cdf0e10cSrcweir 
510cdf0e10cSrcweir             // restore transformations
511cdf0e10cSrcweir             updateViewInformation(aLastViewInformation3D);
512cdf0e10cSrcweir         }
513cdf0e10cSrcweir 
processBasePrimitive3D(const primitive3d::BasePrimitive3D & rBasePrimitive)514cdf0e10cSrcweir         void DefaultProcessor3D::processBasePrimitive3D(const primitive3d::BasePrimitive3D& rBasePrimitive)
515cdf0e10cSrcweir         {
516cdf0e10cSrcweir             // it is a BasePrimitive3D implementation, use getPrimitive3DID() call for switch
517cdf0e10cSrcweir             switch(rBasePrimitive.getPrimitive3DID())
518cdf0e10cSrcweir             {
519cdf0e10cSrcweir                 case PRIMITIVE3D_ID_GRADIENTTEXTUREPRIMITIVE3D :
520cdf0e10cSrcweir                 {
521cdf0e10cSrcweir                     // GradientTexturePrimitive3D
522cdf0e10cSrcweir                     const primitive3d::GradientTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::GradientTexturePrimitive3D& >(rBasePrimitive);
523cdf0e10cSrcweir                     impRenderGradientTexturePrimitive3D(rPrimitive, false);
524cdf0e10cSrcweir                     break;
525cdf0e10cSrcweir                 }
526cdf0e10cSrcweir                 case PRIMITIVE3D_ID_HATCHTEXTUREPRIMITIVE3D :
527cdf0e10cSrcweir                 {
528cdf0e10cSrcweir                     // HatchTexturePrimitive3D
529cdf0e10cSrcweir                     static bool bDoHatchDecomposition(false);
530cdf0e10cSrcweir 
531cdf0e10cSrcweir                     if(bDoHatchDecomposition)
532cdf0e10cSrcweir                     {
533cdf0e10cSrcweir                         // let break down
534cdf0e10cSrcweir                         process(rBasePrimitive.get3DDecomposition(getViewInformation3D()));
535cdf0e10cSrcweir                     }
536cdf0e10cSrcweir                     else
537cdf0e10cSrcweir                     {
538cdf0e10cSrcweir                         // hatchTexturePrimitive3D
539cdf0e10cSrcweir                         const primitive3d::HatchTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::HatchTexturePrimitive3D& >(rBasePrimitive);
540cdf0e10cSrcweir                         impRenderHatchTexturePrimitive3D(rPrimitive);
541cdf0e10cSrcweir                     }
542cdf0e10cSrcweir                     break;
543cdf0e10cSrcweir                 }
544cdf0e10cSrcweir                 case PRIMITIVE3D_ID_BITMAPTEXTUREPRIMITIVE3D :
545cdf0e10cSrcweir                 {
546cdf0e10cSrcweir                     // BitmapTexturePrimitive3D
547cdf0e10cSrcweir                     const primitive3d::BitmapTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::BitmapTexturePrimitive3D& >(rBasePrimitive);
548cdf0e10cSrcweir                     impRenderBitmapTexturePrimitive3D(rPrimitive);
549cdf0e10cSrcweir                     break;
550cdf0e10cSrcweir                 }
551cdf0e10cSrcweir                 case PRIMITIVE3D_ID_TRANSPARENCETEXTUREPRIMITIVE3D :
552cdf0e10cSrcweir                 {
553cdf0e10cSrcweir                     // TransparenceTexturePrimitive3D
554cdf0e10cSrcweir                     const primitive3d::TransparenceTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::TransparenceTexturePrimitive3D& >(rBasePrimitive);
555cdf0e10cSrcweir                     mnTransparenceCounter++;
556cdf0e10cSrcweir                     impRenderGradientTexturePrimitive3D(rPrimitive, true);
557cdf0e10cSrcweir                     mnTransparenceCounter--;
558cdf0e10cSrcweir                     break;
559cdf0e10cSrcweir                 }
560cdf0e10cSrcweir                 case PRIMITIVE3D_ID_MODIFIEDCOLORPRIMITIVE3D :
561cdf0e10cSrcweir                 {
562cdf0e10cSrcweir                     // ModifiedColorPrimitive3D
563cdf0e10cSrcweir                     // Force output to unified color.
564cdf0e10cSrcweir                     const primitive3d::ModifiedColorPrimitive3D& rPrimitive = static_cast< const primitive3d::ModifiedColorPrimitive3D& >(rBasePrimitive);
565cdf0e10cSrcweir                     impRenderModifiedColorPrimitive3D(rPrimitive);
566cdf0e10cSrcweir                     break;
567cdf0e10cSrcweir                 }
568cdf0e10cSrcweir                 case PRIMITIVE3D_ID_POLYGONHAIRLINEPRIMITIVE3D :
569cdf0e10cSrcweir                 {
570cdf0e10cSrcweir                     // directdraw of PolygonHairlinePrimitive3D
571cdf0e10cSrcweir                     const primitive3d::PolygonHairlinePrimitive3D& rPrimitive = static_cast< const primitive3d::PolygonHairlinePrimitive3D& >(rBasePrimitive);
572cdf0e10cSrcweir                     impRenderPolygonHairlinePrimitive3D(rPrimitive);
573cdf0e10cSrcweir                     break;
574cdf0e10cSrcweir                 }
575cdf0e10cSrcweir                 case PRIMITIVE3D_ID_POLYPOLYGONMATERIALPRIMITIVE3D :
576cdf0e10cSrcweir                 {
577cdf0e10cSrcweir                     // directdraw of PolyPolygonMaterialPrimitive3D
578cdf0e10cSrcweir                     const primitive3d::PolyPolygonMaterialPrimitive3D& rPrimitive = static_cast< const primitive3d::PolyPolygonMaterialPrimitive3D& >(rBasePrimitive);
579cdf0e10cSrcweir                     impRenderPolyPolygonMaterialPrimitive3D(rPrimitive);
580cdf0e10cSrcweir                     break;
581cdf0e10cSrcweir                 }
582cdf0e10cSrcweir                 case PRIMITIVE3D_ID_TRANSFORMPRIMITIVE3D :
583cdf0e10cSrcweir                 {
584cdf0e10cSrcweir                     // transform group (TransformPrimitive3D)
585cdf0e10cSrcweir                     impRenderTransformPrimitive3D(static_cast< const primitive3d::TransformPrimitive3D& >(rBasePrimitive));
586cdf0e10cSrcweir                     break;
587cdf0e10cSrcweir                 }
588cdf0e10cSrcweir                 default:
589cdf0e10cSrcweir                 {
590cdf0e10cSrcweir                     // process recursively
591cdf0e10cSrcweir                     process(rBasePrimitive.get3DDecomposition(getViewInformation3D()));
592cdf0e10cSrcweir                     break;
593cdf0e10cSrcweir                 }
594cdf0e10cSrcweir             }
595cdf0e10cSrcweir         }
596cdf0e10cSrcweir 
DefaultProcessor3D(const geometry::ViewInformation3D & rViewInformation,const attribute::SdrSceneAttribute & rSdrSceneAttribute,const attribute::SdrLightingAttribute & rSdrLightingAttribute)597cdf0e10cSrcweir         DefaultProcessor3D::DefaultProcessor3D(
598cdf0e10cSrcweir             const geometry::ViewInformation3D& rViewInformation,
599cdf0e10cSrcweir             const attribute::SdrSceneAttribute& rSdrSceneAttribute,
600cdf0e10cSrcweir             const attribute::SdrLightingAttribute& rSdrLightingAttribute)
601cdf0e10cSrcweir         :   BaseProcessor3D(rViewInformation),
602cdf0e10cSrcweir             mrSdrSceneAttribute(rSdrSceneAttribute),
603cdf0e10cSrcweir             mrSdrLightingAttribute(rSdrLightingAttribute),
604cdf0e10cSrcweir             maRasterRange(),
605cdf0e10cSrcweir             maBColorModifierStack(),
606cdf0e10cSrcweir             mpGeoTexSvx(),
607cdf0e10cSrcweir             mpTransparenceGeoTexSvx(),
608cdf0e10cSrcweir             maDrawinglayerOpt(),
609cdf0e10cSrcweir             mnTransparenceCounter(0),
610cdf0e10cSrcweir             mbModulate(false),
611cdf0e10cSrcweir             mbFilter(false),
612cdf0e10cSrcweir             mbSimpleTextureActive(false)
613cdf0e10cSrcweir         {
614cdf0e10cSrcweir             // a derivation has to set maRasterRange which is used in the basic render methods.
615cdf0e10cSrcweir             // Setting to default here ([0.0 .. 1.0] in X,Y) to avoid problems
616cdf0e10cSrcweir             maRasterRange.expand(basegfx::B2DTuple(0.0, 0.0));
617cdf0e10cSrcweir             maRasterRange.expand(basegfx::B2DTuple(1.0, 1.0));
618cdf0e10cSrcweir         }
619cdf0e10cSrcweir 
~DefaultProcessor3D()620cdf0e10cSrcweir         DefaultProcessor3D::~DefaultProcessor3D()
621cdf0e10cSrcweir         {
622cdf0e10cSrcweir         }
623cdf0e10cSrcweir     } // end of namespace processor3d
624cdf0e10cSrcweir } // end of namespace drawinglayer
625cdf0e10cSrcweir 
626cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
627cdf0e10cSrcweir // eof
628