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