summaryrefslogtreecommitdiff
path: root/svx/source/engine3d/polysc3d.cxx
diff options
context:
space:
mode:
authorJens-Heiner Rechtien <hr@openoffice.org>2000-09-18 16:07:07 +0000
committerJens-Heiner Rechtien <hr@openoffice.org>2000-09-18 16:07:07 +0000
commitf5b2b8667807673ee6e999f13ba7477efab32aa1 (patch)
treee7db8e756f4fd005bddcb9b694991cce5e37dc33 /svx/source/engine3d/polysc3d.cxx
parent9b5f06483e07c3254475f84080995290e30e9242 (diff)
initial import
Diffstat (limited to 'svx/source/engine3d/polysc3d.cxx')
-rw-r--r--svx/source/engine3d/polysc3d.cxx575
1 files changed, 575 insertions, 0 deletions
diff --git a/svx/source/engine3d/polysc3d.cxx b/svx/source/engine3d/polysc3d.cxx
new file mode 100644
index 0000000000..3ea740b9f5
--- /dev/null
+++ b/svx/source/engine3d/polysc3d.cxx
@@ -0,0 +1,575 @@
+/*************************************************************************
+ *
+ * $RCSfile: polysc3d.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:01:15 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SVX_FILLITEM_HXX
+#include "xfillit.hxx"
+#endif
+
+#ifndef _SVDOPATH_HXX //autogen
+#include "svdopath.hxx"
+#endif
+
+#ifndef _SVDOGRP_HXX //autogen
+#include "svdogrp.hxx"
+#endif
+
+#ifndef _SVDITER_HXX //autogen
+#include "svditer.hxx"
+#endif
+
+#ifndef _SVDETC_HXX //autogen
+#include "svdetc.hxx"
+#endif
+
+#ifndef _VIRDEV_HXX //autogen
+#include <vcl/virdev.hxx>
+#endif
+
+#ifndef _SV_SVAPP_HXX
+#include <vcl/svapp.hxx>
+#endif
+
+#ifndef _XOUTX_HXX
+#include "xoutx.hxx"
+#endif
+
+#ifndef _SVDPAGE_HXX
+#include "svdpage.hxx"
+#endif
+
+#ifndef _SVDPOOL_HXX
+#include "svdpool.hxx"
+#endif
+
+#ifndef _SFXSTYLE_HXX
+#include <svtools/style.hxx>
+#endif
+
+#ifndef _E3D_GLOBL3D_HXX
+#include "globl3d.hxx"
+#endif
+
+#ifndef _E3D_POLYSC3D_HXX
+#include "polysc3d.hxx"
+#endif
+
+#ifndef _E3D_PLIGHT3D_HXX
+#include "plight3d.hxx"
+#endif
+
+#ifndef _E3D_DLIGHT3D_HXX
+#include "dlight3d.hxx"
+#endif
+
+#ifndef _B3D_BASE3D_HXX
+#include <goodies/base3d.hxx>
+#endif
+
+#ifndef _B3D_B3DTEX_HXX
+#include <goodies/b3dtex.hxx>
+#endif
+
+#ifndef _SVX_XLNCLIT_HXX
+#include "xlnclit.hxx"
+#endif
+
+#ifndef _SFXMETRICITEM_HXX
+#include <svtools/metitem.hxx>
+#endif
+
+#ifndef _XTABLE_HXX
+#include "xtable.hxx"
+#endif
+
+#ifndef _SVX_XLNWTIT_HXX
+#include "xlnwtit.hxx"
+#endif
+
+#ifndef _SFXINIMGR_HXX
+#include <svtools/iniman.hxx>
+#endif
+
+#define ITEMVALUE(ItemSet,Id,Cast) ((const Cast&)(ItemSet).Get(Id)).GetValue()
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+TYPEINIT1(E3dPolyScene, E3dScene);
+
+E3dPolyScene::E3dPolyScene()
+: E3dScene()
+{
+}
+
+E3dPolyScene::E3dPolyScene(E3dDefaultAttributes& rDefault)
+: E3dScene(rDefault)
+{
+}
+
+/*************************************************************************
+|*
+|* Identifier zurueckgeben
+|*
+\************************************************************************/
+
+UINT16 E3dPolyScene::GetObjIdentifier() const
+{
+ return E3D_POLYSCENE_ID;
+}
+
+/*************************************************************************
+|*
+|* Die Kontur fuer TextToContour
+|*
+\************************************************************************/
+
+void E3dPolyScene::TakeContour(XPolyPolygon& rPoly) const
+{
+ ((E3dPolyScene*)this)->TakeContour3D(rPoly);
+}
+
+/*************************************************************************
+|*
+|* Objekt als Kontur in das Polygon einfuegen
+|*
+\************************************************************************/
+
+void E3dPolyScene::TakeContour3D(XPolyPolygon& rPoly)
+{
+ // TransformationSet vorbereiten
+ InitTransformationSet();
+
+ // Holen
+ E3dScene::TakeContour3D(rPoly);
+}
+
+/*************************************************************************
+|*
+|* Paint
+|*
+\************************************************************************/
+
+FASTBOOL E3dPolyScene::Paint(ExtOutputDevice& rOut,
+ const SdrPaintInfoRec& rInfoRec) const
+{
+ FASTBOOL bOk=TRUE;
+ if(GetSubList() && GetSubList()->GetObjCount())
+ {
+ bOk = ((E3dPolyScene*)this)->LocalPaint3D(rOut, rInfoRec);
+ }
+ else
+ {
+ // Leere Szene, zeichne genau wie leere Gruppe
+ if (!rInfoRec.bPrinter && rInfoRec.aPaintLayer.IsSet(nLayerId)) {
+ OutputDevice* pOutDev=rOut.GetOutDev();
+ pOutDev->SetLineColor(Color(COL_LIGHTGRAY));
+ pOutDev->SetFillColor();
+ pOutDev->DrawRect(aOutRect);
+ }
+ }
+ if (bOk && (rInfoRec.nPaintMode & SDRPAINTMODE_GLUEPOINTS) !=0) {
+ bOk=PaintGluePoints(rOut,rInfoRec);
+ }
+ return bOk;
+}
+
+BOOL E3dPolyScene::LocalPaint3D(ExtOutputDevice& rOut,
+ const SdrPaintInfoRec& rInfoRec)
+{
+ Time aStartTime;
+ Rectangle aBound(GetSnapRect());
+ OutputDevice* pOut = rOut.GetOutDev();
+ Base3D *pBase3D = Base3D::Create(pOut, GetForceDraftShadeModel());
+ DBG_ASSERT(pBase3D, "Habe keinen Base3D Kontext bekommen!!");
+ pBase3D->SetDisplayQuality(GetDisplayQuality());
+ pBase3D->SetShadeModel(GetShadeModel());
+
+ Rectangle aVisible(Point(0,0), pOut->GetOutputSizePixel());
+ aVisible = pOut->PixelToLogic(aVisible);
+
+ // Bei GDIMetaFiles falsches aVisible korrigieren
+ if((aVisible.Left() == aVisible.Right() && aVisible.Top() == aVisible.Bottom())
+ || (aVisible.GetWidth() == 0L || aVisible.GetHeight() == 0L))
+ aVisible = aBound;
+
+ // Feststellen, ob transparente Teile enthalten sind
+ pBase3D->SetTransparentPartsContainedHint(AreThereTransparentParts());
+
+ // eventuell ScissorRegion setzen
+ pBase3D->ActivateScissorRegion(FALSE);
+ if(aBound != aVisible)
+ {
+ Rectangle aClipBound = aBound.GetIntersection(aVisible);
+ if(aClipBound != aBound)
+ {
+ pBase3D->SetScissorRegion(aClipBound);
+
+#ifdef DBG_UTIL // draw aClipBound for testing
+ static BOOL bDoDrawClipBoundForTesting(FALSE);
+ if(bDoDrawClipBoundForTesting)
+ {
+ OutputDevice* pOut = rOut.GetOutDev();
+
+ // red
+ pOut->SetLineColor(Color(COL_RED));
+ pOut->SetFillColor();
+ pOut->DrawRect(aClipBound);
+
+ Rectangle aClipBoundPixel = pOut->LogicToPixel(aClipBound);
+ BOOL bWasEnabled = pOut->IsMapModeEnabled();
+ pOut->EnableMapMode(FALSE);
+
+ // GREEN
+ pOut->SetLineColor(Color(COL_GREEN));
+ pOut->SetFillColor();
+ pOut->DrawRect(aClipBoundPixel);
+
+ pOut->EnableMapMode(bWasEnabled);
+ }
+#endif
+ }
+ }
+
+ // GeometricSet reset und mit pBase3D assoziieren
+ B3dCamera& rSet = GetCameraSet();
+ pBase3D->SetTransformationSet(&rSet);
+
+ // Dithering
+ String aTmp = SfxIniManager::Get()->Get( SFX_KEY_3D_DITHERING );
+ BOOL bGlobalDither = (aTmp.Len() && aTmp.GetChar(0) != sal_Unicode('0'));
+ pBase3D->SetDither(GetDither() && bGlobalDither);
+
+ // Licht setzen, vor Object->World setzen, um Lichter im
+ // WKS zu positionieren
+ pBase3D->SetLightGroup(&(GetLightGroup()));
+
+ // Transformation initialisieren
+ InitTransformationSet();
+
+ // Viewport-Grenzen eintragen
+ rSet.SetViewportRectangle(aBound, aVisible);
+
+ // Matritzen aktualisieren (OpenGL)
+ pBase3D->SetTransformationSet(&rSet);
+
+ if(!pBase3D->GetDisplayQuality())
+ {
+ // Extrem verminderte Darstellungsqualitaet, zeichne als
+ // WireFrame, voellig OHNE renderer
+ DrawWireframe(pBase3D, rOut);
+ }
+ else
+ {
+ // Schatten zeichnen
+ if(pBase3D->GetDisplayQuality() > 128)
+ {
+ B3dVolume aVol = rSet.GetDeviceVolume();
+ Volume3D aVolume(aVol.MinVec(), aVol.MaxVec());
+ DrawAllShadows(pBase3D, rOut, aBound, aVolume, rInfoRec);
+ }
+
+ // Szene mit clipping zeichnen
+ DrawPolySceneClip(rOut, this, pBase3D, rInfoRec);
+ }
+
+ // Labels darueber zeichnen. Da es auch Wertebeschriftungen
+ // im Chart gibt, ist es besser, die Labels hinterher zu zeichnen.
+ // Leider kann es auch dabei zu Zeichenfehlern kommen. Die
+ // LabelObjekte muessen irgendwann mal auf echte 3D-Objekte
+ // umgestellt werden.
+ SdrObjList* pSubList = GetSubList();
+ if(pSubList)
+ {
+ SdrObjListIter a3DIterator(*pSubList, IM_DEEPWITHGROUPS);
+ while ( a3DIterator.IsMore() )
+ {
+ E3dObject* pObj = (E3dObject*) a3DIterator.Next();
+ DBG_ASSERT(pObj->ISA(E3dObject), "In Szenen sind nur 3D-Objekte erlaubt!");
+
+ if(pObj->ISA(E3dLabelObj))
+ {
+ E3dLabelObj* pLabelObject = (E3dLabelObj*)pObj;
+ SdrObject* pLabel = (SdrObject*)pLabelObject->Get2DLabelObj();
+ const Vector3D aPos = rSet.WorldToViewCoor(pLabelObject->GetTransPosition());
+ Point a2DPos((long)(aPos.X() + 0.5), (long)(aPos.Y() + 0.5));
+ pLabel->NbcSetAnchorPos(a2DPos);
+ pLabel->Paint(rOut, rInfoRec);
+ }
+ }
+ }
+
+ // Zeichenzeit bestimmen
+ aPaintTime = Time().GetTime() - aStartTime.GetTime();
+
+ return TRUE;
+}
+
+/*************************************************************************
+|*
+|* Geometrie zeichnen mit clipping Beruecksichtigung
+|*
+\************************************************************************/
+
+void E3dPolyScene::DrawPolySceneClip(ExtOutputDevice& rOut,
+ const E3dObject* p3DObj, Base3D* pBase3D, const SdrPaintInfoRec& rInfoRec)
+{
+ // spezielles Clipping fuer OpenGL, um keine floating windows ueberzumalen
+ OutputDevice* pOut = rOut.GetOutDev();
+
+ if(pBase3D->GetBase3DType() == BASE3D_TYPE_OPENGL
+ && pOut->GetOutDevType() == OUTDEV_WINDOW
+ && pBase3D->GetTransformationSet())
+ {
+ Window* pWin = (Window*)pOut;
+ RegionHandle aRegionHandle;
+ Rectangle aClipRect;
+ Rectangle aSystemClipRect;
+ BOOL bClippingWasActive(FALSE);
+ Region aClipRegion;
+
+#ifdef DBG_UTIL // ClipRegions zum testen zeichnen
+ static BOOL bDoDrawRegionsToMakeThemVisible = FALSE;
+ if(bDoDrawRegionsToMakeThemVisible)
+ {
+ // Rot
+ aClipRegion = pWin->GetWindowClipRegionPixel();
+
+ // Trick von TH, um das Umrechnen auf logische Koordinaten zu vermeiden
+ BOOL bMapModeWasSet = pWin->IsMapModeEnabled();
+ pWin->EnableMapMode(FALSE);
+
+ aClipRegion.Intersect(pWin->GetActiveClipRegion());
+ pWin->EnableMapMode(bMapModeWasSet);
+
+ aRegionHandle = aClipRegion.BeginEnumRects();
+
+ while(aClipRegion.GetEnumRects(aRegionHandle, aClipRect))
+ {
+ pOut->SetLineColor(Color(COL_RED));
+ pOut->SetFillColor();
+ pOut->DrawRect(aClipRect);
+ }
+ aClipRegion.EndEnumRects(aRegionHandle);
+ }
+#endif
+
+ // Eventuell bereits gesetzte ClipRegion sichern und zur Verwendung
+ // vorbereiten
+ if(pBase3D->IsScissorRegionActive())
+ {
+ aSystemClipRect = pBase3D->GetScissorRegionPixel();
+ bClippingWasActive = TRUE;
+ }
+
+ // ClipRegion holen und Durchlauf vorbereiten
+ aClipRegion = pWin->GetWindowClipRegionPixel();
+
+ // Trick von TH, um das Umrechnen auf logische Koordinaten zu vermeiden
+ BOOL bMapModeWasSet = pWin->IsMapModeEnabled();
+ pWin->EnableMapMode(FALSE);
+
+ aClipRegion.Intersect(pWin->GetActiveClipRegion());
+ pWin->EnableMapMode(bMapModeWasSet);
+
+ aRegionHandle = aClipRegion.BeginEnumRects();
+ Rectangle aBase3DRect = pWin->LogicToPixel(
+ pBase3D->GetTransformationSet()->GetLogicalViewportBounds());
+
+ // Lauf ueber die ClipRegions
+ while(aClipRegion.GetEnumRects(aRegionHandle, aClipRect))
+ {
+ if(aClipRect.IsOver(aBase3DRect))
+ {
+ // ClipRegion setzen
+ if(bClippingWasActive)
+ {
+ pBase3D->SetScissorRegionPixel(aClipRect.GetIntersection(aSystemClipRect), TRUE);
+ }
+ else
+ {
+ pBase3D->SetScissorRegionPixel(aClipRect, TRUE);
+ }
+
+ // Beginn szene
+ pBase3D->StartScene();
+
+ // Ausgabe aller 3D Objekte
+ Paint3D(rOut, pBase3D, rInfoRec, 0);
+
+ // Ende der Szene
+ UINT32 nWasDrawMode = rOut.GetOutDev()->GetDrawMode();
+ rOut.GetOutDev()->SetDrawMode(rInfoRec.nOriginalDrawMode);
+ pBase3D->EndScene();
+ rOut.GetOutDev()->SetDrawMode(nWasDrawMode);
+ }
+ }
+ aClipRegion.EndEnumRects(aRegionHandle);
+ }
+ else
+ {
+ // Ohne clipping ausgeben
+ // Beginn szene
+ pBase3D->StartScene();
+
+ // Ausgabe aller 3D Objekte
+ ((E3dPolyScene *)this)->Paint3D(rOut, pBase3D, rInfoRec, 0);
+
+ // Ende der Szene
+ UINT32 nWasDrawMode = rOut.GetOutDev()->GetDrawMode();
+ rOut.GetOutDev()->SetDrawMode(rInfoRec.nOriginalDrawMode);
+ pBase3D->EndScene();
+ rOut.GetOutDev()->SetDrawMode(nWasDrawMode);
+ }
+}
+
+/*************************************************************************
+|*
+|* Zeichenroutine fuer 3D
+|*
+\************************************************************************/
+
+void E3dPolyScene::Paint3D(ExtOutputDevice& rOut, Base3D* pBase3D,
+ const SdrPaintInfoRec& rInfoRec, UINT16 nDrawFlags)
+{
+ if(GetScene() != this)
+ {
+ // Szene in einer Szene, durchreichen
+ E3dObject::Paint3D(rOut, pBase3D, rInfoRec, nDrawFlags);
+ }
+ else
+ {
+ // Dies ist die Root-Szene
+ if(pBase3D->GetTransparentPartsContainedHint())
+ {
+ // Nicht-Transparente Flaechen
+ E3dObject::Paint3D(rOut, pBase3D, rInfoRec, E3D_DRAWFLAG_FILLED);
+
+ // Nicht-Transparente Linien
+ E3dObject::Paint3D(rOut, pBase3D, rInfoRec, E3D_DRAWFLAG_OUTLINE);
+
+ // Transparente Flaechen
+ E3dObject::Paint3D(rOut, pBase3D, rInfoRec, E3D_DRAWFLAG_FILLED|E3D_DRAWFLAG_TRANSPARENT);
+
+ // Transparente Linien
+ E3dObject::Paint3D(rOut, pBase3D, rInfoRec, E3D_DRAWFLAG_OUTLINE|E3D_DRAWFLAG_TRANSPARENT);
+ }
+ else
+ {
+ // call parent
+ E3dObject::Paint3D(rOut, pBase3D, rInfoRec, E3D_DRAWFLAG_FILLED|E3D_DRAWFLAG_OUTLINE);
+ }
+ }
+}
+
+/*************************************************************************
+|*
+|* Schatten aller Objekte zeichnen
+|*
+\************************************************************************/
+
+void E3dPolyScene::DrawAllShadows(Base3D* pBase3D, ExtOutputDevice& rXOut,
+ const Rectangle& rBound, const Volume3D& rVolume,
+ const SdrPaintInfoRec& rInfoRec)
+{
+ // TransformationSet vorbereiten
+ InitTransformationSet();
+
+ // Schatten Zeichnen
+ E3dScene::DrawShadows(pBase3D, rXOut, rBound, rVolume, rInfoRec);
+}
+
+/*************************************************************************
+|*
+|* Verminderte Darstellungsqualitaet, zeichne als WireFrame OHNE renderer
+|*
+\************************************************************************/
+
+void E3dPolyScene::DrawWireframe(Base3D* pBase3D, ExtOutputDevice& rXOut)
+{
+ // Farben setzen
+ rXOut.GetOutDev()->SetLineColor(Color(COL_BLACK));
+ rXOut.GetOutDev()->SetFillColor();
+
+ // Unterobjekte darstellen
+ SdrObjList* pSubList = GetSubList();
+ if(pSubList)
+ {
+ SdrObjListIter a3DIterator(*pSubList, IM_DEEPWITHGROUPS);
+ while ( a3DIterator.IsMore() )
+ {
+ E3dObject* pObj = (E3dObject*) a3DIterator.Next();
+ DBG_ASSERT(pObj->ISA(E3dObject), "In Szenen sind nur 3D-Objekte erlaubt!");
+ if(pObj->ISA(E3dCompoundObject))
+ {
+ E3dCompoundObject* pCompObj = (E3dCompoundObject*)pObj;
+
+ // ObjectTrans setzen
+ Matrix4D mTransform = pCompObj->GetFullTransform();
+ GetCameraSet().SetObjectTrans(mTransform);
+ pBase3D->SetTransformationSet(&(GetScene()->GetCameraSet()));
+
+ // WireFrame eines einzelnen Objektes
+ pCompObj->DrawObjectWireframe(rXOut);
+ }
+ }
+ }
+}
+
+