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
|
/* -*- 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 <helperminimaldepth3d.hxx>
#include <drawinglayer/processor3d/baseprocessor3d.hxx>
#include <drawinglayer/primitive3d/drawinglayer_primitivetypes3d.hxx>
#include <drawinglayer/primitive3d/transformprimitive3d.hxx>
#include <drawinglayer/primitive3d/polygonprimitive3d.hxx>
#include <drawinglayer/primitive3d/polypolygonprimitive3d.hxx>
#include <svx/sdr/contact/viewcontactofe3d.hxx>
#include <svx/sdr/contact/viewcontactofe3dscene.hxx>
#include <svx/obj3d.hxx>
#include <svx/scene3d.hxx>
//////////////////////////////////////////////////////////////////////////////
namespace drawinglayer
{
namespace processor3d
{
class MinimalDephInViewExtractor : public BaseProcessor3D
{
private:
// the value which will be fetched as result
double mfMinimalDepth;
// as tooling, the process() implementation takes over API handling and calls this
// virtual render method when the primitive implementation is BasePrimitive3D-based.
virtual void processBasePrimitive3D(const primitive3d::BasePrimitive3D& rCandidate);
public:
MinimalDephInViewExtractor(const geometry::ViewInformation3D& rViewInformation)
: BaseProcessor3D(rViewInformation),
mfMinimalDepth(DBL_MAX)
{}
// data access
double getMinimalDepth() const { return mfMinimalDepth; }
};
void MinimalDephInViewExtractor::processBasePrimitive3D(const primitive3d::BasePrimitive3D& rCandidate)
{
// it is a BasePrimitive3D implementation, use getPrimitive3DID() call for switch
switch(rCandidate.getPrimitive3DID())
{
case PRIMITIVE3D_ID_TRANSFORMPRIMITIVE3D :
{
// transform group. Remember current transformations
const primitive3d::TransformPrimitive3D& rPrimitive = static_cast< const primitive3d::TransformPrimitive3D& >(rCandidate);
const geometry::ViewInformation3D aLastViewInformation3D(getViewInformation3D());
// create new transformation; add new object transform from right side
const geometry::ViewInformation3D aNewViewInformation3D(
aLastViewInformation3D.getObjectTransformation() * rPrimitive.getTransformation(),
aLastViewInformation3D.getOrientation(),
aLastViewInformation3D.getProjection(),
aLastViewInformation3D.getDeviceToView(),
aLastViewInformation3D.getViewTime(),
aLastViewInformation3D.getExtendedInformationSequence());
updateViewInformation(aNewViewInformation3D);
// let break down
process(rPrimitive.getChildren());
// restore transformations
updateViewInformation(aLastViewInformation3D);
break;
}
case PRIMITIVE3D_ID_POLYGONHAIRLINEPRIMITIVE3D :
{
// PolygonHairlinePrimitive3D
const primitive3d::PolygonHairlinePrimitive3D& rPrimitive = static_cast< const primitive3d::PolygonHairlinePrimitive3D& >(rCandidate);
const basegfx::B3DPolygon& rPolygon = rPrimitive.getB3DPolygon();
const sal_uInt32 nCount(rPolygon.count());
for(sal_uInt32 a(0); a < nCount; a++)
{
const basegfx::B3DPoint aPointInView(getViewInformation3D().getObjectToView() * rPolygon.getB3DPoint(a));
if(aPointInView.getZ() < mfMinimalDepth)
{
mfMinimalDepth = aPointInView.getZ();
}
}
break;
}
case PRIMITIVE3D_ID_POLYPOLYGONMATERIALPRIMITIVE3D :
{
// PolyPolygonMaterialPrimitive3D
const primitive3d::PolyPolygonMaterialPrimitive3D& rPrimitive = static_cast< const primitive3d::PolyPolygonMaterialPrimitive3D& >(rCandidate);
const basegfx::B3DPolyPolygon& rPolyPolygon = rPrimitive.getB3DPolyPolygon();
const sal_uInt32 nPolyCount(rPolyPolygon.count());
for(sal_uInt32 a(0); a < nPolyCount; a++)
{
const basegfx::B3DPolygon aPolygon(rPolyPolygon.getB3DPolygon(a));
const sal_uInt32 nCount(aPolygon.count());
for(sal_uInt32 b(0); b < nCount; b++)
{
const basegfx::B3DPoint aPointInView(getViewInformation3D().getObjectToView() * aPolygon.getB3DPoint(b));
if(aPointInView.getZ() < mfMinimalDepth)
{
mfMinimalDepth = aPointInView.getZ();
}
}
}
break;
}
default :
{
// process recursively
process(rCandidate.get3DDecomposition(getViewInformation3D()));
break;
}
}
}
} // end of namespace processor3d
} // end of namespace drawinglayer
//////////////////////////////////////////////////////////////////////////////
// changed to create values using VCs, Primitive3DSequence and ViewInformation3D to allow
// removal of old 3D bucket geometry. There is one slight difference in the result, it's
// in [0.0 .. 1.0] for Z-Depth since the scaling of the scene as 2D object is no longer
// part of the 3D transformations. This could be added since the ViewContactOfE3dScene is
// given, but is not needed since the permutation of the depth values needs only be correct
// relative to each other
double getMinimalDepthInViewCoordinates(const E3dCompoundObject& rObject)
{
// this is a E3dCompoundObject, so it cannot be a scene (which is a E3dObject).
// Get primitive sequence using VC
const sdr::contact::ViewContactOfE3d& rVCObject = static_cast< sdr::contact::ViewContactOfE3d& >(rObject.GetViewContact());
const drawinglayer::primitive3d::Primitive3DSequence aPrimitives = rVCObject.getViewIndependentPrimitive3DSequence();
double fRetval(DBL_MAX);
if(aPrimitives.hasElements())
{
const E3dScene* pScene = rObject.GetScene();
if(pScene)
{
// get ViewInformation3D from scene using VC
const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pScene->GetViewContact());
const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D());
// the scene's object transformation is already part of aViewInfo3D.getObjectTransformation()
// for historical reasons (see ViewContactOfE3dScene::createViewInformation3D for more info)
// and the object's transform is part of aPrimitives (and taken into account when decomposing
// to PolygonHairlinePrimitive3D and PolyPolygonMaterialPrimitive3D). The missing part may be
// some Scene SdrObjects lying in-between which may need to be added. This is e.g. used in chart,
// and generally allowed in 3d scenes an their 3d object hierarchy
basegfx::B3DHomMatrix aInBetweenSceneMatrix;
E3dScene* pParentScene = dynamic_cast< E3dScene* >(rObject.GetParentObj());
while(pParentScene && pParentScene != pScene)
{
aInBetweenSceneMatrix = pParentScene->GetTransform() * aInBetweenSceneMatrix;
pParentScene = dynamic_cast< E3dScene* >(pParentScene->GetParentObj());
}
// build new ViewInformation containing all transforms
const drawinglayer::geometry::ViewInformation3D aNewViewInformation3D(
aViewInfo3D.getObjectTransformation() * aInBetweenSceneMatrix,
aViewInfo3D.getOrientation(),
aViewInfo3D.getProjection(),
aViewInfo3D.getDeviceToView(),
aViewInfo3D.getViewTime(),
aViewInfo3D.getExtendedInformationSequence());
// create extractor helper, proccess geometry and get return value
drawinglayer::processor3d::MinimalDephInViewExtractor aExtractor(aNewViewInformation3D);
aExtractor.process(aPrimitives);
fRetval = aExtractor.getMinimalDepth();
}
}
return fRetval;
}
//////////////////////////////////////////////////////////////////////////////
// eof
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|