1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_drawinglayer.hxx" 30 31 #include <drawinglayer/processor3d/cutfindprocessor3d.hxx> 32 #include <drawinglayer/primitive3d/drawinglayer_primitivetypes3d.hxx> 33 #include <drawinglayer/primitive3d/transformprimitive3d.hxx> 34 #include <drawinglayer/primitive3d/hatchtextureprimitive3d.hxx> 35 #include <drawinglayer/primitive3d/polypolygonprimitive3d.hxx> 36 #include <basegfx/polygon/b3dpolygon.hxx> 37 #include <basegfx/polygon/b3dpolygontools.hxx> 38 #include <basegfx/polygon/b3dpolypolygontools.hxx> 39 #include <drawinglayer/primitive3d/hiddengeometryprimitive3d.hxx> 40 41 ////////////////////////////////////////////////////////////////////////////// 42 43 namespace drawinglayer 44 { 45 namespace processor3d 46 { 47 CutFindProcessor::CutFindProcessor(const geometry::ViewInformation3D& rViewInformation, 48 const basegfx::B3DPoint& rFront, 49 const basegfx::B3DPoint& rBack, 50 bool bAnyHit) 51 : BaseProcessor3D(rViewInformation), 52 maFront(rFront), 53 maBack(rBack), 54 maResult(), 55 maCombinedTransform(), 56 mbAnyHit(bAnyHit), 57 mbUseInvisiblePrimitiveContent(true) 58 { 59 } 60 61 void CutFindProcessor::processBasePrimitive3D(const primitive3d::BasePrimitive3D& rCandidate) 62 { 63 if(getAnyHit() && maResult.size()) 64 { 65 // stop processing as soon as a hit was recognized 66 return; 67 } 68 69 // it is a BasePrimitive3D implementation, use getPrimitive3DID() call for switch 70 switch(rCandidate.getPrimitive3DID()) 71 { 72 case PRIMITIVE3D_ID_TRANSFORMPRIMITIVE3D : 73 { 74 // transform group. 75 const primitive3d::TransformPrimitive3D& rPrimitive = static_cast< const primitive3d::TransformPrimitive3D& >(rCandidate); 76 77 // remember old and transform front, back to object coordinates 78 const basegfx::B3DPoint aLastFront(maFront); 79 const basegfx::B3DPoint aLastBack(maBack); 80 basegfx::B3DHomMatrix aInverseTrans(rPrimitive.getTransformation()); 81 aInverseTrans.invert(); 82 maFront *= aInverseTrans; 83 maBack *= aInverseTrans; 84 85 // remember current and create new transformation; add new object transform from right side 86 const geometry::ViewInformation3D aLastViewInformation3D(getViewInformation3D()); 87 const geometry::ViewInformation3D aNewViewInformation3D( 88 aLastViewInformation3D.getObjectTransformation() * rPrimitive.getTransformation(), 89 aLastViewInformation3D.getOrientation(), 90 aLastViewInformation3D.getProjection(), 91 aLastViewInformation3D.getDeviceToView(), 92 aLastViewInformation3D.getViewTime(), 93 aLastViewInformation3D.getExtendedInformationSequence()); 94 updateViewInformation(aNewViewInformation3D); 95 96 // #i102956# remember needed back-transform for found cuts (combine from right side) 97 const basegfx::B3DHomMatrix aLastCombinedTransform(maCombinedTransform); 98 maCombinedTransform = maCombinedTransform * rPrimitive.getTransformation(); 99 100 // let break down 101 process(rPrimitive.getChildren()); 102 103 // restore transformations and front, back 104 maCombinedTransform = aLastCombinedTransform; 105 updateViewInformation(aLastViewInformation3D); 106 maFront = aLastFront; 107 maBack = aLastBack; 108 break; 109 } 110 case PRIMITIVE3D_ID_POLYGONHAIRLINEPRIMITIVE3D : 111 { 112 // PolygonHairlinePrimitive3D, not used for hit test with planes, ignore. This 113 // means that also thick line expansion will not be hit-tested as 114 // PolyPolygonMaterialPrimitive3D 115 break; 116 } 117 case PRIMITIVE3D_ID_HATCHTEXTUREPRIMITIVE3D : 118 { 119 // #i97321# 120 // For HatchTexturePrimitive3D, do not use the decomposition since it will produce 121 // clipped hatch lines in 3D. It can be used when the hatch also has a filling, but for 122 // simplicity, just use the children which are the PolyPolygonMaterialPrimitive3D 123 // which define the hatched areas anyways; for HitTest this is more than adequate 124 const primitive3d::HatchTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::HatchTexturePrimitive3D& >(rCandidate); 125 process(rPrimitive.getChildren()); 126 break; 127 } 128 case PRIMITIVE3D_ID_HIDDENGEOMETRYPRIMITIVE3D : 129 { 130 // HiddenGeometryPrimitive3D; the default decomposition would return an empty seqence, 131 // so force this primitive to process it's children directly if the switch is set 132 // (which is the default). Else, ignore invisible content 133 const primitive3d::HiddenGeometryPrimitive3D& rHiddenGeometry(static_cast< const primitive3d::HiddenGeometryPrimitive3D& >(rCandidate)); 134 const primitive3d::Primitive3DSequence& rChildren = rHiddenGeometry.getChildren(); 135 136 if(rChildren.hasElements()) 137 { 138 if(getUseInvisiblePrimitiveContent()) 139 { 140 process(rChildren); 141 } 142 } 143 144 break; 145 } 146 case PRIMITIVE3D_ID_UNIFIEDTRANSPARENCETEXTUREPRIMITIVE3D : 147 { 148 const primitive3d::UnifiedTransparenceTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::UnifiedTransparenceTexturePrimitive3D& >(rCandidate); 149 const primitive3d::Primitive3DSequence rChildren = rPrimitive.getChildren(); 150 151 if(rChildren.getLength()) 152 { 153 if(1.0 <= rPrimitive.getTransparence()) 154 { 155 // not visible, but use for HitTest 156 if(getUseInvisiblePrimitiveContent()) 157 { 158 process(rChildren); 159 } 160 } 161 else if(rPrimitive.getTransparence() >= 0.0 && rPrimitive.getTransparence() < 1.0) 162 { 163 // visible; use content 164 process(rChildren); 165 } 166 } 167 168 break; 169 } 170 case PRIMITIVE3D_ID_POLYPOLYGONMATERIALPRIMITIVE3D : 171 { 172 // PolyPolygonMaterialPrimitive3D 173 const primitive3d::PolyPolygonMaterialPrimitive3D& rPrimitive = static_cast< const primitive3d::PolyPolygonMaterialPrimitive3D& >(rCandidate); 174 175 if(!maFront.equal(maBack)) 176 { 177 const basegfx::B3DPolyPolygon& rPolyPolygon = rPrimitive.getB3DPolyPolygon(); 178 const sal_uInt32 nPolyCount(rPolyPolygon.count()); 179 180 if(nPolyCount) 181 { 182 const basegfx::B3DPolygon aPolygon(rPolyPolygon.getB3DPolygon(0)); 183 const sal_uInt32 nPointCount(aPolygon.count()); 184 185 if(nPointCount > 2) 186 { 187 const basegfx::B3DVector aPlaneNormal(aPolygon.getNormal()); 188 189 if(!aPlaneNormal.equalZero()) 190 { 191 const basegfx::B3DPoint aPointOnPlane(aPolygon.getB3DPoint(0)); 192 double fCut(0.0); 193 194 if(basegfx::tools::getCutBetweenLineAndPlane(aPlaneNormal, aPointOnPlane, maFront, maBack, fCut)) 195 { 196 const basegfx::B3DPoint aCutPoint(basegfx::interpolate(maFront, maBack, fCut)); 197 198 if(basegfx::tools::isInside(rPolyPolygon, aCutPoint, false)) 199 { 200 // #i102956# add result. Do not forget to do this in the coordinate 201 // system the processor get started with, so use the collected 202 // combined transformation from processed TransformPrimitive3D's 203 maResult.push_back(maCombinedTransform * aCutPoint); 204 } 205 } 206 } 207 } 208 } 209 } 210 211 break; 212 } 213 default : 214 { 215 // process recursively 216 process(rCandidate.get3DDecomposition(getViewInformation3D())); 217 break; 218 } 219 } 220 } 221 } // end of namespace processor3d 222 } // end of namespace drawinglayer 223 224 ////////////////////////////////////////////////////////////////////////////// 225 // eof 226