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/processor3d/cutfindprocessor3d.hxx> 28 #include <drawinglayer/primitive3d/drawinglayer_primitivetypes3d.hxx> 29 #include <drawinglayer/primitive3d/transformprimitive3d.hxx> 30 #include <drawinglayer/primitive3d/hatchtextureprimitive3d.hxx> 31 #include <drawinglayer/primitive3d/polypolygonprimitive3d.hxx> 32 #include <basegfx/polygon/b3dpolygon.hxx> 33 #include <basegfx/polygon/b3dpolygontools.hxx> 34 #include <basegfx/polygon/b3dpolypolygontools.hxx> 35 #include <drawinglayer/primitive3d/hiddengeometryprimitive3d.hxx> 36 37 ////////////////////////////////////////////////////////////////////////////// 38 39 namespace drawinglayer 40 { 41 namespace processor3d 42 { CutFindProcessor(const geometry::ViewInformation3D & rViewInformation,const basegfx::B3DPoint & rFront,const basegfx::B3DPoint & rBack,bool bAnyHit)43 CutFindProcessor::CutFindProcessor(const geometry::ViewInformation3D& rViewInformation, 44 const basegfx::B3DPoint& rFront, 45 const basegfx::B3DPoint& rBack, 46 bool bAnyHit) 47 : BaseProcessor3D(rViewInformation), 48 maFront(rFront), 49 maBack(rBack), 50 maResult(), 51 maCombinedTransform(), 52 mbAnyHit(bAnyHit), 53 mbUseInvisiblePrimitiveContent(true) 54 { 55 } 56 processBasePrimitive3D(const primitive3d::BasePrimitive3D & rCandidate)57 void CutFindProcessor::processBasePrimitive3D(const primitive3d::BasePrimitive3D& rCandidate) 58 { 59 if(getAnyHit() && maResult.size()) 60 { 61 // stop processing as soon as a hit was recognized 62 return; 63 } 64 65 // it is a BasePrimitive3D implementation, use getPrimitive3DID() call for switch 66 switch(rCandidate.getPrimitive3DID()) 67 { 68 case PRIMITIVE3D_ID_TRANSFORMPRIMITIVE3D : 69 { 70 // transform group. 71 const primitive3d::TransformPrimitive3D& rPrimitive = static_cast< const primitive3d::TransformPrimitive3D& >(rCandidate); 72 73 // remember old and transform front, back to object coordinates 74 const basegfx::B3DPoint aLastFront(maFront); 75 const basegfx::B3DPoint aLastBack(maBack); 76 basegfx::B3DHomMatrix aInverseTrans(rPrimitive.getTransformation()); 77 aInverseTrans.invert(); 78 maFront *= aInverseTrans; 79 maBack *= aInverseTrans; 80 81 // remember current and create new transformation; add new object transform from right side 82 const geometry::ViewInformation3D aLastViewInformation3D(getViewInformation3D()); 83 const geometry::ViewInformation3D aNewViewInformation3D( 84 aLastViewInformation3D.getObjectTransformation() * rPrimitive.getTransformation(), 85 aLastViewInformation3D.getOrientation(), 86 aLastViewInformation3D.getProjection(), 87 aLastViewInformation3D.getDeviceToView(), 88 aLastViewInformation3D.getViewTime(), 89 aLastViewInformation3D.getExtendedInformationSequence()); 90 updateViewInformation(aNewViewInformation3D); 91 92 // #i102956# remember needed back-transform for found cuts (combine from right side) 93 const basegfx::B3DHomMatrix aLastCombinedTransform(maCombinedTransform); 94 maCombinedTransform = maCombinedTransform * rPrimitive.getTransformation(); 95 96 // let break down 97 process(rPrimitive.getChildren()); 98 99 // restore transformations and front, back 100 maCombinedTransform = aLastCombinedTransform; 101 updateViewInformation(aLastViewInformation3D); 102 maFront = aLastFront; 103 maBack = aLastBack; 104 break; 105 } 106 case PRIMITIVE3D_ID_POLYGONHAIRLINEPRIMITIVE3D : 107 { 108 // PolygonHairlinePrimitive3D, not used for hit test with planes, ignore. This 109 // means that also thick line expansion will not be hit-tested as 110 // PolyPolygonMaterialPrimitive3D 111 break; 112 } 113 case PRIMITIVE3D_ID_HATCHTEXTUREPRIMITIVE3D : 114 { 115 // #i97321# 116 // For HatchTexturePrimitive3D, do not use the decomposition since it will produce 117 // clipped hatch lines in 3D. It can be used when the hatch also has a filling, but for 118 // simplicity, just use the children which are the PolyPolygonMaterialPrimitive3D 119 // which define the hatched areas anyways; for HitTest this is more than adequate 120 const primitive3d::HatchTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::HatchTexturePrimitive3D& >(rCandidate); 121 process(rPrimitive.getChildren()); 122 break; 123 } 124 case PRIMITIVE3D_ID_HIDDENGEOMETRYPRIMITIVE3D : 125 { 126 // HiddenGeometryPrimitive3D; the default decomposition would return an empty seqence, 127 // so force this primitive to process it's children directly if the switch is set 128 // (which is the default). Else, ignore invisible content 129 const primitive3d::HiddenGeometryPrimitive3D& rHiddenGeometry(static_cast< const primitive3d::HiddenGeometryPrimitive3D& >(rCandidate)); 130 const primitive3d::Primitive3DSequence& rChildren = rHiddenGeometry.getChildren(); 131 132 if(rChildren.hasElements()) 133 { 134 if(getUseInvisiblePrimitiveContent()) 135 { 136 process(rChildren); 137 } 138 } 139 140 break; 141 } 142 case PRIMITIVE3D_ID_UNIFIEDTRANSPARENCETEXTUREPRIMITIVE3D : 143 { 144 const primitive3d::UnifiedTransparenceTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::UnifiedTransparenceTexturePrimitive3D& >(rCandidate); 145 const primitive3d::Primitive3DSequence rChildren = rPrimitive.getChildren(); 146 147 if(rChildren.getLength()) 148 { 149 if(1.0 <= rPrimitive.getTransparence()) 150 { 151 // not visible, but use for HitTest 152 if(getUseInvisiblePrimitiveContent()) 153 { 154 process(rChildren); 155 } 156 } 157 else if(rPrimitive.getTransparence() >= 0.0 && rPrimitive.getTransparence() < 1.0) 158 { 159 // visible; use content 160 process(rChildren); 161 } 162 } 163 164 break; 165 } 166 case PRIMITIVE3D_ID_POLYPOLYGONMATERIALPRIMITIVE3D : 167 { 168 // PolyPolygonMaterialPrimitive3D 169 const primitive3d::PolyPolygonMaterialPrimitive3D& rPrimitive = static_cast< const primitive3d::PolyPolygonMaterialPrimitive3D& >(rCandidate); 170 171 if(!maFront.equal(maBack)) 172 { 173 const basegfx::B3DPolyPolygon& rPolyPolygon = rPrimitive.getB3DPolyPolygon(); 174 const sal_uInt32 nPolyCount(rPolyPolygon.count()); 175 176 if(nPolyCount) 177 { 178 const basegfx::B3DPolygon aPolygon(rPolyPolygon.getB3DPolygon(0)); 179 const sal_uInt32 nPointCount(aPolygon.count()); 180 181 if(nPointCount > 2) 182 { 183 const basegfx::B3DVector aPlaneNormal(aPolygon.getNormal()); 184 185 if(!aPlaneNormal.equalZero()) 186 { 187 const basegfx::B3DPoint aPointOnPlane(aPolygon.getB3DPoint(0)); 188 double fCut(0.0); 189 190 if(basegfx::tools::getCutBetweenLineAndPlane(aPlaneNormal, aPointOnPlane, maFront, maBack, fCut)) 191 { 192 const basegfx::B3DPoint aCutPoint(basegfx::interpolate(maFront, maBack, fCut)); 193 194 if(basegfx::tools::isInside(rPolyPolygon, aCutPoint, false)) 195 { 196 // #i102956# add result. Do not forget to do this in the coordinate 197 // system the processor get started with, so use the collected 198 // combined transformation from processed TransformPrimitive3D's 199 maResult.push_back(maCombinedTransform * aCutPoint); 200 } 201 } 202 } 203 } 204 } 205 } 206 207 break; 208 } 209 default : 210 { 211 // process recursively 212 process(rCandidate.get3DDecomposition(getViewInformation3D())); 213 break; 214 } 215 } 216 } 217 } // end of namespace processor3d 218 } // end of namespace drawinglayer 219 220 ////////////////////////////////////////////////////////////////////////////// 221 // eof 222