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