1 /*************************************************************************
3 * OpenOffice.org - a multi-platform office productivity suite
5 * $RCSfile: hatchtextureprimitive3d.cxx,v $
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,
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
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
++)
75 const Primitive3DReference
xReference(aSource
[a
]);
79 // try to cast to BasePrimitive2D implementation
80 const BasePrimitive3D
* pBasePrimitive
= dynamic_cast< const BasePrimitive3D
* >(xReference
.get());
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
));
123 a3N
= aPartPoly
.getB3DPoint(c
);
126 else if(!b2X
&& !a2N
.equal(a2Candidate
))
128 a2X
= a2Candidate
- a2N
;
129 a3X
= aPartPoly
.getB3DPoint(c
) - a3N
;
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
;
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
:
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
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
);
256 // add reference to result
257 aDestination
.push_back(xReference
);
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
];
283 HatchTexturePrimitive3D::HatchTexturePrimitive3D(
284 const attribute::FillHatchAttribute
& rHatch
,
285 const Primitive3DSequence
& rChildren
,
286 const basegfx::B2DVector
& rTextureSize
,
289 : TexturePrimitive3D(rChildren
, rTextureSize
, bModulate
, bFilter
),
294 bool HatchTexturePrimitive3D::operator==(const BasePrimitive3D
& rPrimitive
) const
296 if(TexturePrimitive3D::operator==(rPrimitive
))
298 const HatchTexturePrimitive3D
& rCompare
= (HatchTexturePrimitive3D
&)rPrimitive
;
300 return (getHatch() == rCompare
.getHatch());
307 ImplPrimitrive3DIDBlock(HatchTexturePrimitive3D
, PRIMITIVE3D_ID_HATCHTEXTUREPRIMITIVE3D
)
309 } // end of namespace primitive3d
310 } // end of namespace drawinglayer
312 //////////////////////////////////////////////////////////////////////////////