1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_drawinglayer.hxx" 26 27 #include <drawinglayer/primitive2d/embedded3dprimitive2d.hxx> 28 #include <basegfx/polygon/b2dpolygon.hxx> 29 #include <basegfx/polygon/b2dpolygontools.hxx> 30 #include <basegfx/color/bcolor.hxx> 31 #include <drawinglayer/primitive2d/polygonprimitive2d.hxx> 32 #include <basegfx/tools/canvastools.hxx> 33 #include <drawinglayer/geometry/viewinformation2d.hxx> 34 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> 35 #include <drawinglayer/geometry/viewinformation3d.hxx> 36 #include <drawinglayer/processor3d/shadow3dextractor.hxx> 37 38 ////////////////////////////////////////////////////////////////////////////// 39 40 using namespace com::sun::star; 41 42 ////////////////////////////////////////////////////////////////////////////// 43 44 namespace drawinglayer 45 { 46 namespace primitive2d 47 { impGetShadow3D(const geometry::ViewInformation2D &) const48 bool Embedded3DPrimitive2D::impGetShadow3D(const geometry::ViewInformation2D& /*rViewInformation*/) const 49 { 50 osl::MutexGuard aGuard( m_aMutex ); 51 52 // create on demand 53 if(!mbShadow3DChecked && getChildren3D().hasElements()) 54 { 55 // create shadow extraction processor 56 processor3d::Shadow3DExtractingProcessor aShadowProcessor( 57 getViewInformation3D(), 58 getObjectTransformation(), 59 getLightNormal(), 60 getShadowSlant(), 61 getScene3DRange()); 62 63 // process local primitives 64 aShadowProcessor.process(getChildren3D()); 65 66 // fetch result and set checked flag 67 const_cast< Embedded3DPrimitive2D* >(this)->maShadowPrimitives = aShadowProcessor.getPrimitive2DSequence(); 68 const_cast< Embedded3DPrimitive2D* >(this)->mbShadow3DChecked = true; 69 } 70 71 // return if there are shadow primitives 72 return maShadowPrimitives.hasElements(); 73 } 74 create2DDecomposition(const geometry::ViewInformation2D & rViewInformation) const75 Primitive2DSequence Embedded3DPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const 76 { 77 // use info to create a yellow 2d rectangle, similar to empty 3d scenes and/or groups 78 const basegfx::B2DRange aLocal2DRange(getB2DRange(rViewInformation)); 79 const basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aLocal2DRange)); 80 const basegfx::BColor aYellow(1.0, 1.0, 0.0); 81 const Primitive2DReference xRef(new PolygonHairlinePrimitive2D(aOutline, aYellow)); 82 83 return Primitive2DSequence(&xRef, 1L); 84 } 85 Embedded3DPrimitive2D(const primitive3d::Primitive3DSequence & rxChildren3D,const basegfx::B2DHomMatrix & rObjectTransformation,const geometry::ViewInformation3D & rViewInformation3D,const basegfx::B3DVector & rLightNormal,double fShadowSlant,const basegfx::B3DRange & rScene3DRange)86 Embedded3DPrimitive2D::Embedded3DPrimitive2D( 87 const primitive3d::Primitive3DSequence& rxChildren3D, 88 const basegfx::B2DHomMatrix& rObjectTransformation, 89 const geometry::ViewInformation3D& rViewInformation3D, 90 const basegfx::B3DVector& rLightNormal, 91 double fShadowSlant, 92 const basegfx::B3DRange& rScene3DRange) 93 : BufferedDecompositionPrimitive2D(), 94 mxChildren3D(rxChildren3D), 95 maObjectTransformation(rObjectTransformation), 96 maViewInformation3D(rViewInformation3D), 97 maLightNormal(rLightNormal), 98 mfShadowSlant(fShadowSlant), 99 maScene3DRange(rScene3DRange), 100 maShadowPrimitives(), 101 maB2DRange(), 102 mbShadow3DChecked(false) 103 { 104 maLightNormal.normalize(); 105 } 106 operator ==(const BasePrimitive2D & rPrimitive) const107 bool Embedded3DPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 108 { 109 if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) 110 { 111 const Embedded3DPrimitive2D& rCompare = static_cast< const Embedded3DPrimitive2D& >(rPrimitive); 112 113 return (primitive3d::arePrimitive3DSequencesEqual(getChildren3D(), rCompare.getChildren3D()) 114 && getObjectTransformation() == rCompare.getObjectTransformation() 115 && getViewInformation3D() == rCompare.getViewInformation3D() 116 && getLightNormal() == rCompare.getLightNormal() 117 && getShadowSlant() == rCompare.getShadowSlant() 118 && getScene3DRange() == rCompare.getScene3DRange()); 119 } 120 121 return false; 122 } 123 getB2DRange(const geometry::ViewInformation2D & rViewInformation) const124 basegfx::B2DRange Embedded3DPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const 125 { 126 if(maB2DRange.isEmpty()) 127 { 128 // use the 3d transformation stack to create a projection of the 3D range 129 basegfx::B3DRange a3DRange(primitive3d::getB3DRangeFromPrimitive3DSequence(getChildren3D(), getViewInformation3D())); 130 a3DRange.transform(getViewInformation3D().getObjectToView()); 131 132 // create 2d range from projected 3d and transform with scene's object transformation 133 basegfx::B2DRange aNewRange; 134 aNewRange.expand(basegfx::B2DPoint(a3DRange.getMinX(), a3DRange.getMinY())); 135 aNewRange.expand(basegfx::B2DPoint(a3DRange.getMaxX(), a3DRange.getMaxY())); 136 aNewRange.transform(getObjectTransformation()); 137 138 // cehck for 3D shadows and their 2D projections. If those exist, they need to be 139 // taken into account 140 if(impGetShadow3D(rViewInformation)) 141 { 142 const basegfx::B2DRange aShadow2DRange(getB2DRangeFromPrimitive2DSequence(maShadowPrimitives, rViewInformation)); 143 144 if(!aShadow2DRange.isEmpty()) 145 { 146 aNewRange.expand(aShadow2DRange); 147 } 148 } 149 150 // assign to buffered value 151 const_cast< Embedded3DPrimitive2D* >(this)->maB2DRange = aNewRange; 152 } 153 154 return maB2DRange; 155 } 156 157 // provide unique ID 158 ImplPrimitrive2DIDBlock(Embedded3DPrimitive2D, PRIMITIVE2D_ID_EMBEDDED3DPRIMITIVE2D) 159 160 } // end of namespace primitive2d 161 } // end of namespace drawinglayer 162 163 ////////////////////////////////////////////////////////////////////////////// 164 // eof 165