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
10464702f4SAndrew Rist  *
11464702f4SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12464702f4SAndrew Rist  *
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.
19464702f4SAndrew Rist  *
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>
44*035a2f44SArmin Le Grand #include <vcl/graph.hxx>
45*035a2f44SArmin 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 	{
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 						{
101cdf0e10cSrcweir 							pNewTex.reset(new texture::GeoTexSvxGradientLinear(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), rFillGradient.getAngle()));
102cdf0e10cSrcweir 							break;
103cdf0e10cSrcweir 						}
104cdf0e10cSrcweir 						case attribute::GRADIENTSTYLE_AXIAL:
105cdf0e10cSrcweir 						{
106cdf0e10cSrcweir 							pNewTex.reset(new texture::GeoTexSvxGradientAxial(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), rFillGradient.getAngle()));
107cdf0e10cSrcweir 							break;
108cdf0e10cSrcweir 						}
109cdf0e10cSrcweir 						case attribute::GRADIENTSTYLE_RADIAL:
110cdf0e10cSrcweir 						{
111cdf0e10cSrcweir 							pNewTex.reset(new texture::GeoTexSvxGradientRadial(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), rFillGradient.getOffsetX(), rFillGradient.getOffsetY()));
112cdf0e10cSrcweir 							break;
113cdf0e10cSrcweir 						}
114cdf0e10cSrcweir 						case attribute::GRADIENTSTYLE_ELLIPTICAL:
115cdf0e10cSrcweir 						{
116cdf0e10cSrcweir 							pNewTex.reset(new texture::GeoTexSvxGradientElliptical(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), rFillGradient.getOffsetX(), rFillGradient.getOffsetY(), rFillGradient.getAngle()));
117cdf0e10cSrcweir 							break;
118cdf0e10cSrcweir 						}
119cdf0e10cSrcweir 						case attribute::GRADIENTSTYLE_SQUARE:
120cdf0e10cSrcweir 						{
121cdf0e10cSrcweir 							pNewTex.reset(new texture::GeoTexSvxGradientSquare(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), rFillGradient.getOffsetX(), rFillGradient.getOffsetY(), rFillGradient.getAngle()));
122cdf0e10cSrcweir 							break;
123cdf0e10cSrcweir 						}
124cdf0e10cSrcweir 						case attribute::GRADIENTSTYLE_RECT:
125cdf0e10cSrcweir 						{
126cdf0e10cSrcweir 							pNewTex.reset(new texture::GeoTexSvxGradientRect(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), rFillGradient.getOffsetX(), rFillGradient.getOffsetY(), rFillGradient.getAngle()));
127cdf0e10cSrcweir 							break;
128cdf0e10cSrcweir 						}
129cdf0e10cSrcweir 					}
130cdf0e10cSrcweir 
131cdf0e10cSrcweir 					mbSimpleTextureActive = false;
132cdf0e10cSrcweir 				}
133cdf0e10cSrcweir 				else
134cdf0e10cSrcweir 				{
135cdf0e10cSrcweir 					// no color distance -> same color, use simple texture
136cdf0e10cSrcweir 					pNewTex.reset(new texture::GeoTexSvxMono(aStart, 1.0 - aStart.luminance()));
137cdf0e10cSrcweir 					mbSimpleTextureActive = true;
138cdf0e10cSrcweir 				}
139cdf0e10cSrcweir 
140cdf0e10cSrcweir 				// set created texture
141cdf0e10cSrcweir 				if(bTransparence)
142cdf0e10cSrcweir 				{
143cdf0e10cSrcweir 					mpTransparenceGeoTexSvx = pNewTex;
144cdf0e10cSrcweir 				}
145cdf0e10cSrcweir 				else
146cdf0e10cSrcweir 				{
147cdf0e10cSrcweir 					mpGeoTexSvx = pNewTex;
148cdf0e10cSrcweir 				}
149cdf0e10cSrcweir 
150cdf0e10cSrcweir 				// process sub-list
151cdf0e10cSrcweir 				process(rSubSequence);
152cdf0e10cSrcweir 
153cdf0e10cSrcweir 				// restore values
154cdf0e10cSrcweir 				mbModulate = bOldModulate;
155cdf0e10cSrcweir 				mbFilter = bOldFilter;
156cdf0e10cSrcweir 				mbSimpleTextureActive = bOldSimpleTextureActive;
157cdf0e10cSrcweir 
158cdf0e10cSrcweir 				if(bTransparence)
159cdf0e10cSrcweir 				{
160cdf0e10cSrcweir 					mpTransparenceGeoTexSvx = pOldTex;
161cdf0e10cSrcweir 				}
162cdf0e10cSrcweir 				else
163cdf0e10cSrcweir 				{
164cdf0e10cSrcweir 					mpGeoTexSvx = pOldTex;
165cdf0e10cSrcweir 				}
166cdf0e10cSrcweir 			}
167cdf0e10cSrcweir 		}
168cdf0e10cSrcweir 
169cdf0e10cSrcweir 		void DefaultProcessor3D::impRenderHatchTexturePrimitive3D(const primitive3d::HatchTexturePrimitive3D& rPrimitive)
170cdf0e10cSrcweir 		{
171cdf0e10cSrcweir 			const primitive3d::Primitive3DSequence& rSubSequence = rPrimitive.getChildren();
172cdf0e10cSrcweir 
173cdf0e10cSrcweir 			if(rSubSequence.hasElements())
174cdf0e10cSrcweir 			{
175cdf0e10cSrcweir 				// rescue values
176cdf0e10cSrcweir 				const bool bOldModulate(getModulate()); mbModulate = rPrimitive.getModulate();
177cdf0e10cSrcweir 				const bool bOldFilter(getFilter()); mbFilter = rPrimitive.getFilter();
178cdf0e10cSrcweir 				boost::shared_ptr< texture::GeoTexSvx > pOldTex = mpGeoTexSvx;
179cdf0e10cSrcweir 
180cdf0e10cSrcweir 				// calculate logic pixel size in object coordinates. Create transformation view
181cdf0e10cSrcweir 				// to object by inverting ObjectToView
182cdf0e10cSrcweir 				basegfx::B3DHomMatrix aInvObjectToView(getViewInformation3D().getObjectToView());
183cdf0e10cSrcweir 				aInvObjectToView.invert();
184cdf0e10cSrcweir 
185cdf0e10cSrcweir 				// back-project discrete coordinates to object coordinates and extract
186cdf0e10cSrcweir 				// maximum distance
187cdf0e10cSrcweir 				const basegfx::B3DPoint aZero(aInvObjectToView * basegfx::B3DPoint(0.0, 0.0, 0.0));
188cdf0e10cSrcweir 				const basegfx::B3DPoint aOne(aInvObjectToView * basegfx::B3DPoint(1.0, 1.0, 1.0));
189cdf0e10cSrcweir 				const basegfx::B3DVector aLogicPixel(aOne - aZero);
190cdf0e10cSrcweir 				double fLogicPixelSizeWorld(::std::max(::std::max(fabs(aLogicPixel.getX()), fabs(aLogicPixel.getY())), fabs(aLogicPixel.getZ())));
191cdf0e10cSrcweir 
192cdf0e10cSrcweir 				// calculate logic pixel size in texture coordinates
193cdf0e10cSrcweir 				const double fLogicTexSizeX(fLogicPixelSizeWorld / rPrimitive.getTextureSize().getX());
194cdf0e10cSrcweir 				const double fLogicTexSizeY(fLogicPixelSizeWorld / rPrimitive.getTextureSize().getY());
195cdf0e10cSrcweir 				const double fLogicTexSize(fLogicTexSizeX > fLogicTexSizeY ? fLogicTexSizeX : fLogicTexSizeY);
196cdf0e10cSrcweir 
197cdf0e10cSrcweir 				// create texture and set
198cdf0e10cSrcweir 				mpGeoTexSvx.reset(new texture::GeoTexSvxMultiHatch(rPrimitive, fLogicTexSize));
199cdf0e10cSrcweir 
200cdf0e10cSrcweir 				// process sub-list
201cdf0e10cSrcweir 				process(rSubSequence);
202cdf0e10cSrcweir 
203cdf0e10cSrcweir 				// restore values
204cdf0e10cSrcweir 				mbModulate = bOldModulate;
205cdf0e10cSrcweir 				mbFilter = bOldFilter;
206cdf0e10cSrcweir 				mpGeoTexSvx = pOldTex;
207cdf0e10cSrcweir 			}
208cdf0e10cSrcweir 		}
209cdf0e10cSrcweir 
210cdf0e10cSrcweir 		void DefaultProcessor3D::impRenderBitmapTexturePrimitive3D(const primitive3d::BitmapTexturePrimitive3D& rPrimitive)
211cdf0e10cSrcweir 		{
212cdf0e10cSrcweir 			const primitive3d::Primitive3DSequence& rSubSequence = rPrimitive.getChildren();
213cdf0e10cSrcweir 
214cdf0e10cSrcweir 			if(rSubSequence.hasElements())
215cdf0e10cSrcweir 			{
216cdf0e10cSrcweir 				// rescue values
217cdf0e10cSrcweir 				const bool bOldModulate(getModulate()); mbModulate = rPrimitive.getModulate();
218cdf0e10cSrcweir 				const bool bOldFilter(getFilter()); mbFilter = rPrimitive.getFilter();
219cdf0e10cSrcweir 				boost::shared_ptr< texture::GeoTexSvx > pOldTex = mpGeoTexSvx;
220cdf0e10cSrcweir 
221cdf0e10cSrcweir 				// create texture
222*035a2f44SArmin Le Grand 				const attribute::FillGraphicAttribute& rFillGraphicAttribute = rPrimitive.getFillGraphicAttribute();
223*035a2f44SArmin Le Grand 
224*035a2f44SArmin Le Grand                 // #121194# For 3D texture we will use the BitmapRex representation
225*035a2f44SArmin Le Grand                 const BitmapEx aBitmapEx(rFillGraphicAttribute.getGraphic().GetBitmapEx());
226*035a2f44SArmin Le Grand 
227*035a2f44SArmin Le Grand                 // create range scaled by texture size
228*035a2f44SArmin Le Grand                 basegfx::B2DRange aGraphicRange(rFillGraphicAttribute.getGraphicRange());
229*035a2f44SArmin Le Grand 
230*035a2f44SArmin Le Grand                 aGraphicRange.transform(
231*035a2f44SArmin Le Grand                     basegfx::tools::createScaleB2DHomMatrix(
232*035a2f44SArmin Le Grand                         rPrimitive.getTextureSize()));
233*035a2f44SArmin Le Grand 
234*035a2f44SArmin Le Grand 				if(rFillGraphicAttribute.getTiling())
235cdf0e10cSrcweir 				{
236*035a2f44SArmin Le Grand 					mpGeoTexSvx.reset(
237*035a2f44SArmin Le Grand                         new texture::GeoTexSvxBitmapExTiled(
238*035a2f44SArmin Le Grand 						    aBitmapEx,
239*035a2f44SArmin Le Grand 						    aGraphicRange,
240*035a2f44SArmin Le Grand                             rFillGraphicAttribute.getOffsetX(),
241*035a2f44SArmin Le Grand                             rFillGraphicAttribute.getOffsetY()));
242cdf0e10cSrcweir 				}
243cdf0e10cSrcweir 				else
244cdf0e10cSrcweir 				{
245*035a2f44SArmin Le Grand 					mpGeoTexSvx.reset(
246*035a2f44SArmin Le Grand                         new texture::GeoTexSvxBitmapEx(
247*035a2f44SArmin Le Grand 						    aBitmapEx,
248*035a2f44SArmin Le Grand 						    aGraphicRange));
249cdf0e10cSrcweir 				}
250cdf0e10cSrcweir 
251cdf0e10cSrcweir 				// process sub-list
252cdf0e10cSrcweir 				process(rSubSequence);
253cdf0e10cSrcweir 
254cdf0e10cSrcweir 				// restore values
255cdf0e10cSrcweir 				mbModulate = bOldModulate;
256cdf0e10cSrcweir 				mbFilter = bOldFilter;
257cdf0e10cSrcweir 				mpGeoTexSvx = pOldTex;
258cdf0e10cSrcweir 			}
259cdf0e10cSrcweir 		}
260cdf0e10cSrcweir 
261cdf0e10cSrcweir 		void DefaultProcessor3D::impRenderModifiedColorPrimitive3D(const primitive3d::ModifiedColorPrimitive3D& rModifiedCandidate)
262cdf0e10cSrcweir 		{
263cdf0e10cSrcweir 			const primitive3d::Primitive3DSequence& rSubSequence = rModifiedCandidate.getChildren();
264cdf0e10cSrcweir 
265cdf0e10cSrcweir 			if(rSubSequence.hasElements())
266cdf0e10cSrcweir 			{
267cdf0e10cSrcweir 				// put modifier on stack
268cdf0e10cSrcweir 				maBColorModifierStack.push(rModifiedCandidate.getColorModifier());
269cdf0e10cSrcweir 
270cdf0e10cSrcweir 				// process sub-list
271cdf0e10cSrcweir 				process(rModifiedCandidate.getChildren());
272cdf0e10cSrcweir 
273cdf0e10cSrcweir 				// remove modifier from stack
274cdf0e10cSrcweir 				maBColorModifierStack.pop();
275cdf0e10cSrcweir 			}
276cdf0e10cSrcweir 		}
277cdf0e10cSrcweir 
278cdf0e10cSrcweir 		void DefaultProcessor3D::impRenderPolygonHairlinePrimitive3D(const primitive3d::PolygonHairlinePrimitive3D& rPrimitive)
279cdf0e10cSrcweir 		{
280cdf0e10cSrcweir 			basegfx::B3DPolygon aHairline(rPrimitive.getB3DPolygon());
281cdf0e10cSrcweir 
282cdf0e10cSrcweir 			if(aHairline.count())
283cdf0e10cSrcweir 			{
284cdf0e10cSrcweir 				// hairlines need no extra data, clear it
285cdf0e10cSrcweir 				aHairline.clearTextureCoordinates();
286cdf0e10cSrcweir 				aHairline.clearNormals();
287cdf0e10cSrcweir 				aHairline.clearBColors();
288cdf0e10cSrcweir 
289cdf0e10cSrcweir 				// transform to device coordinates (-1.0 .. 1.0) and check for visibility
290cdf0e10cSrcweir 				aHairline.transform(getViewInformation3D().getObjectToView());
291cdf0e10cSrcweir 				const basegfx::B3DRange a3DRange(basegfx::tools::getRange(aHairline));
292cdf0e10cSrcweir 				const basegfx::B2DRange a2DRange(a3DRange.getMinX(), a3DRange.getMinY(), a3DRange.getMaxX(), a3DRange.getMaxY());
293cdf0e10cSrcweir 
294cdf0e10cSrcweir 				if(a2DRange.overlaps(maRasterRange))
295cdf0e10cSrcweir 				{
296cdf0e10cSrcweir 					const attribute::MaterialAttribute3D aMaterial(maBColorModifierStack.getModifiedColor(rPrimitive.getBColor()));
297cdf0e10cSrcweir 
298cdf0e10cSrcweir 					rasterconvertB3DPolygon(aMaterial, aHairline);
299cdf0e10cSrcweir 				}
300cdf0e10cSrcweir 			}
301cdf0e10cSrcweir 		}
302cdf0e10cSrcweir 
303cdf0e10cSrcweir 		void DefaultProcessor3D::impRenderPolyPolygonMaterialPrimitive3D(const primitive3d::PolyPolygonMaterialPrimitive3D& rPrimitive)
304cdf0e10cSrcweir 		{
305cdf0e10cSrcweir 			basegfx::B3DPolyPolygon aFill(rPrimitive.getB3DPolyPolygon());
306cdf0e10cSrcweir 			basegfx::BColor aObjectColor(rPrimitive.getMaterial().getColor());
307cdf0e10cSrcweir 			bool bPaintIt(aFill.count());
308cdf0e10cSrcweir 
309cdf0e10cSrcweir 			// #i98295# get ShadeMode. Correct early when only flat is possible due to missing normals
310cdf0e10cSrcweir 			const ::com::sun::star::drawing::ShadeMode aShadeMode(
311cdf0e10cSrcweir 				aFill.areNormalsUsed() ?
312cdf0e10cSrcweir 					getSdrSceneAttribute().getShadeMode() : ::com::sun::star::drawing::ShadeMode_FLAT);
313cdf0e10cSrcweir 
314cdf0e10cSrcweir 			if(bPaintIt)
315cdf0e10cSrcweir 			{
316cdf0e10cSrcweir 				// get rid of texture coordinates if there is no texture
317cdf0e10cSrcweir 				if(aFill.areTextureCoordinatesUsed() && !getGeoTexSvx().get() && !getTransparenceGeoTexSvx().get())
318cdf0e10cSrcweir 				{
319cdf0e10cSrcweir 					aFill.clearTextureCoordinates();
320cdf0e10cSrcweir 				}
321cdf0e10cSrcweir 
322cdf0e10cSrcweir 				// #i98295# get rid of normals and color early when not needed
323cdf0e10cSrcweir 				if(::com::sun::star::drawing::ShadeMode_FLAT == aShadeMode)
324cdf0e10cSrcweir 				{
325cdf0e10cSrcweir 					aFill.clearNormals();
326cdf0e10cSrcweir 					aFill.clearBColors();
327cdf0e10cSrcweir 				}
328cdf0e10cSrcweir 
329cdf0e10cSrcweir 				// transform to device coordinates (-1.0 .. 1.0) and check for visibility
330cdf0e10cSrcweir 				aFill.transform(getViewInformation3D().getObjectToView());
331cdf0e10cSrcweir 				const basegfx::B3DRange a3DRange(basegfx::tools::getRange(aFill));
332cdf0e10cSrcweir 				const basegfx::B2DRange a2DRange(a3DRange.getMinX(), a3DRange.getMinY(), a3DRange.getMaxX(), a3DRange.getMaxY());
333cdf0e10cSrcweir 
334cdf0e10cSrcweir 				bPaintIt = a2DRange.overlaps(maRasterRange);
335cdf0e10cSrcweir 			}
336cdf0e10cSrcweir 
337cdf0e10cSrcweir 			// check if it shall be painted regarding hiding of normals (backface culling)
338cdf0e10cSrcweir 			if(bPaintIt && !rPrimitive.getDoubleSided())
339cdf0e10cSrcweir 			{
340cdf0e10cSrcweir 				// get plane normal of polygon in view coordinates (with ZBuffer values),
341cdf0e10cSrcweir 				// left-handed coordinate system
342cdf0e10cSrcweir 				const basegfx::B3DVector aPlaneNormal(aFill.getB3DPolygon(0L).getNormal());
343cdf0e10cSrcweir 
344cdf0e10cSrcweir 				if(aPlaneNormal.getZ() > 0.0)
345cdf0e10cSrcweir 				{
346cdf0e10cSrcweir 					bPaintIt = false;
347cdf0e10cSrcweir 				}
348cdf0e10cSrcweir 			}
349cdf0e10cSrcweir 
350cdf0e10cSrcweir 			if(bPaintIt)
351cdf0e10cSrcweir 			{
352cdf0e10cSrcweir 				// prepare ObjectToEye in NormalTransform
353cdf0e10cSrcweir 				basegfx::B3DHomMatrix aNormalTransform(getViewInformation3D().getOrientation() * getViewInformation3D().getObjectTransformation());
354cdf0e10cSrcweir 
355cdf0e10cSrcweir 				if(getSdrSceneAttribute().getTwoSidedLighting())
356cdf0e10cSrcweir 				{
357cdf0e10cSrcweir 					// get plane normal of polygon in view coordinates (with ZBuffer values),
358cdf0e10cSrcweir 					// left-handed coordinate system
359cdf0e10cSrcweir 					const basegfx::B3DVector aPlaneNormal(aFill.getB3DPolygon(0L).getNormal());
360cdf0e10cSrcweir 
361cdf0e10cSrcweir 					if(aPlaneNormal.getZ() > 0.0)
362cdf0e10cSrcweir 					{
363cdf0e10cSrcweir 						// mirror normals
364cdf0e10cSrcweir 						aNormalTransform.scale(-1.0, -1.0, -1.0);
365cdf0e10cSrcweir 					}
366cdf0e10cSrcweir 				}
367cdf0e10cSrcweir 
368cdf0e10cSrcweir 				switch(aShadeMode)
369cdf0e10cSrcweir 				{
370cdf0e10cSrcweir 					case ::com::sun::star::drawing::ShadeMode_PHONG:
371cdf0e10cSrcweir 					{
372cdf0e10cSrcweir 						// phong shading. Transform normals to eye coor
373cdf0e10cSrcweir 						aFill.transformNormals(aNormalTransform);
374cdf0e10cSrcweir 						break;
375cdf0e10cSrcweir 					}
376cdf0e10cSrcweir 					case ::com::sun::star::drawing::ShadeMode_SMOOTH:
377cdf0e10cSrcweir 					{
378cdf0e10cSrcweir 						// gouraud shading. Transform normals to eye coor
379cdf0e10cSrcweir 						aFill.transformNormals(aNormalTransform);
380cdf0e10cSrcweir 
381cdf0e10cSrcweir 						// prepare color model parameters, evtl. use blend color
382cdf0e10cSrcweir 						const basegfx::BColor aColor(getModulate() ? basegfx::BColor(1.0, 1.0, 1.0) : rPrimitive.getMaterial().getColor());
383cdf0e10cSrcweir 						const basegfx::BColor& rSpecular(rPrimitive.getMaterial().getSpecular());
384cdf0e10cSrcweir 						const basegfx::BColor& rEmission(rPrimitive.getMaterial().getEmission());
385cdf0e10cSrcweir 						const sal_uInt16 nSpecularIntensity(rPrimitive.getMaterial().getSpecularIntensity());
386cdf0e10cSrcweir 
387cdf0e10cSrcweir 						// solve color model for each normal vector, set colors at points. Clear normals.
388cdf0e10cSrcweir 						for(sal_uInt32 a(0L); a < aFill.count(); a++)
389cdf0e10cSrcweir 						{
390cdf0e10cSrcweir 							basegfx::B3DPolygon aPartFill(aFill.getB3DPolygon(a));
391cdf0e10cSrcweir 
392cdf0e10cSrcweir 							for(sal_uInt32 b(0L); b < aPartFill.count(); b++)
393cdf0e10cSrcweir 							{
394cdf0e10cSrcweir 								// solve color model. Transform normal to eye coor
395cdf0e10cSrcweir 								const basegfx::B3DVector aNormal(aPartFill.getNormal(b));
396cdf0e10cSrcweir 								const basegfx::BColor aSolvedColor(getSdrLightingAttribute().solveColorModel(aNormal, aColor, rSpecular, rEmission, nSpecularIntensity));
397cdf0e10cSrcweir 								aPartFill.setBColor(b, aSolvedColor);
398cdf0e10cSrcweir 							}
399cdf0e10cSrcweir 
400cdf0e10cSrcweir 							// clear normals on this part polygon and write it back
401cdf0e10cSrcweir 							aPartFill.clearNormals();
402cdf0e10cSrcweir 							aFill.setB3DPolygon(a, aPartFill);
403cdf0e10cSrcweir 						}
404cdf0e10cSrcweir 						break;
405cdf0e10cSrcweir 					}
406cdf0e10cSrcweir 					case ::com::sun::star::drawing::ShadeMode_FLAT:
407cdf0e10cSrcweir 					{
408cdf0e10cSrcweir 						// flat shading. Get plane vector in eye coordinates
409cdf0e10cSrcweir 						const basegfx::B3DVector aPlaneEyeNormal(aNormalTransform * rPrimitive.getB3DPolyPolygon().getB3DPolygon(0L).getNormal());
410cdf0e10cSrcweir 
411cdf0e10cSrcweir 						// prepare color model parameters, evtl. use blend color
412cdf0e10cSrcweir 						const basegfx::BColor aColor(getModulate() ? basegfx::BColor(1.0, 1.0, 1.0) : rPrimitive.getMaterial().getColor());
413cdf0e10cSrcweir 						const basegfx::BColor& rSpecular(rPrimitive.getMaterial().getSpecular());
414cdf0e10cSrcweir 						const basegfx::BColor& rEmission(rPrimitive.getMaterial().getEmission());
415cdf0e10cSrcweir 						const sal_uInt16 nSpecularIntensity(rPrimitive.getMaterial().getSpecularIntensity());
416cdf0e10cSrcweir 
417cdf0e10cSrcweir 						// solve color model for plane vector and use that color for whole plane
418cdf0e10cSrcweir 						aObjectColor = getSdrLightingAttribute().solveColorModel(aPlaneEyeNormal, aColor, rSpecular, rEmission, nSpecularIntensity);
419cdf0e10cSrcweir 						break;
420cdf0e10cSrcweir 					}
421cdf0e10cSrcweir 					default: // case ::com::sun::star::drawing::ShadeMode_DRAFT:
422cdf0e10cSrcweir 					{
423cdf0e10cSrcweir 						// draft, just use object color which is already set. Delete all other infos
424cdf0e10cSrcweir 						aFill.clearNormals();
425cdf0e10cSrcweir 						aFill.clearBColors();
426cdf0e10cSrcweir 						break;
427cdf0e10cSrcweir 					}
428cdf0e10cSrcweir 				}
429cdf0e10cSrcweir 
430cdf0e10cSrcweir 				// draw it to ZBuffer
431cdf0e10cSrcweir 				const attribute::MaterialAttribute3D aMaterial(
432cdf0e10cSrcweir 					maBColorModifierStack.getModifiedColor(aObjectColor),
433cdf0e10cSrcweir 					rPrimitive.getMaterial().getSpecular(),
434cdf0e10cSrcweir 					rPrimitive.getMaterial().getEmission(),
435cdf0e10cSrcweir 					rPrimitive.getMaterial().getSpecularIntensity());
436cdf0e10cSrcweir 
437cdf0e10cSrcweir 				rasterconvertB3DPolyPolygon(aMaterial, aFill);
438cdf0e10cSrcweir 			}
439cdf0e10cSrcweir 		}
440cdf0e10cSrcweir 
441cdf0e10cSrcweir 		void DefaultProcessor3D::impRenderTransformPrimitive3D(const primitive3d::TransformPrimitive3D& rTransformCandidate)
442cdf0e10cSrcweir 		{
443cdf0e10cSrcweir 			// transform group. Remember current transformations
444cdf0e10cSrcweir 			const geometry::ViewInformation3D aLastViewInformation3D(getViewInformation3D());
445cdf0e10cSrcweir 
446cdf0e10cSrcweir 			// create new transformation; add new object transform from right side
447cdf0e10cSrcweir 			const geometry::ViewInformation3D aNewViewInformation3D(
448cdf0e10cSrcweir 				aLastViewInformation3D.getObjectTransformation() * rTransformCandidate.getTransformation(),
449cdf0e10cSrcweir 				aLastViewInformation3D.getOrientation(),
450cdf0e10cSrcweir 				aLastViewInformation3D.getProjection(),
451cdf0e10cSrcweir 				aLastViewInformation3D.getDeviceToView(),
452cdf0e10cSrcweir 				aLastViewInformation3D.getViewTime(),
453cdf0e10cSrcweir 				aLastViewInformation3D.getExtendedInformationSequence());
454cdf0e10cSrcweir 			updateViewInformation(aNewViewInformation3D);
455cdf0e10cSrcweir 
456cdf0e10cSrcweir 			// let break down recursively
457cdf0e10cSrcweir 			process(rTransformCandidate.getChildren());
458cdf0e10cSrcweir 
459cdf0e10cSrcweir 			// restore transformations
460cdf0e10cSrcweir 			updateViewInformation(aLastViewInformation3D);
461cdf0e10cSrcweir 		}
462cdf0e10cSrcweir 
463cdf0e10cSrcweir 		void DefaultProcessor3D::processBasePrimitive3D(const primitive3d::BasePrimitive3D& rBasePrimitive)
464cdf0e10cSrcweir 		{
465cdf0e10cSrcweir 			// it is a BasePrimitive3D implementation, use getPrimitive3DID() call for switch
466cdf0e10cSrcweir 			switch(rBasePrimitive.getPrimitive3DID())
467cdf0e10cSrcweir 			{
468cdf0e10cSrcweir 				case PRIMITIVE3D_ID_GRADIENTTEXTUREPRIMITIVE3D :
469cdf0e10cSrcweir 				{
470cdf0e10cSrcweir 					// GradientTexturePrimitive3D
471cdf0e10cSrcweir 					const primitive3d::GradientTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::GradientTexturePrimitive3D& >(rBasePrimitive);
472cdf0e10cSrcweir 					impRenderGradientTexturePrimitive3D(rPrimitive, false);
473cdf0e10cSrcweir 					break;
474cdf0e10cSrcweir 				}
475cdf0e10cSrcweir 				case PRIMITIVE3D_ID_HATCHTEXTUREPRIMITIVE3D :
476cdf0e10cSrcweir 				{
477cdf0e10cSrcweir 					// HatchTexturePrimitive3D
478cdf0e10cSrcweir 					static bool bDoHatchDecomposition(false);
479cdf0e10cSrcweir 
480cdf0e10cSrcweir 					if(bDoHatchDecomposition)
481cdf0e10cSrcweir 					{
482cdf0e10cSrcweir 						// let break down
483cdf0e10cSrcweir 						process(rBasePrimitive.get3DDecomposition(getViewInformation3D()));
484cdf0e10cSrcweir 					}
485cdf0e10cSrcweir 					else
486cdf0e10cSrcweir 					{
487cdf0e10cSrcweir 						// hatchTexturePrimitive3D
488cdf0e10cSrcweir 						const primitive3d::HatchTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::HatchTexturePrimitive3D& >(rBasePrimitive);
489cdf0e10cSrcweir 						impRenderHatchTexturePrimitive3D(rPrimitive);
490cdf0e10cSrcweir 					}
491cdf0e10cSrcweir 					break;
492cdf0e10cSrcweir 				}
493cdf0e10cSrcweir 				case PRIMITIVE3D_ID_BITMAPTEXTUREPRIMITIVE3D :
494cdf0e10cSrcweir 				{
495cdf0e10cSrcweir 					// BitmapTexturePrimitive3D
496cdf0e10cSrcweir 					const primitive3d::BitmapTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::BitmapTexturePrimitive3D& >(rBasePrimitive);
497cdf0e10cSrcweir 					impRenderBitmapTexturePrimitive3D(rPrimitive);
498cdf0e10cSrcweir 					break;
499cdf0e10cSrcweir 				}
500cdf0e10cSrcweir 				case PRIMITIVE3D_ID_TRANSPARENCETEXTUREPRIMITIVE3D :
501cdf0e10cSrcweir 				{
502cdf0e10cSrcweir 					// TransparenceTexturePrimitive3D
503cdf0e10cSrcweir 					const primitive3d::TransparenceTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::TransparenceTexturePrimitive3D& >(rBasePrimitive);
504cdf0e10cSrcweir                     mnTransparenceCounter++;
505cdf0e10cSrcweir 					impRenderGradientTexturePrimitive3D(rPrimitive, true);
506cdf0e10cSrcweir                     mnTransparenceCounter--;
507cdf0e10cSrcweir 					break;
508cdf0e10cSrcweir 				}
509cdf0e10cSrcweir 				case PRIMITIVE3D_ID_MODIFIEDCOLORPRIMITIVE3D :
510cdf0e10cSrcweir 				{
511cdf0e10cSrcweir 					// ModifiedColorPrimitive3D
512cdf0e10cSrcweir 					// Force output to unified color.
513cdf0e10cSrcweir 					const primitive3d::ModifiedColorPrimitive3D& rPrimitive = static_cast< const primitive3d::ModifiedColorPrimitive3D& >(rBasePrimitive);
514cdf0e10cSrcweir 					impRenderModifiedColorPrimitive3D(rPrimitive);
515cdf0e10cSrcweir 					break;
516cdf0e10cSrcweir 				}
517cdf0e10cSrcweir 				case PRIMITIVE3D_ID_POLYGONHAIRLINEPRIMITIVE3D :
518cdf0e10cSrcweir 				{
519cdf0e10cSrcweir 					// directdraw of PolygonHairlinePrimitive3D
520cdf0e10cSrcweir 					const primitive3d::PolygonHairlinePrimitive3D& rPrimitive = static_cast< const primitive3d::PolygonHairlinePrimitive3D& >(rBasePrimitive);
521cdf0e10cSrcweir 					impRenderPolygonHairlinePrimitive3D(rPrimitive);
522cdf0e10cSrcweir 					break;
523cdf0e10cSrcweir 				}
524cdf0e10cSrcweir 				case PRIMITIVE3D_ID_POLYPOLYGONMATERIALPRIMITIVE3D :
525cdf0e10cSrcweir 				{
526cdf0e10cSrcweir 					// directdraw of PolyPolygonMaterialPrimitive3D
527cdf0e10cSrcweir 					const primitive3d::PolyPolygonMaterialPrimitive3D& rPrimitive = static_cast< const primitive3d::PolyPolygonMaterialPrimitive3D& >(rBasePrimitive);
528cdf0e10cSrcweir 					impRenderPolyPolygonMaterialPrimitive3D(rPrimitive);
529cdf0e10cSrcweir 					break;
530cdf0e10cSrcweir 				}
531cdf0e10cSrcweir 				case PRIMITIVE3D_ID_TRANSFORMPRIMITIVE3D :
532cdf0e10cSrcweir 				{
533cdf0e10cSrcweir 					// transform group (TransformPrimitive3D)
534cdf0e10cSrcweir 					impRenderTransformPrimitive3D(static_cast< const primitive3d::TransformPrimitive3D& >(rBasePrimitive));
535cdf0e10cSrcweir 					break;
536cdf0e10cSrcweir 				}
537cdf0e10cSrcweir 				default:
538cdf0e10cSrcweir 				{
539cdf0e10cSrcweir 					// process recursively
540cdf0e10cSrcweir 					process(rBasePrimitive.get3DDecomposition(getViewInformation3D()));
541cdf0e10cSrcweir 					break;
542cdf0e10cSrcweir 				}
543cdf0e10cSrcweir 			}
544cdf0e10cSrcweir 		}
545cdf0e10cSrcweir 
546cdf0e10cSrcweir 		DefaultProcessor3D::DefaultProcessor3D(
547cdf0e10cSrcweir 			const geometry::ViewInformation3D& rViewInformation,
548cdf0e10cSrcweir 			const attribute::SdrSceneAttribute& rSdrSceneAttribute,
549cdf0e10cSrcweir 			const attribute::SdrLightingAttribute& rSdrLightingAttribute)
550cdf0e10cSrcweir 		:	BaseProcessor3D(rViewInformation),
551cdf0e10cSrcweir 			mrSdrSceneAttribute(rSdrSceneAttribute),
552cdf0e10cSrcweir 			mrSdrLightingAttribute(rSdrLightingAttribute),
553cdf0e10cSrcweir 			maRasterRange(),
554cdf0e10cSrcweir 			maBColorModifierStack(),
555cdf0e10cSrcweir 			mpGeoTexSvx(),
556cdf0e10cSrcweir 			mpTransparenceGeoTexSvx(),
557cdf0e10cSrcweir             maDrawinglayerOpt(),
558cdf0e10cSrcweir             mnTransparenceCounter(0),
559cdf0e10cSrcweir 			mbModulate(false),
560cdf0e10cSrcweir 			mbFilter(false),
561cdf0e10cSrcweir 			mbSimpleTextureActive(false)
562cdf0e10cSrcweir 		{
563cdf0e10cSrcweir 			// a derivation has to set maRasterRange which is used in the basic render methods.
564cdf0e10cSrcweir 			// Setting to default here ([0.0 .. 1.0] in X,Y) to avoid problems
565cdf0e10cSrcweir 			maRasterRange.expand(basegfx::B2DTuple(0.0, 0.0));
566cdf0e10cSrcweir 			maRasterRange.expand(basegfx::B2DTuple(1.0, 1.0));
567cdf0e10cSrcweir 		}
568cdf0e10cSrcweir 
569cdf0e10cSrcweir 		DefaultProcessor3D::~DefaultProcessor3D()
570cdf0e10cSrcweir 		{
571cdf0e10cSrcweir 		}
572cdf0e10cSrcweir 	} // end of namespace processor3d
573cdf0e10cSrcweir } // end of namespace drawinglayer
574cdf0e10cSrcweir 
575cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
576cdf0e10cSrcweir // eof
577