Files
libreoffice/svx/source/engine3d/obj3d.cxx
Armin Weiss e5792a5438 3D values which were members of the 3D objects before are
implemented als items now. Some corrections and fixes for
the prior change from SetItems to ItemSets.
2000-11-07 11:58:28 +00:00

6247 lines
193 KiB
C++

/*************************************************************************
*
* $RCSfile: obj3d.cxx,v $
*
* $Revision: 1.5 $
*
* last change: $Author: aw $ $Date: 2000-11-07 12:52:01 $
*
* 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): _______________________________________
*
*
************************************************************************/
#define ITEMID_COLOR SID_ATTR_3D_LIGHTCOLOR
#include "svdstr.hrc"
#include "svdglob.hxx"
#ifndef _SOT_DTRANS_HXX
#include <sot/dtrans.hxx>
#endif
#ifndef _SVDVIEW_HXX
#include "svdview.hxx"
#endif
#ifndef _SVDATTR_HXX
#include "svdattr.hxx"
#endif
#ifndef _SVDPAGE_HXX
#include "svdpage.hxx"
#endif
#ifndef _SVDIO_HXX
#include "svdio.hxx"
#endif
#ifndef _SVDMODEL_HXX
#include "svdmodel.hxx"
#endif
#ifndef _SVDITER_HXX
#include "svditer.hxx"
#endif
#ifndef _E3D_GLOBL3D_HXX
#include "globl3d.hxx"
#endif
#ifndef _CAMERA3D_HXX
#include "camera3d.hxx"
#endif
#ifndef _E3D_VOLMRK3D_HXX
#include "volmrk3d.hxx"
#endif
#ifndef _E3D_POLYOB3D_HXX
#include "polyob3d.hxx"
#endif
#ifndef _E3D_SCENE3D_HXX
#include "scene3d.hxx"
#endif
#ifndef _E3D_POLYSC3D_HXX
#include "polysc3d.hxx"
#endif
#ifndef _E3D_CUBE3D_HXX
#include "cube3d.hxx"
#endif
#ifndef _E3D_LATHE3D_HXX
#include "lathe3d.hxx"
#endif
#ifndef _E3D_SPHERE3D_HXX
#include "sphere3d.hxx"
#endif
#ifndef _E3D_EXTRUD3D_HXX
#include "extrud3d.hxx"
#endif
#ifndef _E3D_OBJ3D_HXX
#include "obj3d.hxx"
#endif
#ifndef _XOUTX_HXX
#include "xoutx.hxx"
#endif
#ifndef _XTABLE_HXX
#include "xtable.hxx"
#endif
#ifndef _SVX_XFLCLIT_HXX
#include "xflclit.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_FILLITEM_HXX
#include "xfillit.hxx"
#endif
#ifndef _SVX_XLNWTIT_HXX
#include "xlnwtit.hxx"
#endif
#ifndef _SV_VIRDEV_HXX
#include <vcl/virdev.hxx>
#endif
#ifndef _SVDIO_HXX
#include "svdio.hxx"
#endif
#ifndef _SV_POLY_HXX
#include <vcl/poly.hxx>
#endif
#ifndef _B3D_B3DTRANS_HXX
#include "b3dtrans.hxx"
#endif
#ifndef _SVX_SVXIDS_HRC
#include "svxids.hrc"
#endif
#ifndef _SVX_COLRITEM_HXX
#include "colritem.hxx"
#endif
#ifndef _SVXE3DITEM_HXX
#include "e3ditem.hxx"
#endif
#ifndef _SVX_XLNTRIT_HXX
#include "xlntrit.hxx"
#endif
#ifndef _SVX_XFLTRIT_HXX
#include "xfltrit.hxx"
#endif
#ifndef _SVDPAGV_HXX
#include "svdpagv.hxx"
#endif
#ifndef _SV_GRADIENT_HXX
#include <vcl/gradient.hxx>
#endif
#ifndef _SV_METAACT_HXX
#include <vcl/metaact.hxx>
#endif
#ifndef _SVX3DITEMS_HXX
#include "svx3ditems.hxx"
#endif
#ifndef _SFX_WHITER_HXX
#include <svtools/whiter.hxx>
#endif
#ifndef _EEITEM_HXX
#include "eeitem.hxx"
#endif
#define ITEMVALUE(ItemSet,Id,Cast) ((const Cast&)(ItemSet).Get(Id)).GetValue()
/*************************************************************************
|*
|* Liste fuer 3D-Objekte
|*
\************************************************************************/
TYPEINIT1(E3dObjList, SdrObjList);
E3dObjList::E3dObjList(SdrModel* pNewModel, SdrPage* pNewPage, E3dObjList* pNewUpList)
: SdrObjList(pNewModel, pNewPage, pNewUpList)
{
}
E3dObjList::E3dObjList(const E3dObjList& rSrcList)
: SdrObjList(rSrcList)
{
}
E3dObjList::~E3dObjList()
{
}
void E3dObjList::NbcInsertObject(SdrObject* pObj, ULONG nPos, const SdrInsertReason* pReason)
{
// Owner holen
DBG_ASSERT(GetOwnerObj()->ISA(E3dObject), "AW: Einfuegen 3DObject in Parent != 3DObject");
// Ist es ueberhaupt ein 3D-Objekt?
if(pObj && pObj->ISA(E3dObject))
{
// Normales 3D Objekt, einfuegen mittels
// call parent
SdrObjList::NbcInsertObject(pObj, nPos, pReason);
}
else
{
// Kein 3D Objekt, fuege in Seite statt in Szene ein...
GetOwnerObj()->GetPage()->InsertObject(pObj, nPos);
}
}
SdrObject* E3dObjList::NbcRemoveObject(ULONG nObjNum)
{
// Owner holen
DBG_ASSERT(GetOwnerObj()->ISA(E3dObject), "AW: Entfernen 3DObject aus Parent != 3DObject");
E3dObject* pOwner = (E3dObject*)GetOwnerObj();
// call parent
SdrObject* pRetval = SdrObjList::NbcRemoveObject(nObjNum);
// FitSnapRectToBoundVol vorbereiten
if(GetOwnerObj() && GetOwnerObj()->ISA(E3dScene))
((E3dScene*)GetOwnerObj())->CorrectSceneDimensions();
return pRetval;
}
SdrObject* E3dObjList::RemoveObject(ULONG nObjNum)
{
// Owner holen
DBG_ASSERT(GetOwnerObj()->ISA(E3dObject), "AW: Entfernen 3DObject aus Parent != 3DObject");
E3dObject* pOwner = (E3dObject*)GetOwnerObj();
// call parent
SdrObject* pRetval = SdrObjList::RemoveObject(nObjNum);
// FitSnapRectToBoundVol vorbereiten
if(GetOwnerObj() && GetOwnerObj()->ISA(E3dScene))
((E3dScene*)GetOwnerObj())->CorrectSceneDimensions();
return pRetval;
}
/*************************************************************************
|*
|* Konstruktor
|*
\************************************************************************/
TYPEINIT1(E3dObject, SdrAttrObj);
E3dObject::E3dObject() :
nLogicalGroup(0),
nObjTreeLevel(0),
eDragDetail(E3DDETAIL_ONEBOX),
nPartOfParent(0),
bTfHasChanged(TRUE),
bBoundVolValid(TRUE),
bIsSelected(FALSE)
//-/ bAttrUseSubObjects(TRUE)
{
bIs3DObj = TRUE;
pSub = new E3dObjList(NULL, NULL);
pSub->SetOwnerObj(this);
pSub->SetListKind(SDROBJLIST_GROUPOBJ);
bClosedObj = TRUE;
}
/*************************************************************************
|*
|* Destruktor
|*
\************************************************************************/
E3dObject::~E3dObject()
{
delete pSub;
pSub = NULL;
}
/*************************************************************************
|*
|* Selektions-Flag setzen
|*
\************************************************************************/
void E3dObject::SetSelected(BOOL bNew)
{
// selbst setzen
bIsSelected = bNew;
// bei SubObjekten setzen
for ( ULONG i = 0; i < pSub->GetObjCount(); i++ )
{
if(pSub->GetObj(i) && pSub->GetObj(i)->ISA(E3dObject))
((E3dObject*)pSub->GetObj(i))->SetSelected(bNew);
}
}
/*************************************************************************
|*
|* Aufbrechen, default-Implementierungen
|*
\************************************************************************/
BOOL E3dObject::IsBreakObjPossible()
{
return FALSE;
}
SdrAttrObj* E3dObject::GetBreakObj()
{
return 0L;
}
/*************************************************************************
|*
|* SetRectsDirty muss ueber die lokale SdrSubList gehen
|*
\************************************************************************/
void E3dObject::SetRectsDirty(FASTBOOL bNotMyself)
{
// call parent
SdrAttrObj::SetRectsDirty(bNotMyself);
// Eigene SubListe AUCH behandeln
if(pSub && pSub->GetObjCount())
{
for (ULONG i = 0; i < pSub->GetObjCount(); i++)
{
SdrObject* pObj = pSub->GetObj(i);
DBG_ASSERT(pObj->ISA(E3dObject), "AW: In E3dObject sind nur 3D-Objekte erlaubt!");
((E3dObject*)pObj)->SetRectsDirty(bNotMyself);
}
}
}
/*************************************************************************
|*
|* Inventor zurueckgeben
|*
\************************************************************************/
UINT32 E3dObject::GetObjInventor() const
{
return E3dInventor;
}
/*************************************************************************
|*
|* Identifier zurueckgeben
|*
\************************************************************************/
UINT16 E3dObject::GetObjIdentifier() const
{
return E3D_OBJECT_ID;
}
/*************************************************************************
|*
|* Faehigkeiten des Objektes feststellen
|*
\************************************************************************/
void E3dObject::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
{
rInfo.bResizeFreeAllowed = TRUE;
rInfo.bResizePropAllowed = TRUE;
rInfo.bRotateFreeAllowed = TRUE;
rInfo.bRotate90Allowed = TRUE;
rInfo.bMirrorFreeAllowed = FALSE;
rInfo.bMirror45Allowed = FALSE;
rInfo.bMirror90Allowed = FALSE;
rInfo.bShearAllowed = FALSE;
rInfo.bCanConvToPath = FALSE;
// no transparence for 3d objects
rInfo.bTransparenceAllowed = FALSE;
// gradient depends on fillstyle
// BM *** check if SetItem is NULL ***
XFillStyle eFillStyle = ((XFillStyleItem&)(GetItem(XATTR_FILLSTYLE))).GetValue();
rInfo.bGradientAllowed = (eFillStyle == XFILL_GRADIENT);
// Umwandeln von 3D-Koerpern in Gruppe von Polygonen:
//
// Erst mal nicht moeglich, da die Erzeugung einer Gruppe von
// 2D-Polygonen notwendig waere, die tiefensortiert werden muessten,
// also bei Durchdringugnen auch gegeneinander geschnitten werden
// muessten. Auch die Texturkoorinaten waeren ein ungeloestes
// Problem.
rInfo.bCanConvToPoly = FALSE;
rInfo.bCanConvToContour = FALSE;
rInfo.bCanConvToPathLineToArea = FALSE;
rInfo.bCanConvToPolyLineToArea = FALSE;
}
/*************************************************************************
|*
|* Layer abfragen
|*
\************************************************************************/
SdrLayerID E3dObject::GetLayer() const
{
FASTBOOL bFirst = TRUE;
E3dObjList* pOL = pSub;
ULONG nObjCnt = pOL->GetObjCount();
SdrLayerID nLayer = SdrLayerID(nLayerID);
for ( ULONG i = 0; i < nObjCnt; i++ )
{
SdrLayerID nObjLayer;
if(pOL->GetObj(i)->ISA(E3dPolyObj))
nObjLayer = SdrLayerID(nLayerID);
else
nObjLayer = pOL->GetObj(i)->GetLayer();
if (bFirst)
{
nLayer = nObjLayer;
bFirst = FALSE;
}
else if ( nObjLayer != nLayer )
return 0;
}
return nLayer;
}
/*************************************************************************
|*
|* Layer setzen
|*
\************************************************************************/
void E3dObject::NbcSetLayer(SdrLayerID nLayer)
{
SdrAttrObj::NbcSetLayer(nLayer);
E3dObjList* pOL = pSub;
ULONG nObjCnt = pOL->GetObjCount();
ULONG i;
for ( i = 0; i < nObjCnt; i++ )
pOL->GetObj(i)->NbcSetLayer(nLayer);
}
/*************************************************************************
|*
|* ObjList auch an SubList setzen
|*
\************************************************************************/
void E3dObject::SetObjList(SdrObjList* pNewObjList)
{
SdrObject::SetObjList(pNewObjList);
pSub->SetUpList(pNewObjList);
}
/*************************************************************************
|*
|* Layer setzen
|*
\************************************************************************/
void E3dObject::SetPage(SdrPage* pNewPage)
{
SdrAttrObj::SetPage(pNewPage);
pSub->SetPage(pNewPage);
}
/*************************************************************************
|*
|* Layer setzen
|*
\************************************************************************/
void E3dObject::SetModel(SdrModel* pNewModel)
{
SdrAttrObj::SetModel(pNewModel);
pSub->SetModel(pNewModel);
}
/*************************************************************************
|*
|* resize object, used from old 2d interfaces, e.g. in Move/Scale dialog
|* (F4)
|*
\************************************************************************/
void E3dObject::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
{
// SdrAttrObj::NbcResize(rRef, xFact, yFact);
// Bewegung in X,Y im Augkoordinatensystem
E3dScene* pScene = GetScene();
if(pScene)
{
// pos ermitteln
B3dTransformationSet& rSet = pScene->GetCameraSet();
Vector3D aScaleCenter((double)rRef.X(), (double)rRef.Y(), 32768.0);
aScaleCenter = rSet.ViewToEyeCoor(aScaleCenter);
// scale-faktoren holen
double fScaleX = xFact;
double fScaleY = yFact;
// build transform
Matrix4D mFullTransform(GetFullTransform());
Matrix4D mTrans(mFullTransform);
mTrans *= rSet.GetOrientation();
mTrans.Translate(-aScaleCenter);
mTrans.Scale(fScaleX, fScaleY, 1.0);
mTrans.Translate(aScaleCenter);
mTrans *= rSet.GetInvOrientation();
mFullTransform.Invert();
mTrans *= mFullTransform;
// anwenden
Matrix4D mObjTrans(GetTransform());
mObjTrans *= mTrans;
SetTransform(mObjTrans);
// force new camera and SnapRect on scene, geometry may have really
// changed
pScene->CorrectSceneDimensions();
}
}
/*************************************************************************
|*
|* Objekt verschieben in 2D, wird bei Cursortasten benoetigt
|*
\************************************************************************/
void E3dObject::NbcMove(const Size& rSize)
{
// Bewegung in X,Y im Augkoordinatensystem
E3dScene* pScene = GetScene();
if(pScene)
{
// Abmessungen der Szene in 3D und 2D als Vergleich
Rectangle aRect = pScene->GetSnapRect();
// Transformation Weltkoordinaten bis eine VOR Objektkoordinaten holen
Matrix4D mInvDispTransform;
if(GetParentObj())
{
mInvDispTransform = GetParentObj()->GetFullTransform();
mInvDispTransform.Invert();
}
// BoundVolume von Weltkoordinaten in Eye-Koordinaten
B3dTransformationSet& rSet = pScene->GetCameraSet();
const Volume3D& rVol = pScene->GetBoundVolume();
Volume3D aEyeVol = rVol.GetTransformVolume(rSet.GetOrientation());
// relativen Bewegungsvektor in Augkoordinaten bilden
Vector3D aMove(
(double)rSize.Width() * aEyeVol.GetWidth() / (double)aRect.GetWidth(),
(double)-rSize.Height() * aEyeVol.GetHeight() / (double)aRect.GetHeight(),
0.0);
// Bewegungsvektor in lokale Koordinaten des Parents des Objektes
Vector3D aPos;
aMove = rSet.EyeToWorldCoor(aMove);
aMove *= mInvDispTransform;
aPos = rSet.EyeToWorldCoor(aPos);
aPos *= mInvDispTransform;
aMove = aMove - aPos;
// Transformieren
Translate(aMove);
// force new camera and SnapRect on scene, geometry may have really
// changed
pScene->CorrectSceneDimensions();
}
}
/*************************************************************************
|*
|* liefere die Sublist, aber nur dann, wenn darin Objekte enthalten sind !
|*
\************************************************************************/
SdrObjList* E3dObject::GetSubList() const
{
return pSub;
}
/*************************************************************************
|*
|* Anzahl der Handles zurueckgeben
|*
\************************************************************************/
USHORT E3dObject::GetHdlCount() const
{
// 8 Eckpunkte + 1 E3dVolumeMarker (= Wireframe-Darstellung)
return 9;
}
/*************************************************************************
|*
|* Handle-Liste fuellen
|*
\************************************************************************/
void E3dObject::AddToHdlList(SdrHdlList& rHdlList) const
{
XPolyPolygon aXPP(12);
XPolygon aLine(2);
E3dVolumeMarker* pVolMarker;
USHORT nPolyCnt;
((E3dObject*) this)->ImpCreateWireframePoly(aXPP, E3DDETAIL_ONEBOX);
nPolyCnt = aXPP.Count();
for ( USHORT i = 0; i < nPolyCnt; i += 3 )
{
rHdlList.AddHdl(new SdrHdl(aXPP[i][0], HDL_BWGT));
rHdlList.AddHdl(new SdrHdl(aXPP[i][1], HDL_BWGT));
}
if ( nPolyCnt > 0 )
{
pVolMarker = new E3dVolumeMarker(aXPP);
rHdlList.AddHdl(pVolMarker);
}
}
/*************************************************************************
|*
\************************************************************************/
FASTBOOL E3dObject::HasSpecialDrag() const
{
return TRUE;
}
/*************************************************************************
|*
|* Paint; wird z.Z. nicht benutzt, da das Paint ueber die
|* (2D-)Displayliste der Szene laeuft
|*
\************************************************************************/
void E3dObject::Paint3D(ExtOutputDevice& rOut, Base3D* pBase3D,
const SdrPaintInfoRec& rInfoRec, UINT16 nDrawFlags)
{
if(pSub && pSub->GetObjCount())
{
BOOL bWasNotActive = rInfoRec.bNotActive;
BOOL bIsEnteredGroup(FALSE);
if((rInfoRec.pPV && GetSubList() && rInfoRec.pPV->GetObjList() == GetSubList())
|| (rInfoRec.nPaintMode & SDRPAINTMODE_MASTERPAGE))
{
bIsEnteredGroup = TRUE;
}
if(bIsEnteredGroup && bWasNotActive)
{
// auf aktive Elemente schalten
((SdrPaintInfoRec&)rInfoRec).bNotActive = FALSE;
}
for (ULONG i = 0; i < pSub->GetObjCount(); i++)
{
SdrObject* pObj = pSub->GetObj(i);
DBG_ASSERT(pObj->ISA(E3dObject), "AW: In E3dObject sind nur 3D-Objekte erlaubt!");
((E3dObject*)pObj)->Paint3D(rOut, pBase3D, rInfoRec, nDrawFlags);
}
if(bIsEnteredGroup && bWasNotActive)
{
// Zurueck auf Ursprung, Zustand wieder verlassen
((SdrPaintInfoRec&)rInfoRec).bNotActive = TRUE;
}
}
}
/*************************************************************************
|*
|* Objekt als Kontur in das Polygon einfuegen
|*
\************************************************************************/
void E3dObject::TakeContour3D(XPolyPolygon& rPoly)
{
if(pSub && pSub->GetObjCount())
{
for (ULONG i = 0; i < pSub->GetObjCount(); i++)
{
SdrObject* pObj = pSub->GetObj(i);
DBG_ASSERT(pObj->ISA(E3dObject), "AW: In E3dObject sind nur 3D-Objekte erlaubt!");
((E3dObject*)pObj)->TakeContour3D(rPoly);
}
}
}
/*************************************************************************
|*
|* Schatten fuer 3D-Objekte zeichnen
|*
\************************************************************************/
void E3dObject::DrawShadows(Base3D *pBase3D,
ExtOutputDevice& rXOut,
const Rectangle& rBound, const Volume3D& rVolume,
const SdrPaintInfoRec& rInfoRec)
{
if(pSub && pSub->GetObjCount())
{
for (ULONG i = 0; i < pSub->GetObjCount(); i++)
{
SdrObject* pObj = pSub->GetObj(i);
DBG_ASSERT(pObj->ISA(E3dObject), "AW: In E3dObject sind nur 3D-Objekte erlaubt!");
((E3dObject*)pObj)->DrawShadows(pBase3D, rXOut, rBound, rVolume, rInfoRec);
}
}
}
/*************************************************************************
|*
|* SnapRect berechnen
|*
\************************************************************************/
void E3dObject::RecalcSnapRect()
{
maSnapRect = Rectangle();
if(pSub && pSub->GetObjCount())
{
for (ULONG i = 0; i < pSub->GetObjCount(); i++)
{
SdrObject* pObj = pSub->GetObj(i);
DBG_ASSERT(pObj->ISA(E3dObject), "AW: In E3dObject sind nur 3D-Objekte erlaubt!");
Rectangle aSubRect = ((E3dObject*)pObj)->GetSnapRect();
maSnapRect.Union(aSubRect);
}
}
}
/*************************************************************************
|*
|* BoundRect berechnen
|*
\************************************************************************/
void E3dObject::RecalcBoundRect()
{
// BoundRect aus SnapRect berechnen
aOutRect = GetSnapRect();
if(pSub && pSub->GetObjCount())
{
for (ULONG i = 0; i < pSub->GetObjCount(); i++)
{
SdrObject* pObj = pSub->GetObj(i);
DBG_ASSERT(pObj->ISA(E3dObject), "AW: In E3dObject sind nur 3D-Objekte erlaubt!");
Rectangle aSubRect = ((E3dObject*)pObj)->GetBoundRect();
aOutRect.Union(aSubRect);
}
}
}
/*************************************************************************
|*
|* Einfuegen eines 3D-Objekts an den Parent weitermelden, damit dieser
|* ggf. eine Sonderbehandlung fuer spezielle Objekte durchfuehren kann
|* (z.B. Light/Label in E3dScene)
|*
\************************************************************************/
void E3dObject::NewObjectInserted(const E3dObject* p3DObj)
{
if(GetParentObj())
GetParentObj()->NewObjectInserted(p3DObj);
}
/*************************************************************************
|*
|* Parent ueber Aenderung der Struktur (z.B. durch Transformation)
|* informieren; dabei wird das Objekt, in welchem die Aenderung
|* aufgetreten ist, uebergeben
|*
\************************************************************************/
void E3dObject::StructureChanged(const E3dObject* p3DObj)
{
if ( GetParentObj() )
{
// Wenn sich im Child das BoundVolume geaendert hat, muessen
// auch die der Parents angepasst werden
if ( !p3DObj->bBoundVolValid )
GetParentObj()->bBoundVolValid = FALSE;
GetParentObj()->StructureChanged(p3DObj);
}
}
/*************************************************************************
|*
|* 3D-Objekt einfuegen
|*
\************************************************************************/
void E3dObject::Insert3DObj(E3dObject* p3DObj)
{
DBG_ASSERT(p3DObj, "Insert3DObj mit NULL-Zeiger!");
p3DObj->SetObjTreeLevel(nObjTreeLevel + 1);
SdrPage* pPg = pPage;
pSub->InsertObject(p3DObj);
pPage = pPg;
bBoundVolValid = FALSE;
NewObjectInserted(p3DObj);
StructureChanged(this);
}
void E3dObject::Remove3DObj(E3dObject* p3DObj)
{
DBG_ASSERT(p3DObj, "Remove3DObj mit NULL-Zeiger!");
if(p3DObj->GetParentObj() == this)
{
SdrPage* pPg = pPage;
pSub->RemoveObject(p3DObj->GetOrdNum());
pPage = pPg;
bBoundVolValid = FALSE;
StructureChanged(this);
}
}
/*************************************************************************
|*
|* Linienattribute abfragen, ggf. vom Parent holen
|*
\************************************************************************/
//-/const XLineAttrSetItem* E3dObject::GetLineAttr() const
//-/{
//-/ const XLineAttrSetItem* pSetItem = pLineAttr;
//-/
//-/ if ( pSetItem == NULL && GetParentObj() )
//-/ pSetItem = GetParentObj()->GetLineAttr();
//-/
//-/ return pSetItem;
//-/}
/*************************************************************************
|*
|* Flaechenattribute abfragen, ggf. vom Parent holen
|*
\************************************************************************/
//-/const XFillAttrSetItem* E3dObject::GetFillAttr() const
//-/{
//-/ const XFillAttrSetItem* pSetItem = pFillAttr;
//-/
//-/ if ( pSetItem == NULL && GetParentObj() )
//-/ pSetItem = GetParentObj()->GetFillAttr();
//-/
//-/ return pSetItem;
//-/}
/*************************************************************************
|*
|* Parent holen
|*
\************************************************************************/
E3dObject* E3dObject::GetParentObj() const
{
E3dObject* pRetval = NULL;
if(GetObjList()
&& GetObjList()->GetOwnerObj()
&& GetObjList()->GetOwnerObj()->ISA(E3dObject))
pRetval = ((E3dObject*)GetObjList()->GetOwnerObj());
return pRetval;
}
/*************************************************************************
|*
|* Uebergeordnetes Szenenobjekt bestimmen
|*
\************************************************************************/
E3dScene* E3dObject::GetScene() const
{
if(GetParentObj())
return GetParentObj()->GetScene();
return NULL;
}
/*************************************************************************
|*
|* umschliessendes Volumen inklusive aller Kindobjekte berechnen
|*
\************************************************************************/
void E3dObject::RecalcBoundVolume()
{
E3dObjList* pOL = pSub;
ULONG nObjCnt = pOL->GetObjCount();
if(nObjCnt)
{
aBoundVol = Volume3D();
for (ULONG i = 0; i < nObjCnt; i++)
{
SdrObject* pObj = pOL->GetObj(i);
DBG_ASSERT(pObj->ISA(E3dObject), "In E3dObject sind nur 3D-Objekte erlaubt!");
// Bei den Kindobjekten auch die lokalen Transformationen
// beruecksichtigen
E3dObject* p3DObj = (E3dObject*) pObj;
const Volume3D& rVol = p3DObj->GetBoundVolume();
const Matrix4D& rTf = p3DObj->GetTransform();
aBoundVol.Union(rVol.GetTransformVolume(rTf));
}
aLocalBoundVol = aBoundVol;
}
else
{
aBoundVol = aLocalBoundVol;
}
bBoundVolValid = TRUE;
}
/*************************************************************************
|*
|* umschliessendes Volumen zurueckgeben und ggf. neu berechnen
|*
\************************************************************************/
const Volume3D& E3dObject::GetBoundVolume()
{
if ( !bBoundVolValid )
RecalcBoundVolume();
if(!aBoundVol.IsValid())
aBoundVol = Volume3D(Vector3D(), Vector3D());
return aBoundVol;
}
/*************************************************************************
|*
|* Mittelpunkt liefern
|*
\************************************************************************/
Vector3D E3dObject::GetCenter()
{
Volume3D aVolume = GetBoundVolume();
return (aVolume.MaxVec() + aVolume.MinVec()) / 2.0;
}
/*************************************************************************
|*
|* Aederung des BoundVolumes an alle Kindobjekte weitergeben
|*
\************************************************************************/
void E3dObject::SetBoundVolInvalid()
{
bBoundVolValid = FALSE;
E3dObjList* pOL = pSub;
ULONG nObjCnt = pOL->GetObjCount();
for (ULONG i = 0; i < nObjCnt; i++)
{
SdrObject* pObj = pOL->GetObj(i);
DBG_ASSERT(pObj->ISA(E3dObject), "In E3dObject sind nur 3D-Objekte erlaubt!");
((E3dObject*) pObj)->SetBoundVolInvalid();
}
}
/*************************************************************************
|*
|* Aederung der Transformation an alle Kindobjekte weitergeben
|*
\************************************************************************/
void E3dObject::SetTransformChanged()
{
bTfHasChanged = TRUE;
bBoundVolValid = FALSE;
E3dObjList* pOL = pSub;
ULONG nObjCnt = pOL->GetObjCount();
for (ULONG i = 0; i < nObjCnt; i++)
{
SdrObject* pObj = pOL->GetObj(i);
DBG_ASSERT(pObj->ISA(E3dObject), "In E3dObject sind nur 3D-Objekte erlaubt!");
((E3dObject*) pObj)->SetTransformChanged();
}
}
/*************************************************************************
|*
|* hierarchische Transformation ueber alle Parents bestimmen und mit
|* der uebergebenen Matrix verketten
|*
\************************************************************************/
void E3dObject::GetFullTransform(Matrix4D& rMatrix) const
{
if ( bTfHasChanged )
{
rMatrix *= aTfMatrix;
if ( GetParentObj() )
GetParentObj()->GetFullTransform(rMatrix);
}
else
rMatrix *= aFullTfMatrix;
}
/*************************************************************************
|*
|* hierarchische Transformation ueber alle Parents bestimmen, in
|* aFullTfMatrix ablegen und diese zurueckgeben
|*
\************************************************************************/
const Matrix4D& E3dObject::GetFullTransform()
{
if ( bTfHasChanged )
{
aFullTfMatrix = aTfMatrix;
if ( GetParentObj() )
aFullTfMatrix *= GetParentObj()->GetFullTransform();
bTfHasChanged = FALSE;
}
return aFullTfMatrix;
}
/*************************************************************************
|*
|* Transformationsmatrix abfragen
|*
\************************************************************************/
const Matrix4D& E3dObject::GetTransform() const
{
return aTfMatrix;
}
/*************************************************************************
|*
|* Transformationsmatrix setzen
|*
\************************************************************************/
void E3dObject::NbcSetTransform(const Matrix4D& rMatrix)
{
aTfMatrix = rMatrix;
SetTransformChanged();
StructureChanged(this);
}
/*************************************************************************
|*
|* Transformationsmatrix auf Einheitsmatrix zuruecksetzen
|*
\************************************************************************/
void E3dObject::NbcResetTransform()
{
aTfMatrix.Identity();
SetTransformChanged();
StructureChanged(this);
}
/*************************************************************************
|*
|* Transformationsmatrix setzen mit Repaint-Broadcast
|*
\************************************************************************/
void E3dObject::SetTransform(const Matrix4D& rMatrix)
{
SendRepaintBroadcast();
NbcSetTransform(rMatrix);
SetChanged();
SendRepaintBroadcast();
if (pUserCall != NULL) pUserCall->Changed(*this, SDRUSERCALL_RESIZE, Rectangle());
}
/*************************************************************************
|*
|* Transformationsmatrix zuruecksetzen mit Repaint-Broadcast
|*
\************************************************************************/
void E3dObject::ResetTransform()
{
SendRepaintBroadcast();
NbcResetTransform();
SetChanged();
SendRepaintBroadcast();
if (pUserCall != NULL) pUserCall->Changed(*this, SDRUSERCALL_RESIZE, Rectangle());
}
/*************************************************************************
|*
|* Translation
|*
\************************************************************************/
void E3dObject::NbcTranslate(const Vector3D& rTrans)
{
aTfMatrix.Translate(rTrans);
SetTransformChanged();
StructureChanged(this);
}
/*************************************************************************
|*
|* Translation mit Repaint-Broadcast
|*
\************************************************************************/
void E3dObject::Translate(const Vector3D& rTrans)
{
SendRepaintBroadcast();
NbcTranslate(rTrans);
SetChanged();
SendRepaintBroadcast();
if (pUserCall != NULL) pUserCall->Changed(*this, SDRUSERCALL_RESIZE, Rectangle());
}
/*************************************************************************
|*
|* Skalierungen
|*
\************************************************************************/
void E3dObject::NbcScaleX(double fSx)
{
aTfMatrix.ScaleX(fSx);
SetTransformChanged();
StructureChanged(this);
}
/************************************************************************/
void E3dObject::NbcScaleY(double fSy)
{
aTfMatrix.ScaleY(fSy);
SetTransformChanged();
StructureChanged(this);
}
/************************************************************************/
void E3dObject::NbcScaleZ(double fSz)
{
aTfMatrix.ScaleZ(fSz);
SetTransformChanged();
StructureChanged(this);
}
/************************************************************************/
void E3dObject::NbcScale(double fSx, double fSy, double fSz)
{
aTfMatrix.Scale(fSx, fSy, fSz);
SetTransformChanged();
StructureChanged(this);
}
/*************************************************************************
|*
|* gleichmaessige Skalierung
|*
\************************************************************************/
void E3dObject::NbcScale(double fS)
{
aTfMatrix.Scale(fS, fS, fS);
SetTransformChanged();
StructureChanged(this);
}
/*************************************************************************
|*
|* Skalierungen mit mit Repaint-Broadcast
|*
\************************************************************************/
void E3dObject::ScaleX(double fSx)
{
SendRepaintBroadcast();
NbcScaleX(fSx);
SetChanged();
SendRepaintBroadcast();
if (pUserCall != NULL) pUserCall->Changed(*this, SDRUSERCALL_RESIZE, Rectangle());
}
/************************************************************************/
void E3dObject::ScaleY(double fSy)
{
SendRepaintBroadcast();
NbcScaleY(fSy);
SetChanged();
SendRepaintBroadcast();
if (pUserCall != NULL) pUserCall->Changed(*this, SDRUSERCALL_RESIZE, Rectangle());
}
/************************************************************************/
void E3dObject::ScaleZ(double fSz)
{
SendRepaintBroadcast();
NbcScaleZ(fSz);
SetChanged();
SendRepaintBroadcast();
if (pUserCall != NULL) pUserCall->Changed(*this, SDRUSERCALL_RESIZE, Rectangle());
}
/************************************************************************/
void E3dObject::Scale(double fSx, double fSy, double fSz)
{
SendRepaintBroadcast();
NbcScale(fSx, fSy, fSz);
SetChanged();
SendRepaintBroadcast();
if (pUserCall != NULL) pUserCall->Changed(*this, SDRUSERCALL_RESIZE, Rectangle());
}
/************************************************************************/
void E3dObject::Scale(double fS)
{
SendRepaintBroadcast();
NbcScale(fS);
SetChanged();
SendRepaintBroadcast();
if (pUserCall != NULL) pUserCall->Changed(*this, SDRUSERCALL_RESIZE, Rectangle());
}
/*************************************************************************
|*
|* Rotationen mit Winkel in Radiant
|*
\************************************************************************/
void E3dObject::NbcRotateX(double fAng)
{
aTfMatrix.RotateX(fAng);
SetTransformChanged();
StructureChanged(this);
}
/************************************************************************/
void E3dObject::NbcRotateY(double fAng)
{
aTfMatrix.RotateY(fAng);
SetTransformChanged();
StructureChanged(this);
}
/************************************************************************/
void E3dObject::NbcRotateZ(double fAng)
{
aTfMatrix.RotateZ(fAng);
SetTransformChanged();
StructureChanged(this);
}
/*************************************************************************
|*
|* Rotationen mit Repaint-Broadcast
|*
\************************************************************************/
void E3dObject::RotateX(double fAng)
{
SendRepaintBroadcast();
NbcRotateX(fAng);
SetChanged();
SendRepaintBroadcast();
if (pUserCall != NULL) pUserCall->Changed(*this, SDRUSERCALL_RESIZE, Rectangle());
}
/************************************************************************/
void E3dObject::RotateY(double fAng)
{
SendRepaintBroadcast();
NbcRotateY(fAng);
SetChanged();
SendRepaintBroadcast();
if (pUserCall != NULL) pUserCall->Changed(*this, SDRUSERCALL_RESIZE, Rectangle());
}
/************************************************************************/
void E3dObject::RotateZ(double fAng)
{
SendRepaintBroadcast();
NbcRotateZ(fAng);
SetChanged();
SendRepaintBroadcast();
if (pUserCall != NULL) pUserCall->Changed(*this, SDRUSERCALL_RESIZE, Rectangle());
}
/*************************************************************************
|*
|* uebergebene Transformationsmatrix auf die Objektkoordinaten (bei
|* abgeleiteten Objekten), d.h. nicht auf die lokale Matrix, und auf
|* alle Childs anwenden
|*
\************************************************************************/
void E3dObject::ApplyTransform(const Matrix4D& rMatrix)
{
E3dObjList* pOL = pSub;
ULONG nObjCnt = pOL->GetObjCount();
for (ULONG i = 0; i < nObjCnt; i++)
{
SdrObject* pObj = pOL->GetObj(i);
DBG_ASSERT(pObj->ISA(E3dObject), "In E3dObject sind nur 3D-Objekte erlaubt!");
((E3dObject*) pObj)->ApplyTransform(rMatrix);
}
}
/*************************************************************************
|*
|* Objektbaum-Ebene des Objekts und aller Children setzen
|*
\************************************************************************/
void E3dObject::SetObjTreeLevel(USHORT nNewLevel)
{
nObjTreeLevel = nNewLevel;
nNewLevel++;
E3dObjList* pOL = pSub;
ULONG nObjCnt = pOL->GetObjCount();
for (ULONG i = 0; i < nObjCnt; i++)
{
SdrObject* pObj = pOL->GetObj(i);
DBG_ASSERT(pObj->ISA(E3dObject), "In E3dObject sind nur 3D-Objekte erlaubt!");
((E3dObject*) pObj)->SetObjTreeLevel(nNewLevel);
}
}
/*************************************************************************
|*
|* logische Gruppe setzen
|*
\************************************************************************/
void E3dObject::SetLogicalGroup(USHORT nGroup)
{
nLogicalGroup = nGroup;
}
/*************************************************************************
|*
|* Linien fuer die Wireframe-Darstellung des Objekts dem uebergebenen
|* Polygon3D hinzufuegen. Als default wird das BoundVolume verwendet.
|*
\************************************************************************/
void E3dObject::CreateWireframe(Polygon3D& rWirePoly, const Matrix4D* pTf,
E3dDragDetail eDetail)
{
if ( eDetail == E3DDETAIL_DEFAULT )
eDetail = eDragDetail;
if ( eDetail == E3DDETAIL_ALLBOXES || eDetail == E3DDETAIL_ALLLINES )
{
E3dObjList* pOL = pSub;
ULONG nObjCnt = pOL->GetObjCount();
for (ULONG i = 0; i < nObjCnt; i++)
{
E3dObject* pObj = (E3dObject*)pOL->GetObj(i);
DBG_ASSERT(pObj->ISA(E3dObject), "In E3dObject sind nur 3D-Objekte erlaubt!");
Matrix4D aLocalTf(pObj->GetTransform());
if(pTf)
aLocalTf *= *pTf;
pObj->CreateWireframe(rWirePoly, &aLocalTf, eDetail);
}
if(eDetail == E3DDETAIL_ALLBOXES && nObjCnt != 1)
GetBoundVolume().CreateWireframe(rWirePoly, pTf);
}
else
GetBoundVolume().CreateWireframe(rWirePoly, pTf);
}
/*************************************************************************
|*
|* Get the name of the object (singular)
|*
\************************************************************************/
void E3dObject::TakeObjNameSingul(XubString& rName) const
{
rName=ImpGetResStr(STR_ObjNameSingulObj3d);
}
/*************************************************************************
|*
|* Get the name of the object (plural)
|*
\************************************************************************/
void E3dObject::TakeObjNamePlural(XubString& rName) const
{
rName=ImpGetResStr(STR_ObjNamePluralObj3d);
}
/*************************************************************************
|*
|* Wireframe-XPolyPolygon erzeugen
|*
\************************************************************************/
void E3dObject::ImpCreateWireframePoly(XPolyPolygon& rXPP,
E3dDragDetail eDetail)
{
// Neue Methode
E3dScene* pScene = GetScene();
Polygon3D aPoly3D(24, 240);
XPolygon aLine(2);
USHORT nPntCnt;
// WireFrame herstellen
CreateWireframe(aPoly3D, NULL, eDetail);
nPntCnt = aPoly3D.GetPointCount();
if(pScene)
{
// Maximas holen in DeviceKoordinaten
Volume3D aVolume = pScene->FitInSnapRect();
// Maximas fuer Abbildung verwenden
pScene->GetCameraSet().SetDeviceVolume(aVolume, FALSE);
Matrix4D mTransform = GetFullTransform();
pScene->GetCameraSet().SetObjectTrans(mTransform);
if ( nPntCnt > 1 )
{
Vector3D aVec;
for ( USHORT i = 0; i < nPntCnt; i += 2 )
{
aVec = pScene->GetCameraSet().ObjectToViewCoor(aPoly3D[i]);
aLine[0] = Point((long)(aVec.X() + 0.5), (long)(aVec.Y() + 0.5));
aVec = pScene->GetCameraSet().ObjectToViewCoor(aPoly3D[i+1]);
aLine[1] = Point((long)(aVec.X() + 0.5), (long)(aVec.Y() + 0.5));
rXPP.Insert(aLine);
}
}
}
}
/*************************************************************************
|*
|* Drag-Polygon zurueckgeben
|*
\************************************************************************/
void E3dObject::TakeXorPoly(XPolyPolygon& rXPP, FASTBOOL bDetail) const
{
rXPP.Clear();
// Const mal wieder weg, da evtl. das BoundVolume neu generiert wird
static E3dDragDetail eDetail = E3DDETAIL_DEFAULT;
((E3dObject*) this)->ImpCreateWireframePoly(rXPP, eDetail);
}
/*************************************************************************
|*
|* Zuweisungsoperator
|*
\************************************************************************/
void E3dObject::operator=(const SdrObject& rObj)
{
// erstmal alle Childs kopieren
SdrAttrObj::operator=(rObj);
const E3dObject& r3DObj = (const E3dObject&) rObj;
if (r3DObj.GetSubList())
{
// feststellen, ob alle SubObjekte selektiert oder
// deselektiert sind
BOOL bAllSelected = TRUE;
BOOL bNoneSelected = TRUE;
UINT32 nObjCnt = r3DObj.GetSubList()->GetObjCount();
ULONG i;
for (i = 0; i < nObjCnt; i++)
{
SdrObject* pObj = r3DObj.GetSubList()->GetObj(i);
if(pObj && pObj->ISA(E3dObject))
{
E3dObject* p3DObj = (E3dObject*)pObj;
if(p3DObj->GetSelected())
bNoneSelected = FALSE;
else
bAllSelected = FALSE;
}
}
if(bAllSelected || bNoneSelected)
{
// Normales verhalten
pSub->CopyObjects(*r3DObj.GetSubList());
}
else
{
// Spezielle SubListe aufstellen, kopieren
SdrObjList aOwnSubList(*r3DObj.GetSubList());
// Alle nicht selektierten Objekte rausschmeissen
for(i = 0;i < aOwnSubList.GetObjCount();i++)
{
SdrObject* pObj = aOwnSubList.GetObj(i);
if(pObj && pObj->ISA(E3dObject))
{
E3dObject* p3DObj = (E3dObject*)pObj;
if(!p3DObj->GetSelected())
{
aOwnSubList.NbcRemoveObject(pObj->GetOrdNum());
i--;
delete pObj;
}
}
}
// jetzt diese Liste kopieren
pSub->CopyObjects(aOwnSubList);
// Hier noch ein FitSnapRect einleiten
if(ISA(E3dScene))
((E3dScene&)r3DObj).FitSnapRectToBoundVol();
}
}
// BoundVol kann uebernommen werden, da die Childs auch kopiert werden
bBoundVolValid = r3DObj.bBoundVolValid;
aBoundVol = r3DObj.aBoundVol;
aLocalBoundVol = r3DObj.aLocalBoundVol;
aTfMatrix = r3DObj.aTfMatrix;
nLogicalGroup = r3DObj.nLogicalGroup;
nObjTreeLevel = r3DObj.nObjTreeLevel;
nPartOfParent = r3DObj.nPartOfParent;
eDragDetail = r3DObj.eDragDetail;
// Da sich der Parent geaendert haben kann, Gesamttransformation beim
// naechsten Mal auf jeden Fall neu bestimmen
SetTransformChanged();
// Selektionsstatus kopieren
bIsSelected = r3DObj.bIsSelected;
}
/*************************************************************************
|*
|* Attribute setzen
|*
\************************************************************************/
//-/void E3dObject::Distribute3DAttributes(const SfxItemSet& rAttr)
//-/{
//-/}
//-/void E3dObject::NbcSetAttributes(const SfxItemSet& rAttr, FASTBOOL bReplaceAll)
//-/{
//-/ // call parent
//-/ if(!ISA(E3dScene))
//-/ SdrAttrObj::NbcSetAttributes(rAttr, bReplaceAll);
//-/
//-/ if(bAttrUseSubObjects)
//-/ {
//-/ E3dObjList* pOL = pSub;
//-/ ULONG nObjCnt = pOL->GetObjCount();
//-/ for ( ULONG i = 0; i < nObjCnt; i++ )
//-/ pOL->GetObj(i)->NbcSetAttributes(rAttr, bReplaceAll);
//-/ }
//-/ else
//-/ {
//-/ bAttrUseSubObjects = TRUE;
//-/ }
//-/ StructureChanged(this);
//-/}
/*************************************************************************
|*
|* Attribute abfragen
|*
\************************************************************************/
//-/void E3dObject::TakeAttributes(SfxItemSet& rAttr, FASTBOOL bMerge,
//-/ FASTBOOL bOnlyHardAttr) const
//-/{
//-/ // call parent (only with real 3d objects, not with groups)
//-/ if(!ISA(E3dScene))
//-/ SdrAttrObj::TakeAttributes(rAttr, bMerge, bOnlyHardAttr);
//-/
//-/ if(bAttrUseSubObjects)
//-/ {
//-/ E3dObjList* pOL = pSub;
//-/ ULONG nObjCnt = pOL->GetObjCount();
//-/ for ( ULONG i = 0; i < nObjCnt; i++ )
//-/ pOL->GetObj(i)->TakeAttributes(rAttr, TRUE, bOnlyHardAttr);
//-/ }
//-/ else
//-/ {
//-/ ((E3dObject*)this)->bAttrUseSubObjects = TRUE;
//-/ }
//-/}
//-/void E3dObject::Collect3DAttributes(SfxItemSet& rAttr) const
//-/{
//-/}
// ItemSet access
//-/SfxItemSet* E3dObject::CreateNewItemSet(SfxItemPool& rPool)
//-/{
//-/ return new SfxItemSet(rPool,
//-/ SDRATTR_START, SDRATTR_END,
//-/ SID_ATTR_3D_START, SID_ATTR_3D_END,
//-/ 0, 0);
//-/}
const SfxItemSet& E3dObject::GetItemSet() const
{
E3dScene* pScene = GetScene();
if(pScene && pScene != this)
{
SfxItemSet& rSet = (SfxItemSet&)SdrAttrObj::GetItemSet();
SfxItemSet aSet(*rSet.GetPool(), SDRATTR_3DSCENE_FIRST, SDRATTR_3DSCENE_LAST);
aSet.Put(pScene->E3dObject::GetItemSet());
//-/ rSet.MergeValues(aSet, TRUE);
SfxWhichIter aIter(aSet);
sal_uInt16 nWhich(aIter.FirstWhich());
while(nWhich)
{
const SfxPoolItem* pItem = NULL;
aSet.GetItemState(nWhich, TRUE, &pItem);
if(pItem)
{
if(pItem == (SfxPoolItem *)-1)
rSet.InvalidateItem(nWhich);
else
rSet.MergeValue(*pItem, TRUE);
}
nWhich = aIter.NextWhich();
}
}
return SdrAttrObj::GetItemSet();
}
//-/const SfxItemSet& E3dObject::GetItemSet() const
//-/{
//-/ // get base items from SdrAttrObj
//-/ SfxItemSet& rSet = (SfxItemSet&)SdrAttrObj::GetItemSet();
//-/
//-/ // add local 3D items of this object
//-/ Collect3DAttributes(rSet);
//-/
//-/ // add outmost scene (if available)
//-/ E3dScene* pScene = GetScene();
//-/ if(pScene)
//-/ pScene->Collect3DAttributes(rSet);
//-/
//-/ // return completed ItemSet
//-/ return rSet;
//-/}
void E3dObject::SetItem( const SfxPoolItem& rItem )
{
if(rItem.Which() >= SDRATTR_3DSCENE_FIRST && rItem.Which() <= SDRATTR_3DSCENE_LAST)
{
E3dScene* pScene = GetScene();
if(pScene && pScene != this)
{
pScene->E3dObject::SetItem(rItem);
}
}
SdrAttrObj::SetItem(rItem);
StructureChanged(this);
}
//-/void E3dObject::SetItem( const SfxPoolItem& rItem )
//-/{
//-/ // set base items
//-/ SdrAttrObj::SetItem(rItem);
//-/
//-/ // set local 3D attributes
//-/ const SfxItemSet& rSet = SdrAttrObj::GetItemSet();
//-/ Distribute3DAttributes(rSet);
//-/
//-/ // set at outmost scene (if available)
//-/ E3dScene* pScene = GetScene();
//-/ if(pScene)
//-/ pScene->Distribute3DAttributes(rSet);
//-/}
void E3dObject::ClearItem( USHORT nWhich )
{
if(nWhich >= SDRATTR_3DSCENE_FIRST && nWhich <= SDRATTR_3DSCENE_LAST)
{
E3dScene* pScene = GetScene();
if(pScene && pScene != this)
{
pScene->E3dObject::ClearItem(nWhich);
}
}
if(mpObjectItemSet)
{
SdrAttrObj::ClearItem(nWhich);
StructureChanged(this);
}
}
//-/void E3dObject::ClearItem( USHORT nWhich )
//-/{
//-/ if(mpObjectItemSet)
//-/ {
//-/ // clear base item
//-/ SdrAttrObj::ClearItem(nWhich);
//-/
//-/ // clear local 3D attributes
//-/ const SfxItemSet& rSet = SdrAttrObj::GetItemSet();
//-/ Distribute3DAttributes(rSet);
//-/
//-/ // clear at outmost scene (if available)
//-/ E3dScene* pScene = GetScene();
//-/ if(pScene)
//-/ pScene->Distribute3DAttributes(rSet);
//-/ }
//-/}
void E3dObject::SetItemSet( const SfxItemSet& rSet )
{
E3dScene* pScene = GetScene();
if(pScene && pScene != this)
{
pScene->E3dObject::SetItemSet(rSet);
}
// set base items
SdrAttrObj::SetItemSet(rSet);
StructureChanged(this);
}
//-/void E3dObject::SetItemSet( const SfxItemSet& rSet )
//-/{
//-/ // set base items
//-/ SdrAttrObj::SetItemSet(rSet);
//-/
//-/ // set local 3D attributes
//-/ Distribute3DAttributes(rSet);
//-/
//-/ // set at outmost scene (if available)
//-/ E3dScene* pScene = GetScene();
//-/ if(pScene)
//-/ pScene->Distribute3DAttributes(rSet);
//-/}
SfxItemSet* E3dObject::CreateNewItemSet(SfxItemPool& rPool)
{
// include ALL items, 2D and 3D
return new SfxItemSet(rPool,
// ranges from SdrAttrObj
SDRATTR_START, SDRATTRSET_SHADOW,
SDRATTRSET_OUTLINER, SDRATTRSET_MISC,
// ranges for 3D (object and scene)
SDRATTR_3D_FIRST, SDRATTR_3D_LAST,
// outliner and end
EE_ITEMS_START, EE_ITEMS_END,
0, 0);
}
/*************************************************************************
|*
|* StyleSheet setzen
|*
\************************************************************************/
void E3dObject::NbcSetStyleSheet(SfxStyleSheet* pNewStyleSheet,
FASTBOOL bDontRemoveHardAttr)
{
// call parent
SdrAttrObj::NbcSetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
E3dObjList* pOL = pSub;
ULONG nObjCnt = pOL->GetObjCount();
for ( ULONG i = 0; i < nObjCnt; i++ )
pOL->GetObj(i)->NbcSetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
}
/*************************************************************************
|*
|* Nur die Member des E3dObjekts in den Stream speichern
|* Dies wird direkt auch von E3dSphere gerufen um zu verhindern dass die
|* Subliste weggeschrieben wird. (FG)
|*
\************************************************************************/
void E3dObject::WriteOnlyOwnMembers(SvStream& rOut) const
{
// Fuer Abwaertskompatibilitaet (Lesen neuer Daten mit altem Code)
SdrDownCompat aCompat(rOut, STREAM_WRITE);
#ifdef DBG_UTIL
aCompat.SetID("E3dObjectOwnMembers");
#endif
rOut << aLocalBoundVol;
Old_Matrix3D aMat3D;
aMat3D = aTfMatrix;
rOut << aMat3D;
rOut << nLogicalGroup;
rOut << nObjTreeLevel;
rOut << nPartOfParent;
rOut << UINT16(eDragDetail);
}
/*************************************************************************
|*
|* Objektdaten in Stream speichern
|*
\************************************************************************/
void E3dObject::WriteData(SvStream& rOut) const
{
long position = rOut.Tell();
SdrAttrObj::WriteData(rOut);
position = rOut.Tell();
// Fuer Abwaertskompatibilitaet (Lesen neuer Daten mit altem Code)
SdrDownCompat aCompat(rOut, STREAM_WRITE);
#ifdef DBG_UTIL
aCompat.SetID("E3dObject");
#endif
position = rOut.Tell();
pSub->Save(rOut);
position = rOut.Tell();
if (rOut.GetVersion() < 3560)
{
rOut << aLocalBoundVol;
Old_Matrix3D aMat3D;
aMat3D = aTfMatrix;
rOut << aMat3D;
rOut << nLogicalGroup;
rOut << nObjTreeLevel;
rOut << nPartOfParent;
rOut << UINT16(eDragDetail);
}
else
{
WriteOnlyOwnMembers(rOut);
}
position = rOut.Tell();
}
/*************************************************************************
|*
|* Objektdaten aus Stream laden
|*
\************************************************************************/
void E3dObject::ReadData(const SdrObjIOHeader& rHead, SvStream& rIn)
{
long position = rIn.Tell();
if (ImpCheckSubRecords (rHead, rIn))
{
position = rIn.Tell();
SdrAttrObj::ReadData(rHead, rIn);
position = rIn.Tell();
// Fuer Abwaertskompatibilitaet (Lesen neuer Daten mit altem Code)
SdrDownCompat aCompat(rIn, STREAM_READ);
#ifdef DBG_UTIL
aCompat.SetID("E3dObject");
#endif
pSub->Load(rIn, *pPage);
position = rIn.Tell();
if ((rIn.GetVersion() < 3560) || (rHead.GetVersion() <= 12))
{
UINT16 nTmp16;
rIn >> aLocalBoundVol;
Old_Matrix3D aMat3D;
rIn >> aMat3D;
aTfMatrix = Matrix4D(aMat3D);
rIn >> nLogicalGroup;
rIn >> nObjTreeLevel;
rIn >> nPartOfParent;
rIn >> nTmp16; eDragDetail = E3dDragDetail(nTmp16);
}
else
{
ReadOnlyOwnMembers(rHead, rIn);
}
position = rIn.Tell();
// Wie ein veraendertes Objekt behandeln
SetTransformChanged();
StructureChanged(this);
// BoundVolume muss neu berechnet werden
bBoundVolValid = FALSE;
// SnapRect auch
bSnapRectDirty = TRUE;
}
}
/*************************************************************************
|*
|* Nur die Daten des E3dObject aus Stream laden (nicht der Sublisten und
|* der Basisklassen). Wird von E3dSphere auch genutzt. (FileFormat-Optimierung)
|*
\************************************************************************/
void E3dObject::ReadOnlyOwnMembers(const SdrObjIOHeader& rHead, SvStream& rIn)
{
// Fuer Abwaertskompatibilitaet (Lesen neuer Daten mit altem Code)
SdrDownCompat aCompat(rIn, STREAM_READ);
#ifdef DBG_UTIL
aCompat.SetID("E3dObjectOwnMembers");
#endif
UINT16 nTmp16;
rIn >> aLocalBoundVol;
Old_Matrix3D aMat3D;
rIn >> aMat3D;
aTfMatrix = Matrix4D(aMat3D);
rIn >> nLogicalGroup;
rIn >> nObjTreeLevel;
rIn >> nPartOfParent;
rIn >> nTmp16; eDragDetail = E3dDragDetail(nTmp16);
bBoundVolValid = FALSE;
}
/*************************************************************************
|*
|* nach dem Laden...
|*
\************************************************************************/
void E3dObject::AfterRead()
{
SdrAttrObj::AfterRead();
if (pSub)
pSub->AfterRead();
// put loaded items to ItemSet
//-/ Collect3DAttributes((SfxItemSet&)GetItemSet());
}
//-/void E3dObject::Collect3DAttributes(SfxItemSet& rAttr) const
//-/{
//-/}
/*************************************************************************
|*
|* erstelle neues GeoData-Objekt
|*
\************************************************************************/
SdrObjGeoData *E3dObject::NewGeoData() const
{
// Theoretisch duerfen auch nur Szenen ihre GeoDatas erstellen und verwalten !!
// AW: Dies stimmt nicht mehr, diese Stelle ist mit der neuen Engine OK!
return new E3DObjGeoData;
}
/*************************************************************************
|*
|* uebergebe aktuelle werte an das GeoData-Objekt
|*
\************************************************************************/
void E3dObject::SaveGeoData(SdrObjGeoData& rGeo) const
{
SdrAttrObj::SaveGeoData (rGeo);
((E3DObjGeoData &) rGeo).aLocalBoundVol = aLocalBoundVol;
((E3DObjGeoData &) rGeo).aTfMatrix = aTfMatrix;
}
/*************************************************************************
|*
|* uebernehme werte aus dem GeoData-Objekt
|*
\************************************************************************/
void E3dObject::RestGeoData(const SdrObjGeoData& rGeo)
{
aLocalBoundVol = ((E3DObjGeoData &) rGeo).aLocalBoundVol;
NbcSetTransform (((E3DObjGeoData &) rGeo).aTfMatrix);
SdrAttrObj::RestGeoData (rGeo);
GetScene()->FitSnapRectToBoundVol();
}
/*************************************************************************
|*
|* Pruefe, ob die SubRecords ok sind und mit der Factory gelesen werden
|* koennen.
|*
\************************************************************************/
BOOL E3dObject::ImpCheckSubRecords (const SdrObjIOHeader& rHead,
SvStream& rIn)
{
BOOL bDoRead = FALSE;
if ( rIn.GetError() == SVSTREAM_OK )
{
if (rHead.GetVersion () <= 12)
{
ULONG nPos0 = rIn.Tell();
// Einen SubRecord ueberspringen (SdrObject)
{ SdrDownCompat aCompat(rIn,STREAM_READ); }
// Nocheinen SubRecord ueberspringen (SdrAttrObj)
{ SdrDownCompat aCompat(rIn,STREAM_READ); }
// Und nun muesste meiner kommen
bDoRead = rHead.GetBytesLeft() != 0;
rIn.Seek (nPos0); // FilePos wieder restaurieren
}
else
{
bDoRead = TRUE;
}
}
return bDoRead;
}
/*************************************************************************
|*
|* Keine DefaultAttr, zu langsam
|*
\************************************************************************/
void E3dObject::ForceDefaultAttr()
{
}
/*************************************************************************
|*
|* Falls doch noch DefaultAttrs benoetigt werden
|*
\************************************************************************/
void E3dObject::ForceDefaultAttrAgain()
{
SdrAttrObj::ForceDefaultAttr();
}
/*************************************************************************
|*
|* Rotation eines 3d-Koerpers
|*
\************************************************************************/
// 2D-rotation eines 3D-Koerpers, normalerweise macht das die Szene selbst
// Ist aber eine korrekte Implementierung, denn alles was passiert ist eine
// Rotation um die Achse die senkrecht auf dem Bildschirm steht und zwar
// unabhaengig davon, wie die Szene bisher gedreht worden ist.
void E3dObject::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
{
// Also derzeit sind die Klebepunkte relativ zum aOutRect der Szene definiert. Vor dem Drehen
// werden die Klebepunkte relativ zur Seite definiert. Sie nehmen an der Drehung der Szene noch nicht Teil
// dafuer gibt es den
SetGlueReallyAbsolute(TRUE);
// SendRepaintBroadcast();
double fWinkelInRad = nWink/100 * F_PI180;
NbcRotateZ(fWinkelInRad);
SetRectsDirty(); // Veranlasst eine Neuberechnung aller BoundRects
NbcRotateGluePoints(rRef,nWink,sn,cs); // Rotiert die Klebepunkte (die haben noch Koordinaten relativ
// zum Urpsung des Blattes
SetGlueReallyAbsolute(FALSE); // ab jetzt sind sie wieder relativ zum BoundRect (also dem aOutRect definiert)
}
/*************************************************************************/
TYPEINIT1(E3dCompoundObject, E3dObject);
/*************************************************************************
|*
|* Konstruktor
|*
\************************************************************************/
E3dCompoundObject::E3dCompoundObject() : E3dObject()
{
// Defaults setzen
E3dDefaultAttributes aDefault;
SetDefaultAttributes(aDefault);
bBytesLeft = FALSE;
bCreateE3dPolyObj = FALSE;
bGeometryValid = FALSE;
}
E3dCompoundObject::E3dCompoundObject(E3dDefaultAttributes& rDefault) : E3dObject()
{
// Defaults setzen
SetDefaultAttributes(rDefault);
bBytesLeft = FALSE;
bCreateE3dPolyObj = FALSE;
bGeometryValid = FALSE;
}
void E3dCompoundObject::SetDefaultAttributes(E3dDefaultAttributes& rDefault)
{
// Defaults setzen
//-/ SetFrontMaterial(rDefault.GetDefaultFrontMaterial());
aMaterialAmbientColor = rDefault.GetDefaultAmbientColor();
aBackMaterial = rDefault.GetDefaultBackMaterial();
//-/ eTextureKind = rDefault.GetDefaultTextureKind();
//-/ eTextureMode = rDefault.GetDefaultTextureMode();
//-/ bDoubleSided = rDefault.GetDefaultDoubleSided();
bCreateNormals = rDefault.GetDefaultCreateNormals();
bCreateTexture = rDefault.GetDefaultCreateTexture();
//-/ bUseStdNormals = rDefault.GetDefaultUseStdNormals();
//-/ bUseStdNormalsUseSphere = rDefault.GetDefaultUseStdNormalsUseSphere();
//-/ bInvertNormals = rDefault.GetDefaultInvertNormals();
//-/ bUseStdTextureX = rDefault.GetDefaultUseStdTextureX();
//-/ bUseStdTextureXUseSphere = rDefault.GetDefaultUseStdTextureXUseSphere();
//-/ bUseStdTextureY = rDefault.GetDefaultUseStdTextureY();
//-/ bUseStdTextureYUseSphere = rDefault.GetDefaultUseStdTextureYUseSphere();
//-/ bShadow3D = rDefault.GetDefaultShadow3D();
//-/ bFilterTexture = rDefault.GetDefaultFilterTexture();
bUseDifferentBackMaterial = rDefault.GetDefaultUseDifferentBackMaterial();
}
/*************************************************************************
|*
|* Destruktor
|*
\************************************************************************/
E3dCompoundObject::~E3dCompoundObject ()
{
}
/*************************************************************************
|*
|* Start der Geometrieerzeugung ankuendigen
|*
\************************************************************************/
void E3dCompoundObject::StartCreateGeometry()
{
// Geometriestart mitteilen
aDisplayGeometry.StartDescription();
// Lokales Volumen reset
aLocalBoundVol = Volume3D();
// Geometrie ist ab jetzt gueltig, um ein rekursives weiteres
// Erzeugen zu verhindern
bGeometryValid = TRUE;
}
/*************************************************************************
|*
|* Identifier zurueckgeben
|*
\************************************************************************/
UINT16 E3dCompoundObject::GetObjIdentifier() const
{
return E3D_COMPOUNDOBJ_ID;
}
/*************************************************************************
|*
|* Compounds brauchen Defaults
|*
\************************************************************************/
void E3dCompoundObject::ForceDefaultAttr()
{
SdrAttrObj::ForceDefaultAttr();
}
/*************************************************************************
|*
|* SnapRect berechnen
|*
\************************************************************************/
void E3dCompoundObject::RecalcSnapRect()
{
E3dScene* pScene = GetScene();
if(pScene)
{
// Objekttransformation uebernehmen
const Volume3D& rBoundVol = GetBoundVolume();
maSnapRect = Rectangle();
if(rBoundVol.IsValid())
{
const Matrix4D& rTrans = GetFullTransform();
Vol3DPointIterator aIter(rBoundVol, &rTrans);
Vector3D aTfVec;
while ( aIter.Next(aTfVec) )
{
aTfVec = pScene->GetCameraSet().WorldToViewCoor(aTfVec);
Point aPoint((long)(aTfVec.X() + 0.5), (long)(aTfVec.Y() + 0.5));
maSnapRect.Union(Rectangle(aPoint, aPoint));
}
}
bSnapRectDirty = FALSE;
}
}
/*************************************************************************
|*
|* BoundRect berechnen und evtl. Schatten einbeziehen
|* Dazu muss ein eventueller Schatten des einzelnen 3D-Objektes
|* beruecksichtigt werden
|*
\************************************************************************/
void E3dCompoundObject::RecalcBoundRect()
{
// BoundRect aus SnapRect berechnen
aOutRect = GetSnapRect();
E3dScene* pScene = GetScene();
if(pScene)
{
// Schatten beruecksichtigen
if(DoDrawShadow())
{
// ObjectTrans setzen
Matrix4D mTransform = GetFullTransform();
pScene->GetCameraSet().SetObjectTrans(mTransform);
// Schattenpolygon holen
PolyPolygon aShadowPoly;
GetShadowPolygon(aShadowPoly);
// Hinzufuegen
aOutRect.Union(aShadowPoly.GetBoundRect());
}
// Linienbreite beruecksichtigen
//-/ const XLineAttrSetItem* pLineAttr = GetLineAttr();
INT32 nLineWidth = ((const XLineWidthItem&)(GetItem(XATTR_LINEWIDTH))).GetValue();
if(nLineWidth)
{
Rectangle aShadowRect = aOutRect;
aShadowRect.Left() -= nLineWidth;
aShadowRect.Right() += nLineWidth;
aShadowRect.Top() -= nLineWidth;
aShadowRect.Bottom() += nLineWidth;
aOutRect.Union(aShadowRect);
}
}
}
/*************************************************************************
|*
|* BoundVolume holen. Falls die Geometrie ungueltig ist, diese neu
|* erzeugen und das BoundVol neu berechnen
|*
\************************************************************************/
const Volume3D& E3dCompoundObject::GetBoundVolume()
{
// Geometrie aktuell?
if(!bGeometryValid)
{
// Neu erzeugen und eine Neubestimmung des BoundVol erzwingen
ReCreateGeometry();
bBoundVolValid = FALSE;
}
// call parent
return E3dObject::GetBoundVolume();
}
/*************************************************************************
|*
|* Rausschreiben der Datenmember eines E3dCompounds
|*
\************************************************************************/
void E3dCompoundObject::WriteData(SvStream& rOut) const
{
#ifdef E3D_STREAMING
if (!aLocalBoundVol.IsValid() && aBoundVol.IsValid())
{
// Das aLocalBoundVol wird gespeichert.
// Ist dieses ungueltig, so wird das aBoundVol genommen
// (sollten beim E3dCompoundObject sowieso gleich sein)
((E3dCompoundObject*) this)->aLocalBoundVol = aBoundVol;
}
E3dObject::WriteData(rOut);
if (rOut.GetVersion() < 3560)
{
// In diesem Fall passiert nichts, da vor der Version 4.0
// also im Falle der Revision 3.1
}
else
{
SdrDownCompat aCompat(rOut, STREAM_WRITE);
#ifdef DBG_UTIL
aCompat.SetID("E3dCompoundObject");
#endif
//-/ rOut << BOOL(bDoubleSided);
rOut << BOOL(GetDoubleSided());
#endif
// neue Parameter zur Geometrieerzeugung
rOut << BOOL(bCreateNormals);
rOut << BOOL(bCreateTexture);
//-/ rOut << BOOL(bUseStdNormals);
//-/ rOut << BOOL(bUseStdNormalsUseSphere);
sal_uInt16 nVal = GetNormalsKind();
rOut << BOOL(nVal > 0);
rOut << BOOL(nVal > 1);
//-/ rOut << BOOL(bUseStdTextureX);
//-/ rOut << BOOL(bUseStdTextureXUseSphere);
nVal = GetTextureProjectionX();
rOut << BOOL(nVal > 0);
rOut << BOOL(nVal > 1);
//-/ rOut << BOOL(bUseStdTextureY);
//-/ rOut << BOOL(bUseStdTextureYUseSphere);
nVal = GetTextureProjectionY();
rOut << BOOL(nVal > 0);
rOut << BOOL(nVal > 1);
//-/ rOut << BOOL(bShadow3D);
rOut << BOOL(GetShadow3D());
// neu al 384:
//-/ aFrontMaterial.WriteData(rOut);
rOut << GetMaterialAmbientColor();
rOut << GetMaterialColor();
rOut << GetMaterialSpecular();
rOut << GetMaterialEmission();
rOut << GetMaterialSpecularIntensity();
aBackMaterial.WriteData(rOut);
//-/ rOut << (UINT16)eTextureKind;
rOut << (UINT16)GetTextureKind();
//-/ rOut << (UINT16)eTextureMode;
rOut << (UINT16)GetTextureMode();
//-/ rOut << BOOL(bInvertNormals);
rOut << BOOL(GetNormalsInvert());
// neu ab 534: (hat noch gefehlt)
//-/ rOut << BOOL(bFilterTexture);
rOut << BOOL(GetTextureFilter());
}
}
/*************************************************************************
|*
|* Einlesen der Datenmember eines E3dCompounds
|*
\************************************************************************/
void E3dCompoundObject::ReadData(const SdrObjIOHeader& rHead, SvStream& rIn)
{
if ( rIn.GetError() != SVSTREAM_OK )
return;
E3dObject::ReadData(rHead, rIn);
// Vor der Filerevision 13 wurde das Objekt nie geschrieben.
// auch kein Kompatibilitaetsrecord.
if ((rHead.GetVersion() < 13) || (rIn.GetVersion() < 3560))
{
return;
}
SdrDownCompat aCompat(rIn, STREAM_READ);
#ifdef DBG_UTIL
aCompat.SetID("E3dCompoundObject");
#endif
bBytesLeft = FALSE;
if (aCompat.GetBytesLeft () >= sizeof (BOOL))
{
BOOL bTmp, bTmp2;
sal_uInt16 nTmp;
rIn >> bTmp;
mpObjectItemSet->Put(Svx3DDoubleSidedItem(bTmp));
//-/ bDoubleSided = bTmp;
// neue Parameter zur Geometrieerzeugung
if (aCompat.GetBytesLeft () >= sizeof (BOOL))
{
rIn >> bTmp;
bCreateNormals = bTmp;
rIn >> bTmp;
bCreateTexture = bTmp;
//-/ rIn >> bTmp;
//-/ bUseStdNormals = bTmp;
//-/ rIn >> bTmp;
//-/ bUseStdNormalsUseSphere = bTmp;
rIn >> bTmp;
rIn >> bTmp2;
if(bTmp == FALSE && bTmp2 == FALSE)
nTmp = 0;
else if(bTmp == TRUE && bTmp2 == FALSE)
nTmp = 1;
else
nTmp = 2;
mpObjectItemSet->Put(Svx3DNormalsKindItem(nTmp));
//-/ rIn >> bTmp;
//-/ bUseStdTextureX = bTmp;
//-/ rIn >> bTmp;
//-/ bUseStdTextureXUseSphere = bTmp;
rIn >> bTmp;
rIn >> bTmp2;
if(bTmp == FALSE && bTmp2 == FALSE)
nTmp = 0;
else if(bTmp == TRUE && bTmp2 == FALSE)
nTmp = 1;
else
nTmp = 2;
mpObjectItemSet->Put(Svx3DTextureProjectionXItem(nTmp));
//-/ rIn >> bTmp;
//-/ bUseStdTextureY = bTmp;
//-/ rIn >> bTmp;
//-/ bUseStdTextureYUseSphere = bTmp;
rIn >> bTmp;
rIn >> bTmp2;
if(bTmp == FALSE && bTmp2 == FALSE)
nTmp = 0;
else if(bTmp == TRUE && bTmp2 == FALSE)
nTmp = 1;
else
nTmp = 2;
mpObjectItemSet->Put(Svx3DTextureProjectionYItem(nTmp));
rIn >> bTmp;
//-/ bShadow3D = bTmp;
mpObjectItemSet->Put(Svx3DShadow3DItem(bTmp));
// Setze ein Flag fuer den Aufrufer, dass neues Format
// zu lesen ist
bBytesLeft = TRUE;
}
// neu al 384:
if (aCompat.GetBytesLeft () >= sizeof (B3dMaterial))
{
UINT16 nTmp;
//-/ aFrontMaterial.ReadData(rIn);
Color aCol;
rIn >> aCol;
SetMaterialAmbientColor(aCol);
rIn >> aCol;
//-/ SetItem(Svx3DMaterialColorItem(aCol));
// do NOT use, this is the old 3D-Color(!)
// SetItem(XFillColorItem(String(), aCol));
rIn >> aCol;
mpObjectItemSet->Put(Svx3DMaterialSpecularItem(aCol));
rIn >> aCol;
mpObjectItemSet->Put(Svx3DMaterialEmissionItem(aCol));
rIn >> nTmp;
mpObjectItemSet->Put(Svx3DMaterialSpecularIntensityItem(nTmp));
aBackMaterial.ReadData(rIn);
rIn >> nTmp;
//-/ eTextureKind = (Base3DTextureKind)nTmp;
mpObjectItemSet->Put(Svx3DTextureKindItem(nTmp));
rIn >> nTmp;
//-/ eTextureMode = (Base3DTextureMode)nTmp;
mpObjectItemSet->Put(Svx3DTextureModeItem(nTmp));
rIn >> bTmp;
//-/ bInvertNormals = bTmp;
mpObjectItemSet->Put(Svx3DNormalsInvertItem(bTmp));
}
// neu ab 534: (hat noch gefehlt)
if (aCompat.GetBytesLeft () >= sizeof (BOOL))
{
rIn >> bTmp;
//-/ bFilterTexture = bTmp;
mpObjectItemSet->Put(Svx3DTextureFilterItem(bTmp));
}
}
}
/*************************************************************************
|*
|* Bitmaps fuer 3D-Darstellung von Gradients und Hatches holen
|*
\************************************************************************/
Bitmap E3dCompoundObject::GetGradientBitmap(const SfxItemSet& rSet)
{
VirtualDevice *pVD = new VirtualDevice();
Size aVDSize(256, 256);
pVD->SetOutputSizePixel( aVDSize );
XOutputDevice *pXOut = new XOutputDevice( pVD );
//-/ XFillAttrSetItem *pXFSet = new XFillAttrSetItem( rSet.GetPool() );
SfxItemSet aFillSet(*rSet.GetPool());
aFillSet.Put( XFillStyleItem( XFILL_GRADIENT ) );
aFillSet.Put( rSet.Get(XATTR_FILLGRADIENT) );
aFillSet.Put( rSet.Get(XATTR_GRADIENTSTEPCOUNT) );
pXOut->SetFillAttr( aFillSet );
//-/ XLineAttrSetItem *pXLSet = new XLineAttrSetItem( rSet.GetPool() );
aFillSet.Put( XLineStyleItem( XLINE_NONE ) );
pXOut->SetLineAttr( aFillSet );
pXOut->DrawRect( Rectangle( Point(), aVDSize ) );
Bitmap aGradientBitmap = pVD->GetBitmap( Point(), aVDSize );
if( pVD )
delete pVD;
if( pXOut )
delete pXOut;
//-/ if( pXFSet )
//-/ delete pXFSet;
//-/ if( pXLSet )
//-/ delete pXLSet;
return aGradientBitmap;
}
Bitmap E3dCompoundObject::GetHatchBitmap(const SfxItemSet& rSet)
{
VirtualDevice *pVD = new VirtualDevice();
const XFillHatchItem* pFillHatchItem = (XFillHatchItem*)&rSet.Get(XATTR_FILLHATCH);
const XHatch& rHatch = pFillHatchItem->GetValue();
long nDistance = rHatch.GetDistance(); // in 100stel mm
double fAngle = double(rHatch.GetAngle()) * (F_PI180 / 10.0);
double fMinX(0.0);
double fMaxX(0.0);
double fMinY(0.0);
double fMaxY(0.0);
// nDistance in X-Richtung
double fX = cos(fAngle) * double(nDistance);
double fY = sin(fAngle) * double(nDistance);
if(fX < fMinX)
fMinX = fX;
if(fX > fMaxX)
fMaxX = fX;
if(fY < fMinY)
fMinY = fY;
if(fY > fMaxY)
fMaxY = fY;
// nDistance in Y-Richtung
fX = cos(fAngle + F_PI2) * double(nDistance);
fY = sin(fAngle + F_PI2) * double(nDistance);
if(fX < fMinX)
fMinX = fX;
if(fX > fMaxX)
fMaxX = fX;
if(fY < fMinY)
fMinY = fY;
if(fY > fMaxY)
fMaxY = fY;
// nDistance in -X-Richtung
fX = cos(fAngle + F_PI) * double(nDistance);
fY = sin(fAngle + F_PI) * double(nDistance);
if(fX < fMinX)
fMinX = fX;
if(fX > fMaxX)
fMaxX = fX;
if(fY < fMinY)
fMinY = fY;
if(fY > fMaxY)
fMaxY = fY;
// nDistance in -Y-Richtung
fX = cos(fAngle + (F_PI + F_PI2)) * double(nDistance);
fY = sin(fAngle + (F_PI + F_PI2)) * double(nDistance);
if(fX < fMinX)
fMinX = fX;
if(fX > fMaxX)
fMaxX = fX;
if(fY < fMinY)
fMinY = fY;
if(fY > fMaxY)
fMaxY = fY;
long nDistanceX = long(fMaxX - fMinX);
long nDistanceY = long(fMaxY - fMinY);
// Bei Schraffuren in eine der 4 Himmelsrichtungen Ausdehnung halbieren
if(rHatch.GetAngle() % 900 == 0)
{
nDistanceX /= 2;
nDistanceY /= 2;
}
Size aVDSize(64, 64);
pVD->SetOutputSizePixel( aVDSize );
MapMode aMapMode(MAP_100TH_MM);
pVD->SetMapMode(aMapMode);
XOutputDevice *pXOut = new XOutputDevice( pVD );
//-/ XFillAttrSetItem *pXFSet = new XFillAttrSetItem( rSet.GetPool() );
//-/ XLineAttrSetItem *pXLSet = new XLineAttrSetItem( rSet.GetPool() );
SfxItemSet aFillSet(*rSet.GetPool());
aFillSet.Put( XFillStyleItem( XFILL_SOLID ) );
aFillSet.Put( XFillColorItem( String(), RGB_Color( COL_WHITE ) ) );
aFillSet.Put( XLineStyleItem( XLINE_NONE ) );
pXOut->SetLineAttr( aFillSet );
pXOut->SetFillAttr( aFillSet );
pXOut->DrawRect( Rectangle( Point(), pVD->PixelToLogic(aVDSize) ) );
aFillSet.Put( XFillStyleItem( XFILL_HATCH ) );
aFillSet.Put( rSet.Get(XATTR_FILLHATCH) );
pXOut->SetFillAttr( aFillSet );
Size aLogicalSize = pVD->PixelToLogic(aVDSize);
Fraction aFractionX(aLogicalSize.Width(), nDistanceX);
Fraction aFractionY(aLogicalSize.Height(), nDistanceY);
aMapMode.SetScaleX(aFractionX);
aMapMode.SetScaleY(aFractionY);
pVD->SetMapMode(aMapMode);
pXOut->DrawRect( Rectangle( Point(), pVD->PixelToLogic(aVDSize) ) );
Bitmap aHatchBitmap = pVD->GetBitmap( Point(), pVD->PixelToLogic(aVDSize) );
if( pVD )
delete pVD;
if( pXOut )
delete pXOut;
//-/ if( pXFSet )
//-/ delete pXFSet;
//-/ if( pXLSet )
//-/ delete pXLSet;
return aHatchBitmap;
}
/*************************************************************************
|*
|* Geometrieerzeugung
|*
\************************************************************************/
void E3dCompoundObject::DestroyGeometry()
{
// Alle Objekte in der Sub-Liste zerstoeren. Dies sind die
// zur Visualisierung des Objektes verwendeten Hilfsobjekte
pSub->Clear();
delete pSub;
pSub = new E3dObjList(NULL, NULL);
pSub->SetOwnerObj(this);
pSub->SetListKind(SDROBJLIST_GROUPOBJ);
// Neue Geometrie zerstoeren
aDisplayGeometry.Erase();
// BoundVols resetten
aLocalBoundVol = Volume3D();
bBoundVolValid = FALSE;
StructureChanged(this);
// Geometrie ist ungueltig
bGeometryValid = FALSE;
}
void E3dCompoundObject::CreateGeometry()
{
// Geometrie ist gueltig, um rekursion zu verhindern
bGeometryValid = TRUE;
// Eventuell entstandene Geometrie noch korrigieren
// und Default -Normalen oder -Texturkoordinaten erzeugen
if(bCreateNormals)
{
//-/ if(bUseStdNormals && bUseStdNormalsUseSphere)
if(GetNormalsKind() > 1)
GetDisplayGeometry().CreateDefaultNormalsSphere();
if(GetNormalsInvert())
GetDisplayGeometry().InvertNormals();
}
if(bCreateTexture)
{
//-/ GetDisplayGeometry().CreateDefaultTexture(
//-/ ((bUseStdTextureX) ? B3D_CREATE_DEFAULT_X : FALSE)
//-/ |((bUseStdTextureY) ? B3D_CREATE_DEFAULT_Y : FALSE),
//-/ bUseStdTextureXUseSphere);
GetDisplayGeometry().CreateDefaultTexture(
((GetTextureProjectionX() > 0) ? B3D_CREATE_DEFAULT_X : FALSE)
|((GetTextureProjectionY() > 0) ? B3D_CREATE_DEFAULT_Y : FALSE),
GetTextureProjectionX() > 1);
}
// Am Ende der Geometrieerzeugung das model an den erzeugten
// PolyObj's setzen, d.h. beim ueberladen dieser Funktion
// den parent am Ende rufen.
if(bCreateE3dPolyObj)
SetModel(pModel);
// Das Ende der Geometrieerzeugung anzeigen
aDisplayGeometry.EndDescription();
}
void E3dCompoundObject::ReCreateGeometry(BOOL bCreateOldGeometry)
{
// Geometrie zerstoeren
DestroyGeometry();
// Flag fuer Geometrieerzeugung setzen
bCreateE3dPolyObj = bCreateOldGeometry;
// ... und neu erzeugen
CreateGeometry();
}
/*************************************************************************
|*
|* Geometrieerzeugung
|*
\************************************************************************/
void E3dCompoundObject::AddGeometry(const PolyPolygon3D& rPolyPolygon3D,
BOOL bHintIsComplex, BOOL bOutline)
{
if(rPolyPolygon3D.Count())
{
// eventuell alte Geometrie erzeugen (z.B. zum speichern)
if(bCreateE3dPolyObj)
{
E3dPolyObj* pObj = new E3dPolyObj(
rPolyPolygon3D, GetDoubleSided(), TRUE);
pObj->SetPartOfParent();
Insert3DObj(pObj);
}
// neue Geometrie erzeugen
for(USHORT a = 0; a < rPolyPolygon3D.Count(); a++ )
{
const Polygon3D& rPoly3D = rPolyPolygon3D[a];
aDisplayGeometry.StartObject(bHintIsComplex, bOutline);
for(USHORT b = 0; b < rPoly3D.GetPointCount(); b++ )
aDisplayGeometry.AddEdge(rPoly3D[b]);
}
aDisplayGeometry.EndObject();
// LocalBoundVolume pflegen
aLocalBoundVol.Union(rPolyPolygon3D.GetPolySize());
// Eigenes BoundVol nicht mehr gueltig
SetBoundVolInvalid();
SetRectsDirty();
}
}
void E3dCompoundObject::AddGeometry(
const PolyPolygon3D& rPolyPolygon3D,
const PolyPolygon3D& rPolyNormal3D,
BOOL bHintIsComplex, BOOL bOutline)
{
if(rPolyPolygon3D.Count())
{
// eventuell alte Geometrie erzeugen (z.B. zum speichern)
if(bCreateE3dPolyObj)
{
E3dPolyObj* pObj = new E3dPolyObj(
rPolyPolygon3D, rPolyNormal3D, GetDoubleSided(), TRUE);
pObj->SetPartOfParent();
Insert3DObj(pObj);
}
// neue Geometrie erzeugen
for(USHORT a = 0; a < rPolyPolygon3D.Count(); a++ )
{
const Polygon3D& rPoly3D = rPolyPolygon3D[a];
const Polygon3D& rNormal3D = rPolyNormal3D[a];
aDisplayGeometry.StartObject(bHintIsComplex, bOutline);
for(USHORT b = 0; b < rPoly3D.GetPointCount(); b++ )
aDisplayGeometry.AddEdge(rPoly3D[b], rNormal3D[b]);
}
aDisplayGeometry.EndObject();
// LocalBoundVolume pflegen
aLocalBoundVol.Union(rPolyPolygon3D.GetPolySize());
// Eigenes BoundVol nicht mehr gueltig
SetBoundVolInvalid();
SetRectsDirty();
}
}
void E3dCompoundObject::AddGeometry(
const PolyPolygon3D& rPolyPolygon3D,
const PolyPolygon3D& rPolyNormal3D,
const PolyPolygon3D& rPolyTexture3D,
BOOL bHintIsComplex, BOOL bOutline)
{
if(rPolyPolygon3D.Count())
{
// eventuell alte Geometrie erzeugen (z.B. zum speichern)
if(bCreateE3dPolyObj)
{
E3dPolyObj* pObj = new E3dPolyObj(
rPolyPolygon3D, rPolyNormal3D,
rPolyTexture3D, GetDoubleSided(), TRUE);
pObj->SetPartOfParent();
Insert3DObj(pObj);
}
// neue Geometrie erzeugen
for(USHORT a = 0; a < rPolyPolygon3D.Count(); a++ )
{
const Polygon3D& rPoly3D = rPolyPolygon3D[a];
const Polygon3D& rNormal3D = rPolyNormal3D[a];
const Polygon3D& rTexture3D = rPolyTexture3D[a];
aDisplayGeometry.StartObject(bHintIsComplex, bOutline);
for(USHORT b = 0; b < rPoly3D.GetPointCount(); b++ )
aDisplayGeometry.AddEdge(rPoly3D[b], rNormal3D[b], rTexture3D[b]);
}
aDisplayGeometry.EndObject();
// LocalBoundVolume pflegen
aLocalBoundVol.Union(rPolyPolygon3D.GetPolySize());
// Eigenes BoundVol nicht mehr gueltig
SetBoundVolInvalid();
SetRectsDirty();
}
}
/*************************************************************************
|*
|* Hilfsfunktionen zur Geometrieerzeugung
|*
\************************************************************************/
void E3dCompoundObject::RotatePoly(
PolyPolygon3D& rPolyPolyRotate,
Matrix4D& rRotMat)
{
USHORT nPolyCnt = rPolyPolyRotate.Count();
for(UINT16 a=0;a<nPolyCnt;a++)
{
Polygon3D& rPolyRotate = rPolyPolyRotate[a];
USHORT nPntCnt = rPolyRotate.GetPointCount();
for(UINT16 b=0;b<nPntCnt;b++)
rPolyRotate[b] *= rRotMat;
}
}
void E3dCompoundObject::GrowPoly(
PolyPolygon3D& rPolyPolyGrow,
PolyPolygon3D& rPolyPolyNormals,
double fFactor)
{
USHORT nPolyCnt = rPolyPolyGrow.Count();
for(UINT16 a=0;a<nPolyCnt;a++)
{
Polygon3D& rPolyGrow = rPolyPolyGrow[a];
const Polygon3D& rPolyNormals = rPolyPolyNormals[a];
USHORT nPntCnt = rPolyGrow.GetPointCount();
for(UINT16 b=0;b<nPntCnt;b++)
rPolyGrow[b] += rPolyNormals[b] * fFactor;
}
}
void E3dCompoundObject::AddNormals(
PolyPolygon3D& rPolyPolyDest,
const PolyPolygon3D& rPolyPolySource)
{
USHORT nPolyCnt = rPolyPolyDest.Count();
for(UINT16 a=0;a<nPolyCnt;a++)
{
Polygon3D& rPolyDest = rPolyPolyDest[a];
const Polygon3D& rPolySource = rPolyPolySource[a];
USHORT nPntCnt = rPolyDest.GetPointCount();
for(UINT16 b=0;b<nPntCnt;b++)
{
rPolyDest[b] += rPolySource[b];
rPolyDest[b].Normalize();
}
}
}
void E3dCompoundObject::ScalePoly(
PolyPolygon3D& rPolyPolyScale,
double fFactor)
{
USHORT nPolyCnt = rPolyPolyScale.Count();
Vector3D aMiddle = rPolyPolyScale.GetMiddle();
for(UINT16 a=0;a<nPolyCnt;a++)
{
Polygon3D& rPolyScale = rPolyPolyScale[a];
USHORT nPntCnt = rPolyScale.GetPointCount();
for(UINT16 b=0;b<nPntCnt;b++)
rPolyScale[b] = ((rPolyScale[b] - aMiddle) * fFactor) + aMiddle;
}
}
void E3dCompoundObject::CreateFront(
const PolyPolygon3D& rPolyPoly3D,
const PolyPolygon3D& rFrontNormals,
BOOL bCreateNormals,
BOOL bCreateTexture)
{
// Vorderseite
if(bCreateNormals)
{
if(bCreateTexture)
{
// Polygon fuer die Textur erzeugen
PolyPolygon3D aPolyTexture = rPolyPoly3D;
Volume3D aSize = aPolyTexture.GetPolySize();
Matrix4D aTrans;
aTrans.Identity();
aTrans.Translate(-aSize.MinVec());
aPolyTexture.Transform(aTrans);
double fFactorX(1.0), fFactorY(1.0), fFactorZ(1.0);
if(aSize.GetWidth() != 0.0)
fFactorX = 1.0 / aSize.GetWidth();
if(aSize.GetHeight() != 0.0)
fFactorY = 1.0 / aSize.GetHeight();
if(aSize.GetDepth() != 0.0)
fFactorZ = 1.0 / aSize.GetDepth();
aTrans.Identity();
aTrans.Scale(fFactorX, -fFactorY, fFactorZ);
aTrans.Translate(Vector3D(0.0, 1.0, 0.0));
aPolyTexture.Transform(aTrans);
AddGeometry(rPolyPoly3D, rFrontNormals, aPolyTexture, TRUE);
}
else
AddGeometry(rPolyPoly3D, rFrontNormals, TRUE);
}
else
AddGeometry(rPolyPoly3D, TRUE);
}
void E3dCompoundObject::AddFrontNormals(
const PolyPolygon3D& rPolyPoly3D,
PolyPolygon3D& rNormalsFront,
Vector3D &rOffset)
{
Vector3D aFrontNormal = -rOffset;
aFrontNormal.Normalize();
USHORT nPolyCnt = rPolyPoly3D.Count();
for(UINT16 a=0;a<nPolyCnt;a++)
{
const Polygon3D& rPoly3D = rPolyPoly3D[a];
Polygon3D& rNormalPoly = rNormalsFront[a];
USHORT nPntCnt = rPoly3D.GetPointCount();
for(UINT16 b=0;b<nPntCnt;b++)
{
rNormalPoly[b] += aFrontNormal;
rNormalPoly[b].Normalize();
}
}
}
void E3dCompoundObject::CreateBack(
const PolyPolygon3D& rPolyPoly3D,
const PolyPolygon3D& rBackNormals,
BOOL bCreateNormals,
BOOL bCreateTexture)
{
// PolyPolygon umdrehen
PolyPolygon3D aLocalPoly = rPolyPoly3D;
aLocalPoly.FlipDirections();
// Rueckseite
if(bCreateNormals)
{
PolyPolygon3D aLocalNormals = rBackNormals;
aLocalNormals.FlipDirections();
if(bCreateTexture)
{
// Polygon fuer die Textur erzeugen
PolyPolygon3D aPolyTexture(aLocalPoly);
Volume3D aSize = aPolyTexture.GetPolySize();
Matrix4D aTrans;
aTrans.Identity();
aTrans.Translate(-aSize.MinVec());
aPolyTexture.Transform(aTrans);
double fFactorX(1.0), fFactorY(1.0), fFactorZ(1.0);
if(aSize.GetWidth() != 0.0)
fFactorX = 1.0 / aSize.GetWidth();
if(aSize.GetHeight() != 0.0)
fFactorY = 1.0 / aSize.GetHeight();
if(aSize.GetDepth() != 0.0)
fFactorZ = 1.0 / aSize.GetDepth();
aTrans.Identity();
aTrans.Scale(fFactorX, -fFactorY, fFactorZ);
aTrans.Translate(Vector3D(0.0, 1.0, 0.0));
aPolyTexture.Transform(aTrans);
AddGeometry(aLocalPoly, aLocalNormals, aPolyTexture, TRUE);
}
else
AddGeometry(aLocalPoly, aLocalNormals, TRUE);
}
else
{
AddGeometry(aLocalPoly, TRUE);
}
}
void E3dCompoundObject::AddBackNormals(
const PolyPolygon3D& rPolyPoly3D,
PolyPolygon3D& rNormalsBack,
Vector3D& rOffset)
{
Vector3D aBackNormal = rOffset;
aBackNormal.Normalize();
USHORT nPolyCnt = rPolyPoly3D.Count();
for(UINT16 a=0;a<nPolyCnt;a++)
{
const Polygon3D& rPoly3D = rPolyPoly3D[a];
Polygon3D& rNormalPoly = rNormalsBack[a];
USHORT nPntCnt = rPoly3D.GetPointCount();
for(UINT16 b=0;b<nPntCnt;b++)
{
rNormalPoly[b] += aBackNormal;
rNormalPoly[b].Normalize();
}
}
}
void E3dCompoundObject::CreateInBetween(
const PolyPolygon3D& rPolyPolyFront,
const PolyPolygon3D& rPolyPolyBack,
const PolyPolygon3D& rFrontNormals,
const PolyPolygon3D& rBackNormals,
BOOL bCreateNormals,
double fSurroundFactor,
double fTextureStart,
double fTextureDepth,
BOOL bRotateTexture90)
{
USHORT nPolyCnt = rPolyPolyFront.Count();
BOOL bCreateTexture = (fTextureDepth == 0.0) ? FALSE : TRUE;
double fPolyLength, fPolyPos;
USHORT nLastIndex;
// Verbindungsstuecke
if(bCreateNormals)
{
for(UINT16 a=0;a<nPolyCnt;a++)
{
const Polygon3D& rPoly3DFront = rPolyPolyFront[a];
const Polygon3D& rPoly3DBack = rPolyPolyBack[a];
const Polygon3D& rPolyNormalsFront = rFrontNormals[a];
const Polygon3D& rPolyNormalsBack = rBackNormals[a];
Polygon3D aRect3D(4);
Polygon3D aNormal3D(4);
Polygon3D aTexture3D(4);
USHORT nPntCnt = rPoly3DFront.GetPointCount();
USHORT nPrefillIndex = rPoly3DFront.IsClosed() ? nPntCnt - 1 : 0;
aRect3D[3] = rPoly3DFront[nPrefillIndex];
aRect3D[2] = rPoly3DBack[nPrefillIndex];
aNormal3D[3] = rPolyNormalsFront[nPrefillIndex];
aNormal3D[2] = rPolyNormalsBack[nPrefillIndex];
if(bCreateTexture)
{
fPolyLength = rPoly3DFront.GetLength();
fPolyPos = 0.0;
nLastIndex = rPoly3DFront.IsClosed() ? nPntCnt - 1 : 0;
if(bRotateTexture90)
{
// X,Y vertauschen
aTexture3D[3].X() = fTextureStart;
aTexture3D[3].Y() = (1.0 - fPolyPos) * fSurroundFactor;
aTexture3D[2].X() = fTextureStart + fTextureDepth;
aTexture3D[2].Y() = (1.0 - fPolyPos) * fSurroundFactor;
}
else
{
aTexture3D[3].X() = fPolyPos * fSurroundFactor;
aTexture3D[3].Y() = fTextureStart;
aTexture3D[2].X() = fPolyPos * fSurroundFactor;
aTexture3D[2].Y() = fTextureStart + fTextureDepth;
}
}
for (USHORT i = rPoly3DFront.IsClosed() ? 0 : 1; i < nPntCnt; i++)
{
aRect3D[0] = aRect3D[3];
aRect3D[1] = aRect3D[2];
aRect3D[3] = rPoly3DFront[i];
aRect3D[2] = rPoly3DBack[i];
aNormal3D[0] = aNormal3D[3];
aNormal3D[1] = aNormal3D[2];
aNormal3D[3] = rPolyNormalsFront[i];
aNormal3D[2] = rPolyNormalsBack[i];
if(bCreateTexture)
{
// Texturkoordinaten ermitteln
Vector3D aPart = rPoly3DFront[i] - rPoly3DFront[nLastIndex];
fPolyPos += aPart.GetLength() / fPolyLength;
nLastIndex = i;
// Der Abschnitt am Polygon entspricht dem Teil
// von fPolyPos bis fPolyPos+fPartLength
aTexture3D[0] = aTexture3D[3];
aTexture3D[1] = aTexture3D[2];
if(bRotateTexture90)
{
// X,Y vertauschen
aTexture3D[3].X() = fTextureStart;
aTexture3D[3].Y() = (1.0 - fPolyPos) * fSurroundFactor;
aTexture3D[2].X() = fTextureStart + fTextureDepth;
aTexture3D[2].Y() = (1.0 - fPolyPos) * fSurroundFactor;
}
else
{
aTexture3D[3].X() = fPolyPos * fSurroundFactor;
aTexture3D[3].Y() = fTextureStart;
aTexture3D[2].X() = fPolyPos * fSurroundFactor;
aTexture3D[2].Y() = fTextureStart + fTextureDepth;
}
AddGeometry(aRect3D, aNormal3D, aTexture3D, FALSE);
}
else
AddGeometry(aRect3D, aNormal3D, FALSE);
}
}
}
else
{
for(UINT16 a=0;a<nPolyCnt;a++)
{
const Polygon3D& rPoly3DFront = rPolyPolyFront[a];
const Polygon3D& rPoly3DBack = rPolyPolyBack[a];
Polygon3D aRect3D(4);
USHORT nPntCnt = rPoly3DFront.GetPointCount();
USHORT nPrefillIndex = rPoly3DFront.IsClosed() ? nPntCnt - 1 : 0;
aRect3D[3] = rPoly3DFront[nPrefillIndex];
aRect3D[2] = rPoly3DBack[nPrefillIndex];
for (USHORT i = rPoly3DFront.IsClosed() ? 0 : 1; i < nPntCnt; i++)
{
aRect3D[0] = aRect3D[3];
aRect3D[1] = aRect3D[2];
aRect3D[3] = rPoly3DFront[i];
aRect3D[2] = rPoly3DBack[i];
AddGeometry(aRect3D, FALSE);
}
}
}
}
void E3dCompoundObject::AddInBetweenNormals(
const PolyPolygon3D& rPolyPolyFront,
const PolyPolygon3D& rPolyPolyBack,
PolyPolygon3D& rNormals,
BOOL bSmoothed)
{
USHORT nPolyCnt = rPolyPolyFront.Count();
// Verbindungsstuecke
for(UINT16 a=0;a<nPolyCnt;a++)
{
const Polygon3D& rPoly3DFront = rPolyPolyFront[a];
const Polygon3D& rPoly3DBack = rPolyPolyBack[a];
Polygon3D& rNormalPoly = rNormals[a];
USHORT nPntCnt = rPoly3DFront.GetPointCount();
if(rPoly3DBack.IsClosed())
{
Vector3D aNormal = (rPoly3DBack[nPntCnt - 1] - rPoly3DFront[nPntCnt - 1])
|(rPoly3DFront[0] - rPoly3DFront[nPntCnt - 1]);
aNormal.Normalize();
for (USHORT i = 0; i < nPntCnt; i++)
{
Vector3D aNextNormal = (rPoly3DBack[i] - rPoly3DFront[i])
|(rPoly3DFront[(i+1 == nPntCnt) ? 0 : i+1] - rPoly3DFront[i]);
aNextNormal.Normalize();
if(bSmoothed)
{
Vector3D aMidNormal = aNormal + aNextNormal;
aMidNormal.Normalize();
rNormalPoly[i] += aMidNormal;
}
else
rNormalPoly[i] += aNormal;
rNormalPoly[i].Normalize();
aNormal = aNextNormal;
}
}
else
{
Vector3D aNormal;
if(rPoly3DBack[0] == rPoly3DFront[0])
{
aNormal = (rPoly3DBack[1] - rPoly3DFront[1])
|(rPoly3DFront[1] - rPoly3DFront[0]);
}
else
{
aNormal = (rPoly3DBack[0] - rPoly3DFront[0])
|(rPoly3DFront[1] - rPoly3DFront[0]);
}
aNormal.Normalize();
rNormalPoly[0] += aNormal; rNormalPoly[0].Normalize();
for (USHORT i = 1; i < nPntCnt; i++)
{
Vector3D aNextNormal;
if(i+1 == nPntCnt)
{
aNextNormal = aNormal;
}
else
{
aNextNormal = (rPoly3DBack[i] - rPoly3DFront[i])
|(rPoly3DFront[i+1] - rPoly3DFront[i]);
}
aNextNormal.Normalize();
if(bSmoothed)
{
Vector3D aMidNormal = aNormal + aNextNormal;
aMidNormal.Normalize();
rNormalPoly[i] += aMidNormal;
}
else
rNormalPoly[i] += aNormal;
rNormalPoly[i].Normalize();
aNormal = aNextNormal;
}
}
}
}
/*************************************************************************
|*
|* Copy-Operator
|*
\************************************************************************/
void E3dCompoundObject::operator=(const SdrObject& rObj)
{
// erstmal alle Childs kopieren
E3dObject::operator=(rObj);
// weitere Parameter kopieren
const E3dCompoundObject& r3DObj = (const E3dCompoundObject&) rObj;
aDisplayGeometry = r3DObj.aDisplayGeometry;
//-/ bDoubleSided = r3DObj.bDoubleSided;
bCreateNormals = r3DObj.bCreateNormals;
bCreateTexture = r3DObj.bCreateTexture;
//-/ bUseStdNormals = r3DObj.bUseStdNormals;
//-/ bUseStdNormalsUseSphere = r3DObj.bUseStdNormalsUseSphere;
//-/ bUseStdTextureX = r3DObj.bUseStdTextureX;
//-/ bUseStdTextureXUseSphere = r3DObj.bUseStdTextureXUseSphere;
//-/ bUseStdTextureY = r3DObj.bUseStdTextureY;
//-/ bUseStdTextureYUseSphere = r3DObj.bUseStdTextureYUseSphere;
bGeometryValid = r3DObj.bGeometryValid;
//-/ bShadow3D = r3DObj.bShadow3D;
bBytesLeft = r3DObj.bBytesLeft;
bCreateE3dPolyObj = r3DObj.bCreateE3dPolyObj;
// neu ab 383:
//-/ aFrontMaterial = r3DObj.aFrontMaterial;
aMaterialAmbientColor = r3DObj.aMaterialAmbientColor;
aBackMaterial = r3DObj.aBackMaterial;
//-/ eTextureKind = r3DObj.eTextureKind;
//-/ eTextureMode = r3DObj.eTextureMode;
//-/ bInvertNormals = r3DObj.bInvertNormals;
//-/ bFilterTexture = r3DObj.bFilterTexture;
bUseDifferentBackMaterial = r3DObj.bUseDifferentBackMaterial;
}
/*************************************************************************
|*
|* Ausgabeparameter an 3D-Kontext setzen
|*
\************************************************************************/
void E3dCompoundObject::SetBase3DParams(ExtOutputDevice& rOut, Base3D* pBase3D,
BOOL& bDrawObject, BOOL& bDrawOutline, UINT16 nDrawFlags, BOOL bGhosted,
BOOL bIsLineDraft, BOOL bIsFillDraft)
{
bDrawObject = (nDrawFlags & E3D_DRAWFLAG_FILLED);
if(bDrawObject)
{
// Attribute aus dem Objekt holen
//-/ const XFillAttrSetItem* pFillAttr = GetFillAttr();
if(!bIsFillDraft)
{
const SfxItemSet& rSet = GetItemSet();
UINT16 nFillTrans = ITEMVALUE(rSet, XATTR_FILLTRANSPARENCE, XFillTransparenceItem);
if(
(nFillTrans && (nDrawFlags & E3D_DRAWFLAG_TRANSPARENT))
|| (!nFillTrans && !(nDrawFlags & E3D_DRAWFLAG_TRANSPARENT)))
{
XFillStyle eFillStyle = ITEMVALUE(rSet, XATTR_FILLSTYLE, XFillStyleItem );
Color aColorSolid = ((const XFillColorItem&) (rSet.
Get(XATTR_FILLCOLOR))).GetValue();
if(bGhosted)
{
aColorSolid = Color((aColorSolid.GetRed() >> 1) + 0x80,
(aColorSolid.GetGreen() >> 1) + 0x80,
(aColorSolid.GetBlue() >> 1) + 0x80);
}
Color aColorSolidWithTransparency = aColorSolid;
aColorSolidWithTransparency.SetTransparency((UINT8)(nFillTrans * 255 / 100));
Color aColorWhite(COL_WHITE);
Color aColorWhiteWithTransparency(COL_WHITE);
aColorWhiteWithTransparency.SetTransparency((UINT8)(nFillTrans * 255 / 100));
B3dTexture* pTexture = NULL;
// Material setzen
pBase3D->SetMaterial(aColorWhite, Base3DMaterialAmbient);
pBase3D->SetMaterial(aColorWhiteWithTransparency, Base3DMaterialDiffuse);
//-/ pBase3D->SetMaterial(aFrontMaterial.GetMaterial(Base3DMaterialSpecular), Base3DMaterialSpecular);
pBase3D->SetMaterial(GetMaterialSpecular(), Base3DMaterialSpecular);
//-/ pBase3D->SetMaterial(aFrontMaterial.GetMaterial(Base3DMaterialEmission), Base3DMaterialEmission);
pBase3D->SetMaterial(GetMaterialEmission(), Base3DMaterialEmission);
//-/ pBase3D->SetShininess(aFrontMaterial.GetShininess());
pBase3D->SetShininess(GetMaterialSpecularIntensity());
if(GetUseDifferentBackMaterial())
{
pBase3D->SetMaterial(aColorWhite, Base3DMaterialAmbient, Base3DMaterialBack);
pBase3D->SetMaterial(aColorWhiteWithTransparency, Base3DMaterialDiffuse, Base3DMaterialBack);
pBase3D->SetMaterial(aBackMaterial.GetMaterial(Base3DMaterialSpecular), Base3DMaterialSpecular, Base3DMaterialBack);
pBase3D->SetMaterial(aBackMaterial.GetMaterial(Base3DMaterialEmission), Base3DMaterialEmission, Base3DMaterialBack);
pBase3D->SetShininess(aBackMaterial.GetShininess(), Base3DMaterialBack);
}
Base3DTextureWrap eWrapX = Base3DTextureRepeat;
Base3DTextureWrap eWrapY = Base3DTextureRepeat;
Matrix4D mTexture;
if(pBase3D->GetOutputDevice()->GetDrawMode() & DRAWMODE_WHITEFILL)
{
// Farbe bleibt auf Weiss, nur noch den RenderMode setzen
pBase3D->SetRenderMode(Base3DRenderFill);
}
else if(eFillStyle == XFILL_NONE)
{
bDrawObject = FALSE;
}
else if(eFillStyle == XFILL_BITMAP)
{
Bitmap aBmp;
if(SFX_ITEM_SET == rSet.GetItemState(XATTR_FILLBITMAP, TRUE))
{
// EIndeutige Bitmap, benutze diese
aBmp = ITEMVALUE( rSet, XATTR_FILLBITMAP, XFillBitmapItem ).GetBitmap();
}
else
{
// Keine eindeutige Bitmap. benutze default
//
// DIES IST EINE NOTLOESUNG, BIS MAN IRGENDWO AN DIE
// DEAULT-BITMAP RANKOMMT (IST VON KA IN VORBEREITUNG)
//
aBmp = Bitmap(Size(4,4), 8);
}
if(bGhosted)
{
aBmp.Adjust( 50 );
}
// Texturattribute bilden
TextureAttributesBitmap aTexAttr(aBmp);
pTexture = pBase3D->ObtainTexture(aTexAttr);
if(!pTexture)
pTexture = pBase3D->ObtainTexture(aTexAttr, aBmp);
USHORT nOffX = ITEMVALUE( rSet, XATTR_FILLBMP_TILEOFFSETX, SfxUInt16Item );
USHORT nOffY = ITEMVALUE( rSet, XATTR_FILLBMP_TILEOFFSETY, SfxUInt16Item );
USHORT nOffPosX = ITEMVALUE( rSet, XATTR_FILLBMP_POSOFFSETX, SfxUInt16Item );
USHORT nOffPosY = ITEMVALUE( rSet, XATTR_FILLBMP_POSOFFSETY, SfxUInt16Item );
RECT_POINT eRectPoint = (RECT_POINT) ITEMVALUE( rSet, XATTR_FILLBMP_POS, SfxEnumItem );
BOOL bTile = ITEMVALUE( rSet, XATTR_FILLBMP_TILE, SfxBoolItem );
BOOL bStretch = ITEMVALUE( rSet, XATTR_FILLBMP_STRETCH, SfxBoolItem );
BOOL bLogSize = ITEMVALUE( rSet, XATTR_FILLBMP_SIZELOG, SfxBoolItem );
Size aSize;
aSize.Width() = labs( ITEMVALUE( rSet, XATTR_FILLBMP_SIZEX, SfxMetricItem ) );
aSize.Height() = labs( ITEMVALUE( rSet, XATTR_FILLBMP_SIZEY, SfxMetricItem ) );
Vector3D aScaleVector(1.0, 1.0, 1.0);
Vector3D aTranslateVector(0.0, 0.0, 0.0);
// Groesse beachten, logische Groesse einer Kachel bestimmen
// erst mal in 1/100 mm
Size aLogicalSize = aBmp.GetPrefSize();
const Volume3D& rVol = GetBoundVolume();
if(aLogicalSize.Width() == 0 || aLogicalSize.Height() == 0)
{
// Keine logische Groesse, nimm Pixelgroesse
// und wandle diese um
aLogicalSize = Application::GetDefaultDevice()->PixelToLogic(aBmp.GetSizePixel(), MAP_100TH_MM);
}
else
{
aLogicalSize =
OutputDevice::LogicToLogic(aLogicalSize, aBmp.GetPrefMapMode(), MAP_100TH_MM);
}
if(bLogSize)
{
// logische Groesse
if(aSize.Width() == 0 && aSize.Height() == 0)
{
// Originalgroesse benutzen, Original flag
// Um ein vernuenftiges Mapping bei defaults auch
// fuer 3D-Objekte zu erreichen, nimm die logische
// groesse einfach als groesser an
aLogicalSize.Width() /= 5; //10;
aLogicalSize.Height() /= 5; //10;
}
else
{
// Groesse in 100TH_MM in aSize, keine Flags
aLogicalSize = aSize;
// Um ein vernuenftiges Mapping bei defaults auch
// fuer 3D-Objekte zu erreichen, nimm die logische
// groesse einfach als groesser an
aLogicalSize.Width() /= 5; //10;
aLogicalSize.Height() /= 5; //10;
}
}
else
{
// relative Groesse
// 0..100 Prozent in aSize, relativ flag
aLogicalSize = Size(
(long)((rVol.GetWidth() * (double)aSize.Width() / 100.0) + 0.5),
(long)((rVol.GetHeight() * (double)aSize.Height() / 100.0) + 0.5));
}
// Skalieren
aScaleVector.X() = rVol.GetWidth() / (double)aLogicalSize.Width();
aScaleVector.Y() = rVol.GetHeight() / (double)aLogicalSize.Height();
if(bTile)
{
// Aneinandergefuegt drauflegen
double fLeftBound, fTopBound;
// Vertikal
if(eRectPoint == RP_LT || eRectPoint == RP_LM || eRectPoint == RP_LB)
{
// Links aligned starten
fLeftBound = 0.0;
}
else if(eRectPoint == RP_MT || eRectPoint == RP_MM || eRectPoint == RP_MB)
{
// Mittig
fLeftBound = (rVol.GetWidth() / 2.0)
- ((double)aLogicalSize.Width() / 2.0);
}
else
{
// Rechts aligned starten
fLeftBound = rVol.GetWidth()
- (double)aLogicalSize.Width();
}
// Horizontal
if(eRectPoint == RP_LT || eRectPoint == RP_MT || eRectPoint == RP_RT)
{
// Top aligned starten
fTopBound = 0.0;
}
else if(eRectPoint == RP_LM || eRectPoint == RP_MM || eRectPoint == RP_RM)
{
// Mittig
fTopBound = (rVol.GetHeight() / 2.0)
- ((double)aLogicalSize.Height() / 2.0);
}
else
{
// Bottom aligned starten
fTopBound = rVol.GetHeight()
- (double)aLogicalSize.Height();
}
// Verschieben
aTranslateVector.X() = fLeftBound;
aTranslateVector.Y() = fTopBound;
// Offset beachten
if(nOffPosX || nOffPosY)
{
aTranslateVector.X() += (double)aLogicalSize.Width() * ((double)nOffPosX / 100.0);
aTranslateVector.Y() += (double)aLogicalSize.Height() * ((double)nOffPosY / 100.0);
}
}
else
{
if(bStretch)
{
// 1x drauflegen, alles wie gehabt
// fertig
aScaleVector.X() = 1.0;
aScaleVector.Y() = 1.0;
}
else
{
// nur einmal benutzen
eWrapX = Base3DTextureSingle;
eWrapY = Base3DTextureSingle;
// Groesse beachten, zentriert anlegen
double fLeftBound = (rVol.GetWidth() / 2.0)
- ((double)aLogicalSize.Width() / 2.0);
double fTopBound = (rVol.GetHeight() / 2.0)
- ((double)aLogicalSize.Height() / 2.0);
// Verschieben
aTranslateVector.X() = fLeftBound;
aTranslateVector.Y() = fTopBound;
}
}
// TranslateVector anpassen
if(aTranslateVector.X())
aTranslateVector.X() /= -rVol.GetWidth();
if(aTranslateVector.Y())
aTranslateVector.Y() /= -rVol.GetHeight();
// Texturtransformation setzen
mTexture.Translate(aTranslateVector);
mTexture.Scale(aScaleVector);
}
else if(eFillStyle == XFILL_GRADIENT)
{
TextureAttributesGradient aTexAttr(
(void*)&rSet.Get(XATTR_FILLGRADIENT),
(void*)&rSet.Get(XATTR_GRADIENTSTEPCOUNT));
pTexture = pBase3D->ObtainTexture(aTexAttr);
if(!pTexture)
{
Bitmap aBmp = GetGradientBitmap(rSet);
if(bGhosted)
{
aBmp.Adjust( 50 );
}
pTexture = pBase3D->ObtainTexture(aTexAttr, aBmp);
}
}
else if(eFillStyle == XFILL_HATCH)
{
TextureAttributesHatch aTexAttr(
(void*)&rSet.Get(XATTR_FILLHATCH));
pTexture = pBase3D->ObtainTexture(aTexAttr);
if(!pTexture)
{
Bitmap aBmp = GetHatchBitmap(rSet);
if(bGhosted)
{
aBmp.Adjust( 50 );
}
pTexture = pBase3D->ObtainTexture(aTexAttr, aBmp);
}
// Texturtransformation setzen
mTexture.Scale(Vector3D(20.0, 20.0, 20.0));
}
else // if(eFillStyle == XFILL_SOLID)
{
// Material setzen
pBase3D->SetMaterial(aColorSolid, Base3DMaterialAmbient);
pBase3D->SetMaterial(aColorSolidWithTransparency, Base3DMaterialDiffuse);
if(GetUseDifferentBackMaterial())
{
pBase3D->SetMaterial(aBackMaterial.GetMaterial(Base3DMaterialAmbient), Base3DMaterialAmbient, Base3DMaterialBack);
pBase3D->SetMaterial(aBackMaterial.GetMaterial(Base3DMaterialDiffuse), Base3DMaterialDiffuse, Base3DMaterialBack);
}
pBase3D->SetRenderMode(Base3DRenderFill);
}
// Textur verwenden?
if(pTexture)
{
// Einige Modi einstellen
//-/ pTexture->SetTextureKind(eTextureKind);
pTexture->SetTextureKind(GetTextureKind());
//-/ pTexture->SetTextureMode(eTextureMode);
pTexture->SetTextureMode(GetTextureMode());
//-/ pTexture->SetTextureFilter(bFilterTexture ? Base3DTextureLinear : Base3DTextureNearest);
pTexture->SetTextureFilter(GetTextureFilter() ?
Base3DTextureLinear : Base3DTextureNearest);
pTexture->SetTextureWrapS(eWrapX);
pTexture->SetTextureWrapT(eWrapY);
pTexture->SetBlendColor(aColorSolid);
pTexture->SetTextureColor(aColorSolid);
// Textur aktivieren
pBase3D->SetActiveTexture(pTexture);
pBase3D->SetRenderMode(Base3DRenderFill);
// Texturtransformation setzen
GetScene()->GetCameraSet().SetTexture(mTexture);
}
else
{
// Reset auf Standardwerte
pBase3D->SetActiveTexture();
}
}
else
{
bDrawObject = FALSE;
}
}
else
{
bDrawObject = FALSE;
}
}
bDrawOutline = (nDrawFlags & E3D_DRAWFLAG_OUTLINE);
if(bDrawOutline)
{
XLineStyle aLineStyle(XLINE_NONE);
//-/ const XLineAttrSetItem* pLineAttr = GetLineAttr();
if(!rOut.GetIgnoreLineStyle())
{
Color aColorLine(COL_WHITE);
UINT16 nLineTransparence = ITEMVALUE(GetItemSet(), XATTR_LINETRANSPARENCE, XLineTransparenceItem);
if(
(nLineTransparence && (nDrawFlags & E3D_DRAWFLAG_TRANSPARENT))
|| (!nLineTransparence && !(nDrawFlags & E3D_DRAWFLAG_TRANSPARENT)))
{
aColorLine = ((const XLineColorItem&)(GetItem(XATTR_LINECOLOR))).GetValue();
if(bGhosted)
{
aColorLine = Color( (aColorLine.GetRed() >> 1) + 0x80,
(aColorLine.GetGreen() >> 1) + 0x80,
(aColorLine.GetBlue() >> 1) + 0x80);
}
aColorLine.SetTransparency((UINT8)(nLineTransparence * 255 / 100));
aLineStyle = ((const XLineStyleItem&)(GetItem(XATTR_LINESTYLE))).GetValue();
INT32 nLineWidth = ((const XLineWidthItem&)(GetItem(XATTR_LINEWIDTH))).GetValue();
if(nLineWidth && !bIsLineDraft)
{
Point aPnt(nLineWidth, 0);
aPnt = pBase3D->GetOutputDevice()->LogicToPixel(aPnt)
- pBase3D->GetOutputDevice()->LogicToPixel(Point());
if(aPnt.X() <= 0)
aPnt.X() = 1;
pBase3D->SetLineWidth((double)aPnt.X());
}
else
{
pBase3D->SetLineWidth(1.0);
}
// Material setzen
pBase3D->SetColor(aColorLine);
}
else
{
bDrawOutline = FALSE;
}
}
// Muss auch eine Outline des Objektes generiert werden?
if(bDrawOutline)
bDrawOutline = (aLineStyle != XLINE_NONE);
// Spezieller Modus, falls in Schwarz/Weiss gezeichnet werden soll.
// Die Linienfarbe ist bereits auf Schwarz gesetzt (Base3d::SetColor())
if(!bDrawOutline && pBase3D->GetOutputDevice()->GetDrawMode() & DRAWMODE_WHITEFILL)
bDrawOutline = TRUE;
}
if(bDrawObject || bDrawOutline)
{
// ObjectTrans setzen
Matrix4D mTransform = GetFullTransform();
GetScene()->GetCameraSet().SetObjectTrans(mTransform);
pBase3D->SetTransformationSet(&(GetScene()->GetCameraSet()));
}
}
/*************************************************************************
|*
|* Transformation auf die Geometrie anwenden
|*
\************************************************************************/
void E3dCompoundObject::ApplyTransform(const Matrix4D& rMatrix)
{
// call parent
E3dObject::ApplyTransform(rMatrix);
// Anwenden auf subobjekte (alte Geometrie)
ULONG nObjCnt = pSub->GetObjCount();
aLocalBoundVol = Volume3D();
for (ULONG i = 0; i < nObjCnt; i++)
{
E3dObject *p3DObj = (E3dObject*) pSub->GetObj(i);
if ( p3DObj->IsPartOfParent() )
aLocalBoundVol.Union(p3DObj->GetLocalBoundVolume());
}
// Geometrie herstellen
if(!bGeometryValid)
ReCreateGeometry();
// Matrix auch auf die neue Geometrie anwenden
aDisplayGeometry.Transform(rMatrix);
// LocalBoundVol neu aufbauen
aLocalBoundVol = aDisplayGeometry.GetBoundVolume();
}
/*************************************************************************
|*
|* Hittest fuer 3D-Objekte, wird an Geometrie weitergegeben
|*
\************************************************************************/
SdrObject* E3dCompoundObject::CheckHit(const Point& rPnt, USHORT nTol,
const SetOfByte* pVisiLayer) const
{
E3dPolyScene* pScene = (E3dPolyScene*)GetScene();
if(pScene)
{
// HitLine holen in ObjektKoordinaten
// ObjectTrans setzen
Matrix4D mTransform = ((E3dCompoundObject*)this)->GetFullTransform();
pScene->GetCameraSet().SetObjectTrans(mTransform);
// HitPoint Front und Back erzeugen und umrechnen
Vector3D aFront(rPnt.X(), rPnt.Y(), 0.0);
Vector3D aBack(rPnt.X(), rPnt.Y(), ZBUFFER_DEPTH_RANGE);
aFront = pScene->GetCameraSet().ViewToObjectCoor(aFront);
aBack = pScene->GetCameraSet().ViewToObjectCoor(aBack);
const Volume3D& rBoundVol = ((E3dCompoundObject*)this)->GetBoundVolume();
if(rBoundVol.IsValid())
{
double fXMax = aFront.X();
double fXMin = aBack.X();
if(fXMax < fXMin)
{
fXMax = aBack.X();
fXMin = aFront.X();
}
if(rBoundVol.MinVec().X() <= fXMax && rBoundVol.MaxVec().X() >= fXMin)
{
double fYMax = aFront.Y();
double fYMin = aBack.Y();
if(fYMax < fYMin)
{
fYMax = aBack.Y();
fYMin = aFront.Y();
}
if(rBoundVol.MinVec().Y() <= fYMax && rBoundVol.MaxVec().Y() >= fYMin)
{
double fZMax = aFront.Z();
double fZMin = aBack.Z();
if(fZMax < fZMin)
{
fZMax = aBack.Z();
fZMin = aFront.Z();
}
if(rBoundVol.MinVec().Z() <= fZMax && rBoundVol.MaxVec().Z() >= fZMin)
{
// Geometrie herstellen
if(!bGeometryValid)
((E3dCompoundObject*)this)->ReCreateGeometry();
// 3D Volumes schneiden sich, teste in der Geometrie
// auf Basis der Projektion weiter
if(((E3dCompoundObject*)this)->aDisplayGeometry.CheckHit(aFront, aBack, nTol) != -1L)
return ((E3dCompoundObject*)this);
}
}
}
}
}
return NULL;
}
/*************************************************************************
|*
|* Geometrie des Objektes auf angegebenen Punkt zentrieren
|*
\************************************************************************/
void E3dCompoundObject::CenterObject(const Vector3D& rCenter)
{
// Geometrie herstellen
if(!bGeometryValid)
ReCreateGeometry();
Vector3D aOldCenter = aDisplayGeometry.GetCenter();
Vector3D aMoveVector = rCenter - aOldCenter;
Matrix4D aTransMat;
aTransMat.Translate(aMoveVector);
ApplyTransform(aTransMat);
}
/*************************************************************************
|*
|* Schattenattribute holen
|*
\************************************************************************/
Color E3dCompoundObject::GetShadowColor()
{
return ((SdrShadowColorItem&)(GetItem(SDRATTR_SHADOWCOLOR))).GetValue();
//-/ Color aShadCol = rShadColItem.GetValue();
//-/ return aShadCol;
//-/ Color aShadCol;
//-/
//-/ if (pShadAttr!=NULL)
//-/ {
//-/ const SdrShadowColorItem& rShadColItem=((SdrShadowColorItem&)(pShadAttr->GetItem(SDRATTR_SHADOWCOLOR)));
//-/ aShadCol = rShadColItem.GetValue();
//-/ }
//-/
//-/ return aShadCol;
}
BOOL E3dCompoundObject::DrawShadowAsOutline()
{
const SfxItemSet& rSet = GetItemSet();
XFillStyle eFillStyle = ((XFillStyleItem&)(rSet.Get(XATTR_FILLSTYLE))).GetValue();
XLineStyle eLineStyle = ((XLineStyleItem&)(rSet.Get(XATTR_LINESTYLE))).GetValue();
BOOL bFillAttrIsNone = eFillStyle == XFILL_NONE;
BOOL bLineAttrIsNone = eLineStyle == XLINE_NONE;
return (bFillAttrIsNone && !bLineAttrIsNone);
//-/ BOOL bRetval = FALSE;
//-/
//-/ if (pShadAttr!=NULL)
//-/ {
//-/ BOOL bFillAttrIsNone = TRUE;
//-/ if (pFillAttr!=NULL)
//-/ {
//-/ XFillStyle eFillStyle=((XFillStyleItem&)(pFillAttr->GetItem(XATTR_FILLSTYLE))).GetValue();
//-/ if (eFillStyle!=XFILL_NONE)
//-/ bFillAttrIsNone = FALSE;
//-/ }
//-/
//-/ BOOL bLineAttrIsNone = TRUE;
//-/ if (pLineAttr!=NULL)
//-/ {
//-/ XLineStyle eLineStyle=((XLineStyleItem&)(pLineAttr->GetItem(XATTR_LINESTYLE))).GetValue();
//-/ if (eLineStyle!=XLINE_NONE)
//-/ bLineAttrIsNone = FALSE;
//-/ }
//-/
//-/ bRetval = bFillAttrIsNone && !bLineAttrIsNone;
//-/ }
//-/
//-/ return bRetval;
}
INT32 E3dCompoundObject::GetShadowXDistance()
{
return (long)((SdrShadowXDistItem&)(GetItem(SDRATTR_SHADOWXDIST))).GetValue();
}
INT32 E3dCompoundObject::GetShadowYDistance()
{
return (long)((SdrShadowYDistItem&)(GetItem(SDRATTR_SHADOWYDIST))).GetValue();
}
UINT16 E3dCompoundObject::GetShadowTransparence()
{
return (UINT16)((SdrShadowTransparenceItem&)(GetItem(SDRATTR_SHADOWTRANSPARENCE))).GetValue();
}
BOOL E3dCompoundObject::DoDrawShadow()
{
const SfxItemSet& rSet = GetItemSet();
BOOL bRetval(FALSE);
BOOL bShadOn = ((SdrShadowItem&)(rSet.Get(SDRATTR_SHADOW))).GetValue();
if(bShadOn)
{
bRetval = TRUE;
if(((XFillStyleItem&)(rSet.Get(XATTR_FILLSTYLE))).GetValue() == XFILL_NONE)
{
if(((XLineStyleItem&)(rSet.Get(XATTR_LINESTYLE))).GetValue() == XLINE_NONE)
{
bRetval = FALSE;
}
}
}
//-/ BOOL bRetval = FALSE;
//-/
//-/ if (pShadAttr!=NULL)
//-/ {
//-/ FASTBOOL bShadOn=((SdrShadowItem&)(pShadAttr->GetItem(SDRATTR_SHADOW))).GetValue();
//-/ if (bShadOn) {
//-/ bRetval = TRUE;
//-/
//-/ // Eventuell bRetval auf FALSE falls nicht gefuellt und
//-/ // kein Linienstil!
//-/ if(!pFillAttr
//-/ || ((XFillStyleItem&)(pFillAttr->GetItem(XATTR_FILLSTYLE))).GetValue() == XFILL_NONE)
//-/ {
//-/ if(!pLineAttr
//-/ || ((XLineStyleItem&)(pLineAttr->GetItem(XATTR_LINESTYLE))).GetValue() == XLINE_NONE)
//-/ {
//-/ bRetval = FALSE;
//-/ }
//-/ }
//-/ }
//-/ }
return bRetval;
}
/*************************************************************************
|*
|* Objekt als WireFrame zeichnen
|*
\************************************************************************/
void E3dCompoundObject::DrawObjectWireframe(ExtOutputDevice& rXOut)
{
UINT32 nPolyCounter = 0;
UINT32 nEntityCounter = 0;
UINT32 nUpperBound;
Point aFirstPoint, aLastPoint, aNewPoint;
B3dEntityBucket& rEntityBucket = GetDisplayGeometry().GetEntityBucket();
GeometryIndexValueBucket& rIndexBucket = GetDisplayGeometry().GetIndexBucket();
B3dTransformationSet& rSet = GetScene()->GetCameraSet();
BOOL bDrawLine, bLastDrawLine;
Vector3D aPoint;
while(nPolyCounter < rIndexBucket.Count())
{
// Naechstes Primitiv
nUpperBound = rIndexBucket[nPolyCounter++].GetIndex();
bDrawLine = bLastDrawLine = rEntityBucket[nEntityCounter].IsEdgeVisible();
aPoint = rSet.ObjectToViewCoor(rEntityBucket[nEntityCounter++].Point().GetVector3D());
aFirstPoint.X() = (long)(aPoint.X() + 0.5);
aFirstPoint.Y() = (long)(aPoint.Y() + 0.5);
aLastPoint = aFirstPoint;
// Polygon fuellen
while(nEntityCounter < nUpperBound)
{
// Punkt holen und auf Weltkoordinaten umrechnen
bDrawLine = rEntityBucket[nEntityCounter].IsEdgeVisible();
aPoint = rSet.ObjectToViewCoor(rEntityBucket[nEntityCounter++].Point().GetVector3D());
aNewPoint.X() = (long)(aPoint.X() + 0.5);
aNewPoint.Y() = (long)(aPoint.Y() + 0.5);
if(bLastDrawLine)
rXOut.GetOutDev()->DrawLine(aLastPoint, aNewPoint);
aLastPoint = aNewPoint;
bLastDrawLine = bDrawLine;
}
// Polygon scliessen
if(bLastDrawLine)
rXOut.GetOutDev()->DrawLine(aLastPoint, aFirstPoint);
}
}
/*************************************************************************
|*
|* Ein Segment fuer Extrude oder Lathe erzeugen
|*
\************************************************************************/
void E3dCompoundObject::CreateSegment(
const PolyPolygon3D& rFront, // vorderes Polygon
const PolyPolygon3D& rBack, // hinteres Polygon
const PolyPolygon3D* pPrev, // smooth uebergang zu Vorgaenger
const PolyPolygon3D* pNext, // smooth uebergang zu Nachfolger
BOOL bCreateFront, // vorderen Deckel erzeugen
BOOL bCreateBack, // hinteren Deckel erzeugen
double fPercentDiag, // Anteil des Deckels an der Tiefe
BOOL bSmoothLeft, // Glaetten der umlaufenden Normalen links
BOOL bSmoothRight, // Glaetten der umlaufenden Normalen rechts
BOOL bSmoothFrontBack, // Glaetten der Abschlussflaechen
double fSurroundFactor, // Wertebereich der Texturkoordinaten im Umlauf
double fTextureStart, // TexCoor ueber Extrude-Tiefe
double fTextureDepth, // TexCoor ueber Extrude-Tiefe
BOOL bCreateTexture,
BOOL bCreateNormals,
BOOL bCharacterExtrude, // FALSE=exakt, TRUE=ohne Ueberschneidungen
BOOL bRotateTexture90 // Textur der Seitenflaechen um 90 Grad kippen
)
{
PolyPolygon3D aNormalsLeft, aNormalsRight;
AddInBetweenNormals(rFront, rBack, aNormalsLeft, bSmoothLeft);
AddInBetweenNormals(rFront, rBack, aNormalsRight, bSmoothRight);
Vector3D aOffset = rBack.GetMiddle() - rFront.GetMiddle();
// Ausnahmen: Nicht geschlossen
if(!rFront.IsClosed())
{
bCreateFront = FALSE;
}
if(!rBack.IsClosed())
{
bCreateBack = FALSE;
}
// Ausnahmen: Einfache Linie
if(rFront[0].GetPointCount() < 3 || (!bCreateFront && !bCreateBack))
{
fPercentDiag = 0.0;
}
if(fPercentDiag == 0.0)
{
// Ohne Schraegen, Vorderseite
if(bCreateFront)
{
PolyPolygon3D aNormalsFront;
AddFrontNormals(rFront, aNormalsFront, aOffset);
if(!bSmoothFrontBack)
CreateFront(rFront, aNormalsFront, bCreateNormals, bCreateTexture);
if(bSmoothLeft)
AddFrontNormals(rFront, aNormalsLeft, aOffset);
if(bSmoothFrontBack)
CreateFront(rFront, aNormalsLeft, bCreateNormals, bCreateTexture);
}
else
{
if(pPrev)
AddInBetweenNormals(*pPrev, rFront, aNormalsLeft, bSmoothLeft);
}
// Ohne Schraegen, Rueckseite
if(bCreateBack)
{
PolyPolygon3D aNormalsBack;
AddBackNormals(rBack, aNormalsBack, aOffset);
if(!bSmoothFrontBack)
CreateBack(rBack, aNormalsBack, bCreateNormals, bCreateTexture);
if(bSmoothRight)
AddBackNormals(rBack, aNormalsRight, aOffset);
if(bSmoothFrontBack)
CreateBack(rBack, aNormalsRight, bCreateNormals, bCreateTexture);
}
else
{
if(pNext)
AddInBetweenNormals(rBack, *pNext, aNormalsRight, bSmoothRight);
}
// eigentliches Zwischenstueck
CreateInBetween(rFront, rBack,
aNormalsLeft, aNormalsRight,
bCreateNormals,
fSurroundFactor,
fTextureStart,
fTextureDepth,
bRotateTexture90);
}
else
{
// Mit Scraegen, Vorderseite
PolyPolygon3D aLocalFront = rFront;
PolyPolygon3D aLocalBack = rBack;
double fExtrudeDepth, fDiagLen;
double fTexMidStart = fTextureStart;
double fTexMidDepth = fTextureDepth;
if(bCreateFront || bCreateBack)
{
fExtrudeDepth = aOffset.GetLength();
fDiagLen = fPercentDiag * fExtrudeDepth;
}
if(bCreateFront)
{
PolyPolygon3D aOuterFront;
PolyPolygon3D aNormalsOuterFront;
AddFrontNormals(aLocalFront, aNormalsOuterFront, aOffset);
if(bCharacterExtrude)
{
// Polygon kopieren
aOuterFront = aLocalFront;
// notwendige Normalen erzeugen
PolyPolygon3D aGrowDirection;
AddInBetweenNormals(aLocalFront, aLocalBack, aGrowDirection, bSmoothLeft);
// Groesse inneres Polygon merken
Volume3D aOldSize(aLocalFront.GetPolySize());
// Inneres Polygon vergroessern
GrowPoly(aLocalFront, aGrowDirection, fDiagLen);
// Inneres Polygon nach innen verschieben
GrowPoly(aLocalFront, aNormalsOuterFront, -fDiagLen);
// Neue Groesse inneres Polygon feststellen
Volume3D aNewSize(aLocalFront.GetPolySize());
// Skalierung feststellen (nur X,Y)
Vector3D aScaleVec(aOldSize.GetWidth() / aNewSize.GetWidth(),
aOldSize.GetHeight() / aNewSize.GetHeight(),
1.0);
// Transformation bilden
Matrix4D aTransMat;
aTransMat.Scale(aScaleVec);
// aeusseres und inneres Polygon skalieren
aLocalFront.Transform(aTransMat);
aOuterFront.Transform(aTransMat);
// Neue Groesse aktualisieren
aNewSize = aLocalFront.GetPolySize();
// Translation feststellen
Vector3D aTransVec(aOldSize.MinVec().X() - aNewSize.MinVec().X(),
aOldSize.MinVec().Y() - aNewSize.MinVec().Y(),
0.0);
// Transformation bilden
aTransMat.Identity();
aTransMat.Translate(aTransVec);
// aeusseres und inneres Polygon skalieren
aLocalFront.Transform(aTransMat);
aOuterFront.Transform(aTransMat);
}
else
{
// Polygon kopieren
aOuterFront = aLocalFront;
// notwendige Normalen erzeugen
PolyPolygon3D aGrowDirection;
AddInBetweenNormals(aLocalFront, aLocalBack, aGrowDirection, bSmoothLeft);
// Aeusseres Polygon verkleinern
GrowPoly(aOuterFront, aGrowDirection, -fDiagLen);
aOuterFront.CorrectGrownPoly(aLocalFront);
// Inneres Polygon nach innen verschieben
GrowPoly(aLocalFront, aNormalsOuterFront, -fDiagLen);
}
// eventuell noch glaetten
if(bSmoothLeft)
{
if(bSmoothFrontBack)
AddInBetweenNormals(aOuterFront, aLocalFront, aNormalsOuterFront, bSmoothLeft);
AddInBetweenNormals(aOuterFront, aLocalFront, aNormalsLeft, bSmoothLeft);
}
// vordere Zwischenstuecke erzeugen
CreateInBetween(aOuterFront, aLocalFront,
aNormalsOuterFront, aNormalsLeft,
bCreateNormals,
fSurroundFactor,
fTextureStart,
fTextureDepth * fPercentDiag,
bRotateTexture90);
// Vorderseite erzeugen
CreateFront(aOuterFront, aNormalsOuterFront, bCreateNormals, bCreateTexture);
// Weitere Texturwerte setzen
fTexMidStart += fTextureDepth * fPercentDiag;
fTexMidDepth -= fTextureDepth * fPercentDiag;
}
else
{
if(pPrev)
AddInBetweenNormals(*pPrev, rFront, aNormalsLeft, bSmoothLeft);
}
// Mit Scraegen, Rueckseite
if(bCreateBack)
{
PolyPolygon3D aOuterBack;
PolyPolygon3D aNormalsOuterBack;
AddBackNormals(aLocalBack, aNormalsOuterBack, aOffset);
if(bCharacterExtrude)
{
// Polygon kopieren
aOuterBack = aLocalBack;
// notwendige Normalen erzeugen
PolyPolygon3D aGrowDirection;
AddInBetweenNormals(aLocalFront, aLocalBack, aGrowDirection, bSmoothRight);
// Groesse inneres Polygon merken
Volume3D aOldSize(aLocalBack.GetPolySize());
// Inneres Polygon vergroessern
GrowPoly(aLocalBack, aGrowDirection, fDiagLen);
// Inneres Polygon nach innen verschieben
GrowPoly(aLocalBack, aNormalsOuterBack, -fDiagLen);
// Neue Groesse inneres Polygon feststellen
Volume3D aNewSize(aLocalBack.GetPolySize());
// Skalierung feststellen (nur X,Y)
Vector3D aScaleVec(aOldSize.GetWidth() / aNewSize.GetWidth(),
aOldSize.GetHeight() / aNewSize.GetHeight(),
1.0);
// Transformation bilden
Matrix4D aTransMat;
aTransMat.Scale(aScaleVec);
// aeusseres und inneres Polygon skalieren
aLocalBack.Transform(aTransMat);
aOuterBack.Transform(aTransMat);
// Neue Groesse aktualisieren
aNewSize = aLocalBack.GetPolySize();
// Translation feststellen
Vector3D aTransVec(aOldSize.MinVec().X() - aNewSize.MinVec().X(),
aOldSize.MinVec().Y() - aNewSize.MinVec().Y(),
0.0);
// Transformation bilden
aTransMat.Identity();
aTransMat.Translate(aTransVec);
// aeusseres und inneres Polygon skalieren
aLocalBack.Transform(aTransMat);
aOuterBack.Transform(aTransMat);
}
else
{
// Polygon kopieren
aOuterBack = aLocalBack;
// notwendige Normalen erzeugen
PolyPolygon3D aGrowDirection;
AddInBetweenNormals(aLocalFront, aLocalBack, aGrowDirection, bSmoothRight);
// Aeusseres Polygon verkleinern
GrowPoly(aOuterBack, aGrowDirection, -fDiagLen);
aOuterBack.CorrectGrownPoly(aLocalBack);
// Inneres Polygon nach innen verschieben
GrowPoly(aLocalBack, aNormalsOuterBack, -fDiagLen);
}
// eventuell noch glaetten
if(bSmoothRight)
{
if(bSmoothFrontBack)
AddInBetweenNormals(aLocalBack, aOuterBack, aNormalsOuterBack, bSmoothRight);
AddInBetweenNormals(aLocalBack, aOuterBack, aNormalsRight, bSmoothRight);
}
// vordere Zwischenstuecke erzeugen
// hintere Zwischenstuecke erzeugen
CreateInBetween(aLocalBack, aOuterBack,
aNormalsRight, aNormalsOuterBack,
bCreateNormals,
fSurroundFactor,
fTextureStart + (fTextureDepth * (1.0 - fPercentDiag)),
fTextureDepth * fPercentDiag,
bRotateTexture90);
// Rueckseite erzeugen
CreateBack(aOuterBack, aNormalsOuterBack, bCreateNormals, bCreateTexture);
// Weitere Texturwerte setzen
fTexMidDepth -= fTextureDepth * fPercentDiag;
}
else
{
if(pNext)
AddInBetweenNormals(rBack, *pNext, aNormalsRight, bSmoothRight);
}
// eigentliches Zwischenstueck
CreateInBetween(aLocalFront, aLocalBack,
aNormalsLeft, aNormalsRight,
bCreateNormals,
fSurroundFactor,
fTexMidStart,
fTexMidDepth,
bRotateTexture90);
}
}
/*************************************************************************
|*
|* Parameter Geometrieerzeugung setzen
|*
\************************************************************************/
void E3dCompoundObject::SetCreateNormals(BOOL bNew)
{
if(bCreateNormals != bNew)
{
bCreateNormals = bNew;
bGeometryValid = FALSE;
}
}
void E3dCompoundObject::SetCreateTexture(BOOL bNew)
{
if(bCreateTexture != bNew)
{
bCreateTexture = bNew;
bGeometryValid = FALSE;
}
}
/*************************************************************************
|*
|* DisplayGeometry rausruecken
|*
\************************************************************************/
B3dGeometry& E3dCompoundObject::GetDisplayGeometry()
{
// Geometrie herstellen
if(!bGeometryValid)
ReCreateGeometry();
return aDisplayGeometry;
}
/*************************************************************************
|*
|* Material des Objektes
|*
\************************************************************************/
//-/void E3dCompoundObject::SetFrontMaterial(const B3dMaterial& rNew)
//-/{
//-/ if(aFrontMaterial != rNew)
//-/ {
//-/ aFrontMaterial = rNew;
//-/ }
//-/}
void E3dCompoundObject::SetMaterialAmbientColor(const Color& rColor)
{
if(aMaterialAmbientColor != rColor)
{
aMaterialAmbientColor = rColor;
}
}
void E3dCompoundObject::SetBackMaterial(const B3dMaterial& rNew)
{
if(aBackMaterial != rNew)
{
aBackMaterial = rNew;
}
}
void E3dCompoundObject::SetUseDifferentBackMaterial(BOOL bNew)
{
if(bUseDifferentBackMaterial != bNew)
{
bUseDifferentBackMaterial = bNew;
}
}
/*************************************************************************
|*
|* 3D Ausgabe
|*
\************************************************************************/
void E3dCompoundObject::Paint3D(ExtOutputDevice& rOut, Base3D* pBase3D,
const SdrPaintInfoRec& rInfoRec, UINT16 nDrawFlags)
{
// call parent, draw all subobjects
E3dObject::Paint3D(rOut, pBase3D, rInfoRec, nDrawFlags);
// Feststellen, ob das Objekt dargestellt werden muss, was die Layer angeht
BOOL bPrinter = (pBase3D->GetOutputDevice()->GetOutDevType()==OUTDEV_PRINTER);
const SetOfByte* pVisiLayer=&rInfoRec.aPaintLayer;
E3dScene* pScene = GetScene();
BOOL bOnlySelectedCriteria = (pScene && (!pScene->DoDrawOnlySelected() || GetSelected()));
if((!bPrinter || IsPrintable()) && pVisiLayer->IsSet(GetLayer()) && bOnlySelectedCriteria)
{
// Ausgabeparameter setzen
BOOL bDrawOutline;
BOOL bDrawObject;
BOOL bIsLineDraft(0 != (rInfoRec.nPaintMode & SDRPAINTMODE_DRAFTLINE));
BOOL bIsFillDraft(0 != (rInfoRec.nPaintMode & SDRPAINTMODE_DRAFTFILL));
SetBase3DParams(rOut, pBase3D, bDrawObject, bDrawOutline, nDrawFlags,
(rInfoRec.pPV && rInfoRec.pPV->GetView().DoVisualizeEnteredGroup()) ? rInfoRec.bNotActive : FALSE,
bIsLineDraft, bIsFillDraft);
// Culling?
pBase3D->SetCullMode(GetDoubleSided() ? Base3DCullNone : Base3DCullBack);
// Objekt flat darstellen?
//-/ BOOL bForceFlat = (bUseStdNormals && !bUseStdNormalsUseSphere);
BOOL bForceFlat = ((GetNormalsKind() > 0) && !(GetNormalsKind() > 1));
pBase3D->SetForceFlat(bForceFlat);
// Geometrie ausgeben
if(bDrawObject)
pBase3D->DrawPolygonGeometry(GetDisplayGeometry());
// Outline ausgeben
if(bDrawOutline && pBase3D->GetLightGroup())
{
BOOL bLightingWasEnabled = pBase3D->GetLightGroup()->IsLightingEnabled();
pBase3D->GetLightGroup()->EnableLighting(FALSE);
pBase3D->SetLightGroup(pBase3D->GetLightGroup());
// #79585# switch off texturing (if used)
pBase3D->SetActiveTexture();
pBase3D->DrawPolygonGeometry(GetDisplayGeometry(), TRUE);
pBase3D->GetLightGroup()->EnableLighting(bLightingWasEnabled);
pBase3D->SetLightGroup(pBase3D->GetLightGroup());
}
}
#ifdef DBG_UTIL // SnapRect und BoundRect zum testen zeichnen
static BOOL bDoDrawSnapBoundToMakeThemVisible = FALSE;
if(bDoDrawSnapBoundToMakeThemVisible)
{
OutputDevice* pOut = rOut.GetOutDev();
// SnapRect in Rot
Rectangle aTempRect = GetSnapRect();
pOut->SetLineColor(Color(COL_RED));
pOut->SetFillColor();
pOut->DrawRect(aTempRect);
// BoundRect in Gruen
aTempRect = GetBoundRect();
pOut->SetLineColor(Color(COL_GREEN));
pOut->SetFillColor();
pOut->DrawRect(aTempRect);
}
#endif
}
/*************************************************************************
|*
|* Objekt als Kontur in das Polygon einfuegen
|*
\************************************************************************/
void E3dCompoundObject::TakeContour3D(XPolyPolygon& rPoly)
{
// call parent
E3dObject::TakeContour3D(rPoly);
// Kontur dieses Objektes liefern
UINT32 nPolyCounter = 0;
UINT32 nEntityCounter = 0;
UINT32 nUpperBound;
B3dEntityBucket& rEntityBucket = GetDisplayGeometry().GetEntityBucket();
GeometryIndexValueBucket& rIndexBucket = GetDisplayGeometry().GetIndexBucket();
B3dTransformationSet& rSet = GetScene()->GetCameraSet();
Vector3D aPoint;
Point aNewPoint;
// ObjectTrans setzen
Matrix4D mTransform = GetFullTransform();
rSet.SetObjectTrans(mTransform);
while(nPolyCounter < rIndexBucket.Count())
{
// Naechstes Primitiv
nUpperBound = rIndexBucket[nPolyCounter++].GetIndex();
XPolygon aNewPart(UINT16(nUpperBound - nEntityCounter));
UINT16 nIndex = 0;
while(nEntityCounter < nUpperBound)
{
aPoint = rSet.ObjectToViewCoor(rEntityBucket[nEntityCounter++].Point().GetVector3D());
aNewPart[nIndex ].X() = (long)(aPoint.X() + 0.5);
aNewPart[nIndex++].Y() = (long)(aPoint.Y() + 0.5);
}
// Teilprimitiv einfuegen
rPoly.Insert(aNewPart);
}
// add shadow now too (#61279#)
PolyPolygon aShadowPolyPoly;
GetShadowPolygon(aShadowPolyPoly);
for(UINT16 a = 0; a < aShadowPolyPoly.Count(); a++)
{
XPolygon aNewPart(aShadowPolyPoly[a]);
rPoly.Insert(aNewPart);
}
}
/*************************************************************************
|*
|* Schatten fuer 3D-Objekte zeichnen
|*
\************************************************************************/
void E3dCompoundObject::DrawShadows(Base3D *pBase3D, ExtOutputDevice& rXOut,
const Rectangle& rBound, const Volume3D& rVolume,
const SdrPaintInfoRec& rInfoRec)
{
// call parent
E3dObject::DrawShadows(pBase3D, rXOut, rBound, rVolume, rInfoRec);
// Schatten fuer dieses Objekt zeichnen
// Feststellen, ob das Objekt dargestellt werden muss, was die Layer angeht
BOOL bPrinter = (pBase3D->GetOutputDevice()->GetOutDevType()==OUTDEV_PRINTER);
const SetOfByte* pVisiLayer=&rInfoRec.aPaintLayer;
if(DoDrawShadow()
&& (!bPrinter || IsPrintable())
&& pVisiLayer->IsSet(GetLayer()))
{
// ObjectTrans setzen
Matrix4D mTransform = GetFullTransform();
GetScene()->GetCameraSet().SetObjectTrans(mTransform);
// Schattenpolygon holen
PolyPolygon aShadowPoly;
GetShadowPolygon(aShadowPoly);
// ...und Zeichnen
DrawShadowPolygon(aShadowPoly, rXOut);
}
}
void E3dCompoundObject::GetShadowPolygon(PolyPolygon& rPoly)
{
INT32 nXDist = GetShadowXDistance();
INT32 nYDist = GetShadowYDistance();
UINT32 nPolyCounter = 0;
UINT32 nEntityCounter = 0;
UINT32 nUpperBound;
UINT16 nPolyPos = 0;
Point aPolyPoint;
// Buckets der Geometrie holen
B3dTransformationSet& rSet = GetScene()->GetCameraSet();
B3dEntityBucket& rEntityBucket = GetDisplayGeometry().GetEntityBucket();
GeometryIndexValueBucket& rIndexBucket = GetDisplayGeometry().GetIndexBucket();
//-/ if(bShadow3D)
if(GetShadow3D())
{
// 3D Schatten. Nimm Lichtquelle und Ebene. Projiziere
// die Punkte und jage sie durch die 3D Darstellung.
Vector3D aLampPositionOrDirection;
BOOL bDirectionalSource(TRUE);
Vector3D aGroundPosition;
Vector3D aGroundDirection;
B3dLightGroup& rLightGroup = GetScene()->GetLightGroup();
// Lampe waehlen
Base3DLightNumber aLightNumber = Base3DLight0;
BOOL bLightNumberValid(FALSE);
while(!bLightNumberValid && aLightNumber <= Base3DLight7)
{
if(rLightGroup.IsEnabled(aLightNumber))
bLightNumberValid = TRUE;
else
aLightNumber = (Base3DLightNumber)((UINT16)aLightNumber + 1);
}
if(bLightNumberValid)
{
// Position oder Vektor aus der Lampe extrahieren
if(rLightGroup.IsDirectionalSource(aLightNumber))
{
// Nur Richtung vorhanden
aLampPositionOrDirection = -rLightGroup.GetDirection(aLightNumber);
aLampPositionOrDirection.Normalize();
}
else
{
// Nur Position vorhanden
aLampPositionOrDirection = rLightGroup.GetPosition(aLightNumber);
bDirectionalSource = FALSE;
}
// Ebene holen, Richtung in Augkoordinaten
aGroundDirection = -GetScene()->GetShadowPlaneDirection();
aGroundDirection.Normalize();
// Ist die Lampe auch vor der Ebene?
Vector3D aLightNormal = aLampPositionOrDirection;
if(!bDirectionalSource)
{
// Nur Position vorhanden, berechne einen Lichtvektor
aLightNormal = GetDisplayGeometry().GetEntityBucket()[0].Point().GetVector3D()
- aLampPositionOrDirection;
aLightNormal.Normalize();
}
double fLightAndNormal = aLightNormal.Scalar(aGroundDirection);
B3dVolume aVolume = rSet.GetDeviceVolume();
// auf Augkoordinaten umstellen
double fTemp = aVolume.MinVec().Z();
aVolume.MinVec().Z() = -aVolume.MaxVec().Z();
aVolume.MaxVec().Z() = -fTemp;
if(fLightAndNormal > 0.0)
{
// Position der Ebene in Augkoordinaten setzen
aGroundPosition.X() = (aGroundDirection.X() < 0.0) ? aVolume.MinVec().X() : aVolume.MaxVec().X();
aGroundPosition.Y() = (aGroundDirection.Y() < 0.0) ? aVolume.MinVec().Y() : aVolume.MaxVec().Y();
aGroundPosition.Z() = aVolume.MinVec().Z() - ((aVolume.MaxVec().Z() - aVolume.MinVec().Z()) / 8.0);
// Skalar der Ebenengleichung holen
double fGroundScalar = -aGroundPosition.Scalar(aGroundDirection);
// ObjectTrans setzen
BOOL bPolygonVisible(TRUE);
B3dTransformationSet& rSet = GetScene()->GetCameraSet();
Matrix4D mTransform = GetFullTransform();
rSet.SetObjectTrans(mTransform);
while(nPolyCounter < rIndexBucket.Count())
{
// Naechstes Primitiv
nUpperBound = rIndexBucket[nPolyCounter++].GetIndex();
nPolyPos = 0;
bPolygonVisible = TRUE;
Polygon aPoly((UINT16)(nUpperBound - nEntityCounter));
// Polygon fuellen
while(nEntityCounter < nUpperBound)
{
// Naechsten Punkt holen
Vector3D aPoint = rEntityBucket[nEntityCounter++].Point().GetVector3D();
// Auf Augkoordinaten umrechnen
aPoint = rSet.ObjectToEyeCoor(aPoint);
// Richtung bestimmen
Vector3D aDirection = aLampPositionOrDirection;
if(!bDirectionalSource)
{
aDirection = aPoint - aLampPositionOrDirection;
aDirection.Normalize();
}
// Schnittpunkt berechnen (N.D)
double fDiv = aGroundDirection.Scalar(aDirection);
if(fabs(fDiv) < SMALL_DVALUE)
{
bPolygonVisible = FALSE;
}
else
{
fDiv = -((fGroundScalar + aGroundDirection.Scalar(aPoint)) / fDiv);
aPoint += aDirection * fDiv;
}
// Punkt normal transformieren
if(bPolygonVisible)
{
// Auf ViewKoordinaten
Vector3D aShadowPoint = rSet.EyeToViewCoor(aPoint);
aPolyPoint.X() = (long)(aShadowPoint.X() + 0.5) + nXDist;
aPolyPoint.Y() = (long)(aShadowPoint.Y() + 0.5) + nYDist;
aPoly[nPolyPos++] = aPolyPoint;
}
}
// Teilpolygon einfuegen
rPoly.Insert(aPoly);
}
}
}
}
else
{
// Normaler 2D Schatten
Vector3D aPoint;
// ObjectTrans setzen
Matrix4D mTransform = GetFullTransform();
rSet.SetObjectTrans(mTransform);
if(DrawShadowAsOutline())
{
//SubPolygon mit Punktpaaren bilden
BOOL bLastLineVisible;
UINT16 nPolySize = (UINT16)(rEntityBucket.Count() * 2);
Polygon aPoly(nPolySize);
Vector3D aLast;
Point aLastPolyPoint;
nPolyPos = 0;
while(nPolyCounter < rIndexBucket.Count())
{
// Naechstes Primitiv
nUpperBound = rIndexBucket[nPolyCounter++].GetIndex();
// Polygon bilden
if(bLastLineVisible = rEntityBucket[nUpperBound - 1].IsEdgeVisible())
{
aLast = rEntityBucket[nUpperBound - 1].Point().GetVector3D();
aLast = rSet.ObjectToViewCoor(aLast);
aLastPolyPoint.X() = (long)(aLast.X() + 0.5) + nXDist;
aLastPolyPoint.Y() = (long)(aLast.Y() + 0.5) + nYDist;
}
while(nEntityCounter < nUpperBound)
{
aPoint = rEntityBucket[nEntityCounter].Point().GetVector3D();
aPoint = rSet.ObjectToViewCoor(aPoint);
aPolyPoint.X() = (long)(aPoint.X() + 0.5) + nXDist;
aPolyPoint.Y() = (long)(aPoint.Y() + 0.5) + nYDist;
// Linie aLast, aPoint erfassen
if(bLastLineVisible)
{
if(nPolyPos + 2 > nPolySize)
{
// Polygon muss groesser
nPolySize *= 2;
aPoly.SetSize(nPolySize);
}
aPoly[nPolyPos++] = aLastPolyPoint;
aPoly[nPolyPos++] = aPolyPoint;
}
// naechster Punkt
aLastPolyPoint = aPolyPoint;
aLast = aPoint;
bLastLineVisible = rEntityBucket[nEntityCounter++].IsEdgeVisible();
}
}
// Wahre Groesse setzen
aPoly.SetSize(nPolyPos);
// Teilpolygon einfuegen
rPoly.Insert(aPoly);
}
else
{
while(nPolyCounter < rIndexBucket.Count())
{
// Naechstes Primitiv
nUpperBound = rIndexBucket[nPolyCounter++].GetIndex();
Polygon aPoly((UINT16)(nUpperBound - nEntityCounter));
nPolyPos = 0;
// Polygon fuellen
while(nEntityCounter < nUpperBound)
{
aPoint = rEntityBucket[nEntityCounter++].Point().GetVector3D();
aPoint = rSet.ObjectToViewCoor(aPoint);
aPolyPoint.X() = (long)(aPoint.X() + 0.5) + nXDist;
aPolyPoint.Y() = (long)(aPoint.Y() + 0.5) + nYDist;
aPoly[nPolyPos++] = aPolyPoint;
}
// Teilpolygon einfuegen
rPoly.Insert(aPoly);
}
}
}
}
void E3dCompoundObject::DrawShadowPolygon(PolyPolygon& rPoly, ExtOutputDevice& rXOut)
{
Color aCol = GetShadowColor();
OutputDevice *pDevice = rXOut.GetOutDev();
BOOL bDrawAsOutline(DrawShadowAsOutline());
UINT16 nTransparence = GetShadowTransparence();
if(nTransparence)
{
if(nTransparence != 100)
{
// transparence, draw to metafile and then transparent to
// outdev
UINT8 nScaledTrans((UINT8)((nTransparence * 255)/100));
Color aTransColor(nScaledTrans, nScaledTrans, nScaledTrans);
Gradient aGradient(GRADIENT_LINEAR, aTransColor, aTransColor);
GDIMetaFile aMetaFile;
VirtualDevice aVDev;
MapMode aMap(rXOut.GetOutDev()->GetMapMode());
// StepCount to someting small
aGradient.SetSteps(3);
// create BoundRectangle
Rectangle aBound(rPoly.GetBoundRect());
// prepare VDev and MetaFile
aVDev.EnableOutput(FALSE);
aVDev.SetMapMode(rXOut.GetOutDev()->GetMapMode());
aMetaFile.Record(&aVDev);
if(bDrawAsOutline)
{
aVDev.SetLineColor(aCol);
aVDev.SetFillColor();
}
else
{
aVDev.SetLineColor();
aVDev.SetFillColor(aCol);
}
aVDev.SetFont(rXOut.GetOutDev()->GetFont());
aVDev.SetDrawMode(rXOut.GetOutDev()->GetDrawMode());
aVDev.SetRefPoint(rXOut.GetOutDev()->GetRefPoint());
// create output
for(UINT16 a(0); a < rPoly.Count(); a++)
aMetaFile.AddAction(new MetaPolygonAction(rPoly[a]));
// draw metafile
aMetaFile.Stop();
aMetaFile.WindStart();
aMap.SetOrigin(aBound.TopLeft());
aMetaFile.SetPrefMapMode(aMap);
aMetaFile.SetPrefSize(aBound.GetSize());
rXOut.GetOutDev()->DrawTransparent(aMetaFile, aBound.TopLeft(), aBound.GetSize(), aGradient);
}
}
else
{
// no transparence, draw all single polys directly
if(bDrawAsOutline)
{
pDevice->SetLineColor(aCol);
pDevice->SetFillColor();
}
else
{
pDevice->SetLineColor();
pDevice->SetFillColor(aCol);
}
for(UINT16 a(0); a < rPoly.Count(); a++)
pDevice->DrawPolygon(rPoly[a]);
}
}
/*************************************************************************
|*
|* convert given PolyPolygon3D to screen coor
|*
\************************************************************************/
XPolyPolygon E3dCompoundObject::TransformToScreenCoor(const PolyPolygon3D &rExtrudePoly)
{
XPolyPolygon aNewPolyPolygon;
B3dTransformationSet& rSet = GetScene()->GetCameraSet();
// set ObjectTrans
Matrix4D mTransform = GetFullTransform();
rSet.SetObjectTrans(mTransform);
// transform base polygon to screen coor
for(UINT16 a=0;a<rExtrudePoly.Count();a++)
{
const Polygon3D &rExtPoly = rExtrudePoly[a];
BOOL bClosed = rExtPoly.IsClosed();
XPolygon aNewPoly(rExtPoly.GetPointCount() + (bClosed ? 1 : 0));
UINT16 b;
for(b=0;b<rExtPoly.GetPointCount();b++)
{
Vector3D aPoint = rSet.ObjectToViewCoor(rExtPoly[b]);
aNewPoly[b].X() = (long)(aPoint.X() + 0.5);
aNewPoly[b].Y() = (long)(aPoint.Y() + 0.5);
}
if(bClosed)
aNewPoly[b] = aNewPoly[0];
aNewPolyPolygon.Insert(aNewPoly);
}
return aNewPolyPolygon;
}
/*************************************************************************
|*
|* Attribute setzen
|*
\************************************************************************/
//-/void E3dCompoundObject::Distribute3DAttributes(const SfxItemSet& rAttr)
//-/{
//-/ // call parent
//-/ E3dObject::Distribute3DAttributes(rAttr);
//-/
//-/ // special Attr for E3dCompoundObject
//-/ const SfxPoolItem* pPoolItem = NULL;
//-/ B3dMaterial aNewMat = GetFrontMaterial();
//-/ BOOL bNewMatUsed = FALSE;
//-/
//-/ if( SFX_ITEM_SET == rAttr.GetItemState( SID_ATTR_3D_DOUBLE_SIDED, TRUE, &pPoolItem ) )
//-/ {
//-/ BOOL bNew = ((const SfxBoolItem*)pPoolItem)->GetValue();
//-/ SetDoubleSided(bNew);
//-/ }
//-/ if( SFX_ITEM_SET == rAttr.GetItemState( SID_ATTR_3D_NORMALS_KIND, TRUE, &pPoolItem ) )
//-/ {
//-/ UINT16 nNew = ( ( const SfxUInt16Item* ) pPoolItem )->GetValue();
//-/ if(nNew == 0)
//-/ {
//-/ SetUseStdNormals(FALSE);
//-/ SetUseStdNormalsUseSphere(FALSE);
//-/ }
//-/ else if(nNew == 1)
//-/ {
//-/ SetUseStdNormals(TRUE);
//-/ SetUseStdNormalsUseSphere(FALSE);
//-/ }
//-/ else
//-/ {
//-/ SetUseStdNormals(TRUE);
//-/ SetUseStdNormalsUseSphere(TRUE);
//-/ }
//-/ }
//-/ if( SFX_ITEM_SET == rAttr.GetItemState( SID_ATTR_3D_NORMALS_INVERT, TRUE, &pPoolItem ) )
//-/ {
//-/ BOOL bNew = ( ( const SfxBoolItem* ) pPoolItem )->GetValue();
//-/ SetInvertNormals(bNew);
//-/ }
//-/ if( SFX_ITEM_SET == rAttr.GetItemState( SID_ATTR_3D_TEXTURE_PROJ_X, TRUE, &pPoolItem ) )
//-/ {
//-/ UINT16 nNew = ( ( const SfxUInt16Item* ) pPoolItem )->GetValue();
//-/ if(nNew == 0)
//-/ {
//-/ SetUseStdTextureX(FALSE);
//-/ SetUseStdTextureXUseSphere(FALSE);
//-/ }
//-/ else if(nNew == 1)
//-/ {
//-/ SetUseStdTextureX(TRUE);
//-/ SetUseStdTextureXUseSphere(FALSE);
//-/ }
//-/ else
//-/ {
//-/ SetUseStdTextureX(TRUE);
//-/ SetUseStdTextureXUseSphere(TRUE);
//-/ }
//-/ }
//-/ if( SFX_ITEM_SET == rAttr.GetItemState( SID_ATTR_3D_TEXTURE_PROJ_Y, TRUE, &pPoolItem ) )
//-/ {
//-/ UINT16 nNew = ( ( const SfxUInt16Item* ) pPoolItem )->GetValue();
//-/ if(nNew == 0)
//-/ {
//-/ SetUseStdTextureY(FALSE);
//-/ SetUseStdTextureYUseSphere(FALSE);
//-/ }
//-/ else if(nNew == 1)
//-/ {
//-/ SetUseStdTextureY(TRUE);
//-/ SetUseStdTextureYUseSphere(FALSE);
//-/ }
//-/ else
//-/ {
//-/ SetUseStdTextureY(TRUE);
//-/ SetUseStdTextureYUseSphere(TRUE);
//-/ }
//-/ }
//-/ if( SFX_ITEM_SET == rAttr.GetItemState( SID_ATTR_3D_SHADOW_3D, TRUE, &pPoolItem ) )
//-/ {
//-/ BOOL bNew = ( ( const SfxBoolItem* ) pPoolItem )->GetValue();
//-/ SetDrawShadow3D(bNew);
//-/ }
//-/ if( SFX_ITEM_SET == rAttr.GetItemState( SID_ATTR_3D_MAT_COLOR, TRUE, &pPoolItem ) )
//-/ {
//-/ Color aNew = ( ( const SvxColorItem* ) pPoolItem )->GetValue();
//-/ aNewMat.SetMaterial(aNew, Base3DMaterialDiffuse);
//-/ bNewMatUsed = TRUE;
//-/ }
//-/ if( SFX_ITEM_SET == rAttr.GetItemState( SID_ATTR_3D_MAT_EMISSION, TRUE, &pPoolItem ) )
//-/ {
//-/ Color aNew = ( ( const SvxColorItem* ) pPoolItem )->GetValue();
//-/ aNewMat.SetMaterial(aNew, Base3DMaterialEmission);
//-/ bNewMatUsed = TRUE;
//-/ }
//-/ if( SFX_ITEM_SET == rAttr.GetItemState( SID_ATTR_3D_MAT_SPECULAR, TRUE, &pPoolItem ) )
//-/ {
//-/ Color aNew = ( ( const SvxColorItem* ) pPoolItem )->GetValue();
//-/ aNewMat.SetMaterial(aNew, Base3DMaterialSpecular);
//-/ bNewMatUsed = TRUE;
//-/ }
//-/ if( SFX_ITEM_SET == rAttr.GetItemState( SID_ATTR_3D_MAT_SPECULAR_INTENSITY, TRUE, &pPoolItem ) )
//-/ {
//-/ UINT16 nNew = ( ( const SfxUInt16Item* ) pPoolItem )->GetValue();
//-/ aNewMat.SetShininess(nNew);
//-/ bNewMatUsed = TRUE;
//-/ }
//-/ if(bNewMatUsed)
//-/ SetFrontMaterial(aNewMat);
//-/
//-/ if( SFX_ITEM_SET == rAttr.GetItemState( SID_ATTR_3D_TEXTURE_KIND, TRUE, &pPoolItem ) )
//-/ {
//-/ UINT16 nNew = ( ( const SfxUInt16Item* ) pPoolItem )->GetValue();
//-/ if(nNew == 0)
//-/ {
//-/ SetTextureKind(Base3DTextureLuminance);
//-/ }
//-/ else
//-/ {
//-/ SetTextureKind(Base3DTextureColor);
//-/ }
//-/ }
//-/ if( SFX_ITEM_SET == rAttr.GetItemState( SID_ATTR_3D_TEXTURE_MODE, TRUE, &pPoolItem ) )
//-/ {
//-/ UINT16 nNew = ( ( const SfxUInt16Item* ) pPoolItem )->GetValue();
//-/ if(nNew == 0)
//-/ {
//-/ SetTextureMode(Base3DTextureReplace);
//-/ }
//-/ else if(nNew == 1)
//-/ {
//-/ SetTextureMode(Base3DTextureModulate);
//-/ }
//-/ else
//-/ {
//-/ SetTextureMode(Base3DTextureBlend);
//-/ }
//-/ }
//-/ if( SFX_ITEM_SET == rAttr.GetItemState( SID_ATTR_3D_TEXTURE_FILTER, TRUE, &pPoolItem ) )
//-/ {
//-/ BOOL bNew = ( ( const SfxBoolItem* ) pPoolItem )->GetValue();
//-/ SetFilterTexture(bNew);
//-/ }
//-/}
void E3dCompoundObject::ImpLocalItemValueChange(const SfxPoolItem& rNew)
{
switch(rNew.Which())
{
case SDRATTR_3DOBJ_DOUBLE_SIDED:
{
//-/ BOOL bNew = ((const Svx3DDoubleSidedItem&)rNew).GetValue();
//-/ if(GetDoubleSided() != bNew)
bGeometryValid = FALSE;
break;
}
case SDRATTR_3DOBJ_NORMALS_KIND:
{
//-/ UINT16 nNew = ((const Svx3DNormalsKindItem&)rNew).GetValue();
//-/ if(GetNormalsKind() != nNew)
bGeometryValid = FALSE;
//-/ if(nNew == 0)
//-/ {
//-/ ImpSetUseStdNormals(FALSE);
//-/ ImpSetUseStdNormalsUseSphere(FALSE);
//-/ }
//-/ else if(nNew == 1)
//-/ {
//-/ ImpSetUseStdNormals(TRUE);
//-/ ImpSetUseStdNormalsUseSphere(FALSE);
//-/ }
//-/ else
//-/ {
//-/ ImpSetUseStdNormals(TRUE);
//-/ ImpSetUseStdNormalsUseSphere(TRUE);
//-/ }
break;
}
case SDRATTR_3DOBJ_NORMALS_INVERT:
{
//-/ BOOL bNew = ((const Svx3DNormalsInvertItem&)rNew).GetValue();
//-/ if(GetNormalsInvert() != bNew)
//-/ GetDisplayGeometry().InvertNormals();
bGeometryValid = FALSE;
//-/ ImpSetInvertNormals(bNew);
break;
}
case SDRATTR_3DOBJ_TEXTURE_PROJ_X:
{
//-/ UINT16 nNew = ((const Svx3DTextureProjectionXItem&)rNew).GetValue();
//-/ if(GetTextureProjectionX() != nNew)
bGeometryValid = FALSE;
//-/ if(nNew == 0)
//-/ {
//-/ ImpSetUseStdTextureX(FALSE);
//-/ ImpSetUseStdTextureXUseSphere(FALSE);
//-/ }
//-/ else if(nNew == 1)
//-/ {
//-/ ImpSetUseStdTextureX(TRUE);
//-/ ImpSetUseStdTextureXUseSphere(FALSE);
//-/ }
//-/ else
//-/ {
//-/ ImpSetUseStdTextureX(TRUE);
//-/ ImpSetUseStdTextureXUseSphere(TRUE);
//-/ }
break;
}
case SDRATTR_3DOBJ_TEXTURE_PROJ_Y:
{
//-/ UINT16 nNew = ((const Svx3DTextureProjectionYItem&)rNew).GetValue();
//-/ if(GetTextureProjectionY() != nNew)
bGeometryValid = FALSE;
//-/ if(nNew == 0)
//-/ {
//-/ ImpSetUseStdTextureY(FALSE);
//-/ ImpSetUseStdTextureYUseSphere(FALSE);
//-/ }
//-/ else if(nNew == 1)
//-/ {
//-/ ImpSetUseStdTextureY(TRUE);
//-/ ImpSetUseStdTextureYUseSphere(FALSE);
//-/ }
//-/ else
//-/ {
//-/ ImpSetUseStdTextureY(TRUE);
//-/ ImpSetUseStdTextureYUseSphere(TRUE);
//-/ }
break;
}
//-/ case SDRATTR_3DOBJ_SHADOW_3D:
//-/ {
//-/ BOOL bNew = ((const Svx3DShadow3DItem&)rNew).GetValue();
//-/ if(GetShadow3D() != bNew)
//-/ ;
//-///-/ ImpSetDrawShadow3D(bNew);
//-/ break;
//-/ }
//-/ case SDRATTR_3DOBJ_MAT_COLOR:
//-/ {
//-/ // set 3d object color as fill color
//-/ Color aNew = ((const Svx3DMaterialColorItem&)rNew).GetValue();
//-/ ImpForceItemSet();
//-/ mpObjectItemSet->Put(XFillColorItem(String(), aNew));
//-///-/ if(GetMaterialColor() != aNew)
//-///-/ {
//-///-/ B3dMaterial aNewMat = GetFrontMaterial();
//-///-/ aNewMat.SetMaterial(aNew, Base3DMaterialDiffuse);
//-///-/ SetFrontMaterial(aNewMat);
//-///-/ }
//-/ break;
//-/ }
//-/ case SDRATTR_3DOBJ_MAT_EMISSION:
//-/ {
//-/ Color aNew = ((const Svx3DMaterialEmissionItem&)rNew).GetValue();
//-/ if(GetMaterialEmission() != aNew)
//-/ {
//-/ B3dMaterial aNewMat = GetFrontMaterial();
//-/ aNewMat.SetMaterial(aNew, Base3DMaterialEmission);
//-/ SetFrontMaterial(aNewMat);
//-/ }
//-/ break;
//-/ }
//-/ case SDRATTR_3DOBJ_MAT_SPECULAR:
//-/ {
//-/ Color aNew = ((const Svx3DMaterialSpecularItem&)rNew).GetValue();
//-/ if(GetMaterialSpecular() != aNew)
//-/ {
//-/ B3dMaterial aNewMat = GetFrontMaterial();
//-/ aNewMat.SetMaterial(aNew, Base3DMaterialSpecular);
//-/ SetFrontMaterial(aNewMat);
//-/ }
//-/ break;
//-/ }
//-/ case SDRATTR_3DOBJ_MAT_SPECULAR_INTENSITY:
//-/ {
//-/ UINT16 nNew = ((const Svx3DMaterialSpecularIntensityItem&)rNew).GetValue();
//-/ if(GetMaterialSpecularIntensity() != nNew)
//-/ {
//-/ B3dMaterial aNewMat = GetFrontMaterial();
//-/ aNewMat.SetShininess(nNew);
//-/ SetFrontMaterial(aNewMat);
//-/ }
//-/ break;
//-/ }
//-/ case SDRATTR_3DOBJ_TEXTURE_KIND:
//-/ {
//-/ Base3DTextureKind eNew = ((const Svx3DTextureKindItem&)rNew).GetValue();
//-/ if(GetTextureKind() != eNew)
//-/ ;
//-/ if(nNew == 0)
//-/ {
//-/ ImpSetTextureKind(Base3DTextureLuminance);
//-/ }
//-/ else
//-/ {
//-/ ImpSetTextureKind(Base3DTextureColor);
//-/ }
//-/ break;
//-/ }
//-/ case SDRATTR_3DOBJ_TEXTURE_MODE:
//-/ {
//-/ Base3DTextureMode eNew = ((const Svx3DTextureModeItem&)rNew).GetValue();
//-/ if(GetTextureMode() != eNew)
//-/ ;
//-/ if(nNew == 0)
//-/ {
//-/ ImpSetTextureMode(Base3DTextureReplace);
//-/ }
//-/ else if(nNew == 1)
//-/ {
//-/ ImpSetTextureMode(Base3DTextureModulate);
//-/ }
//-/ else
//-/ {
//-/ ImpSetTextureMode(Base3DTextureBlend);
//-/ }
//-/ break;
//-/ }
//-/ case SDRATTR_3DOBJ_TEXTURE_FILTER:
//-/ {
//-/ BOOL bNew = ((const Svx3DTextureFilterItem&)rNew).GetValue();
//-/ if(GetTextureFilter() != bNew)
//-/ ;
//-/ ImpSetFilterTexture(bNew);
//-/ break;
//-/ }
}
}
void E3dCompoundObject::SetItem( const SfxPoolItem& rItem )
{
// set item
E3dObject::SetItem(rItem);
// handle value change
if(rItem.Which() >= SDRATTR_3DOBJ_FIRST && rItem.Which() <= SDRATTR_3DOBJ_LAST)
ImpLocalItemValueChange(rItem);
//-/ // set fill color as 3d object color
//-/ if(rItem.Which() == XATTR_FILLCOLOR)
//-/ {
//-/ Color aNew = ((const XFillColorItem&)rItem).GetValue();
//-/ mpObjectItemSet->Put(Svx3DMaterialColorItem(aNew));
//-/ }
}
void E3dCompoundObject::ClearItem( USHORT nWhich )
{
if(mpObjectItemSet)
{
// clear base items at SdrAttrObj, NOT at E3dObject(!)
E3dObject::ClearItem(nWhich);
// handle value change
if(nWhich >= SDRATTR_3DOBJ_FIRST && nWhich <= SDRATTR_3DOBJ_LAST)
ImpLocalItemValueChange(mpObjectItemSet->Get(nWhich));
//-/ // clear fill color when 3d object color is cleared
//-/ if(nWhich == XATTR_FILLCOLOR)
//-/ mpObjectItemSet->ClearItem(SDRATTR_3DOBJ_MAT_COLOR);
}
}
void E3dCompoundObject::SetItemSet( const SfxItemSet& rSet )
{
// set base items at SdrAttrObj, NOT at E3dObject(!)
E3dObject::SetItemSet(rSet);
// handle value change
for(sal_uInt16 nWhich(SDRATTR_3DOBJ_FIRST); nWhich <= SDRATTR_3DOBJ_TEXTURE_FILTER; nWhich++)
if(SFX_ITEM_SET == rSet.GetItemState(nWhich, FALSE))
ImpLocalItemValueChange(rSet.Get(nWhich));
//-/ // set fill color as 3d object color
//-/ if(SFX_ITEM_SET == rSet.GetItemState(XATTR_FILLCOLOR, FALSE))
//-/ {
//-/ Color aNew = ((const XFillColorItem&)rSet.Get(XATTR_FILLCOLOR)).GetValue();
//-/ mpObjectItemSet->Put(Svx3DMaterialColorItem(aNew));
//-/ }
}
//-/void E3dCompoundObject::NbcSetAttributes(const SfxItemSet& rAttr, FASTBOOL bReplaceAll)
//-/{
//-/ // call parent
//-/ E3dObject::NbcSetAttributes(rAttr, bReplaceAll);
//-/
//-/ // special Attr for E3dCompoundObject
//-/ const SfxPoolItem* pPoolItem = NULL;
//-/ B3dMaterial aNewMat = GetFrontMaterial();
//-/ BOOL bNewMatUsed = FALSE;
//-/
//-/ if( SFX_ITEM_SET == rAttr.GetItemState( SID_ATTR_3D_DOUBLE_SIDED, TRUE, &pPoolItem ) )
//-/ {
//-/ BOOL bNew = ((const SfxBoolItem*)pPoolItem)->GetValue();
//-/ SetDoubleSided(bNew);
//-/ }
//-/ if( SFX_ITEM_SET == rAttr.GetItemState( SID_ATTR_3D_NORMALS_KIND, TRUE, &pPoolItem ) )
//-/ {
//-/ UINT16 nNew = ( ( const SfxUInt16Item* ) pPoolItem )->GetValue();
//-/ if(nNew == 0)
//-/ {
//-/ SetUseStdNormals(FALSE);
//-/ SetUseStdNormalsUseSphere(FALSE);
//-/ }
//-/ else if(nNew == 1)
//-/ {
//-/ SetUseStdNormals(TRUE);
//-/ SetUseStdNormalsUseSphere(FALSE);
//-/ }
//-/ else
//-/ {
//-/ SetUseStdNormals(TRUE);
//-/ SetUseStdNormalsUseSphere(TRUE);
//-/ }
//-/ }
//-/ if( SFX_ITEM_SET == rAttr.GetItemState( SID_ATTR_3D_NORMALS_INVERT, TRUE, &pPoolItem ) )
//-/ {
//-/ BOOL bNew = ( ( const SfxBoolItem* ) pPoolItem )->GetValue();
//-/ SetInvertNormals(bNew);
//-/ }
//-/ if( SFX_ITEM_SET == rAttr.GetItemState( SID_ATTR_3D_TEXTURE_PROJ_X, TRUE, &pPoolItem ) )
//-/ {
//-/ UINT16 nNew = ( ( const SfxUInt16Item* ) pPoolItem )->GetValue();
//-/ if(nNew == 0)
//-/ {
//-/ SetUseStdTextureX(FALSE);
//-/ SetUseStdTextureXUseSphere(FALSE);
//-/ }
//-/ else if(nNew == 1)
//-/ {
//-/ SetUseStdTextureX(TRUE);
//-/ SetUseStdTextureXUseSphere(FALSE);
//-/ }
//-/ else
//-/ {
//-/ SetUseStdTextureX(TRUE);
//-/ SetUseStdTextureXUseSphere(TRUE);
//-/ }
//-/ }
//-/ if( SFX_ITEM_SET == rAttr.GetItemState( SID_ATTR_3D_TEXTURE_PROJ_Y, TRUE, &pPoolItem ) )
//-/ {
//-/ UINT16 nNew = ( ( const SfxUInt16Item* ) pPoolItem )->GetValue();
//-/ if(nNew == 0)
//-/ {
//-/ SetUseStdTextureY(FALSE);
//-/ SetUseStdTextureYUseSphere(FALSE);
//-/ }
//-/ else if(nNew == 1)
//-/ {
//-/ SetUseStdTextureY(TRUE);
//-/ SetUseStdTextureYUseSphere(FALSE);
//-/ }
//-/ else
//-/ {
//-/ SetUseStdTextureY(TRUE);
//-/ SetUseStdTextureYUseSphere(TRUE);
//-/ }
//-/ }
//-/ if( SFX_ITEM_SET == rAttr.GetItemState( SID_ATTR_3D_SHADOW_3D, TRUE, &pPoolItem ) )
//-/ {
//-/ BOOL bNew = ( ( const SfxBoolItem* ) pPoolItem )->GetValue();
//-/ SetDrawShadow3D(bNew);
//-/ }
//-/ if( SFX_ITEM_SET == rAttr.GetItemState( SID_ATTR_3D_MAT_COLOR, TRUE, &pPoolItem ) )
//-/ {
//-/ Color aNew = ( ( const SvxColorItem* ) pPoolItem )->GetValue();
//-/
//-/ // Im Objekt setzen
//-/ SfxItemSet aNewSet(GetModel()->GetItemPool());
//-/ aNewSet.Put(XFillColorItem(String(), aNew));
//-/ SdrAttrObj::NbcSetAttributes(aNewSet, FALSE);
//-/
//-/ // ...und im Material setzen
//-/ aNewMat.SetMaterial(aNew, Base3DMaterialDiffuse);
//-/ bNewMatUsed = TRUE;
//-/ }
//-/ if( SFX_ITEM_SET == rAttr.GetItemState( SID_ATTR_3D_MAT_EMISSION, TRUE, &pPoolItem ) )
//-/ {
//-/ Color aNew = ( ( const SvxColorItem* ) pPoolItem )->GetValue();
//-/ aNewMat.SetMaterial(aNew, Base3DMaterialEmission);
//-/ bNewMatUsed = TRUE;
//-/ }
//-/ if( SFX_ITEM_SET == rAttr.GetItemState( SID_ATTR_3D_MAT_SPECULAR, TRUE, &pPoolItem ) )
//-/ {
//-/ Color aNew = ( ( const SvxColorItem* ) pPoolItem )->GetValue();
//-/ aNewMat.SetMaterial(aNew, Base3DMaterialSpecular);
//-/ bNewMatUsed = TRUE;
//-/ }
//-/ if( SFX_ITEM_SET == rAttr.GetItemState( SID_ATTR_3D_MAT_SPECULAR_INTENSITY, TRUE, &pPoolItem ) )
//-/ {
//-/ UINT16 nNew = ( ( const SfxUInt16Item* ) pPoolItem )->GetValue();
//-/ aNewMat.SetShininess(nNew);
//-/ bNewMatUsed = TRUE;
//-/ }
//-/ if(bNewMatUsed)
//-/ SetFrontMaterial(aNewMat);
//-/
//-/ if( SFX_ITEM_SET == rAttr.GetItemState( SID_ATTR_3D_TEXTURE_KIND, TRUE, &pPoolItem ) )
//-/ {
//-/ UINT16 nNew = ( ( const SfxUInt16Item* ) pPoolItem )->GetValue();
//-/ if(nNew == 0)
//-/ {
//-/ SetTextureKind(Base3DTextureLuminance);
//-/ }
//-/ else
//-/ {
//-/ SetTextureKind(Base3DTextureColor);
//-/ }
//-/ }
//-/ if( SFX_ITEM_SET == rAttr.GetItemState( SID_ATTR_3D_TEXTURE_MODE, TRUE, &pPoolItem ) )
//-/ {
//-/ UINT16 nNew = ( ( const SfxUInt16Item* ) pPoolItem )->GetValue();
//-/ if(nNew == 0)
//-/ {
//-/ SetTextureMode(Base3DTextureReplace);
//-/ }
//-/ else if(nNew == 1)
//-/ {
//-/ SetTextureMode(Base3DTextureModulate);
//-/ }
//-/ else
//-/ {
//-/ SetTextureMode(Base3DTextureBlend);
//-/ }
//-/ }
//-/ if( SFX_ITEM_SET == rAttr.GetItemState( SID_ATTR_3D_TEXTURE_FILTER, TRUE, &pPoolItem ) )
//-/ {
//-/ BOOL bNew = ( ( const SfxBoolItem* ) pPoolItem )->GetValue();
//-/ SetFilterTexture(bNew);
//-/ }
//-/}
/*************************************************************************
|*
|* Attribute lesen
|*
\************************************************************************/
//-/void E3dCompoundObject::Collect3DAttributes(SfxItemSet& rAttr) const
//-/{
//-/ // call parent
//-/ E3dObject::Collect3DAttributes(rAttr);
//-/
//-/ // special Attr for E3dCompoundObject
//-/ BOOL bObjDoubleSided = bDoubleSided;
//-/ UINT16 nObjNormalsKind;
//-/ if(!bUseStdNormals)
//-/ {
//-/ nObjNormalsKind = 0;
//-/ }
//-/ else
//-/ {
//-/ if(bUseStdNormalsUseSphere)
//-/ {
//-/ nObjNormalsKind = 2;
//-/ }
//-/ else
//-/ {
//-/ nObjNormalsKind = 1;
//-/ }
//-/ }
//-/ BOOL bObjNormalsInvert = bInvertNormals;
//-/ UINT16 nObjTextureProjX;
//-/ if(!bUseStdTextureX)
//-/ {
//-/ nObjTextureProjX = 0;
//-/ }
//-/ else
//-/ {
//-/ if(bUseStdTextureXUseSphere)
//-/ {
//-/ nObjTextureProjX = 2;
//-/ }
//-/ else
//-/ {
//-/ nObjTextureProjX = 1;
//-/ }
//-/ }
//-/ UINT16 nObjTextureProjY;
//-/ if(!bUseStdTextureY)
//-/ {
//-/ nObjTextureProjY = 0;
//-/ }
//-/ else
//-/ {
//-/ if(bUseStdTextureYUseSphere)
//-/ {
//-/ nObjTextureProjY = 2;
//-/ }
//-/ else
//-/ {
//-/ nObjTextureProjY = 1;
//-/ }
//-/ }
//-/ BOOL bObjShadow3D = bShadow3D;
//-/ const B3dMaterial& rMat = GetFrontMaterial();
//-/ Color aObjMaterialColor = ((const XFillColorItem&)(GetItem(XATTR_FILLCOLOR))).GetValue();
//-/ Color aObjMaterialEmission = rMat.GetMaterial(Base3DMaterialEmission);
//-/ Color aObjMaterialSpecular = rMat.GetMaterial(Base3DMaterialSpecular);
//-/ UINT16 nObjMaterialIntensity = rMat.GetShininess();
//-/ UINT16 nObjTextureKind;
//-/ if(eTextureKind == Base3DTextureColor)
//-/ {
//-/ nObjTextureKind = 1;
//-/ }
//-/ else
//-/ {
//-/ nObjTextureKind = 0;
//-/ }
//-/ UINT16 nObjTextureMode;
//-/ if(eTextureMode == Base3DTextureReplace)
//-/ {
//-/ nObjTextureMode = 0;
//-/ }
//-/ else if(eTextureMode == Base3DTextureModulate)
//-/ {
//-/ nObjTextureMode = 1;
//-/ }
//-/ else
//-/ {
//-/ nObjTextureMode = 2;
//-/ }
//-/ BOOL bObjTextureFilter = bFilterTexture;
//-/
//-/ // DoubleSided
//-/ rAttr.Put(SfxBoolItem(SDRATTR_3DOBJ_DOUBLE_SIDED, bObjDoubleSided));
//-/
//-/ // NormalsKind
//-/ rAttr.Put(SfxUInt16Item(SDRATTR_3DOBJ_NORMALS_KIND, nObjNormalsKind));
//-/
//-/ // NormalsInvert
//-/ rAttr.Put(SfxBoolItem(SDRATTR_3DOBJ_NORMALS_INVERT, bObjNormalsInvert));
//-/
//-/ // TextureProjectionX
//-/ rAttr.Put(SfxUInt16Item(SDRATTR_3DOBJ_TEXTURE_PROJ_X, nObjTextureProjX));
//-/
//-/ // TextureProjectionY
//-/ rAttr.Put(SfxUInt16Item(SDRATTR_3DOBJ_TEXTURE_PROJ_Y, nObjTextureProjY));
//-/
//-/ // Shadow3D
//-/ rAttr.Put(SfxBoolItem(SDRATTR_3DOBJ_SHADOW_3D, bObjShadow3D));
//-/
//-/ // Material
//-/ rAttr.Put(SvxColorItem(aObjMaterialColor, SDRATTR_3DOBJ_MAT_COLOR));
//-/ rAttr.Put(SvxColorItem(aObjMaterialEmission, SDRATTR_3DOBJ_MAT_EMISSION));
//-/ rAttr.Put(SvxColorItem(aObjMaterialSpecular, SDRATTR_3DOBJ_MAT_SPECULAR));
//-/ rAttr.Put(SfxUInt16Item(SDRATTR_3DOBJ_MAT_SPECULAR_INTENSITY, nObjMaterialIntensity));
//-/
//-/ // TextureKind
//-/ rAttr.Put(SfxUInt16Item(SDRATTR_3DOBJ_TEXTURE_KIND, nObjTextureKind));
//-/
//-/ // TextureMode
//-/ rAttr.Put(SfxUInt16Item(SDRATTR_3DOBJ_TEXTURE_MODE, nObjTextureMode));
//-/
//-/ // TextureFilter
//-/ rAttr.Put(SfxBoolItem(SDRATTR_3DOBJ_TEXTURE_FILTER, bObjTextureFilter));
//-/}
//-/void E3dCompoundObject::TakeAttributes(SfxItemSet& rAttr, FASTBOOL bMerge, FASTBOOL bOnlyHardAttr) const
//-/{
//-/ // call parent
//-/ E3dObject::TakeAttributes(rAttr, bMerge, bOnlyHardAttr);
//-/
//-/ // special Attr for E3dCompoundObject
//-/ const SfxPoolItem* pPoolItem = NULL;
//-/ SfxItemState eState;
//-/
//-/ BOOL bObjDoubleSided = GetDoubleSided();
//-/ UINT16 nObjNormalsKind;
//-/ if(!GetUseStdNormals())
//-/ {
//-/ nObjNormalsKind = 0;
//-/ }
//-/ else
//-/ {
//-/ if(GetUseStdNormalsUseSphere())
//-/ {
//-/ nObjNormalsKind = 2;
//-/ }
//-/ else
//-/ {
//-/ nObjNormalsKind = 1;
//-/ }
//-/ }
//-/ BOOL bObjNormalsInvert = GetInvertNormals();
//-/ UINT16 nObjTextureProjX;
//-/ if(!GetUseStdTextureX())
//-/ {
//-/ nObjTextureProjX = 0;
//-/ }
//-/ else
//-/ {
//-/ if(GetUseStdTextureXUseSphere())
//-/ {
//-/ nObjTextureProjX = 2;
//-/ }
//-/ else
//-/ {
//-/ nObjTextureProjX = 1;
//-/ }
//-/ }
//-/ UINT16 nObjTextureProjY;
//-/ if(!GetUseStdTextureY())
//-/ {
//-/ nObjTextureProjY = 0;
//-/ }
//-/ else
//-/ {
//-/ if(GetUseStdTextureYUseSphere())
//-/ {
//-/ nObjTextureProjY = 2;
//-/ }
//-/ else
//-/ {
//-/ nObjTextureProjY = 1;
//-/ }
//-/ }
//-/ BOOL bObjShadow3D = GetDrawShadow3D();
//-///-/ const XFillAttrSetItem* pFillAttr = GetFillAttr();
//-/ const B3dMaterial& rMat = GetFrontMaterial();
//-///-/ Color aObjMaterialColor;
//-///-/ if(pFillAttr)
//-///-/ {
//-///-/ const SfxItemSet& rSet = pFillAttr->GetItemSet();
//-/ Color aObjMaterialColor = ((const XFillColorItem&) (GetItemSet().Get(XATTR_FILLCOLOR))).GetValue();
//-///-/ }
//-///-/ else
//-///-/ {
//-///-/ aObjMaterialColor = rMat.GetMaterial(Base3DMaterialDiffuse);
//-///-/ }
//-/ Color aObjMaterialEmission = rMat.GetMaterial(Base3DMaterialEmission);
//-/ Color aObjMaterialSpecular = rMat.GetMaterial(Base3DMaterialSpecular);
//-/ UINT16 nObjMaterialIntensity = rMat.GetShininess();
//-/ UINT16 nObjTextureKind;
//-/ if(GetTextureKind() == Base3DTextureColor)
//-/ {
//-/ nObjTextureKind = 1;
//-/ }
//-/ else
//-/ {
//-/ nObjTextureKind = 0;
//-/ }
//-/ UINT16 nObjTextureMode;
//-/ if(GetTextureMode() == Base3DTextureReplace)
//-/ {
//-/ nObjTextureMode = 0;
//-/ }
//-/ else if(GetTextureMode() == Base3DTextureModulate)
//-/ {
//-/ nObjTextureMode = 1;
//-/ }
//-/ else
//-/ {
//-/ nObjTextureMode = 2;
//-/ }
//-/ BOOL bObjTextureFilter = GetFilterTexture();
//-/
//-/ // DoubleSided
//-/ eState = rAttr.GetItemState(SID_ATTR_3D_DOUBLE_SIDED, FALSE, &pPoolItem);
//-/ if(eState == SFX_ITEM_SET)
//-/ {
//-/ // Ist gesetzt
//-/ if(bObjDoubleSided != ((const SfxBoolItem*)pPoolItem)->GetValue())
//-/ {
//-/ // SfxPoolItem muss invalidiert werden
//-/ rAttr.InvalidateItem(SID_ATTR_3D_DOUBLE_SIDED);
//-/ }
//-/ }
//-/ else
//-/ {
//-/ if(!(eState == SFX_ITEM_DONTCARE))
//-/ {
//-/ // Item gab es noch nicht, setze es
//-/ rAttr.Put(SfxBoolItem(SID_ATTR_3D_DOUBLE_SIDED, bObjDoubleSided));
//-/ }
//-/ }
//-/
//-/ // NormalsKind
//-/ eState = rAttr.GetItemState(SID_ATTR_3D_NORMALS_KIND, FALSE, &pPoolItem);
//-/ if(eState == SFX_ITEM_SET)
//-/ {
//-/ // Ist gesetzt
//-/ if(nObjNormalsKind != ((const SfxUInt16Item*)pPoolItem)->GetValue())
//-/ {
//-/ // SfxPoolItem muss invalidiert werden
//-/ rAttr.InvalidateItem(SID_ATTR_3D_NORMALS_KIND);
//-/ }
//-/ }
//-/ else
//-/ {
//-/ if(!(eState == SFX_ITEM_DONTCARE))
//-/ {
//-/ // Item gab es noch nicht, setze es
//-/ rAttr.Put(SfxUInt16Item(SID_ATTR_3D_NORMALS_KIND, nObjNormalsKind));
//-/ }
//-/ }
//-/
//-/ // NormalsInvert
//-/ eState = rAttr.GetItemState(SID_ATTR_3D_NORMALS_INVERT, FALSE, &pPoolItem);
//-/ if(eState == SFX_ITEM_SET)
//-/ {
//-/ // Ist gesetzt
//-/ if(bObjNormalsInvert != ((const SfxBoolItem*)pPoolItem)->GetValue())
//-/ {
//-/ // SfxPoolItem muss invalidiert werden
//-/ rAttr.InvalidateItem(SID_ATTR_3D_NORMALS_INVERT);
//-/ }
//-/ }
//-/ else
//-/ {
//-/ if(!(eState == SFX_ITEM_DONTCARE))
//-/ {
//-/ // Item gab es noch nicht, setze es
//-/ rAttr.Put(SfxBoolItem(SID_ATTR_3D_NORMALS_INVERT, bObjNormalsInvert));
//-/ }
//-/ }
//-/
//-/ // TextureProjectionX
//-/ eState = rAttr.GetItemState(SID_ATTR_3D_TEXTURE_PROJ_X, FALSE, &pPoolItem);
//-/ if(eState == SFX_ITEM_SET)
//-/ {
//-/ // Ist gesetzt
//-/ if(nObjTextureProjX != ((const SfxUInt16Item*)pPoolItem)->GetValue())
//-/ {
//-/ // SfxPoolItem muss invalidiert werden
//-/ rAttr.InvalidateItem(SID_ATTR_3D_TEXTURE_PROJ_X);
//-/ }
//-/ }
//-/ else
//-/ {
//-/ if(!(eState == SFX_ITEM_DONTCARE))
//-/ {
//-/ // Item gab es noch nicht, setze es
//-/ rAttr.Put(SfxUInt16Item(SID_ATTR_3D_TEXTURE_PROJ_X, nObjTextureProjX));
//-/ }
//-/ }
//-/
//-/ // TextureProjectionY
//-/ eState = rAttr.GetItemState(SID_ATTR_3D_TEXTURE_PROJ_Y, FALSE, &pPoolItem);
//-/ if(eState == SFX_ITEM_SET)
//-/ {
//-/ // Ist gesetzt
//-/ if(nObjTextureProjY != ((const SfxUInt16Item*)pPoolItem)->GetValue())
//-/ {
//-/ // SfxPoolItem muss invalidiert werden
//-/ rAttr.InvalidateItem(SID_ATTR_3D_TEXTURE_PROJ_Y);
//-/ }
//-/ }
//-/ else
//-/ {
//-/ if(!(eState == SFX_ITEM_DONTCARE))
//-/ {
//-/ // Item gab es noch nicht, setze es
//-/ rAttr.Put(SfxUInt16Item(SID_ATTR_3D_TEXTURE_PROJ_Y, nObjTextureProjY));
//-/ }
//-/ }
//-/
//-/ // Shadow3D
//-/ eState = rAttr.GetItemState(SID_ATTR_3D_SHADOW_3D, FALSE, &pPoolItem);
//-/ if(eState == SFX_ITEM_SET)
//-/ {
//-/ // Ist gesetzt
//-/ if(bObjShadow3D != ((const SfxBoolItem*)pPoolItem)->GetValue())
//-/ {
//-/ // SfxPoolItem muss invalidiert werden
//-/ rAttr.InvalidateItem(SID_ATTR_3D_SHADOW_3D);
//-/ }
//-/ }
//-/ else
//-/ {
//-/ if(!(eState == SFX_ITEM_DONTCARE))
//-/ {
//-/ // Item gab es noch nicht, setze es
//-/ rAttr.Put(SfxBoolItem(SID_ATTR_3D_SHADOW_3D, bObjShadow3D));
//-/ }
//-/ }
//-/
//-/ // Material
//-/ eState = rAttr.GetItemState(SID_ATTR_3D_MAT_COLOR, FALSE, &pPoolItem);
//-/ if(eState == SFX_ITEM_SET)
//-/ {
//-/ // Ist gesetzt
//-/ if(aObjMaterialColor != ((const SvxColorItem*)pPoolItem)->GetValue())
//-/ {
//-/ // SfxPoolItem muss invalidiert werden
//-/ rAttr.InvalidateItem(SID_ATTR_3D_MAT_COLOR);
//-/ rAttr.InvalidateItem(XATTR_FILLCOLOR);
//-/ }
//-/ }
//-/ else
//-/ {
//-/ if(!(eState == SFX_ITEM_DONTCARE))
//-/ {
//-/ // Item gab es noch nicht, setze es
//-/ rAttr.Put(SvxColorItem(aObjMaterialColor, SID_ATTR_3D_MAT_COLOR));
//-/ }
//-/ else
//-/ {
//-/ // kann nur invalidate sein, setze auch die farbe wieder so
//-/ rAttr.InvalidateItem(XATTR_FILLCOLOR);
//-/ }
//-/ }
//-/
//-/ eState = rAttr.GetItemState(SID_ATTR_3D_MAT_EMISSION, FALSE, &pPoolItem);
//-/ if(eState == SFX_ITEM_SET)
//-/ {
//-/ // Ist gesetzt
//-/ if(aObjMaterialEmission != ((const SvxColorItem*)pPoolItem)->GetValue())
//-/ {
//-/ // SfxPoolItem muss invalidiert werden
//-/ rAttr.InvalidateItem(SID_ATTR_3D_MAT_EMISSION);
//-/ }
//-/ }
//-/ else
//-/ {
//-/ if(!(eState == SFX_ITEM_DONTCARE))
//-/ {
//-/ // Item gab es noch nicht, setze es
//-/ rAttr.Put(SvxColorItem(aObjMaterialEmission, SID_ATTR_3D_MAT_EMISSION));
//-/ }
//-/ }
//-/
//-/ eState = rAttr.GetItemState(SID_ATTR_3D_MAT_SPECULAR, FALSE, &pPoolItem);
//-/ if(eState == SFX_ITEM_SET)
//-/ {
//-/ // Ist gesetzt
//-/ if(aObjMaterialSpecular != ((const SvxColorItem*)pPoolItem)->GetValue())
//-/ {
//-/ // SfxPoolItem muss invalidiert werden
//-/ rAttr.InvalidateItem(SID_ATTR_3D_MAT_SPECULAR);
//-/ }
//-/ }
//-/ else
//-/ {
//-/ if(!(eState == SFX_ITEM_DONTCARE))
//-/ {
//-/ // Item gab es noch nicht, setze es
//-/ rAttr.Put(SvxColorItem(aObjMaterialSpecular, SID_ATTR_3D_MAT_SPECULAR));
//-/ }
//-/ }
//-/
//-/ eState = rAttr.GetItemState(SID_ATTR_3D_MAT_SPECULAR_INTENSITY, FALSE, &pPoolItem);
//-/ if(eState == SFX_ITEM_SET)
//-/ {
//-/ // Ist gesetzt
//-/ if(nObjMaterialIntensity != ((const SfxUInt16Item*)pPoolItem)->GetValue())
//-/ {
//-/ // SfxPoolItem muss invalidiert werden
//-/ rAttr.InvalidateItem(SID_ATTR_3D_MAT_SPECULAR_INTENSITY);
//-/ }
//-/ }
//-/ else
//-/ {
//-/ if(!(eState == SFX_ITEM_DONTCARE))
//-/ {
//-/ // Item gab es noch nicht, setze es
//-/ rAttr.Put(SfxUInt16Item(SID_ATTR_3D_MAT_SPECULAR_INTENSITY, nObjMaterialIntensity));
//-/ }
//-/ }
//-/
//-/ // TextureKind
//-/ eState = rAttr.GetItemState(SID_ATTR_3D_TEXTURE_KIND, FALSE, &pPoolItem);
//-/ if(eState == SFX_ITEM_SET)
//-/ {
//-/ // Ist gesetzt
//-/ if(nObjTextureKind != ((const SfxUInt16Item*)pPoolItem)->GetValue())
//-/ {
//-/ // SfxPoolItem muss invalidiert werden
//-/ rAttr.InvalidateItem(SID_ATTR_3D_TEXTURE_KIND);
//-/ }
//-/ }
//-/ else
//-/ {
//-/ if(!(eState == SFX_ITEM_DONTCARE))
//-/ {
//-/ // Item gab es noch nicht, setze es
//-/ rAttr.Put(SfxUInt16Item(SID_ATTR_3D_TEXTURE_KIND, nObjTextureKind));
//-/ }
//-/ }
//-/
//-/ // TextureMode
//-/ eState = rAttr.GetItemState(SID_ATTR_3D_TEXTURE_MODE, FALSE, &pPoolItem);
//-/ if(eState == SFX_ITEM_SET)
//-/ {
//-/ // Ist gesetzt
//-/ if(nObjTextureMode != ((const SfxUInt16Item*)pPoolItem)->GetValue())
//-/ {
//-/ // SfxPoolItem muss invalidiert werden
//-/ rAttr.InvalidateItem(SID_ATTR_3D_TEXTURE_MODE);
//-/ }
//-/ }
//-/ else
//-/ {
//-/ if(!(eState == SFX_ITEM_DONTCARE))
//-/ {
//-/ // Item gab es noch nicht, setze es
//-/ rAttr.Put(SfxUInt16Item(SID_ATTR_3D_TEXTURE_MODE, nObjTextureMode));
//-/ }
//-/ }
//-/
//-/ // TextureFilter
//-/ eState = rAttr.GetItemState(SID_ATTR_3D_TEXTURE_FILTER, FALSE, &pPoolItem);
//-/ if(eState == SFX_ITEM_SET)
//-/ {
//-/ // Ist gesetzt
//-/ if(bObjTextureFilter != ((const SfxBoolItem*)pPoolItem)->GetValue())
//-/ {
//-/ // SfxPoolItem muss invalidiert werden
//-/ rAttr.InvalidateItem(SID_ATTR_3D_TEXTURE_FILTER);
//-/ }
//-/ }
//-/ else
//-/ {
//-/ if(!(eState == SFX_ITEM_DONTCARE))
//-/ {
//-/ // Item gab es noch nicht, setze es
//-/ rAttr.Put(SfxBoolItem(SID_ATTR_3D_TEXTURE_FILTER, bObjTextureFilter));
//-/ }
//-/ }
//-/}
//-/void E3dCompoundObject::ImpSetDoubleSided(BOOL bNew)
//-/{
//-/ if(bDoubleSided != bNew)
//-/ {
//-/ bDoubleSided = bNew;
//-/ bGeometryValid = FALSE;
//-/ }
//-/}
//-/void E3dCompoundObject::ImpSetUseStdNormals(BOOL bNew)
//-/{
//-/ if(bUseStdNormals != bNew)
//-/ {
//-/ bUseStdNormals = bNew;
//-/ bGeometryValid = FALSE;
//-/ }
//-/}
//-/void E3dCompoundObject::ImpSetUseStdNormalsUseSphere(BOOL bNew)
//-/{
//-/ if(bUseStdNormalsUseSphere != bNew)
//-/ {
//-/ bUseStdNormalsUseSphere = bNew;
//-/ bGeometryValid = FALSE;
//-/ }
//-/}
//-/void E3dCompoundObject::ImpSetInvertNormals(BOOL bNew)
//-/{
//-/ if(bInvertNormals != bNew)
//-/ {
//-/ bInvertNormals = bNew;
//-/ GetDisplayGeometry().InvertNormals();
//-/ }
//-/}
//-/void E3dCompoundObject::ImpSetUseStdTextureX(BOOL bNew)
//-/{
//-/ if(bUseStdTextureX != bNew)
//-/ {
//-/ bUseStdTextureX = bNew;
//-/ bGeometryValid = FALSE;
//-/ }
//-/}
//-/void E3dCompoundObject::ImpSetUseStdTextureXUseSphere(BOOL bNew)
//-/{
//-/ if(bUseStdTextureXUseSphere != bNew)
//-/ {
//-/ bUseStdTextureXUseSphere = bNew;
//-/ bGeometryValid = FALSE;
//-/ }
//-/}
//-/void E3dCompoundObject::ImpSetUseStdTextureY(BOOL bNew)
//-/{
//-/ if(bUseStdTextureY != bNew)
//-/ {
//-/ bUseStdTextureY = bNew;
//-/ bGeometryValid = FALSE;
//-/ }
//-/}
//-/void E3dCompoundObject::ImpSetUseStdTextureYUseSphere(BOOL bNew)
//-/{
//-/ if(bUseStdTextureYUseSphere != bNew)
//-/ {
//-/ bUseStdTextureYUseSphere = bNew;
//-/ bGeometryValid = FALSE;
//-/ }
//-/}
//-/void E3dCompoundObject::ImpSetTextureKind(Base3DTextureKind eNew)
//-/{
//-/ if(eTextureKind != eNew)
//-/ {
//-/ eTextureKind = eNew;
//-/ }
//-/}
//-/void E3dCompoundObject::ImpSetTextureMode(Base3DTextureMode eNew)
//-/{
//-/ if(eTextureMode != eNew)
//-/ {
//-/ eTextureMode = eNew;
//-/ }
//-/}
//-/void E3dCompoundObject::ImpSetFilterTexture(BOOL bNew)
//-/{
//-/ if(bFilterTexture != bNew)
//-/ {
//-/ bFilterTexture = bNew;
//-/ }
//-/}
// EOF