merge the formfield patch from ooo-build
[ooovba.git] / drawinglayer / source / primitive3d / hatchtextureprimitive3d.cxx
blob1bb44f98887db65b77f6acb651b0d48f5e2fc86a
1 /*************************************************************************
3 * OpenOffice.org - a multi-platform office productivity suite
5 * $RCSfile: hatchtextureprimitive3d.cxx,v $
7 * $Revision: 1.11 $
9 * last change: $Author: aw $ $Date: 2008-06-10 09:29:33 $
11 * The Contents of this file are made available subject to
12 * the terms of GNU Lesser General Public License Version 2.1.
15 * GNU Lesser General Public License Version 2.1
16 * =============================================
17 * Copyright 2005 by Sun Microsystems, Inc.
18 * 901 San Antonio Road, Palo Alto, CA 94303, USA
20 * This library is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU Lesser General Public
22 * License version 2.1, as published by the Free Software Foundation.
24 * This library is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 * Lesser General Public License for more details.
29 * You should have received a copy of the GNU Lesser General Public
30 * License along with this library; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
32 * MA 02111-1307 USA
34 ************************************************************************/
36 // MARKER(update_precomp.py): autogen include statement, do not remove
37 #include "precompiled_drawinglayer.hxx"
39 #include <drawinglayer/primitive3d/hatchtextureprimitive3d.hxx>
40 #include <drawinglayer/primitive3d/polypolygonprimitive3d.hxx>
41 #include <basegfx/polygon/b2dpolypolygon.hxx>
42 #include <basegfx/polygon/b3dpolygon.hxx>
43 #include <basegfx/polygon/b2dpolygon.hxx>
44 #include <basegfx/polygon/b2dpolypolygontools.hxx>
45 #include <basegfx/range/b2drange.hxx>
46 #include <drawinglayer/texture/texture.hxx>
47 #include <basegfx/polygon/b2dpolygonclipper.hxx>
48 #include <basegfx/matrix/b3dhommatrix.hxx>
49 #include <drawinglayer/primitive3d/polygonprimitive3d.hxx>
50 #include <drawinglayer/primitive3d/drawinglayer_primitivetypes3d.hxx>
52 //////////////////////////////////////////////////////////////////////////////
54 using namespace com::sun::star;
56 //////////////////////////////////////////////////////////////////////////////
58 namespace drawinglayer
60 namespace primitive3d
62 Primitive3DSequence HatchTexturePrimitive3D::createLocalDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const
64 Primitive3DSequence aRetval;
66 if(getChildren().hasElements())
68 const Primitive3DSequence aSource(getChildren());
69 const sal_uInt32 nSourceCount(aSource.getLength());
70 std::vector< Primitive3DReference > aDestination;
72 for(sal_uInt32 a(0); a < nSourceCount; a++)
74 // get reference
75 const Primitive3DReference xReference(aSource[a]);
77 if(xReference.is())
79 // try to cast to BasePrimitive2D implementation
80 const BasePrimitive3D* pBasePrimitive = dynamic_cast< const BasePrimitive3D* >(xReference.get());
82 if(pBasePrimitive)
84 // it is a BasePrimitive3D implementation, use getPrimitiveID() call for switch
85 // not all content is needed, remove transparencies and ModifiedColorPrimitives
86 switch(pBasePrimitive->getPrimitiveID())
88 case PRIMITIVE3D_ID_POLYPOLYGONMATERIALPRIMITIVE3D :
90 // polyPolygonMaterialPrimitive3D, check texturing and hatching
91 const PolyPolygonMaterialPrimitive3D& rPrimitive = static_cast< const PolyPolygonMaterialPrimitive3D& >(*pBasePrimitive);
92 const basegfx::B3DPolyPolygon aFillPolyPolygon(rPrimitive.getB3DPolyPolygon());
94 if(maHatch.isFillBackground())
96 // add original primitive for background
97 aDestination.push_back(xReference);
100 if(aFillPolyPolygon.areTextureCoordinatesUsed())
102 const sal_uInt32 nPolyCount(aFillPolyPolygon.count());
103 basegfx::B2DPolyPolygon aTexPolyPolygon;
104 basegfx::B2DPoint a2N;
105 basegfx::B2DVector a2X, a2Y;
106 basegfx::B3DPoint a3N;
107 basegfx::B3DVector a3X, a3Y;
108 bool b2N(false), b2X(false), b2Y(false);
110 for(sal_uInt32 b(0); b < nPolyCount; b++)
112 const basegfx::B3DPolygon aPartPoly(aFillPolyPolygon.getB3DPolygon(b));
113 const sal_uInt32 nPointCount(aPartPoly.count());
114 basegfx::B2DPolygon aTexPolygon;
116 for(sal_uInt32 c(0); c < nPointCount; c++)
118 const basegfx::B2DPoint a2Candidate(aPartPoly.getTextureCoordinate(c));
120 if(!b2N)
122 a2N = a2Candidate;
123 a3N = aPartPoly.getB3DPoint(c);
124 b2N = true;
126 else if(!b2X && !a2N.equal(a2Candidate))
128 a2X = a2Candidate - a2N;
129 a3X = aPartPoly.getB3DPoint(c) - a3N;
130 b2X = true;
132 else if(!b2Y && !a2N.equal(a2Candidate) && !a2X.equal(a2Candidate))
134 a2Y = a2Candidate - a2N;
136 const double fCross(a2X.cross(a2Y));
138 if(!basegfx::fTools::equalZero(fCross))
140 a3Y = aPartPoly.getB3DPoint(c) - a3N;
141 b2Y = true;
145 aTexPolygon.append(a2Candidate);
148 aTexPolygon.setClosed(true);
149 aTexPolyPolygon.append(aTexPolygon);
152 if(b2N && b2X && b2Y)
154 // found two linearly independent 2D vectors
155 // get 2d range of texture coordinates
156 const basegfx::B2DRange aOutlineRange(basegfx::tools::getRange(aTexPolyPolygon));
157 const basegfx::BColor aHatchColor(getHatch().getColor());
158 const double fAngle(-getHatch().getAngle());
159 ::std::vector< basegfx::B2DHomMatrix > aMatrices;
161 // get hatch transformations
162 switch(getHatch().getStyle())
164 case attribute::HATCHSTYLE_TRIPLE:
166 // rotated 45 degrees
167 texture::GeoTexSvxHatch aHatch(aOutlineRange, getHatch().getDistance(), fAngle + F_PI4);
168 aHatch.appendTransformations(aMatrices);
170 case attribute::HATCHSTYLE_DOUBLE:
172 // rotated 90 degrees
173 texture::GeoTexSvxHatch aHatch(aOutlineRange, getHatch().getDistance(), fAngle + F_PI2);
174 aHatch.appendTransformations(aMatrices);
176 case attribute::HATCHSTYLE_SINGLE:
178 // angle as given
179 texture::GeoTexSvxHatch aHatch(aOutlineRange, getHatch().getDistance(), fAngle);
180 aHatch.appendTransformations(aMatrices);
184 // create geometry from unit line
185 basegfx::B2DPolyPolygon a2DHatchLines;
186 basegfx::B2DPolygon a2DUnitLine;
187 a2DUnitLine.append(basegfx::B2DPoint(0.0, 0.0));
188 a2DUnitLine.append(basegfx::B2DPoint(1.0, 0.0));
190 for(sal_uInt32 c(0); c < aMatrices.size(); c++)
192 const basegfx::B2DHomMatrix& rMatrix = aMatrices[c];
193 basegfx::B2DPolygon aNewLine(a2DUnitLine);
194 aNewLine.transform(rMatrix);
195 a2DHatchLines.append(aNewLine);
198 if(a2DHatchLines.count())
200 // clip against texture polygon
201 a2DHatchLines = basegfx::tools::clipPolyPolygonOnPolyPolygon(a2DHatchLines, aTexPolyPolygon, true, true);
204 if(a2DHatchLines.count())
206 // create 2d matrix with 2d vectors as column vectors and 2d point as offset, this represents
207 // a coordinate system transformation from unit coordinates to the new coordinate system
208 basegfx::B2DHomMatrix a2D;
209 a2D.set(0, 0, a2X.getX());
210 a2D.set(1, 0, a2X.getY());
211 a2D.set(0, 1, a2Y.getX());
212 a2D.set(1, 1, a2Y.getY());
213 a2D.set(0, 2, a2N.getX());
214 a2D.set(1, 2, a2N.getY());
216 // invert that transformation, so we have a back-transformation from texture coordinates
217 // to unit coordinates
218 a2D.invert();
219 a2DHatchLines.transform(a2D);
221 // expand back-transformated geometry tpo 3D
222 basegfx::B3DPolyPolygon a3DHatchLines(basegfx::tools::createB3DPolyPolygonFromB2DPolyPolygon(a2DHatchLines, 0.0));
224 // create 3d matrix with 3d vectors as column vectors (0,0,1 as Z) and 3d point as offset, this represents
225 // a coordinate system transformation from unit coordinates to the object's 3d coordinate system
226 basegfx::B3DHomMatrix a3D;
227 a3D.set(0, 0, a3X.getX());
228 a3D.set(1, 0, a3X.getY());
229 a3D.set(2, 0, a3X.getZ());
230 a3D.set(0, 1, a3Y.getX());
231 a3D.set(1, 1, a3Y.getY());
232 a3D.set(2, 1, a3Y.getZ());
233 a3D.set(0, 3, a3N.getX());
234 a3D.set(1, 3, a3N.getY());
235 a3D.set(2, 3, a3N.getZ());
237 // transform hatch lines to 3D object coordinates
238 a3DHatchLines.transform(a3D);
240 // build primitives from this geometry
241 const sal_uInt32 nHatchLines(a3DHatchLines.count());
243 for(sal_uInt32 d(0); d < nHatchLines; d++)
245 const Primitive3DReference xRef(new PolygonHairlinePrimitive3D(a3DHatchLines.getB3DPolygon(d), aHatchColor));
246 aDestination.push_back(xRef);
252 break;
254 default :
256 // add reference to result
257 aDestination.push_back(xReference);
258 break;
262 else
264 // unknown implementation, add to result
265 aDestination.push_back(xReference);
270 // prepare return value
271 const sal_uInt32 nDestSize(aDestination.size());
272 aRetval.realloc(nDestSize);
274 for(sal_uInt32 b(0); b < nDestSize; b++)
276 aRetval[b] = aDestination[b];
280 return aRetval;
283 HatchTexturePrimitive3D::HatchTexturePrimitive3D(
284 const attribute::FillHatchAttribute& rHatch,
285 const Primitive3DSequence& rChildren,
286 const basegfx::B2DVector& rTextureSize,
287 bool bModulate,
288 bool bFilter)
289 : TexturePrimitive3D(rChildren, rTextureSize, bModulate, bFilter),
290 maHatch(rHatch)
294 bool HatchTexturePrimitive3D::operator==(const BasePrimitive3D& rPrimitive) const
296 if(TexturePrimitive3D::operator==(rPrimitive))
298 const HatchTexturePrimitive3D& rCompare = (HatchTexturePrimitive3D&)rPrimitive;
300 return (getHatch() == rCompare.getHatch());
303 return false;
306 // provide unique ID
307 ImplPrimitrive3DIDBlock(HatchTexturePrimitive3D, PRIMITIVE3D_ID_HATCHTEXTUREPRIMITIVE3D)
309 } // end of namespace primitive3d
310 } // end of namespace drawinglayer
312 //////////////////////////////////////////////////////////////////////////////
313 // eof