summaryrefslogtreecommitdiff
path: root/binfilter/bf_svx/source/engine3d/svx_obj3d.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'binfilter/bf_svx/source/engine3d/svx_obj3d.cxx')
-rw-r--r--binfilter/bf_svx/source/engine3d/svx_obj3d.cxx2969
1 files changed, 2969 insertions, 0 deletions
diff --git a/binfilter/bf_svx/source/engine3d/svx_obj3d.cxx b/binfilter/bf_svx/source/engine3d/svx_obj3d.cxx
new file mode 100644
index 000000000000..950028c4469a
--- /dev/null
+++ b/binfilter/bf_svx/source/engine3d/svx_obj3d.cxx
@@ -0,0 +1,2969 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define ITEMID_COLOR SID_ATTR_3D_LIGHTCOLOR
+
+#include "svdstr.hrc"
+
+#include "svdview.hxx"
+
+
+
+
+
+
+#include "globl3d.hxx"
+
+
+
+#include "polyob3d.hxx"
+
+
+#include "polysc3d.hxx"
+
+
+
+
+
+
+#include "xoutx.hxx"
+
+
+
+
+
+
+
+
+
+
+
+#include "xlnwtit.hxx"
+
+
+#include "svdio.hxx"
+
+
+
+#include "svxids.hrc"
+
+
+
+
+
+
+
+
+
+
+
+#include "eeitem.hxx"
+
+
+namespace binfilter {
+
+#define ITEMVALUE(ItemSet,Id,Cast) ((const Cast&)(ItemSet).Get(Id)).GetValue()
+
+/*************************************************************************
+|*
+|* Liste fuer 3D-Objekte
+|*
+\************************************************************************/
+
+/*N*/ TYPEINIT1(E3dObjList, SdrObjList);
+
+/*N*/ E3dObjList::E3dObjList(SdrModel* pNewModel, SdrPage* pNewPage, E3dObjList* pNewUpList)
+/*N*/ : SdrObjList(pNewModel, pNewPage, pNewUpList)
+/*N*/ {
+/*N*/ }
+
+/*?*/ E3dObjList::E3dObjList(const E3dObjList& rSrcList)
+/*?*/ : SdrObjList(rSrcList)
+/*?*/ {
+/*?*/ }
+
+/*N*/ E3dObjList::~E3dObjList()
+/*N*/ {
+/*N*/ }
+
+/*N*/ void E3dObjList::NbcInsertObject(SdrObject* pObj, ULONG nPos, const SdrInsertReason* pReason)
+/*N*/ {
+/*N*/ // Owner holen
+/*N*/ DBG_ASSERT(GetOwnerObj()->ISA(E3dObject), "AW: Einfuegen 3DObject in Parent != 3DObject");
+/*N*/
+/*N*/ // Ist es ueberhaupt ein 3D-Objekt?
+/*N*/ if(pObj && pObj->ISA(E3dObject))
+/*N*/ {
+/*N*/ // Normales 3D Objekt, einfuegen mittels
+/*N*/ // call parent
+/*N*/ SdrObjList::NbcInsertObject(pObj, nPos, pReason);
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*?*/ // Kein 3D Objekt, fuege in Seite statt in Szene ein...
+/*?*/ GetOwnerObj()->GetPage()->InsertObject(pObj, nPos);
+/*N*/ }
+/*N*/ }
+
+
+/*N*/ SdrObject* E3dObjList::RemoveObject(ULONG nObjNum)
+/*N*/ {
+/*N*/ // Owner holen
+/*N*/ DBG_ASSERT(GetOwnerObj()->ISA(E3dObject), "AW: Entfernen 3DObject aus Parent != 3DObject");
+/*N*/ E3dObject* pOwner = (E3dObject*)GetOwnerObj();
+/*N*/
+/*N*/ // call parent
+/*N*/ SdrObject* pRetval = SdrObjList::RemoveObject(nObjNum);
+/*N*/
+/*N*/ // FitSnapRectToBoundVol vorbereiten
+/*N*/ if(GetOwnerObj() && GetOwnerObj()->ISA(E3dScene))
+/*N*/ ((E3dScene*)GetOwnerObj())->CorrectSceneDimensions();
+/*N*/
+/*N*/ return pRetval;
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Konstruktor
+|*
+\************************************************************************/
+
+/*N*/ TYPEINIT1(E3dObject, SdrAttrObj);
+
+/*N*/ E3dObject::E3dObject() :
+/*N*/ nLogicalGroup(0),
+/*N*/ nObjTreeLevel(0),
+/*N*/ eDragDetail(E3DDETAIL_ONEBOX),
+/*N*/ nPartOfParent(0),
+/*N*/ bTfHasChanged(TRUE),
+/*N*/ bBoundVolValid(TRUE),
+/*N*/ bIsSelected(FALSE)
+/*N*/ {
+/*N*/ bIs3DObj = TRUE;
+/*N*/ pSub = new E3dObjList(NULL, NULL);
+/*N*/ pSub->SetOwnerObj(this);
+/*N*/ pSub->SetListKind(SDROBJLIST_GROUPOBJ);
+/*N*/ bClosedObj = TRUE;
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Destruktor
+|*
+\************************************************************************/
+
+/*N*/ E3dObject::~E3dObject()
+/*N*/ {
+/*N*/ delete pSub;
+/*N*/ pSub = NULL;
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Selektions-Flag setzen
+|*
+\************************************************************************/
+
+
+/*************************************************************************
+|*
+|* Aufbrechen, default-Implementierungen
+|*
+\************************************************************************/
+
+
+/*N*/ SdrAttrObj* E3dObject::GetBreakObj()
+/*N*/ {
+/*N*/ return 0L;
+/*N*/ }
+
+/*************************************************************************
+|*
+|* SetRectsDirty muss ueber die lokale SdrSubList gehen
+|*
+\************************************************************************/
+
+/*N*/ void E3dObject::SetRectsDirty(FASTBOOL bNotMyself)
+/*N*/ {
+/*N*/ // call parent
+/*N*/ SdrAttrObj::SetRectsDirty(bNotMyself);
+/*N*/
+/*N*/ // Eigene SubListe AUCH behandeln
+/*N*/ if(pSub && pSub->GetObjCount())
+/*N*/ {
+/*N*/ for (ULONG i = 0; i < pSub->GetObjCount(); i++)
+/*N*/ {
+/*N*/ SdrObject* pObj = pSub->GetObj(i);
+/*N*/ DBG_ASSERT(pObj->ISA(E3dObject), "AW: In E3dObject sind nur 3D-Objekte erlaubt!");
+/*N*/ ((E3dObject*)pObj)->SetRectsDirty(bNotMyself);
+/*N*/ }
+/*N*/ }
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Inventor zurueckgeben
+|*
+\************************************************************************/
+
+/*N*/ UINT32 E3dObject::GetObjInventor() const
+/*N*/ {
+/*N*/ return E3dInventor;
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Identifier zurueckgeben
+|*
+\************************************************************************/
+
+/*N*/ UINT16 E3dObject::GetObjIdentifier() const
+/*N*/ {
+/*N*/ return E3D_OBJECT_ID;
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Faehigkeiten des Objektes feststellen
+|*
+\************************************************************************/
+
+
+/*************************************************************************
+|*
+|* Layer abfragen
+|*
+\************************************************************************/
+
+/*N*/ SdrLayerID E3dObject::GetLayer() const
+/*N*/ {
+/*N*/ FASTBOOL bFirst = TRUE;
+/*N*/ E3dObjList* pOL = pSub;
+/*N*/ ULONG nObjCnt = pOL->GetObjCount();
+/*N*/ SdrLayerID nLayer = SdrLayerID(nLayerID);
+/*N*/
+/*N*/ for ( ULONG i = 0; i < nObjCnt; i++ )
+/*N*/ {
+/*N*/ SdrLayerID nObjLayer;
+/*N*/ if(pOL->GetObj(i)->ISA(E3dPolyObj))
+/*N*/ nObjLayer = SdrLayerID(nLayerID);
+/*N*/ else
+/*N*/ nObjLayer = pOL->GetObj(i)->GetLayer();
+/*N*/
+/*N*/ if (bFirst)
+/*N*/ {
+/*N*/ nLayer = nObjLayer;
+/*N*/ bFirst = FALSE;
+/*N*/ }
+/*N*/ else if ( nObjLayer != nLayer )
+/*N*/ return 0;
+/*N*/ }
+/*N*/ return nLayer;
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Layer setzen
+|*
+\************************************************************************/
+
+/*N*/ void E3dObject::NbcSetLayer(SdrLayerID nLayer)
+/*N*/ {
+/*N*/ SdrAttrObj::NbcSetLayer(nLayer);
+/*N*/
+/*N*/ E3dObjList* pOL = pSub;
+/*N*/ ULONG nObjCnt = pOL->GetObjCount();
+/*N*/ ULONG i;
+/*N*/ for ( i = 0; i < nObjCnt; i++ )
+/*N*/ pOL->GetObj(i)->NbcSetLayer(nLayer);
+/*N*/ }
+
+/*************************************************************************
+|*
+|* ObjList auch an SubList setzen
+|*
+\************************************************************************/
+
+/*N*/ void E3dObject::SetObjList(SdrObjList* pNewObjList)
+/*N*/ {
+/*N*/ SdrObject::SetObjList(pNewObjList);
+/*N*/ pSub->SetUpList(pNewObjList);
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Layer setzen
+|*
+\************************************************************************/
+
+/*N*/ void E3dObject::SetPage(SdrPage* pNewPage)
+/*N*/ {
+/*N*/ SdrAttrObj::SetPage(pNewPage);
+/*N*/ pSub->SetPage(pNewPage);
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Layer setzen
+|*
+\************************************************************************/
+
+/*N*/ void E3dObject::SetModel(SdrModel* pNewModel)
+/*N*/ {
+/*N*/ SdrAttrObj::SetModel(pNewModel);
+/*N*/ pSub->SetModel(pNewModel);
+/*N*/ }
+
+/*************************************************************************
+|*
+|* resize object, used from old 2d interfaces, e.g. in Move/Scale dialog
+|* (F4)
+|*
+\************************************************************************/
+/*N*/ void E3dObject::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
+/*N*/ {
+/*N*/ #ifndef SVX_LIGHT
+/*N*/ // SdrAttrObj::NbcResize(rRef, xFact, yFact);
+/*N*/
+/*N*/ // Bewegung in X,Y im Augkoordinatensystem
+/*N*/ E3dScene* pScene = GetScene();
+/*N*/
+/*N*/ if(pScene)
+/*N*/ {
+/*N*/ // pos ermitteln
+/*N*/ B3dTransformationSet& rTransSet = pScene->GetCameraSet();
+/*N*/ Vector3D aScaleCenter((double)rRef.X(), (double)rRef.Y(), 32768.0);
+/*N*/ aScaleCenter = rTransSet.ViewToEyeCoor(aScaleCenter);
+/*N*/
+/*N*/ // scale-faktoren holen
+/*N*/ double fScaleX = xFact;
+/*N*/ double fScaleY = yFact;
+/*N*/
+/*N*/ // build transform
+/*N*/ Matrix4D mFullTransform(GetFullTransform());
+/*N*/ Matrix4D mTrans(mFullTransform);
+/*N*/
+/*N*/ mTrans *= rTransSet.GetOrientation();
+/*N*/ mTrans.Translate(-aScaleCenter);
+/*N*/ mTrans.Scale(fScaleX, fScaleY, 1.0);
+/*N*/ mTrans.Translate(aScaleCenter);
+/*N*/ mTrans *= rTransSet.GetInvOrientation();
+/*N*/ mFullTransform.Invert();
+/*N*/ mTrans *= mFullTransform;
+/*N*/
+/*N*/ // anwenden
+/*N*/ Matrix4D mObjTrans(GetTransform());
+/*N*/ mObjTrans *= mTrans;
+/*N*/ SetTransform(mObjTrans);
+/*N*/
+/*N*/ // force new camera and SnapRect on scene, geometry may have really
+/*N*/ // changed
+/*N*/ pScene->CorrectSceneDimensions();
+/*N*/ }
+/*N*/ #endif
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Objekt verschieben in 2D, wird bei Cursortasten benoetigt
+|*
+\************************************************************************/
+
+/*************************************************************************
+|*
+|* liefere die Sublist, aber nur dann, wenn darin Objekte enthalten sind !
+|*
+\************************************************************************/
+
+/*N*/ SdrObjList* E3dObject::GetSubList() const
+/*N*/ {
+/*N*/ return pSub;
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Anzahl der Handles zurueckgeben
+|*
+\************************************************************************/
+
+
+/*************************************************************************
+|*
+|* Handle-Liste fuellen
+|*
+\************************************************************************/
+
+
+/*************************************************************************
+|*
+\************************************************************************/
+
+
+/*************************************************************************
+|*
+|* Paint; wird z.Z. nicht benutzt, da das Paint ueber die
+|* (2D-)Displayliste der Szene laeuft
+|*
+\************************************************************************/
+
+
+/*************************************************************************
+|*
+|* Objekt als Kontur in das Polygon einfuegen
+|*
+\************************************************************************/
+
+
+/*************************************************************************
+|*
+|* Schatten fuer 3D-Objekte zeichnen
+|*
+\************************************************************************/
+
+
+/*************************************************************************
+|*
+|* SnapRect berechnen
+|*
+\************************************************************************/
+
+/*N*/ void E3dObject::RecalcSnapRect()
+/*N*/ {
+/*N*/ maSnapRect = Rectangle();
+/*N*/ if(pSub && pSub->GetObjCount())
+/*N*/ {
+/*N*/ for (ULONG i = 0; i < pSub->GetObjCount(); i++)
+/*N*/ {
+/*N*/ SdrObject* pObj = pSub->GetObj(i);
+/*N*/ DBG_ASSERT(pObj->ISA(E3dObject), "AW: In E3dObject sind nur 3D-Objekte erlaubt!");
+/*N*/ Rectangle aSubRect = ((E3dObject*)pObj)->GetSnapRect();
+/*N*/ maSnapRect.Union(aSubRect);
+/*N*/ }
+/*N*/ }
+/*N*/ }
+
+/*************************************************************************
+|*
+|* BoundRect berechnen
+|*
+\************************************************************************/
+
+/*N*/ void E3dObject::RecalcBoundRect()
+/*N*/ {
+/*N*/ // BoundRect aus SnapRect berechnen
+/*N*/ aOutRect = GetSnapRect();
+/*N*/
+/*N*/ if(pSub && pSub->GetObjCount())
+/*N*/ {
+/*N*/ for (ULONG i = 0; i < pSub->GetObjCount(); i++)
+/*N*/ {
+/*N*/ SdrObject* pObj = pSub->GetObj(i);
+/*N*/ DBG_ASSERT(pObj->ISA(E3dObject), "AW: In E3dObject sind nur 3D-Objekte erlaubt!");
+/*N*/ Rectangle aSubRect = ((E3dObject*)pObj)->GetBoundRect();
+/*N*/ aOutRect.Union(aSubRect);
+/*N*/ }
+/*N*/ }
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Einfuegen eines 3D-Objekts an den Parent weitermelden, damit dieser
+|* ggf. eine Sonderbehandlung fuer spezielle Objekte durchfuehren kann
+|* (z.B. Light/Label in E3dScene)
+|*
+\************************************************************************/
+
+/*N*/ void E3dObject::NewObjectInserted(const E3dObject* p3DObj)
+/*N*/ {
+/*N*/ if(GetParentObj())
+/*N*/ GetParentObj()->NewObjectInserted(p3DObj);
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Parent ueber Aenderung der Struktur (z.B. durch Transformation)
+|* informieren; dabei wird das Objekt, in welchem die Aenderung
+|* aufgetreten ist, uebergeben
+|*
+\************************************************************************/
+
+/*N*/ void E3dObject::StructureChanged(const E3dObject* p3DObj)
+/*N*/ {
+/*N*/ if ( GetParentObj() )
+/*N*/ {
+/*N*/ // Wenn sich im Child das BoundVolume geaendert hat, muessen
+/*N*/ // auch die der Parents angepasst werden
+/*N*/ if ( !p3DObj->bBoundVolValid )
+/*N*/ GetParentObj()->bBoundVolValid = FALSE;
+/*N*/
+/*N*/ GetParentObj()->StructureChanged(p3DObj);
+/*N*/ }
+/*N*/ }
+
+/*************************************************************************
+|*
+|* 3D-Objekt einfuegen
+|*
+\************************************************************************/
+
+/*N*/ void E3dObject::Insert3DObj(E3dObject* p3DObj)
+/*N*/ {
+/*N*/ DBG_ASSERT(p3DObj, "Insert3DObj mit NULL-Zeiger!");
+/*N*/ p3DObj->SetObjTreeLevel(nObjTreeLevel + 1);
+/*N*/ SdrPage* pPg = pPage;
+/*N*/ pSub->InsertObject(p3DObj);
+/*N*/ pPage = pPg;
+/*N*/ bBoundVolValid = FALSE;
+/*N*/ NewObjectInserted(p3DObj);
+/*N*/ StructureChanged(this);
+/*N*/ }
+
+/*N*/ void E3dObject::Remove3DObj(E3dObject* p3DObj)
+/*N*/ {
+/*N*/ DBG_ASSERT(p3DObj, "Remove3DObj mit NULL-Zeiger!");
+/*N*/
+/*N*/ if(p3DObj->GetParentObj() == this)
+/*N*/ {
+/*N*/ SdrPage* pPg = pPage;
+/*N*/ pSub->RemoveObject(p3DObj->GetOrdNum());
+/*N*/ pPage = pPg;
+/*N*/
+/*N*/ bBoundVolValid = FALSE;
+/*N*/ StructureChanged(this);
+/*N*/ }
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Parent holen
+|*
+\************************************************************************/
+
+/*N*/ E3dObject* E3dObject::GetParentObj() const
+/*N*/ {
+/*N*/ E3dObject* pRetval = NULL;
+/*N*/
+/*N*/ if(GetObjList()
+/*N*/ && GetObjList()->GetOwnerObj()
+/*N*/ && GetObjList()->GetOwnerObj()->ISA(E3dObject))
+/*N*/ pRetval = ((E3dObject*)GetObjList()->GetOwnerObj());
+/*N*/ return pRetval;
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Uebergeordnetes Szenenobjekt bestimmen
+|*
+\************************************************************************/
+
+/*N*/ E3dScene* E3dObject::GetScene() const
+/*N*/ {
+/*N*/ if(GetParentObj())
+/*N*/ return GetParentObj()->GetScene();
+/*N*/ return NULL;
+/*N*/ }
+
+/*************************************************************************
+|*
+|* umschliessendes Volumen inklusive aller Kindobjekte berechnen
+|*
+\************************************************************************/
+
+/*N*/ void E3dObject::RecalcBoundVolume()
+/*N*/ {
+/*N*/ E3dObjList* pOL = pSub;
+/*N*/ ULONG nObjCnt = pOL->GetObjCount();
+/*N*/
+/*N*/ if(nObjCnt)
+/*N*/ {
+/*N*/ aBoundVol = Volume3D();
+/*N*/
+/*N*/ for (ULONG i = 0; i < nObjCnt; i++)
+/*N*/ {
+/*N*/ SdrObject* pObj = pOL->GetObj(i);
+/*N*/
+/*N*/ DBG_ASSERT(pObj->ISA(E3dObject), "In E3dObject sind nur 3D-Objekte erlaubt!");
+/*N*/ // Bei den Kindobjekten auch die lokalen Transformationen
+/*N*/ // beruecksichtigen
+/*N*/ E3dObject* p3DObj = (E3dObject*) pObj;
+/*N*/ const Volume3D& rVol = p3DObj->GetBoundVolume();
+/*N*/ const Matrix4D& rTf = p3DObj->GetTransform();
+/*N*/ aBoundVol.Union(rVol.GetTransformVolume(rTf));
+/*N*/ }
+/*N*/
+/*N*/ aLocalBoundVol = aBoundVol;
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ aBoundVol = aLocalBoundVol;
+/*N*/ }
+/*N*/
+/*N*/ bBoundVolValid = TRUE;
+/*N*/ }
+
+/*************************************************************************
+|*
+|* umschliessendes Volumen zurueckgeben und ggf. neu berechnen
+|*
+\************************************************************************/
+
+/*N*/ const Volume3D& E3dObject::GetBoundVolume()
+/*N*/ {
+/*N*/ if ( !bBoundVolValid )
+/*N*/ RecalcBoundVolume();
+/*N*/
+/*N*/ if(!aBoundVol.IsValid())
+/*N*/ aBoundVol = Volume3D(Vector3D(), Vector3D());
+/*N*/
+/*N*/ return aBoundVol;
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Mittelpunkt liefern
+|*
+\************************************************************************/
+
+/*N*/ Vector3D E3dObject::GetCenter()
+/*N*/ {
+/*N*/ Volume3D aVolume = GetBoundVolume();
+/*N*/ return (aVolume.MaxVec() + aVolume.MinVec()) / 2.0;
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Aederung des BoundVolumes an alle Kindobjekte weitergeben
+|*
+\************************************************************************/
+
+/*N*/ void E3dObject::SetBoundVolInvalid()
+/*N*/ {
+/*N*/ bBoundVolValid = FALSE;
+/*N*/
+/*N*/ E3dObjList* pOL = pSub;
+/*N*/ ULONG nObjCnt = pOL->GetObjCount();
+/*N*/
+/*N*/ for (ULONG i = 0; i < nObjCnt; i++)
+/*N*/ {
+/*N*/ SdrObject* pObj = pOL->GetObj(i);
+/*N*/ DBG_ASSERT(pObj->ISA(E3dObject), "In E3dObject sind nur 3D-Objekte erlaubt!");
+/*N*/
+/*N*/ ((E3dObject*) pObj)->SetBoundVolInvalid();
+/*N*/ }
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Aederung der Transformation an alle Kindobjekte weitergeben
+|*
+\************************************************************************/
+
+/*N*/ void E3dObject::SetTransformChanged()
+/*N*/ {
+/*N*/ bTfHasChanged = TRUE;
+/*N*/ bBoundVolValid = FALSE;
+/*N*/
+/*N*/ E3dObjList* pOL = pSub;
+/*N*/ ULONG nObjCnt = pOL->GetObjCount();
+/*N*/
+/*N*/ for (ULONG i = 0; i < nObjCnt; i++)
+/*N*/ {
+/*N*/ SdrObject* pObj = pOL->GetObj(i);
+/*N*/ DBG_ASSERT(pObj->ISA(E3dObject), "In E3dObject sind nur 3D-Objekte erlaubt!");
+/*N*/
+/*N*/ ((E3dObject*) pObj)->SetTransformChanged();
+/*N*/ }
+/*N*/ }
+
+/*************************************************************************
+|*
+|* hierarchische Transformation ueber alle Parents bestimmen und mit
+|* der uebergebenen Matrix verketten
+|*
+\************************************************************************/
+
+
+/*************************************************************************
+|*
+|* hierarchische Transformation ueber alle Parents bestimmen, in
+|* aFullTfMatrix ablegen und diese zurueckgeben
+|*
+\************************************************************************/
+
+/*N*/ const Matrix4D& E3dObject::GetFullTransform()
+/*N*/ {
+/*N*/ if ( bTfHasChanged )
+/*N*/ {
+/*N*/ aFullTfMatrix = aTfMatrix;
+/*N*/
+/*N*/ if ( GetParentObj() )
+/*N*/ aFullTfMatrix *= GetParentObj()->GetFullTransform();
+/*N*/
+/*N*/ bTfHasChanged = FALSE;
+/*N*/ }
+/*N*/
+/*N*/ return aFullTfMatrix;
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Transformationsmatrix abfragen
+|*
+\************************************************************************/
+
+/*N*/ const Matrix4D& E3dObject::GetTransform() const
+/*N*/ {
+/*N*/ return aTfMatrix;
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Transformationsmatrix setzen
+|*
+\************************************************************************/
+
+/*N*/ void E3dObject::NbcSetTransform(const Matrix4D& rMatrix)
+/*N*/ {
+/*N*/ aTfMatrix = rMatrix;
+/*N*/ SetTransformChanged();
+/*N*/ StructureChanged(this);
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Transformationsmatrix auf Einheitsmatrix zuruecksetzen
+|*
+\************************************************************************/
+
+/*N*/ void E3dObject::NbcResetTransform()
+/*N*/ {
+/*N*/ aTfMatrix.Identity();
+/*N*/ SetTransformChanged();
+/*N*/ StructureChanged(this);
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Transformationsmatrix setzen mit Repaint-Broadcast
+|*
+\************************************************************************/
+
+/*N*/ void E3dObject::SetTransform(const Matrix4D& rMatrix)
+/*N*/ {
+/*N*/ SendRepaintBroadcast();
+/*N*/ NbcSetTransform(rMatrix);
+/*N*/ SetChanged();
+/*N*/ SendRepaintBroadcast();
+/*N*/ if (pUserCall != NULL) pUserCall->Changed(*this, SDRUSERCALL_RESIZE, Rectangle());
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Transformationsmatrix zuruecksetzen mit Repaint-Broadcast
+|*
+\************************************************************************/
+
+
+/*************************************************************************
+|*
+|* Translation
+|*
+\************************************************************************/
+
+/*************************************************************************
+|*
+|* Translation mit Repaint-Broadcast
+|*
+\************************************************************************/
+
+
+/*************************************************************************
+|*
+|* Skalierungen
+|*
+\************************************************************************/
+
+
+/************************************************************************/
+
+
+/************************************************************************/
+
+
+/************************************************************************/
+
+
+/*************************************************************************
+|*
+|* gleichmaessige Skalierung
+|*
+\************************************************************************/
+
+
+/*************************************************************************
+|*
+|* Skalierungen mit mit Repaint-Broadcast
+|*
+\************************************************************************/
+
+
+/************************************************************************/
+
+
+/************************************************************************/
+
+
+/************************************************************************/
+
+
+/************************************************************************/
+
+
+/*************************************************************************
+|*
+|* Rotationen mit Winkel in Radiant
+|*
+\************************************************************************/
+
+
+/************************************************************************/
+
+
+/************************************************************************/
+
+
+/*************************************************************************
+|*
+|* Rotationen mit Repaint-Broadcast
+|*
+\************************************************************************/
+
+
+/************************************************************************/
+
+
+/************************************************************************/
+
+
+/*************************************************************************
+|*
+|* Objektbaum-Ebene des Objekts und aller Children setzen
+|*
+\************************************************************************/
+
+/*N*/ void E3dObject::SetObjTreeLevel(USHORT nNewLevel)
+/*N*/ {
+/*N*/ nObjTreeLevel = nNewLevel;
+/*N*/ nNewLevel++;
+/*N*/
+/*N*/ E3dObjList* pOL = pSub;
+/*N*/ ULONG nObjCnt = pOL->GetObjCount();
+/*N*/
+/*N*/ for (ULONG i = 0; i < nObjCnt; i++)
+/*N*/ {
+/*N*/ SdrObject* pObj = pOL->GetObj(i);
+/*N*/ DBG_ASSERT(pObj->ISA(E3dObject), "In E3dObject sind nur 3D-Objekte erlaubt!");
+/*N*/
+/*N*/ ((E3dObject*) pObj)->SetObjTreeLevel(nNewLevel);
+/*N*/ }
+/*N*/ }
+
+/*************************************************************************
+|*
+|* logische Gruppe setzen
+|*
+\************************************************************************/
+
+
+/*************************************************************************
+|*
+|* Linien fuer die Wireframe-Darstellung des Objekts dem uebergebenen
+|* Polygon3D hinzufuegen. Als default wird das BoundVolume verwendet.
+|*
+\************************************************************************/
+
+
+/*************************************************************************
+|*
+|* Get the name of the object (singular)
+|*
+\************************************************************************/
+
+
+/*************************************************************************
+|*
+|* Get the name of the object (plural)
+|*
+\************************************************************************/
+
+
+/*************************************************************************
+|*
+|* Wireframe-XPolyPolygon erzeugen
+|*
+\************************************************************************/
+
+
+/*************************************************************************
+|*
+|* Drag-Polygon zurueckgeben
+|*
+\************************************************************************/
+
+
+/*************************************************************************
+|*
+|* Zuweisungsoperator
+|*
+\************************************************************************/
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ItemSet access
+
+/*N*/ const SfxItemSet& E3dObject::GetItemSet() const
+/*N*/ {
+/*N*/ // include Items of scene this object belongs to
+/*N*/ E3dScene* pScene = GetScene();
+/*N*/ if(pScene && pScene != this)
+/*N*/ {
+/*N*/ SfxItemSet& rSet = (SfxItemSet&)SdrAttrObj::GetItemSet();
+/*N*/ SfxItemSet aSet(*rSet.GetPool(), SDRATTR_3DSCENE_FIRST, SDRATTR_3DSCENE_LAST);
+/*N*/ aSet.Put(pScene->E3dObject::GetItemSet());
+/*N*/ rSet.Put(aSet);
+/*N*/ }
+/*N*/
+/*N*/ return SdrAttrObj::GetItemSet();
+/*N*/ }
+
+/*N*/ SfxItemSet* E3dObject::CreateNewItemSet(SfxItemPool& rPool)
+/*N*/ {
+/*N*/ // include ALL items, 2D and 3D
+/*N*/ return new SfxItemSet(rPool,
+/*N*/ // ranges from SdrAttrObj
+/*N*/ SDRATTR_START, SDRATTRSET_SHADOW,
+/*N*/ SDRATTRSET_OUTLINER, SDRATTRSET_MISC,
+/*N*/
+/*N*/ // ranges for 3D (object and scene)
+/*N*/ SDRATTR_3D_FIRST, SDRATTR_3D_LAST,
+/*N*/
+/*N*/ // outliner and end
+/*N*/ EE_ITEMS_START, EE_ITEMS_END,
+/*N*/ 0, 0);
+/*N*/ }
+
+// private support routines for ItemSet access. NULL pointer means clear item.
+/*N*/ void E3dObject::ItemChange(const sal_uInt16 nWhich, const SfxPoolItem* pNewItem)
+/*N*/ {
+/*N*/ // propagate item changes to scene
+/*N*/ if(!nWhich || (nWhich >= SDRATTR_3DSCENE_FIRST && nWhich <= SDRATTR_3DSCENE_LAST))
+/*N*/ {
+/*N*/ E3dScene* pScene = GetScene();
+/*N*/ if(pScene && pScene != this)
+/*N*/ pScene->E3dObject::ItemChange(nWhich, pNewItem);
+/*N*/ }
+/*N*/
+/*N*/ // call parent
+/*N*/ SdrAttrObj::ItemChange(nWhich, pNewItem);
+/*N*/ }
+
+// #107770# Like propagating ItemChange to the scene if scene items are changed,
+// do the same with the PostItemChange calls.
+/*N*/ void E3dObject::PostItemChange(const sal_uInt16 nWhich)
+/*N*/ {
+/*N*/ // propagate item changes to scene
+/*N*/ if(!nWhich || (nWhich >= SDRATTR_3DSCENE_FIRST && nWhich <= SDRATTR_3DSCENE_LAST))
+/*N*/ {
+/*N*/ E3dScene* pScene = GetScene();
+/*N*/ if(pScene && pScene != this)
+/*N*/ pScene->PostItemChange(nWhich);
+/*N*/ }
+/*N*/
+/*N*/ // call parent
+/*N*/ SdrAttrObj::PostItemChange(nWhich);
+/*N*/ }
+
+/*N*/ void E3dObject::ItemSetChanged( const SfxItemSet& rSet )
+/*N*/ {
+/*N*/ // call parent
+/*N*/ SdrAttrObj::ItemSetChanged( rSet );
+/*N*/
+/*N*/ // local changes
+/*N*/ StructureChanged(this);
+/*N*/ }
+
+/*************************************************************************
+|*
+|* StyleSheet setzen
+|*
+\************************************************************************/
+
+/*N*/ void E3dObject::NbcSetStyleSheet(SfxStyleSheet* pNewStyleSheet,
+/*N*/ FASTBOOL bDontRemoveHardAttr)
+/*N*/ {
+/*N*/ // call parent
+/*N*/ SdrAttrObj::NbcSetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
+/*N*/
+/*N*/ E3dObjList* pOL = pSub;
+/*N*/ ULONG nObjCnt = pOL->GetObjCount();
+/*N*/ for ( ULONG i = 0; i < nObjCnt; i++ )
+/*?*/ pOL->GetObj(i)->NbcSetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
+/*N*/ }
+
+/*************************************************************************
+|*
+|* 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)
+|*
+\************************************************************************/
+
+/*N*/ #ifndef SVX_LIGHT
+/*N*/ void E3dObject::WriteOnlyOwnMembers(SvStream& rOut) const
+/*N*/ {
+/*N*/ // Fuer Abwaertskompatibilitaet (Lesen neuer Daten mit altem Code)
+/*N*/ SdrDownCompat aCompat(rOut, STREAM_WRITE);
+/*N*/ #ifdef DBG_UTIL
+/*N*/ aCompat.SetID("E3dObjectOwnMembers");
+/*N*/ #endif
+/*N*/
+/*N*/ rOut << aLocalBoundVol;
+/*N*/
+/*N*/ Old_Matrix3D aMat3D;
+/*N*/ aMat3D = aTfMatrix;
+/*N*/ rOut << aMat3D;
+/*N*/
+/*N*/ rOut << nLogicalGroup;
+/*N*/ rOut << nObjTreeLevel;
+/*N*/ rOut << nPartOfParent;
+/*N*/ rOut << UINT16(eDragDetail);
+/*N*/ }
+/*N*/ #endif
+
+/*************************************************************************
+|*
+|* Objektdaten in Stream speichern
+|*
+\************************************************************************/
+
+/*N*/ void E3dObject::WriteData(SvStream& rOut) const
+/*N*/ {
+/*N*/ #ifndef SVX_LIGHT
+/*N*/ long position = rOut.Tell();
+/*N*/ SdrAttrObj::WriteData(rOut);
+/*N*/ position = rOut.Tell();
+/*N*/
+/*N*/ // Fuer Abwaertskompatibilitaet (Lesen neuer Daten mit altem Code)
+/*N*/ SdrDownCompat aCompat(rOut, STREAM_WRITE);
+/*N*/ #ifdef DBG_UTIL
+/*N*/ aCompat.SetID("E3dObject");
+/*N*/ #endif
+/*N*/
+/*N*/ position = rOut.Tell();
+/*N*/ pSub->Save(rOut);
+/*N*/ position = rOut.Tell();
+/*N*/
+/*N*/ if (rOut.GetVersion() < 3560)
+/*N*/ {
+/*N*/ rOut << aLocalBoundVol;
+/*N*/
+/*N*/ Old_Matrix3D aMat3D;
+/*N*/ aMat3D = aTfMatrix;
+/*N*/ rOut << aMat3D;
+/*N*/
+/*N*/ rOut << nLogicalGroup;
+/*N*/ rOut << nObjTreeLevel;
+/*N*/ rOut << nPartOfParent;
+/*N*/ rOut << UINT16(eDragDetail);
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ WriteOnlyOwnMembers(rOut);
+/*N*/ }
+/*N*/ position = rOut.Tell();
+/*N*/ #endif
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Objektdaten aus Stream laden
+|*
+\************************************************************************/
+
+/*N*/ void E3dObject::ReadData(const SdrObjIOHeader& rHead, SvStream& rIn)
+/*N*/ {
+/*N*/ long position = rIn.Tell();
+/*N*/ if (ImpCheckSubRecords (rHead, rIn))
+/*N*/ {
+/*N*/ position = rIn.Tell();
+/*N*/ SdrAttrObj::ReadData(rHead, rIn);
+/*N*/ position = rIn.Tell();
+/*N*/ // Fuer Abwaertskompatibilitaet (Lesen neuer Daten mit altem Code)
+/*N*/ SdrDownCompat aCompat(rIn, STREAM_READ);
+/*N*/ #ifdef DBG_UTIL
+/*N*/ aCompat.SetID("E3dObject");
+/*N*/ #endif
+/*N*/ pSub->Load(rIn, *pPage);
+/*N*/
+/*N*/ position = rIn.Tell();
+/*N*/ if ((rIn.GetVersion() < 3560) || (rHead.GetVersion() <= 12))
+/*N*/ {
+/*N*/ UINT16 nTmp16;
+/*N*/
+/*N*/ rIn >> aLocalBoundVol;
+/*N*/
+/*N*/ Old_Matrix3D aMat3D;
+/*N*/ rIn >> aMat3D;
+/*N*/ aTfMatrix = Matrix4D(aMat3D);
+/*N*/
+/*N*/ rIn >> nLogicalGroup;
+/*N*/ rIn >> nObjTreeLevel;
+/*N*/ rIn >> nPartOfParent;
+/*N*/ rIn >> nTmp16; eDragDetail = E3dDragDetail(nTmp16);
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ ReadOnlyOwnMembers(rHead, rIn);
+/*N*/ }
+/*N*/ position = rIn.Tell();
+/*N*/
+/*N*/ // Wie ein veraendertes Objekt behandeln
+/*N*/ SetTransformChanged();
+/*N*/ StructureChanged(this);
+/*N*/
+/*N*/ // BoundVolume muss neu berechnet werden
+/*N*/ bBoundVolValid = FALSE;
+/*N*/
+/*N*/ // SnapRect auch
+/*N*/ bSnapRectDirty = TRUE;
+/*N*/ }
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Nur die Daten des E3dObject aus Stream laden (nicht der Sublisten und
+|* der Basisklassen). Wird von E3dSphere auch genutzt. (FileFormat-Optimierung)
+|*
+\************************************************************************/
+
+/*N*/ void E3dObject::ReadOnlyOwnMembers(const SdrObjIOHeader& rHead, SvStream& rIn)
+/*N*/ {
+/*N*/ // Fuer Abwaertskompatibilitaet (Lesen neuer Daten mit altem Code)
+/*N*/ SdrDownCompat aCompat(rIn, STREAM_READ);
+/*N*/ #ifdef DBG_UTIL
+/*N*/ aCompat.SetID("E3dObjectOwnMembers");
+/*N*/ #endif
+/*N*/ UINT16 nTmp16;
+/*N*/
+/*N*/ rIn >> aLocalBoundVol;
+/*N*/
+/*N*/ Old_Matrix3D aMat3D;
+/*N*/ rIn >> aMat3D;
+/*N*/ aTfMatrix = Matrix4D(aMat3D);
+/*N*/
+/*N*/ rIn >> nLogicalGroup;
+/*N*/ rIn >> nObjTreeLevel;
+/*N*/ rIn >> nPartOfParent;
+/*N*/ rIn >> nTmp16; eDragDetail = E3dDragDetail(nTmp16);
+/*N*/
+/*N*/ bBoundVolValid = FALSE;
+/*N*/ }
+
+
+/*************************************************************************
+|*
+|* nach dem Laden...
+|*
+\************************************************************************/
+
+/*N*/ void E3dObject::AfterRead()
+/*N*/ {
+/*N*/ SdrAttrObj::AfterRead();
+/*N*/ if (pSub)
+/*N*/ pSub->AfterRead();
+/*N*/ }
+
+/*************************************************************************
+|*
+|* erstelle neues GeoData-Objekt
+|*
+\************************************************************************/
+
+/*N*/ SdrObjGeoData *E3dObject::NewGeoData() const
+/*N*/ {
+/*N*/ // Theoretisch duerfen auch nur Szenen ihre GeoDatas erstellen und verwalten !!
+/*N*/ // AW: Dies stimmt nicht mehr, diese Stelle ist mit der neuen Engine OK!
+/*N*/ return new E3DObjGeoData;
+/*N*/ }
+
+/*************************************************************************
+|*
+|* uebergebe aktuelle werte an das GeoData-Objekt
+|*
+\************************************************************************/
+
+/*N*/ void E3dObject::SaveGeoData(SdrObjGeoData& rGeo) const
+/*N*/ {
+/*N*/ SdrAttrObj::SaveGeoData (rGeo);
+/*N*/
+/*N*/ ((E3DObjGeoData &) rGeo).aLocalBoundVol = aLocalBoundVol;
+/*N*/ ((E3DObjGeoData &) rGeo).aTfMatrix = aTfMatrix;
+/*N*/ }
+
+/*************************************************************************
+|*
+|* uebernehme werte aus dem GeoData-Objekt
+|*
+\************************************************************************/
+
+/*N*/ void E3dObject::RestGeoData(const SdrObjGeoData& rGeo)
+/*N*/ {
+/*N*/ aLocalBoundVol = ((E3DObjGeoData &) rGeo).aLocalBoundVol;
+/*N*/ NbcSetTransform (((E3DObjGeoData &) rGeo).aTfMatrix);
+/*N*/
+/*N*/ SdrAttrObj::RestGeoData (rGeo);
+/*N*/ GetScene()->FitSnapRectToBoundVol();
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Pruefe, ob die SubRecords ok sind und mit der Factory gelesen werden
+|* koennen.
+|*
+\************************************************************************/
+
+/*N*/ BOOL E3dObject::ImpCheckSubRecords (const SdrObjIOHeader& rHead,
+/*N*/ SvStream& rIn)
+/*N*/ {
+/*N*/ BOOL bDoRead = FALSE;
+/*N*/
+/*N*/ if ( rIn.GetError() == SVSTREAM_OK )
+/*N*/ {
+/*N*/ if (rHead.GetVersion () <= 12)
+/*N*/ {
+/*N*/ ULONG nPos0 = rIn.Tell();
+/*N*/ // Einen SubRecord ueberspringen (SdrObject)
+/*N*/ { SdrDownCompat aCompat(rIn,STREAM_READ); }
+/*N*/ // Nocheinen SubRecord ueberspringen (SdrAttrObj)
+/*N*/ { SdrDownCompat aCompat(rIn,STREAM_READ); }
+/*N*/ // Und nun muesste meiner kommen
+/*N*/ bDoRead = rHead.GetBytesLeft() != 0;
+/*N*/ rIn.Seek (nPos0); // FilePos wieder restaurieren
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ bDoRead = TRUE;
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ return bDoRead;
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Keine DefaultAttr, zu langsam
+|*
+\************************************************************************/
+
+/*N*/ void E3dObject::ForceDefaultAttr()
+/*N*/ {
+/*N*/ }
+
+/*************************************************************************/
+
+/*N*/ TYPEINIT1(E3dCompoundObject, E3dObject);
+
+/*************************************************************************
+|*
+|* Konstruktor
+|*
+\************************************************************************/
+
+/*N*/ E3dCompoundObject::E3dCompoundObject() : E3dObject()
+/*N*/ {
+/*N*/ // Defaults setzen
+/*N*/ E3dDefaultAttributes aDefault;
+/*N*/ SetDefaultAttributes(aDefault);
+/*N*/
+/*N*/ bBytesLeft = FALSE;
+/*N*/ bCreateE3dPolyObj = FALSE;
+/*N*/ bGeometryValid = FALSE;
+/*N*/ }
+
+/*N*/ E3dCompoundObject::E3dCompoundObject(E3dDefaultAttributes& rDefault) : E3dObject()
+/*N*/ {
+/*N*/ // Defaults setzen
+/*N*/ SetDefaultAttributes(rDefault);
+/*N*/
+/*N*/ bBytesLeft = FALSE;
+/*N*/ bCreateE3dPolyObj = FALSE;
+/*N*/ bGeometryValid = FALSE;
+/*N*/ }
+
+/*N*/ void E3dCompoundObject::SetDefaultAttributes(E3dDefaultAttributes& rDefault)
+/*N*/ {
+/*N*/ // Defaults setzen
+/*N*/ aMaterialAmbientColor = rDefault.GetDefaultAmbientColor();
+/*N*/
+//is always default, so it needs not to be set /*N*/ aBackMaterial = rDefault.GetDefaultBackMaterial();
+/*N*/ bCreateNormals = rDefault.GetDefaultCreateNormals();
+/*N*/ bCreateTexture = rDefault.GetDefaultCreateTexture();
+/*N*/ bUseDifferentBackMaterial = rDefault.GetDefaultUseDifferentBackMaterial();
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Destruktor
+|*
+\************************************************************************/
+
+/*N*/ E3dCompoundObject::~E3dCompoundObject ()
+/*N*/ {
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Start der Geometrieerzeugung ankuendigen
+|*
+\************************************************************************/
+
+/*N*/ void E3dCompoundObject::StartCreateGeometry()
+/*N*/ {
+/*N*/ // Geometriestart mitteilen
+/*N*/ aDisplayGeometry.StartDescription();
+/*N*/
+/*N*/ // Lokales Volumen reset
+/*N*/ aLocalBoundVol = Volume3D();
+/*N*/
+/*N*/ // Geometrie ist ab jetzt gueltig, um ein rekursives weiteres
+/*N*/ // Erzeugen zu verhindern
+/*N*/ bGeometryValid = TRUE;
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Identifier zurueckgeben
+|*
+\************************************************************************/
+
+/*N*/ UINT16 E3dCompoundObject::GetObjIdentifier() const
+/*N*/ {
+/*N*/ return E3D_COMPOUNDOBJ_ID;
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Compounds brauchen Defaults
+|*
+\************************************************************************/
+
+/*N*/ void E3dCompoundObject::ForceDefaultAttr()
+/*N*/ {
+/*N*/ SdrAttrObj::ForceDefaultAttr();
+/*N*/ }
+
+/*************************************************************************
+|*
+|* SnapRect berechnen
+|*
+\************************************************************************/
+
+/*N*/ void E3dCompoundObject::RecalcSnapRect()
+/*N*/ {
+/*N*/ E3dScene* pScene = GetScene();
+/*N*/ if(pScene)
+/*N*/ {
+/*N*/ // Objekttransformation uebernehmen
+/*N*/ const Volume3D& rBoundVol = GetBoundVolume();
+/*N*/ maSnapRect = Rectangle();
+/*N*/
+/*N*/ if(rBoundVol.IsValid())
+/*N*/ {
+/*N*/ const Matrix4D& rTrans = GetFullTransform();
+/*N*/ Vol3DPointIterator aIter(rBoundVol, &rTrans);
+/*N*/ Vector3D aTfVec;
+/*N*/ while ( aIter.Next(aTfVec) )
+/*N*/ {
+/*N*/ aTfVec = pScene->GetCameraSet().WorldToViewCoor(aTfVec);
+/*N*/ Point aPoint((long)(aTfVec.X() + 0.5), (long)(aTfVec.Y() + 0.5));
+/*N*/ maSnapRect.Union(Rectangle(aPoint, aPoint));
+/*N*/ }
+/*N*/ }
+/*N*/ bSnapRectDirty = FALSE;
+/*N*/ }
+/*N*/ }
+
+/*************************************************************************
+|*
+|* BoundRect berechnen und evtl. Schatten einbeziehen
+|* Dazu muss ein eventueller Schatten des einzelnen 3D-Objektes
+|* beruecksichtigt werden
+|*
+\************************************************************************/
+
+/*N*/ void E3dCompoundObject::RecalcBoundRect()
+/*N*/ {
+/*N*/ // BoundRect aus SnapRect berechnen
+/*N*/ aOutRect = GetSnapRect();
+/*N*/
+/*N*/ E3dScene* pScene = GetScene();
+/*N*/ if(pScene)
+/*N*/ {
+/*N*/ // Schatten beruecksichtigen
+/*N*/ if(DoDrawShadow())
+/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001
+/*N*/ }
+
+ // Linienbreite beruecksichtigen
+/*N*/ INT32 nLineWidth = ((const XLineWidthItem&)(GetItem(XATTR_LINEWIDTH))).GetValue();
+/*N*/ if(nLineWidth)
+/*N*/ {
+/*?*/ Rectangle aShadowRect = aOutRect;
+/*?*/ aShadowRect.Left() -= nLineWidth;
+/*?*/ aShadowRect.Right() += nLineWidth;
+/*?*/ aShadowRect.Top() -= nLineWidth;
+/*?*/ aShadowRect.Bottom() += nLineWidth;
+/*?*/ aOutRect.Union(aShadowRect);
+/*N*/ }
+/*N*/ }
+/*N*/ }
+
+/*************************************************************************
+|*
+|* BoundVolume holen. Falls die Geometrie ungueltig ist, diese neu
+|* erzeugen und das BoundVol neu berechnen
+|*
+\************************************************************************/
+
+/*N*/ const Volume3D& E3dCompoundObject::GetBoundVolume()
+/*N*/ {
+/*N*/ // Geometrie aktuell?
+/*N*/ if(!bGeometryValid)
+/*N*/ {
+/*N*/ // Neu erzeugen und eine Neubestimmung des BoundVol erzwingen
+/*N*/ ReCreateGeometry();
+/*N*/ bBoundVolValid = FALSE;
+/*N*/ }
+/*N*/
+/*N*/ // call parent
+/*N*/ return E3dObject::GetBoundVolume();
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Rausschreiben der Datenmember eines E3dCompounds
+|*
+\************************************************************************/
+
+/*N*/ void E3dCompoundObject::WriteData(SvStream& rOut) const
+/*N*/ {
+/*N*/ #ifndef SVX_LIGHT
+/*N*/ #ifdef E3D_STREAMING
+/*N*/
+/*N*/ if (!aLocalBoundVol.IsValid() && aBoundVol.IsValid())
+/*N*/ {
+/*N*/ // Das aLocalBoundVol wird gespeichert.
+/*N*/ // Ist dieses ungueltig, so wird das aBoundVol genommen
+/*N*/ // (sollten beim E3dCompoundObject sowieso gleich sein)
+/*N*/ ((E3dCompoundObject*) this)->aLocalBoundVol = aBoundVol;
+/*N*/ }
+/*N*/
+/*N*/ E3dObject::WriteData(rOut);
+/*N*/ if (rOut.GetVersion() < 3560)
+/*N*/ {
+/*N*/ // In diesem Fall passiert nichts, da vor der Version 4.0
+/*N*/ // also im Falle der Revision 3.1
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ SdrDownCompat aCompat(rOut, STREAM_WRITE);
+/*N*/ #ifdef DBG_UTIL
+/*N*/ aCompat.SetID("E3dCompoundObject");
+/*N*/ #endif
+/*N*/ rOut << BOOL(GetDoubleSided());
+/*N*/ #endif
+/*N*/
+/*N*/ // neue Parameter zur Geometrieerzeugung
+/*N*/ rOut << BOOL(bCreateNormals);
+/*N*/ rOut << BOOL(bCreateTexture);
+/*N*/
+/*N*/ sal_uInt16 nVal = GetNormalsKind();
+/*N*/ rOut << BOOL(nVal > 0);
+/*N*/ rOut << BOOL(nVal > 1);
+/*N*/
+/*N*/ nVal = GetTextureProjectionX();
+/*N*/ rOut << BOOL(nVal > 0);
+/*N*/ rOut << BOOL(nVal > 1);
+/*N*/
+/*N*/ nVal = GetTextureProjectionY();
+/*N*/ rOut << BOOL(nVal > 0);
+/*N*/ rOut << BOOL(nVal > 1);
+/*N*/
+/*N*/ rOut << BOOL(GetShadow3D());
+/*N*/
+/*N*/ // neu al 384:
+/*N*/ rOut << GetMaterialAmbientColor();
+/*N*/ rOut << GetMaterialColor();
+/*N*/ rOut << GetMaterialSpecular();
+/*N*/ rOut << GetMaterialEmission();
+/*N*/ rOut << GetMaterialSpecularIntensity();
+/*N*/
+/*N*/ aBackMaterial.WriteData(rOut);
+/*N*/
+/*N*/ rOut << (UINT16)GetTextureKind();
+/*N*/
+/*N*/ rOut << (UINT16)GetTextureMode();
+/*N*/
+/*N*/ rOut << BOOL(GetNormalsInvert());
+/*N*/
+/*N*/ // neu ab 534: (hat noch gefehlt)
+/*N*/ rOut << BOOL(GetTextureFilter());
+/*N*/ }
+/*N*/ #endif
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Einlesen der Datenmember eines E3dCompounds
+|*
+\************************************************************************/
+
+/*N*/ void E3dCompoundObject::ReadData(const SdrObjIOHeader& rHead, SvStream& rIn)
+/*N*/ {
+/*N*/ if ( rIn.GetError() != SVSTREAM_OK )
+/*N*/ return;
+/*N*/
+/*N*/ E3dObject::ReadData(rHead, rIn);
+/*N*/
+/*N*/ // Vor der Filerevision 13 wurde das Objekt nie geschrieben.
+/*N*/ // auch kein Kompatibilitaetsrecord.
+/*N*/ if ((rHead.GetVersion() < 13) || (rIn.GetVersion() < 3560))
+/*N*/ {
+/*N*/ return;
+/*N*/ }
+/*N*/
+/*N*/ SdrDownCompat aCompat(rIn, STREAM_READ);
+/*N*/ #ifdef DBG_UTIL
+/*N*/ aCompat.SetID("E3dCompoundObject");
+/*N*/ #endif
+/*N*/
+/*N*/ bBytesLeft = FALSE;
+/*N*/ if (aCompat.GetBytesLeft () >= sizeof (BOOL))
+/*N*/ {
+/*N*/ BOOL bTmp, bTmp2;
+/*N*/ sal_uInt16 nTmp;
+/*N*/
+/*N*/ rIn >> bTmp;
+/*N*/ mpObjectItemSet->Put(Svx3DDoubleSidedItem(bTmp));
+/*N*/
+/*N*/ // neue Parameter zur Geometrieerzeugung
+/*N*/ if (aCompat.GetBytesLeft () >= sizeof (BOOL))
+/*N*/ {
+/*N*/ rIn >> bTmp;
+/*N*/ bCreateNormals = bTmp;
+/*N*/
+/*N*/ rIn >> bTmp;
+/*N*/ bCreateTexture = bTmp;
+/*N*/
+/*N*/ rIn >> bTmp;
+/*N*/ rIn >> bTmp2;
+/*N*/ if(bTmp == FALSE && bTmp2 == FALSE)
+/*N*/ nTmp = 0;
+/*N*/ else if(bTmp == TRUE && bTmp2 == FALSE)
+/*N*/ nTmp = 1;
+/*N*/ else
+/*N*/ nTmp = 2;
+/*N*/ mpObjectItemSet->Put(Svx3DNormalsKindItem(nTmp));
+/*N*/
+/*N*/ rIn >> bTmp;
+/*N*/ rIn >> bTmp2;
+/*N*/ if(bTmp == FALSE && bTmp2 == FALSE)
+/*N*/ nTmp = 0;
+/*N*/ else if(bTmp == TRUE && bTmp2 == FALSE)
+/*N*/ nTmp = 1;
+/*N*/ else
+/*N*/ nTmp = 2;
+/*N*/ mpObjectItemSet->Put(Svx3DTextureProjectionXItem(nTmp));
+/*N*/
+/*N*/ rIn >> bTmp;
+/*N*/ rIn >> bTmp2;
+/*N*/ if(bTmp == FALSE && bTmp2 == FALSE)
+/*N*/ nTmp = 0;
+/*N*/ else if(bTmp == TRUE && bTmp2 == FALSE)
+/*N*/ nTmp = 1;
+/*N*/ else
+/*N*/ nTmp = 2;
+/*N*/ mpObjectItemSet->Put(Svx3DTextureProjectionYItem(nTmp));
+/*N*/
+/*N*/ rIn >> bTmp;
+/*N*/ mpObjectItemSet->Put(Svx3DShadow3DItem(bTmp));
+/*N*/
+/*N*/ // Setze ein Flag fuer den Aufrufer, dass neues Format
+/*N*/ // zu lesen ist
+/*N*/ bBytesLeft = TRUE;
+/*N*/ }
+/*N*/
+/*N*/ // neu al 384:
+/*N*/ if (aCompat.GetBytesLeft () >= sizeof (B3dMaterial))
+/*N*/ {
+/*N*/ UINT16 nTmp;
+/*N*/
+/*N*/ Color aCol;
+/*N*/
+/*N*/ rIn >> aCol;
+/*N*/ SetMaterialAmbientColor(aCol);
+/*N*/
+/*N*/ rIn >> aCol;
+/*N*/ // do NOT use, this is the old 3D-Color(!)
+/*N*/ // SetItem(XFillColorItem(String(), aCol));
+/*N*/
+/*N*/ rIn >> aCol;
+/*N*/ mpObjectItemSet->Put(Svx3DMaterialSpecularItem(aCol));
+/*N*/
+/*N*/ rIn >> aCol;
+/*N*/ mpObjectItemSet->Put(Svx3DMaterialEmissionItem(aCol));
+/*N*/
+/*N*/ rIn >> nTmp;
+/*N*/ mpObjectItemSet->Put(Svx3DMaterialSpecularIntensityItem(nTmp));
+/*N*/
+/*N*/ aBackMaterial.ReadData(rIn);
+/*N*/
+/*N*/ rIn >> nTmp;
+/*N*/ mpObjectItemSet->Put(Svx3DTextureKindItem(nTmp));
+/*N*/
+/*N*/ rIn >> nTmp;
+/*N*/ mpObjectItemSet->Put(Svx3DTextureModeItem(nTmp));
+/*N*/
+/*N*/ rIn >> bTmp;
+/*N*/ mpObjectItemSet->Put(Svx3DNormalsInvertItem(bTmp));
+/*N*/ }
+/*N*/
+/*N*/ // neu ab 534: (hat noch gefehlt)
+/*N*/ if (aCompat.GetBytesLeft () >= sizeof (BOOL))
+/*N*/ {
+/*N*/ rIn >> bTmp;
+/*N*/ mpObjectItemSet->Put(Svx3DTextureFilterItem(bTmp));
+/*N*/ }
+/*N*/ }
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Bitmaps fuer 3D-Darstellung von Gradients und Hatches holen
+|*
+\************************************************************************/
+
+
+
+
+/*************************************************************************
+|*
+|* Give out simple line geometry
+|*
+\************************************************************************/
+
+
+/*************************************************************************
+|*
+|* Geometrieerzeugung
+|*
+\************************************************************************/
+
+/*N*/ void E3dCompoundObject::DestroyGeometry()
+/*N*/ {
+/*N*/ // Alle Objekte in der Sub-Liste zerstoeren. Dies sind die
+/*N*/ // zur Visualisierung des Objektes verwendeten Hilfsobjekte
+/*N*/ pSub->Clear();
+/*N*/ delete pSub;
+/*N*/ pSub = new E3dObjList(NULL, NULL);
+/*N*/ pSub->SetOwnerObj(this);
+/*N*/ pSub->SetListKind(SDROBJLIST_GROUPOBJ);
+/*N*/
+/*N*/ // Neue Geometrie zerstoeren
+/*N*/ aDisplayGeometry.Erase();
+/*N*/
+/*N*/ // BoundVols resetten
+/*N*/ aLocalBoundVol = Volume3D();
+/*N*/ bBoundVolValid = FALSE;
+/*N*/ StructureChanged(this);
+/*N*/
+/*N*/ // Geometrie ist ungueltig
+/*N*/ bGeometryValid = FALSE;
+/*N*/ }
+
+/*N*/ void E3dCompoundObject::CreateGeometry()
+/*N*/ {
+/*N*/ // Geometrie ist gueltig, um rekursion zu verhindern
+/*N*/ bGeometryValid = TRUE;
+/*N*/
+/*N*/ // Eventuell entstandene Geometrie noch korrigieren
+/*N*/ // und Default -Normalen oder -Texturkoordinaten erzeugen
+/*N*/ if(bCreateNormals)
+/*N*/ {
+/*N*/ if(GetNormalsKind() > 1)
+/*?*/ GetDisplayGeometry().CreateDefaultNormalsSphere();
+/*N*/ if(GetNormalsInvert())
+/*?*/ GetDisplayGeometry().InvertNormals();
+/*N*/ }
+/*N*/
+/*N*/ if(bCreateTexture)
+/*N*/ {
+/*N*/ GetDisplayGeometry().CreateDefaultTexture(
+/*N*/ ((GetTextureProjectionX() > 0) ? B3D_CREATE_DEFAULT_X : FALSE)
+/*N*/ |((GetTextureProjectionY() > 0) ? B3D_CREATE_DEFAULT_Y : FALSE),
+/*N*/ GetTextureProjectionX() > 1);
+/*N*/ }
+/*N*/
+/*N*/ // Am Ende der Geometrieerzeugung das model an den erzeugten
+/*N*/ // PolyObj's setzen, d.h. beim ueberladen dieser Funktion
+/*N*/ // den parent am Ende rufen.
+/*N*/ if(bCreateE3dPolyObj)
+/*N*/ SetModel(pModel);
+/*N*/
+/*N*/ // Das Ende der Geometrieerzeugung anzeigen
+/*N*/ aDisplayGeometry.EndDescription();
+/*N*/ }
+
+/*N*/ void E3dCompoundObject::ReCreateGeometry(BOOL bCreateOldGeometry)
+/*N*/ {
+/*N*/ // Geometrie zerstoeren
+/*N*/ DestroyGeometry();
+/*N*/
+/*N*/ // Flag fuer Geometrieerzeugung setzen
+/*N*/ bCreateE3dPolyObj = bCreateOldGeometry;
+/*N*/
+/*N*/ // ... und neu erzeugen
+/*N*/ CreateGeometry();
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Geometrieerzeugung
+|*
+\************************************************************************/
+
+/*N*/ void E3dCompoundObject::AddGeometry(const PolyPolygon3D& rPolyPolygon3D,
+/*N*/ BOOL bHintIsComplex, BOOL bOutline)
+/*N*/ {
+/*N*/ if(rPolyPolygon3D.Count())
+/*N*/ {
+/*N*/ // eventuell alte Geometrie erzeugen (z.B. zum speichern)
+/*N*/ if(bCreateE3dPolyObj)
+/*N*/ {
+/*N*/ E3dPolyObj* pObj = new E3dPolyObj(
+/*N*/ rPolyPolygon3D, GetDoubleSided(), TRUE);
+/*N*/ pObj->SetPartOfParent();
+/*N*/ Insert3DObj(pObj);
+/*N*/ }
+/*N*/
+/*N*/ // neue Geometrie erzeugen
+/*N*/ for(USHORT a = 0; a < rPolyPolygon3D.Count(); a++ )
+/*N*/ {
+/*N*/ const Polygon3D& rPoly3D = rPolyPolygon3D[a];
+/*N*/ aDisplayGeometry.StartObject(bHintIsComplex, bOutline);
+/*N*/ for(USHORT b = 0; b < rPoly3D.GetPointCount(); b++ )
+/*N*/ aDisplayGeometry.AddEdge(rPoly3D[b]);
+/*N*/ }
+/*N*/ aDisplayGeometry.EndObject();
+/*N*/
+/*N*/ // LocalBoundVolume pflegen
+/*N*/ aLocalBoundVol.Union(rPolyPolygon3D.GetPolySize());
+/*N*/
+/*N*/ // Eigenes BoundVol nicht mehr gueltig
+/*N*/ SetBoundVolInvalid();
+/*N*/ SetRectsDirty();
+/*N*/ }
+/*N*/ }
+
+/*?*/ 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();
+/*?*/ }
+/*?*/ }
+
+/*N*/ void E3dCompoundObject::AddGeometry(
+/*N*/ const PolyPolygon3D& rPolyPolygon3D,
+/*N*/ const PolyPolygon3D& rPolyNormal3D,
+/*N*/ const PolyPolygon3D& rPolyTexture3D,
+/*N*/ BOOL bHintIsComplex, BOOL bOutline)
+/*N*/ {
+/*N*/ if(rPolyPolygon3D.Count())
+/*N*/ {
+/*N*/ // eventuell alte Geometrie erzeugen (z.B. zum speichern)
+/*N*/ if(bCreateE3dPolyObj)
+/*N*/ {
+/*N*/ E3dPolyObj* pObj = new E3dPolyObj(
+/*N*/ rPolyPolygon3D, rPolyNormal3D,
+/*N*/ rPolyTexture3D, GetDoubleSided(), TRUE);
+/*N*/ pObj->SetPartOfParent();
+/*N*/ Insert3DObj(pObj);
+/*N*/ }
+/*N*/
+/*N*/ // neue Geometrie erzeugen
+/*N*/ for(USHORT a = 0; a < rPolyPolygon3D.Count(); a++ )
+/*N*/ {
+/*N*/ const Polygon3D& rPoly3D = rPolyPolygon3D[a];
+/*N*/ const Polygon3D& rNormal3D = rPolyNormal3D[a];
+/*N*/ const Polygon3D& rTexture3D = rPolyTexture3D[a];
+/*N*/ aDisplayGeometry.StartObject(bHintIsComplex, bOutline);
+/*N*/ for(USHORT b = 0; b < rPoly3D.GetPointCount(); b++ )
+/*N*/ aDisplayGeometry.AddEdge(rPoly3D[b], rNormal3D[b], rTexture3D[b]);
+/*N*/ }
+/*N*/ aDisplayGeometry.EndObject();
+/*N*/
+/*N*/ // LocalBoundVolume pflegen
+/*N*/ aLocalBoundVol.Union(rPolyPolygon3D.GetPolySize());
+/*N*/
+/*N*/ // Eigenes BoundVol nicht mehr gueltig
+/*N*/ SetBoundVolInvalid();
+/*N*/ SetRectsDirty();
+/*N*/ }
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Hilfsfunktionen zur Geometrieerzeugung
+|*
+\************************************************************************/
+
+/*N*/ void E3dCompoundObject::RotatePoly(
+/*N*/ PolyPolygon3D& rPolyPolyRotate,
+/*N*/ Matrix4D& rRotMat)
+/*N*/ {
+/*N*/ USHORT nPolyCnt = rPolyPolyRotate.Count();
+/*N*/
+/*N*/ for(UINT16 a=0;a<nPolyCnt;a++)
+/*N*/ {
+/*N*/ Polygon3D& rPolyRotate = rPolyPolyRotate[a];
+/*N*/ USHORT nPntCnt = rPolyRotate.GetPointCount();
+/*N*/
+/*N*/ for(UINT16 b=0;b<nPntCnt;b++)
+/*N*/ rPolyRotate[b] *= rRotMat;
+/*N*/ }
+/*N*/ }
+
+/*N*/ void E3dCompoundObject::GrowPoly(
+/*N*/ PolyPolygon3D& rPolyPolyGrow,
+/*N*/ PolyPolygon3D& rPolyPolyNormals,
+/*N*/ double fFactor)
+/*N*/ {
+/*N*/ USHORT nPolyCnt = rPolyPolyGrow.Count();
+/*N*/
+/*N*/ for(UINT16 a=0;a<nPolyCnt;a++)
+/*N*/ {
+/*N*/ Polygon3D& rPolyGrow = rPolyPolyGrow[a];
+/*N*/ const Polygon3D& rPolyNormals = rPolyPolyNormals[a];
+/*N*/ USHORT nPntCnt = rPolyGrow.GetPointCount();
+/*N*/
+/*N*/ for(UINT16 b=0;b<nPntCnt;b++)
+/*N*/ rPolyGrow[b] += rPolyNormals[b] * fFactor;
+/*N*/ }
+/*N*/ }
+
+
+/*N*/ void E3dCompoundObject::ScalePoly(
+/*N*/ PolyPolygon3D& rPolyPolyScale,
+/*N*/ double fFactor)
+/*N*/ {
+/*N*/ USHORT nPolyCnt = rPolyPolyScale.Count();
+/*N*/ Vector3D aMiddle = rPolyPolyScale.GetMiddle();
+/*N*/
+/*N*/ for(UINT16 a=0;a<nPolyCnt;a++)
+/*N*/ {
+/*N*/ Polygon3D& rPolyScale = rPolyPolyScale[a];
+/*N*/ USHORT nPntCnt = rPolyScale.GetPointCount();
+/*N*/
+/*N*/ for(UINT16 b=0;b<nPntCnt;b++)
+/*N*/ rPolyScale[b] = ((rPolyScale[b] - aMiddle) * fFactor) + aMiddle;
+/*N*/ }
+/*N*/ }
+
+/*N*/ void E3dCompoundObject::CreateFront(
+/*N*/ const PolyPolygon3D& rPolyPoly3D,
+/*N*/ const PolyPolygon3D& rFrontNormals,
+/*N*/ BOOL bCreateNormals,
+/*N*/ BOOL bCreateTexture)
+/*N*/ {
+/*N*/ // Vorderseite
+/*N*/ if(bCreateNormals)
+/*N*/ {
+/*N*/ if(bCreateTexture)
+/*N*/ {
+/*N*/ // Polygon fuer die Textur erzeugen
+/*N*/ PolyPolygon3D aPolyTexture = rPolyPoly3D;
+/*N*/ Volume3D aSize = aPolyTexture.GetPolySize();
+/*N*/ Matrix4D aTrans;
+/*N*/
+/*N*/ aTrans.Identity();
+/*N*/ aTrans.Translate(-aSize.MinVec());
+/*N*/ aPolyTexture.Transform(aTrans);
+/*N*/
+/*N*/ double fFactorX(1.0), fFactorY(1.0), fFactorZ(1.0);
+/*N*/
+/*N*/ if(aSize.GetWidth() != 0.0)
+/*N*/ fFactorX = 1.0 / aSize.GetWidth();
+/*N*/
+/*N*/ if(aSize.GetHeight() != 0.0)
+/*N*/ fFactorY = 1.0 / aSize.GetHeight();
+/*N*/
+/*N*/ if(aSize.GetDepth() != 0.0)
+/*N*/ fFactorZ = 1.0 / aSize.GetDepth();
+/*N*/
+/*N*/ aTrans.Identity();
+/*N*/ aTrans.Scale(fFactorX, -fFactorY, fFactorZ);
+/*N*/ aTrans.Translate(Vector3D(0.0, 1.0, 0.0));
+/*N*/ aPolyTexture.Transform(aTrans);
+/*N*/
+/*N*/ AddGeometry(rPolyPoly3D, rFrontNormals, aPolyTexture, TRUE);
+/*N*/ }
+/*N*/ else
+/*N*/ AddGeometry(rPolyPoly3D, rFrontNormals, TRUE);
+/*N*/ }
+/*N*/ else
+/*N*/ AddGeometry(rPolyPoly3D, TRUE);
+/*N*/ }
+
+/*N*/ void E3dCompoundObject::AddFrontNormals(
+/*N*/ const PolyPolygon3D& rPolyPoly3D,
+/*N*/ PolyPolygon3D& rNormalsFront,
+/*N*/ Vector3D &rOffset)
+/*N*/ {
+/*N*/ Vector3D aFrontNormal = -rOffset;
+/*N*/ aFrontNormal.Normalize();
+/*N*/ USHORT nPolyCnt = rPolyPoly3D.Count();
+/*N*/
+/*N*/ for(UINT16 a=0;a<nPolyCnt;a++)
+/*N*/ {
+/*N*/ const Polygon3D& rPoly3D = rPolyPoly3D[a];
+/*N*/ Polygon3D& rNormalPoly = rNormalsFront[a];
+/*N*/ USHORT nPntCnt = rPoly3D.GetPointCount();
+/*N*/
+/*N*/ for(UINT16 b=0;b<nPntCnt;b++)
+/*N*/ {
+/*N*/ rNormalPoly[b] += aFrontNormal;
+/*N*/ rNormalPoly[b].Normalize();
+/*N*/ }
+/*N*/ }
+/*N*/ }
+
+/*N*/ void E3dCompoundObject::CreateBack(
+/*N*/ const PolyPolygon3D& rPolyPoly3D,
+/*N*/ const PolyPolygon3D& rBackNormals,
+/*N*/ BOOL bCreateNormals,
+/*N*/ BOOL bCreateTexture)
+/*N*/ {
+/*N*/ // PolyPolygon umdrehen
+/*N*/ PolyPolygon3D aLocalPoly = rPolyPoly3D;
+/*N*/ aLocalPoly.FlipDirections();
+/*N*/
+/*N*/ // Rueckseite
+/*N*/ if(bCreateNormals)
+/*N*/ {
+/*N*/ PolyPolygon3D aLocalNormals = rBackNormals;
+/*N*/ aLocalNormals.FlipDirections();
+/*N*/ if(bCreateTexture)
+/*N*/ {
+/*N*/ // Polygon fuer die Textur erzeugen
+/*N*/ PolyPolygon3D aPolyTexture(aLocalPoly);
+/*N*/ Volume3D aSize = aPolyTexture.GetPolySize();
+/*N*/ Matrix4D aTrans;
+/*N*/
+/*N*/ aTrans.Identity();
+/*N*/ aTrans.Translate(-aSize.MinVec());
+/*N*/ aPolyTexture.Transform(aTrans);
+/*N*/
+/*N*/ double fFactorX(1.0), fFactorY(1.0), fFactorZ(1.0);
+/*N*/
+/*N*/ if(aSize.GetWidth() != 0.0)
+/*N*/ fFactorX = 1.0 / aSize.GetWidth();
+/*N*/
+/*N*/ if(aSize.GetHeight() != 0.0)
+/*N*/ fFactorY = 1.0 / aSize.GetHeight();
+/*N*/
+/*N*/ if(aSize.GetDepth() != 0.0)
+/*N*/ fFactorZ = 1.0 / aSize.GetDepth();
+/*N*/
+/*N*/ aTrans.Identity();
+/*N*/ aTrans.Scale(fFactorX, -fFactorY, fFactorZ);
+/*N*/ aTrans.Translate(Vector3D(0.0, 1.0, 0.0));
+/*N*/ aPolyTexture.Transform(aTrans);
+/*N*/
+/*N*/ AddGeometry(aLocalPoly, aLocalNormals, aPolyTexture, TRUE);
+/*N*/ }
+/*N*/ else
+/*N*/ AddGeometry(aLocalPoly, aLocalNormals, TRUE);
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ AddGeometry(aLocalPoly, TRUE);
+/*N*/ }
+/*N*/ }
+
+/*N*/ void E3dCompoundObject::AddBackNormals(
+/*N*/ const PolyPolygon3D& rPolyPoly3D,
+/*N*/ PolyPolygon3D& rNormalsBack,
+/*N*/ Vector3D& rOffset)
+/*N*/ {
+/*N*/ Vector3D aBackNormal = rOffset;
+/*N*/ aBackNormal.Normalize();
+/*N*/ USHORT nPolyCnt = rPolyPoly3D.Count();
+/*N*/
+/*N*/ for(UINT16 a=0;a<nPolyCnt;a++)
+/*N*/ {
+/*N*/ const Polygon3D& rPoly3D = rPolyPoly3D[a];
+/*N*/ Polygon3D& rNormalPoly = rNormalsBack[a];
+/*N*/ USHORT nPntCnt = rPoly3D.GetPointCount();
+/*N*/
+/*N*/ for(UINT16 b=0;b<nPntCnt;b++)
+/*N*/ {
+/*N*/ rNormalPoly[b] += aBackNormal;
+/*N*/ rNormalPoly[b].Normalize();
+/*N*/ }
+/*N*/ }
+/*N*/ }
+
+/*N*/ void E3dCompoundObject::CreateInBetween(
+/*N*/ const PolyPolygon3D& rPolyPolyFront,
+/*N*/ const PolyPolygon3D& rPolyPolyBack,
+/*N*/ const PolyPolygon3D& rFrontNormals,
+/*N*/ const PolyPolygon3D& rBackNormals,
+/*N*/ BOOL bCreateNormals,
+/*N*/ double fSurroundFactor,
+/*N*/ double fTextureStart,
+/*N*/ double fTextureDepth,
+/*N*/ BOOL bRotateTexture90)
+/*N*/ {
+/*N*/ USHORT nPolyCnt = rPolyPolyFront.Count();
+/*N*/ BOOL bCreateTexture = (fTextureDepth == 0.0) ? FALSE : TRUE;
+/*N*/ double fPolyLength, fPolyPos;
+/*N*/ USHORT nLastIndex;
+/*N*/
+/*N*/ // Verbindungsstuecke
+/*N*/ if(bCreateNormals)
+/*N*/ {
+/*N*/ for(UINT16 a=0;a<nPolyCnt;a++)
+/*N*/ {
+/*N*/ const Polygon3D& rPoly3DFront = rPolyPolyFront[a];
+/*N*/ const Polygon3D& rPoly3DBack = rPolyPolyBack[a];
+/*N*/
+/*N*/ const Polygon3D& rPolyNormalsFront = rFrontNormals[a];
+/*N*/ const Polygon3D& rPolyNormalsBack = rBackNormals[a];
+/*N*/
+/*N*/ Polygon3D aRect3D(4);
+/*N*/ Polygon3D aNormal3D(4);
+/*N*/ Polygon3D aTexture3D(4);
+/*N*/ USHORT nPntCnt = rPoly3DFront.GetPointCount();
+/*N*/ USHORT nPrefillIndex = rPoly3DFront.IsClosed() ? nPntCnt - 1 : 0;
+/*N*/
+/*N*/ aRect3D[3] = rPoly3DFront[nPrefillIndex];
+/*N*/ aRect3D[2] = rPoly3DBack[nPrefillIndex];
+/*N*/ aNormal3D[3] = rPolyNormalsFront[nPrefillIndex];
+/*N*/ aNormal3D[2] = rPolyNormalsBack[nPrefillIndex];
+/*N*/
+/*N*/ if(bCreateTexture)
+/*N*/ {
+/*N*/ fPolyLength = rPoly3DFront.GetLength();
+/*N*/ fPolyPos = 0.0;
+/*N*/ nLastIndex = rPoly3DFront.IsClosed() ? nPntCnt - 1 : 0;
+/*N*/
+/*N*/ if(bRotateTexture90)
+/*N*/ {
+/*N*/ // X,Y vertauschen
+/*N*/ aTexture3D[3].X() = fTextureStart;
+/*N*/ aTexture3D[3].Y() = (1.0 - fPolyPos) * fSurroundFactor;
+/*N*/
+/*N*/ aTexture3D[2].X() = fTextureStart + fTextureDepth;
+/*N*/ aTexture3D[2].Y() = (1.0 - fPolyPos) * fSurroundFactor;
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ aTexture3D[3].X() = fPolyPos * fSurroundFactor;
+/*N*/ aTexture3D[3].Y() = fTextureStart;
+/*N*/
+/*N*/ aTexture3D[2].X() = fPolyPos * fSurroundFactor;
+/*N*/ aTexture3D[2].Y() = fTextureStart + fTextureDepth;
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ for (USHORT i = rPoly3DFront.IsClosed() ? 0 : 1; i < nPntCnt; i++)
+/*N*/ {
+/*N*/ aRect3D[0] = aRect3D[3];
+/*N*/ aRect3D[1] = aRect3D[2];
+/*N*/
+/*N*/ aRect3D[3] = rPoly3DFront[i];
+/*N*/ aRect3D[2] = rPoly3DBack[i];
+/*N*/
+/*N*/ aNormal3D[0] = aNormal3D[3];
+/*N*/ aNormal3D[1] = aNormal3D[2];
+/*N*/
+/*N*/ aNormal3D[3] = rPolyNormalsFront[i];
+/*N*/ aNormal3D[2] = rPolyNormalsBack[i];
+/*N*/
+/*N*/ if(bCreateTexture)
+/*N*/ {
+/*N*/ // Texturkoordinaten ermitteln
+/*N*/ Vector3D aPart = rPoly3DFront[i] - rPoly3DFront[nLastIndex];
+/*N*/ fPolyPos += aPart.GetLength() / fPolyLength;
+/*N*/ nLastIndex = i;
+/*N*/
+/*N*/ // Der Abschnitt am Polygon entspricht dem Teil
+/*N*/ // von fPolyPos bis fPolyPos+fPartLength
+/*N*/
+/*N*/ aTexture3D[0] = aTexture3D[3];
+/*N*/ aTexture3D[1] = aTexture3D[2];
+/*N*/
+/*N*/ if(bRotateTexture90)
+/*N*/ {
+/*N*/ // X,Y vertauschen
+/*N*/ aTexture3D[3].X() = fTextureStart;
+/*N*/ aTexture3D[3].Y() = (1.0 - fPolyPos) * fSurroundFactor;
+/*N*/
+/*N*/ aTexture3D[2].X() = fTextureStart + fTextureDepth;
+/*N*/ aTexture3D[2].Y() = (1.0 - fPolyPos) * fSurroundFactor;
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ aTexture3D[3].X() = fPolyPos * fSurroundFactor;
+/*N*/ aTexture3D[3].Y() = fTextureStart;
+/*N*/
+/*N*/ aTexture3D[2].X() = fPolyPos * fSurroundFactor;
+/*N*/ aTexture3D[2].Y() = fTextureStart + fTextureDepth;
+/*N*/ }
+/*N*/
+/*N*/ AddGeometry(aRect3D, aNormal3D, aTexture3D, FALSE);
+/*N*/ }
+/*N*/ else
+/*N*/ AddGeometry(aRect3D, aNormal3D, FALSE);
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ for(UINT16 a=0;a<nPolyCnt;a++)
+/*N*/ {
+/*N*/ const Polygon3D& rPoly3DFront = rPolyPolyFront[a];
+/*N*/ const Polygon3D& rPoly3DBack = rPolyPolyBack[a];
+/*N*/ Polygon3D aRect3D(4);
+/*N*/ USHORT nPntCnt = rPoly3DFront.GetPointCount();
+/*N*/ USHORT nPrefillIndex = rPoly3DFront.IsClosed() ? nPntCnt - 1 : 0;
+/*N*/
+/*N*/ aRect3D[3] = rPoly3DFront[nPrefillIndex];
+/*N*/ aRect3D[2] = rPoly3DBack[nPrefillIndex];
+/*N*/
+/*N*/ for (USHORT i = rPoly3DFront.IsClosed() ? 0 : 1; i < nPntCnt; i++)
+/*N*/ {
+/*N*/ aRect3D[0] = aRect3D[3];
+/*N*/ aRect3D[1] = aRect3D[2];
+/*N*/
+/*N*/ aRect3D[3] = rPoly3DFront[i];
+/*N*/ aRect3D[2] = rPoly3DBack[i];
+/*N*/
+/*N*/ AddGeometry(aRect3D, FALSE);
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ }
+
+/*N*/ void E3dCompoundObject::AddInBetweenNormals(
+/*N*/ const PolyPolygon3D& rPolyPolyFront,
+/*N*/ const PolyPolygon3D& rPolyPolyBack,
+/*N*/ PolyPolygon3D& rNormals,
+/*N*/ BOOL bSmoothed)
+/*N*/ {
+/*N*/ USHORT nPolyCnt = rPolyPolyFront.Count();
+/*N*/
+/*N*/ // Verbindungsstuecke
+/*N*/ for(UINT16 a=0;a<nPolyCnt;a++)
+/*N*/ {
+/*N*/ const Polygon3D& rPoly3DFront = rPolyPolyFront[a];
+/*N*/ const Polygon3D& rPoly3DBack = rPolyPolyBack[a];
+/*N*/ Polygon3D& rNormalPoly = rNormals[a];
+/*N*/ USHORT nPntCnt = rPoly3DFront.GetPointCount();
+/*N*/
+/*N*/ if(rPoly3DBack.IsClosed())
+/*N*/ {
+/*N*/ Vector3D aNormal = (rPoly3DBack[nPntCnt - 1] - rPoly3DFront[nPntCnt - 1])
+/*N*/ |(rPoly3DFront[0] - rPoly3DFront[nPntCnt - 1]);
+/*N*/ aNormal.Normalize();
+/*N*/ for (USHORT i = 0; i < nPntCnt; i++)
+/*N*/ {
+/*N*/ Vector3D aNextNormal = (rPoly3DBack[i] - rPoly3DFront[i])
+/*N*/ |(rPoly3DFront[(i+1 == nPntCnt) ? 0 : i+1] - rPoly3DFront[i]);
+/*N*/ aNextNormal.Normalize();
+/*N*/ if(bSmoothed)
+/*N*/ {
+/*N*/ Vector3D aMidNormal = aNormal + aNextNormal;
+/*N*/ aMidNormal.Normalize();
+/*N*/ rNormalPoly[i] += aMidNormal;
+/*N*/ }
+/*N*/ else
+/*N*/ rNormalPoly[i] += aNormal;
+/*N*/ rNormalPoly[i].Normalize();
+/*N*/ aNormal = aNextNormal;
+/*N*/ }
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ Vector3D aNormal;
+/*N*/ if(rPoly3DBack[0] == rPoly3DFront[0])
+/*N*/ {
+/*N*/ aNormal = (rPoly3DBack[1] - rPoly3DFront[1])
+/*N*/ |(rPoly3DFront[1] - rPoly3DFront[0]);
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ aNormal = (rPoly3DBack[0] - rPoly3DFront[0])
+/*N*/ |(rPoly3DFront[1] - rPoly3DFront[0]);
+/*N*/ }
+/*N*/ aNormal.Normalize();
+/*N*/ rNormalPoly[0] += aNormal; rNormalPoly[0].Normalize();
+/*N*/ for (USHORT i = 1; i < nPntCnt; i++)
+/*N*/ {
+/*N*/ Vector3D aNextNormal;
+/*N*/ if(i+1 == nPntCnt)
+/*N*/ {
+/*N*/ aNextNormal = aNormal;
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ aNextNormal = (rPoly3DBack[i] - rPoly3DFront[i])
+/*N*/ |(rPoly3DFront[i+1] - rPoly3DFront[i]);
+/*N*/ }
+/*N*/ aNextNormal.Normalize();
+/*N*/ if(bSmoothed)
+/*N*/ {
+/*N*/ Vector3D aMidNormal = aNormal + aNextNormal;
+/*N*/ aMidNormal.Normalize();
+/*N*/ rNormalPoly[i] += aMidNormal;
+/*N*/ }
+/*N*/ else
+/*N*/ rNormalPoly[i] += aNormal;
+/*N*/ rNormalPoly[i].Normalize();
+/*N*/ aNormal = aNextNormal;
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Copy-Operator
+|*
+\************************************************************************/
+
+
+/*************************************************************************
+|*
+|* Ausgabeparameter an 3D-Kontext setzen
+|*
+\************************************************************************/
+
+
+
+
+/*************************************************************************
+|*
+|* Hittest fuer 3D-Objekte, wird an Geometrie weitergegeben
+|*
+\************************************************************************/
+
+/*N*/ SdrObject* E3dCompoundObject::CheckHit(const Point& rPnt, USHORT nTol,
+/*N*/ const SetOfByte* pVisiLayer) const
+/*N*/ {
+/*N*/ E3dPolyScene* pScene = (E3dPolyScene*)GetScene();
+/*N*/ if(pScene)
+/*N*/ {
+/*N*/ // HitLine holen in ObjektKoordinaten
+/*N*/ // ObjectTrans setzen
+/*N*/ Matrix4D mTransform = ((E3dCompoundObject*)this)->GetFullTransform();
+/*N*/ pScene->GetCameraSet().SetObjectTrans(mTransform);
+/*N*/
+/*N*/ // HitPoint Front und Back erzeugen und umrechnen
+/*N*/ Vector3D aFront(rPnt.X(), rPnt.Y(), 0.0);
+/*N*/ Vector3D aBack(rPnt.X(), rPnt.Y(), ZBUFFER_DEPTH_RANGE);
+/*N*/ aFront = pScene->GetCameraSet().ViewToObjectCoor(aFront);
+/*N*/ aBack = pScene->GetCameraSet().ViewToObjectCoor(aBack);
+/*N*/
+/*N*/ const Volume3D& rBoundVol = ((E3dCompoundObject*)this)->GetBoundVolume();
+/*N*/ if(rBoundVol.IsValid())
+/*N*/ {
+/*N*/ double fXMax = aFront.X();
+/*N*/ double fXMin = aBack.X();
+/*N*/
+/*N*/ if(fXMax < fXMin)
+/*N*/ {
+/*N*/ fXMax = aBack.X();
+/*N*/ fXMin = aFront.X();
+/*N*/ }
+/*N*/
+/*N*/ if(rBoundVol.MinVec().X() <= fXMax && rBoundVol.MaxVec().X() >= fXMin)
+/*N*/ {
+/*N*/ double fYMax = aFront.Y();
+/*N*/ double fYMin = aBack.Y();
+/*N*/
+/*N*/ if(fYMax < fYMin)
+/*N*/ {
+/*N*/ fYMax = aBack.Y();
+/*N*/ fYMin = aFront.Y();
+/*N*/ }
+/*N*/
+/*N*/ if(rBoundVol.MinVec().Y() <= fYMax && rBoundVol.MaxVec().Y() >= fYMin)
+/*N*/ {
+/*N*/ double fZMax = aFront.Z();
+/*N*/ double fZMin = aBack.Z();
+/*N*/
+/*N*/ if(fZMax < fZMin)
+/*N*/ {
+/*N*/ fZMax = aBack.Z();
+/*N*/ fZMin = aFront.Z();
+/*N*/ }
+/*N*/
+/*N*/ if(rBoundVol.MinVec().Z() <= fZMax && rBoundVol.MaxVec().Z() >= fZMin)
+/*N*/ {
+/*N*/ // Geometrie herstellen
+/*N*/ if(!bGeometryValid)
+/*?*/ ((E3dCompoundObject*)this)->ReCreateGeometry();
+/*N*/
+/*N*/ // 3D Volumes schneiden sich, teste in der Geometrie
+/*N*/ // auf Basis der Projektion weiter
+/*N*/ if(((E3dCompoundObject*)this)->aDisplayGeometry.CheckHit(aFront, aBack, nTol) != -1L)
+/*?*/ return ((E3dCompoundObject*)this);
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ return NULL;
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Geometrie des Objektes auf angegebenen Punkt zentrieren
+|*
+\************************************************************************/
+
+
+/*************************************************************************
+|*
+|* Schattenattribute holen
+|*
+\************************************************************************/
+
+
+
+
+
+
+/*N*/ BOOL E3dCompoundObject::DoDrawShadow()
+/*N*/ {
+/*N*/ const SfxItemSet& rSet = GetItemSet();
+/*N*/ BOOL bRetval(FALSE);
+/*N*/ BOOL bShadOn = ((SdrShadowItem&)(rSet.Get(SDRATTR_SHADOW))).GetValue();
+/*N*/
+/*N*/ if(bShadOn)
+/*N*/ {
+/*?*/ bRetval = TRUE;
+/*?*/
+/*?*/ if(((XFillStyleItem&)(rSet.Get(XATTR_FILLSTYLE))).GetValue() == XFILL_NONE)
+/*?*/ {
+/*?*/ if(((XLineStyleItem&)(rSet.Get(XATTR_LINESTYLE))).GetValue() == XLINE_NONE)
+/*?*/ {
+/*?*/ bRetval = FALSE;
+/*?*/ }
+/*?*/ }
+/*N*/ }
+/*N*/ return bRetval;
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Objekt als WireFrame zeichnen
+|*
+\************************************************************************/
+
+
+/*************************************************************************
+|*
+|* Create vertical polygons for line polygon
+|*
+\************************************************************************/
+
+// #78972#
+/*N*/ void E3dCompoundObject::ImpCompleteLinePolygon(PolyPolygon3D& rLinePolyPoly,
+/*N*/ sal_uInt16 nPolysPerRun, BOOL bClosed)
+/*N*/ {
+/*N*/ if(rLinePolyPoly.Count() && nPolysPerRun)
+/*N*/ {
+/*N*/ // get number of layers
+/*N*/ sal_uInt16 nLayers(rLinePolyPoly.Count() / nPolysPerRun);
+/*N*/ sal_uInt16 a, b, c;
+/*N*/
+/*N*/ // add vertical Polygons if at least two horizontal ones exist
+/*N*/ if(nLayers > 1)
+/*N*/ {
+/*N*/ for(a = 0; a < nPolysPerRun; a++)
+/*N*/ {
+/*N*/ const sal_uInt16 nPntCnt = rLinePolyPoly[a].GetPointCount();
+/*N*/
+/*N*/ for(b = 0; b < nPntCnt; b++)
+/*N*/ {
+/*N*/ Polygon3D aNewVerPoly(bClosed ? nLayers + 1 : nLayers);
+/*N*/
+/*N*/ for(c = 0; c < nLayers; c++)
+/*N*/ aNewVerPoly[c] = rLinePolyPoly[(c * nPolysPerRun) + a][b];
+/*N*/
+/*N*/ // evtl. set first point again to close polygon
+/*N*/ if(bClosed)
+/*N*/ aNewVerPoly[aNewVerPoly.GetPointCount()] = aNewVerPoly[0];
+/*N*/
+/*N*/ // insert
+/*N*/ rLinePolyPoly.Insert(aNewVerPoly);
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ // open closed polygons
+/*N*/ for(a = 0; a < rLinePolyPoly.Count(); a++)
+/*N*/ {
+/*N*/ if(rLinePolyPoly[a].IsClosed())
+/*N*/ {
+/*N*/ rLinePolyPoly[a][rLinePolyPoly[a].GetPointCount()] = rLinePolyPoly[a][0];
+/*N*/ rLinePolyPoly[a].SetClosed(FALSE);
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/
+/*************************************************************************
+|*
+|* Ein Segment fuer Extrude oder Lathe erzeugen
+|*
+\************************************************************************/
+
+/*N*/ void E3dCompoundObject::ImpCreateSegment(
+/*N*/ const PolyPolygon3D& rFront, // vorderes Polygon
+/*N*/ const PolyPolygon3D& rBack, // hinteres Polygon
+/*N*/ const PolyPolygon3D* pPrev, // smooth uebergang zu Vorgaenger
+/*N*/ const PolyPolygon3D* pNext, // smooth uebergang zu Nachfolger
+/*N*/ BOOL bCreateFront, // vorderen Deckel erzeugen
+/*N*/ BOOL bCreateBack, // hinteren Deckel erzeugen
+/*N*/ double fPercentDiag, // Anteil des Deckels an der Tiefe
+/*N*/ BOOL bSmoothLeft, // Glaetten der umlaufenden Normalen links
+/*N*/ BOOL bSmoothRight, // Glaetten der umlaufenden Normalen rechts
+/*N*/ BOOL bSmoothFrontBack, // Glaetten der Abschlussflaechen
+/*N*/ double fSurroundFactor, // Wertebereich der Texturkoordinaten im Umlauf
+/*N*/ double fTextureStart, // TexCoor ueber Extrude-Tiefe
+/*N*/ double fTextureDepth, // TexCoor ueber Extrude-Tiefe
+/*N*/ BOOL bCreateTexture,
+/*N*/ BOOL bCreateNormals,
+/*N*/ BOOL bCharacterExtrude, // FALSE=exakt, TRUE=ohne Ueberschneidungen
+/*N*/ BOOL bRotateTexture90, // Textur der Seitenflaechen um 90 Grad kippen
+/*N*/ PolyPolygon3D* pLineGeometry // For creation of line geometry
+/*N*/ )
+/*N*/ {
+/*N*/ PolyPolygon3D aNormalsLeft, aNormalsRight;
+/*N*/ AddInBetweenNormals(rFront, rBack, aNormalsLeft, bSmoothLeft);
+/*N*/ AddInBetweenNormals(rFront, rBack, aNormalsRight, bSmoothRight);
+/*N*/ Vector3D aOffset = rBack.GetMiddle() - rFront.GetMiddle();
+/*N*/
+/*N*/ // Ausnahmen: Nicht geschlossen
+/*N*/ if(!rFront.IsClosed())
+/*N*/ {
+/*N*/ bCreateFront = FALSE;
+/*N*/ }
+/*N*/ if(!rBack.IsClosed())
+/*N*/ {
+/*N*/ bCreateBack = FALSE;
+/*N*/ }
+/*N*/
+/*N*/ // Ausnahmen: Einfache Linie
+/*N*/ if(rFront[0].GetPointCount() < 3 || (!bCreateFront && !bCreateBack))
+/*N*/ {
+/*N*/ fPercentDiag = 0.0;
+/*N*/ }
+/*N*/
+/*N*/ if(fPercentDiag == 0.0)
+/*N*/ {
+/*N*/ // Ohne Schraegen, Vorderseite
+/*N*/ if(bCreateFront)
+/*N*/ {
+/*N*/ PolyPolygon3D aNormalsFront;
+/*N*/ AddFrontNormals(rFront, aNormalsFront, aOffset);
+/*N*/
+/*N*/ if(!bSmoothFrontBack)
+/*N*/ CreateFront(rFront, aNormalsFront, bCreateNormals, bCreateTexture);
+/*N*/ if(bSmoothLeft)
+/*N*/ AddFrontNormals(rFront, aNormalsLeft, aOffset);
+/*N*/ if(bSmoothFrontBack)
+/*?*/ CreateFront(rFront, aNormalsLeft, bCreateNormals, bCreateTexture);
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ if(pPrev)
+/*N*/ AddInBetweenNormals(*pPrev, rFront, aNormalsLeft, bSmoothLeft);
+/*N*/ }
+/*N*/
+/*N*/ // Ohne Schraegen, Rueckseite
+/*N*/ if(bCreateBack)
+/*N*/ {
+/*N*/ PolyPolygon3D aNormalsBack;
+/*N*/ AddBackNormals(rBack, aNormalsBack, aOffset);
+/*N*/
+/*N*/ if(!bSmoothFrontBack)
+/*N*/ CreateBack(rBack, aNormalsBack, bCreateNormals, bCreateTexture);
+/*N*/ if(bSmoothRight)
+/*N*/ AddBackNormals(rBack, aNormalsRight, aOffset);
+/*N*/ if(bSmoothFrontBack)
+/*?*/ CreateBack(rBack, aNormalsRight, bCreateNormals, bCreateTexture);
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ if(pNext)
+/*N*/ AddInBetweenNormals(rBack, *pNext, aNormalsRight, bSmoothRight);
+/*N*/ }
+/*N*/
+/*N*/ // eigentliches Zwischenstueck
+/*N*/ CreateInBetween(rFront, rBack,
+/*N*/ aNormalsLeft, aNormalsRight,
+/*N*/ bCreateNormals,
+/*N*/ fSurroundFactor,
+/*N*/ fTextureStart,
+/*N*/ fTextureDepth,
+/*N*/ bRotateTexture90);
+/*N*/
+/*N*/ // #78972#
+/*N*/ if(pLineGeometry)
+/*N*/ {
+/*N*/ pLineGeometry->Insert(rFront);
+/*N*/ if(bCreateBack)
+/*N*/ pLineGeometry->Insert(rBack);
+/*N*/ }
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ // Mit Scraegen, Vorderseite
+/*N*/ PolyPolygon3D aLocalFront = rFront;
+/*N*/ PolyPolygon3D aLocalBack = rBack;
+/*N*/ double fExtrudeDepth, fDiagLen;
+/*N*/ double fTexMidStart = fTextureStart;
+/*N*/ double fTexMidDepth = fTextureDepth;
+/*N*/
+/*N*/ if(bCreateFront || bCreateBack)
+/*N*/ {
+/*N*/ fExtrudeDepth = aOffset.GetLength();
+/*N*/ fDiagLen = fPercentDiag * fExtrudeDepth;
+/*N*/ }
+/*N*/
+/*N*/ PolyPolygon3D aOuterFront;
+/*N*/ PolyPolygon3D aOuterBack;
+/*N*/
+/*N*/ if(bCreateFront)
+/*N*/ {
+/*N*/ PolyPolygon3D aNormalsOuterFront;
+/*N*/ AddFrontNormals(aLocalFront, aNormalsOuterFront, aOffset);
+/*N*/
+/*N*/ if(bCharacterExtrude)
+/*N*/ {
+/*N*/ // Polygon kopieren
+/*N*/ aOuterFront = aLocalFront;
+/*N*/
+/*N*/ // notwendige Normalen erzeugen
+/*N*/ PolyPolygon3D aGrowDirection;
+/*N*/ AddInBetweenNormals(aLocalFront, aLocalBack, aGrowDirection, bSmoothLeft);
+/*N*/
+/*N*/ // Groesse inneres Polygon merken
+/*N*/ Volume3D aOldSize(aLocalFront.GetPolySize());
+/*N*/
+/*N*/ // Inneres Polygon vergroessern
+/*N*/ GrowPoly(aLocalFront, aGrowDirection, fDiagLen);
+/*N*/
+/*N*/ // Inneres Polygon nach innen verschieben
+/*N*/ //GrowPoly(aLocalFront, aNormalsOuterFront, -fDiagLen);
+/*N*/
+/*N*/ // Neue Groesse inneres Polygon feststellen
+/*N*/ Volume3D aNewSize(aLocalFront.GetPolySize());
+/*N*/
+/*N*/ // Skalierung feststellen (nur X,Y)
+/*N*/ Vector3D aScaleVec(
+/*N*/ (aNewSize.GetWidth() != 0.0) ? aOldSize.GetWidth() / aNewSize.GetWidth() : 1.0,
+/*N*/ (aNewSize.GetHeight() != 0.0) ? aOldSize.GetHeight() / aNewSize.GetHeight() : 1.0,
+/*N*/ (aNewSize.GetDepth() != 0.0) ? aOldSize.GetDepth() / aNewSize.GetDepth() : 1.0);
+/*N*/
+/*N*/ // Transformation bilden
+/*N*/ Matrix4D aTransMat;
+/*N*/ aTransMat.Scale(aScaleVec);
+/*N*/
+/*N*/ // aeusseres und inneres Polygon skalieren
+/*N*/ aLocalFront.Transform(aTransMat);
+/*N*/ aOuterFront.Transform(aTransMat);
+/*N*/
+/*N*/ // Neue Groesse aktualisieren
+/*N*/ aNewSize = aLocalFront.GetPolySize();
+/*N*/
+/*N*/ // Translation feststellen
+/*N*/ Vector3D aTransVec(
+/*N*/ aOldSize.MinVec().X() - aNewSize.MinVec().X(),
+/*N*/ aOldSize.MinVec().Y() - aNewSize.MinVec().Y(),
+/*N*/ aOldSize.MinVec().Z() - aNewSize.MinVec().Z());
+/*N*/
+/*N*/ // Transformation bilden
+/*N*/ aTransMat.Identity();
+/*N*/ aTransMat.Translate(aTransVec);
+/*N*/
+/*N*/ // aeusseres und inneres Polygon skalieren
+/*N*/ aLocalFront.Transform(aTransMat);
+/*N*/ aOuterFront.Transform(aTransMat);
+/*N*/
+/*N*/ // move aLocalFront again, scale and translate has moved it back
+/*N*/ GrowPoly(aLocalFront, aNormalsOuterFront, -fDiagLen);
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ // Polygon kopieren
+/*N*/ aOuterFront = aLocalFront;
+/*N*/
+/*N*/ // notwendige Normalen erzeugen
+/*N*/ PolyPolygon3D aGrowDirection;
+/*N*/ AddInBetweenNormals(aLocalFront, aLocalBack, aGrowDirection, bSmoothLeft);
+/*N*/
+/*N*/ // Aeusseres Polygon verkleinern
+/*N*/ GrowPoly(aOuterFront, aGrowDirection, -fDiagLen);
+/*N*/ aOuterFront.CorrectGrownPoly(aLocalFront);
+/*N*/
+/*N*/ // Inneres Polygon nach innen verschieben
+/*N*/ GrowPoly(aLocalFront, aNormalsOuterFront, -fDiagLen);
+/*N*/ }
+/*N*/
+/*N*/ // eventuell noch glaetten
+/*N*/ if(bSmoothLeft)
+/*N*/ {
+/*N*/ if(bSmoothFrontBack)
+/*?*/ AddInBetweenNormals(aOuterFront, aLocalFront, aNormalsOuterFront, bSmoothLeft);
+/*N*/ AddInBetweenNormals(aOuterFront, aLocalFront, aNormalsLeft, bSmoothLeft);
+/*N*/ }
+/*N*/
+/*N*/ // vordere Zwischenstuecke erzeugen
+/*N*/ CreateInBetween(aOuterFront, aLocalFront,
+/*N*/ aNormalsOuterFront, aNormalsLeft,
+/*N*/ bCreateNormals,
+/*N*/ fSurroundFactor,
+/*N*/ fTextureStart,
+/*N*/ fTextureDepth * fPercentDiag,
+/*N*/ bRotateTexture90);
+/*N*/
+/*N*/ // Vorderseite erzeugen
+/*N*/ CreateFront(aOuterFront, aNormalsOuterFront, bCreateNormals, bCreateTexture);
+/*N*/
+/*N*/ // Weitere Texturwerte setzen
+/*N*/ fTexMidStart += fTextureDepth * fPercentDiag;
+/*N*/ fTexMidDepth -= fTextureDepth * fPercentDiag;
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*?*/ if(pPrev)
+/*?*/ AddInBetweenNormals(*pPrev, rFront, aNormalsLeft, bSmoothLeft);
+/*N*/ }
+/*N*/
+/*N*/ // Mit Scraegen, Rueckseite
+/*N*/ if(bCreateBack)
+/*N*/ {
+/*N*/ PolyPolygon3D aNormalsOuterBack;
+/*N*/ AddBackNormals(aLocalBack, aNormalsOuterBack, aOffset);
+/*N*/
+/*N*/ if(bCharacterExtrude)
+/*N*/ {
+/*N*/ // Polygon kopieren
+/*N*/ aOuterBack = aLocalBack;
+/*N*/
+/*N*/ // notwendige Normalen erzeugen
+/*N*/ PolyPolygon3D aGrowDirection;
+/*N*/ AddInBetweenNormals(aLocalFront, aLocalBack, aGrowDirection, bSmoothRight);
+/*N*/
+/*N*/ // Groesse inneres Polygon merken
+/*N*/ Volume3D aOldSize(aLocalBack.GetPolySize());
+/*N*/
+/*N*/ // Inneres Polygon vergroessern
+/*N*/ GrowPoly(aLocalBack, aGrowDirection, fDiagLen);
+/*N*/
+/*N*/ // Inneres Polygon nach innen verschieben
+/*N*/ //GrowPoly(aLocalBack, aNormalsOuterBack, -fDiagLen);
+/*N*/
+/*N*/ // Neue Groesse inneres Polygon feststellen
+/*N*/ Volume3D aNewSize(aLocalBack.GetPolySize());
+/*N*/
+/*N*/ // Skalierung feststellen (nur X,Y)
+/*N*/ Vector3D aScaleVec(
+/*N*/ (aNewSize.GetWidth() != 0.0) ? aOldSize.GetWidth() / aNewSize.GetWidth() : 1.0,
+/*N*/ (aNewSize.GetHeight() != 0.0) ? aOldSize.GetHeight() / aNewSize.GetHeight() : 1.0,
+/*N*/ (aNewSize.GetDepth() != 0.0) ? aOldSize.GetDepth() / aNewSize.GetDepth() : 1.0);
+/*N*/
+/*N*/ // Transformation bilden
+/*N*/ Matrix4D aTransMat;
+/*N*/ aTransMat.Scale(aScaleVec);
+/*N*/
+/*N*/ // aeusseres und inneres Polygon skalieren
+/*N*/ aLocalBack.Transform(aTransMat);
+/*N*/ aOuterBack.Transform(aTransMat);
+/*N*/
+/*N*/ // Neue Groesse aktualisieren
+/*N*/ aNewSize = aLocalBack.GetPolySize();
+/*N*/
+/*N*/ // Translation feststellen
+/*N*/ Vector3D aTransVec(
+/*N*/ aOldSize.MinVec().X() - aNewSize.MinVec().X(),
+/*N*/ aOldSize.MinVec().Y() - aNewSize.MinVec().Y(),
+/*N*/ aOldSize.MinVec().Z() - aNewSize.MinVec().Z());
+/*N*/
+/*N*/ // Transformation bilden
+/*N*/ aTransMat.Identity();
+/*N*/ aTransMat.Translate(aTransVec);
+/*N*/
+/*N*/ // aeusseres und inneres Polygon skalieren
+/*N*/ aLocalBack.Transform(aTransMat);
+/*N*/ aOuterBack.Transform(aTransMat);
+/*N*/
+/*N*/ // move aLocalBack again, scale and translate has moved it back
+/*N*/ GrowPoly(aLocalBack, aNormalsOuterBack, -fDiagLen);
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ // Polygon kopieren
+/*N*/ aOuterBack = aLocalBack;
+/*N*/
+/*N*/ // notwendige Normalen erzeugen
+/*N*/ PolyPolygon3D aGrowDirection;
+/*N*/ AddInBetweenNormals(aLocalFront, aLocalBack, aGrowDirection, bSmoothRight);
+/*N*/
+/*N*/ // Aeusseres Polygon verkleinern
+/*N*/ GrowPoly(aOuterBack, aGrowDirection, -fDiagLen);
+/*N*/ aOuterBack.CorrectGrownPoly(aLocalBack);
+/*N*/
+/*N*/ // Inneres Polygon nach innen verschieben
+/*N*/ GrowPoly(aLocalBack, aNormalsOuterBack, -fDiagLen);
+/*N*/ }
+/*N*/
+/*N*/ // eventuell noch glaetten
+/*N*/ if(bSmoothRight)
+/*N*/ {
+/*N*/ if(bSmoothFrontBack)
+/*?*/ AddInBetweenNormals(aLocalBack, aOuterBack, aNormalsOuterBack, bSmoothRight);
+/*N*/ AddInBetweenNormals(aLocalBack, aOuterBack, aNormalsRight, bSmoothRight);
+/*N*/ }
+/*N*/
+/*N*/ // vordere Zwischenstuecke erzeugen
+/*N*/ // hintere Zwischenstuecke erzeugen
+/*N*/ CreateInBetween(aLocalBack, aOuterBack,
+/*N*/ aNormalsRight, aNormalsOuterBack,
+/*N*/ bCreateNormals,
+/*N*/ fSurroundFactor,
+/*N*/ fTextureStart + (fTextureDepth * (1.0 - fPercentDiag)),
+/*N*/ fTextureDepth * fPercentDiag,
+/*N*/ bRotateTexture90);
+/*N*/
+/*N*/ // Rueckseite erzeugen
+/*N*/ CreateBack(aOuterBack, aNormalsOuterBack, bCreateNormals, bCreateTexture);
+/*N*/
+/*N*/ // Weitere Texturwerte setzen
+/*N*/ fTexMidDepth -= fTextureDepth * fPercentDiag;
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*?*/ if(pNext)
+/*?*/ AddInBetweenNormals(rBack, *pNext, aNormalsRight, bSmoothRight);
+/*?*/ }
+/*N*/
+/*N*/ // eigentliches Zwischenstueck
+/*N*/ CreateInBetween(aLocalFront, aLocalBack,
+/*N*/ aNormalsLeft, aNormalsRight,
+/*N*/ bCreateNormals,
+/*N*/ fSurroundFactor,
+/*N*/ fTexMidStart,
+/*N*/ fTexMidDepth,
+/*N*/ bRotateTexture90);
+/*N*/
+/*N*/ // #78972#
+/*N*/ if(pLineGeometry)
+/*N*/ {
+/*N*/ if(bCreateFront)
+/*N*/ pLineGeometry->Insert(aOuterFront);
+/*N*/ pLineGeometry->Insert(aLocalFront);
+/*N*/ if(bCreateBack)
+/*N*/ {
+/*N*/ pLineGeometry->Insert(aLocalBack);
+/*N*/ pLineGeometry->Insert(aOuterBack);
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Parameter Geometrieerzeugung setzen
+|*
+\************************************************************************/
+
+
+
+/*************************************************************************
+|*
+|* DisplayGeometry rausruecken
+|*
+\************************************************************************/
+
+/*N*/ B3dGeometry& E3dCompoundObject::GetDisplayGeometry()
+/*N*/ {
+/*N*/ // Geometrie herstellen
+/*N*/ if(!bGeometryValid)
+/*?*/ ReCreateGeometry();
+/*N*/
+/*N*/ return aDisplayGeometry;
+/*N*/ }
+
+/*************************************************************************
+|*
+|* Material des Objektes
+|*
+\************************************************************************/
+
+/*N*/ void E3dCompoundObject::SetMaterialAmbientColor(const Color& rColor)
+/*N*/ {
+/*N*/ if(aMaterialAmbientColor != rColor)
+/*N*/ {
+/*?*/ aMaterialAmbientColor = rColor;
+/*N*/ }
+/*N*/ }
+
+
+
+/*************************************************************************
+|*
+|* 3D Ausgabe
+|*
+\************************************************************************/
+
+
+/*************************************************************************
+|*
+|* Objekt als Kontur in das Polygon einfuegen
+|*
+\************************************************************************/
+
+
+/*************************************************************************
+|*
+|* Schatten fuer 3D-Objekte zeichnen
+|*
+\************************************************************************/
+
+
+
+
+/*************************************************************************
+|*
+|* convert given PolyPolygon3D to screen coor
+|*
+\************************************************************************/
+
+
+/*************************************************************************
+|*
+|* Attribute setzen
+|*
+\************************************************************************/
+
+// private support routines for ItemSet access. NULL pointer means clear item.
+/*N*/ void E3dCompoundObject::PostItemChange(const sal_uInt16 nWhich)
+/*N*/ {
+/*N*/ // call parent
+/*N*/ E3dObject::PostItemChange(nWhich);
+/*N*/
+/*N*/ // handle value change
+/*N*/ switch(nWhich)
+/*N*/ {
+/*N*/ case SDRATTR_3DOBJ_DOUBLE_SIDED:
+/*N*/ {
+/*N*/ bGeometryValid = FALSE;
+/*N*/ break;
+/*N*/ }
+/*N*/ case SDRATTR_3DOBJ_NORMALS_KIND:
+/*N*/ {
+/*N*/ bGeometryValid = FALSE;
+/*N*/ break;
+/*N*/ }
+/*N*/ case SDRATTR_3DOBJ_NORMALS_INVERT:
+/*N*/ {
+/*N*/ bGeometryValid = FALSE;
+/*N*/ break;
+/*N*/ }
+/*N*/ case SDRATTR_3DOBJ_TEXTURE_PROJ_X:
+/*N*/ {
+/*N*/ bGeometryValid = FALSE;
+/*N*/ break;
+/*N*/ }
+/*N*/ case SDRATTR_3DOBJ_TEXTURE_PROJ_Y:
+/*N*/ {
+/*N*/ bGeometryValid = FALSE;
+/*N*/ break;
+/*N*/ }
+/*N*/ }
+/*N*/ }
+
+// EOF
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */